update_bot/src/main.rs

187 lines
6.7 KiB
Rust
Raw Normal View History

extern crate core;
2022-04-12 19:22:36 +00:00
use ::imp::event::Event;
use ::imp::imp;
use std::fs::read_dir;
use std::path::{Path, PathBuf};
use std::thread;
use serde_json;
use libcwtch;
use libcwtch::structs::*;
use libcwtch::CwtchLib;
2022-04-12 19:22:36 +00:00
use crate::imp::{Behaviour, Imp};
const DIST_DIR: &str = "cwtch_dist";
const BOT_HOME: &str = "~/.cwtch/bots/update_bot";
const PASSWORD: &str = "be gay do crime";
const BOT_NAME: &str = "Update Bot";
const LAST_OFFERED_KEY: &str = "profile.last_version_offered";
struct UpdateBot {
versions_dirs: Vec<PathBuf>,
latest_version: PathBuf,
version: String,
}
impl UpdateBot {
pub fn new() -> Self {
let mut versions_dirs = vec![];
2022-04-09 18:11:01 +00:00
for entry in
read_dir(Path::new(DIST_DIR)).expect(&format!("could not open '{}' dir", DIST_DIR))
{
let entry = entry.unwrap();
let path: PathBuf = entry.path();
if path.is_dir() {
println!("version: {}", path.to_str().unwrap());
versions_dirs.push(path);
}
}
versions_dirs.sort();
println!("sorted vd: {:?}", versions_dirs);
2022-04-09 18:11:01 +00:00
let latest_version = versions_dirs[versions_dirs.len() - 1].clone();
let version: String = latest_version
.strip_prefix(DIST_DIR)
.unwrap()
.to_str()
.unwrap()
.to_string();
let bot = UpdateBot {
versions_dirs: versions_dirs,
latest_version: latest_version,
version: version,
};
println!("versions: {:?}\n", bot.versions_dirs);
2022-04-09 18:11:01 +00:00
return bot;
}
}
fn main() {
if !Path::new(DIST_DIR).exists() {
panic!("no '{}' directory with versions to distribute", DIST_DIR)
}
let mut update_bot = UpdateBot::new();
let behaviour: Behaviour = Behaviour::new_default_acceptor(BOT_NAME.to_string(), "build_bot.png".to_string());
let event_loop_handle = thread::spawn(move || {
2022-04-12 19:22:36 +00:00
let mut bot = Imp::spawn(behaviour, PASSWORD.to_string(), BOT_HOME.to_string());
bot.event_loop(Box::new(update_bot));
});
event_loop_handle.join().expect("Error running event loop");
}
impl UpdateBot {
pub fn greet(&self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, convo_id: i32) {
if let Some(profile) = profile_opt {
let do_offer = match cwtch.get_conversation_attribute(
&profile.handle,
convo_id,
&format!("local.{}", LAST_OFFERED_KEY),
) {
Ok(ret) => match ret {
Some(last_offered) => last_offered != self.version,
None => true,
},
Err(e) => {
println!("Error parsing attribute: {}", e);
false
}
};
if do_offer {
self.offer(cwtch, profile_opt, convo_id);
cwtch.set_conversation_attribute(
&profile.handle,
convo_id,
LAST_OFFERED_KEY,
&self.version,
);
}
}
}
pub fn offer(&self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, convo_id: i32) {
if let Some(profile) = profile_opt {
let resp_message = format!(
"Currently offering Cwtch {}\nPlease respond with the OS you would like a package for:\n- Windows\n- Android\n- MacOS\n- Linux",
self.version
);
let response = Message {
o: 1,
d: resp_message,
};
let response_json =
serde_json::to_string(&response).expect("Error parsing json response");
cwtch.send_message(&profile.handle, convo_id, &response_json);
}
}
}
2022-04-12 19:22:36 +00:00
impl imp::EventHandler for UpdateBot {
fn handle(&self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: CwtchEvent) {
2022-04-12 19:22:36 +00:00
let event_type = Event::from(event.event_type.as_str());
match event_type {
Event::ContactCreated => {
if event.data["ConnectionState"] == "Authenticated" {
let convo_id = event.data["ConversationID"].parse::<i32>().unwrap();
self.greet(cwtch, profile_opt, convo_id);
}
}
Event::PeerStateChange => {
if event.data["ConnectionState"] == "Authenticated" {
match profile_opt.as_ref() {
Some(profile) => {
let conversation =
&profile.conversations[&event.data["RemotePeer"]];
self.greet(cwtch, profile_opt, conversation.identifier);
2022-04-09 18:11:01 +00:00
}
None => (),
};
}
}
Event::NewMessageFromPeer => {
let to = &event.data["ProfileOnion"];
let conversation_id = event.data["ConversationID"].parse::<i32>().unwrap();
let message_wrapper: Message =
serde_json::from_str(&event.data["Data"]).expect("Error parsing message");
let mut message = message_wrapper.d.clone();
message.make_ascii_lowercase();
match message.as_str() {
"windows" => {
let mut windows_path = self.latest_version.clone();
windows_path.push("cwtch-installer.exe");
cwtch.share_file(&to, conversation_id, windows_path.to_str().unwrap());
}
"linux" => {
let mut linux_path = self.latest_version.clone();
linux_path.push(format!("cwtch-{}.tar.gz", self.version));
cwtch.share_file(&to, conversation_id, linux_path.to_str().unwrap());
}
"macos" => {
let mut mac_path = self.latest_version.clone();
mac_path.push("Cwtch.dmg");
cwtch.share_file(&to, conversation_id, mac_path.to_str().unwrap());
}
"android" => {
let mut android_path = self.latest_version.clone();
android_path.push("app-release.apk");
cwtch.share_file(&to, conversation_id, android_path.to_str().unwrap());
}
_ => {
self.offer( cwtch, profile_opt, conversation_id);
}
}
}
Event::ErrUnhandled(err) => eprintln!("unhandled event: {}!", err),
_ => ()
};
}
}