Handle duplicate file names in exercises

This commit is contained in:
FliegendeWurst 2020-12-16 08:32:47 +01:00
parent 72f7842336
commit d557efef6b

View File

@ -15,7 +15,7 @@ use tokio::io::stream_reader;
use tokio::task::{self, JoinHandle}; use tokio::task::{self, JoinHandle};
use url::Url; use url::Url;
use std::default::Default; use std::{collections::HashSet, default::Default};
use std::future::Future; use std::future::Future;
use std::io; use std::io;
use std::panic; use std::panic;
@ -465,6 +465,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
ExerciseHandler { url, .. } => { ExerciseHandler { url, .. } => {
create_dir(&path).await?; create_dir(&path).await?;
let html = ilias.get_html(&url.url).await?; let html = ilias.get_html(&url.url).await?;
let mut filenames = HashSet::new();
for row in html.select(&form_group) { for row in html.select(&form_group) {
let link = row.select(&a).next(); let link = row.select(&a).next();
if link.is_none() { if link.is_none() {
@ -485,7 +486,23 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
let name = row.select(&form_name).next().context("link without file name")?.text().collect::<String>().trim().to_owned(); let name = row.select(&form_name).next().context("link without file name")?.text().collect::<String>().trim().to_owned();
let item = File { url, name }; let item = File { url, name };
let mut path = path.clone(); let mut path = path.clone();
path.push(file_escape(item.name())); // handle files with the same name
let filename = file_escape(item.name());
let mut parts = filename.rsplitn(2, '.');
let extension = parts.next().unwrap_or(&filename);
let name = parts.next().unwrap_or("");
let mut unique_filename = filename.clone();
let mut i = 1;
while filenames.contains(&unique_filename) {
i += 1;
if name != "" {
unique_filename = format!("{}{}.{}", name, i, extension);
} else {
unique_filename = format!("{}{}", extension, i);
}
}
filenames.insert(unique_filename.clone());
path.push(unique_filename);
let ilias = Arc::clone(&ilias); let ilias = Arc::clone(&ilias);
spawn!(process_gracefully(ilias, path, item)); spawn!(process_gracefully(ilias, path, item));
} }