diff --git a/src/post.rs b/src/post.rs index 1b67d03..3bf810d 100644 --- a/src/post.rs +++ b/src/post.rs @@ -72,7 +72,7 @@ async fn parse_post(json: &serde_json::Value) -> Post { let ratio: f64 = post["data"]["upvote_ratio"].as_f64().unwrap_or(1.0) * 100.0; // Determine the type of media along with the media URL - let (post_type, media) = media(&post["data"]).await; + let (post_type, media, gallery) = media(&post["data"]).await; // Build a post using data parsed from Reddit post API Post { @@ -124,6 +124,7 @@ async fn parse_post(json: &serde_json::Value) -> Post { rel_time, created, comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()), + gallery, } } diff --git a/src/utils.rs b/src/utils.rs index f834055..512784c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -46,6 +46,14 @@ pub struct Media { pub height: i64, } +pub struct GalleryMedia { + pub url: String, + pub width: i64, + pub height: i64, + pub caption: String, + pub outbound_url: String, +} + // Post containing content, metadata and media pub struct Post { pub id: String, @@ -65,6 +73,7 @@ pub struct Post { pub rel_time: String, pub created: String, pub comments: String, + pub gallery: Vec, } // Comment with content, post, score and data/time that it was posted @@ -188,8 +197,9 @@ pub fn format_num(num: i64) -> String { } } -pub async fn media(data: &Value) -> (String, Media) { +pub async fn media(data: &Value) -> (String, Media, Vec) { let post_type: &str; + let mut gallery = Vec::new(); // If post is a video, return the video let url = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() { post_type = "video"; @@ -215,6 +225,25 @@ pub async fn media(data: &Value) -> (String, Media) { } else if data["is_self"].as_bool().unwrap_or_default() { post_type = "self"; data["permalink"].as_str().unwrap_or_default().to_string() + } else if data["is_gallery"].as_bool().unwrap_or_default() { + post_type = "gallery"; + gallery = data["gallery_data"]["items"] + .as_array() + .unwrap() + .iter() + .map(|item| { + let media_id = item["media_id"].as_str().unwrap_or_default(); + let image = data["media_metadata"][media_id].as_object().unwrap(); + GalleryMedia { + url: format_url(image["s"]["u"].as_str().unwrap_or_default()), + width: image["s"]["x"].as_i64().unwrap_or_default(), + height: image["s"]["y"].as_i64().unwrap_or_default(), + caption: item["caption"].as_str().unwrap_or_default().to_string(), + outbound_url: item["outbound_url"].as_str().unwrap_or_default().to_string(), + } + }) + .collect::>(); + data["url"].as_str().unwrap_or_default().to_string() } else { post_type = "link"; data["url"].as_str().unwrap_or_default().to_string() @@ -227,6 +256,7 @@ pub async fn media(data: &Value) -> (String, Media) { width: data["preview"]["images"][0]["source"]["width"].as_i64().unwrap_or_default(), height: data["preview"]["images"][0]["source"]["height"].as_i64().unwrap_or_default(), }, + gallery, ) } @@ -323,7 +353,7 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec Result<(Vec {% else if post.post_type == "video" || post.post_type == "gif" %} + {% else if post.post_type == "gallery" %} + {% else if post.post_type == "link" %} {{ post.media.url }} {% endif %}