add mastoapi deploy support and change a bunch of things
This commit is contained in:
parent
c4869d1447
commit
ea80ad1e9a
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -584,9 +584,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.132"
|
version = "0.2.147"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub async fn check_missing(args: CheckMissingArgs) {
|
||||||
.sticker_sets
|
.sticker_sets
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pack_id| {
|
.map(|pack_id| {
|
||||||
|
println!("{}", pack_id);
|
||||||
return (pack_id, config.sticker_sets.get(pack_id).unwrap());
|
return (pack_id, config.sticker_sets.get(pack_id).unwrap());
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::creds::Creds;
|
|
||||||
use crate::deploy_discord::deploy_discord;
|
use crate::deploy_discord::deploy_discord;
|
||||||
|
use crate::deploy_mastodon::deploy_mastodon;
|
||||||
use crate::deploy_telegram::deploy_telegram;
|
use crate::deploy_telegram::deploy_telegram;
|
||||||
use crate::sticker_config::StickerConfig;
|
use crate::sticker_config::StickerConfig;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
@ -16,9 +17,16 @@ pub async fn deploy(args: crate::args::DeployArgs) {
|
||||||
|
|
||||||
let config: StickerConfig =
|
let config: StickerConfig =
|
||||||
serde_yaml::from_reader(config_file).expect("could not parse stickers.yml");
|
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");
|
let creds: HashMap<String, String> =
|
||||||
|
serde_yaml::from_reader(creds_file).expect("could not parse creds.yml");
|
||||||
|
|
||||||
for deploy_id in args.deploy_ids.into_iter() {
|
let mut deploy_ids = args.deploy_ids;
|
||||||
|
|
||||||
|
if deploy_ids.is_empty() {
|
||||||
|
deploy_ids = config.deploy_where.keys().cloned().collect::<Vec<String>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
for deploy_id in deploy_ids.into_iter() {
|
||||||
let sticker_config = config.clone();
|
let sticker_config = config.clone();
|
||||||
|
|
||||||
match sticker_config
|
match sticker_config
|
||||||
|
@ -48,6 +56,16 @@ pub async fn deploy(args: crate::args::DeployArgs) {
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
"mastodon" => {
|
||||||
|
println!("deploying {} to mastodon", &deploy_id);
|
||||||
|
deploy_mastodon(
|
||||||
|
deploy_id,
|
||||||
|
sticker_config,
|
||||||
|
creds.clone(),
|
||||||
|
args.folder.clone(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("deploy_to not set")
|
panic!("deploy_to not set")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
|
||||||
pub struct Creds {
|
|
||||||
pub discord_bot_token: String,
|
|
||||||
pub telegram_bot_token: String,
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::creds::Creds;
|
|
||||||
use crate::sticker_config::{DiscordDeployLocation, Sticker, StickerConfig, StickerType};
|
use crate::sticker_config::{DiscordDeployLocation, Sticker, StickerConfig, StickerType};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use serenity::http::client::Http as DiscordClient;
|
use serenity::http::client::Http as DiscordClient;
|
||||||
|
@ -79,16 +78,12 @@ fn split_by(
|
||||||
pub async fn deploy_discord(
|
pub async fn deploy_discord(
|
||||||
deploy_id: String,
|
deploy_id: String,
|
||||||
sticker_config: StickerConfig,
|
sticker_config: StickerConfig,
|
||||||
creds: Creds,
|
creds: HashMap<String, String>,
|
||||||
base_stickerdb_path: String,
|
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_where = sticker_config.deploy_where.get(&deploy_id).unwrap();
|
||||||
let deploy_locations = deploy_where.discord.as_ref().unwrap().clone();
|
let deploy_locations = deploy_where.discord.as_ref().unwrap().clone();
|
||||||
let deploy_locations_map: HashMap<_, _> = deploy_locations
|
let deploy_locations_map: HashMap<String, &DiscordDeployLocation> = deploy_locations
|
||||||
.iter()
|
.iter()
|
||||||
.map(|loc| (loc.deploy_name.clone(), loc))
|
.map(|loc| (loc.deploy_name.clone(), loc))
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -152,6 +147,9 @@ pub async fn deploy_discord(
|
||||||
|
|
||||||
let deploy_location = deploy_locations_map.get(&deploy_name).unwrap();
|
let deploy_location = deploy_locations_map.get(&deploy_name).unwrap();
|
||||||
|
|
||||||
|
let discord_token = creds.get(&deploy_location.credential_name).unwrap();
|
||||||
|
let discord_client = DiscordClient::new(discord_token);
|
||||||
|
|
||||||
let deploy_emoji_names: Vec<String> = deploy_emojis
|
let deploy_emoji_names: Vec<String> = deploy_emojis
|
||||||
.iter()
|
.iter()
|
||||||
.map(|deploy_emoji| deploy_emoji.0.clone())
|
.map(|deploy_emoji| deploy_emoji.0.clone())
|
||||||
|
|
142
src/deploy_mastodon.rs
Normal file
142
src/deploy_mastodon.rs
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
use std::{collections::HashMap, io::Read, path::PathBuf, process::Command};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
mastodon_api::{AdminEmoji, MastodonAPI},
|
||||||
|
sticker_config::{Sticker, StickerConfig},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn convert_to_png(path: PathBuf) -> Vec<u8> {
|
||||||
|
let output = Command::new("convert")
|
||||||
|
.args([
|
||||||
|
"-format",
|
||||||
|
"png",
|
||||||
|
"-resize",
|
||||||
|
"128x128",
|
||||||
|
path.as_os_str().to_str().unwrap(),
|
||||||
|
"png:-",
|
||||||
|
])
|
||||||
|
.output()
|
||||||
|
.expect("failed to execute process");
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
panic!(
|
||||||
|
"failed to run convert, stderr: {}",
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
output.stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn deploy_mastodon(
|
||||||
|
deploy_id: String,
|
||||||
|
sticker_config: StickerConfig,
|
||||||
|
creds: HashMap<String, String>,
|
||||||
|
base_stickerdb_path: String,
|
||||||
|
) {
|
||||||
|
let deploy_where = sticker_config.deploy_where.get(&deploy_id).unwrap();
|
||||||
|
|
||||||
|
let deploy_location = deploy_where.mastodon.as_ref().unwrap();
|
||||||
|
|
||||||
|
let pack_contents = sticker_config
|
||||||
|
.sticker_sets
|
||||||
|
.get(&deploy_where.pack_id)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let pack_stickers: HashMap<String, Sticker> = pack_contents
|
||||||
|
.iter()
|
||||||
|
.map(|sticker_name| {
|
||||||
|
return (
|
||||||
|
sticker_name.clone(),
|
||||||
|
sticker_config.stickers.get(sticker_name).unwrap().clone(),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let token = creds.get(&deploy_location.credential_name).unwrap();
|
||||||
|
|
||||||
|
let mastodon_api = MastodonAPI::new(token.to_string(), deploy_location.api_base.clone());
|
||||||
|
|
||||||
|
let filter = vec!["domain:local".to_string()];
|
||||||
|
|
||||||
|
let mut mastodon_emojis = mastodon_api
|
||||||
|
.get_custom_emoji(&filter)
|
||||||
|
.await
|
||||||
|
.expect("could not get custom emojis");
|
||||||
|
|
||||||
|
// Delete emojis which have been removed from list
|
||||||
|
{
|
||||||
|
let invalid_emojis: Vec<AdminEmoji> = mastodon_emojis
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|emoji| {
|
||||||
|
!(pack_contents.contains(&emoji.shortcode)
|
||||||
|
|| emoji.category != deploy_location.category)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for invalid_emoji in invalid_emojis.iter() {
|
||||||
|
println!("Deleting emoji with name {}", &invalid_emoji.shortcode);
|
||||||
|
mastodon_api
|
||||||
|
.delete_custom_emoji(&invalid_emoji.id)
|
||||||
|
.await
|
||||||
|
.expect("could not delete emoji");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(category) = &deploy_location.category {
|
||||||
|
mastodon_emojis = mastodon_emojis
|
||||||
|
.into_iter()
|
||||||
|
.filter(|emoji| emoji.category.is_some())
|
||||||
|
.filter(|emoji| emoji.category == Some(category.to_string()))
|
||||||
|
.collect();
|
||||||
|
} else {
|
||||||
|
mastodon_emojis = mastodon_emojis
|
||||||
|
.into_iter()
|
||||||
|
.filter(|emoji| emoji.category.is_none())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
// add emoji that arent in mastodon_emojis
|
||||||
|
{
|
||||||
|
let missing_emoji: Vec<String> = pack_contents
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|emoji_name| {
|
||||||
|
for emoji in mastodon_emojis.iter() {
|
||||||
|
if &emoji.shortcode == emoji_name {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for emoji_name in missing_emoji.iter() {
|
||||||
|
println!("Uploading Emoji: {}", emoji_name);
|
||||||
|
let sticker_data = pack_stickers.get(emoji_name).unwrap();
|
||||||
|
|
||||||
|
let file_path = PathBuf::from(&base_stickerdb_path).join(&sticker_data.file);
|
||||||
|
|
||||||
|
let mut file_data: Vec<u8>;
|
||||||
|
if file_path.extension().unwrap() != "png" {
|
||||||
|
file_data = convert_to_png(file_path);
|
||||||
|
} else {
|
||||||
|
file_data = Vec::new();
|
||||||
|
|
||||||
|
let mut file = std::fs::File::open(file_path).unwrap();
|
||||||
|
file.read_to_end(&mut file_data)
|
||||||
|
.expect("could not read file");
|
||||||
|
}
|
||||||
|
|
||||||
|
mastodon_api
|
||||||
|
.upload_emoji(
|
||||||
|
emoji_name.clone(),
|
||||||
|
deploy_location.category.clone(),
|
||||||
|
file_data,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("could not upload emoji");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ use std::ops::Index;
|
||||||
use std::{collections::HashMap, error::Error};
|
use std::{collections::HashMap, error::Error};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
creds::Creds,
|
|
||||||
sticker_config::{Sticker, StickerConfig, StickerType},
|
sticker_config::{Sticker, StickerConfig, StickerType},
|
||||||
tg_api::{TelegramAPI, TelegramSticker},
|
tg_api::{TelegramAPI, TelegramSticker},
|
||||||
};
|
};
|
||||||
|
@ -56,7 +55,7 @@ impl TelegramStickerIDState {
|
||||||
pub async fn deploy_telegram(
|
pub async fn deploy_telegram(
|
||||||
deploy_id: String,
|
deploy_id: String,
|
||||||
sticker_config: StickerConfig,
|
sticker_config: StickerConfig,
|
||||||
creds: Creds,
|
creds: HashMap<String, String>,
|
||||||
base_stickerdb_path: String,
|
base_stickerdb_path: String,
|
||||||
) {
|
) {
|
||||||
let mut tg_state = TelegramStickerIDState::new(&base_stickerdb_path);
|
let mut tg_state = TelegramStickerIDState::new(&base_stickerdb_path);
|
||||||
|
@ -106,7 +105,9 @@ pub async fn deploy_telegram(
|
||||||
panic!("too many stickers in pack");
|
panic!("too many stickers in pack");
|
||||||
}
|
}
|
||||||
|
|
||||||
let tg_bot = TelegramAPI::new(creds.telegram_bot_token);
|
let token = creds.get(&deploy_location.credential_name).unwrap();
|
||||||
|
|
||||||
|
let tg_bot = TelegramAPI::new(token.to_string());
|
||||||
let tg_sticker_set = tg_bot
|
let tg_sticker_set = tg_bot
|
||||||
.get_sticker_set(&deploy_location.name)
|
.get_sticker_set(&deploy_location.name)
|
||||||
.await
|
.await
|
||||||
|
@ -241,7 +242,7 @@ pub async fn deploy_telegram(
|
||||||
tg_state.set(&new_sticker.file_unique_id, sticker_name);
|
tg_state.set(&new_sticker.file_unique_id, sticker_name);
|
||||||
|
|
||||||
tg_stickers.push((
|
tg_stickers.push((
|
||||||
sticker_name.clone(),
|
sticker_name.to_string(),
|
||||||
tg_new_sticker_set
|
tg_new_sticker_set
|
||||||
.stickers
|
.stickers
|
||||||
.index(new_sticker_position_base + i)
|
.index(new_sticker_position_base + i)
|
||||||
|
|
|
@ -2,9 +2,10 @@ pub mod args;
|
||||||
pub mod cmd_check_missing;
|
pub mod cmd_check_missing;
|
||||||
pub mod cmd_createtg;
|
pub mod cmd_createtg;
|
||||||
pub mod cmd_deploy;
|
pub mod cmd_deploy;
|
||||||
pub mod creds;
|
|
||||||
pub mod deploy_discord;
|
pub mod deploy_discord;
|
||||||
|
pub mod deploy_mastodon;
|
||||||
pub mod deploy_telegram;
|
pub mod deploy_telegram;
|
||||||
|
pub mod mastodon_api;
|
||||||
pub mod sticker_config;
|
pub mod sticker_config;
|
||||||
pub mod tg_api;
|
pub mod tg_api;
|
||||||
|
|
||||||
|
@ -22,10 +23,11 @@ async fn main() {
|
||||||
if args.debug {
|
if args.debug {
|
||||||
let subscriber = tracing_subscriber::fmt()
|
let subscriber = tracing_subscriber::fmt()
|
||||||
.with_max_level(tracing::Level::DEBUG)
|
.with_max_level(tracing::Level::DEBUG)
|
||||||
.compact()
|
.pretty()
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
tracing::subscriber::set_global_default(subscriber).expect("setting tracing default failed");
|
tracing::subscriber::set_global_default(subscriber)
|
||||||
|
.expect("setting tracing default failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
match args.command {
|
match args.command {
|
||||||
|
|
168
src/mastodon_api.rs
Normal file
168
src/mastodon_api.rs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
use reqwest::multipart::Part;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{collections::HashMap, error::Error};
|
||||||
|
|
||||||
|
// API docs taken from https://github.com/superseriousbusiness/gotosocial/blob/main/docs/api/swagger.yaml
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct MastodonErrorResp {
|
||||||
|
pub error: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MastodonErrorResp {
|
||||||
|
fn to_error(&self, error_code: u16) -> MastodonAPIError {
|
||||||
|
MastodonAPIError::new(self.error.clone(), error_code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct MastodonAPIError {
|
||||||
|
error: String,
|
||||||
|
error_code: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MastodonAPIError {
|
||||||
|
fn new(error: String, error_code: u16) -> MastodonAPIError {
|
||||||
|
MastodonAPIError { error, error_code }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for MastodonAPIError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "{}: {}", self.error_code, self.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for MastodonAPIError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
self.error.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct AdminEmoji {
|
||||||
|
pub id: String,
|
||||||
|
pub category: Option<String>,
|
||||||
|
pub shortcode: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Emoji {
|
||||||
|
pub category: Option<String>,
|
||||||
|
pub shortcode: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MastodonAPI {
|
||||||
|
token: String,
|
||||||
|
api_base: String,
|
||||||
|
client: reqwest::Client,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MastodonAPI {
|
||||||
|
pub fn new(token: String, api_base: String) -> Self {
|
||||||
|
Self {
|
||||||
|
token,
|
||||||
|
api_base,
|
||||||
|
client: reqwest::Client::builder()
|
||||||
|
.user_agent("stickerdeploy")
|
||||||
|
.build()
|
||||||
|
.unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_custom_emoji(
|
||||||
|
&self,
|
||||||
|
filter: &[String],
|
||||||
|
) -> Result<Vec<AdminEmoji>, Box<dyn Error>> {
|
||||||
|
let url = format!("{}/api/v1/admin/custom_emojis", self.api_base);
|
||||||
|
|
||||||
|
let mut query: HashMap<String, String> = HashMap::new();
|
||||||
|
query.insert("filter".to_string(), filter.join(","));
|
||||||
|
query.insert("limit".to_string(), "0".to_string());
|
||||||
|
|
||||||
|
let res = self
|
||||||
|
.client
|
||||||
|
.get(url)
|
||||||
|
.header(
|
||||||
|
"Authorization".to_string(),
|
||||||
|
format!("Bearer {}", self.token).to_string(),
|
||||||
|
)
|
||||||
|
.query(&query)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let status = res.status();
|
||||||
|
if status.is_success() {
|
||||||
|
let json = res.json::<Vec<AdminEmoji>>().await?;
|
||||||
|
|
||||||
|
Ok(json)
|
||||||
|
} else {
|
||||||
|
let json = res.json::<MastodonErrorResp>().await?;
|
||||||
|
|
||||||
|
Err(Box::new(json.to_error(status.as_u16())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_custom_emoji(&self, id: &String) -> Result<(), Box<dyn Error>> {
|
||||||
|
let url = format!("{}/api/v1/admin/custom_emojis/{}", self.api_base, id);
|
||||||
|
|
||||||
|
let res = self
|
||||||
|
.client
|
||||||
|
.delete(url)
|
||||||
|
.header(
|
||||||
|
"Authorization".to_string(),
|
||||||
|
format!("Bearer {}", self.token).to_string(),
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let status = res.status();
|
||||||
|
if !status.is_success() {
|
||||||
|
let json = res.json::<MastodonErrorResp>().await?;
|
||||||
|
|
||||||
|
Err(Box::new(json.to_error(status.as_u16())))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn upload_emoji(
|
||||||
|
&self,
|
||||||
|
shortcode: String,
|
||||||
|
category: Option<String>,
|
||||||
|
file_data: Vec<u8>,
|
||||||
|
) -> Result<Emoji, Box<dyn Error>> {
|
||||||
|
let url = format!("{}/api/v1/admin/custom_emojis", self.api_base);
|
||||||
|
|
||||||
|
let mut form = reqwest::multipart::Form::new();
|
||||||
|
form = form.text("shortcode", shortcode.clone());
|
||||||
|
if let Some(category) = category {
|
||||||
|
form = form.text("category", category);
|
||||||
|
} else {
|
||||||
|
form = form.text("category", "");
|
||||||
|
}
|
||||||
|
form = form.part("image", Part::bytes(file_data).file_name("test.png"));
|
||||||
|
|
||||||
|
let res = self
|
||||||
|
.client
|
||||||
|
.post(url)
|
||||||
|
.header(
|
||||||
|
"Authorization".to_string(),
|
||||||
|
format!("Bearer {}", self.token).to_string(),
|
||||||
|
)
|
||||||
|
.multipart(form)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let status = res.status();
|
||||||
|
if status.is_success() {
|
||||||
|
let json = res.json::<Emoji>().await?;
|
||||||
|
|
||||||
|
Ok(json)
|
||||||
|
} else {
|
||||||
|
let json = res.json::<MastodonErrorResp>().await?;
|
||||||
|
|
||||||
|
Err(Box::new(json.to_error(status.as_u16())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,26 +15,50 @@ pub struct DeployWhere {
|
||||||
pub deploy_to: String,
|
pub deploy_to: String,
|
||||||
pub discord: Option<Vec<DiscordDeployLocation>>,
|
pub discord: Option<Vec<DiscordDeployLocation>>,
|
||||||
pub telegram: Option<TelegramDeployLocation>,
|
pub telegram: Option<TelegramDeployLocation>,
|
||||||
|
pub mastodon: Option<MastodonDeployLocation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct TelegramDeployLocation {
|
pub struct TelegramDeployLocation {
|
||||||
pub deploy_name: String,
|
#[serde(default = "telegram_credential_name_default")]
|
||||||
|
pub credential_name: String,
|
||||||
pub r#type: StickerType,
|
pub r#type: StickerType,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub user_id: u64,
|
pub user_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn telegram_credential_name_default() -> String {
|
||||||
|
"telegram".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct MastodonDeployLocation {
|
||||||
|
pub api_base: String,
|
||||||
|
#[serde(default = "mastodon_credential_name_default")]
|
||||||
|
pub credential_name: String,
|
||||||
|
pub category: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mastodon_credential_name_default() -> String {
|
||||||
|
"mastodon".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct DiscordDeployLocation {
|
pub struct DiscordDeployLocation {
|
||||||
pub deploy_name: String,
|
pub deploy_name: String,
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
|
#[serde(default = "discord_credential_name_default")]
|
||||||
|
pub credential_name: String,
|
||||||
#[serde(default = "discord_max_regular_emoji_default")]
|
#[serde(default = "discord_max_regular_emoji_default")]
|
||||||
pub max_regular_emoji: u64,
|
pub max_regular_emoji: u64,
|
||||||
#[serde(default = "discord_max_animated_emoji_default")]
|
#[serde(default = "discord_max_animated_emoji_default")]
|
||||||
pub max_animated_emoji: u64,
|
pub max_animated_emoji: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn discord_credential_name_default() -> String {
|
||||||
|
"discord".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn discord_max_regular_emoji_default() -> u64 {
|
fn discord_max_regular_emoji_default() -> u64 {
|
||||||
50
|
50
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue