Compare commits

...

3 Commits

Author SHA1 Message Date
FliegendeWurst
1ea88fb193 Version 0.3.6 2022-10-21 09:52:39 +02:00
FliegendeWurst
dbfa3cf3ad Update dependencies 2022-10-21 09:50:15 +02:00
FliegendeWurst
f2c9ce5fa0 Apply rustfmt 2022-10-21 09:50:13 +02:00
8 changed files with 293 additions and 225 deletions

View File

@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.3.6]
### Fixed
- `--all` once again downloads all courses you're a member of
## [0.3.5] ## [0.3.5]
### Added ### Added
- `--pass-path` option to get the password from [pass](https://www.passwordstore.org/) (PR [#33] by [@Ma27]) - `--pass-path` option to get the password from [pass](https://www.passwordstore.org/) (PR [#33] by [@Ma27])

446
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "KIT-ILIAS-downloader" name = "KIT-ILIAS-downloader"
version = "0.3.5" version = "0.3.6"
authors = ["FliegendeWurst <2012gdwu@posteo.de>"] authors = ["FliegendeWurst <2012gdwu@posteo.de>"]
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
edition = "2018" edition = "2018"

View File

@ -174,35 +174,34 @@ pub fn ask_user_pass(opt: &Opt) -> Result<(String, String)> {
error!(e); error!(e);
pass = rpassword::prompt_password("Password: ").context("password prompt")?; pass = rpassword::prompt_password("Password: ").context("password prompt")?;
should_store = true; should_store = true;
} },
} }
} else if let Some(pass_path) = &opt.pass_path { } else if let Some(pass_path) = &opt.pass_path {
let pw_out = Command::new("pass") let pw_out = Command::new("pass").arg("show").arg(pass_path).output().map_err(|x| {
.arg("show") if x.kind() == ErrorKind::NotFound {
.arg(pass_path) Error::new(ErrorKind::NotFound, "pass not found in $PATH!")
.output() } else {
.map_err(|x| { x
if x.kind() == ErrorKind::NotFound { }
Error::new(ErrorKind::NotFound, "pass not found in $PATH!") })?;
} else {
x
}
})?;
if !pw_out.status.success() { if !pw_out.status.success() {
return Err(Error::new( return Err(Error::new(
ErrorKind::Other, ErrorKind::Other,
format!( format!(
"`pass` failed with non-zero exit code {}: {}", "`pass` failed with non-zero exit code {}: {}",
pw_out.status.code() pw_out.status.code().expect("Failed retrieving pass exit code!"),
.expect("Failed retrieving pass exit code!"), String::from_utf8(pw_out.stderr).expect("Failed decoding stderr of pass!")
String::from_utf8(pw_out.stderr) ),
.expect("Failed decoding stderr of pass!") ))?;
)
))?
} else { } else {
pass = String::from_utf8(pw_out.stdout).map(|x| { pass = String::from_utf8(pw_out.stdout)
x.lines().next().map(|x| x.to_owned()).ok_or_else(|| anyhow!("empty pass(1) entry!")) .map(|x| {
})?.expect("utf-8 decode of `pass(1)`-output failed"); x.lines()
.next()
.map(|x| x.to_owned())
.ok_or_else(|| anyhow!("empty pass(1) entry"))
})?
.expect("utf-8 decode of `pass(1)`-output failed");
should_store = false; should_store = false;
} }
} else { } else {

View File

@ -28,8 +28,10 @@ static ALERT_DANGER: Lazy<Selector> = Lazy::new(|| Selector::parse("div.alert-da
static IL_CONTENT_CONTAINER: Lazy<Selector> = Lazy::new(|| Selector::parse("#il_center_col").unwrap()); static IL_CONTENT_CONTAINER: Lazy<Selector> = Lazy::new(|| Selector::parse("#il_center_col").unwrap());
static BLOCK_FAVORITES: Lazy<Selector> = Lazy::new(|| Selector::parse("#block_pditems_0").unwrap()); static BLOCK_FAVORITES: Lazy<Selector> = Lazy::new(|| Selector::parse("#block_pditems_0").unwrap());
static ITEM_PROP: Lazy<Selector> = Lazy::new(|| Selector::parse("span.il_ItemProperty").unwrap()); static ITEM_PROP: Lazy<Selector> = Lazy::new(|| Selector::parse("span.il_ItemProperty").unwrap());
static CONTAINER_ITEMS: Lazy<Selector> = Lazy::new(|| Selector::parse("div.il_ContainerListItem, .il-std-item").unwrap()); static CONTAINER_ITEMS: Lazy<Selector> =
static CONTAINER_ITEM_TITLE: Lazy<Selector> = Lazy::new(|| Selector::parse("a.il_ContainerItemTitle, .il-item-title > a").unwrap()); Lazy::new(|| Selector::parse("div.il_ContainerListItem, .il-std-item").unwrap());
static CONTAINER_ITEM_TITLE: Lazy<Selector> =
Lazy::new(|| Selector::parse("a.il_ContainerItemTitle, .il-item-title > a").unwrap());
pub struct ILIAS { pub struct ILIAS {
pub opt: Opt, pub opt: Opt,
@ -341,7 +343,7 @@ impl Object {
| Generic { name, .. } => &name, | Generic { name, .. } => &name,
Thread { url } => &url.thr_pk.as_ref().unwrap(), Thread { url } => &url.thr_pk.as_ref().unwrap(),
Video { url } => &url.url, Video { url } => &url.url,
Dashboard { url } => &url.url Dashboard { url } => &url.url,
} }
} }

View File

@ -1,4 +1,4 @@
use std::{path::Path, sync::Arc, collections::HashSet}; use std::{collections::HashSet, path::Path, sync::Arc};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -23,9 +23,7 @@ pub async fn download(path: &Path, ilias: Arc<ILIAS>, url: &URL) -> Result<()> {
let mut names = HashSet::new(); let mut names = HashSet::new();
for item in content.0 { for item in content.0 {
let item = item?; let item = item?;
let item_name = file_escape( let item_name = file_escape(ilias.course_names.get(item.name()).map(|x| &**x).unwrap_or(item.name()));
ilias.course_names.get(item.name()).map(|x| &**x).unwrap_or(item.name()),
);
if names.contains(&item_name) { if names.contains(&item_name) {
warning!(format => "folder {} contains duplicated folder {:?}", path.display(), item_name); warning!(format => "folder {} contains duplicated folder {:?}", path.display(), item_name);
} }

View File

@ -14,7 +14,9 @@ static LINKS: Lazy<Selector> = Lazy::new(|| Selector::parse("a").unwrap());
static A_TARGET_BLANK: Lazy<Selector> = Lazy::new(|| Selector::parse(r#"a[target="_blank"]"#).unwrap()); static A_TARGET_BLANK: Lazy<Selector> = Lazy::new(|| Selector::parse(r#"a[target="_blank"]"#).unwrap());
static VIDEO_ROWS: Lazy<Selector> = Lazy::new(|| Selector::parse(".ilTableOuter > div > table > tbody > tr").unwrap()); static VIDEO_ROWS: Lazy<Selector> = Lazy::new(|| Selector::parse(".ilTableOuter > div > table > tbody > tr").unwrap());
static TABLE_CELLS: Lazy<Selector> = Lazy::new(|| Selector::parse("td").unwrap()); static TABLE_CELLS: Lazy<Selector> = Lazy::new(|| Selector::parse("td").unwrap());
static LIST_URL: Lazy<Regex> = Lazy::new(|| Regex::new("ilias\\.php\\?ref_id=\\d+&cmdClass=xocteventgui&cmdNode=.{9}&baseClass=ilObjPluginDispatchGUI.*&cmd=asyncGetTableGUI&cmdMode=asynch").unwrap()); static LIST_URL: Lazy<Regex> = Lazy::new(|| {
Regex::new("ilias\\.php\\?ref_id=\\d+&cmdClass=xocteventgui&cmdNode=.{9}&baseClass=ilObjPluginDispatchGUI.*&cmd=asyncGetTableGUI&cmdMode=asynch").unwrap()
});
const NO_ENTRIES: &str = "Keine Einträge"; const NO_ENTRIES: &str = "Keine Einträge";

View File

@ -17,7 +17,6 @@ use std::sync::Arc;
use std::time::SystemTime; use std::time::SystemTime;
static ILIAS_URL: &str = "https://ilias.studium.kit.edu/"; static ILIAS_URL: &str = "https://ilias.studium.kit.edu/";
/// main personal desktop
static DEFAULT_SYNC_URL: &str = static DEFAULT_SYNC_URL: &str =
"https://ilias.studium.kit.edu/ilias.php?baseClass=ilDashboardGUI&cmd=jumpToMemberships"; "https://ilias.studium.kit.edu/ilias.php?baseClass=ilDashboardGUI&cmd=jumpToMemberships";
@ -161,8 +160,10 @@ async fn real_main(mut opt: Opt) -> Result<()> {
} }
let sync_url = if ilias.opt.all { let sync_url = if ilias.opt.all {
// change on ILIAS update format!(
format!("{}ilias.php?cmdClass=ilmembershipoverviewgui&cmdNode=iy&baseClass=ilmembershipoverviewgui", ILIAS_URL) "{}ilias.php?cmdClass=ilmembershipoverviewgui&baseClass=ilmembershipoverviewgui",
ILIAS_URL
)
} else { } else {
ilias.opt.sync_url.as_deref().unwrap_or(DEFAULT_SYNC_URL).to_owned() ilias.opt.sync_url.as_deref().unwrap_or(DEFAULT_SYNC_URL).to_owned()
}; };