fmt: cargo+clippy
This commit is contained in:
parent
51bc2f177f
commit
9d50efb757
5 changed files with 222 additions and 583 deletions
|
@ -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());
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -3,4 +3,4 @@ pub mod minecraft;
|
|||
pub mod set_roles;
|
||||
pub mod wolves;
|
||||
|
||||
pub mod renderer;
|
||||
pub mod renderer;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue