From f005b98453fcaf19f1f9e0049dfdbd3752dc72af Mon Sep 17 00:00:00 2001 From: Junko Date: Thu, 23 Nov 2023 14:55:30 +0100 Subject: [PATCH] add command, finished set command --- README.org | 549 ---------------------------------------------------- TODO.org | 79 ++++---- src/main.rs | 211 +++++++++++++++----- 3 files changed, 204 insertions(+), 635 deletions(-) delete mode 100644 README.org diff --git a/README.org b/README.org deleted file mode 100644 index 92e6229..0000000 --- a/README.org +++ /dev/null @@ -1,549 +0,0 @@ -#+title: Pluralsync (Codename pluralshit) -#+author: Jvnko - -* About -* Configuration -#+begin_src json :tangle config.example.json -{ - "pk_key": "// Pluralkit token", - "sp_key": "// Simplplural token" -} -#+end_src - -* Code -** Cargo.toml -#+begin_src toml :tangle Cargo.toml -[package] -name = "pluralshit" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -dirs = "5.0.1" -serde = { version = "1.0.192", features = ["derive"] } -serde_json = "1.0" -reqwest = { version = "0.11.22", features = ["json"] } -rofi = "0.3.0" -tokio = { version = "1", features = ["full"] } -#+end_src - -** Main.rs -*** Imports -#+begin_src rust :tangle src/main.rs :comments link -use std::fs; -use std::fs::create_dir; -use std::path::Path; -use std::collections::HashMap; - -use reqwest::header::{USER_AGENT, AUTHORIZATION}; - -use serde::{Serialize, Deserialize}; -use serde_json::Value; - -use dirs; -#+end_src - -*** Constants -#+begin_src rust :tangle src/main.rs :comments link -const PK_URL: &str = "https://api.pluralkit.me/v2"; -const SP_URL: &str = "https://api.apparyllis.com/v1"; -#+end_src - -*** Structs -#+begin_src rust :tangle src/main.rs :comments link -#[derive(Debug)] -#[derive(Serialize)] -#[derive(Deserialize)] -#[derive(Clone)] -struct System { - pk_userid: String, - sp_userid: String, - members: Vec, -} - -#[derive(Debug)] -#[derive(Serialize)] -#[derive(Deserialize)] -#[derive(Clone)] -#[derive(PartialEq)] -struct Member { - pk_id: String, - sp_id: String, - name: String, - alias: String -} -#+end_src - -*** Main -#+begin_src rust :tangle src/main.rs :comments link -fn main() { - if std::env::args().len() > 1 { - let augs: Vec = std::env::args().collect(); - let command = &augs[1]; - let config_path: String; - match dirs::config_dir() { - Some(x) => { - config_path = format!("{}/pluralshit", x.display()); - match command.as_str() { - "sync" => { - let _ = sync(config_path); - }, - "set" => { - if std::env::args().len() > 2 { - match set_member(config_path, &augs[2..]) { - Ok(_) => (), - Err(e) => println!("{e}"), - } - } else { - //set_empty(config_path); - } - }, - "get" => get(config_path), - "memberlist" => memberlist(config_path), - &_ => println!("Invalid command"), - } - }, - None => println!("Something went wrong") - } - } else { - println!("No arguments given"); - } -} -#+end_src - -*** Functions -**** Main commands -***** Sync -#+begin_src rust :tangle src/main.rs :comments link -fn sync(config_path: String) -> Result<(), String>{ - // Get config - let config = get_config(&config_path); - if config == Value::Null { - println!("Stopping."); - return Ok(()); - } - - let pk_key = &config["pk_key"].as_str().unwrap(); - let sp_key = &config["sp_key"].as_str().unwrap(); - - // Get Pluralkit system id - let pk_sys = pk_get_system(pk_key); - let pk_sysid = pk_sys["id"].as_str().unwrap(); - - // Get Simplyplural user id - let sp_user_id = sp_get_userid(sp_key); - - // Get Simplyplural member ids - let sp_member_ids = sp_get_memberids(sp_key, &sp_user_id); - - // get members - let pk_members = pk_get_members(pk_key, pk_sysid); - let mut members: Vec = Vec::new(); - for member in pk_members { - let mut m = Member { - pk_id: member["id"].as_str().unwrap().to_string(), - sp_id: String::new(), - name: member["name"].as_str().unwrap().to_string(), - alias: String::new() - }; - - if member["display_name"].as_str() != None { - m.alias = member["display_name"].as_str().unwrap().to_string(); - } else { - m.alias = String::from(&m.name); - } - - m.sp_id = get_sp_id(&m, &sp_member_ids); - - members.push(m); - } - - let sys = System { - pk_userid: pk_sysid.to_string(), - sp_userid: sp_user_id, - members: members.clone(), - }; - - let json = serde_json::to_string(&sys); - let _ = fs::write(format!("{}/system.json", config_path), &json.unwrap()); - - Ok(()) -} -#+end_src - -***** Set member -#+begin_src rust :tangle src/main.rs :comments link -/* -TODO fn set_empty(config_path: String) { -TODO let config = load_json(format!("{}/config.json", config_path)); -TODO let system = get_system(&config_path); -TODO } -*/ - -fn set_member(config_path: String, tf_members: &[String]) -> Result<(), &'static str> { - let config = get_config(&config_path); - if config == Value::Null { - return Err("Config not found. Stopping"); - } - - let system: System = get_system(&config_path); - - let mut to_front: Vec = Vec::new(); - for member in tf_members { - for mem in &system.members { - if mem.name.to_lowercase() == member.to_lowercase() || mem.alias.to_lowercase() == member.to_lowercase() { - println!("Member {member} found"); - to_front.push(mem.clone()); - - break; - } - } - } - if to_front.len() != 0 { - let fronters = get_fronters(&config["pk_key"].as_str().unwrap(), &config["sp_key"].as_str().unwrap(), &system); - pk_set_fronters(&config["pk_key"].as_str().unwrap(), &system, to_front, &fronters); - } - get(config_path); - Ok(()) -} - -fn memberlist(config_path: String) { - let sys = get_system(&config_path); - - for mem in sys.members { - if mem.name != mem.alias { - println!("{} / {}", mem.name, mem.alias); - } else { - println!("{}", mem.name); - } - } - -} - -fn get(config_path: String) { - let config = get_config(&config_path); - let sys = get_system(&config_path); - - let f = get_fronters(&config["pk_key"].as_str().unwrap(), &config["sp_key"].as_str().unwrap(), &sys); - let mut names = Vec::new(); - for m in &f["pk"] { - names.push(String::from(&m.name)); - } - let fronters = names.join(" || "); - println!("Currently fronting: {}", fronters); - let _ = fs::write(format!("{}/.front", config_path), fronters); -} -#+end_src - -***** Memberlist -#+begin_src rust :tangle src/main.rs :comments link -fn memberlist(config_path: String) { - let sys = get_system(&config_path); - - for mem in sys.members { - if mem.name != mem.alias { - println!("{} / {}", mem.name, mem.alias); - } else { - println!("{}", mem.name); - } - } - -} -#+end_src - -**** Pluralkit -***** Get system -#+begin_src rust :tangle src/main.rs :comments link -fn pk_get_system(key: &str) -> Value { - let url = format!("{}/systems/@me", PK_URL); - - let res = http_get_request(url,key); - return serde_json::from_str(&res.unwrap()).unwrap(); -} - -fn pk_get_members(key: &str, sysid: &str) -> Vec { - let url = format!("{}/systems/{}/members", PK_URL, sysid); - - let res = http_get_request(url,key); - let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); - - return datas; -} -#+end_src - -***** Get members -#+begin_src rust :tangle src/main.rs :comments link -fn pk_get_members(key: &str, sysid: &str) -> Vec { - let url = format!("{}/systems/{}/members", PK_URL, sysid); - - let res = http_get_request(url,key); - let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); - - return datas; -} -#+end_src - -***** Get fronters -#+begin_src rust :tangle src/main.rs :comments link -fn sp_get_fronters(key: &str, sys: &System) -> Vec { - let url = format!("{}/fronters", SP_URL); - - let res = http_get_request(url,key); - let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); - - let mut members: Vec = Vec::new(); - for data in datas { - let sp_id = &data["content"]["member"].as_str().unwrap(); - for member in &sys.members { - if &member.sp_id == sp_id { - members.push(member.clone()); - } - } - - } - return members; -} -#+end_src - -**** Simplyplural -***** Get user ID -#+begin_src rust :tangle src/main.rs :comments link -fn sp_get_userid(key: &str) -> String { - let url = format!("{}/me", SP_URL); - - let res = http_get_request(url,key); - let json_res : Value = serde_json::from_str(&res.unwrap()).unwrap(); - return json_res["id"].as_str().unwrap().to_string(); -} -#+end_src - -***** Get members ID -#+begin_src rust :tangle src/main.rs :comments link -fn sp_get_memberids(key: &str, system_id: &str) -> HashMap { - let url = format!("{}/members/{}", SP_URL, system_id); - - let res = http_get_request(url,key); - let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); - - let mut sp_memberdata: HashMap = HashMap::new(); - for data in datas { - sp_memberdata.insert(String::from(data["content"]["name"].as_str().unwrap()), String::from(data["id"].as_str().unwrap())); - } - - return sp_memberdata; -} -#+end_src - -***** Get ID from member -#+begin_src rust :tangle src/main.rs :comments link -fn get_sp_id(mem: &Member, ids: &HashMap) -> String { - - let mut member_id = String::new(); - - for (mn, mid) in ids { - if &mem.name == mn || &mem.alias == mn { - member_id = String::from(mid); - } - } - - return member_id; -} -#+end_src - -***** Get fronters -#+begin_src rust :tangle src/main.rs :comments link -fn sp_get_fronters(key: &str, sys: &System) -> Vec { - let url = format!("{}/fronters", SP_URL); - - let res = http_get_request(url,key); - let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); - - let mut members: Vec = Vec::new(); - for data in datas { - let sp_id = &data["content"]["member"].as_str().unwrap(); - let mut push_name = String::new(); - for member in &sys.members { - if &member.sp_id == sp_id { - push_name = String::from(&member.name); - } - } - members.push(push_name); - - } - return members; -} -#+end_src - -**** Utilities -***** Load JSON -#+begin_src rust :tangle src/main.rs :comments link -fn load_json(path: String) -> Value { - if Path::new(&path).exists() { - let config_data = fs::read_to_string(&path).expect("File not found"); - return serde_json::from_str(&config_data).unwrap(); - } else { - println!("Config file in {path} not found"); - return Value::Null; - } -} -#+end_src - -***** Get config json -#+begin_src rust :tangle src/main.rs :comments link -fn get_config(config_path: &str) -> Value { - let path = format!("{}/config.json", config_path); - if Path::new(config_path).exists() { - - let result = load_json(String::from(&path)); - - if result == Value::Null { - println!("Config file missing, creating template in {path}"); - let _ = fs::write(path, r#" -{ - "pk_key": "// Pluralkit token", - "sp_key": "// Simplplural token" -} - "#); - } - - return result; - } else { - println!("Directory {config_path} does not exist. Creating with template config"); - let _ = create_dir(config_path); - let _ = fs::write(path, r#" -{ - "pk_key": "// Pluralkit token", - "sp_key": "// Simplplural token" -} - "#); - return Value::Null; - } -} -#+end_src - -***** Get system json -#+begin_src rust :tangle src/main.rs :comments link -fn get_system(config_path: &str) -> System { - let path = format!("{}/system.json", config_path); - - let mut result = load_json(String::from(&path)); - - if result == Value::Null { - println!("Syncing system config"); - let _ = sync(String::from(config_path)); - result = load_json(String::from(&path)); - } - - let vec = serde_json::to_vec(&result).unwrap(); - let sys = serde_json::from_slice::(&vec).unwrap(); - - return sys; - -} - -fn get_fronters(pk_key: &str, sp_key: &str, sys: &System) -> HashMap> { - let mut fronters: HashMap> = HashMap::new(); - fronters.insert(String::from("pk"), pk_get_fronters(pk_key, sys)); - fronters.insert(String::from("sp"), sp_get_fronters(sp_key, sys)); - - return fronters; -} -#+end_src - -***** Get fronters -#+begin_src rust :tangle src/main.rs :comments link -fn get_fronters(pk_key: &str, sp_key: &str, sys: &System) -> HashMap> { - let mut fronters: HashMap> = HashMap::new(); - fronters.insert(String::from("pk"), pk_get_fronters(pk_key, sys)); - fronters.insert(String::from("sp"), sp_get_fronters(sp_key, sys)); - - return fronters; -} -#+end_src - -**** Http Request handler -***** Get request -#+begin_src rust :tangle src/main.rs :comments link -#[tokio::main] -async fn http_get_request(url: String, key: &str) -> Result> { - let client = reqwest::Client::new(); - let res = client - .get(url) - .header(USER_AGENT, "Pluralsync") - .header(AUTHORIZATION, key) - .send() - .await? - .text() - .await?; - Ok(res) -} - - -#[tokio::main] -async fn http_post_request(url: String, key: &str, body: &HashMap<&str, Vec>) -> Result<(), Box> { - let client = reqwest::Client::new(); - let _ = client - .post(url) - .json(body) - .header(USER_AGENT, "Pluralsync") - .header(AUTHORIZATION, key) - .send() - .await?; - Ok(()) -} - -/* -#[tokio::main] -async fn http_patch_request(url: String, key: &str) -> Result> { - let client = reqwest::Client::new(); - let res = client - .patch(url) - .body("wiwiwiw") - .header(USER_AGENT, "Pluralsync") - .header(AUTHORIZATION, key) - .send() - .await? - .text() - .await?; - Ok(res) -} -*/ -#+end_src - -***** Post request -#+begin_src rust :tangle src/main.rs :comments link -#[tokio::main] -async fn http_post_request(url: String, key: &str, body: &HashMap<&str, Vec>) -> Result<(), Box> { - let client = reqwest::Client::new(); - let _ = client - .post(url) - .json(body) - .header(USER_AGENT, "Pluralsync") - .header(AUTHORIZATION, key) - .send() - .await?; - Ok(()) -} -#+end_src - -***** Patch request -#+begin_src rust :tangle src/main.rs :comments link -/* -#[tokio::main] -async fn http_patch_request(url: String, key: &str) -> Result> { - let client = reqwest::Client::new(); - let res = client - .patch(url) - .body("wiwiwiw") - .header(USER_AGENT, "Pluralsync") - .header(AUTHORIZATION, key) - .send() - .await? - .text() - .await?; - Ok(res) -} -*/ -#+end_src diff --git a/TODO.org b/TODO.org index 6a5ed97..849bfe8 100644 --- a/TODO.org +++ b/TODO.org @@ -8,19 +8,22 @@ :PROPERTIES: :COOKIE_DATA: recursive :END: -*** Milestone 1.0 [12/24][50%] -**** Main functions [4/10][40%] +*** Milestone 1.0 [20/26][76%] +**** Main functions [9/13][69%] ***** Finished Add `sync` command -***** HighPriority Add `set` command [2/3] -****** Backlog [SET] Add empty +***** Finished Add `set` command [0/0] ****** Finished [SET] Add set -****** Finished Adapt to set multiple arguments -***** InProgress Add `get` command -***** Backlog Add `add` command [0/2] -****** Backlog [ADD] Add empty -****** Backlog [ADD] Add set +****** Finished Adapt to set multiple members +***** Finished Add `get` command +***** Finished Add `add` command [0/0] +****** Finished [ADD] Add set +****** Finished Adapt to add multiple members ***** Finished Add `memberlist` command -**** Utils [7/12][58%] +***** LowPriority Rofi stuff [0/3] +****** LowPriority Rofi backend +****** LowPriority Set empty +****** LowPriority Add emtpy +**** Utils [11/11][100%] ***** Json loading [2/2] ****** Finished Add new function to get the config create empty in path if not exists ****** Finished `Get system` if Value::Null sync and load json @@ -29,34 +32,36 @@ ***** Finished http POST request ***** Finished Set members know the alias ***** Finished Compare if sent members are currently fronting and keep them otherwise add to fronting array -***** InProgress Set simplyplural -***** InProgress Check if member is currently fronting and just add if not, remove the ones who do not -***** HighPriority Check for mismatch in fronting between pluralkit and simplyplural -***** LowPriority Get fronters handles the front file -***** HighPriority Rofi stuff +***** Finished Set simplyplural +***** Finished Check if member is currently fronting and just add if not, remove the ones who do not +***** Finished Check for mismatch in fronting between pluralkit and simplyplural +***** Finished Get fronters handles the front file +**** HighPriority Docs **** Exception handling [0/1][0%] -***** Backlog do it proper -**** Doc [1/1][100%] -***** Functions [1/1] -****** Finished Separate memberlist into its own code block in the readme +***** HighPriority do it proper ** Kanban -| Backlog | LowPriority | HighPriority | InProgress | Finished | -|-------------------------+--------------------------------+--------------------------------+--------------------------------+--------------------------------| -| [[/home/alicia/git/pluralshit/TODO.org::\[SET\] Add empty][{SET} Add empty]] | [[/home/alicia/git/pluralshit/TODO.org::Get fronters handles the front file][Get fronters handles the front]] | [[/home/alicia/git/pluralshit/TODO.org::Add `set` command \[2/3\]][Add `set` command {2/3}]] | [[/home/alicia/git/pluralshit/TODO.org::Add `get` command][Add `get` command]] | [[/home/alicia/git/pluralshit/TODO.org::Add `sync` command][Add `sync` command]] | -| [[/home/alicia/git/pluralshit/TODO.org::Add `add` command \[0/2\]][Add `add` command {0/2}]] | | [[/home/alicia/git/pluralshit/TODO.org::Check for mismatch in fronting between pluralkit and simplyplural][Check for mismatch in fronting]] | [[/home/alicia/git/pluralshit/TODO.org::Set simplyplural][Set simplyplural]] | [[/home/alicia/git/pluralshit/TODO.org::\[SET\] Add set][{SET} Add set]] | -| [[/home/alicia/git/pluralshit/TODO.org::\[ADD\] Add empty][{ADD} Add empty]] | | [[/home/alicia/git/pluralshit/TODO.org::Rofi stuff][Rofi stuff]] | [[/home/alicia/git/pluralshit/TODO.org::Check if member is currently fronting and just add if not, remove the ones who do not][Check if member is currently f]] | [[/home/alicia/git/pluralshit/TODO.org::Adapt to set multiple arguments][Adapt to set multiple argument]] | -| [[/home/alicia/git/pluralshit/TODO.org::\[ADD\] Add set][{ADD} Add set]] | | | | [[/home/alicia/git/pluralshit/TODO.org::Add `memberlist` command][Add `memberlist` command]] | -| [[/home/alicia/git/pluralshit/TODO.org::do it proper][do it proper]] | | | | [[/home/alicia/git/pluralshit/TODO.org::Add new function to get the config create empty in path if not exists][Add new function to get the co]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::`Get system` if Value::Null sync and load json][`Get system` if Value::Null sy]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::Get current front][Get current front]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::http PATCH request][http PATCH request]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::http POST request][http POST request]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::Set members know the alias][Set members know the alias]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::Compare if sent members are currently fronting and keep them otherwise add to fronting array][Compare if sent members are cu]] | -| | | | | [[/home/alicia/git/pluralshit/TODO.org::Separate memberlist into its own code block in the readme][Separate memberlist into its o]] | -| | | | | | -| | | | | | -| | | | | | -| | | | | | +| Backlog | LowPriority | HighPriority | InProgress | Finished | +|---------+------------------+--------------+------------+--------------------------------| +| | [[/home/alicia/git/pluralshit/TODO.org::Rofi stuff \[0/3\]][Rofi stuff {0/3}]] | [[/home/alicia/git/pluralshit/TODO.org::Docs][Docs]] | | [[/home/alicia/git/pluralshit/TODO.org::Add `sync` command][Add `sync` command]] | +| | [[/home/alicia/git/pluralshit/TODO.org::Rofi backend][Rofi backend]] | [[/home/alicia/git/pluralshit/TODO.org::do it proper][do it proper]] | | [[/home/alicia/git/pluralshit/TODO.org::Add `set` command \[0/0\]][Add `set` command {0/0}]] | +| | [[/home/alicia/git/pluralshit/TODO.org::Set empty][Set empty]] | | | [[/home/alicia/git/pluralshit/TODO.org::\[SET\] Add set][{SET} Add set]] | +| | [[/home/alicia/git/pluralshit/TODO.org::Add emtpy][Add emtpy]] | | | [[/home/alicia/git/pluralshit/TODO.org::Adapt to set multiple members][Adapt to set multiple members]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Add `get` command][Add `get` command]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Add `add` command \[0/0\]][Add `add` command {0/0}]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::\[ADD\] Add set][{ADD} Add set]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Adapt to add multiple members][Adapt to add multiple members]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Add `memberlist` command][Add `memberlist` command]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Add new function to get the config create empty in path if not exists][Add new function to get the co]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::`Get system` if Value::Null sync and load json][`Get system` if Value::Null sy]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Get current front][Get current front]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::http PATCH request][http PATCH request]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::http POST request][http POST request]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Set members know the alias][Set members know the alias]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Compare if sent members are currently fronting and keep them otherwise add to fronting array][Compare if sent members are cu]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Set simplyplural][Set simplyplural]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Check if member is currently fronting and just add if not, remove the ones who do not][Check if member is currently f]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Check for mismatch in fronting between pluralkit and simplyplural][Check for mismatch in fronting]] | +| | | | | [[/home/alicia/git/pluralshit/TODO.org::Get fronters handles the front file][Get fronters handles the front]] | +| | | | | | #+TBLFM: @1='(kanban-headers $#)::@2$1..@>$>='(kanban-zero @# $# nil (list (buffer-file-name))) diff --git a/src/main.rs b/src/main.rs index dec31f0..57b9e4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -// [[file:../README.org::*Imports][Imports:1]] use std::fs; use std::fs::create_dir; use std::path::Path; @@ -10,14 +9,10 @@ use serde::{Serialize, Deserialize}; use serde_json::Value; use dirs; -// Imports:1 ends here -// [[file:../README.org::*Constants][Constants:1]] const PK_URL: &str = "https://api.pluralkit.me/v2"; const SP_URL: &str = "https://api.apparyllis.com/v1"; -// Constants:1 ends here -// [[file:../README.org::*Structs][Structs:1]] #[derive(Debug)] #[derive(Serialize)] #[derive(Deserialize)] @@ -39,9 +34,7 @@ struct Member { name: String, alias: String } -// Structs:1 ends here -// [[file:../README.org::*Main][Main:1]] fn main() { if std::env::args().len() > 1 { let augs: Vec = std::env::args().collect(); @@ -64,6 +57,17 @@ fn main() { //set_empty(config_path); } }, + "add" => { + if std::env::args().len() > 2 { + match add_member(config_path, &augs[2..]) { + Ok(_) => (), + Err(e) => println!("{e}"), + } + } else { + //add_empty(config_path); + } + + } "get" => get(config_path), "memberlist" => memberlist(config_path), &_ => println!("Invalid command"), @@ -75,9 +79,7 @@ fn main() { println!("No arguments given"); } } -// Main:1 ends here -// [[file:../README.org::*Sync][Sync:1]] fn sync(config_path: String) -> Result<(), String>{ // Get config let config = get_config(&config_path); @@ -132,9 +134,7 @@ fn sync(config_path: String) -> Result<(), String>{ Ok(()) } -// Sync:1 ends here -// [[file:../README.org::*Set member][Set member:1]] /* TODO fn set_empty(config_path: String) { TODO let config = load_json(format!("{}/config.json", config_path)); @@ -163,7 +163,42 @@ fn set_member(config_path: String, tf_members: &[String]) -> Result<(), &'static } if to_front.len() != 0 { let fronters = get_fronters(&config["pk_key"].as_str().unwrap(), &config["sp_key"].as_str().unwrap(), &system); - pk_set_fronters(&config["pk_key"].as_str().unwrap(), &system, to_front, &fronters); + pk_set_fronters(&config["pk_key"].as_str().unwrap(), &system, &to_front, &fronters); + sp_set_fronters(&config["sp_key"].as_str().unwrap(), &to_front, &fronters); + } + get(config_path); + Ok(()) +} + +fn add_member(config_path: String, tf_members: &[String]) -> Result<(), &'static str> { + let config = get_config(&config_path); + if config == Value::Null { + return Err("Config not found. Stopping"); + } + + let system: System = get_system(&config_path); + + let mut to_front: Vec = Vec::new(); + for member in tf_members { + for mem in &system.members { + if mem.name.to_lowercase() == member.to_lowercase() || mem.alias.to_lowercase() == member.to_lowercase() { + println!("Member {member} found"); + to_front.push(mem.clone()); + + break; + } + } + } + if to_front.len() != 0 { + let mut fronters = get_fronters(&config["pk_key"].as_str().unwrap(), &config["sp_key"].as_str().unwrap(), &system); + + let mut aux: Vec = Vec::new(); + aux.append(&mut fronters["pk"].clone()); + aux.append(&mut to_front); + to_front = aux; + + pk_set_fronters(&config["pk_key"].as_str().unwrap(), &system, &to_front, &fronters); + sp_set_fronters(&config["sp_key"].as_str().unwrap(), &to_front, &fronters); } get(config_path); Ok(()) @@ -195,9 +230,7 @@ fn get(config_path: String) { println!("Currently fronting: {}", fronters); let _ = fs::write(format!("{}/.front", config_path), fronters); } -// Set member:1 ends here -// [[file:../README.org::*Get system][Get system:1]] fn pk_get_system(key: &str) -> Value { let url = format!("{}/systems/@me", PK_URL); @@ -213,9 +246,7 @@ fn pk_get_members(key: &str, sysid: &str) -> Vec { return datas; } -// Get system:1 ends here -// [[file:../README.org::*Get fronters][Get fronters:1]] fn pk_get_fronters(key: &str, sys: &System) -> Vec { let url = format!("{}/systems/{}/fronters", PK_URL, sys.pk_userid); @@ -237,13 +268,13 @@ fn pk_get_fronters(key: &str, sys: &System) -> Vec { return members; } -fn pk_set_fronters(key: &str, sys: &System, to_front: Vec, fronters: &HashMap>) { +fn pk_set_fronters(key: &str, sys: &System, to_front: &Vec, fronters: &HashMap>) { let url = format!("{}/systems/{}/switches", PK_URL, sys.pk_userid); - if to_front != fronters["pk"] { + if to_front != &fronters["pk"] { let mut frontcodes = Vec::new(); for tf in to_front { - frontcodes.push(tf.pk_id); + frontcodes.push(String::from(&tf.pk_id)); } let mut body: HashMap<&str, Vec> = HashMap::new(); body.insert("members", frontcodes); @@ -253,9 +284,7 @@ fn pk_set_fronters(key: &str, sys: &System, to_front: Vec, fronters: &Ha } } -// Get fronters:1 ends here -// [[file:../README.org::*Get user ID][Get user ID:1]] fn sp_get_userid(key: &str) -> String { let url = format!("{}/me", SP_URL); @@ -263,9 +292,7 @@ fn sp_get_userid(key: &str) -> String { let json_res : Value = serde_json::from_str(&res.unwrap()).unwrap(); return json_res["id"].as_str().unwrap().to_string(); } -// Get user ID:1 ends here -// [[file:../README.org::*Get members ID][Get members ID:1]] fn sp_get_memberids(key: &str, system_id: &str) -> HashMap { let url = format!("{}/members/{}", SP_URL, system_id); @@ -279,9 +306,7 @@ fn sp_get_memberids(key: &str, system_id: &str) -> HashMap { return sp_memberdata; } -// Get members ID:1 ends here -// [[file:../README.org::*Get ID from member][Get ID from member:1]] fn get_sp_id(mem: &Member, ids: &HashMap) -> String { let mut member_id = String::new(); @@ -294,16 +319,14 @@ fn get_sp_id(mem: &Member, ids: &HashMap) -> String { return member_id; } -// Get ID from member:1 ends here -// [[file:../README.org::*Get fronters][Get fronters:1]] fn sp_get_fronters(key: &str, sys: &System) -> Vec { let url = format!("{}/fronters", SP_URL); let res = http_get_request(url,key); let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); - let mut members: Vec = Vec::new(); + let mut members = Vec::new(); for data in datas { let sp_id = &data["content"]["member"].as_str().unwrap(); for member in &sys.members { @@ -315,9 +338,92 @@ fn sp_get_fronters(key: &str, sys: &System) -> Vec { } return members; } -// Get fronters:1 ends here -// [[file:../README.org::*Load JSON][Load JSON:1]] +fn sp_get_frontids(key: &str, to_id: &Member) -> String { + let url = format!("{}/fronters", SP_URL); + + let res = http_get_request(url,key); + let datas: Vec = serde_json::from_str(&res.unwrap()).unwrap(); + + for data in datas { + let sp_f_id = &data["id"].as_str().unwrap(); + let sp_id = &data["content"]["member"].as_str().unwrap(); + if sp_id.to_string() == to_id.sp_id { + return sp_f_id.to_string(); + } + } + return String::new(); +} + +fn sp_set_fronters(key: &str, to_front: &Vec, fronters: &HashMap>) { + if to_front != &fronters["sp"] { + for fronting_member in &fronters["sp"] { + if !to_front.contains(&fronting_member) { + let f_id = sp_get_frontids(&key, &fronting_member); + + let url = format!("{}/frontHistory/{}", SP_URL, f_id); + + #[derive (Serialize)] + #[allow (non_snake_case)] + struct SpRem { + live: bool, + endTime: u64 + } + + let end_time = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH).expect("wa").as_secs(); + let rem = SpRem { + live: false, + endTime: end_time * 1000 + }; + + let body = serde_json::to_string(&rem).expect("Error"); + + let _ = http_patch_request(url, key, body); + } + } + + for tf_member in to_front { + if !fronters["sp"].contains(&tf_member) { + let url = format!("{}/frontHistory", SP_URL); + + #[derive (Serialize)] + #[allow (non_snake_case)] + struct SpAdd { + member: String, + custom: bool, + live: bool, + startTime: u64 + } + + let start_time = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH).expect("wa").as_secs(); + let rem = SpAdd { + member: String::from(&tf_member.sp_id), + custom: false, + live: true, + startTime: start_time * 1000 + }; + + let body = serde_json::to_string(&rem).expect("Error"); + + let _ = http_post_request_st(url, key, body); + } + } + + /* + let mut frontcodes = Vec::new(); + for tf in to_front { + frontcodes.push(tf.sp_id); + } + let mut body: HashMap<&str, Vec> = HashMap::new(); + body.insert("members", frontcodes); + */ + //let _ = http_post_request(url, key, &body); + } else { + println!("Members already fonting"); + } + +} + fn load_json(path: String) -> Value { if Path::new(&path).exists() { let config_data = fs::read_to_string(&path).expect("File not found"); @@ -327,9 +433,7 @@ fn load_json(path: String) -> Value { return Value::Null; } } -// Load JSON:1 ends here -// [[file:../README.org::*Get config json][Get config json:1]] fn get_config(config_path: &str) -> Value { let path = format!("{}/config.json", config_path); if Path::new(config_path).exists() { @@ -359,9 +463,7 @@ fn get_config(config_path: &str) -> Value { return Value::Null; } } -// Get config json:1 ends here -// [[file:../README.org::*Get system json][Get system json:1]] fn get_system(config_path: &str) -> System { let path = format!("{}/system.json", config_path); @@ -385,11 +487,13 @@ fn get_fronters(pk_key: &str, sp_key: &str, sys: &System) -> HashMap Result> { let client = reqwest::Client::new(); @@ -404,7 +508,6 @@ async fn http_get_request(url: String, key: &str) -> Result>) -> Result<(), Box> { let client = reqwest::Client::new(); @@ -418,20 +521,30 @@ async fn http_post_request(url: String, key: &str, body: &HashMap<&str, Vec Result> { +async fn http_post_request_st(url: String, key: &str, body: String) -> Result<(), Box> { let client = reqwest::Client::new(); - let res = client - .patch(url) - .body("wiwiwiw") + let c = client + .post(url) + .body(body) + .header("content-type", "application/json; charset=utf-8") .header(USER_AGENT, "Pluralsync") - .header(AUTHORIZATION, key) - .send() - .await? - .text() + .header(AUTHORIZATION, key); + let res = c.send() .await?; - Ok(res) + Ok(()) +} + +#[tokio::main] +async fn http_patch_request(url: String, key: &str, body: String ) -> Result<(), Box> { + let client = reqwest::Client::new(); + let c = client + .patch(url) + .body(body) + .header("content-type", "application/json; charset=utf-8") + .header(USER_AGENT, "Pluralsync") + .header(AUTHORIZATION, key); + let _res = c.send() + .await?; + Ok(()) } -*/ -// Http Request handler:1 ends here