mirror of https://github.com/spikecodes/libreddit
Parse video data from cross_post_parent_list as vanilla Reddit does.
introduce testdata directory for testing JSON parsing functions. refactor Media::parse for slightly more readability. Add various test cases.
This commit is contained in:
parent
67d3be06e1
commit
1e9ca3cb55
|
@ -113,6 +113,9 @@ pub async fn json(path: String, quarantine: bool) -> Result<Value, String> {
|
|||
// Build Reddit url from path
|
||||
let url = format!("https://www.reddit.com{}", path);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
println!("{}", url);
|
||||
|
||||
// Closure to quickly build errors
|
||||
let err = |msg: &str, e: String| -> Result<Value, String> {
|
||||
// eprintln!("{} - {}: {}", url, msg, e);
|
||||
|
|
35
src/post.rs
35
src/post.rs
|
@ -229,3 +229,38 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
|
|||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::File;
|
||||
use super::parse_post;
|
||||
|
||||
#[tokio::test]
|
||||
async fn parse_post_works() {
|
||||
// https://www.reddit.com/r/antiwork/comments/qybiul.json?&sort=confidence&raw_json=1
|
||||
let testdata = File::open("testdata/cross_post_parent_list.json")
|
||||
.expect("error reading file");
|
||||
let post_json: serde_json::Value = serde_json::from_reader(testdata)
|
||||
.expect("error parsing JSON");
|
||||
|
||||
let post = parse_post(&post_json[0]).await;
|
||||
println!("{:?}", post.media);
|
||||
|
||||
assert_eq!(
|
||||
post.post_type,
|
||||
"video"
|
||||
);
|
||||
assert_ne!(
|
||||
post.media.url,
|
||||
""
|
||||
);
|
||||
assert_ne!(
|
||||
post.media.alt_url,
|
||||
""
|
||||
);
|
||||
assert_ne!(
|
||||
post.media.poster,
|
||||
""
|
||||
);
|
||||
}
|
||||
}
|
49
src/utils.rs
49
src/utils.rs
|
@ -73,6 +73,7 @@ pub struct Flags {
|
|||
pub stickied: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Media {
|
||||
pub url: String,
|
||||
pub alt_url: String,
|
||||
|
@ -85,28 +86,41 @@ impl Media {
|
|||
pub async fn parse(data: &Value) -> (String, Self, Vec<GalleryMedia>) {
|
||||
let mut gallery = Vec::new();
|
||||
|
||||
// Define the various known places that Reddit might put video URLs.
|
||||
let data_preview = &data["preview"]["reddit_video_preview"];
|
||||
let secure_media = &data["secure_media"]["reddit_video"];
|
||||
let crosspost_parent_media = &data["crosspost_parent_list"][0]["secure_media"]["reddit_video"];
|
||||
|
||||
// If post is a video, return the video
|
||||
let (post_type, url_val, alt_url_val) = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() {
|
||||
// Return reddit video
|
||||
let (post_type, url_val, alt_url_val) = if data_preview["fallback_url"].is_string() {
|
||||
(
|
||||
if data["preview"]["reddit_video_preview"]["is_gif"].as_bool().unwrap_or(false) {
|
||||
if data_preview["is_gif"].as_bool().unwrap_or(false) {
|
||||
"gif"
|
||||
} else {
|
||||
"video"
|
||||
},
|
||||
&data["preview"]["reddit_video_preview"]["fallback_url"],
|
||||
Some(&data["preview"]["reddit_video_preview"]["hls_url"]),
|
||||
&data_preview["fallback_url"],
|
||||
Some(&data_preview["hls_url"]),
|
||||
)
|
||||
} else if data["secure_media"]["reddit_video"]["fallback_url"].is_string() {
|
||||
// Return reddit video
|
||||
} else if secure_media["fallback_url"].is_string() {
|
||||
(
|
||||
if data["preview"]["reddit_video_preview"]["is_gif"].as_bool().unwrap_or(false) {
|
||||
if secure_media["is_gif"].as_bool().unwrap_or(false) {
|
||||
"gif"
|
||||
} else {
|
||||
"video"
|
||||
},
|
||||
&data["secure_media"]["reddit_video"]["fallback_url"],
|
||||
Some(&data["secure_media"]["reddit_video"]["hls_url"]),
|
||||
&secure_media["fallback_url"],
|
||||
Some(&secure_media["hls_url"]),
|
||||
)
|
||||
} else if crosspost_parent_media["fallback_url"].is_string() {
|
||||
(
|
||||
if crosspost_parent_media["is_gif"].as_bool().unwrap_or(false) {
|
||||
"gif"
|
||||
} else {
|
||||
"video"
|
||||
},
|
||||
&crosspost_parent_media["fallback_url"],
|
||||
Some(&crosspost_parent_media["hls_url"]),
|
||||
)
|
||||
} else if data["post_hint"].as_str().unwrap_or("") == "image" {
|
||||
// Handle images, whether GIFs or pics
|
||||
|
@ -512,7 +526,7 @@ pub fn format_url(url: &str) -> String {
|
|||
|
||||
match domain {
|
||||
"v.redd.it" => chain!(
|
||||
capture(r"https://v\.redd\.it/(.*)/DASH_([0-9]{2,4}(\.mp4|$))", "/vid/", 2),
|
||||
capture(r"https://v\.redd\.it/(.*)/DASH_([0-9]{2,4}(\.mp4|$|\?source=fallback))", "/vid/", 2),
|
||||
capture(r"https://v\.redd\.it/(.+)/(HLSPlaylist\.m3u8.*)$", "/hls/", 2)
|
||||
),
|
||||
"i.redd.it" => capture(r"https://i\.redd\.it/(.*)", "/img/", 1),
|
||||
|
@ -634,6 +648,7 @@ pub async fn error(req: Request<Body>, msg: String) -> Result<Response<Body>, St
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::format_num;
|
||||
use super::format_url;
|
||||
|
||||
#[test]
|
||||
fn format_num_works() {
|
||||
|
@ -658,4 +673,16 @@ mod tests {
|
|||
("2.0m".to_string(), "1999999".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_url_works() {
|
||||
assert_eq!(
|
||||
format_url("https://v.redd.it/test123/DASH_480?source=fallback"),
|
||||
"/vid/test123/480?source=fallback"
|
||||
);
|
||||
assert_eq!(
|
||||
format_url("https://v.redd.it/test123/DASH_720.mp4?source=fallback"),
|
||||
"/vid/test123/720.mp4"
|
||||
);
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue