fmt: cargo+clippy

This commit is contained in:
silver 2025-06-14 18:00:40 +01:00
parent 51bc2f177f
commit 9d50efb757
Signed by: silver
GPG key ID: 36F93D61BAD3FD7D
5 changed files with 222 additions and 583 deletions

311
Cargo.lock generated
View file

@ -104,56 +104,6 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.93"
@ -472,16 +422,6 @@ dependencies = [
"shlex",
]
[[package]]
name = "cfg-expr"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a2b34126159980f92da2a08bdec0694fd80fb5eb9e48aff25d20a0d8dfa710d"
dependencies = [
"smallvec",
"target-lexicon",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -521,46 +461,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "clap"
version = "4.5.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "color-eyre"
version = "0.6.5"
@ -594,22 +494,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "colored"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
"windows-sys 0.59.0",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@ -1222,31 +1106,6 @@ dependencies = [
"byteorder",
]
[[package]]
name = "gdk-pixbuf"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd242894c084f4beed508a56952750bce3e96e85eb68fdc153637daa163e10c"
dependencies = [
"gdk-pixbuf-sys",
"gio",
"glib",
"libc",
]
[[package]]
name = "gdk-pixbuf-sys"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b34f3b580c988bd217e9543a2de59823fafae369d1a055555e5f95a8b130b96"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -1317,80 +1176,6 @@ version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
[[package]]
name = "gio"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2a5c3829f5794cb15120db87707b2ec03720edff7ad09eb7b711b532e3fe747"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"gio-sys",
"glib",
"libc",
"pin-project-lite",
"smallvec",
]
[[package]]
name = "gio-sys"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521e93a7e56fc89e84aea9a52cfc9436816a4b363b030260b699950ff1336c83"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"windows-sys 0.59.0",
]
[[package]]
name = "glib"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c501c495842c2b23cdacead803a5a343ca2a5d7a7ddaff14cc5f6cf22cfb92c2"
dependencies = [
"bitflags 2.6.0",
"futures-channel",
"futures-core",
"futures-executor",
"futures-task",
"futures-util",
"gio-sys",
"glib-macros",
"glib-sys",
"gobject-sys",
"libc",
"memchr",
"smallvec",
]
[[package]]
name = "glib-macros"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebe6dc9ce29887c4b3b74d78d5ba473db160a258ae7ed883d23632ac7fed7bc9"
dependencies = [
"heck",
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]]
name = "glib-sys"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ab79e1ed126803a8fb827e3de0e2ff95191912b8db65cee467edb56fc4cc215"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "gloo-timers"
version = "0.3.0"
@ -1403,17 +1188,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gobject-sys"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec9aca94bb73989e3cfdbf8f2e0f1f6da04db4d291c431f444838925c4c63eda"
dependencies = [
"glib-sys",
"libc",
"system-deps",
]
[[package]]
name = "h2"
version = "0.3.26"
@ -1983,12 +1757,6 @@ version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "isahc"
version = "0.9.14"
@ -2341,15 +2109,6 @@ dependencies = [
"libm",
]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]]
name = "object"
version = "0.36.4"
@ -2365,12 +2124,6 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "opaque-debug"
version = "0.3.1"
@ -2601,15 +2354,6 @@ dependencies = [
"zerocopy 0.7.35",
]
[[package]]
name = "proc-macro-crate"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.20+deprecated"
@ -3357,18 +3101,6 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "simple_logger"
version = "4.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e7e46c8c90251d47d08b28b8a419ffb4aede0f87c2eea95e17d1d5bacbf3ef1"
dependencies = [
"colored",
"log",
"time 0.3.36",
"windows-sys 0.48.0",
]
[[package]]
name = "simplecss"
version = "0.2.2"
@ -3389,20 +3121,16 @@ name = "skynet_discord_bot"
version = "0.1.0"
dependencies = [
"chrono",
"clap",
"color-eyre",
"dotenvy",
"eyre",
"gdk-pixbuf",
"lettre",
"log",
"maud",
"rand 0.9.0",
"resvg",
"serde",
"serde_json",
"serenity",
"simple_logger",
"sqlx",
"surf",
"tiny-skia",
@ -3764,12 +3492,6 @@ dependencies = [
"unicode-properties",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
@ -3919,25 +3641,6 @@ dependencies = [
"libc",
]
[[package]]
name = "system-deps"
version = "7.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4be53aa0cba896d2dc615bd42bbc130acdcffa239e0a2d965ea5b3b2a86ffdb"
dependencies = [
"cfg-expr",
"heck",
"pkg-config",
"toml",
"version-compare",
]
[[package]]
name = "target-lexicon"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
[[package]]
name = "tempfile"
version = "3.12.0"
@ -4024,9 +3727,7 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"time-core",
@ -4547,12 +4248,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.1"
@ -4571,12 +4266,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
[[package]]
name = "version_check"
version = "0.9.5"

View file

@ -48,14 +48,10 @@ maud = "0.27"
toml = "0.8.23"
serde = "1.0"
gdk-pixbuf = "0.20.10"
clap = { version = "4.1.4", features = ["derive"] }
# for image conversion
eyre = "0.6.8"
color-eyre = "0.6.2"
usvg-text-layout = "0.29.0"
usvg = "0.29.0"
resvg = "0.29.0"
tiny-skia = "0.8.3"
log = "0.4.20"
simple_logger = "4.2.0"
tiny-skia = "0.8.3"

View file

@ -1,30 +1,30 @@
use chrono::{Datelike, Utc};
use rand::{rngs::SmallRng, seq::IndexedRandom, SeedableRng};
use serde::Deserialize;
use serenity::{
all::GuildId,
async_trait,
builder::{CreateAttachment, EditGuild},
client::{Context, EventHandler},
model::gateway::{GatewayIntents, Ready},
Client,
};
use skynet_discord_bot::common::database::{db_init, DataBase, RoleAdder};
use skynet_discord_bot::{get_config, get_now_iso, Config};
use std::{fs, process, sync::Arc};
use std::ffi::{OsStr, OsString};
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use std::process::Command;
use chrono::{Datelike, Utc};
use gdk_pixbuf::{Pixbuf, PixbufFormat, PixbufLoader};
use gdk_pixbuf::prelude::PixbufLoaderExt;
use rand::rngs::SmallRng;
use rand::SeedableRng;
use rand::seq::IndexedRandom;
use resvg::usvg;
use serde::Deserialize;
use serenity::all::GuildId;
use serenity::builder::{CreateAttachment, EditGuild};
use skynet_discord_bot::{
common::{
database::{db_init, DataBase},
renderer::{Args, Renderer},
},
get_config, get_now_iso, Config,
};
use sqlx::{Pool, Sqlite};
use std::{
ffi::OsString,
fs,
path::PathBuf,
process::{self, Command},
sync::Arc,
};
use tokio::sync::RwLock;
use skynet_discord_bot::common::renderer::{Args, Renderer};
#[tokio::main]
async fn main() {
@ -61,7 +61,6 @@ impl EventHandler for Handler {
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;
@ -82,19 +81,17 @@ async fn update_icon_main(ctx: Arc<Context>) {
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
let logos = get_logos(&config_global, &config_toml);
@ -104,31 +101,29 @@ async fn update_icon_main(ctx: Arc<Context>) {
let mut rng = SmallRng::from_os_rng();
let logo_selected = logos_filtered.choose(&mut rng).unwrap();
logo_set(&ctx, &db,&server, logo_selected).await;
logo_set(&ctx, &db, &server, logo_selected).await;
}
struct FestivalData{
#[derive(Debug)]
struct FestivalData {
current: Vec<String>,
exclusions: Vec<String>,
}
fn get_festival(config_toml: &ConfigToml)-> FestivalData {
fn get_festival(config_toml: &ConfigToml) -> FestivalData {
let today = Utc::now();
let day = today.day();
let month = today.month();
let year = today.year();
let mut result = FestivalData {
current: vec![],
exclusions: vec![],
};
for festival in &config_toml.festivals {
if (day >= festival.start.day && day <= festival.end.day) &&
(month >= festival.start.month && month <= festival.end.month ) {
if festival.start.year == 0 || festival.end.year == 0 {
result.current.push(festival.name.to_owned());
} else if (year >= festival.start.year && year <= festival.end.year) {
if (day >= festival.start.day && day <= festival.end.day) && (month >= festival.start.month && month <= festival.end.month) {
if festival.start.year == 0 || festival.end.year == 0 || (year >= festival.start.year && year <= festival.end.year) {
result.current.push(festival.name.to_owned());
}
} else if !festival.all_year {
@ -144,24 +139,24 @@ struct ConfigToml {
source: ConfigTomlSource,
festivals: Vec<ConfigTomlFestivals>,
}
#[derive(Deserialize)]
#[derive(Deserialize, Debug)]
struct ConfigTomlSource {
repo: String,
directory: String,
}
#[derive(Deserialize)]
#[derive(Deserialize, Debug)]
struct ConfigTomlFestivals {
name: String,
all_year: bool,
start: ConfigTomlFestivalsTime,
end: ConfigTomlFestivalsTime,
}
#[derive(Deserialize)]
#[derive(Deserialize, Debug)]
struct ConfigTomlFestivalsTime {
day: u32,
month: u32,
year:i32
year: i32,
}
fn get_config_icons() -> ConfigToml {
@ -169,56 +164,34 @@ fn get_config_icons() -> ConfigToml {
let config: ConfigToml = toml::from_str(toml_raw).unwrap();
config
}
fn clone_repo(config: &Config, config_toml: &ConfigToml){
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("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: &PathBuf, out: &PathBuf){
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");
.arg("pull")
.arg("origin")
.arg("main")
.current_dir(&folder)
.output()
.expect("failed to execute process");
}
#[derive(Debug)]
struct LogoData {
name: OsString,
path: PathBuf,
}
fn get_logos(config: &Config, config_toml: &ConfigToml) -> Vec<LogoData> {
fn get_logos(config: &Config, config_toml: &ConfigToml) -> Vec<LogoData> {
let folder = format!("{}/open-governance/{}", &config.home, &config_toml.source.directory);
let folder_path = PathBuf::from(&folder);
let mut folder_output = folder_path.clone();
folder_output.push("converted");
let paths = fs::read_dir(folder).unwrap();
let args = Args{
let args = Args {
input: folder_path.clone(),
output: folder_output,
colors: String::from(""),
@ -226,15 +199,15 @@ fn get_logos(config: &Config, config_toml: &ConfigToml) -> Vec<LogoData> {
height: 1024,
};
let mut r = Renderer::new(&args).unwrap();
let mut logos = vec![];
for tmp in paths.flatten() {
let path_local = tmp.path().to_owned();
let path_local2 = tmp.path().to_owned();
let name = path_local2.file_name().unwrap().to_owned();
let mut path = tmp.path();
if path.is_dir() {
continue;
}
@ -250,14 +223,14 @@ fn get_logos(config: &Config, config_toml: &ConfigToml) -> Vec<LogoData> {
path_new.pop();
path_new.push("converted");
path_new.push(filename);
// check if exists
if !path_new.exists() {
// convert if it hasnt been converted already
match r.render(&path_local, &args) {
Ok(_) => log::info!("Successfully rendered all colors of {path_local:?}"),
Err(e) => {
log::error!("Failed to render {path_local:?}: {}", e)
Ok(_) => {}
Err(_e) => {
dbg!("Failed to render {path_local:?}: {}");
}
}
}
@ -266,18 +239,18 @@ fn get_logos(config: &Config, config_toml: &ConfigToml) -> Vec<LogoData> {
}
};
logos.push(LogoData{
logos.push(LogoData {
name,
path,
});
println!("Name: {}", &tmp.path().display());
// println!("Name: {}", &tmp.path().display());
}
logos
}
fn logos_filter(festival_data: &FestivalData, existing: Vec<LogoData>) -> Vec<LogoData>{
fn logos_filter(festival_data: &FestivalData, existing: Vec<LogoData>) -> Vec<LogoData> {
let mut filtered: Vec<LogoData> = vec![];
'outer: for logo in existing {
@ -310,7 +283,6 @@ fn logos_filter(festival_data: &FestivalData, existing: Vec<LogoData>) -> Vec<L
filtered
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct ServerIcons {
pub id: i64,
@ -318,9 +290,9 @@ pub struct ServerIcons {
pub date: String,
}
async fn logo_set(ctx: &Arc<Context>, db: &Pool<Sqlite>, server: &GuildId, logo_selected: &LogoData){
async fn logo_set(ctx: &Arc<Context>, db: &Pool<Sqlite>, server: &GuildId, logo_selected: &LogoData) {
// add to teh database
logo_set_db(db ,logo_selected).await;
logo_set_db(db, logo_selected).await;
let icon = CreateAttachment::path(logo_selected.path.to_str().unwrap_or_default()).await.unwrap();
@ -329,21 +301,27 @@ async fn logo_set(ctx: &Arc<Context>, db: &Pool<Sqlite>, server: &GuildId, logo
server.edit(ctx, builder).await.unwrap();
}
async fn logo_set_db(db: &Pool<Sqlite>, logo_selected: &LogoData){
async fn logo_set_db(db: &Pool<Sqlite>, logo_selected: &LogoData) {
let name = logo_selected.name.to_str().unwrap_or_default();
sqlx::query_as::<_, ServerIcons>(
match sqlx::query_as::<_, ServerIcons>(
"
INSERT OR REPLACE INTO server_icons (name, date)
VALUES (?1, ?2, ?3)
VALUES (?1, ?2)
",
)
.bind(name)
.bind(get_now_iso(false))
.fetch_optional(db)
.await;
.bind(name)
.bind(get_now_iso(false))
.fetch_optional(db)
.await
{
Ok(_) => {}
Err(e) => {
dbg!(e);
}
}
}
// fn command(config_toml: &ConfigToml, logo_selected: &LogoData){
// let web_url = format!("{}/src/branch/main/{}/{}", &config_toml.source.repo, &config_toml.source.directory, &logo_selected.name.to_str().unwrap_or_default());
// }
// }

View file

@ -3,4 +3,4 @@ pub mod minecraft;
pub mod set_roles;
pub mod wolves;
pub mod renderer;
pub mod renderer;

View file

@ -1,216 +1,192 @@
// this code is taken from https://github.com/MCorange99/svg2colored-png/tree/main
// I was unable to figure out how to use usvg myself so younked it from here.
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use clap::builder::OsStr;
use clap::Parser;
use color_eyre::{Result, eyre::bail};
// use clap::builder::OsStr;
use color_eyre::{eyre::bail, Result};
use usvg_text_layout::TreeTextToPath;
#[derive(Parser, Debug, Clone)]
#[command(name = "svg2colored-png")]
#[command(author = "MCorange <mcorangecodes@gmail.com>")]
#[command(version = env!("CARGO_PKG_VERSION"))]
#[command(about = "Converts svgs to multiple png's that differ in color", long_about = "Made by MCorange <mcorangecodes@gmail.com>")]
#[derive(Debug, Clone)]
pub struct Args {
/// Input folder with the SVG's
#[arg(long, short)]
pub input: PathBuf,
pub input: PathBuf,
/// Output folder where the PNG's will be placed
#[arg[long, short]]
pub output: PathBuf,
/// Output folder where the PNG's will be placed
pub output: PathBuf,
/// Comma seperated colors that will be used in HEX Eg. 000000,ffffff
/// Can be like an object: black:000000,white:ffffff
#[arg[long, short, default_value_t = String::from("0d6efd,6c757d,198754,0dcaf0,ffc107,dc3545,f8f9fa,212529,ffffff,000000")]]
pub colors: String,
/// Comma seperated colors that will be used in HEX Eg. 000000,ffffff
/// Can be like an object: black:000000,white:ffffff
pub colors: String,
/// Width of the generated PNG's
#[arg(long, default_value_t = 1024)]
pub width: u32,
/// Height of the generated PNG's
#[arg(long, default_value_t = 1024)]
pub height: u32
/// Width of the generated PNG's
pub width: u32,
/// Height of the generated PNG's
pub height: u32,
}
#[derive(Debug, Clone)]
enum ColorType {
Array(Vec<String>),
Object(Vec<(String, String)>),
None
Array(Vec<String>),
Object(Vec<(String, String)>),
None,
}
#[derive(Debug, Clone)]
pub struct Renderer {
fontdb: usvg_text_layout::fontdb::Database,
colors: ColorType,
size: (u32, u32),
pub count: u64,
fontdb: usvg_text_layout::fontdb::Database,
colors: ColorType,
size: (u32, u32),
pub count: u64,
}
impl Renderer {
pub fn new(args: &Args) -> Result<Self> {
let mut db = usvg_text_layout::fontdb::Database::new();
db.load_system_fonts();
pub fn new(args: &Args) -> Result<Self> {
let mut db = usvg_text_layout::fontdb::Database::new();
db.load_system_fonts();
let mut this = Self {
fontdb: db,
colors: ColorType::None,
size: (args.width, args.height),
count: 0,
};
let mut this = Self {
fontdb: db,
colors: ColorType::None,
size: (args.width, args.height),
count: 0,
};
let colors = if args.colors.contains(':') {
//? object
let obj = args.colors.split(',').map(|s| {
let s = s.split(':').collect::<Vec<&str>>();
let colors = if args.colors.contains(':') {
//? object
let obj = args
.colors
.split(',')
.map(|s| {
let s = s.split(':').collect::<Vec<&str>>();
if s.len() < 2 {
log::error!("Invalid color object, try checking help");
return None;
}
if s.len() < 2 {
dbg!("Invalid color object, try checking help");
return None;
}
Some((s[0].to_string(), s[1].to_string()))
}).collect::<Vec<Option<(String, String)>>>();
Some((s[0].to_string(), s[1].to_string()))
})
.collect::<Vec<Option<(String, String)>>>();
let mut colors = Vec::new();
let mut colors = Vec::new();
for c in obj {
if let Some(c) = c {
std::fs::create_dir_all(args.output.join(&c.0))?;
for c in obj.into_iter().flatten() {
std::fs::create_dir_all(args.output.join(&c.0))?;
colors.push(c);
}
}
colors.push(c);
}
ColorType::Object(colors)
ColorType::Object(colors)
} else {
//? list
// let colors = args.colors.split(",").map(|s| {
// s.to_string()
// })
// .collect::<Vec<String>>();
} else {
//? list
// let colors = args.colors.split(",").map(|s| {
// s.to_string()
// })
// .collect::<Vec<String>>();
let mut colors = Vec::new();
let mut colors = Vec::new();
for color in args.colors.split(',') {
std::fs::create_dir_all(args.output.join(color))?;
colors.push(color.to_string())
}
for color in args.colors.split(',') {
std::fs::create_dir_all(args.output.join(&color))?;
colors.push(color.to_string())
}
ColorType::Array(colors)
};
this.colors = colors;
Ok(this)
}
ColorType::Array(colors)
};
pub fn render(&mut self, fi: &Path, args: &Args) -> Result<()> {
match fi.extension() {
Some(e) if e.to_str() == Some("svg") => {}
Some(_) | None => {
dbg!("Filer {:?} is not of type SVG", fi);
// util::logger::warning(format!("File '{}' is not of SVG type", fi.clone().to_str().unwrap()));
bail!("Failed to render");
}
};
this.colors = colors;
Ok(this)
}
pub fn render(&mut self, fi: &Path, args: &Args) -> Result<()> {
match fi.extension() {
Some(e) if e.to_str() == Some("svg") => {},
Some(_) |
None => {
log::warn!("Filer {:?} is not of type SVG", fi);
// util::logger::warning(format!("File '{}' is not of SVG type", fi.clone().to_str().unwrap()));
bail!("Failed to render");
}
};
match self.colors.clone() {
ColorType::Array(c) => {
for color in c {
log::info!("Rendering the color {color:?}");
let fo = self.get_out_file(fi, &color, &args);
self.render_one(fi, &fo, &color)?;
}
},
ColorType::Object(c) => {
for o in c {
log::info!("Rendering the color {:?}", o);
let fo = self.get_out_file(fi, &o.0, &args);
self.render_one(fi, &fo, &o.1)?;
}
},
ColorType::None => unreachable!(),
match self.colors.clone() {
ColorType::Array(c) => {
for color in c {
// log::info!("Rendering the color {color:?}");
let fo = self.get_out_file(fi, &color, args);
self.render_one(fi, &fo, &color)?;
}
Ok(())
}
fn render_one(&mut self, fi: &Path, fo: &Path, color: &String) -> Result<()>{
if fo.exists() {
log::warn!("File {fo:?} exists, skipping");
return Ok(());
}
ColorType::Object(c) => {
for o in c {
// log::info!("Rendering the color {:?}", o);
let fo = self.get_out_file(fi, &o.0, args);
self.render_one(fi, &fo, &o.1)?;
}
let svg = self.set_color(&self.get_svg_data(fi)?, &color);
let mut opt = usvg::Options::default();
// Get file's absolute directory.
opt.resources_dir = std::fs::canonicalize(fi.clone())
.ok()
.and_then(|p| p.parent().map(|p| p.to_path_buf()));
let mut tree = match usvg::Tree::from_data(svg.as_bytes(), &opt) {
Ok(v) => v,
Err(_) => {
log::error!("Failed to parse {fi:?}");
bail!("");
}
};
tree.convert_text(&self.fontdb);
let mut pixmap = tiny_skia::Pixmap::new(self.size.0, self.size.1).unwrap();
log::info!("Rendering {fo:?}");
//? maybe handle this and possibly throw error if its none
let _ = resvg::render(
&tree,
usvg::FitTo::Size(self.size.0, self.size.1),
tiny_skia::Transform::default(),
pixmap.as_mut(),
);
pixmap.save_png(fo)?;
self.count += 1;
Ok(())
}
ColorType::None => unreachable!(),
}
Ok(())
}
#[inline]
fn get_out_file(&mut self, fi: &Path, sub_folder: &String, args: &Args) -> PathBuf {
let mut fo: std::path::PathBuf = args.output.clone();
// fo.push(sub_folder);
fo.push(fi.file_name().unwrap_or(&OsStr::from("default")).to_str().unwrap_or("default").replace(".svg", ""));
fo.set_extension("png");
fo
fn render_one(&mut self, fi: &Path, fo: &Path, color: &String) -> Result<()> {
if fo.exists() {
dbg!("File {fo:?} exists, skipping");
return Ok(());
}
fn set_color(&self, svg: &String, color: &String) -> String {
svg.replace("fill=\"currentColor\"", &format!("fill=\"#{}\"", color))
}
let svg = self.set_color(&self.get_svg_data(fi)?, color);
fn get_svg_data(&self, fi: &Path) -> Result<String>{
match std::fs::read_to_string(fi) {
Ok(d) => Ok(d),
Err(_) => {
log::error!("File {fi:?} does not exist");
bail!("File {fi:?} does not exist");
}
}
let opt = usvg::Options {
// Get file's absolute directory.
resources_dir: std::fs::canonicalize(fi).ok().and_then(|p| p.parent().map(|p| p.to_path_buf())),
..Default::default()
};
let mut tree = match usvg::Tree::from_data(svg.as_bytes(), &opt) {
Ok(v) => v,
Err(_) => {
dbg!("Failed to parse {fi:?}");
bail!("");
}
};
tree.convert_text(&self.fontdb);
let mut pixmap = tiny_skia::Pixmap::new(self.size.0, self.size.1).unwrap();
// log::info!("Rendering {fo:?}");
//? maybe handle this and possibly throw error if its none
let _ = resvg::render(&tree, usvg::FitTo::Size(self.size.0, self.size.1), tiny_skia::Transform::default(), pixmap.as_mut());
pixmap.save_png(fo)?;
self.count += 1;
Ok(())
}
#[inline]
fn get_out_file(&mut self, fi: &Path, _sub_folder: &str, args: &Args) -> PathBuf {
let mut fo: std::path::PathBuf = args.output.clone();
// fo.push(sub_folder);
fo.push(fi.file_name().unwrap_or(OsStr::new("default")).to_str().unwrap_or("default").replace(".svg", ""));
fo.set_extension("png");
fo
}
fn set_color(&self, svg: &str, color: &String) -> String {
svg.replace("fill=\"currentColor\"", &format!("fill=\"#{}\"", color))
}
fn get_svg_data(&self, fi: &Path) -> Result<String> {
match std::fs::read_to_string(fi) {
Ok(d) => Ok(d),
Err(_) => {
dbg!("File {fi:?} does not exist");
bail!("File {fi:?} does not exist");
}
}
}
}
}