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; pub type EleSession = elefren::Mastodon; pub type EleWebsocket = websocket::sync::Client>; /// 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::(KEY_OAUTH_REGISTRATION) { Some(reg) => { info!("Loaded registration from store"); EleRegistratered::from_parts( // this sucks ®.parts.0, ®.parts.1, ®.parts.2, ®.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::(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") }