Added support for misskey publisher, and switching between publishers via config
This commit is contained in:
parent
677226a77f
commit
bd42f495dc
File diff suppressed because it is too large
Load Diff
|
@ -17,3 +17,5 @@ uuid = { version = "0.8.2", features = ["v4"] }
|
|||
anyhow = "1.0.41"
|
||||
mammut = "0.13.0"
|
||||
thiserror = "1.0.26"
|
||||
misskey = "0.2.0"
|
||||
url = "2.2.2"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{error::Error, path::Path};
|
||||
|
||||
use core::fmt::Debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{error::Error, path::Path};
|
||||
use telegram_bot::ChatId;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
|
@ -10,12 +10,12 @@ pub struct Config {
|
|||
pub temperature: String,
|
||||
pub top_k: String,
|
||||
pub gpt_code_path: String,
|
||||
pub fediverse_base_url: String,
|
||||
pub interval_seconds: MinMax,
|
||||
pub bot_token: String,
|
||||
pub chat_ref: ChatId,
|
||||
pub fediverse_token: Option<mammut::Data>,
|
||||
pub mastodon_token: Option<mammut::Data>,
|
||||
pub post_buffer: u32,
|
||||
pub publisher: Publisher,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
|
@ -24,6 +24,18 @@ pub struct MinMax {
|
|||
pub max: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub enum Publisher {
|
||||
Misskey(FediverseConfig<String>),
|
||||
Mastodon(FediverseConfig<Option<mammut::Data>>),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct FediverseConfig<T> {
|
||||
pub base_url: String,
|
||||
pub token: T,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Config {
|
||||
|
@ -32,15 +44,18 @@ impl Default for Config {
|
|||
temperature: String::from("1"),
|
||||
top_k: String::from("40"),
|
||||
gpt_code_path: String::from("./gpt/"),
|
||||
fediverse_base_url: String::from("https://lain.com"),
|
||||
interval_seconds: MinMax {
|
||||
min: 60 * 30,
|
||||
max: 60 * 90,
|
||||
},
|
||||
post_buffer: 5,
|
||||
fediverse_token: None,
|
||||
mastodon_token: None,
|
||||
bot_token: "".to_owned(),
|
||||
chat_ref: ChatId::new(0),
|
||||
publisher: Publisher::Misskey(FediverseConfig {
|
||||
base_url: "".to_string(),
|
||||
token: "".to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
79
src/main.rs
79
src/main.rs
|
@ -10,11 +10,13 @@ use rand::Rng;
|
|||
use telegram_bot::{Api, ChatId, ChatRef, ToChatRef};
|
||||
|
||||
use crate::{
|
||||
config::{FediverseConfig, Publisher},
|
||||
publish::MastodonPublisher,
|
||||
publish::MisskeyPublisher,
|
||||
selection::{telegram::get_chat_ref, SelectorExt, TelegramSelector},
|
||||
};
|
||||
|
||||
use futures::{channel::mpsc::channel, sink::unfold, SinkExt, StreamExt, TryStreamExt};
|
||||
use futures::{SinkExt, StreamExt, TryStreamExt, channel::mpsc::channel, future::Either, sink::unfold};
|
||||
use model::SampleModelExt;
|
||||
|
||||
mod config;
|
||||
|
@ -38,34 +40,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
}?;
|
||||
|
||||
let app = AppBuilder {
|
||||
client_name: "izzilis",
|
||||
redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
|
||||
scopes: Scopes::Write,
|
||||
website: None,
|
||||
};
|
||||
|
||||
let mut registration = Registration::new(cfg.fediverse_base_url.clone());
|
||||
registration.register(app)?;
|
||||
|
||||
let mastodon = if let Some(data) = &cfg.fediverse_token {
|
||||
Mastodon::from_data(data.clone())
|
||||
} else {
|
||||
let url = registration.authorise()?;
|
||||
println!("{}", url);
|
||||
|
||||
let mut buffer = String::new();
|
||||
stdin().read_line(&mut buffer).await?;
|
||||
|
||||
let fedi = registration.create_access_token(buffer)?;
|
||||
|
||||
cfg.fediverse_token = Some(fedi.data.clone());
|
||||
cfg.save(CONFIG_PATH)?;
|
||||
|
||||
fedi
|
||||
};
|
||||
|
||||
let publisher = MastodonPublisher::new(mastodon);
|
||||
let publisher = resolve_publisher(&mut cfg).await?;
|
||||
|
||||
let api = Arc::new(Api::new(cfg.bot_token.clone()));
|
||||
|
||||
|
@ -145,7 +120,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
});
|
||||
|
||||
publisher
|
||||
.sink_map_err(|e| Box::new(e) as Box<dyn Error>)
|
||||
.sink_map_err(|e| e)
|
||||
.send_all(
|
||||
&mut receiver
|
||||
.then(|item| {
|
||||
|
@ -165,3 +140,47 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
async fn resolve_publisher(
|
||||
config: &mut config::Config,
|
||||
) -> Result<Either<MisskeyPublisher, MastodonPublisher>, Box<dyn Error>> {
|
||||
let publisher = match &config.publisher {
|
||||
config::Publisher::Misskey(cfg) => {
|
||||
Either::Left(MisskeyPublisher::new(&cfg.base_url, cfg.token.clone())?)
|
||||
}
|
||||
config::Publisher::Mastodon(cfg) => {
|
||||
let app = AppBuilder {
|
||||
client_name: "izzilis",
|
||||
redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
|
||||
scopes: Scopes::Write,
|
||||
website: None,
|
||||
};
|
||||
|
||||
let mut registration = Registration::new(cfg.base_url.clone());
|
||||
registration.register(app)?;
|
||||
|
||||
let mastodon = if let Some(data) = cfg.token.clone() {
|
||||
Mastodon::from_data(data.clone())
|
||||
} else {
|
||||
let url = registration.authorise()?;
|
||||
println!("{}", url);
|
||||
|
||||
let mut buffer = String::new();
|
||||
stdin().read_line(&mut buffer).await?;
|
||||
|
||||
let fedi = registration.create_access_token(buffer)?;
|
||||
|
||||
config.publisher = Publisher::Mastodon(FediverseConfig {
|
||||
base_url: cfg.base_url.clone(),
|
||||
token: Some(fedi.data.clone()),
|
||||
});
|
||||
config.save(CONFIG_PATH)?;
|
||||
|
||||
fedi
|
||||
};
|
||||
|
||||
Either::Right(MastodonPublisher::new(mastodon))
|
||||
}
|
||||
};
|
||||
Ok(publisher)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use std::{
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use std::{error::Error, pin::Pin, task::{Context, Poll}};
|
||||
|
||||
use futures::Sink;
|
||||
use mammut::{status_builder::Visibility, Mastodon, StatusBuilder};
|
||||
|
@ -17,7 +14,7 @@ impl MastodonPublisher {
|
|||
}
|
||||
|
||||
impl Sink<String> for MastodonPublisher {
|
||||
type Error = mammut::Error;
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
use futures::Sink;
|
||||
use misskey::{ClientExt, HttpClient};
|
||||
use std::{error::Error, task::Poll};
|
||||
use tokio::runtime::Runtime;
|
||||
use url::Url;
|
||||
|
||||
pub struct MisskeyPublisher {
|
||||
client: HttpClient,
|
||||
}
|
||||
|
||||
impl MisskeyPublisher {
|
||||
pub fn new(url: &String, token: String) -> Result<Self, Box<dyn Error>> {
|
||||
Ok(Self {
|
||||
client: HttpClient::with_token(Url::parse(url)?, token)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Sink<String> for MisskeyPublisher {
|
||||
type Error = Box<dyn Error>;
|
||||
|
||||
fn poll_ready(
|
||||
self: std::pin::Pin<&mut Self>,
|
||||
_: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn start_send(self: std::pin::Pin<&mut Self>, item: String) -> Result<(), Self::Error> {
|
||||
let mut runtime = Runtime::new()?;
|
||||
let fut = self.client.create_note(item);
|
||||
runtime.block_on(fut)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn poll_flush(
|
||||
self: std::pin::Pin<&mut Self>,
|
||||
_: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn poll_close(
|
||||
self: std::pin::Pin<&mut Self>,
|
||||
_: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
}
|
|
@ -1,2 +1,4 @@
|
|||
mod mastodon;
|
||||
mod misskey;
|
||||
pub use mastodon::MastodonPublisher;
|
||||
pub use crate::publish::misskey::MisskeyPublisher;
|
||||
|
|
Loading…
Reference in New Issue