From 6915e9a967a0b2df1e245d769e83bf8f872a4182 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 10:17:36 +0200 Subject: [PATCH 1/7] unharcoded all the things, i think! --- Cargo.lock | 129 +++++++++++++++++++++++++----- Cargo.toml | 2 + config.toml | 12 +++ src/main.rs | 223 +++++++++++++++++++++++++++++++--------------------- 4 files changed, 257 insertions(+), 109 deletions(-) create mode 100644 config.toml diff --git a/Cargo.lock b/Cargo.lock index a9e4371..49c033d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -135,7 +135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -146,7 +146,7 @@ checksum = "dcdbcee2d9941369faba772587a565f4f534e42cb8d17e5295871de730163b2b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -164,6 +164,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "erased-serde" version = "0.3.24" @@ -277,7 +283,7 @@ checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -339,7 +345,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.2", "slab", "tokio", "tokio-util", @@ -352,6 +358,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -449,7 +461,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", ] [[package]] @@ -542,7 +564,7 @@ dependencies = [ "time", "tokio", "tokio-util", - "toml", + "toml 0.5.11", "url", "uuid", ] @@ -567,8 +589,10 @@ version = "0.1.0" dependencies = [ "mastodon-async", "reqwest", + "serde", "tokio", "tokio-test", + "toml 0.7.6", ] [[package]] @@ -662,7 +686,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -740,9 +764,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] @@ -760,9 +784,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.23" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -900,22 +924,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.25", ] [[package]] @@ -949,6 +973,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1027,6 +1060,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap-reader" version = "1.0.1" @@ -1064,7 +1108,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1135,7 +1179,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1195,6 +1239,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f8751d9c1b03c6500c387e96f81f815a4f8e72d142d2d4a9ffa6fedd51ddee7" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -1351,7 +1429,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -1385,7 +1463,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1531,6 +1609,15 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "winnow" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index d9ffe21..be9f9ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } tokio-test = "0.4.2" reqwest = "0.11.14" +serde = "1.0.171" +toml = "0.7.1" [dependencies.mastodon-async] version = "1.0" diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..946f71f --- /dev/null +++ b/config.toml @@ -0,0 +1,12 @@ +[Bot] +name = "sleeping-girls-bot" +instance = "https://awoo.fai.st" +bio = "Bot who posts images of sleeping girls every 6 hours." + +[Config] +urls = "./urls.csv" +posted = "./posted.csv" +tempfile = "./.tmp" + +[Errors] +out-of-images = "@Sugui@awoo.fai.st @MeDueleLaTeta@awoo.fai.st me quedé sin chicas" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e7035ad..6ed6e25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,116 +1,163 @@ -use std::collections::HashSet; -use std::process::Command; -use mastodon_async::helpers::toml; use mastodon_async::scopes; -use mastodon_async::{prelude::*}; -use mastodon_async::{entities::visibility::Visibility}; +use mastodon_async::entities::visibility::Visibility; +use mastodon_async::helpers::toml as masto_toml; +use mastodon_async::prelude::*; use mastodon_async::{helpers::cli, Result}; use reqwest; +use serde::Deserialize; +use std::collections::HashSet; use std::io::Cursor; use std::io::Write; +use std::process::Command; +use toml; + +const CONFIG_FILENAME: &str = "config.toml"; + +#[derive(Deserialize)] +struct Config { + bot: Bot, + files: Files, + errors: Errors, +} + +#[derive(Deserialize)] +struct Bot { + name: String, + instance: String, + bio: String, +} + +#[derive(Deserialize)] +struct Files { + posted: String, + urls: String, + tempfile: String, +} + +#[derive(Deserialize)] +struct Errors { + out_of_images: String, +} + +/// Parses the given filename to a config struct +fn parse_config(filename: &str) -> Config { + let toml_file = std::fs::read_to_string(filename) + .expect("No config file, consider getting the original one and modifing it"); + toml::from_str(&toml_file).expect("Malformed config file, check the original one for reference") +} #[tokio::main] // requires `features = ["mt"] async fn main() -> Result<()> { - let mastodon = if let Ok(data) = toml::from_file("mastodon-data.toml") { - Mastodon::from(data) - } else { - register().await? - }; + let config: Config = parse_config(CONFIG_FILENAME); + let mastodon = if let Ok(data) = masto_toml::from_file("mastodon-data.toml") { + Mastodon::from(data) + } else { + register(&config).await? + }; -/* - let data = Data::default(); - let client = Mastodon::from(data); - let statuses = client.statuses(&AccountId::new("user-id"), Default::default()).await.unwrap(); - dbg!(statuses); -*/ - match get_next_url() { - Some(url) => { - post_image(&mastodon, &url).await; - update_bio(&mastodon).await; - }, - None => post(&mastodon, "@Sugui@awoo.fai.st @MeDueleLaTeta@awoo.fai.st me quedé sin chicas").await - }; - - Ok(()) -} - -fn get_next_url() -> Option { - let binding = std::fs::read("./posted.csv").expect("File not found").iter().map(|c| *c as char).collect::(); - let posted = binding.lines().collect::>(); - let binding = std::fs::read("./urls.csv").expect("File not found").iter().map(|c| *c as char).collect::(); - let urls = binding.lines().collect::>(); - let urls = urls.difference(&posted).collect::>(); - if urls.is_empty() { - None - } else { - let mut file = std::fs::OpenOptions::new() - .write(true) - .append(true) // This is needed to append to file - .open("./posted.csv") - .unwrap(); - write!(file, "{}\n", urls[0]).unwrap(); - Some(urls[0].to_string().clone()) + match get_next_url(&config) { + Some(url) => { + post_image(&mastodon, &url, &config).await; + update_bio(&mastodon, &config).await; } + None => post(&mastodon, &config.errors.out_of_images).await, + }; + + Ok(()) } -async fn post_image(account: &Mastodon, url: &String) { - fetch_url(url.to_string(), ".tmp".to_string()).await.unwrap(); - let attachment = account.media("./.tmp", Some(url.to_string())).await.expect("upload"); - let attachment = account.wait_for_processing(attachment, Default::default()).await.expect("processing"); - let status = StatusBuilder::new() - .media_ids(&[attachment.id]) - .visibility(Visibility::Unlisted) - .sensitive(true) - .build() - .unwrap(); - account.new_status(status).await.unwrap(); - - +fn get_next_url(config: &Config) -> Option { + let binding = std::fs::read_to_string(&config.files.posted).expect("Posted file not found"); + let posted = binding.lines().collect::>(); + let binding = std::fs::read_to_string(&config.files.urls).expect("Urls file not found"); + let urls = binding.lines().collect::>(); + let urls = urls.difference(&posted).collect::>(); + if urls.is_empty() { + None + } else { + let mut file = std::fs::OpenOptions::new() + .write(true) + .append(true) // This is needed to append to file + .open(&config.files.posted) + .unwrap(); + write!(file, "{}\n", urls[0]).unwrap(); + Some(urls[0].to_string().clone()) + } } -async fn update_bio(account: &Mastodon) { - let binding = std::fs::read("./posted.csv").expect("File not found").iter().map(|c| *c as char).collect::(); - let posted = binding.lines().collect::>(); - let binding = std::fs::read("./urls.csv").expect("File not found").iter().map(|c| *c as char).collect::(); - let urls = binding.lines().collect::>(); - - let remaining = urls.difference(&posted).count(); +async fn post_image(account: &Mastodon, url: &String, config: &Config) { + fetch_url(url.to_string(), &config.files.tempfile) + .await + .unwrap(); + let attachment = account + .media(&config.files.tempfile, Some(url.to_string())) + .await + .expect("Attachment upload error"); + let attachment = account + .wait_for_processing(attachment, Default::default()) + .await + .expect("Attachment processing error"); + let status = StatusBuilder::new() + .media_ids(&[attachment.id]) + .visibility(Visibility::Unlisted) + .sensitive(true) + .build() + .unwrap(); + account.new_status(status).await.unwrap(); +} - Command::new("curl") - .args([ - "-X", "PATCH", - "https://awoo.fai.st/api/v1/accounts/update_credentials", - "-H", &format!("Authorization:Bearer {}", account.data.token), - "-d", &format!("note=Bot who posts images of sleeping girls every 6 hours.\n\n{} new images remaining", remaining), - ]).spawn().unwrap().wait().unwrap(); +async fn update_bio(account: &Mastodon, config: &Config) { + let binding = std::fs::read_to_string(&config.files.posted).expect("Posted file not found"); + let posted = binding.lines().collect::>(); + let binding = std::fs::read_to_string(&config.files.urls).expect("Url file not found"); + let urls = binding.lines().collect::>(); + let remaining = urls.difference(&posted).count(); + + Command::new("curl") + .args([ + "-X", + "PATCH", + &format!("{}/api/v1/accounts/update_credentials", config.bot.instance), + "-H", + &format!("Authorization:Bearer {}", account.data.token), + "-d", + &format!( + "note={}\n\n{} new images remaining", + config.bot.bio, remaining + ), + ]) + .spawn() + .unwrap() + .wait() + .unwrap(); } async fn post(account: &Mastodon, msg: &str) { - let status = StatusBuilder::new() + let status = StatusBuilder::new() .visibility(Visibility::Direct) .status(msg) .build() .unwrap(); - account.new_status(status).await.unwrap(); + account.new_status(status).await.unwrap(); } -async fn fetch_url(url: String, file_name: String) -> Result<()> { - let response = reqwest::get(url).await?; - let mut file = std::fs::File::create(file_name)?; - let mut content = Cursor::new(response.bytes().await?); - std::io::copy(&mut content, &mut file)?; - Ok(()) +async fn fetch_url(url: String, file_name: &String) -> Result<()> { + let response = reqwest::get(url).await?; + let mut file = std::fs::File::create(file_name)?; + let mut content = Cursor::new(response.bytes().await?); + std::io::copy(&mut content, &mut file)?; + Ok(()) } -async fn register() -> Result { - let registration = Registration::new("https://awoo.fai.st") - .client_name("sleeping-girls-bot") - .scopes(Scopes::write_all()) - .build() - .await?; - let mastodon = cli::authenticate(registration).await?; +async fn register(config: &Config) -> Result { + let registration = Registration::new(&config.bot.instance) + .client_name(&config.bot.name) + .scopes(Scopes::write_all()) + .build() + .await?; + let mastodon = cli::authenticate(registration).await?; - // Save app data for using on the next run. - toml::to_file(&mastodon.data, "mastodon-data.toml")?; + // Save app data for using on the next run. + masto_toml::to_file(&mastodon.data, "mastodon-data.toml")?; - Ok(mastodon) + Ok(mastodon) } From 325b9eadde29251e929a8bfb9eb828db3d7a8e58 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 10:57:53 +0200 Subject: [PATCH 2/7] fix toml errors --- config.toml | 10 +++++----- src/main.rs | 10 ++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/config.toml b/config.toml index 946f71f..8d4433f 100644 --- a/config.toml +++ b/config.toml @@ -1,12 +1,12 @@ -[Bot] -name = "sleeping-girls-bot" +[bot] +name = "dev-sleeping-girls-bot" instance = "https://awoo.fai.st" bio = "Bot who posts images of sleeping girls every 6 hours." -[Config] +[filess] urls = "./urls.csv" posted = "./posted.csv" tempfile = "./.tmp" -[Errors] -out-of-images = "@Sugui@awoo.fai.st @MeDueleLaTeta@awoo.fai.st me quedé sin chicas" \ No newline at end of file +[errors] +out_of_images = "@Sugui@awoo.fai.st @MeDueleLaTeta@awoo.fai.st me quedé sin chicas" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6ed6e25..0dddc20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,7 +87,7 @@ fn get_next_url(config: &Config) -> Option { async fn post_image(account: &Mastodon, url: &String, config: &Config) { fetch_url(url.to_string(), &config.files.tempfile) .await - .unwrap(); + .expect("Error fetching url"); let attachment = account .media(&config.files.tempfile, Some(url.to_string())) .await @@ -102,7 +102,8 @@ async fn post_image(account: &Mastodon, url: &String, config: &Config) { .sensitive(true) .build() .unwrap(); - account.new_status(status).await.unwrap(); + account.new_status(status).await.expect("Error generating status"); + println!("Status posted") } async fn update_bio(account: &Mastodon, config: &Config) { @@ -136,8 +137,9 @@ async fn post(account: &Mastodon, msg: &str) { .visibility(Visibility::Direct) .status(msg) .build() - .unwrap(); - account.new_status(status).await.unwrap(); + .expect("Error building error status"); + account.new_status(status).await.expect("Error posting error status"); + println!("Error status posted") } async fn fetch_url(url: String, file_name: &String) -> Result<()> { From c0b134b9a0c32d780015e879d20f36233a700569 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 10:58:53 +0200 Subject: [PATCH 3/7] update gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index db4e4ac..d948472 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /target mastodon-data.toml *.csv -.tmp \ No newline at end of file +*.tmp +*.log +tmp/ \ No newline at end of file From 87ca81c18a254a1855b65fe9821dfeef46a80829 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 11:03:28 +0200 Subject: [PATCH 4/7] made all errors verbose --- run_with_log.sh | 10 ++++++++++ src/main.rs | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) create mode 100755 run_with_log.sh diff --git a/run_with_log.sh b/run_with_log.sh new file mode 100755 index 0000000..413220c --- /dev/null +++ b/run_with_log.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +mastodon-image-uploader-bot >./tmp/log.out 2>./tmp/log.err +if [ ! -s ./tmp/log.err ]; then + echo -n "$(date +"[%Y-%M-%d %T]") success: " >> ./bot.log + cat ./tmp/log.out >> ./bot.log +else + echo -n "$(date +"[%Y-%M-%d %T]") errors: " >> ./bot.log + cat ./tmp/log.err >> ./bot.log +fi \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 0dddc20..bc1908c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,8 +78,8 @@ fn get_next_url(config: &Config) -> Option { .write(true) .append(true) // This is needed to append to file .open(&config.files.posted) - .unwrap(); - write!(file, "{}\n", urls[0]).unwrap(); + .expect("Cannot open posted file"); // Maybe we should retry just in case + write!(file, "{}\n", urls[0]).expect("Cannot write to posted file"); // maybe we should retry tbh Some(urls[0].to_string().clone()) } } @@ -101,8 +101,8 @@ async fn post_image(account: &Mastodon, url: &String, config: &Config) { .visibility(Visibility::Unlisted) .sensitive(true) .build() - .unwrap(); - account.new_status(status).await.expect("Error generating status"); + .expect("Could not build status"); // we should retry + account.new_status(status).await.expect("Error generating status"); // we should retry or delete last url in posted println!("Status posted") } @@ -127,9 +127,9 @@ async fn update_bio(account: &Mastodon, config: &Config) { ), ]) .spawn() - .unwrap() + .expect("Could not spawn curl") .wait() - .unwrap(); + .expect("Curl failed"); } async fn post(account: &Mastodon, msg: &str) { From 26e61fd71eb05f713800d45eef0bc2a2a70ee821 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 11:04:24 +0200 Subject: [PATCH 5/7] forgor to fix config --- config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.toml b/config.toml index 8d4433f..595f930 100644 --- a/config.toml +++ b/config.toml @@ -3,7 +3,7 @@ name = "dev-sleeping-girls-bot" instance = "https://awoo.fai.st" bio = "Bot who posts images of sleeping girls every 6 hours." -[filess] +[files] urls = "./urls.csv" posted = "./posted.csv" tempfile = "./.tmp" From 6d61144a0da1a30d4eaf8f23d5e45685bbecd437 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 19:04:58 +0200 Subject: [PATCH 6/7] logging and retries implemented --- Cargo.lock | 323 ++++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 2 + config.toml | 5 +- run_with_log.sh | 10 -- src/main.rs | 181 ++++++++++++++++++--------- 5 files changed, 416 insertions(+), 105 deletions(-) delete mode 100755 run_with_log.sh diff --git a/Cargo.lock b/Cargo.lock index 49c033d..8bbeae9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "async-stream" version = "0.3.4" @@ -33,6 +48,17 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -112,6 +138,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "winapi", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -128,16 +168,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote", - "syn 1.0.107", -] - [[package]] name = "derive_deref" version = "1.1.1" @@ -364,6 +394,15 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.2.6" @@ -444,6 +483,29 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.3.0" @@ -528,11 +590,10 @@ checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" dependencies = [ - "cfg-if", "serde", "value-bag", ] @@ -587,9 +648,11 @@ dependencies = [ name = "mastodon-image-uploader-bot" version = "0.1.0" dependencies = [ + "log", "mastodon-async", "reqwest", "serde", + "stderrlog", "tokio", "tokio-test", "toml 0.7.6", @@ -647,13 +710,22 @@ dependencies = [ "tempfile", ] +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -1041,12 +1113,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "sval" -version = "1.0.0-alpha.5" +name = "stderrlog" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f6ee7c7b87caf59549e9fe45d6a69c75c8019e79e212a835c5da0e92f0ba08" +checksum = "69a26bbf6de627d389164afa9783739b56746c6c72c4ed16539f4ff54170327b" +dependencies = [ + "atty", + "chrono", + "log", + "termcolor", + "thread_local", +] + +[[package]] +name = "sval" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" + +[[package]] +name = "sval_buffer" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" dependencies = [ "serde", + "sval", + "sval_buffer", + "sval_fmt", ] [[package]] @@ -1091,6 +1235,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.38" @@ -1111,6 +1264,16 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.3.19" @@ -1357,16 +1520,38 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.0.0-alpha.9" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" dependencies = [ - "ctor", "erased-serde", "serde", "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" +dependencies = [ "sval", - "version_check", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", ] [[package]] @@ -1528,19 +1713,28 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.1", +] + [[package]] name = "windows-sys" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", ] [[package]] @@ -1549,7 +1743,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.1", ] [[package]] @@ -1558,13 +1752,28 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -1573,42 +1782,84 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winnow" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index be9f9ba..781e0db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,8 @@ tokio-test = "0.4.2" reqwest = "0.11.14" serde = "1.0.171" toml = "0.7.1" +log = "0.4.19" +stderrlog = "0.5.4" [dependencies.mastodon-async] version = "1.0" diff --git a/config.toml b/config.toml index 595f930..956bec4 100644 --- a/config.toml +++ b/config.toml @@ -6,7 +6,8 @@ bio = "Bot who posts images of sleeping girls every 6 hours." [files] urls = "./urls.csv" posted = "./posted.csv" -tempfile = "./.tmp" +tempfile = ".tmp" [errors] -out_of_images = "@Sugui@awoo.fai.st @MeDueleLaTeta@awoo.fai.st me quedé sin chicas" \ No newline at end of file +out_of_images = "@Sugui@awoo.fai.st @MeDueleLaTeta@awoo.fai.st me quedé sin chicas" +retry = 10 \ No newline at end of file diff --git a/run_with_log.sh b/run_with_log.sh deleted file mode 100755 index 413220c..0000000 --- a/run_with_log.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -mastodon-image-uploader-bot >./tmp/log.out 2>./tmp/log.err -if [ ! -s ./tmp/log.err ]; then - echo -n "$(date +"[%Y-%M-%d %T]") success: " >> ./bot.log - cat ./tmp/log.out >> ./bot.log -else - echo -n "$(date +"[%Y-%M-%d %T]") errors: " >> ./bot.log - cat ./tmp/log.err >> ./bot.log -fi \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index bc1908c..fd89a16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,21 @@ use mastodon_async::entities::visibility::Visibility; -use mastodon_async::helpers::toml as masto_toml; +use mastodon_async::helpers::{cli, toml as masto_toml}; use mastodon_async::prelude::*; -use mastodon_async::{helpers::cli, Result}; +use mastodon_async::Result as MastoResult; use reqwest; use serde::Deserialize; use std::collections::HashSet; -use std::io::Cursor; -use std::io::Write; -use std::process::Command; +use std::error::Error; +use std::io::{Cursor, Write}; +use std::process::{exit, Command}; use toml; +use log; + const CONFIG_FILENAME: &str = "config.toml"; +type DynResult = Result>; + #[derive(Deserialize)] struct Config { bot: Bot, @@ -36,80 +40,144 @@ struct Files { #[derive(Deserialize)] struct Errors { out_of_images: String, -} - -/// Parses the given filename to a config struct -fn parse_config(filename: &str) -> Config { - let toml_file = std::fs::read_to_string(filename) - .expect("No config file, consider getting the original one and modifing it"); - toml::from_str(&toml_file).expect("Malformed config file, check the original one for reference") + retry: u8, } #[tokio::main] // requires `features = ["mt"] -async fn main() -> Result<()> { - let config: Config = parse_config(CONFIG_FILENAME); +async fn main() -> DynResult<()> { + stderrlog::new() + .module(module_path!()) + .quiet(false) + .verbosity(4) // Debug + .timestamp(stderrlog::Timestamp::Second) + .init()?; + let config: Config = match parse_config(CONFIG_FILENAME) { + Ok(config) => config, + Err(err) => { + log::error!("Config file parsing unsuccesful: {}", err); + exit(1); + } + }; + let mastodon = if let Ok(data) = masto_toml::from_file("mastodon-data.toml") { Mastodon::from(data) } else { - register(&config).await? + match register(&config).await { + Ok(account) => account, + Err(err) => { + log::error!("Api registation unsuccesful: {}", err); + exit(1); + } + } }; match get_next_url(&config) { - Some(url) => { - post_image(&mastodon, &url, &config).await; - update_bio(&mastodon, &config).await; + Ok(url) => match url { + Some(url) => { + let mut retry: u8 = 0; + while let Err(err) = post_image(&mastodon, &url, &config).await { + log::warn!("Cannot post image, retry: {}, {}", retry, err); + retry += 1; + if retry >= config.errors.retry { + log::error!("Max ammount of retries reached on post_image"); + log::info!("Reverting file changes"); + while let Err(err) = pop_last_line_of_file(&config.files.posted) { + log::warn!("Failed to revert, retrying: {}", err); + } + exit(1); + } + } + let mut retry: u8 = 0; + while let Err(err) = update_bio(&mastodon, &config).await { + log::warn!("Cannot update bio, retry: {}, {}", retry, err); + retry += 1; + if retry >= config.errors.retry { + log::error!("Max ammount of retries reached on update bio"); + exit(1); + } + } + } + None => { + let mut retry: u8 = 0; + while let Err(err) = post(&mastodon, &config.errors.out_of_images).await { + log::warn!("Cannot post, retry: {}, {}", retry, err); + retry += 1; + if retry >= config.errors.retry { + log::error!("Max ammount of retries reached on post"); + exit(1); + } + } + } + }, + Err(err) => { + log::error!("Cannot get next image: {}", err); + match post(&mastodon, &err.to_string()).await { + Ok(_) => {} + Err(err) => { + log::error!("Cannot post error message: {}", err); + exit(1); + } + }; } - None => post(&mastodon, &config.errors.out_of_images).await, - }; - + } Ok(()) } -fn get_next_url(config: &Config) -> Option { - let binding = std::fs::read_to_string(&config.files.posted).expect("Posted file not found"); +/// Parses the given filename to a config struct +fn parse_config(filename: &str) -> DynResult { + let toml_file = std::fs::read_to_string(filename)?; //.expect("No config file, consider getting the original one and modifing it"); + Ok(toml::from_str(&toml_file)?) //("Malformed config file, check the original one for reference") +} + +fn pop_last_line_of_file(filename: &str) -> DynResult<()> { + let binding = std::fs::read_to_string(filename)?; + let mut posted: Vec<_> = binding.lines().collect(); + posted.pop(); + std::fs::write(filename, posted.concat())?; + log::info!("Success reverting changes"); + Ok(()) +} + +fn get_next_url(config: &Config) -> DynResult> { + let binding = std::fs::read_to_string(&config.files.posted)?; //.expect("Posted file not found"); let posted = binding.lines().collect::>(); - let binding = std::fs::read_to_string(&config.files.urls).expect("Urls file not found"); + let binding = std::fs::read_to_string(&config.files.urls)?; //.expect("Urls file not found"); let urls = binding.lines().collect::>(); let urls = urls.difference(&posted).collect::>(); if urls.is_empty() { - None + Ok(None) } else { let mut file = std::fs::OpenOptions::new() .write(true) .append(true) // This is needed to append to file - .open(&config.files.posted) - .expect("Cannot open posted file"); // Maybe we should retry just in case - write!(file, "{}\n", urls[0]).expect("Cannot write to posted file"); // maybe we should retry tbh - Some(urls[0].to_string().clone()) + .open(&config.files.posted)?; //.expect("Cannot open posted file"); // Maybe we should retry just in case + write!(file, "{}\n", urls[0])?; //.expect("Cannot write to posted file"); // maybe we should retry tbh + Ok(Some(urls[0].to_string().clone())) } } -async fn post_image(account: &Mastodon, url: &String, config: &Config) { - fetch_url(url.to_string(), &config.files.tempfile) - .await - .expect("Error fetching url"); +async fn post_image(account: &Mastodon, url: &String, config: &Config) -> DynResult<()> { + fetch_url(url.to_string(), &config.files.tempfile).await?; //.expect("Error fetching url"); let attachment = account .media(&config.files.tempfile, Some(url.to_string())) - .await - .expect("Attachment upload error"); + .await?; //.expect("Attachment upload error"); let attachment = account .wait_for_processing(attachment, Default::default()) - .await - .expect("Attachment processing error"); + .await?; //.expect("Attachment processing error"); let status = StatusBuilder::new() .media_ids(&[attachment.id]) .visibility(Visibility::Unlisted) .sensitive(true) - .build() - .expect("Could not build status"); // we should retry - account.new_status(status).await.expect("Error generating status"); // we should retry or delete last url in posted - println!("Status posted") + .build()?; //.expect("Could not build status"); // we should retry + account.new_status(status).await?; //.expect("Error generating status"); // we should retry or delete last url in posted + log::info!("Image status posted: {}", url); + Ok(()) } -async fn update_bio(account: &Mastodon, config: &Config) { - let binding = std::fs::read_to_string(&config.files.posted).expect("Posted file not found"); +async fn update_bio(account: &Mastodon, config: &Config) -> DynResult<()> { + let binding = std::fs::read_to_string(&config.files.posted)?; //.expect("Posted file not found"); let posted = binding.lines().collect::>(); - let binding = std::fs::read_to_string(&config.files.urls).expect("Url file not found"); + let binding = std::fs::read_to_string(&config.files.urls)?; //.expect("Url file not found"); let urls = binding.lines().collect::>(); let remaining = urls.difference(&posted).count(); @@ -126,31 +194,30 @@ async fn update_bio(account: &Mastodon, config: &Config) { config.bot.bio, remaining ), ]) - .spawn() - .expect("Could not spawn curl") - .wait() - .expect("Curl failed"); + .spawn()? //.expect("Could not spawn curl") + .wait()?; //.expect("Curl failed"); + Ok(()) } -async fn post(account: &Mastodon, msg: &str) { +async fn post(account: &Mastodon, msg: &str) -> MastoResult<()> { let status = StatusBuilder::new() .visibility(Visibility::Direct) .status(msg) - .build() - .expect("Error building error status"); - account.new_status(status).await.expect("Error posting error status"); - println!("Error status posted") + .build()?; //.expect("Error building error status"); + account.new_status(status).await?; //.expect("Error posting error status"); + log::info!("Text status posted: {}", msg); + Ok(()) } -async fn fetch_url(url: String, file_name: &String) -> Result<()> { - let response = reqwest::get(url).await?; +async fn fetch_url(url: String, file_name: &String) -> MastoResult<()> { + let response = reqwest::get(url); let mut file = std::fs::File::create(file_name)?; - let mut content = Cursor::new(response.bytes().await?); + let mut content = Cursor::new(response.await?.bytes().await?); std::io::copy(&mut content, &mut file)?; Ok(()) } -async fn register(config: &Config) -> Result { +async fn register(config: &Config) -> MastoResult { let registration = Registration::new(&config.bot.instance) .client_name(&config.bot.name) .scopes(Scopes::write_all()) From 3bc20ff657a34b1989fcb0809be384cbf5764452 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 14 Jul 2023 19:08:15 +0200 Subject: [PATCH 7/7] change version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8bbeae9..66db7e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,7 +646,7 @@ dependencies = [ [[package]] name = "mastodon-image-uploader-bot" -version = "0.1.0" +version = "0.2.0" dependencies = [ "log", "mastodon-async", diff --git a/Cargo.toml b/Cargo.toml index 781e0db..4e10a40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mastodon-image-uploader-bot" -version = "0.1.0" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html