migrate to lcr following lcg 1.7 and now feature complete

This commit is contained in:
Dan Ballard 2022-04-09 10:51:55 -07:00
parent 6facc03a63
commit 9648bb6310
1 changed files with 68 additions and 42 deletions

View File

@ -19,24 +19,34 @@ const DIST_DIR: &str = "cwtch_dist";
const BOT_HOME: &str = "~/.cwtch/bots/update_bot"; const BOT_HOME: &str = "~/.cwtch/bots/update_bot";
const PASSWORD: &str = "be gay do crime"; const PASSWORD: &str = "be gay do crime";
const BOT_NAME: &str = "Update Bot";
const LAST_OFFERED_KEY: &str = "profile.last_version_offered";
struct UpdateBot { struct UpdateBot {
settings: Option<Settings>, settings: Option<Settings>,
profile: Option<Profile>, profile: Option<Profile>,
versions_dirs: Vec<PathBuf>, versions_dirs: Vec<PathBuf>,
latest_version: PathBuf,
version: String,
} }
impl UpdateBot { impl UpdateBot {
pub fn new() -> Self { pub fn new() -> Self {
let mut version_dirs = vec![]; let mut versions_dirs = vec![];
for entry in read_dir(Path::new(DIST_DIR)).expect(&format!("could not open '{}' dir", DIST_DIR)) { for entry in read_dir(Path::new(DIST_DIR)).expect(&format!("could not open '{}' dir", DIST_DIR)) {
let entry = entry.unwrap(); let entry = entry.unwrap();
let path: PathBuf = entry.path(); let path: PathBuf = entry.path();
if path.is_dir() { if path.is_dir() {
println!("version: {}", path.to_str().unwrap()); println!("version: {}", path.to_str().unwrap());
version_dirs.push(path); versions_dirs.push(path);
} }
} }
let bot = UpdateBot{ versions_dirs: version_dirs, profile: None, settings: None}; versions_dirs.sort();
println!("sorted vd: {:?}", versions_dirs);
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, profile: None, settings: None, latest_version: latest_version, version: version};
println!("versions: {:?}\n", bot.versions_dirs); println!("versions: {:?}\n", bot.versions_dirs);
return bot return bot
} }
@ -95,14 +105,15 @@ fn main() {
}; };
settings.ExperimentsEnabled = true; settings.ExperimentsEnabled = true;
settings.Experiments.insert(Experiments::FileSharingExperiment.to_key_string(),true); settings.Experiments.insert(Experiments::FileSharingExperiment.to_key_string(),true);
settings.Experiments.insert(Experiments::ImagePreviewsExperiment.to_key_string(),true); // TODO delete
settings.Experiments.insert(Experiments::ImagePreviewsExperiment.to_key_string(),false);
match settings.save(&cwtch) { match settings.save(&cwtch) {
Ok(_) => (), Ok(_) => (),
Err(e) => println!("ERROR: could not save settings: {}", e) Err(e) => println!("ERROR: could not save settings: {}", e)
}; };
match update_bot.profile.as_ref() { match update_bot.profile.as_ref() {
Some(profile) => { Some(profile) => {
cwtch.share_file(&profile.onion, -1, "build_bot.png"); cwtch.share_file(&profile.handle, -1, "build_bot.png");
}, },
None => (), None => (),
}; };
@ -114,7 +125,7 @@ fn main() {
event.data["name"], event.data["Identity"] event.data["name"], event.data["Identity"]
); );
// process json for profile, contacts and servers...else { // process json for profile, conversations and servers...else {
let profile = match Profile::new( let profile = match Profile::new(
&event.data["Identity"], &event.data["Identity"],
&event.data["name"], &event.data["name"],
@ -129,21 +140,22 @@ fn main() {
// Share profile image // Share profile image
match update_bot.settings.as_ref() { match update_bot.settings.as_ref() {
Some(_settings) => { Some(_settings) => {
cwtch.share_file(&profile.onion, -1, "build_bot.png"); cwtch.share_file(&profile.handle, -1, "build_bot.png");
}, },
None => (), None => (),
}; };
for (_id, contact) in &profile.contacts { cwtch.set_profile_attribute(&profile.handle, "profile.name", BOT_NAME);
if contact.accepted != true { for (_id, conversation) in &profile.conversations {
cwtch.accept_conversation(profile.onion.as_str(), contact.identifier) if conversation.accepted != true {
cwtch.accept_conversation(profile.handle.as_str(), conversation.identifier)
} }
} }
update_bot.profile = Some(profile); update_bot.profile = Some(profile);
} }
Event::AppError => { Event::AppError => {
if initialized && event.data["Error"] == "Loaded 0 profiles" { if initialized && event.data["Error"] == "Loaded 0 profiles" {
cwtch.create_profile("Upgrade Bot", PASSWORD); cwtch.create_profile(BOT_NAME, PASSWORD);
} }
} }
Event::ContactCreated => { Event::ContactCreated => {
@ -151,23 +163,26 @@ fn main() {
let profile_onion = event.data["RemotePeer"].to_string(); let profile_onion = event.data["RemotePeer"].to_string();
let convo_id = event.data["ConversationID"].parse::<i32>().unwrap(); let convo_id = event.data["ConversationID"].parse::<i32>().unwrap();
let contact = Contact{ let acl: ACL = serde_json::from_str(&event.data["accessControlList"]).expect("Error parsing conversation");
onion: profile_onion.clone(),
let conversation = Conversation {
handle: profile_onion.clone(),
identifier: event.data["ConversationID"].parse::<i32>().unwrap(), identifier: event.data["ConversationID"].parse::<i32>().unwrap(),
name: event.data["nick"].to_string(), name: event.data["nick"].to_string(),
status: ConnectionState::new(&event.data["status"]), status: ConnectionState::new(&event.data["status"]),
blocked: event.data["blocked"] == "true", blocked: event.data["blocked"] == "true",
accepted: event.data["accepted"] == "true", accepted: event.data["accepted"] == "true",
access_control_list: acl,
is_group: false, // by definition is_group: false, // by definition
}; };
if contact.accepted != true { if conversation.accepted != true {
cwtch.accept_conversation(&contact.onion.clone(), convo_id) cwtch.accept_conversation(&conversation.handle.clone(), convo_id)
} }
match update_bot.profile.as_mut() { match update_bot.profile.as_mut() {
Some(profile) => { Some(profile) => {
profile.contacts.insert(event.data["RemotePeer"].to_string(), contact); profile.conversations.insert(event.data["RemotePeer"].to_string(), conversation);
} }
None => () None => ()
}; };
@ -180,12 +195,11 @@ fn main() {
if event.data["ConnectionState"] == "Authenticated" { if event.data["ConnectionState"] == "Authenticated" {
match update_bot.profile.as_ref() { match update_bot.profile.as_ref() {
Some(profile) => { Some(profile) => {
let contact = &profile.contacts[&event.data["RemotePeer"]]; let conversation = &profile.conversations[&event.data["RemotePeer"]];
if contact.accepted != true { if conversation.accepted != true {
cwtch.accept_conversation(profile.onion.as_str(), contact.identifier) cwtch.accept_conversation(profile.handle.as_str(), conversation.identifier)
} }
println!("Sending greeting as peer came online"); update_bot.greet(&cwtch, conversation.identifier);
update_bot.greet(&cwtch, contact.identifier);
} }
None => () None => ()
}; };
@ -197,40 +211,32 @@ fn main() {
let message_wrapper: Message = let message_wrapper: Message =
serde_json::from_str(&event.data["Data"]).expect("Error parsing message"); serde_json::from_str(&event.data["Data"]).expect("Error parsing message");
let latest_version = &update_bot.versions_dirs[update_bot.versions_dirs.len()-1];
let version = latest_version.strip_prefix(DIST_DIR).unwrap().to_str().unwrap();
let mut message = message_wrapper.d.clone(); let mut message = message_wrapper.d.clone();
message.make_ascii_lowercase(); message.make_ascii_lowercase();
match message.as_str() { match message.as_str() {
"windows" => { "windows" => {
let mut windows_path = latest_version.clone(); let mut windows_path = update_bot.latest_version.clone();
windows_path.push("cwtch-installer.exe"); windows_path.push("cwtch-installer.exe");
cwtch.share_file(&to, conversation_id, windows_path.to_str().unwrap()); cwtch.share_file(&to, conversation_id, windows_path.to_str().unwrap());
}, },
"linux" => { "linux" => {
let mut linux_path = latest_version.clone(); let mut linux_path = update_bot.latest_version.clone();
linux_path.push(format!("cwtch-{}.tar.gz", version)); linux_path.push(format!("cwtch-{}.tar.gz", update_bot.version));
cwtch.share_file(&to, conversation_id, linux_path.to_str().unwrap()); cwtch.share_file(&to, conversation_id, linux_path.to_str().unwrap());
}, },
"macos" => { "macos" => {
let mut mac_path = latest_version.clone(); let mut mac_path = update_bot.latest_version.clone();
mac_path.push("Cwtch.dmg"); mac_path.push("Cwtch.dmg");
cwtch.share_file(&to, conversation_id, mac_path.to_str().unwrap()); cwtch.share_file(&to, conversation_id, mac_path.to_str().unwrap());
}, },
"android" => { "android" => {
let mut android_path = latest_version.clone(); let mut android_path = update_bot.latest_version.clone();
android_path.push("app-release.apk"); android_path.push("app-release.apk");
cwtch.share_file(&to, conversation_id, android_path.to_str().unwrap()); cwtch.share_file(&to, conversation_id, android_path.to_str().unwrap());
} }
_ => { _ => {
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", version); update_bot.offer(&cwtch, conversation_id);
let response = Message { o: 1, d: resp_message };
let response_json =
serde_json::to_string(&response).expect("Error parsing json response");
cwtch.send_message(&to, conversation_id, &response_json);
} }
} }
@ -248,13 +254,33 @@ impl UpdateBot {
pub fn greet(&self, cwtch: &dyn CwtchLib, convo_id: i32) { pub fn greet(&self, cwtch: &dyn CwtchLib, convo_id: i32) {
match self.profile.as_ref() { match self.profile.as_ref() {
Some(profile) => { Some(profile) => {
// TODO throttle as we seem to be able to get a bunch of Authenticated messages let do_offer = match cwtch.get_conversation_attribute(&profile.handle, convo_id, &format!("local.{}", LAST_OFFERED_KEY)) {
// TODO getAttribute what was the last version we offered, if there is a newer, make the offer, update attr Ok(ret) => match ret {
println!("Sending greeting as peer came online"); Some(last_offered) => last_offered != self.version,
let greeting = Message { o: 1, d: "Hello".to_string() }; None => true,
let greeting_json = },
serde_json::to_string(&greeting).expect("Error parsing json response"); Err(e) => {
cwtch.send_message(profile.onion.as_ref(), convo_id, &greeting_json); println!("Error parsing attribute: {}", e);
false
}
};
if do_offer {
self.offer(cwtch, convo_id);
cwtch.set_conversation_attribute(&profile.handle, convo_id, LAST_OFFERED_KEY, &self.version);
}
}
None => ()
};
}
pub fn offer(&self, cwtch: &dyn CwtchLib, convo_id: i32) {
match self.profile.as_ref() {
Some(profile) => {
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);
} }
None => () None => ()
}; };