diff --git a/Cargo.lock b/Cargo.lock index d290880..b4c1fc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -52,7 +52,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi 0.3.9", ] @@ -82,7 +82,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide", + "miniz_oxide 0.5.4", "object", "rustc-demangle", ] @@ -197,9 +197,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "camino" @@ -234,9 +234,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.76" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" [[package]] name = "cfg-if" @@ -268,13 +268,13 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.24" +version = "4.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60494cedb60cb47462c0ff7be53de32c0e42a6fc2c772184554fa12bd9489c03" +checksum = "0acbd8d28a0a60d7108d7ae850af6ba34cf2d1257fc646980e5f97ce14275966" dependencies = [ - "atty", "bitflags", "clap_lex", + "is-terminal", "strsim", "termcolor", ] @@ -446,9 +446,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888" +checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" dependencies = [ "cc", "cxxbridge-flags", @@ -458,9 +458,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3" +checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" dependencies = [ "cc", "codespan-reporting", @@ -473,15 +473,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f" +checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" [[package]] name = "cxxbridge-macro" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" +checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" dependencies = [ "proc-macro2", "quote", @@ -560,7 +560,7 @@ dependencies = [ "serde_json", "sha-1 0.9.8", "thiserror", - "tokio 1.21.2", + "tokio 1.22.0", "url 2.3.1", ] @@ -603,6 +603,27 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "error-chain" version = "0.12.4" @@ -664,12 +685,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] @@ -906,7 +927,7 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ - "bytes 1.2.1", + "bytes 1.3.0", "fnv", "futures-core", "futures-sink", @@ -914,7 +935,7 @@ dependencies = [ "http 0.2.8", "indexmap", "slab", - "tokio 1.21.2", + "tokio 1.22.0", "tokio-util", "tracing", ] @@ -952,6 +973,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hmac" version = "0.11.0" @@ -988,7 +1018,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ - "bytes 1.2.1", + "bytes 1.3.0", "fnv", "itoa 1.0.4", ] @@ -1011,7 +1041,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.2.1", + "bytes 1.3.0", "http 0.2.8", "pin-project-lite", ] @@ -1064,7 +1094,7 @@ version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ - "bytes 1.2.1", + "bytes 1.3.0", "futures-channel", "futures-core", "futures-util", @@ -1076,7 +1106,7 @@ dependencies = [ "itoa 1.0.4", "pin-project-lite", "socket2", - "tokio 1.21.2", + "tokio 1.22.0", "tower-service", "tracing", "want 0.3.0", @@ -1118,10 +1148,10 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.2.1", + "bytes 1.3.0", "hyper 0.14.23", "native-tls", - "tokio 1.21.2", + "tokio 1.22.0", "tokio-native-tls", ] @@ -1183,9 +1213,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg 1.1.0", "hashbrown 0.12.3", @@ -1209,6 +1239,16 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "io-lifetimes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "iovec" version = "0.1.4" @@ -1224,6 +1264,18 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" +[[package]] +name = "is-terminal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae5bc6e2eb41c9def29a3e0f1306382807764b9b53112030eff57435667352d" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "isolang" version = "1.0.0" @@ -1303,6 +1355,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" + [[package]] name = "lock_api" version = "0.3.4" @@ -1383,6 +1441,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.6.23" @@ -1480,7 +1547,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -1522,9 +1589,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1554,9 +1621,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.77" +version = "0.9.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" +checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132" dependencies = [ "autocfg 1.1.0", "cc", @@ -1567,9 +1634,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.4.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5bf27447411e9ee3ff51186bf7a08e16c341efdde93f4d823e8844429bed7e" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "parking_lot" @@ -1996,12 +2063,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" dependencies = [ "base64 0.13.1", - "bytes 1.2.1", + "bytes 1.3.0", "encoding_rs", "futures-core", "futures-util", @@ -2021,7 +2088,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded 0.7.1", - "tokio 1.21.2", + "tokio 1.22.0", "tokio-native-tls", "tower-service", "url 2.3.1", @@ -2070,6 +2137,20 @@ dependencies = [ "semver 1.0.14", ] +[[package]] +name = "rustix" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "ryu" version = "1.0.11" @@ -2103,7 +2184,7 @@ dependencies = [ [[package]] name = "scootaloo" -version = "0.11.1" +version = "0.12.1" dependencies = [ "clap", "egg-mode", @@ -2113,11 +2194,11 @@ dependencies = [ "log", "mime", "regex", - "reqwest 0.11.12", + "reqwest 0.11.13", "rusqlite", "serde", "simple_logger", - "tokio 1.21.2", + "tokio 1.22.0", "toml", ] @@ -2202,9 +2283,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa 1.0.4", "ryu", @@ -2530,12 +2611,12 @@ dependencies = [ [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg 1.1.0", - "bytes 1.2.1", + "bytes 1.3.0", "libc", "memchr", "mio 0.8.5", @@ -2608,7 +2689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", - "tokio 1.21.2", + "tokio 1.22.0", ] [[package]] @@ -2689,11 +2770,11 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ - "bytes 1.2.1", + "bytes 1.3.0", "futures-core", "futures-sink", "pin-project-lite", - "tokio 1.21.2", + "tokio 1.22.0", "tracing", ] diff --git a/Cargo.toml b/Cargo.toml index 270fd73..fe48947 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scootaloo" -version = "0.11.1" +version = "0.12.2" authors = ["VC "] edition = "2021" 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 !"); }