Retry the start of the download if failing

This commit is contained in:
2017-03-02 17:41:18 +01:00
parent 0c529187a9
commit dab3e94027

View File

@@ -14,7 +14,7 @@ use std::collections::HashMap;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use json::JsonValue; use json::JsonValue;
use reqwest::{Client, RedirectPolicy}; use reqwest::{Client, Response, RedirectPolicy};
use reqwest::header::{Cookie, Charset, SetCookie}; use reqwest::header::{Cookie, Charset, SetCookie};
use reqwest::header::{ContentDisposition, DispositionType, DispositionParam}; use reqwest::header::{ContentDisposition, DispositionType, DispositionParam};
use zip::ZipArchive; use zip::ZipArchive;
@@ -34,6 +34,8 @@ mod catalogs {
// TODO: use clap for proper CLI // TODO: use clap for proper CLI
// TODO: clippy // TODO: clippy
// TODO: replace unwraps with descriptive expects
// TODO: retry some things if sensible
lazy_static! { lazy_static! {
static ref CLIENT: Client = { static ref CLIENT: Client = {
@@ -126,8 +128,11 @@ fn download_catalog(catalog_name: &str, out_dir: &Path, auth: &str) {
presentations.len()); presentations.len());
for (i, presentation) in presentations.iter().enumerate() { for (i, presentation) in presentations.iter().enumerate() {
println!("Downloading {}/{}: {}", i + 1, presentations.len(), presentation.name); println!("Downloading {}/{}: {}",
download_presentation(&presentation, out_dir, auth); i + 1,
presentations.len(),
presentation.name);
download_presentation(presentation, out_dir, auth);
} }
} }
@@ -151,26 +156,46 @@ fn get_catalog_id(name: &str, auth: &str) -> String {
} }
fn download_presentation(presentation: &Presentation, out_dir: &Path, auth: &str) { fn download_presentation(presentation: &Presentation, out_dir: &Path, auth: &str) {
let response = CLIENT.get(&presentation.download_url) fn try_download(presentation: &Presentation, auth: &str) -> Option<(Response, String)> {
.header(construct_cookie(auth)) let response = CLIENT.get(&presentation.download_url)
.send() .header(construct_cookie(auth))
.unwrap(); .send()
.unwrap();
let filename = { let filename = if let Some(content_disposition) =
let content_disposition: &ContentDisposition = response.headers().get().unwrap(); response.headers().get::<ContentDisposition>() {
assert_eq!(content_disposition.disposition, DispositionType::Attachment); assert_eq!(content_disposition.disposition, DispositionType::Attachment);
let mut name = None; let mut name = None;
for param in &content_disposition.parameters { for param in &content_disposition.parameters {
match *param { match *param {
DispositionParam::Filename(ref charset, _, ref vec) => { DispositionParam::Filename(ref charset, _, ref vec) => {
assert_eq!(&Charset::Ext("UTF-8".to_string()), charset); assert_eq!(&Charset::Ext("UTF-8".to_string()), charset);
name = Some(String::from_utf8(vec.to_vec()).unwrap()); name = Some(String::from_utf8(vec.to_vec()).unwrap());
}
_ => continue,
} }
_ => continue,
} }
name.expect("Missing filename in ContentDisposition!")
} else {
return None;
};
Some((response, filename))
}
let mut tries = 0;
let mut tuple = None;
while tries < 8 {
let try = try_download(presentation, auth);
if try.is_some() {
tuple = try;
} }
name.expect("Missing filename in ContentDisposition!") tries += 1;
}; }
if tuple.is_none() {
panic!("Failed to get a proper response while trying to download presentation!");
}
let (response, filename) = tuple.unwrap();
let mut path = PathBuf::from(out_dir); let mut path = PathBuf::from(out_dir);
path.push(fix_filename(&filename)); path.push(fix_filename(&filename));