diff --git a/src/lib.rs b/src/lib.rs index eec647a..37badf8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -112,6 +112,45 @@ pub async fn run(config: Config) { let mut associated_urls = associate_urls(&tweet.entities.urls, &display_url_re); + if let Some(q) = &tweet.quoted_status { + if let Some(u) = &q.user { + info!( + "Tweet {} contains a quote, we try to find it within the DB", + tweet.id + ); + // we know we have a quote and a user, we can lock both the + // connection to DB and global_config + // we will release them manually as soon as they’re useless + let lconn = task_conn.lock().await; + let global_mastodon_config = global_mastodon_config.lock().await; + if let Ok(Some(r)) = read_state(&lconn, &u.screen_name, Some(q.id)) + { + info!("We have found the associated toot({})", &r.toot_id); + // drop conn immediately after the request: we won’t need it + // any more and the treatment there might be time-consuming + drop(lconn); + if let Some((m, t)) = + find_mastodon_screen_name_by_twitter_screen_name( + &r.twitter_screen_name, + &global_mastodon_config, + ) + { + // drop the global conf, we have all we required, no need + // to block it further + drop(global_mastodon_config); + replace_tweet_by_toot( + &mut associated_urls, + &r.twitter_screen_name, + q.id, + &m, + &t, + &r.toot_id, + ); + } + } + } + } + if let Some(a) = &scootaloo_alt_services { replace_alt_services(&mut associated_urls, a); } diff --git a/src/mastodon.rs b/src/mastodon.rs index 74e8840..5d59726 100644 --- a/src/mastodon.rs +++ b/src/mastodon.rs @@ -81,6 +81,43 @@ pub fn replace_alt_services(urls: &mut HashMap, alts: &HashMap, +) -> Option<(String, String)> { + masto.iter().find_map(|(_, v)| { + if twitter_screen_name == v.twitter_screen_name && v.mastodon_screen_name.is_some() { + Some(( + v.mastodon_screen_name.as_ref().unwrap().to_owned(), + v.base.to_owned(), + )) + } else { + None + } + }) +} + +/// Replaces the original quoted tweet by the corresponding toot +pub fn replace_tweet_by_toot( + urls: &mut HashMap, + twitter_screen_name: &str, + tweet_id: u64, + mastodon_screen_name: &str, + base_url: &str, + toot_id: &str, +) { + for val in urls.values_mut() { + if val.to_lowercase().starts_with(&format!( + "https://twitter.com/{}/status/{}", + twitter_screen_name.to_lowercase(), + tweet_id + )) { + *val = format!("{}/@{}/{}", base_url, mastodon_screen_name, toot_id); + } + } +} + /// Gets Mastodon Data pub fn get_mastodon_token(masto: &MastodonConfig) -> Mastodon { let data = Data { @@ -157,6 +194,125 @@ mastodon_screen_name = \"{}\" mod tests { use super::*; + #[test] + fn test_replace_tweet_by_toot() { + let mut associated_urls = HashMap::from([ + ( + "https://t.co/perdudeouf".to_string(), + "https://www.perdu.com".to_string(), + ), + ( + "https://t.co/realquoteshere".to_string(), + "https://twitter.com/nintendojofr/status/1590047921633755136".to_string(), + ), + ( + "https://t.co/almostthere".to_string(), + "https://twitter.com/NintendojoFR/status/nope".to_string(), + ), + ( + "http://t.co/yetanotherone".to_string(), + "https://twitter.com/NINTENDOJOFR/status/1590047921633755136".to_string(), + ), + ]); + + let expected_urls = HashMap::from([ + ( + "https://t.co/perdudeouf".to_string(), + "https://www.perdu.com".to_string(), + ), + ( + "https://t.co/realquoteshere".to_string(), + "https://m.nintendojo.fr/@nintendojofr/109309605486908797".to_string(), + ), + ( + "https://t.co/almostthere".to_string(), + "https://twitter.com/NintendojoFR/status/nope".to_string(), + ), + ( + "http://t.co/yetanotherone".to_string(), + "https://m.nintendojo.fr/@nintendojofr/109309605486908797".to_string(), + ), + ]); + + replace_tweet_by_toot( + &mut associated_urls, + "NintendojoFR", + 1590047921633755136, + "nintendojofr", + "https://m.nintendojo.fr", + "109309605486908797", + ); + + assert_eq!(associated_urls, expected_urls); + } + + #[test] + fn test_find_mastodon_screen_name_by_twitter_screen_name() { + let masto_config = HashMap::from([ + ( + "test".to_string(), + MastodonConfig { + twitter_screen_name: "tonpere".to_string(), + mastodon_screen_name: Some("lalali".to_string()), + twitter_page_size: None, + base: "https://mstdn.net".to_string(), + client_id: "".to_string(), + client_secret: "".to_string(), + redirect: "".to_string(), + token: "".to_string(), + }, + ), + ( + "test2".to_string(), + MastodonConfig { + twitter_screen_name: "tamerelol".to_string(), + mastodon_screen_name: None, + twitter_page_size: None, + base: "https://mastoot.fr".to_string(), + client_id: "".to_string(), + client_secret: "".to_string(), + redirect: "".to_string(), + token: "".to_string(), + }, + ), + ( + "test3".to_string(), + MastodonConfig { + twitter_screen_name: "NintendojoFR".to_string(), + mastodon_screen_name: Some("nintendojofr".to_string()), + twitter_page_size: None, + base: "https://m.nintendojo.fr".to_string(), + client_id: "".to_string(), + client_secret: "".to_string(), + redirect: "".to_string(), + token: "".to_string(), + }, + ), + ]); + + // case sensitiveness, to avoid any mistake + assert_eq!( + None, + find_mastodon_screen_name_by_twitter_screen_name("nintendojofr", &masto_config) + ); + assert_eq!( + Some(( + "nintendojofr".to_string(), + "https://m.nintendojo.fr".to_string() + )), + find_mastodon_screen_name_by_twitter_screen_name("NintendojoFR", &masto_config) + ); + // should return None if twitter_screen_name is undefined + assert_eq!( + None, + find_mastodon_screen_name_by_twitter_screen_name("tamerelol", &masto_config) + ); + assert_eq!( + Some(("lalali".to_string(), "https://mstdn.net".to_string())), + find_mastodon_screen_name_by_twitter_screen_name("tonpere", &masto_config) + ); + } + #[test] fn test_twitter_mentions() { let mention_entities = vec![ @@ -176,7 +332,7 @@ mod tests { let mut toot = ":kikoo: @tamerelol @tonpere !".to_string(); - let scootaloo_config = HashMap::from([( + let masto_config = HashMap::from([( "test".to_string(), (MastodonConfig { twitter_screen_name: "tonpere".to_string(), @@ -190,7 +346,7 @@ mod tests { }), )]); - twitter_mentions(&mut toot, &mention_entities, &scootaloo_config); + twitter_mentions(&mut toot, &mention_entities, &masto_config); assert_eq!(&toot, ":kikoo: @tamerelol@twitter.com @lalali@mstdn.net !"); }