use std::path::Path; use std::fs; use serde::{Serialize, Deserialize}; use serde_json::Value; use color_eyre::eyre::{eyre, Result}; use crate::api::{pk, sp}; use crate::utils::load_json; use crate::app::App; use crate::clap_ps::ForceFrom; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct System { pub pk_userid: String, pub sp_userid: String, pub members: Vec<Member>, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Member { pub pk_id: String, pub sp_id: String, pub name: String, pub aliases: Vec<String> } impl System { pub fn get_system(app: &App, update: bool) -> Result<System>{ let sys_file_path = format!("{}/system.json", app.cfg_dir); if Path::new(&sys_file_path).exists() && !update { let json_system: Value = load_json(&sys_file_path)?; let sys: System = serde_json::from_value(json_system)?; Ok(sys) } else { match Self::update_system(app) { Ok(s) => { Ok(s) }, Err(e) => { Err(e) } } } } fn update_system(app: &App) -> Result<System> { if let Some(conf) = &app.cfg { // PluralKit let pk_sys = pk::get_system(&conf.pk_key)?; let pk_id = pk_sys["id"].as_str().unwrap(); let pk_members = pk::get_members(&conf.pk_key, &pk_id)?; // Simplyplural let sp_user_id = sp::get_user_id(&conf.sp_key)?; let sp_member_ids = sp::get_member_ids(&conf.sp_key, &sp_user_id)?; // Get members let mut members: Vec<Member> = Vec::new(); for pk_mem in pk_members { let mut m = Member { pk_id: pk_mem["id"].as_str().unwrap().to_string(), sp_id: String::new(), name: pk_mem["name"].as_str().unwrap().to_string(), aliases: Vec::new(), }; if pk_mem["display_name"].as_str() != None { m.aliases.push(pk_mem["display_name"].as_str().unwrap().to_string()); } m.sp_id = sp::get_member_id(&m, &sp_member_ids)?; members.push(m); } // Create system let sys = System { pk_userid: pk_id.to_string(), sp_userid: sp_user_id, members: members.clone(), }; let json = serde_json::to_string(&sys)?; fs::write(format!("{}/system.json", &app.cfg_dir), &json)?; return Ok(sys); } Err(eyre!("No configuration loaded!")) } } #[derive(Debug, Clone)] pub struct Fronters { pub sp: Vec<Member>, pub pk: Vec<Member>, } impl Fronters { pub fn new(pk: Vec<Member>, sp: Vec<Member>) -> Self { Self {sp, pk} } pub fn get(app: &App, ff: ForceFrom) -> Result<Self> { if let Some(cfg) = &app.cfg { if let Some(sys) = &app.sys { let mut fronters = Fronters::new( pk::get_fronters(&cfg.pk_key, &sys)?, sp::get_fronters(&cfg.sp_key, &sys)?, ); if fronters.pk != fronters.sp { match ff { ForceFrom::SP => { fronters.pk = fronters.sp.clone(); } ForceFrom::PK => { fronters.sp = fronters.pk.clone(); } ForceFrom::None => { } } } return Ok(fronters); } } Err(eyre!("System or configuration missing")) } pub fn set(app: &App, to_front: Vec<Member>) -> Result<Fronters> { if let Some(cfg) = &app.cfg { if let Some(sys) = &app.sys { if let Some(fronters) = &app.fronters { pk::set_fronters(&cfg.pk_key, &sys, &to_front, &fronters)?; sp::set_fronters(&cfg.sp_key, &to_front, &fronters)?; return Ok(Fronters::new(to_front.clone(), to_front.clone())); } return Err(eyre!("Missing Fronters")); } return Err(eyre!("Missing System")); } Err(eyre!("Missing Config")) } }