1
0
Fork 0
stickerdeploy/src/deploy_discord.rs
2022-08-22 16:39:05 +01:00

221 lines
7.1 KiB
Rust

use crate::creds::Creds;
use crate::sticker_config::{DiscordDeployLocation, Sticker, StickerConfig, StickerType};
use indexmap::IndexMap;
use serenity::http::client::Http as DiscordClient;
//use serenity::cache::Cache as DiscordCache;
use serenity::model::prelude::Emoji;
use std::collections::{HashMap, VecDeque};
use serde_json::json;
fn split_by(
pack_contents: &[String],
sticker_type: StickerType,
deploy_locations: &[DiscordDeployLocation],
pack_emojis: &HashMap<String, Sticker>,
) -> IndexMap<String, Vec<(String, Sticker)>> {
let pack_type_emoji_count = pack_emojis
.iter()
.filter(|emoji| emoji.1.r#type == sticker_type)
.count();
let max_type_emoji_total: u64 = deploy_locations
.iter()
.map(|loc| {
return match sticker_type {
StickerType::Regular => loc.max_regular_emoji,
StickerType::Gif => loc.max_animated_emoji,
_ => unreachable!("wrong sticker type for discord"),
};
})
.sum();
if pack_type_emoji_count > max_type_emoji_total.try_into().unwrap() {
panic!("not enough space in servers for emoji, please add more servers to deploy across")
}
let mut pack_type_emojis: VecDeque<(String, Sticker)> = pack_contents
.iter()
.filter(|emoji| {
return pack_emojis.get(*emoji).unwrap().r#type == sticker_type;
})
.map(|emoji| {
return (emoji.clone(), pack_emojis.get(emoji).unwrap().clone());
})
.collect();
let mut emojis_per_server: IndexMap<String, Vec<(String, Sticker)>> = IndexMap::new();
for deploy_location in deploy_locations.iter() {
emojis_per_server.insert(deploy_location.deploy_name.clone(), Vec::new());
}
'outer: for deploy_location in deploy_locations.iter() {
let mut sticker_count = 0;
let max_type_emoji = match sticker_type {
StickerType::Regular => deploy_location.max_regular_emoji,
StickerType::Gif => deploy_location.max_animated_emoji,
_ => unreachable!("wrong sticker type for discord"),
};
while sticker_count < max_type_emoji {
let emoji = pack_type_emojis.pop_front();
if emoji.is_none() {
break 'outer;
}
emojis_per_server
.get_mut(&deploy_location.deploy_name)
.unwrap()
.push(emoji.unwrap());
sticker_count += 1;
}
}
emojis_per_server
}
pub async fn deploy_discord(
deploy_id: String,
sticker_config: StickerConfig,
creds: Creds,
base_stickerdb_path: String,
) {
let discord_token = creds.discord_bot_token.as_str();
let discord_client = DiscordClient::new(discord_token);
//let discord_cache = DiscordCache::new()
let deploy_where = sticker_config.deploy_where.get(&deploy_id).unwrap();
let deploy_locations = deploy_where.discord.as_ref().unwrap().clone();
let deploy_locations_map: HashMap<_, _> = deploy_locations
.iter()
.map(|loc| (loc.deploy_name.clone(), loc))
.collect();
let pack_contents = sticker_config.sticker_sets.get(&deploy_where.pack_id).unwrap();
let pack_emojis: HashMap<String, Sticker> = pack_contents
.iter()
.map(|emoji_name| {
return (
emoji_name.clone(),
sticker_config.stickers.get(emoji_name).unwrap().clone(),
);
})
.collect();
let mut emojis_per_server: IndexMap<String, Vec<(String, Sticker)>> = IndexMap::new();
for deploy_location in deploy_locations.iter() {
emojis_per_server.insert(deploy_location.deploy_name.clone(), Vec::new());
}
// block only so can hide in IDE
{
let regular_emoji_per_server = split_by(
pack_contents,
StickerType::Regular,
&deploy_locations,
&pack_emojis,
);
for loc in regular_emoji_per_server.into_iter() {
emojis_per_server
.get_mut(&loc.0)
.unwrap()
.extend(loc.1.into_iter());
}
let gif_emoji_per_server = split_by(
pack_contents,
StickerType::Gif,
&deploy_locations,
&pack_emojis,
);
for loc in gif_emoji_per_server.into_iter() {
emojis_per_server
.get_mut(&loc.0)
.unwrap()
.extend(loc.1.into_iter());
}
}
for server_k_v in emojis_per_server.iter() {
let deploy_name = server_k_v.0.to_owned();
let deploy_emojis = server_k_v.1.to_owned();
println!("Deploying to {}", deploy_name);
let deploy_location = deploy_locations_map.get(&deploy_name).unwrap();
let deploy_emoji_names: Vec<String> = deploy_emojis
.iter()
.map(|deploy_emoji| deploy_emoji.0.clone())
.collect();
let discord_emojis = discord_client
.get_emojis(deploy_location.id)
.await
.expect("could not fetch discord emoji");
let discord_emojis_names: Vec<String> = discord_emojis
.iter()
.map(|emoji| emoji.name.clone())
.collect();
let invalid_emojis: Vec<Emoji> = discord_emojis
.clone()
.into_iter()
.filter(|emoji| !deploy_emoji_names.contains(&emoji.name))
.collect();
if !invalid_emojis.is_empty() {
for emoji in invalid_emojis.iter() {
println!("Removing Emoji {}", &emoji.name);
discord_client
.delete_emoji(deploy_location.id, emoji.id.0)
.await
.expect("could not delete emoji")
}
}
let missing_emojis: Vec<String> = deploy_emoji_names
.clone()
.into_iter()
.filter(|emoji| !discord_emojis_names.contains(emoji))
.collect();
if !missing_emojis.is_empty() {
for emoji in missing_emojis.iter() {
println!("Uploading Emoji {}", &emoji);
let emoji_data = pack_emojis.get(emoji).unwrap();
let image_path = std::path::PathBuf::from(&base_stickerdb_path)
.join(std::path::PathBuf::from(emoji_data.file.clone()));
let image_data =
serenity::utils::read_image(image_path).expect("could not open emoji file");
discord_client
.create_emoji(
deploy_location.id,
&json!({
"name": emoji,
"image": image_data,
}),
None,
)
.await
.expect("could not upload emoji");
}
}
println!(
"Missing: {:#?}\nInvalid: {:#?}",
missing_emojis, invalid_emojis
);
}
//println!("{:#?}", emojis_per_server);
//println!("{} {} {:?}", max_regular_emoji_total, max_animated_emoji_total, deploy_locations);
}