Utility function to create a directory

This commit is contained in:
FliegendeWurst 2020-05-11 17:17:13 +02:00
parent 9a88edf297
commit dfdd6829fc
2 changed files with 24 additions and 41 deletions

View File

@ -8,12 +8,12 @@ use reqwest::Client;
use scraper::{ElementRef, Html, Selector}; use scraper::{ElementRef, Html, Selector};
use serde_json::json; use serde_json::json;
use structopt::StructOpt; use structopt::StructOpt;
use tokio::fs;
use tokio::io::stream_reader; use tokio::io::stream_reader;
use tokio::task; use tokio::task;
use url::Url; use url::Url;
use std::default::Default; use std::default::Default;
use std::fs;
use std::future::Future; use std::future::Future;
use std::io; use std::io;
use std::panic; use std::panic;
@ -160,11 +160,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
log!(2, " URL: {}", obj.url().url); log!(2, " URL: {}", obj.url().url);
match &obj { match &obj {
Course { url, name } => { Course { url, name } => {
if let Err(e) = fs::create_dir(&path) { create_dir(&path).await?;
if e.kind() != io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
let content = if ilias.opt.content_tree { let content = if ilias.opt.content_tree {
let html = ilias.download(&url.url).await?.text().await?; let html = ilias.download(&url.url).await?.text().await?;
let cmd_node = cmd_node_regex.find(&html).context("can't find cmdNode")?.as_str()[8..].to_owned(); let cmd_node = cmd_node_regex.find(&html).context("can't find cmdNode")?.as_str()[8..].to_owned();
@ -194,11 +190,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
} }
}, },
Folder { url, .. } => { Folder { url, .. } => {
if let Err(e) = fs::create_dir(&path) { create_dir(&path).await?;
if e.kind() != io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
let content = ilias.get_course_content(&url).await?; let content = ilias.get_course_content(&url).await?;
for item in content { for item in content {
if item.is_err() { if item.is_err() {
@ -218,7 +210,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
if ilias.opt.skip_files { if ilias.opt.skip_files {
return Ok(()); return Ok(());
} }
if !ilias.opt.force && fs::metadata(&path).is_ok() { if !ilias.opt.force && fs::metadata(&path).await.is_ok() {
log!(2, "Skipping download, file exists already"); log!(2, "Skipping download, file exists already");
return Ok(()); return Ok(());
} }
@ -233,11 +225,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
if ilias.opt.no_videos { if ilias.opt.no_videos {
return Ok(()); return Ok(());
} }
if let Err(e) = fs::create_dir(&path) { create_dir(&path).await?;
if e.kind() != io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
let list_url = format!("{}ilias.php?ref_id={}&cmdClass=xocteventgui&cmdNode=n7:mz:14p&baseClass=ilObjPluginDispatchGUI&lang=de&limit=20&cmd=asyncGetTableGUI&cmdMode=asynch", ILIAS_URL, url.ref_id); let list_url = format!("{}ilias.php?ref_id={}&cmdClass=xocteventgui&cmdNode=n7:mz:14p&baseClass=ilObjPluginDispatchGUI&lang=de&limit=20&cmd=asyncGetTableGUI&cmdMode=asynch", ILIAS_URL, url.ref_id);
let data = ilias.download(&list_url); let data = ilias.download(&list_url);
let html = data.await?.text().await?; let html = data.await?.text().await?;
@ -293,7 +281,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
.map(|x| x.as_str()) .map(|x| x.as_str())
.ok_or(anyhow!("video src not found"))? .ok_or(anyhow!("video src not found"))?
.ok_or(anyhow!("video src not string"))?; .ok_or(anyhow!("video src not string"))?;
if let Ok(meta) = fs::metadata(&path) { if let Ok(meta) = fs::metadata(&path).await {
let head = ilias.client.head(url).send().await.context("HEAD request failed")?; let head = ilias.client.head(url).send().await.context("HEAD request failed")?;
if let Some(len) = head.headers().get("content-length") { if let Some(len) = head.headers().get("content-length") {
if meta.len() != len.to_str()?.parse::<u64>()? { if meta.len() != len.to_str()?.parse::<u64>()? {
@ -316,11 +304,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
if !ilias.opt.forum { if !ilias.opt.forum {
return Ok(()); return Ok(());
} }
if let Err(e) = fs::create_dir(&path) { create_dir(&path).await?;
if e.kind() != io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
let url = format!("{}ilias.php?ref_id={}&cmd=showThreads&cmdClass=ilrepositorygui&cmdNode=uf&baseClass=ilrepositorygui", ILIAS_URL, url.ref_id); let url = format!("{}ilias.php?ref_id={}&cmd=showThreads&cmdClass=ilrepositorygui&cmdNode=uf&baseClass=ilrepositorygui", ILIAS_URL, url.ref_id);
let html = { let html = {
let data = ilias.download(&url); let data = ilias.download(&url);
@ -355,7 +339,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
path.push(name); path.push(name);
// TODO: set modification date? // TODO: set modification date?
let saved_posts = { let saved_posts = {
match fs::read_dir(&path) { match std::fs::read_dir(&path) { // TODO: make this async
Ok(stream) => stream.count(), Ok(stream) => stream.count(),
Err(_) => 0 Err(_) => 0
} }
@ -378,11 +362,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
if !ilias.opt.forum { if !ilias.opt.forum {
return Ok(()); return Ok(());
} }
if let Err(e) = fs::create_dir(&path) { create_dir(&path).await?;
if e.kind() != io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
let html = ilias.get_html(&url.url).await?; let html = ilias.get_html(&url.url).await?;
for post in html.select(&post_row) { for post in html.select(&post_row) {
let title = post.select(&post_title).next().ok_or(anyhow!("post title not found"))?.text().collect::<String>().replace('/', "-"); let title = post.select(&post_title).next().ok_or(anyhow!("post title not found"))?.text().collect::<String>().replace('/', "-");
@ -423,11 +403,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
} }
}, },
ExerciseHandler { url, .. } => { ExerciseHandler { url, .. } => {
if let Err(e) = fs::create_dir(&path) { create_dir(&path).await?;
if e.kind() != io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
let html = ilias.get_html(&url.url).await?; let html = ilias.get_html(&url.url).await?;
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();
@ -457,7 +433,7 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
} }
}, },
Weblink { url, .. } => { Weblink { url, .. } => {
if !ilias.opt.force && fs::metadata(&path).is_ok() { if !ilias.opt.force && fs::metadata(&path).await.is_ok() {
log!(2, "Skipping download, link exists already"); log!(2, "Skipping download, link exists already");
return Ok(()); return Ok(());
} }
@ -465,11 +441,8 @@ fn process(ilias: Arc<ILIAS>, mut path: PathBuf, obj: Object) -> impl Future<Out
let url = head.url().as_str(); let url = head.url().as_str();
if url.starts_with(ILIAS_URL) { if url.starts_with(ILIAS_URL) {
// is a link list // is a link list
if let Err(e) = fs::create_dir(&path) { if !fs::metadata(&path).await.is_ok() {
if e.kind() != io::ErrorKind::AlreadyExists { create_dir(&path).await?;
Err(e)?;
}
} else {
log!(0, "Writing {}", relative_path.to_string_lossy()); log!(0, "Writing {}", relative_path.to_string_lossy());
} }

View File

@ -12,4 +12,14 @@ where R: AsyncRead + Unpin {
let mut file = BufWriter::new(file); let mut file = BufWriter::new(file);
tokio::io::copy(data, &mut file).await.context("failed to write to file")?; tokio::io::copy(data, &mut file).await.context("failed to write to file")?;
Ok(()) Ok(())
} }
/// Create a directory. Does not error if the directory already exists.
pub async fn create_dir(path: &Path) -> Result<()> {
if let Err(e) = tokio::fs::create_dir(&path).await {
if e.kind() != tokio::io::ErrorKind::AlreadyExists {
Err(e)?;
}
}
Ok(())
}