Skip to content

Commit

Permalink
feat: respect .iliasignore files in parent folder
Browse files Browse the repository at this point in the history
see #38
  • Loading branch information
FliegendeWurst committed Nov 23, 2022
1 parent 07dc3a9 commit cc7dcd6
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 13 deletions.
9 changes: 4 additions & 5 deletions src/ilias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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>,
Expand All @@ -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()
Expand All @@ -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();
Expand Down
66 changes: 66 additions & 0 deletions src/iliasignore.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 6 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ mod cli;
use cli::*;
mod ilias;
use ilias::*;
mod iliasignore;
use iliasignore::*;
use Object::*;
mod queue;
mod util;
Expand All @@ -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()?;
Expand All @@ -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())
Expand Down Expand Up @@ -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");
Expand All @@ -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?;
Expand Down Expand Up @@ -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(());
}
Expand Down

0 comments on commit cc7dcd6

Please sign in to comment.