2022-02-24 04:57:20 +00:00
|
|
|
extern crate core;
|
|
|
|
|
2022-04-27 22:46:24 +00:00
|
|
|
use std::borrow::{Borrow, BorrowMut};
|
|
|
|
use std::collections::HashMap;
|
2022-02-24 04:57:20 +00:00
|
|
|
use std::fs::read_dir;
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use std::thread;
|
|
|
|
|
2022-04-27 22:46:24 +00:00
|
|
|
use ::imp::event::Event;
|
|
|
|
use ::imp::imp;
|
|
|
|
use ::imp::imp::EventHandler;
|
2022-05-02 02:49:56 +00:00
|
|
|
use ::imp::imp::NewContactPolicy;
|
2022-02-24 04:57:20 +00:00
|
|
|
use libcwtch;
|
|
|
|
use libcwtch::CwtchLib;
|
2022-04-27 22:46:24 +00:00
|
|
|
use libcwtch::structs::*;
|
|
|
|
use serde_json;
|
|
|
|
|
|
|
|
use crate::imp::{Behaviour, BehaviourBuilder, Imp};
|
2022-02-24 04:57:20 +00:00
|
|
|
|
|
|
|
const DIST_DIR: &str = "cwtch_dist";
|
|
|
|
const BOT_HOME: &str = "~/.cwtch/bots/update_bot";
|
|
|
|
const PASSWORD: &str = "be gay do crime";
|
|
|
|
|
2022-04-09 17:51:55 +00:00
|
|
|
const BOT_NAME: &str = "Update Bot";
|
|
|
|
|
|
|
|
const LAST_OFFERED_KEY: &str = "profile.last_version_offered";
|
|
|
|
|
2022-02-24 04:57:20 +00:00
|
|
|
struct UpdateBot {
|
|
|
|
versions_dirs: Vec<PathBuf>,
|
2022-04-09 17:51:55 +00:00
|
|
|
latest_version: PathBuf,
|
|
|
|
version: String,
|
2022-02-24 04:57:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl UpdateBot {
|
|
|
|
pub fn new() -> Self {
|
2022-04-09 17:51:55 +00:00
|
|
|
let mut versions_dirs = vec![];
|
2022-04-09 18:11:01 +00:00
|
|
|
for entry in
|
2022-04-27 22:46:24 +00:00
|
|
|
read_dir(Path::new(DIST_DIR)).expect(&format!("could not open '{}' dir", DIST_DIR))
|
2022-04-09 18:11:01 +00:00
|
|
|
{
|
2022-02-24 04:57:20 +00:00
|
|
|
let entry = entry.unwrap();
|
|
|
|
let path: PathBuf = entry.path();
|
|
|
|
if path.is_dir() {
|
|
|
|
println!("version: {}", path.to_str().unwrap());
|
2022-04-09 17:51:55 +00:00
|
|
|
versions_dirs.push(path);
|
2022-02-24 04:57:20 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-22 00:24:42 +00:00
|
|
|
if versions_dirs.len() == 0 {
|
|
|
|
panic!("no cwtch versions detected in {}!", DIST_DIR)
|
|
|
|
}
|
2022-04-09 17:51:55 +00:00
|
|
|
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();
|
2022-04-27 22:46:24 +00:00
|
|
|
let mut bot = UpdateBot {
|
2022-04-09 18:11:01 +00:00
|
|
|
versions_dirs: versions_dirs,
|
|
|
|
latest_version: latest_version,
|
|
|
|
version: version,
|
|
|
|
};
|
2022-02-24 04:57:20 +00:00
|
|
|
println!("versions: {:?}\n", bot.versions_dirs);
|
2022-04-09 18:11:01 +00:00
|
|
|
return bot;
|
2022-02-24 04:57:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
if !Path::new(DIST_DIR).exists() {
|
|
|
|
panic!("no '{}' directory with versions to distribute", DIST_DIR)
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut update_bot = UpdateBot::new();
|
2022-05-02 02:49:56 +00:00
|
|
|
let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).profile_pic_path("build_bot.png".to_string()).new_contact_policy(imp::NewContactPolicy::Accept).build();
|
2022-02-24 04:57:20 +00:00
|
|
|
|
2022-04-10 06:35:11 +00:00
|
|
|
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());
|
2022-02-24 04:57:20 +00:00
|
|
|
|
2022-04-27 22:46:24 +00:00
|
|
|
bot.event_loop::<UpdateBot>(update_bot.borrow_mut());
|
2022-04-10 06:35:11 +00:00
|
|
|
});
|
2022-02-24 04:57:20 +00:00
|
|
|
|
2022-04-27 22:46:24 +00:00
|
|
|
event_loop_handle.join().expect("Error running event loop");
|
2022-04-10 06:35:11 +00:00
|
|
|
}
|
2022-02-24 04:57:20 +00:00
|
|
|
|
|
|
|
|
2022-04-10 06:35:11 +00:00
|
|
|
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,
|
|
|
|
},
|
2022-04-22 03:36:34 +00:00
|
|
|
Err(e) => false
|
2022-04-10 06:35:11 +00:00
|
|
|
};
|
|
|
|
if do_offer {
|
|
|
|
self.offer(cwtch, profile_opt, convo_id);
|
|
|
|
cwtch.set_conversation_attribute(
|
|
|
|
&profile.handle,
|
|
|
|
convo_id,
|
|
|
|
LAST_OFFERED_KEY,
|
|
|
|
&self.version,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2022-04-27 22:46:24 +00:00
|
|
|
}
|
2022-04-10 06:35:11 +00:00
|
|
|
|
|
|
|
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,
|
|
|
|
};
|
2022-04-27 20:28:13 +00:00
|
|
|
match serde_json::to_string(&response) {
|
2022-04-27 22:46:24 +00:00
|
|
|
Ok(response_json) => cwtch.send_message(&profile.handle, convo_id, &response_json),
|
|
|
|
Err(e) => { println!("Error parsing json response: {}", e.to_string()); "".to_string() }
|
|
|
|
};
|
2022-04-10 06:35:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-02-24 04:57:20 +00:00
|
|
|
|
2022-04-12 19:22:36 +00:00
|
|
|
impl imp::EventHandler for UpdateBot {
|
2022-05-02 02:49:56 +00:00
|
|
|
fn handle(&mut self, cwtch: &dyn libcwtch::CwtchLib, profile_opt: Option<&Profile>, event: Event) {
|
2022-04-27 22:46:24 +00:00
|
|
|
match event {
|
|
|
|
Event::ContactCreated { data } => {
|
|
|
|
let convo_id = data["ConversationID"].parse::<i32>().unwrap();
|
2022-04-22 03:36:34 +00:00
|
|
|
self.greet(cwtch, profile_opt, convo_id);
|
2022-04-10 06:35:11 +00:00
|
|
|
}
|
2022-04-27 22:46:24 +00:00
|
|
|
Event::PeerStateChange { data } => {
|
|
|
|
if data["ConnectionState"] == "Authenticated" {
|
2022-04-10 06:35:11 +00:00
|
|
|
match profile_opt.as_ref() {
|
2022-04-05 01:12:51 +00:00
|
|
|
Some(profile) => {
|
2022-05-02 02:49:56 +00:00
|
|
|
match profile.find_conversation_id_by_handle(data["RemotePeer"].clone()) {
|
|
|
|
Some(conversation_id) => self.greet(cwtch, profile_opt, conversation_id),
|
|
|
|
None => {}
|
2022-04-22 03:36:34 +00:00
|
|
|
}
|
2022-04-09 18:11:01 +00:00
|
|
|
}
|
2022-04-05 01:12:51 +00:00
|
|
|
None => (),
|
|
|
|
};
|
2022-02-24 04:57:20 +00:00
|
|
|
}
|
2022-04-10 06:35:11 +00:00
|
|
|
}
|
2022-04-27 22:46:24 +00:00
|
|
|
Event::NewMessageFromPeer { conversation_id, handle, timestamp_received, message } => {
|
|
|
|
match profile_opt {
|
|
|
|
Some(profile) => {
|
|
|
|
let from = profile.handle.as_str();
|
|
|
|
let message_wrapper: Message =
|
|
|
|
serde_json::from_str(&message).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(&from, 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(&from, conversation_id, linux_path.to_str().unwrap());
|
|
|
|
}
|
|
|
|
"macos" => {
|
|
|
|
let mut mac_path = self.latest_version.clone();
|
|
|
|
mac_path.push("Cwtch.dmg");
|
|
|
|
cwtch.share_file(&from, 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(&from, conversation_id, android_path.to_str().unwrap());
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
self.offer(cwtch, profile_opt, conversation_id);
|
|
|
|
}
|
|
|
|
}
|
2022-04-09 17:51:55 +00:00
|
|
|
}
|
2022-04-27 22:46:24 +00:00
|
|
|
_ => {}
|
2022-04-09 17:51:55 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-27 22:46:24 +00:00
|
|
|
Event::ErrUnhandled { name, data } => eprintln!("unhandled event: {}!", name),
|
2022-04-10 06:35:11 +00:00
|
|
|
_ => ()
|
2022-04-05 01:12:51 +00:00
|
|
|
};
|
|
|
|
}
|
2022-04-10 06:35:11 +00:00
|
|
|
}
|