From 8673dd78666e6ca5d424b22f7859d7db24b33724 Mon Sep 17 00:00:00 2001 From: VC Date: Wed, 17 Aug 2022 11:49:41 +0200 Subject: [PATCH] feat: adapt to rust 1.63 --- Cargo.lock | 3 +- Cargo.toml | 3 +- src/twitter.rs | 148 ++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 132 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bcaf49f..fb86c74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2016,7 +2016,7 @@ dependencies = [ [[package]] name = "scootaloo" -version = "0.6.0" +version = "0.6.1" dependencies = [ "chrono", "clap", @@ -2025,6 +2025,7 @@ dependencies = [ "futures 0.3.14", "html-escape", "log", + "mime", "reqwest 0.11.3", "rusqlite", "serde", diff --git a/Cargo.toml b/Cargo.toml index 07bba49..077e763 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scootaloo" -version = "0.6.0" +version = "0.6.1" authors = ["VC "] edition = "2021" @@ -20,6 +20,7 @@ html-escape = "^0.2" reqwest = "^0.11" log = "^0.4" simple_logger = "^2.1" +mime = "^0.3" [profile.release] strip = true diff --git a/src/twitter.rs b/src/twitter.rs index cf530ca..7a5733b 100644 --- a/src/twitter.rs +++ b/src/twitter.rs @@ -50,29 +50,137 @@ pub async fn get_user_timeline( /// Retrieves a single media from a tweet and store it in a temporary file pub async fn get_tweet_media(m: &MediaEntity, t: &str) -> Result> { match m.media_type { - MediaType::Photo => { - return cache_media(&m.media_url_https, t).await; - } + MediaType::Photo => cache_media(&m.media_url_https, t).await, _ => match &m.video_info { - Some(v) => { - for variant in &v.variants { - if variant.content_type == "video/mp4" { - return cache_media(&variant.url, t).await; - } - } - return Err(ScootalooError::new(&format!( + Some(v) => match &v.variants.iter().find(|&x| x.content_type == "video/mp4") { + Some(u) => cache_media(&u.url, t).await, + None => Err(ScootalooError::new(&format!( "Media Type for {} is video but no mp4 file URL is available", &m.url )) - .into()); - } - None => { - return Err(ScootalooError::new(&format!( - "Media Type for {} is video but does not contain any video_info", - &m.url - )) - .into()); - } + .into()), + }, + None => Err(ScootalooError::new(&format!( + "Media Type for {} is video but does not contain any video_info", + &m.url + )) + .into()), }, - }; + } +} + +#[cfg(test)] +mod tests { + use super::*; + use egg_mode::entities::{ + MediaSize, MediaSizes, + MediaType::{Gif, Photo}, + ResizeMode::Crop, + ResizeMode::Fit, + VideoInfo, VideoVariant, + }; + use std::fs::remove_dir_all; + + const TMP_DIR: &'static str = "/tmp/scootaloo_get_tweet_media_test"; + + #[tokio::test] + async fn test_get_tweet_media() { + let m_photo = MediaEntity { + display_url: "pic.twitter.com/sHrwmP69Yv".to_string(), + expanded_url: "https://twitter.com/NintendojoFR/status/1555473821121056771/photo/1" + .to_string(), + id: 1555473771280080896, + range: (91, 114), + media_url: "http://pbs.twimg.com/media/FZYnJ1qWIAAReHt.jpg".to_string(), + media_url_https: "https://pbs.twimg.com/media/FZYnJ1qWIAAReHt.jpg" + .to_string(), + sizes: MediaSizes { + thumb: MediaSize { + w: 150, + h: 150, + resize: Crop + }, + small: MediaSize { + w: 680, + h: 510, + resize: Fit + }, + medium: MediaSize { + w: 1200, + h: 900, + resize: Fit + }, + large: MediaSize { + w: 1280, + h: 960, + resize: Fit + } + }, + source_status_id: None, + media_type: Photo, + url: "https://t.co/sHrwmP69Yv".to_string(), + video_info: None, + ext_alt_text: Some("Le menu «\u{a0}Classes » du jeu vidéo Xenoblade Chronicles 3 (Switch). L’affinité du personnage pour la classe est notée par quatre lettres : C, A, C, A (caca)." + .to_string()) + }; + let m_video = MediaEntity { + display_url: "pic.twitter.com/xDln0RrkjU".to_string(), + expanded_url: "https://twitter.com/NintendojoFR/status/1551822196833673218/photo/1" + .to_string(), + id: 1551822189711790081, + range: (275, 298), + media_url: "http://pbs.twimg.com/tweet_video_thumb/FYkuD0RXEAE-iDx.jpg".to_string(), + media_url_https: "https://pbs.twimg.com/tweet_video_thumb/FYkuD0RXEAE-iDx.jpg" + .to_string(), + sizes: MediaSizes { + thumb: MediaSize { + w: 150, + h: 150, + resize: Crop, + }, + small: MediaSize { + w: 320, + h: 240, + resize: Fit, + }, + medium: MediaSize { + w: 320, + h: 240, + resize: Fit, + }, + large: MediaSize { + w: 320, + h: 240, + resize: Fit, + }, + }, + source_status_id: None, + media_type: Gif, + url: "https://t.co/xDln0RrkjU".to_string(), + video_info: Some(VideoInfo { + aspect_ratio: (4, 3), + duration_millis: None, + variants: vec![VideoVariant { + bitrate: Some(0), + content_type: "video/mp4".parse::().unwrap(), + url: "https://video.twimg.com/tweet_video/FYkuD0RXEAE-iDx.mp4".to_string(), + }], + }), + ext_alt_text: Some("Scared Nintendo GIF".to_string()), + }; + + let tweet_media_photo = get_tweet_media(&m_photo, TMP_DIR).await.unwrap(); + let tweet_media_video = get_tweet_media(&m_video, TMP_DIR).await.unwrap(); + + assert_eq!( + tweet_media_photo, + format!("{}/FZYnJ1qWIAAReHt.jpg", TMP_DIR) + ); + assert_eq!( + tweet_media_video, + format!("{}/FYkuD0RXEAE-iDx.mp4", TMP_DIR) + ); + + remove_dir_all(TMP_DIR).unwrap(); + } }