izzilis/src/publish.rs

84 lines
2.1 KiB
Rust

use std::{convert::Infallible, error::Error};
use elefren::{
helpers::{cli, toml},
scopes::Scopes,
status_builder::Visibility,
Language, Mastodon, MastodonClient, Registration, StatusBuilder,
};
const FEDIVERSE_TOML_PATH: &str = "fediverse.toml";
pub trait Publisher {
type Error;
fn publish(&self, content: String) -> Result<(), Self::Error>;
}
pub struct FediversePublisher {
client: Mastodon,
}
pub struct ConsolePublisher;
impl Publisher for ConsolePublisher {
type Error = Infallible;
fn publish(&self, content: String) -> Result<(), Self::Error> {
println!("Publishing content to stdout: {}", content);
Ok(())
}
}
impl ConsolePublisher {
pub fn new() -> ConsolePublisher {
ConsolePublisher {}
}
}
impl FediversePublisher {
pub fn new(fedi_url: String) -> Result<FediversePublisher, Box<dyn Error>> {
Ok(Self {
client: toml::from_file(FEDIVERSE_TOML_PATH)
.map(|data| Ok(Mastodon::from(data)))
.unwrap_or_else(|_| register(fedi_url))?,
})
}
}
impl Publisher for FediversePublisher {
type Error = Box<dyn Error>;
fn publish(&self, content: String) -> Result<(), Self::Error> {
let status = StatusBuilder::new()
.status(&content)
// .visibility(Visibility::Direct)
.visibility(Visibility::Public)
.sensitive(false)
.language(Language::Eng)
.build()
.map_err(|e| Box::new(e) as Box<dyn Error>)?;
println!("Posting status [{}] to fediverse", &content);
self.client
.new_status(status)
.map_err(|e| Box::new(e) as Box<dyn Error>)?;
Ok(())
}
}
fn register(fedi_url: String) -> Result<Mastodon, Box<dyn Error>> {
let registration = Registration::new(fedi_url)
.client_name("izzilis")
.scopes(Scopes::write_all())
.build()?;
let fediverse = cli::authenticate(registration)?;
// Save app data for using on the next run.
toml::to_file(&*fediverse, FEDIVERSE_TOML_PATH.to_string())?;
Ok(fediverse)
}