pfp and disc modules
This commit is contained in:
parent
a22b2c5e4d
commit
4ce3af150c
21
README.org
21
README.org
|
@ -12,7 +12,18 @@ On the first run, if it does not exist, PluralSync will create a configuration d
|
||||||
#+begin_src js
|
#+begin_src js
|
||||||
{
|
{
|
||||||
"pk_key": "// Pluralkit token",
|
"pk_key": "// Pluralkit token",
|
||||||
"sp_key": "// Simplplural token"
|
"sp_key": "// Simplplural token",
|
||||||
|
"pfp_module": {
|
||||||
|
"enabled": false,
|
||||||
|
"pfp_folder": "// Folder to grab profile pictures, they follow they member1member2...memberX.png format",
|
||||||
|
"pfp_output_path": "// Path for the copied selected pfp"
|
||||||
|
},
|
||||||
|
"disc_module": {
|
||||||
|
"enabled": false,
|
||||||
|
"token": "// Discord user token",
|
||||||
|
"python_path": "// Path of the python executable",
|
||||||
|
"script_path": "// Path of the pfp changer python script"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -36,8 +47,14 @@ Displays the current front. The result is displayed in console but also stored i
|
||||||
*** Memberlist
|
*** Memberlist
|
||||||
Writes the known list of members based on the =system.json= file.
|
Writes the known list of members based on the =system.json= file.
|
||||||
|
|
||||||
|
** Modules
|
||||||
|
*** PFP module
|
||||||
|
requires docs
|
||||||
|
*** Discord module
|
||||||
|
goes against ToS be gentle
|
||||||
|
|
||||||
* Future
|
* Future
|
||||||
Given the nature of the project as a learning exercise, there are currently a set of features and improvements I'd like to add eventually.
|
Given the nature of the project as a learning exercise, there are currently a set of features and improvements I'd like to add eventually.
|
||||||
- [ ] Proper error handling (What I have currently is simply a mess)
|
- [X] Proper error handling (What I have currently is simply a mess)
|
||||||
- [ ] Rofi and zenity support
|
- [ ] Rofi and zenity support
|
||||||
- [ ] Proper way to handle front conflicts between PluralKit and SimplyPlural
|
- [ ] Proper way to handle front conflicts between PluralKit and SimplyPlural
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
{
|
{
|
||||||
"pk_key": "// Pluralkit token",
|
"pk_key": "// Pluralkit token",
|
||||||
"sp_key": "// Simplplural token"
|
"sp_key": "// Simplplural token",
|
||||||
|
"pfp_module": {
|
||||||
|
"enabled": false,
|
||||||
|
"pfp_folder": "// Folder to grab profile pictures, they follow they member1member2.png format",
|
||||||
|
"pfp_output_path": "// Path for the copied selected pfp"
|
||||||
|
},
|
||||||
|
"disc_module": {
|
||||||
|
"enabled": false,
|
||||||
|
"token": "// Discord user token",
|
||||||
|
"python_path": "// Path of the python executable",
|
||||||
|
"script_path": "// Path of the pfp changer python script"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
155
src/main.rs
155
src/main.rs
|
@ -1,7 +1,8 @@
|
||||||
use std::fs;
|
use std::fs::{self, remove_file};
|
||||||
use std::fs::create_dir;
|
use std::fs::create_dir;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
use reqwest::header::{USER_AGENT, AUTHORIZATION};
|
use reqwest::header::{USER_AGENT, AUTHORIZATION};
|
||||||
|
|
||||||
|
@ -13,6 +14,45 @@ use dirs;
|
||||||
const PK_URL: &str = "https://api.pluralkit.me/v2";
|
const PK_URL: &str = "https://api.pluralkit.me/v2";
|
||||||
const SP_URL: &str = "https://api.apparyllis.com/v1";
|
const SP_URL: &str = "https://api.apparyllis.com/v1";
|
||||||
|
|
||||||
|
const EXAMPLE_JSON: &str = r#"{
|
||||||
|
"pk_key": "// Pluralkit token",
|
||||||
|
"sp_key": "// Simplplural token",
|
||||||
|
"pfp_module": {
|
||||||
|
"enabled": false,
|
||||||
|
"pfp_folder": "// Folder to grab profile pictures, they follow they member1member2.png format",
|
||||||
|
"pfp_output_path": "// Path for the copied selected pfp"
|
||||||
|
},
|
||||||
|
"disc_module": {
|
||||||
|
"enabled": false,
|
||||||
|
"token": "// Discord user token",
|
||||||
|
"python_path": "// Path of the python executable",
|
||||||
|
"script_path": "// Path of the pfp changer python script"
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Config {
|
||||||
|
pk_key: String,
|
||||||
|
sp_key: String,
|
||||||
|
pfp_module: PfpModule,
|
||||||
|
disc_module: DiscModule
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct PfpModule {
|
||||||
|
enabled: bool,
|
||||||
|
pfp_folder: String,
|
||||||
|
pfp_output_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct DiscModule {
|
||||||
|
enabled: bool,
|
||||||
|
token: String,
|
||||||
|
python_path: String,
|
||||||
|
script_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
struct System {
|
struct System {
|
||||||
pk_userid: String,
|
pk_userid: String,
|
||||||
|
@ -81,7 +121,9 @@ memberlist - Shows loaded member list"#;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
"get" => get(config_path),
|
"get" => {
|
||||||
|
let _ = get(config_path);
|
||||||
|
},
|
||||||
"memberlist" => memberlist(config_path),
|
"memberlist" => memberlist(config_path),
|
||||||
&_ => println!("{}", helpstring),
|
&_ => println!("{}", helpstring),
|
||||||
}
|
}
|
||||||
|
@ -93,29 +135,25 @@ memberlist - Shows loaded member list"#;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync(config_path: String) -> Result<(), String>{
|
fn sync(config_path: String) -> Result<(), &'static str> {
|
||||||
// Get config
|
// Get config
|
||||||
let config = get_config(&config_path);
|
let config: Config = match get_config(&config_path) {
|
||||||
if config == Value::Null {
|
Ok(c) => c,
|
||||||
println!("Stopping.");
|
Err(e) => return Err(e)
|
||||||
return Ok(());
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let pk_key = &config["pk_key"].as_str().unwrap();
|
|
||||||
let sp_key = &config["sp_key"].as_str().unwrap();
|
|
||||||
|
|
||||||
// Get Pluralkit system id
|
// Get Pluralkit system id
|
||||||
let pk_sys = pk_get_system(pk_key);
|
let pk_sys = pk_get_system(&config.pk_key);
|
||||||
let pk_sysid = pk_sys["id"].as_str().unwrap();
|
let pk_sysid = pk_sys["id"].as_str().unwrap();
|
||||||
|
|
||||||
// Get Simplyplural user id
|
// Get Simplyplural user id
|
||||||
let sp_user_id = sp_get_userid(sp_key);
|
let sp_user_id = sp_get_userid(&config.sp_key);
|
||||||
|
|
||||||
// Get Simplyplural member ids
|
// Get Simplyplural member ids
|
||||||
let sp_member_ids = sp_get_memberids(sp_key, &sp_user_id);
|
let sp_member_ids = sp_get_memberids(&config.sp_key, &sp_user_id);
|
||||||
|
|
||||||
// get members
|
// get members
|
||||||
let pk_members = pk_get_members(pk_key, pk_sysid);
|
let pk_members = pk_get_members(&config.pk_key, pk_sysid);
|
||||||
let mut members: Vec<Member> = Vec::new();
|
let mut members: Vec<Member> = Vec::new();
|
||||||
for member in pk_members {
|
for member in pk_members {
|
||||||
let mut m = Member {
|
let mut m = Member {
|
||||||
|
@ -156,10 +194,10 @@ TODO }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn set_member(config_path: String, tf_members: &[String]) -> Result<(), &'static str> {
|
fn set_member(config_path: String, tf_members: &[String]) -> Result<(), &'static str> {
|
||||||
let config = get_config(&config_path);
|
let config: Config = match get_config(&config_path) {
|
||||||
if config == Value::Null {
|
Ok(c) => c,
|
||||||
return Err("Config not found. Stopping");
|
Err(e) => return Err(e)
|
||||||
}
|
};
|
||||||
|
|
||||||
let system: System = get_system(&config_path);
|
let system: System = get_system(&config_path);
|
||||||
|
|
||||||
|
@ -175,12 +213,12 @@ fn set_member(config_path: String, tf_members: &[String]) -> Result<(), &'static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if to_front.len() != 0 {
|
if to_front.len() != 0 {
|
||||||
let fronters = get_fronters(&config["pk_key"].as_str().unwrap(), &config["sp_key"].as_str().unwrap(), &system);
|
let fronters = get_fronters(&config.pk_key, &config.sp_key, &system);
|
||||||
|
|
||||||
pk_set_fronters(&config["pk_key"].as_str().unwrap(), &system, &to_front, &fronters);
|
pk_set_fronters(&config.pk_key, &system, &to_front, &fronters);
|
||||||
sp_set_fronters(&config["sp_key"].as_str().unwrap(), &to_front, &fronters);
|
sp_set_fronters(&config.sp_key, &to_front, &fronters);
|
||||||
|
|
||||||
get(config_path);
|
let _ = get(config_path);
|
||||||
} else {
|
} else {
|
||||||
println!("No members found. Known members:\n--------------------------");
|
println!("No members found. Known members:\n--------------------------");
|
||||||
memberlist(config_path);
|
memberlist(config_path);
|
||||||
|
@ -190,10 +228,10 @@ fn set_member(config_path: String, tf_members: &[String]) -> Result<(), &'static
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_member(config_path: String, tf_members: &[String]) -> Result<(), &'static str> {
|
fn add_member(config_path: String, tf_members: &[String]) -> Result<(), &'static str> {
|
||||||
let config = get_config(&config_path);
|
let config: Config = match get_config(&config_path) {
|
||||||
if config == Value::Null {
|
Ok(c) => c,
|
||||||
return Err("Config not found. Stopping");
|
Err(e) => return Err(e)
|
||||||
}
|
};
|
||||||
|
|
||||||
let system: System = get_system(&config_path);
|
let system: System = get_system(&config_path);
|
||||||
|
|
||||||
|
@ -207,17 +245,17 @@ fn add_member(config_path: String, tf_members: &[String]) -> Result<(), &'static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if to_front.len() != 0 {
|
if to_front.len() != 0 {
|
||||||
let fronters = get_fronters(&config["pk_key"].as_str().unwrap(), &config["sp_key"].as_str().unwrap(), &system);
|
let fronters = get_fronters(&config.pk_key, &config.sp_key, &system);
|
||||||
|
|
||||||
let mut aux: Vec<Member> = Vec::new();
|
let mut aux: Vec<Member> = Vec::new();
|
||||||
aux.append(&mut fronters.pk.clone());
|
aux.append(&mut fronters.pk.clone());
|
||||||
aux.append(&mut to_front);
|
aux.append(&mut to_front);
|
||||||
to_front = aux;
|
to_front = aux;
|
||||||
|
|
||||||
pk_set_fronters(&config["pk_key"].as_str().unwrap(), &system, &to_front, &fronters);
|
pk_set_fronters(&config.pk_key, &system, &to_front, &fronters);
|
||||||
sp_set_fronters(&config["sp_key"].as_str().unwrap(), &to_front, &fronters);
|
sp_set_fronters(&config.sp_key, &to_front, &fronters);
|
||||||
|
|
||||||
get(config_path);
|
let _ = get(config_path);
|
||||||
} else {
|
} else {
|
||||||
println!("No members found. Known members:\n--------------------------");
|
println!("No members found. Known members:\n--------------------------");
|
||||||
memberlist(config_path);
|
memberlist(config_path);
|
||||||
|
@ -239,18 +277,37 @@ fn memberlist(config_path: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(config_path: String) {
|
fn get(config_path: String) -> Result<(), &'static str> {
|
||||||
let config = get_config(&config_path);
|
let config: Config = match get_config(&config_path) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => return Err(e)
|
||||||
|
};
|
||||||
let sys = get_system(&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 f = get_fronters(&config.pk_key, &config.sp_key, &sys);
|
||||||
let mut names = Vec::new();
|
let mut names = Vec::new();
|
||||||
for m in &f.pk {
|
for m in &f.sp {
|
||||||
names.push(String::from(&m.name));
|
names.push(String::from(&m.name));
|
||||||
}
|
}
|
||||||
let fronters = names.join(" || ");
|
let fronters = names.join(" || ");
|
||||||
println!("Currently fronting: {}", fronters);
|
println!("Currently fronting: {}", fronters);
|
||||||
let _ = fs::write(format!("{}/.front", config_path), fronters);
|
let _ = fs::write(format!("{}/.front", config_path), fronters);
|
||||||
|
|
||||||
|
if config.pfp_module.enabled {
|
||||||
|
let pfpnames = names.join("").to_lowercase() + ".png";
|
||||||
|
|
||||||
|
if Path::new(&config.pfp_module.pfp_output_path).exists() {
|
||||||
|
let _ = remove_file(&config.pfp_module.pfp_output_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Command::new("sh").arg("-c").arg(format!("cp {}/{} {}", &config.pfp_module.pfp_folder, pfpnames, &config.pfp_module.pfp_output_path)).output().expect("pfp module error");
|
||||||
|
|
||||||
|
if config.disc_module.enabled {
|
||||||
|
Command::new("sh").arg("-c").arg(format!("{} {}", &config.disc_module.python_path, &config.disc_module.script_path)).output().expect("discord module error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pk_get_system(key: &str) -> Value {
|
fn pk_get_system(key: &str) -> Value {
|
||||||
|
@ -446,33 +503,23 @@ fn load_json(path: String) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config(config_path: &str) -> Value {
|
fn get_config(config_path: &str) -> Result<Config, &'static str> {
|
||||||
let path = format!("{}/config.json", config_path);
|
let path = format!("{}/config.json", config_path);
|
||||||
if Path::new(config_path).exists() {
|
if Path::new(config_path).exists() {
|
||||||
|
|
||||||
let result = load_json(String::from(&path));
|
let result = load_json(String::from(&path));
|
||||||
|
|
||||||
if result == Value::Null {
|
if result == Value::Null {
|
||||||
println!("Config file missing, creating template in {path}");
|
let _ = fs::write(path, EXAMPLE_JSON);
|
||||||
let _ = fs::write(path, r#"
|
return Err("Config file missing, creating template in {path}");
|
||||||
{
|
|
||||||
"pk_key": "// Pluralkit token",
|
|
||||||
"sp_key": "// Simplplural token"
|
|
||||||
}
|
|
||||||
"#);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} else {
|
} else {
|
||||||
println!("Directory {config_path} does not exist. Creating with template config");
|
let config: Config = serde_json::from_value(result).expect("Error unwrapping");
|
||||||
let _ = create_dir(config_path);
|
return Ok(config);
|
||||||
let _ = fs::write(path, r#"
|
|
||||||
{
|
|
||||||
"pk_key": "// Pluralkit token",
|
|
||||||
"sp_key": "// Simplplural token"
|
|
||||||
}
|
}
|
||||||
"#);
|
} else {
|
||||||
return Value::Null;
|
let _ = create_dir(config_path);
|
||||||
|
let _ = fs::write(path, EXAMPLE_JSON);
|
||||||
|
return Err("Directory {config_path} does not exist. Creating with template config");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import discord
|
||||||
|
|
||||||
|
config_dir = os.getenv('APPDATA') if os.name == "nt" else os.path.expanduser('~') + "/.config"
|
||||||
|
config_dir += "/pluralsync/config.json"
|
||||||
|
|
||||||
|
f = open(config_dir)
|
||||||
|
json = json.load(f)
|
||||||
|
|
||||||
|
class MyClient(discord.Client):
|
||||||
|
async def on_ready(self):
|
||||||
|
print('Logged on as', self.user)
|
||||||
|
pfp_path = json["pfp_module"]["pfp_output_path"]
|
||||||
|
fp = open(pfp_path, 'rb')
|
||||||
|
pfp = fp.read()
|
||||||
|
await self.user.edit(avatar=pfp)
|
||||||
|
await self.close()
|
||||||
|
|
||||||
|
client = MyClient()
|
||||||
|
client.run(json["disc_module"]["token"])
|
Loading…
Reference in New Issue