Reformat...
This commit is contained in:
57
src/main.rs
57
src/main.rs
@@ -51,36 +51,42 @@ enum DownloadError {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("TumMediasiteDownloader")
|
let matches = App::new("TumMediasiteDownloader")
|
||||||
.author("Boris-Chengbiao Zhou <bobo1239@web.de>")
|
.author("Boris-Chengbiao Zhou <bobo1239@web.de>")
|
||||||
.about("Downloads \'catalogs\' from the TUM's Mediasite lecture archive.")
|
.about(
|
||||||
|
"Downloads \'catalogs\' from the TUM's Mediasite lecture archive.",
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("CATALOG_NAME")
|
Arg::with_name("CATALOG_NAME")
|
||||||
.help(
|
.help(
|
||||||
"name of the catalog e.g. from the URL:\n\
|
"name of the catalog e.g. from the URL:\n\
|
||||||
https://streams.tum.de/Mediasite/Catalog/catalogs/era-2016 -> era-2016\n\
|
https://streams.tum.de/Mediasite/Catalog/catalogs/era-2016 -> era-2016\n\
|
||||||
special cases (WS16/17; login included): DS, EIDI, ERA, ..."
|
special cases (WS16/17; login included): DS, EIDI, ERA, ...",
|
||||||
)
|
)
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(1)
|
.index(1),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("OUTPUT_DIRECTORY")
|
Arg::with_name("OUTPUT_DIRECTORY")
|
||||||
.help("where to output the downloaded files")
|
.help("where to output the downloaded files")
|
||||||
.required(true)
|
.required(true)
|
||||||
.index(2)
|
.index(2),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("username")
|
Arg::with_name("username")
|
||||||
.short("u")
|
.short("u")
|
||||||
.help("username for login; can be omitted if the user from .env should be used")
|
.help(
|
||||||
|
"username for login; can be omitted if the user from .env should be used",
|
||||||
|
)
|
||||||
.requires("password")
|
.requires("password")
|
||||||
.takes_value(true)
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("password")
|
Arg::with_name("password")
|
||||||
.short("p")
|
.short("p")
|
||||||
.help("password for login; can be omitted if the user from .env should be used")
|
.help(
|
||||||
|
"password for login; can be omitted if the user from .env should be used",
|
||||||
|
)
|
||||||
.requires("username")
|
.requires("username")
|
||||||
.takes_value(true)
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
@@ -153,8 +159,8 @@ fn get_auth() {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
let set_cookie: &SetCookie = res.headers().get().unwrap();
|
let set_cookie: &SetCookie = res.headers().get().unwrap();
|
||||||
let cookie = cookie::Cookie::parse(set_cookie.0[0].to_string())
|
let cookie =
|
||||||
.expect("Failed to parse SetCookie");
|
cookie::Cookie::parse(set_cookie.0[0].to_string()).expect("Failed to parse SetCookie");
|
||||||
assert_eq!(cookie.name(), "MediasiteAuth");
|
assert_eq!(cookie.name(), "MediasiteAuth");
|
||||||
|
|
||||||
let mut auth = AUTH.lock().unwrap();
|
let mut auth = AUTH.lock().unwrap();
|
||||||
@@ -202,11 +208,10 @@ fn get_catalog_id(name: &str) -> String {
|
|||||||
let body = read_response_body(&mut res);
|
let body = read_response_body(&mut res);
|
||||||
|
|
||||||
let prefix = "CatalogId: '";
|
let prefix = "CatalogId: '";
|
||||||
let idx = body.find(prefix)
|
let idx = body.find(prefix).expect(
|
||||||
.expect(
|
"Failed to find CatalogId on the catalog page! Perhaps you got the wrong catalog \
|
||||||
"Failed to find CatalogId on the catalog page! Perhaps you got the wrong catalog \
|
name or an invalid login? Maybe you need to open the page in a browser once...",
|
||||||
name or an invalid login? Maybe you need to open the page in a browser once..."
|
);
|
||||||
);
|
|
||||||
let pre_len = prefix.len();
|
let pre_len = prefix.len();
|
||||||
// Assuming all catalog ids follow this pattern!
|
// Assuming all catalog ids follow this pattern!
|
||||||
let len = "a6fca0c1-0be4-4e66-83b7-bcdc4eb5e95e".len();
|
let len = "a6fca0c1-0be4-4e66-83b7-bcdc4eb5e95e".len();
|
||||||
@@ -234,14 +239,14 @@ fn get_json(catalog_id: &str) -> String {
|
|||||||
data.insert("CurrentFolderId", catalog_id);
|
data.insert("CurrentFolderId", catalog_id);
|
||||||
data.insert("ItemsPerPage", "500");
|
data.insert("ItemsPerPage", "500");
|
||||||
|
|
||||||
let mut res = try_to_get_response(
|
let mut res = try_to_get_response(|client| {
|
||||||
|client| {
|
client
|
||||||
client
|
.post(
|
||||||
.post("https://streams.tum.de/Mediasite/Catalog/Data/GetPresentationsForFolder")
|
"https://streams.tum.de/Mediasite/Catalog/Data/GetPresentationsForFolder",
|
||||||
.header(construct_cookie())
|
)
|
||||||
.json(&data)
|
.header(construct_cookie())
|
||||||
}
|
.json(&data)
|
||||||
);
|
});
|
||||||
read_response_body(&mut res)
|
read_response_body(&mut res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +282,8 @@ where
|
|||||||
|
|
||||||
fn read_response_body(response: &mut Response) -> String {
|
fn read_response_body(response: &mut Response) -> String {
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
response
|
response.read_to_string(&mut string).expect(
|
||||||
.read_to_string(&mut string)
|
"Failed to read body",
|
||||||
.expect("Failed to read body");
|
);
|
||||||
string
|
string
|
||||||
}
|
}
|
||||||
|
@@ -71,10 +71,9 @@ impl Presentation {
|
|||||||
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(
|
name = Some(String::from_utf8(vec.to_vec()).expect(
|
||||||
String::from_utf8(vec.to_vec())
|
"Suggested filename isn't valid UTF-8!",
|
||||||
.expect("Suggested filename isn't valid UTF-8!")
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
@@ -105,15 +104,13 @@ impl Presentation {
|
|||||||
|
|
||||||
let url = "https://streams.tum.de/Mediasite/PlayerService/\
|
let url = "https://streams.tum.de/Mediasite/PlayerService/\
|
||||||
PlayerService.svc/json/GetPlayerOptions";
|
PlayerService.svc/json/GetPlayerOptions";
|
||||||
let mut res = try_to_get_response(
|
let mut res = try_to_get_response(|client| {
|
||||||
|client| {
|
client
|
||||||
client
|
.post(url)
|
||||||
.post(url)
|
.header(construct_cookie())
|
||||||
.header(construct_cookie())
|
.header(ContentType::json())
|
||||||
.header(ContentType::json())
|
.body(&*payload)
|
||||||
.body(&*payload)
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let json_text = read_response_body(&mut res);
|
let json_text = read_response_body(&mut res);
|
||||||
if json_text.contains("You are not authorized to view the requested content") {
|
if json_text.contains("You are not authorized to view the requested content") {
|
||||||
@@ -130,11 +127,10 @@ impl Presentation {
|
|||||||
vec
|
vec
|
||||||
};
|
};
|
||||||
for (i, download_url) in videos.iter().enumerate() {
|
for (i, download_url) in videos.iter().enumerate() {
|
||||||
let mut response =
|
let mut response = try_to_get_valid_response(
|
||||||
try_to_get_valid_response(
|
|client| client.get(download_url).header(construct_cookie()),
|
||||||
|client| client.get(download_url).header(construct_cookie()),
|
|resp| resp.status() == &StatusCode::Ok,
|
||||||
|resp| resp.status() == &StatusCode::Ok,
|
);
|
||||||
);
|
|
||||||
// TODO: Support formats besides mp4
|
// TODO: Support formats besides mp4
|
||||||
// extract extension from url or somewehre else...
|
// extract extension from url or somewehre else...
|
||||||
let filename = format!("{} - {}.mp4", fix_filename(self.name()), i + 1);
|
let filename = format!("{} - {}.mp4", fix_filename(self.name()), i + 1);
|
||||||
@@ -159,10 +155,9 @@ impl<'a> From<&'a JsonValue> for Presentation {
|
|||||||
if json["DownloadUrls"].len() >= 1 {
|
if json["DownloadUrls"].len() >= 1 {
|
||||||
assert_eq!(json["DownloadUrls"].len(), 1);
|
assert_eq!(json["DownloadUrls"].len(), 1);
|
||||||
Presentation::PublishToGo {
|
Presentation::PublishToGo {
|
||||||
name: json["Name"]
|
name: json["Name"].clone().take_string().expect(
|
||||||
.clone()
|
"json: Presentation didn't contain a \"Name\"!",
|
||||||
.take_string()
|
),
|
||||||
.expect("json: Presentation didn't contain a \"Name\"!"),
|
|
||||||
download_url: json["DownloadUrls"][0]["Url"]
|
download_url: json["DownloadUrls"][0]["Url"]
|
||||||
.clone()
|
.clone()
|
||||||
.take_string()
|
.take_string()
|
||||||
@@ -177,10 +172,9 @@ impl<'a> From<&'a JsonValue> for Presentation {
|
|||||||
let index_start_resource = index - "cdf23465581b45aa92d588ebd59619d91d".len();
|
let index_start_resource = index - "cdf23465581b45aa92d588ebd59619d91d".len();
|
||||||
|
|
||||||
Presentation::VideoOnDemand {
|
Presentation::VideoOnDemand {
|
||||||
name: json["Name"]
|
name: json["Name"].clone().take_string().expect(
|
||||||
.clone()
|
"json: Presentation didn't contain a \"Name\"!",
|
||||||
.take_string()
|
),
|
||||||
.expect("json: Presentation didn't contain a \"Name\"!"),
|
|
||||||
query_string: player_url[index..index_end_query].to_string(),
|
query_string: player_url[index..index_end_query].to_string(),
|
||||||
resource_id: player_url[index_start_resource..index].to_string(),
|
resource_id: player_url[index_start_resource..index].to_string(),
|
||||||
}
|
}
|
||||||
@@ -206,8 +200,9 @@ fn download_to_file(response: &mut Response, path: &Path) -> Result<(), io::Erro
|
|||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
file.write_all(&buf[0..len])
|
file.write_all(&buf[0..len]).expect(
|
||||||
.expect("Failed writing into the file!");
|
"Failed writing into the file!",
|
||||||
|
);
|
||||||
done += len;
|
done += len;
|
||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
@@ -217,9 +212,9 @@ fn download_to_file(response: &mut Response, path: &Path) -> Result<(), io::Erro
|
|||||||
2,
|
2,
|
||||||
done as f64 * 1000.0 / update_duration_millis as f64 / 1024.0
|
done as f64 * 1000.0 / update_duration_millis as f64 / 1024.0
|
||||||
);
|
);
|
||||||
::std::io::stdout()
|
::std::io::stdout().flush().expect(
|
||||||
.flush()
|
"Failed flushing the terminal!",
|
||||||
.expect("Failed flushing the terminal!");
|
);
|
||||||
last = now;
|
last = now;
|
||||||
done = 0;
|
done = 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user