make db call simpler

pull/11/head
Patrick Cleavelin 2023-08-06 16:28:44 -05:00
parent 5da57545e2
commit 9f426407a9
3 changed files with 72 additions and 80 deletions

View File

@ -1,6 +1,8 @@
use std::path::Path; use std::path::Path;
use iter_tools::Itertools;
use rusqlite::{Connection, Result}; use rusqlite::{Connection, Result};
use tracing::error;
use crate::auth; use crate::auth;
@ -133,6 +135,22 @@ impl Database {
|row| Ok(auth::Permissions(row.get(0)?)), |row| Ok(auth::Permissions(row.get(0)?)),
) )
} }
pub(crate) fn get_user_channel_intros(
&self,
username: &str,
guild_id: u64,
channel_name: &str,
) -> Result<Vec<Intro>> {
let all_user_intros = self.get_all_user_intros(guild_id)?.into_iter();
let intros = all_user_intros
.filter(|intro| &intro.username == &username && &intro.channel_name == channel_name)
.map(|intro| intro.intro)
.collect();
Ok(intros)
}
} }
pub struct Guild { pub struct Guild {

View File

@ -120,10 +120,10 @@ pub(crate) async fn guild_dashboard(
.get_user_permissions(&user.name, guild_id) .get_user_permissions(&user.name, guild_id)
.unwrap_or_default(); .unwrap_or_default();
let grouped_intros = all_user_intros.iter().group_by(|intro| &intro.username); let user_intros = all_user_intros
let user_intros = grouped_intros .iter()
.into_iter() .filter(|intro| &intro.username == &user.name)
.filter(|(username, _)| username == &&user.name); .group_by(|intro| &intro.channel_name);
let can_upload = user_permissions.can(auth::Permission::UploadSounds); let can_upload = user_permissions.can(auth::Permission::UploadSounds);
let is_moderator = user_permissions.can(auth::Permission::DeleteSounds); let is_moderator = user_permissions.can(auth::Permission::DeleteSounds);
@ -175,26 +175,22 @@ pub(crate) async fn guild_dashboard(
.builder(Tag::Article, |b| { .builder(Tag::Article, |b| {
let mut b = b.builder_text(Tag::Header, "Guild Intros"); let mut b = b.builder_text(Tag::Header, "Guild Intros");
for (_, intros) in user_intros { for (channel_name, intros) in user_intros.into_iter() {
for (channel_name, intros) in b = b.builder(Tag::Article, |b| {
intros.group_by(|intro| &intro.channel_name).into_iter() b.builder_text(Tag::Header, &channel_name).builder(
{ Tag::Div,
b = b.builder(Tag::Article, |b| { |b| {
b.builder_text(Tag::Header, &channel_name).builder( b.attribute("id", "channel-intro-selector")
Tag::Div, .push_builder(channel_intro_selector(
|b| { &state.origin,
b.attribute("id", "channel-intro-selector") guild_id,
.push_builder(channel_intro_selector( channel_name,
&state.origin, intros.map(|intro| &intro.intro),
guild_id, guild_intros.iter(),
channel_name, ))
intros.map(|intro| &intro.intro), },
guild_intros.iter(), )
)) });
},
)
});
}
} }
b b

View File

@ -364,42 +364,21 @@ pub(crate) async fn v2_add_intro_to_user(
// TODO: change to actual error // TODO: change to actual error
Redirect::to("/login") Redirect::to("/login")
})?; })?;
let all_user_intros = db.get_all_user_intros(guild_id).map_err(|err| {
error!(?err, %guild_id, "couldn't get user intros");
// TODO: change to actual error
Redirect::to("/login")
})?;
let grouped_intros = all_user_intros.iter().group_by(|intro| &intro.username); let intros = db
let user_intros = grouped_intros .get_user_channel_intros(&user.name, guild_id, &channel)
.into_iter() .map_err(|err| {
.filter_map(|(username, intro)| { error!(?err, user = %user.name, %guild_id, "couldn't get user intros");
if username == &user.name { // TODO: change to actual error
Some(intro) Redirect::to("/login")
} else { })?;
None
}
})
.flatten();
let grouped_user_intros = user_intros.group_by(|intro| &intro.channel_name);
let intros = grouped_user_intros
.into_iter()
.filter_map(|(channel_name, intros)| {
if channel_name == &channel {
Some(intros.map(|intro| &intro.intro))
} else {
None
}
})
.flatten();
Ok(Html( Ok(Html(
page::channel_intro_selector( page::channel_intro_selector(
&state.origin, &state.origin,
guild_id, guild_id,
&channel, &channel,
intros, intros.iter(),
guild_intros.iter(), guild_intros.iter(),
) )
.build(), .build(),
@ -411,42 +390,41 @@ pub(crate) async fn v2_remove_intro_from_user(
Path((guild_id, channel)): Path<(u64, String)>, Path((guild_id, channel)): Path<(u64, String)>,
user: User, user: User,
mut form_data: Multipart, mut form_data: Multipart,
) -> HeaderMap { ) -> Result<Html<String>, Redirect> {
let mut headers = HeaderMap::new(); let db = state.db.lock().await;
headers.insert("HX-Refresh", HeaderValue::from_static("true"));
let mut settings = state.settings.lock().await;
let Some(guild) = settings.guilds.get_mut(&guild_id) else {
return headers;
};
let Some(channel) = guild.channels.get_mut(&channel) else {
return headers;
};
let Some(channel_user) = channel.users.get_mut(&user.name) else {
return headers;
};
while let Ok(Some(field)) = form_data.next_field().await { while let Ok(Some(field)) = form_data.next_field().await {
let Some(field_name) = field.name() else { let Some(field_name) = field.name() else {
continue; continue;
}; };
if let Some(index) = channel_user // TODO: remove from database
.intros
.iter()
.position(|intro| intro.index == field_name)
{
channel_user.intros.remove(index);
}
} }
// TODO: don't save on every change let guild_intros = db.get_guild_intros(guild_id).map_err(|err| {
if let Err(err) = settings.save() { error!(?err, %guild_id, "couldn't get guild intros");
error!("Failed to save config: {err:?}"); // TODO: change to actual error
} Redirect::to("/login")
})?;
headers let intros = db
.get_user_channel_intros(&user.name, guild_id, &channel)
.map_err(|err| {
error!(?err, user = %user.name, %guild_id, "couldn't get user intros");
// TODO: change to actual error
Redirect::to("/login")
})?;
Ok(Html(
page::channel_intro_selector(
&state.origin,
guild_id,
&channel,
intros.iter(),
guild_intros.iter(),
)
.build(),
))
} }
pub(crate) async fn add_intro_to_user( pub(crate) async fn add_intro_to_user(