diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..e5a6fd1 --- /dev/null +++ b/src/args.rs @@ -0,0 +1,38 @@ +use clap::{Args, Parser, Subcommand}; + +#[derive(Debug, Parser)] +#[clap()] +pub struct CLIArgs { + #[clap(subcommand)] + pub command: Commands, +} + +#[derive(Debug, Subcommand)] +pub enum Commands { + Deploy(DeployArgs), + CreateTelegramStickerPack(CreateTelegramStickerPackArgs), + CheckMissing(CheckMissingArgs), +} + +#[derive(Debug, Args)] +pub struct DeployArgs { + pub folder: String, + pub deploy_id: String, +} + +#[derive(Debug, Args)] +pub struct CreateTelegramStickerPackArgs { + pub token: String, + pub user_id: u64, + pub name: String, + pub title: String, + pub emojis: String, + pub r#type: String, + pub filename: String, +} + +#[derive(Debug, Args)] +pub struct CheckMissingArgs { + pub folder: String, + pub sticker_sets: Vec, +} diff --git a/src/cmd_check_missing.rs b/src/cmd_check_missing.rs new file mode 100644 index 0000000..d5921c8 --- /dev/null +++ b/src/cmd_check_missing.rs @@ -0,0 +1,57 @@ +use std::{collections::HashMap, fs::File, path::PathBuf}; + +use crate::{args::CheckMissingArgs, sticker_config::StickerConfig}; + +pub async fn check_missing(args: CheckMissingArgs) { + let base_path = PathBuf::from(&args.folder); + let config_path = base_path.join("stickers.yml"); + let config_file = File::open(config_path).expect("could not open stickers.yml"); + let config: StickerConfig = + serde_yaml::from_reader(config_file).expect("could not parse stickers.yml"); + + let stickers_for_sticker_sets: Vec<(String, Vec)> = args + .sticker_sets + .iter() + .map(|pack_id| { + return ( + pack_id.clone(), + config.sticker_sets.get(pack_id).unwrap().clone(), + ); + }) + .collect(); + + let missing_stickers: Vec<(String, Vec)> = stickers_for_sticker_sets + .iter() + .map(|(sticker_set_name, sticker_set_stickers)| { + return ( + sticker_set_name.clone(), + config + .stickers + .iter() + .filter(|all_stickers_sticker| { + !sticker_set_stickers.contains(all_stickers_sticker.0) + }) + .map(|b| b.0.clone()) + .collect::>(), + ); + }) + .collect(); + + let total_missing: Vec = HashMap::::from_iter( + missing_stickers + .iter() + .map(|(_, stickers)| stickers.clone()) + .collect::>>() + .concat() + .iter() + .map(|sticker_name| (sticker_name.clone(), true)), + ) + .into_keys() + .collect(); + + for (pack_name, stickers) in missing_stickers.iter() { + println!("Pack: {}\nMissing: {:#?}\n", pack_name, stickers); + } + + println!("Total Missing {:#?}", total_missing); +} diff --git a/src/cmd_createtg.rs b/src/cmd_createtg.rs new file mode 100644 index 0000000..03a37be --- /dev/null +++ b/src/cmd_createtg.rs @@ -0,0 +1,45 @@ +use crate::args::CreateTelegramStickerPackArgs; +use crate::tg_api::TelegramAPI; + +use std::fs::File; +use std::io::Read; + +pub async fn create_telegram_sticker_pack(args: CreateTelegramStickerPackArgs) { + let bot = TelegramAPI::new(args.token); + + let mut file = File::open(args.filename).unwrap(); + let mut file_data: Vec = Vec::new(); + file.read_to_end(&mut file_data) + .expect("could not read file"); + + let mut png_sticker: Option> = None; + let mut tgs_sticker: Option> = None; + let mut webm_sticker: Option> = None; + + match args.r#type.as_str() { + "regular" => { + png_sticker = Some(file_data); + } + "animated" => { + tgs_sticker = Some(file_data); + } + "video" => { + webm_sticker = Some(file_data); + } + _ => { + panic!("wrong type, use regular, animated or video") + } + } + + bot.create_sticker_pack( + args.user_id, + args.name, + args.title, + args.emojis, + png_sticker, + tgs_sticker, + webm_sticker, + ) + .await + .expect("could not create sticker pack"); +} diff --git a/src/cmd_deploy.rs b/src/cmd_deploy.rs new file mode 100644 index 0000000..30b601c --- /dev/null +++ b/src/cmd_deploy.rs @@ -0,0 +1,40 @@ +use crate::creds::Creds; +use crate::deploy_discord::deploy_discord; +use crate::deploy_telegram::deploy_telegram; +use crate::sticker_config::StickerConfig; + +use std::fs::File; +use std::path::PathBuf; + +pub async fn deploy(args: crate::args::DeployArgs) { + let base_path = PathBuf::from(&args.folder); + let config_path = base_path.join("stickers.yml"); + let creds_path = base_path.join("../stickerdb/creds.yml"); + + let config_file = File::open(config_path).expect("could not open stickers.yml"); + let creds_file = File::open(creds_path).expect("could not open creds.yml"); + + let config: StickerConfig = + serde_yaml::from_reader(config_file).expect("could not parse stickers.yml"); + let creds: Creds = serde_yaml::from_reader(creds_file).expect("could not parse creds.yml"); + + match config + .deploy_where + .get(&args.deploy_id) + .expect("no deploy config with id specified found") + .deploy_to + .as_str() + { + "discord" => { + println!("deploying {} to discord", &args.deploy_id); + deploy_discord(args.deploy_id, config, creds, args.folder).await; + } + "telegram" => { + println!("deploying {} to telegram", &args.deploy_id); + deploy_telegram(args.deploy_id, config, creds, args.folder).await; + } + _ => { + panic!("deploy_to not set") + } + } +} diff --git a/src/deploy_discord.rs b/src/deploy_discord.rs index e7e4a08..f7b1412 100644 --- a/src/deploy_discord.rs +++ b/src/deploy_discord.rs @@ -97,6 +97,7 @@ pub async fn deploy_discord( .sticker_sets .get(&deploy_where.pack_id) .unwrap(); + let pack_emojis: HashMap = pack_contents .iter() .map(|emoji_name| { @@ -210,11 +211,6 @@ pub async fn deploy_discord( .expect("could not upload emoji"); } } - - println!( - "Missing: {:#?}\nInvalid: {:#?}", - missing_emojis, invalid_emojis - ); } //println!("{:#?}", emojis_per_server); diff --git a/src/deploy_telegram.rs b/src/deploy_telegram.rs index 4e8a0da..3a4e718 100644 --- a/src/deploy_telegram.rs +++ b/src/deploy_telegram.rs @@ -93,6 +93,20 @@ pub async fn deploy_telegram( panic!("pack contains a invalid type of emoji for pack type") } + let max = match deploy_location.r#type { + StickerType::Regular => 120, + StickerType::TelegramVideo => 50, + StickerType::TelegramAnimated => 50, + _ => { + unreachable!(); + } + }; + + if pack_contents.len() >= max - 1 { + panic!("too many stickers in pack"); + } + println!("{}", pack_contents.len()); + let tg_bot = TelegramAPI::new(creds.telegram_bot_token); let tg_sticker_set = tg_bot .get_sticker_set(&deploy_location.name) @@ -210,8 +224,6 @@ pub async fn deploy_telegram( new_stickers.push(sticker_name.clone()); } - - println!("{:#?}", missing_stickers); } // Update tg_stickers with current sticker contents diff --git a/src/main.rs b/src/main.rs index 569bf5f..abdad7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,57 +1,32 @@ +pub mod args; +pub mod cmd_check_missing; +pub mod cmd_createtg; +pub mod cmd_deploy; pub mod creds; pub mod deploy_discord; pub mod deploy_telegram; pub mod sticker_config; pub mod tg_api; -use creds::Creds; -use deploy_discord::deploy_discord; -use deploy_telegram::deploy_telegram; -use sticker_config::StickerConfig; - use clap::Parser; -use std::fs::File; -use std::path::PathBuf; -#[derive(Debug, Parser)] -#[clap()] -pub struct CLIArgs { - pub folder: String, - pub deploy_id: String, -} +use args::{CLIArgs, Commands}; +use cmd_check_missing::check_missing; +use cmd_createtg::create_telegram_sticker_pack; +use cmd_deploy::deploy; #[tokio::main] async fn main() { let args = CLIArgs::parse(); - - let base_path = PathBuf::from(&args.folder); - let config_path = base_path.join("stickers.yml"); - let creds_path = base_path.join("../stickerdb/creds.yml"); - - let config_file = File::open(config_path).expect("could not open stickers.yml"); - let creds_file = File::open(creds_path).expect("could not open creds.yml"); - - let config: StickerConfig = - serde_yaml::from_reader(config_file).expect("could not parse stickers.yml"); - let creds: Creds = serde_yaml::from_reader(creds_file).expect("could not parse creds.yml"); - - match config - .deploy_where - .get(&args.deploy_id) - .expect("no deploy config with id specified found") - .deploy_to - .as_str() - { - "discord" => { - println!("deploying {} to discord", &args.deploy_id); - deploy_discord(args.deploy_id, config, creds, args.folder).await; + match args.command { + Commands::Deploy(subcommand_args) => { + deploy(subcommand_args).await; } - "telegram" => { - println!("deploying {} to telegram", &args.deploy_id); - deploy_telegram(args.deploy_id, config, creds, args.folder).await; + Commands::CreateTelegramStickerPack(subcommand_args) => { + create_telegram_sticker_pack(subcommand_args).await; } - _ => { - panic!("deploy_to not set") + Commands::CheckMissing(subcommand_args) => { + check_missing(subcommand_args).await; } } } diff --git a/src/tg_api.rs b/src/tg_api.rs index c802121..4c9cc86 100644 --- a/src/tg_api.rs +++ b/src/tg_api.rs @@ -116,6 +116,58 @@ impl TelegramAPI { Ok(res_json.result.unwrap()) } + #[allow(clippy::too_many_arguments)] + pub async fn create_sticker_pack( + &self, + user_id: u64, + name: String, + title: String, + emojis: String, + png_sticker: Option>, + tgs_sticker: Option>, + webm_sticker: Option>, + ) -> Result> { + let url = format!("{}/bot{}/createNewStickerSet", API_BASE, self.token); + + let mut form = reqwest::multipart::Form::new(); + form = form.text("user_id", user_id.to_string()); + form = form.text("name", name); + form = form.text("title", title); + form = form.text("emojis", emojis); + + if png_sticker.is_some() { + form = form.part( + "png_sticker", + reqwest::multipart::Part::bytes(png_sticker.unwrap()).file_name(""), + ); + } + if tgs_sticker.is_some() { + form = form.part( + "tgs_sticker", + reqwest::multipart::Part::bytes(tgs_sticker.unwrap()), + ); + } + if webm_sticker.is_some() { + form = form.part( + "webm_sticker", + reqwest::multipart::Part::bytes(webm_sticker.unwrap()), + ); + } + + let res = self.client.get(url).multipart(form).send().await?; + + let res_json = res.json::>().await?; + + if !res_json.ok { + return Err(Box::new(TelegramError::new( + res_json.error_code.unwrap(), + res_json.description.unwrap(), + ))); + } + + Ok(res_json.result.unwrap()) + } + pub async fn upload_sticker( &self, user_id: u64,