aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs77
-rw-r--r--src/message.rs94
2 files changed, 171 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..ddf4feb
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,77 @@
+use std::process::Command;
+use std::fs::File;
+use std::io::prelude::*;
+
+extern crate toml;
+extern crate websocket;
+extern crate rustc_serialize;
+use rustc_serialize::{Decodable};
+use rustc_serialize::json::{Json, Decoder};
+
+mod message;
+use message::{Message, Push};
+
+fn main() {
+ use websocket::{Receiver};
+ use websocket::client::request::Url;
+ use websocket::Client;
+
+ let mut cfg_file = File::open("config.toml").unwrap();
+ let mut s = String::new();
+ cfg_file.read_to_string(&mut s);
+ let cfg = toml::Parser::new(s.as_ref()).parse().unwrap();
+ let token = cfg.get("pushbullet").unwrap().as_table().unwrap().get("token").expect("Could not find 'token' in config.toml").as_str().unwrap();
+
+ let wss_url = format!("wss://stream.pushbullet.com/websocket/{}", token);
+ let url = Url::parse(wss_url.as_ref()).unwrap();
+ let request = Client::connect(url).unwrap();
+ let response = request.send().unwrap();
+ response.validate().unwrap();
+
+ let (mut sender, mut receiver) = response.begin().split();
+
+ for message in receiver.incoming_messages() {
+ let message = match message {
+ Ok(m) => m,
+ Err(e) => {
+ println!("Error: {:?}", e);
+ return;
+ }
+ };
+
+ match message {
+ websocket::Message::Close(_) => {
+ return;
+ }
+ websocket::Message::Text(message) => {
+ let json = Json::from_str(message.as_ref()).unwrap();
+ let mut decoder = Decoder::new(json);
+ let msg = Decodable::decode(&mut decoder).unwrap();
+ println!("Got {:?}", msg);
+ match msg {
+ Message::Nop => {}
+ Message::Push(Push::Mirror {
+ notification_id,
+ title,
+ body,
+ application_name,
+ ..
+ }) => {
+ let _ = Command::new("notify-send")
+ .arg(title)
+ .arg(body)
+ .arg("-t")
+ .arg("8000")
+ .status().unwrap();
+ }
+ Message::Push(Push::Dismissal { notification_id }) => {
+
+ }
+ }
+ }
+ _ => {
+ println!("Got {:?}", message);
+ }
+ }
+ }
+}
diff --git a/src/message.rs b/src/message.rs
new file mode 100644
index 0000000..c0a766c
--- /dev/null
+++ b/src/message.rs
@@ -0,0 +1,94 @@
+extern crate rustc_serialize;
+
+use self::rustc_serialize::{json, Decodable, Decoder};
+
+#[derive(Debug)]
+pub enum Push {
+ Mirror {
+ notification_id: i32,
+ title: String,
+ body: String,
+ application_name: String,
+ package_name: String,
+ icon: String
+ },
+ Dismissal {
+ notification_id: i32
+ }
+}
+
+#[derive(Debug)]
+pub enum Message {
+ Nop,
+ Push(Push)
+}
+
+impl Decodable for Push {
+ fn decode<D: Decoder>(d: &mut D) -> Result<Push, D::Error> {
+ d.read_struct("root", 0, |d| {
+ let type_ : String = try!(d.read_struct_field("type", 0, Decodable::decode));
+ match type_.as_ref() {
+ "mirror" => {
+ let id = try!(
+ d.read_struct_field("notification_id", 0, Decodable::decode));
+ let title = try!(
+ d.read_struct_field("title", 0, Decodable::decode));
+ let body = try!(
+ d.read_struct_field("body", 0, Decodable::decode));
+ let app_name = try!(
+ d.read_struct_field("application_name", 0, Decodable::decode));
+ let package_name = try!(
+ d.read_struct_field("package_name", 0, Decodable::decode));
+ let icon = try!(
+ d.read_struct_field("icon", 0, Decodable::decode));
+
+ Ok(Push::Mirror {
+ title: title,
+ body: body,
+ application_name: app_name,
+ package_name: package_name,
+ notification_id: id,
+ icon: icon
+ })
+ }
+ "dismissal" => {
+ let id = try!(
+ d.read_struct_field("notification_id", 0, Decodable::decode));
+
+ Ok(Push::Dismissal {
+ notification_id: id
+ })
+ }
+ _ => {
+ let err_msg = format!(
+ "Invalid value for push type: {} (expected 'mirror' or 'dismissal')",
+ type_);
+ Err(d.error(err_msg.as_ref()))
+ }
+ }
+ })
+ }
+}
+
+impl Decodable for Message {
+ fn decode<D: Decoder>(d: &mut D) -> Result<Message, D::Error> {
+ d.read_struct("root", 0, |d| {
+ let type_ : String = try!(d.read_struct_field("type", 0, Decodable::decode));
+
+ match type_.as_ref() {
+ "nop" => Ok(Message::Nop),
+ "push" => {
+ d.read_struct_field("push", 0, |d| {
+ Ok(Message::Push(try!(Decodable::decode(d))))
+ })
+ },
+ _ => {
+ let err_msg = format!(
+ "Invalid value for message type: {}",
+ type_);
+ Err(d.error(err_msg.as_ref()))
+ }
+ }
+ })
+ }
+}