From acec764eac7f671ce4893050e9f704a2d1196155 Mon Sep 17 00:00:00 2001 From: vorboyvo Date: Wed, 12 Nov 2025 15:10:38 -0500 Subject: [PATCH] Made it functional, adding a bunch of blocking api stuff. A while ago so idk really. --- src/file.rs | 4 ++-- src/main.rs | 28 +++++++++++++--------------- src/mastodon.rs | 21 ++++++++++++++------- src/wikipedia.rs | 19 +++++++++++++++---- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/file.rs b/src/file.rs index ffdfa60..f29e2e8 100644 --- a/src/file.rs +++ b/src/file.rs @@ -36,13 +36,13 @@ impl<'a> LinksFile<'a> { let file_contents = read_to_string(self.0)?; let mut file_lines = file_contents.split("\n"); let mut line = file_lines.next(); + // run through all empty lines while let Some("") = line { line = file_lines.next(); }; let line_clean = match line { - Some("") => return Err(FileError::EmptyLine), Some(a) => a, - None => panic!("Iterator returns None, something wrong happened") + None => return Err(FileError::EmptyLine) }; let rest_of_file = file_lines .collect::>() diff --git a/src/main.rs b/src/main.rs index 42727e8..d7a559c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use std::path::Path; -use tokio::{spawn}; +use tokio::{spawn, task::spawn_blocking}; use tokio_cron_scheduler::{Job, JobScheduler}; mod file; @@ -24,35 +24,33 @@ async fn post_link_from_file(queue: LinksFile<'_>, backup: LinksFile<'_>, mastod // convert said link into a post status let post_status = post_body(link_to_post).await.unwrap(); // post it on mastodon - mastodon.post_text_status(post_status, Visibility::Public).await.unwrap(); + spawn_blocking( + move || { + mastodon.post_text_status(post_status, Visibility::Public).unwrap(); + } + ); } #[tokio::main] async fn main() { dotenv::dotenv().ok(); // let app_code = std::env::var("APP_CODE").expect("APP_CODE required."); - let app_token = std::env::var("APP_TOKEN").expect("APP_TOKEN required."); - let app_instance = std::env::var("APP_INSTANCE").expect("APP_INSTANCE required."); + let dwh_app_token = std::env::var("DWH_APP_TOKEN").expect("DWH_APP_TOKEN required."); + let dwh_app_instance = std::env::var("DWH_APP_INSTANCE").expect("DWH_APP_INSTANCE required."); + let dwh_cron_schedule = std::env::var("DWH_CRON_SCHEDULE").expect("DWH_CRON_SCHEDULE required."); let sched = JobScheduler::new().await.unwrap(); sched.add( - Job::new_async("0 0 8 * * *", move |_uuid, _l| { + Job::new_async(dwh_cron_schedule, move |_uuid, _l| { Box::pin({ - let app_instance_cloned = app_instance.clone(); - let app_token_cloned = app_token.clone(); + let app_instance_cloned = dwh_app_instance.clone(); + let app_token_cloned = dwh_app_token.clone(); async move { let queue = LinksFile::new(Path::new("queue.txt")); let backup = LinksFile::new(Path::new("backup.txt")); let mastodon = Mastodon::new(app_instance_cloned, app_token_cloned); - - let mut interval_timer = tokio::time::interval( - chrono::Duration::minutes(10).to_std().unwrap() - ); - loop { - interval_timer.tick().await; - post_link_from_file(queue, backup, mastodon.clone()).await; - }; + post_link_from_file(queue, backup, mastodon.clone()).await; } }) }).unwrap() diff --git a/src/mastodon.rs b/src/mastodon.rs index 54c70fa..3996206 100644 --- a/src/mastodon.rs +++ b/src/mastodon.rs @@ -1,4 +1,4 @@ -use reqwest::{multipart, StatusCode}; +use reqwest::{blocking::{Client, multipart}, StatusCode}; #[derive(Debug)] pub enum Error { @@ -34,24 +34,31 @@ impl Visibility { #[derive(Clone)] pub struct Mastodon { instance: String, - token: String + token: String, } impl Mastodon { pub fn new(instance: String, token: String) -> Self { - Mastodon { instance, token } + Mastodon { + instance, + token, + + } } - pub async fn post_text_status(&self, status: String, visibility: Visibility) -> Result<(), Error> { + pub fn post_text_status(&self, status: String, visibility: Visibility) -> Result<(), Error> { let form = multipart::Form::new() .text("status", status) .text("visibility", visibility.enum_name()); - let client = reqwest::Client::new(); - let response = client + let client = reqwest::blocking::Client::builder() + .danger_accept_invalid_certs(true) + .build() + .expect(""); + let response = client .post(format!("{}/api/v1/statuses", self.instance)) .header("Authorization", format!("Bearer {}", self.token)) .multipart(form) - .send().await?; + .send()?; match response.status() { StatusCode::OK => Ok(()), s => Err(Error::FailureStatus(s)) diff --git a/src/wikipedia.rs b/src/wikipedia.rs index 8317173..f42a1f5 100644 --- a/src/wikipedia.rs +++ b/src/wikipedia.rs @@ -1,4 +1,7 @@ use regex::Regex; +use tokio::task::spawn_blocking; + +static APP_USER_AGENT: &str = r"DailyWikiHuman/0.0 (https://en.wikipedia.org/wiki/User:WittyWidi) generic-library/0.0"; #[derive(Debug)] pub enum Error{ @@ -30,14 +33,19 @@ pub fn slug_from_link(link: String) -> Result { } } -pub async fn title_from_slug(slug: String) -> Result { +pub fn title_from_slug(slug: String) -> Result { let escaped_slug = slug.replace("/", "%2F"); + let client = reqwest::blocking::Client::builder() + .user_agent(APP_USER_AGENT) + .build() + .expect(""); let request_url = format!( "https://api.wikimedia.org/core/v1/wikipedia/en/page/{escaped_slug}/bare" ); - let response = reqwest::get(request_url).await?; - let json_body = response.text().await?; + let response = client.get(request_url).send()?; + let json_body = response.text()?; + println!("{:?}", json_body); let body = json::parse(&json_body)?; match body["title"].as_str() { Some(x) => Ok(x.to_owned()), @@ -46,7 +54,10 @@ pub async fn title_from_slug(slug: String) -> Result { } pub async fn post_body(link: String) -> Result { - let title = title_from_slug(slug_from_link(link.clone())?).await?; + let link_copy = link.clone(); + let title = spawn_blocking( + move || {title_from_slug(slug_from_link(link_copy)?)} + ).await.expect("failed with JoinError")?; Ok(format!("Today's wikipedia article is {title}\n\n\ {link}\n\n\ #wikipedia").to_owned())