Made it functional, adding a bunch of blocking api stuff. A while ago so idk really.

This commit is contained in:
vorboyvo 2025-11-12 15:10:38 -05:00
parent 71da65576b
commit acec764eac
4 changed files with 44 additions and 28 deletions

View file

@ -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::<Vec<&str>>()

View file

@ -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()

View file

@ -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))

View file

@ -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<String, Error> {
}
}
pub async fn title_from_slug(slug: String) -> Result<String, Error> {
pub fn title_from_slug(slug: String) -> Result<String, Error> {
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<String, Error> {
}
pub async fn post_body(link: String) -> Result<String, Error> {
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())