add pretty printing to json store, move notif handling to a thread

master
Ondřej Hruška 5 years ago
parent dc88755e7b
commit 176bde9d01
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 11
      src/bootstrap.rs
  2. 19
      src/ele.rs
  3. 54
      src/main.rs
  4. 18
      src/store.rs

@ -1,15 +1,9 @@
//! Application start-up code handling CLI args, logging, config file load etc
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 CONFIG_FILE: &str = "manabu.toml";
@ -39,6 +33,7 @@ pub fn load_config(file: &str) -> Fallible<Config> {
Ok(config)
}
/// Boot up the application. Initializes common stuff and returns the loaded config.
pub fn handle_cli_args_and_load_config() -> Fallible<Config> {
let version = format!("{}, built from {}", env!("CARGO_PKG_VERSION"), env!("GIT_REV"));
let argv =

@ -1,6 +1,5 @@
use std::fs::File;
use std::io::Read;
use failure::Fallible;
//! Mastodon API types and functions building on elefren
use serde::Deserialize;
use serde::Serialize;
use crate::store::Store;
@ -10,13 +9,14 @@ use elefren::http_send::HttpSender;
use elefren::helpers::cli;
use elefren::scopes::Scopes;
use std::str::FromStr;
use failure::Fallible;
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>>;
pub type EleStreamSocket = websocket::sync::Client<native_tls::TlsStream<std::net::TcpStream>>;
/// Wrapper for the long tuple with Registration state
#[derive(Serialize,Deserialize,Debug)]
@ -49,6 +49,7 @@ pub fn register(store : &mut Store, config : &Config) -> EleRegistratered {
}
}
/// Open mastodon API session (get access token)
pub fn open_session(store : &mut Store, registered: EleRegistratered) -> EleSession {
match store.get::<elefren::Data>(KEY_OAUTH_SESSION) {
Some(data) => {
@ -68,8 +69,9 @@ pub fn open_session(store : &mut Store, registered: EleRegistratered) -> EleSess
}
}
pub fn open_stream_websocket(session : &EleSession, stream_name : &str) -> EleWebsocket {
let connector = native_tls::TlsConnector::new().unwrap();
/// Open streaming api websocket
pub fn open_stream_websocket(session : &EleSession, stream_name : &str) -> Fallible<EleStreamSocket> {
let connector = native_tls::TlsConnector::new()?;
let hostname = &session.data.base[session.data.base.find("://").unwrap()+3..];
@ -80,8 +82,7 @@ pub fn open_stream_websocket(session : &EleSession, stream_name : &str) -> EleWe
debug!("WS url = {}", &url);
websocket::ClientBuilder::new(&url)
Ok(websocket::ClientBuilder::new(&url)
.expect("Error create ClientBuilder")
.connect_secure(Some(connector))
.expect("Error connect to wss")
.connect_secure(Some(connector))?)
}

@ -6,19 +6,9 @@ extern crate failure;
extern crate smart_default;
#[macro_use]
extern crate serde;
#[macro_use]
use elefren::{
helpers::cli,
prelude::*,
entities::prelude::*,
http_send::HttpSender,
};
use failure::Fallible;
use native_tls::TlsConnector;
use std::io::{Read, Write};
use std::net::TcpStream;
use websocket::{OwnedMessage, ClientBuilder};
use websocket::{OwnedMessage};
use std::thread;
mod bootstrap;
mod store;
@ -27,13 +17,18 @@ mod ele;
use crate::bootstrap::handle_cli_args_and_load_config;
use crate::store::Store;
use crate::ele::{EleSession, EleStreamSocket};
use std::time::Duration;
#[derive(SmartDefault,Serialize,Deserialize,Debug)]
#[serde(default)]
pub struct Config {
/// Logging level to use (can be increased using -v flags)
#[default="info"]
pub logging: String,
/// Instance domain name, e.g. example.com
pub instance: String,
/// File to use for session storage
#[default="manabu_store.json"]
pub store: String,
}
@ -45,6 +40,7 @@ fn main() {
let mut store = Store::from_file(&config.store);
store.set_autosave(true);
store.set_pretty_print(true);
let registered = ele::register(&mut store, &config);
@ -52,25 +48,43 @@ fn main() {
debug!("Listening to events");
let mut socket = ele::open_stream_websocket(&session, "user");
let m_session = session.clone();
let handle = thread::spawn(move || handle_stream(m_session));
let _ = handle.join();
}
fn handle_stream(session : EleSession) -> ! {
loop {
debug!("Trying to open websocket");
match ele::open_stream_websocket(&session, "user") {
Ok(socket) => process_incoming_events(socket),
Err(e) => error!("Error opening socket: {}", e)
}
debug!("Delay before reconnecting...");
thread::sleep(Duration::from_secs(10));
}
}
for m in socket.incoming_messages() {
fn process_incoming_events(mut socket : EleStreamSocket) {
'listen: for m in socket.incoming_messages() {
match m {
Ok(OwnedMessage::Text(text)) => {
debug!("Got msg: {}", text);
},
Ok(OwnedMessage::Close(text)) => {
Ok(OwnedMessage::Close(_text)) => {
debug!("Close");
break;
break 'listen;
},
Ok(any) => {
debug!("Unhandled msg: {:?}", any);
}
Err(e) => {
error!("{}", e);
break;
error!("Error reading from socket: {}", e);
break 'listen;
},
}
}
info!("Exit.");
}

@ -1,3 +1,7 @@
#![allow(unused)]
//! JSON store
use std::borrow::Cow;
use serde::{Serialize, Deserialize};
use serde::de::DeserializeOwned;
@ -18,6 +22,7 @@ use std::fmt::{self, Display, Formatter};
pub struct Store {
path: Option<PathBuf>,
autosave: bool,
prettysave: bool,
items: Map<String, serde_json::Value>,
}
@ -26,6 +31,7 @@ impl Default for Store {
Self {
path: None,
autosave: false,
prettysave: false,
items: Map::new()
}
}
@ -82,6 +88,7 @@ impl Store {
let mut store = Store {
path: Some(path.as_ref().into()),
autosave: false,
prettysave: false,
items: Map::new(),
};
@ -92,6 +99,11 @@ impl Store {
store
}
/// Set pretty print option to use when saved
pub fn set_pretty_print(&mut self, pretty : bool) {
self.prettysave = pretty;
}
/// Set auto-save option - save on each mutation.
pub fn set_autosave(&mut self, autosave: bool) {
self.autosave = autosave;
@ -142,7 +154,11 @@ impl Store {
/// Save the map to a custom file path.
pub fn save_to<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let as_str = serde_json::to_string(&self.items).unwrap();
let as_str = (if self.prettysave {
serde_json::to_string_pretty(&self.items)
} else {
serde_json::to_string(&self.items)
}).unwrap();
let mut file = File::create(path)?;
file.write(as_str.as_bytes())?;

Loading…
Cancel
Save