feat: initial tests of new function to handle changing the logo in discord server

This commit is contained in:
silver 2025-06-07 00:10:52 +01:00
parent fcfcfb8409
commit 725bfa41cc
Signed by: silver
GPG key ID: 36F93D61BAD3FD7D
2 changed files with 216 additions and 0 deletions

23
.server-icons.toml Normal file
View file

@ -0,0 +1,23 @@
# this file controls the
[source]
repo = "https://forgejo.skynet.ie/Computer_Society/open-goverance"
directory = "Resources/Logo_Variants"
[[festivals]]
name = "pride"
all_year = true
start = { day = 1, month = 6, year = 0}
end = { day = 30, month = 6, year = 0}
[[festivals]]
name = "christmas"
all_year = false
start = { day = 1, month = 12, year = 0}
end = { day = 31, month = 12, year = 0}
[[festivals]]
name = "halloween"
all_year = false
start = { day = 1, month = 12, year = 0}
end = { day = 31, month = 12, year = 0}

View file

@ -0,0 +1,193 @@
use serenity::{
async_trait,
client::{Context, EventHandler},
model::gateway::{GatewayIntents, Ready},
Client,
};
use skynet_discord_bot::common::database::{db_init, DataBase};
use skynet_discord_bot::{get_config, Config};
use std::{fs, process, sync::Arc};
use std::fs::File;
use std::io::Read;
use std::process::Command;
use chrono::{Datelike, Utc};
use gdk_pixbuf::PixbufLoader;
use gdk_pixbuf::prelude::PixbufLoaderExt;
use resvg::usvg;
use serde::Deserialize;
use serenity::all::GuildId;
use tokio::sync::RwLock;
#[tokio::main]
async fn main() {
let config = get_config();
let db = match db_init(&config).await {
Ok(x) => x,
Err(_) => return,
};
// Intents are a bitflag, bitwise operations can be used to dictate which intents to use
let intents = GatewayIntents::GUILDS | GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_MEMBERS;
// Build our client.
let mut client = Client::builder(&config.discord_token, intents)
.event_handler(Handler {})
.await
.expect("Error creating client");
{
let mut data = client.data.write().await;
data.insert::<Config>(Arc::new(RwLock::new(config)));
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
}
if let Err(why) = client.start().await {
println!("Client error: {:?}", why);
}
}
struct Handler;
#[async_trait]
impl EventHandler for Handler {
async fn ready(&self, ctx: Context, ready: Ready) {
let ctx = Arc::new(ctx);
println!("{} is connected!", ready.user.name);
// pull in the open governance repo
// u[date committee server
update_icon_main(Arc::clone(&ctx)).await;
// finish up
process::exit(0);
}
}
async fn update_icon_main(ctx: Arc<Context>) {
let db_lock = {
let data_read = ctx.data.read().await;
data_read.get::<DataBase>().expect("Expected Config in TypeMap.").clone()
};
let db = db_lock.read().await;
let config_lock = {
let data_read = ctx.data.read().await;
data_read.get::<Config>().expect("Expected Config in TypeMap.").clone()
};
let config_global = config_lock.read().await;
let config_toml = get_config_icons();
let server = GuildId::new(689189992417067052);
// clone repo into local folder
clone_repo(&config_global, &config_toml);
// see if there is a current festival
let festival_data = get_festival(&config_toml);
// get a list of all the graphics files
get_logos(&config_global, &config_toml);
}
fn get_festival(config_toml: &ConfigToml)-> (Option<String>, Vec<String>){
let today = Utc::now();
let day = today.day();
let month = today.month();
let year = today.year();
let mut festival_current = None;
let mut festival_not = vec![];
for festival in &config_toml.festivals {
if (day >= festival.start.day && day <= festival.end.day)
&& (month >= festival.start.month && month <= festival.end.month )
&& (year >= festival.start.year && year <= festival.end.year) {
festival_current = Some(festival.name.to_owned());
} else if !festival.all_year {
festival_not.push(festival.name.to_owned());
}
}
(festival_current, festival_not)
}
#[derive(Deserialize)]
struct ConfigToml {
source: ConfigTomlSource,
festivals: Vec<ConfigTomlFestivals>,
}
#[derive(Deserialize)]
struct ConfigTomlSource {
repo: String,
directory: String,
}
#[derive(Deserialize)]
struct ConfigTomlFestivals {
name: String,
all_year: bool,
start: ConfigTomlFestivalsTime,
end: ConfigTomlFestivalsTime,
}
#[derive(Deserialize)]
struct ConfigTomlFestivalsTime {
day: u32,
month: u32,
year:i32
}
fn get_config_icons() -> ConfigToml {
let toml_raw = include_str!("../../.server-icons.toml");
let config: ConfigToml = toml::from_str(toml_raw).unwrap();
config
}
fn clone_repo(config: &Config, config_toml: &ConfigToml){
let url = &config_toml.source.repo;
let folder = format!("{}/open-governance", &config.home);
Command::new("git")
.arg("clone")
.arg(url)
.arg(&folder)
.output()
.expect("failed to execute process");
Command::new("git")
.arg("pull")
.arg("origin")
.arg("main")
.current_dir(&folder)
.output()
.expect("failed to execute process");
}
fn convert_svg_to_png(original: &str, out: &str){
let mut f = File::open(original).unwrap();
let mut buffer = Vec::new();
// read the whole file
f.read_to_end(&mut buffer).unwrap();
let loader = PixbufLoader::with_mime_type("image/svg+xml")
.expect("error loader");
loader.write(&buffer).expect("TODO: panic message");
loader.close().expect("TODO: panic message");
let pixbuf = loader.pixbuf().expect("no pixbuf");
let (width, height) = (pixbuf.width(), pixbuf.height());
println!("size: {}x{}", width, height);
let bytes: Vec<u8> =
pixbuf.save_to_bufferv("png", &[]).expect("must not error");
fs::write(out, &bytes).expect("TODO: panic message");
}
fn get_logos(config: &Config, config_toml: &ConfigToml){
let folder = format!("{}/open-governance/{}", &config.home, &config_toml.source.directory);
let paths = fs::read_dir(folder).unwrap();
for path in paths {
let tmp = path.unwrap();
println!("Name: {}", &tmp.path().display());
}
}