support adding and removing intros
ci/woodpecker/push/woodpecker Pipeline failed
Details
ci/woodpecker/push/woodpecker Pipeline failed
Details
parent
9f426407a9
commit
52d7cc7ded
84
src/db.rs
84
src/db.rs
|
@ -2,7 +2,7 @@ use std::path::Path;
|
|||
|
||||
use iter_tools::Itertools;
|
||||
use rusqlite::{Connection, Result};
|
||||
use tracing::error;
|
||||
use tracing::{error, warn};
|
||||
|
||||
use crate::auth;
|
||||
|
||||
|
@ -136,6 +136,34 @@ impl Database {
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) fn get_guild_channels(&self, guild_id: u64) -> Result<Vec<String>> {
|
||||
let mut query = self.conn.prepare(
|
||||
"
|
||||
SELECT
|
||||
Channel.name
|
||||
FROM Channel
|
||||
WHERE
|
||||
Channel.guild_id = :guild_id
|
||||
ORDER BY Channel.name DESC
|
||||
",
|
||||
)?;
|
||||
|
||||
// NOTE(pcleavelin): for some reason this needs to be a let-binding or else
|
||||
// the compiler complains about it being dropped too early (maybe I should update the compiler version)
|
||||
let intros = query
|
||||
.query_map(
|
||||
&[
|
||||
// :vomit:
|
||||
(":guild_id", &guild_id.to_string()),
|
||||
],
|
||||
|row| Ok(row.get(0)?),
|
||||
)?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<String>>>();
|
||||
|
||||
intros
|
||||
}
|
||||
|
||||
pub(crate) fn get_user_channel_intros(
|
||||
&self,
|
||||
username: &str,
|
||||
|
@ -151,6 +179,60 @@ impl Database {
|
|||
|
||||
Ok(intros)
|
||||
}
|
||||
|
||||
pub fn insert_user_intro(
|
||||
&self,
|
||||
username: &str,
|
||||
guild_id: u64,
|
||||
channel_name: &str,
|
||||
intro_id: i32,
|
||||
) -> Result<()> {
|
||||
let affected = self.conn.execute(
|
||||
"INSERT INTO UserIntro (username, guild_id, channel_name, intro_id) VALUES (?1, ?2, ?3, ?4)",
|
||||
&[
|
||||
username,
|
||||
&guild_id.to_string(),
|
||||
channel_name,
|
||||
&intro_id.to_string(),
|
||||
],
|
||||
)?;
|
||||
|
||||
if affected < 1 {
|
||||
warn!("no rows affected when attempting to insert user intro");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_user_intro(
|
||||
&self,
|
||||
username: &str,
|
||||
guild_id: u64,
|
||||
channel_name: &str,
|
||||
intro_id: i32,
|
||||
) -> Result<()> {
|
||||
let affected = self.conn.execute(
|
||||
"DELETE FROM
|
||||
UserIntro
|
||||
WHERE
|
||||
username = ?1
|
||||
AND guild_id = ?2
|
||||
AND channel_name = ?3
|
||||
AND intro_id = ?4",
|
||||
&[
|
||||
username,
|
||||
&guild_id.to_string(),
|
||||
channel_name,
|
||||
&intro_id.to_string(),
|
||||
],
|
||||
)?;
|
||||
|
||||
if affected < 1 {
|
||||
warn!("no rows affected when attempting to delete user intro");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Guild {
|
||||
|
|
23
src/page.rs
23
src/page.rs
|
@ -111,6 +111,11 @@ pub(crate) async fn guild_dashboard(
|
|||
// TODO: change to actual error
|
||||
Redirect::to("/login")
|
||||
})?;
|
||||
let guild_channels = db.get_guild_channels(guild_id).map_err(|err| {
|
||||
error!(?err, %guild_id, "couldn't get guild channels");
|
||||
// TODO: change to actual error
|
||||
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
|
||||
|
@ -175,17 +180,27 @@ pub(crate) async fn guild_dashboard(
|
|||
.builder(Tag::Article, |b| {
|
||||
let mut b = b.builder_text(Tag::Header, "Guild Intros");
|
||||
|
||||
for (channel_name, intros) in user_intros.into_iter() {
|
||||
let mut user_intros = user_intros.into_iter().peekable();
|
||||
|
||||
for guild_channel_name in guild_channels {
|
||||
// Get user intros for this channel
|
||||
let intros = user_intros
|
||||
.peeking_take_while(|(channel_name, _)| {
|
||||
channel_name == &&guild_channel_name
|
||||
})
|
||||
.map(|(_, intros)| intros.map(|intro| &intro.intro))
|
||||
.flatten();
|
||||
|
||||
b = b.builder(Tag::Article, |b| {
|
||||
b.builder_text(Tag::Header, &channel_name).builder(
|
||||
b.builder_text(Tag::Header, &guild_channel_name).builder(
|
||||
Tag::Div,
|
||||
|b| {
|
||||
b.attribute("id", "channel-intro-selector")
|
||||
.push_builder(channel_intro_selector(
|
||||
&state.origin,
|
||||
guild_id,
|
||||
channel_name,
|
||||
intros.map(|intro| &intro.intro),
|
||||
&guild_channel_name,
|
||||
intros,
|
||||
guild_intros.iter(),
|
||||
))
|
||||
},
|
||||
|
|
|
@ -342,21 +342,22 @@ pub(crate) async fn v2_add_intro_to_user(
|
|||
let db = state.db.lock().await;
|
||||
|
||||
while let Ok(Some(field)) = form_data.next_field().await {
|
||||
let Some(field_name) = field.name() else {
|
||||
let Some(intro_id) = field.name() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// TODO: insert into database
|
||||
//if !channel_user
|
||||
// .intros
|
||||
// .iter()
|
||||
// .any(|intro| intro.index == field_name)
|
||||
//{
|
||||
// channel_user.intros.push(IntroIndex {
|
||||
// index: field_name.to_string(),
|
||||
// volume: 20,
|
||||
// });
|
||||
//}
|
||||
let intro_id = intro_id.parse::<i32>().map_err(|err| {
|
||||
error!(?err, "invalid intro id");
|
||||
// TODO: change to actual error
|
||||
Redirect::to("/login")
|
||||
})?;
|
||||
|
||||
db.insert_user_intro(&user.name, guild_id, &channel, intro_id)
|
||||
.map_err(|err| {
|
||||
error!(?err, "failed to add user intro");
|
||||
// TODO: change to actual error
|
||||
Redirect::to("/login")
|
||||
})?;
|
||||
}
|
||||
|
||||
let guild_intros = db.get_guild_intros(guild_id).map_err(|err| {
|
||||
|
@ -394,11 +395,22 @@ pub(crate) async fn v2_remove_intro_from_user(
|
|||
let db = state.db.lock().await;
|
||||
|
||||
while let Ok(Some(field)) = form_data.next_field().await {
|
||||
let Some(field_name) = field.name() else {
|
||||
let Some(intro_id) = field.name() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// TODO: remove from database
|
||||
let intro_id = intro_id.parse::<i32>().map_err(|err| {
|
||||
error!(?err, "invalid intro id");
|
||||
// TODO: change to actual error
|
||||
Redirect::to("/login")
|
||||
})?;
|
||||
|
||||
db.remove_user_intro(&user.name, guild_id, &channel, intro_id)
|
||||
.map_err(|err| {
|
||||
error!(?err, "failed to remove user intro");
|
||||
// TODO: change to actual error
|
||||
Redirect::to("/login")
|
||||
})?;
|
||||
}
|
||||
|
||||
let guild_intros = db.get_guild_intros(guild_id).map_err(|err| {
|
||||
|
|
Loading…
Reference in New Issue