182 lines
5.7 KiB
Rust
182 lines
5.7 KiB
Rust
use crate::web::routes::dashboard::{create_reminder_template, ReminderTemplate};
|
|
use crate::web::{
|
|
check_authorization,
|
|
guards::transaction::Transaction,
|
|
routes::{
|
|
dashboard::{
|
|
create_reminder, CreateReminder, ImportBody, ReminderCsv, ReminderTemplateCsv, TodoCsv,
|
|
},
|
|
JsonResult,
|
|
},
|
|
};
|
|
use crate::Database;
|
|
use base64::{prelude::BASE64_STANDARD, Engine};
|
|
use csv::{QuoteStyle, WriterBuilder};
|
|
use log::warn;
|
|
use rocket::{
|
|
get,
|
|
http::CookieJar,
|
|
put,
|
|
serde::json::{json, Json},
|
|
State,
|
|
};
|
|
use serenity::{
|
|
client::Context,
|
|
model::id::{ChannelId, GuildId, UserId},
|
|
};
|
|
use sqlx::{MySql, Pool};
|
|
|
|
#[get("/api/guild/<id>/export/reminder_templates")]
|
|
pub async fn export(
|
|
id: u64,
|
|
cookies: &CookieJar<'_>,
|
|
ctx: &State<Context>,
|
|
pool: &State<Pool<MySql>>,
|
|
) -> JsonResult {
|
|
check_authorization(cookies, ctx.inner(), id).await?;
|
|
|
|
let mut csv_writer = WriterBuilder::new().quote_style(QuoteStyle::Always).from_writer(vec![]);
|
|
|
|
match sqlx::query_as_unchecked!(
|
|
ReminderTemplateCsv,
|
|
"SELECT
|
|
name,
|
|
attachment,
|
|
attachment_name,
|
|
avatar,
|
|
content,
|
|
embed_author,
|
|
embed_author_url,
|
|
embed_color,
|
|
embed_description,
|
|
embed_footer,
|
|
embed_footer_url,
|
|
embed_image_url,
|
|
embed_thumbnail_url,
|
|
embed_title,
|
|
embed_fields,
|
|
interval_seconds,
|
|
interval_days,
|
|
interval_months,
|
|
tts,
|
|
username
|
|
FROM reminder_template WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)",
|
|
id
|
|
)
|
|
.fetch_all(pool.inner())
|
|
.await
|
|
{
|
|
Ok(templates) => {
|
|
templates.iter().for_each(|template| {
|
|
csv_writer.serialize(template).unwrap();
|
|
});
|
|
|
|
match csv_writer.into_inner() {
|
|
Ok(inner) => match String::from_utf8(inner) {
|
|
Ok(encoded) => Ok(json!({ "body": encoded })),
|
|
|
|
Err(e) => {
|
|
warn!("Failed to write UTF-8: {:?}", e);
|
|
|
|
json_err!("Failed to write UTF-8")
|
|
}
|
|
},
|
|
|
|
Err(e) => {
|
|
warn!("Failed to extract CSV: {:?}", e);
|
|
|
|
json_err!("Failed to extract CSV")
|
|
}
|
|
}
|
|
}
|
|
Err(e) => {
|
|
warn!("Could not fetch templates from {}: {:?}", id, e);
|
|
|
|
json_err!("Failed to query templates")
|
|
}
|
|
}
|
|
}
|
|
|
|
#[put("/api/guild/<id>/export/reminder_templates", data = "<body>")]
|
|
pub async fn import(
|
|
id: u64,
|
|
cookies: &CookieJar<'_>,
|
|
body: Json<ImportBody>,
|
|
ctx: &State<Context>,
|
|
mut transaction: Transaction<'_>,
|
|
) -> JsonResult {
|
|
check_authorization(cookies, ctx.inner(), id).await?;
|
|
|
|
match BASE64_STANDARD.decode(&body.body) {
|
|
Ok(body) => {
|
|
let mut reader = csv::Reader::from_reader(body.as_slice());
|
|
let mut count = 0;
|
|
|
|
for result in reader.deserialize::<ReminderTemplateCsv>() {
|
|
match result {
|
|
Ok(record) => {
|
|
let reminder_template = ReminderTemplate {
|
|
id: 0,
|
|
guild_id: 0,
|
|
name: record.name,
|
|
attachment: record.attachment,
|
|
attachment_name: record.attachment_name,
|
|
avatar: record.avatar,
|
|
content: record.content,
|
|
embed_author: record.embed_author,
|
|
embed_author_url: record.embed_author_url,
|
|
embed_color: record.embed_color,
|
|
embed_description: record.embed_description,
|
|
embed_footer: record.embed_footer,
|
|
embed_footer_url: record.embed_footer_url,
|
|
embed_image_url: record.embed_image_url,
|
|
embed_thumbnail_url: record.embed_thumbnail_url,
|
|
embed_title: record.embed_title,
|
|
embed_fields: record
|
|
.embed_fields
|
|
.map(|s| serde_json::from_str(&s).ok())
|
|
.flatten(),
|
|
interval_seconds: record.interval_seconds,
|
|
interval_days: record.interval_days,
|
|
interval_months: record.interval_months,
|
|
tts: record.tts,
|
|
username: record.username,
|
|
};
|
|
|
|
create_reminder_template(
|
|
ctx.inner(),
|
|
&mut transaction,
|
|
GuildId::new(id),
|
|
reminder_template,
|
|
)
|
|
.await?;
|
|
|
|
count += 1;
|
|
}
|
|
|
|
Err(e) => {
|
|
warn!("Couldn't deserialize CSV row: {:?}", e);
|
|
|
|
return json_err!(format!("Deserialize error: {:?}", e));
|
|
}
|
|
}
|
|
}
|
|
|
|
match transaction.commit().await {
|
|
Ok(_) => Ok(json!({
|
|
"message": format!("Imported {} reminder templates", count)
|
|
})),
|
|
|
|
Err(e) => {
|
|
warn!("Failed to commit transaction: {:?}", e);
|
|
json_err!("Couldn't commit transaction")
|
|
}
|
|
}
|
|
}
|
|
|
|
Err(_) => {
|
|
json_err!("Malformed base64")
|
|
}
|
|
}
|
|
}
|