mirror of
https://github.com/FliegendeWurst/KIT-ILIAS-downloader.git
synced 2024-08-28 04:04:18 +00:00
parent
07dc3a9be2
commit
cc7dcd6f9d
@ -4,14 +4,13 @@ use std::{collections::HashMap, error::Error as _, io::Write, sync::Arc};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use cookie_store::CookieStore;
|
||||
use ignore::gitignore::Gitignore;
|
||||
use once_cell::sync::Lazy;
|
||||
use reqwest::{Client, IntoUrl, Proxy, Url};
|
||||
use reqwest_cookie_store::CookieStoreMutex;
|
||||
use scraper::{ElementRef, Html, Selector};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{cli::Opt, queue, util::wrap_html, ILIAS_URL};
|
||||
use crate::{cli::Opt, queue, util::wrap_html, ILIAS_URL, iliasignore::IliasIgnore};
|
||||
|
||||
pub mod course;
|
||||
pub mod exercise;
|
||||
@ -35,7 +34,7 @@ static CONTAINER_ITEM_TITLE: Lazy<Selector> =
|
||||
|
||||
pub struct ILIAS {
|
||||
pub opt: Opt,
|
||||
pub ignore: Gitignore,
|
||||
pub ignore: IliasIgnore,
|
||||
client: Client,
|
||||
cookies: Arc<CookieStoreMutex>,
|
||||
pub course_names: HashMap<String, String>,
|
||||
@ -61,7 +60,7 @@ impl ILIAS {
|
||||
pub async fn with_session(
|
||||
opt: Opt,
|
||||
session: Arc<CookieStoreMutex>,
|
||||
ignore: Gitignore,
|
||||
ignore: IliasIgnore,
|
||||
course_names: HashMap<String, String>,
|
||||
) -> Result<Self> {
|
||||
let mut builder = Client::builder()
|
||||
@ -88,7 +87,7 @@ impl ILIAS {
|
||||
opt: Opt,
|
||||
user: &str,
|
||||
pass: &str,
|
||||
ignore: Gitignore,
|
||||
ignore: IliasIgnore,
|
||||
course_names: HashMap<String, String>,
|
||||
) -> Result<Self> {
|
||||
let cookie_store = CookieStore::default();
|
||||
|
66
src/iliasignore.rs
Normal file
66
src/iliasignore.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use std::{path::{Path, PathBuf, Component}, ffi::OsString};
|
||||
|
||||
use anyhow::Result;
|
||||
use ignore::gitignore::Gitignore;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IliasIgnore {
|
||||
ignores: Vec<IgnoreFile>
|
||||
}
|
||||
|
||||
impl IliasIgnore {
|
||||
pub fn load(mut path: PathBuf) -> Result<Self> {
|
||||
let mut ignores = Vec::new();
|
||||
let mut prefix = Vec::new();
|
||||
// example scenario:
|
||||
// path = /KIT/ILIAS/SS 23/Next Generation Internet
|
||||
// iliasignore in ILIAS/.iliasignore: prefix = SS 23/Next Generation Internet
|
||||
// iliasignore in Next Generation Internet/.iliasignore: prefix = ""
|
||||
loop {
|
||||
let (ignore, error) = Gitignore::new(path.join(".iliasignore"));
|
||||
if let Some(err) = error {
|
||||
warning!(err);
|
||||
}
|
||||
if ignore.len() > 0 {
|
||||
ignores.push(IgnoreFile {
|
||||
ignore,
|
||||
prefix: prefix.iter().fold(OsString::new(), |mut acc, el| {
|
||||
acc.push(el);
|
||||
acc.push("/");
|
||||
acc
|
||||
})
|
||||
});
|
||||
}
|
||||
if let Some(last) = path.components().last() {
|
||||
match last {
|
||||
Component::Normal(name) => prefix.insert(0, name.to_owned()),
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
path.pop();
|
||||
}
|
||||
Ok(IliasIgnore {
|
||||
ignores
|
||||
})
|
||||
}
|
||||
|
||||
pub fn should_ignore(&self, path: &Path, is_dir: bool) -> bool {
|
||||
for ignore_file in &self.ignores {
|
||||
let mut full_path = ignore_file.prefix.clone();
|
||||
full_path.push(path.as_os_str());
|
||||
let matched = ignore_file.ignore.matched(&full_path, is_dir);
|
||||
if matched.is_whitelist() {
|
||||
return false;
|
||||
} else if matched.is_ignore() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct IgnoreFile {
|
||||
ignore: Gitignore,
|
||||
prefix: OsString
|
||||
}
|
14
src/main.rs
14
src/main.rs
@ -25,6 +25,8 @@ mod cli;
|
||||
use cli::*;
|
||||
mod ilias;
|
||||
use ilias::*;
|
||||
mod iliasignore;
|
||||
use iliasignore::*;
|
||||
use Object::*;
|
||||
mod queue;
|
||||
mod util;
|
||||
@ -38,7 +40,7 @@ async fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
async fn try_to_load_session(opt: Opt, ignore: Gitignore, course_names: HashMap<String, String>) -> Result<ILIAS> {
|
||||
async fn try_to_load_session(opt: Opt, ignore: IliasIgnore, course_names: HashMap<String, String>) -> Result<ILIAS> {
|
||||
let session_path = opt.output.join(".iliassession");
|
||||
let meta = tokio::fs::metadata(&session_path).await?;
|
||||
let modified = meta.modified()?;
|
||||
@ -58,7 +60,7 @@ async fn try_to_load_session(opt: Opt, ignore: Gitignore, course_names: HashMap<
|
||||
}
|
||||
}
|
||||
|
||||
async fn login(opt: Opt, ignore: Gitignore, course_names: HashMap<String, String>) -> Result<ILIAS> {
|
||||
async fn login(opt: Opt, ignore: IliasIgnore, course_names: HashMap<String, String>) -> Result<ILIAS> {
|
||||
// load .iliassession file
|
||||
if opt.keep_session {
|
||||
match try_to_load_session(opt.clone(), ignore.clone(), course_names.clone())
|
||||
@ -117,7 +119,7 @@ async fn real_main(mut opt: Opt) -> Result<()> {
|
||||
.context("failed to canonicalize output directory")?;
|
||||
|
||||
// load .iliasignore file
|
||||
let (ignore, error) = Gitignore::new(opt.output.join(".iliasignore"));
|
||||
let ignore = IliasIgnore::load(opt.output.clone())?;
|
||||
|
||||
// Load course_names.toml file
|
||||
let course_names_path = opt.output.join("course_names.toml");
|
||||
@ -134,10 +136,6 @@ async fn real_main(mut opt: Opt) -> Result<()> {
|
||||
HashMap::new()
|
||||
};
|
||||
|
||||
if let Some(err) = error {
|
||||
warning!(err);
|
||||
}
|
||||
|
||||
queue::set_download_rate(opt.rate);
|
||||
|
||||
let ilias = login(opt, ignore, course_names).await?;
|
||||
@ -235,7 +233,7 @@ async fn process(ilias: Arc<ILIAS>, path: PathBuf, obj: Object) -> Result<()> {
|
||||
}
|
||||
}
|
||||
// root path should not be matched
|
||||
if relative_path.parent().is_some() && ilias.ignore.matched(relative_path, obj.is_dir()).is_ignore() {
|
||||
if relative_path.parent().is_some() && ilias.ignore.should_ignore(relative_path, obj.is_dir()) {
|
||||
log!(1, "Ignored {}", relative_path.to_string_lossy());
|
||||
return Ok(());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user