master
Ondřej Hruška 5 years ago
parent 80e0fce32a
commit dc88755e7b
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 22
      src/bootstrap.rs
  2. 87
      src/ele.rs
  3. 85
      src/main.rs

@ -3,6 +3,13 @@ use std::io::Read;
use failure::Fallible; use failure::Fallible;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use crate::store::Store;
use crate::Config;
use elefren::{Registration, Mastodon};
use elefren::http_send::HttpSender;
use elefren::helpers::cli;
use elefren::scopes::Scopes;
use std::str::FromStr;
const CONFIG_FILE: &str = "manabu.toml"; const CONFIG_FILE: &str = "manabu.toml";
@ -12,20 +19,11 @@ const SOFTWARE_NAME: &str = env!("CARGO_PKG_NAME");
/// to allow using e.g. TRACE without drowing our custom messages /// to allow using e.g. TRACE without drowing our custom messages
const SPAMMY_LIBS: [&str; 6] = ["tokio_reactor", "hyper", "reqwest", "mio", "want", "elefren"]; const SPAMMY_LIBS: [&str; 6] = ["tokio_reactor", "hyper", "reqwest", "mio", "want", "elefren"];
#[derive(SmartDefault,Serialize,Deserialize,Debug)]
#[serde(default)]
pub struct Config {
#[default="info"]
logging: String,
pub instance: String,
#[default="manabu_store.json"]
pub store: String,
}
const LOG_LEVELS: [&str; 5] = ["error", "warn", "info", "debug", "trace"]; const LOG_LEVELS: [&str; 5] = ["error", "warn", "info", "debug", "trace"];
/// Load the shared config file /// Load the shared config file
fn load_config(file: &str) -> Fallible<Config> { pub fn load_config(file: &str) -> Fallible<Config> {
let mut file = File::open(file)?; let mut file = File::open(file)?;
let mut buf = String::new(); let mut buf = String::new();
@ -41,7 +39,7 @@ fn load_config(file: &str) -> Fallible<Config> {
Ok(config) Ok(config)
} }
pub(crate) fn init() -> Fallible<Config> { pub fn handle_cli_args_and_load_config() -> Fallible<Config> {
let version = format!("{}, built from {}", env!("CARGO_PKG_VERSION"), env!("GIT_REV")); let version = format!("{}, built from {}", env!("CARGO_PKG_VERSION"), env!("GIT_REV"));
let argv = let argv =
clap::App::new(SOFTWARE_NAME) clap::App::new(SOFTWARE_NAME)

@ -0,0 +1,87 @@
use std::fs::File;
use std::io::Read;
use failure::Fallible;
use serde::Deserialize;
use serde::Serialize;
use crate::store::Store;
use crate::Config;
use elefren::{Registration, Mastodon};
use elefren::http_send::HttpSender;
use elefren::helpers::cli;
use elefren::scopes::Scopes;
use std::str::FromStr;
const KEY_OAUTH_REGISTRATION: &str = "oauth.registration";
const KEY_OAUTH_SESSION: &str = "oauth.session";
pub type EleRegistratered = elefren::registration::Registered<HttpSender>;
pub type EleSession = elefren::Mastodon<HttpSender>;
pub type EleWebsocket = websocket::sync::Client<native_tls::TlsStream<std::net::TcpStream>>;
/// Wrapper for the long tuple with Registration state
#[derive(Serialize,Deserialize,Debug)]
pub struct ElefrenRegistration {
pub parts: (String, String, String, String, Scopes, bool),
}
/// Register "app" in the server software
pub fn register(store : &mut Store, config : &Config) -> EleRegistratered {
match store.get::<ElefrenRegistration>(KEY_OAUTH_REGISTRATION) {
Some(reg) => {
info!("Loaded registration from store");
EleRegistratered::from_parts(
// this sucks
&reg.parts.0, &reg.parts.1, &reg.parts.2, &reg.parts.3, reg.parts.4, reg.parts.5
)
}
None => {
info!("Creating a new registration");
let registered = Registration::new(&format!("https://{}", config.instance))
.client_name("manabu")
.scopes(Scopes::from_str("read write").expect("err parse scopes"))
.build().expect("error register");
store.put(KEY_OAUTH_REGISTRATION, ElefrenRegistration { parts : registered.clone().into_parts() });
registered
}
}
}
pub fn open_session(store : &mut Store, registered: EleRegistratered) -> EleSession {
match store.get::<elefren::Data>(KEY_OAUTH_SESSION) {
Some(data) => {
info!("Reusing saved authorization.");
let cli = Mastodon::from(data);
// TODO check if the session is live, somehow
cli
}
None => {
info!("Creating new authorization.");
let cli = cli::authenticate(registered).expect("error auth");
store.put(KEY_OAUTH_SESSION, cli.data.clone());
cli
}
}
}
pub fn open_stream_websocket(session : &EleSession, stream_name : &str) -> EleWebsocket {
let connector = native_tls::TlsConnector::new().unwrap();
let hostname = &session.data.base[session.data.base.find("://").unwrap()+3..];
let url = format!("wss://{host}/api/v1/streaming/?stream={sname}&access_token={token}",
host=hostname,
sname=stream_name,
token=session.data.token);
debug!("WS url = {}", &url);
websocket::ClientBuilder::new(&url)
.expect("Error create ClientBuilder")
.connect_secure(Some(connector))
.expect("Error connect to wss")
}

@ -15,54 +15,46 @@ use elefren::{
}; };
use failure::Fallible; use failure::Fallible;
use crate::bootstrap::Config;
use crate::store::Store;
use native_tls::TlsConnector; use native_tls::TlsConnector;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::net::TcpStream; use std::net::TcpStream;
use websocket::OwnedMessage; use websocket::{OwnedMessage, ClientBuilder};
mod bootstrap; mod bootstrap;
mod store; mod store;
mod ele;
type EleRegistratered = elefren::registration::Registered<HttpSender>; use crate::bootstrap::handle_cli_args_and_load_config;
/// Wrapper for the long tuple with Registration state use crate::store::Store;
#[derive(Serialize,Deserialize,Debug)]
struct ElefrenRegistration {
parts: (String, String, String, String, Scopes, bool),
}
const KEY_OAUTH_REGISTRATION: &str = "elefren.registration"; #[derive(SmartDefault,Serialize,Deserialize,Debug)]
const KEY_OAUTH_SESSION: &str = "elefren.session"; #[serde(default)]
pub struct Config {
#[default="info"]
pub logging: String,
pub instance: String,
#[default="manabu_store.json"]
pub store: String,
}
fn main() { fn main() {
let config : Config = bootstrap::init().expect("error init config"); let config : Config = handle_cli_args_and_load_config().expect("error init");
debug!("Loaded config: {:#?}", config); debug!("Loaded config: {:#?}", config);
let mut store = Store::from_file(&config.store); let mut store = Store::from_file(&config.store);
store.set_autosave(true); store.set_autosave(true);
let registered = register(&mut store, &config); let registered = ele::register(&mut store, &config);
let client = open_session(&mut store, registered); let session = ele::open_session(&mut store, registered);
debug!("Listening to events"); debug!("Listening to events");
let connector = TlsConnector::new().unwrap(); let mut socket = ele::open_stream_websocket(&session, "user");
use websocket::ClientBuilder;
let url = format!("wss://{host}/api/v1/streaming/?stream=user&access_token={token}", host=config.instance, token=client.data.token); for m in socket.incoming_messages() {
debug!("WS url = {}", &url);
let mut client = ClientBuilder::new(&url)
.expect("Error create ClientBuilder")
.connect_secure(Some(connector))
.expect("Error connect to wss");
for m in client.incoming_messages() {
match m { match m {
Ok(OwnedMessage::Text(text)) => { Ok(OwnedMessage::Text(text)) => {
debug!("Got msg: {}", text); debug!("Got msg: {}", text);
@ -82,44 +74,3 @@ fn main() {
} }
info!("Exit."); info!("Exit.");
} }
fn register(store : &mut Store, config : &Config) -> EleRegistratered {
match store.get::<ElefrenRegistration>(KEY_OAUTH_REGISTRATION) {
Some(reg) => {
info!("Loaded registration from store");
EleRegistratered::from_parts(
// this sucks
&reg.parts.0, &reg.parts.1, &reg.parts.2, &reg.parts.3, reg.parts.4, reg.parts.5
)
}
None => {
info!("Creating a new registration");
let registered = Registration::new(&format!("https://{}", config.instance))
.client_name("manabu")
.build().expect("error register");
store.put(KEY_OAUTH_REGISTRATION, ElefrenRegistration { parts : registered.clone().into_parts() });
registered
}
}
}
fn open_session(store : &mut Store, registered: EleRegistratered) -> Mastodon<HttpSender> {
match store.get::<elefren::Data>(KEY_OAUTH_SESSION) {
Some(data) => {
info!("Reusing saved authorization.");
let cli = Mastodon::from(data);
// TODO check if the session is live, somehow
cli
}
None => {
info!("Creating new authorization.");
let cli = cli::authenticate(registered).expect("error auth");
store.put(KEY_OAUTH_SESSION, cli.data.clone());
cli
}
}
}

Loading…
Cancel
Save