Merge branch 'noasync' of framagit.org:veretcle/scootaloo into noasync

This commit is contained in:
VC
2021-04-24 09:45:50 +02:00
5 changed files with 178 additions and 17 deletions

View File

@@ -9,5 +9,5 @@ rust-latest:
image: rust:latest
script:
- cargo build --release --verbose
- strip target/release/scootaloo
- strip target/release/${CI_PROJECT_NAME}

View File

@@ -1,3 +1,23 @@
# v0.3.3
* optimizing the size of the final executable (now ⩽ 6MiB)
# v0.3.2
* 100% async version
* now media are download in parallel thanks to async
* log are introduced into code for your viewing pleasure
# v0.2.3
* using the async version of `reqwest`
* introducing async functions and make `tokio` the de facto executor for everything async
# v0.2.1
* using `tokio-compat` to avoid having 3 different versions of `tokio` in the same executable
* encapsulating async calls inside blocking tokio runtime calls
# v0.1.8
* fix #1: mentions are treated like decoded urls (this is not really needed to push it this far but it would be easier in case you want to modify it)

136
Cargo.lock generated
View File

@@ -95,6 +95,12 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bitflags"
version = "1.2.1"
@@ -141,6 +147,21 @@ dependencies = [
[[package]]
name = "bytes"
<<<<<<< HEAD
=======
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "bytes"
>>>>>>> ac80b67c9f303e8a829b55f6f1e60329a419dc02
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
@@ -353,7 +374,7 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6"
dependencies = [
"generic-array",
"generic-array 0.14.4",
"subtle",
]
@@ -381,7 +402,16 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
"generic-array 0.12.3",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array 0.14.4",
]
[[package]]
@@ -416,7 +446,7 @@ dependencies = [
"regex",
"serde",
"serde_json",
"sha-1",
"sha-1 0.9.4",
"thiserror",
"tokio 1.5.0",
"url 2.2.1",
@@ -430,9 +460,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "elefren"
version = "0.20.1"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfca8d8d0147086081224e22183a37a7b98e3230b945a717f1b5a0eed5fb07af"
checksum = "ba08a959d3824df696d49c2ec023f45851f663c47b57b2de933aab749104cd18"
dependencies = [
"chrono",
"doc-comment",
@@ -448,6 +478,7 @@ dependencies = [
"skeptic",
"tap-reader",
"try_from",
"tungstenite",
"url 1.7.2",
]
@@ -672,7 +703,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
<<<<<<< HEAD
"version_check",
=======
"version_check 0.9.1",
]
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check 0.9.1",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if 0.1.9",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
>>>>>>> ac80b67c9f303e8a829b55f6f1e60329a419dc02
]
[[package]]
@@ -757,7 +813,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15"
dependencies = [
"crypto-mac",
"digest",
"digest 0.9.0",
]
[[package]]
@@ -783,7 +839,11 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
dependencies = [
<<<<<<< HEAD
"bytes 1.0.1",
=======
"bytes 0.5.6",
>>>>>>> ac80b67c9f303e8a829b55f6f1e60329a419dc02
"fnv",
"itoa",
]
@@ -823,6 +883,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9"
[[package]]
name = "httpdate"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
[[package]]
name = "hyper"
version = "0.12.36"
@@ -1201,6 +1267,15 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "ntapi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a31937dea023539c72ddae0e3571deadc1414b300483fa7aaec176168cfa9d2"
dependencies = [
"winapi 0.3.8",
]
[[package]]
name = "num-integer"
version = "0.1.44"
@@ -1248,6 +1323,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.33"
@@ -1332,6 +1413,20 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "parking_lot_core"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
dependencies = [
"cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall",
"smallvec 1.2.0",
"winapi 0.3.8",
]
[[package]]
name = "percent-encoding"
version = "1.0.1"
@@ -1803,7 +1898,10 @@ dependencies = [
"clap",
"egg-mode",
"elefren",
<<<<<<< HEAD
"futures 0.3.14",
=======
>>>>>>> ac80b67c9f303e8a829b55f6f1e60329a419dc02
"htmlescape",
"log",
"reqwest 0.11.3",
@@ -2030,6 +2128,17 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "socket2"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
dependencies = [
"cfg-if 1.0.0",
"libc",
"winapi 0.3.8",
]
[[package]]
name = "string"
version = "0.2.1"
@@ -2460,6 +2569,12 @@ dependencies = [
"percent-encoding 2.1.0",
]
[[package]]
name = "utf-8"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
[[package]]
name = "uuid"
version = "0.7.4"
@@ -2664,6 +2779,15 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "winreg"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
dependencies = [
"winapi 0.3.8",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"

View File

@@ -3,7 +3,7 @@ A Twitter to Mastodon copy bot written in Rust
It:
* copies the content (text) of the original Tweet
* dereferences the links
* gets every attach media (photo, video or gif)
* gets every attached media (photo, video or gif)
If any of the last steps failed, the Toot gets published with the exact same text as the Tweet.
@@ -74,4 +74,3 @@ echo -n '8189881949849' > last_tweet
**This file should only contain the last tweet ID without any other char (no EOL or new line).**
Oh and everything is sync (and not async) so this does not run at a blazing speed…

View File

@@ -6,6 +6,7 @@ use std::{
fmt,
fs::{read_to_string, write},
error::Error,
sync::{Arc, Mutex},
};
// toml
@@ -52,7 +53,7 @@ use log::{info, warn, error, debug};
/*
* Those functions are related to the Twitter side of things
*/
/// Read last tweet id from a file
/// Reads last tweet id from a file
fn read_state(s: &str) -> Option<u64> {
let state = read_to_string(s);
@@ -69,7 +70,7 @@ fn write_state(f: &str, s: u64) -> Result<(), std::io::Error> {
write(f, format!("{}", s))
}
/// Gets twitter oauth2 token
/// Gets Twitter oauth2 token
fn get_oauth2_token(config: &Config) -> Token {
let con_token = KeyPair::new(String::from(&config.twitter.consumer_key), String::from(&config.twitter.consumer_secret));
let access_token = KeyPair::new(String::from(&config.twitter.access_key), String::from(&config.twitter.access_secret));
@@ -80,12 +81,13 @@ fn get_oauth2_token(config: &Config) -> Token {
}
}
/// Gets twitter user timeline
/// Gets Twitter user timeline
async fn get_user_timeline(config: &Config, token: Token, lid: Option<u64>) -> Result<Vec<Tweet>, Box<dyn Error>> {
// fix the page size to 200 as it is the maximum Twitter authorizes
let (_timeline, feed) = user_timeline(UserID::from(String::from(&config.twitter.username)), true, false, &token)
let (_, feed) = user_timeline(UserID::from(String::from(&config.twitter.username)), true, false, &token)
.with_page_size(200)
.older(lid).await?;
.older(lid)
.await?;
Ok(feed.to_vec())
}
@@ -206,6 +208,15 @@ async fn cache_media(u: &str, t: &str) -> Result<String, Box<dyn Error>> {
Ok(dest_filepath)
}
/**********
* This is the struct that holds the Mastodon Media ID and the Twitter Media URL at the same Time
**********/
#[derive(Debug)]
struct ScootalooSpawnResponse {
mastodon_media_id: String,
twitter_media_url: String,
}
/**********
* local error handler
**********/
@@ -324,10 +335,12 @@ pub async fn run(config: Config) {
let token = get_oauth2_token(&config);
// get Mastodon instance
let mastodon = get_mastodon_token(&config.mastodon);
let mastodon = Arc::new(Mutex::new(get_mastodon_token(&config.mastodon)));
// get user timeline feed (Vec<tweet>)
let mut feed = get_user_timeline(&config, token, last_tweet_id).await.unwrap_or_else(|e|
let mut feed = get_user_timeline(&config, token, last_tweet_id)
.await
.unwrap_or_else(|e|
panic!("Something went wrong when trying to retrieve {}s timeline: {}", &config.twitter.username, e)
);
@@ -341,6 +354,7 @@ pub async fn run(config: Config) {
feed.reverse();
for tweet in &feed {
debug!("Treating Tweet {} inside feed", tweet.id);
// determine if the tweet is part of a thread (response to self) or a standard response
debug!("Treating Tweet {} inside feed", tweet.id);
if let Some(r) = &tweet.in_reply_to_screen_name {
@@ -364,6 +378,8 @@ pub async fn run(config: Config) {
// reupload the attachments if any
if let Some(m) = &tweet.extended_entities {
let (tx, mut rx) = mpsc::channel(4);
for media in &m.media {
let local_tweet_media_path = match get_tweet_media(&media, &config.scootaloo.cache_path).await {
Ok(m) => m,
@@ -390,6 +406,7 @@ pub async fn run(config: Config) {
status_text = status_text.replace(&media.url, "");
}
}
// finished reuploading attachments, now lets do the toot baby!
debug!("Building corresponding Mastodon status");
let status = StatusBuilder::new()
@@ -399,7 +416,8 @@ pub async fn run(config: Config) {
.expect(&format!("Cannot build status with text {}", &status_text));
// publish status
mastodon.new_status(status).unwrap();
// again unwrap is safe here as we are in the main thread
mastodon.lock().unwrap().new_status(status).unwrap();
// this will panic if it cannot publish the status, which is a good thing, it allows the
// last_tweet gathered not to be written