Added core functionality.
This commit is contained in:
parent
ed40f2e299
commit
7a12fc4490
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fs::{read_to_string, write, File};
|
use std::fs::{read_to_string, write};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -15,6 +14,7 @@ impl From<io::Error> for FileError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
pub struct LinksFile<'a>(&'a Path);
|
pub struct LinksFile<'a>(&'a Path);
|
||||||
|
|
||||||
impl<'a> LinksFile<'a> {
|
impl<'a> LinksFile<'a> {
|
||||||
|
|
|
||||||
44
src/main.rs
44
src/main.rs
|
|
@ -1,23 +1,15 @@
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use file::{FileError, LinksFile};
|
|
||||||
use mastodon::Mastodon;
|
|
||||||
|
|
||||||
mod file;
|
mod file;
|
||||||
mod wikipedia;
|
mod wikipedia;
|
||||||
mod mastodon;
|
mod mastodon;
|
||||||
|
mod server;
|
||||||
|
|
||||||
fn main() {
|
use file::{FileError, LinksFile};
|
||||||
dotenv::dotenv().ok();
|
use mastodon::{Mastodon, Visibility};
|
||||||
let app_code = std::env::var("APP_CODE").expect("APP_CODE required.");
|
use wikipedia::post_body;
|
||||||
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 queue = LinksFile::new(Path::new("queue.txt"));
|
|
||||||
let backup = LinksFile::new(Path::new("backup.txt"));
|
|
||||||
|
|
||||||
let mastodon = Mastodon::new(app_instance, app_token);
|
|
||||||
|
|
||||||
|
async fn post_link_from_file(queue: LinksFile<'_>, backup: LinksFile<'_>, mastodon: Mastodon) {
|
||||||
// get link to post
|
// get link to post
|
||||||
let link_to_post = match queue.remove_first_line() {
|
let link_to_post = match queue.remove_first_line() {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
|
|
@ -27,5 +19,29 @@ fn main() {
|
||||||
},
|
},
|
||||||
Err(d) => panic!("{d:?}")
|
Err(d) => panic!("{d:?}")
|
||||||
};
|
};
|
||||||
println!("{link_to_post}")
|
// 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::Direct).await.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 queue = LinksFile::new(Path::new("queue.txt"));
|
||||||
|
let backup = LinksFile::new(Path::new("backup.txt"));
|
||||||
|
let mastodon = Mastodon::new(app_instance, app_token);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use reqwest::{blocking::multipart, StatusCode};
|
use reqwest::{multipart, StatusCode};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
ReqwestError(reqwest::Error),
|
ReqwestError(reqwest::Error),
|
||||||
FailureStatus(reqwest::StatusCode)
|
FailureStatus(reqwest::StatusCode)
|
||||||
|
|
@ -12,7 +13,7 @@ impl From<reqwest::Error> for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum Visibility {
|
pub enum Visibility {
|
||||||
Public,
|
Public,
|
||||||
Unlisted,
|
Unlisted,
|
||||||
Private,
|
Private,
|
||||||
|
|
@ -30,6 +31,7 @@ impl Visibility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Mastodon {
|
pub struct Mastodon {
|
||||||
instance: String,
|
instance: String,
|
||||||
token: String
|
token: String
|
||||||
|
|
@ -40,16 +42,16 @@ impl Mastodon {
|
||||||
Mastodon { instance, token }
|
Mastodon { instance, token }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn post_text_status(&self, status: String, visibility: Visibility) -> Result<(), Error> {
|
pub async fn post_text_status(&self, status: String, visibility: Visibility) -> Result<(), Error> {
|
||||||
let form = multipart::Form::new()
|
let form = multipart::Form::new()
|
||||||
.text("status", status)
|
.text("status", status)
|
||||||
.text("visibility", visibility.enum_name());
|
.text("visibility", visibility.enum_name());
|
||||||
let client = reqwest::blocking::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/api/v1/statuses", self.instance))
|
.post(format!("{}/api/v1/statuses", self.instance))
|
||||||
.header("Authorization", format!("Bearer {}", self.token))
|
.header("Authorization", format!("Bearer {}", self.token))
|
||||||
.multipart(form)
|
.multipart(form)
|
||||||
.send()?;
|
.send().await?;
|
||||||
match response.status() {
|
match response.status() {
|
||||||
StatusCode::OK => Ok(()),
|
StatusCode::OK => Ok(()),
|
||||||
s => Err(Error::FailureStatus(s))
|
s => Err(Error::FailureStatus(s))
|
||||||
|
|
|
||||||
0
src/server.rs
Normal file
0
src/server.rs
Normal file
|
|
@ -30,14 +30,14 @@ pub fn slug_from_link(link: String) -> Result<String, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title_from_slug(slug: String) -> Result<String, Error> {
|
pub async fn title_from_slug(slug: String) -> Result<String, Error> {
|
||||||
let escaped_slug = slug.replace("/", "%2F");
|
let escaped_slug = slug.replace("/", "%2F");
|
||||||
let request_url =
|
let request_url =
|
||||||
format!(
|
format!(
|
||||||
"https://api.wikimedia.org/core/v1/wikipedia/en/page/{escaped_slug}/bare"
|
"https://api.wikimedia.org/core/v1/wikipedia/en/page/{escaped_slug}/bare"
|
||||||
);
|
);
|
||||||
let response = reqwest::blocking::get(request_url)?;
|
let response = reqwest::get(request_url).await?;
|
||||||
let json_body = response.text()?;
|
let json_body = response.text().await?;
|
||||||
let body = json::parse(&json_body)?;
|
let body = json::parse(&json_body)?;
|
||||||
match body["title"].as_str() {
|
match body["title"].as_str() {
|
||||||
Some(x) => Ok(x.to_string()),
|
Some(x) => Ok(x.to_string()),
|
||||||
|
|
@ -45,8 +45,8 @@ pub fn title_from_slug(slug: String) -> Result<String, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn post_body(link: String) -> Result<String, Error> {
|
pub async fn post_body(link: String) -> Result<String, Error> {
|
||||||
let title = title_from_slug(slug_from_link(link.clone())?)?;
|
let title = title_from_slug(slug_from_link(link.clone())?).await?;
|
||||||
Ok(format!("Today's wikipedia article is {title}\n\n\
|
Ok(format!("Today's wikipedia article is {title}\n\n\
|
||||||
{link}\n\n\
|
{link}\n\n\
|
||||||
#wikipedia").to_string())
|
#wikipedia").to_string())
|
||||||
|
|
@ -66,19 +66,19 @@ mod tests {
|
||||||
assert_eq!(slug_from_link("https://en.wikipedia.org/wiki/GNU/Linux_naming_controversy".to_string()).unwrap().as_str(), "GNU/Linux_naming_controversy")
|
assert_eq!(slug_from_link("https://en.wikipedia.org/wiki/GNU/Linux_naming_controversy".to_string()).unwrap().as_str(), "GNU/Linux_naming_controversy")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn test_title_from_slug_1() {
|
async fn test_title_from_slug_1() {
|
||||||
assert_eq!(title_from_slug("Buck-a-beer".to_string()).unwrap().as_str(), "Buck-a-beer")
|
assert_eq!(title_from_slug("Buck-a-beer".to_string()).await.unwrap().as_str(), "Buck-a-beer")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn test_title_from_slug_2() {
|
async fn test_title_from_slug_2() {
|
||||||
assert_eq!(title_from_slug("GNU/Linux_naming_controversy".to_string()).unwrap().as_str(), "GNU/Linux naming controversy")
|
assert_eq!(title_from_slug("GNU/Linux_naming_controversy".to_string()).await.unwrap().as_str(), "GNU/Linux naming controversy")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn test_post_body_1() {
|
async fn test_post_body_1() {
|
||||||
let body = post_body("https://en.wikipedia.org/wiki/GNU%2FLinux_naming_controversy".to_string()).unwrap();
|
let body = post_body("https://en.wikipedia.org/wiki/GNU%2FLinux_naming_controversy".to_string()).await.unwrap();
|
||||||
let expected = "Today's wikipedia article is GNU/Linux naming controversy\n\n\
|
let expected = "Today's wikipedia article is GNU/Linux naming controversy\n\n\
|
||||||
https://en.wikipedia.org/wiki/GNU%2FLinux_naming_controversy\n\n\
|
https://en.wikipedia.org/wiki/GNU%2FLinux_naming_controversy\n\n\
|
||||||
#wikipedia";
|
#wikipedia";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue