diff --git a/Cargo.lock b/Cargo.lock index 66db7e1..2cc8b8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,101 @@ dependencies = [ "libc", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" version = "0.3.4" @@ -48,6 +143,18 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "atty" version = "0.2.14" @@ -77,6 +184,21 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -152,6 +274,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -168,6 +299,15 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + [[package]] name = "derive_deref" version = "1.1.1" @@ -209,6 +349,27 @@ dependencies = [ "serde", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[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" @@ -218,6 +379,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "fastrand" version = "1.9.0" @@ -305,6 +472,21 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.26" @@ -363,6 +545,18 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "h2" version = "0.3.15" @@ -412,6 +606,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + [[package]] name = "http" version = "0.2.9" @@ -545,6 +745,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.2", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.7.1" @@ -576,6 +787,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -588,6 +808,12 @@ version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "log" version = "0.4.19" @@ -648,6 +874,7 @@ dependencies = [ name = "mastodon-image-uploader-bot" version = "0.2.0" dependencies = [ + "async-std", "log", "mastodon-async", "reqwest", @@ -780,6 +1007,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parse_link_header" version = "0.3.3" @@ -834,6 +1067,22 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "proc-macro2" version = "1.0.64" @@ -938,6 +1187,20 @@ dependencies = [ "winreg", ] +[[package]] +name = "rustix" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + [[package]] name = "ryu" version = "1.0.12" @@ -1566,6 +1829,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" version = "2.3.2" @@ -1746,6 +2015,15 @@ dependencies = [ "windows-targets 0.42.1", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.1", +] + [[package]] name = "windows-targets" version = "0.42.1" diff --git a/Cargo.toml b/Cargo.toml index 4e10a40..39e552a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,8 @@ serde = "1.0.171" toml = "0.7.1" log = "0.4.19" stderrlog = "0.5.4" +async-std = "1.12.0" [dependencies.mastodon-async] version = "1.0" -features = ["toml", "mt"] \ No newline at end of file +features = ["toml", "mt"] diff --git a/src/main.rs b/src/main.rs index fd89a16..78293b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,19 @@ +use async_std; +use log; use mastodon_async::entities::visibility::Visibility; use mastodon_async::helpers::{cli, toml as masto_toml}; use mastodon_async::prelude::*; -use mastodon_async::Result as MastoResult; use reqwest; use serde::Deserialize; use std::collections::HashSet; -use std::error::Error; use std::io::{Cursor, Write}; -use std::process::{exit, Command}; +use std::process::exit; +use std::time::Duration; use toml; -use log; - const CONFIG_FILENAME: &str = "config.toml"; -type DynResult = Result>; +type DynResult = Result>; #[derive(Deserialize)] struct Config { @@ -77,12 +76,14 @@ async fn main() -> DynResult<()> { let mut retry: u8 = 0; while let Err(err) = post_image(&mastodon, &url, &config).await { log::warn!("Cannot post image, retry: {}, {}", retry, err); + async_std::task::sleep(Duration::new(1, 0)).await; 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); + async_std::task::sleep(Duration::new(1, 0)).await; } exit(1); } @@ -90,6 +91,7 @@ async fn main() -> DynResult<()> { let mut retry: u8 = 0; while let Err(err) = update_bio(&mastodon, &config).await { log::warn!("Cannot update bio, retry: {}, {}", retry, err); + async_std::task::sleep(Duration::new(1, 0)).await; retry += 1; if retry >= config.errors.retry { log::error!("Max ammount of retries reached on update bio"); @@ -101,6 +103,7 @@ async fn main() -> DynResult<()> { let mut retry: u8 = 0; while let Err(err) = post(&mastodon, &config.errors.out_of_images).await { log::warn!("Cannot post, retry: {}, {}", retry, err); + async_std::task::sleep(Duration::new(1, 0)).await; retry += 1; if retry >= config.errors.retry { log::error!("Max ammount of retries reached on post"); @@ -157,7 +160,7 @@ fn get_next_url(config: &Config) -> DynResult> { } async fn post_image(account: &Mastodon, url: &String, config: &Config) -> DynResult<()> { - fetch_url(url.to_string(), &config.files.tempfile).await?; //.expect("Error fetching url"); + fetch_url(url, &config.files.tempfile).await?; //.expect("Error fetching url"); let attachment = account .media(&config.files.tempfile, Some(url.to_string())) .await?; //.expect("Attachment upload error"); @@ -179,27 +182,27 @@ async fn update_bio(account: &Mastodon, config: &Config) -> DynResult<()> { 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()? //.expect("Could not spawn curl") - .wait()?; //.expect("Curl failed"); + let remaining = urls.difference(&posted).count(); + let client = reqwest::Client::new(); + + let response = client + .patch(&format!( + "{}/api/v1/accounts/update_credentials", + config.bot.instance + )) + .bearer_auth(&account.data.token) + .body(format!( + "note={}\n\n{} new images remaining", + config.bot.bio, remaining + )) + .send() + .await?; + log::info!("Bio updated, response status: {}", response.status()); Ok(()) } -async fn post(account: &Mastodon, msg: &str) -> MastoResult<()> { +async fn post(account: &Mastodon, msg: &str) -> DynResult<()> { let status = StatusBuilder::new() .visibility(Visibility::Direct) .status(msg) @@ -209,7 +212,7 @@ async fn post(account: &Mastodon, msg: &str) -> MastoResult<()> { Ok(()) } -async fn fetch_url(url: String, file_name: &String) -> MastoResult<()> { +async fn fetch_url(url: &String, file_name: &String) -> DynResult<()> { let response = reqwest::get(url); let mut file = std::fs::File::create(file_name)?; let mut content = Cursor::new(response.await?.bytes().await?); @@ -217,7 +220,7 @@ async fn fetch_url(url: String, file_name: &String) -> MastoResult<()> { Ok(()) } -async fn register(config: &Config) -> MastoResult { +async fn register(config: &Config) -> DynResult { let registration = Registration::new(&config.bot.instance) .client_name(&config.bot.name) .scopes(Scopes::write_all())