create roles

This commit is contained in:
nora 2022-06-14 22:32:56 +02:00
parent 9c6f958f68
commit afd5e49eda
5 changed files with 121 additions and 11 deletions

1
Cargo.lock generated
View file

@ -204,6 +204,7 @@ dependencies = [
"mongodb", "mongodb",
"nougat", "nougat",
"serde", "serde",
"serde_json",
"serenity", "serenity",
"tokio", "tokio",
"tracing", "tracing",

View file

@ -14,6 +14,7 @@ tracing = "0.1.35"
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
serde = { version = "1.0.137", features = ["derive"] } serde = { version = "1.0.137", features = ["derive"] }
nougat = "0.1.0" nougat = "0.1.0"
serde_json = "1.0.81"
[dependencies.serenity] [dependencies.serenity]
version = "0.11.2" version = "0.11.2"

View file

@ -83,7 +83,7 @@ pub struct Handler {
pub mongo: Mongo, pub mongo: Mongo,
} }
enum Response { pub enum Response {
Simple(String), Simple(String),
} }
@ -176,7 +176,7 @@ async fn lawsuit_command_handler(
let subcommand = options.get(0).wrap_err("needs subcommand")?; let subcommand = options.get(0).wrap_err("needs subcommand")?;
let options = &subcommand.options; let options = &subcommand.options;
let guild_id = command.guild_id.wrap_err("guild_id not found")?.to_string(); let guild_id = command.guild_id.wrap_err("guild_id not found")?;
match subcommand.name.as_str() { match subcommand.name.as_str() {
"create" => { "create" => {
@ -198,14 +198,14 @@ async fn lawsuit_command_handler(
court_room: None, court_room: None,
}; };
lawsuit let response = lawsuit
.initialize(&guild_id, mongo_client) .initialize(&ctx.http, guild_id, mongo_client)
.await .await
.wrap_err("initialize lawsuit")?; .wrap_err("initialize lawsuit")?;
info!(?lawsuit, "Created lawsuit"); info!(?lawsuit, "Created lawsuit");
Ok(Response::Simple("hani erstellt, keis problem".to_owned())) Ok(response)
} }
"set_category" => { "set_category" => {
let channel = ChannelOption::get(options.get(0))?; let channel = ChannelOption::get(options.get(0))?;
@ -219,7 +219,7 @@ async fn lawsuit_command_handler(
Some(category) => { Some(category) => {
let id = category.id; let id = category.id;
mongo_client mongo_client
.set_court_category(&guild_id, &id.to_string()) .set_court_category(&guild_id.to_string(), &id.to_string())
.await?; .await?;
} }
None => return Ok(Response::Simple("Das ist keine Kategorie!".to_owned())), None => return Ok(Response::Simple("Das ist keine Kategorie!".to_owned())),

View file

@ -1,8 +1,19 @@
use std::str::FromStr;
use color_eyre::Result; use color_eyre::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serenity::model::id::{ChannelId, UserId}; use serenity::{
http::Http,
model::{
channel::PermissionOverwriteType,
id::{ChannelId, UserId},
prelude::{GuildId, PermissionOverwrite},
Permissions,
},
};
use tracing::info;
use crate::Mongo; use crate::{handler::Response, model::CourtRoom, Mongo, WrapErr};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum LawsuitState { pub enum LawsuitState {
@ -23,9 +34,92 @@ pub struct Lawsuit {
} }
impl Lawsuit { impl Lawsuit {
pub async fn initialize(&mut self, guild_id: &str, mongo_client: &Mongo) -> Result<()> { pub async fn initialize(
let _state = mongo_client.find_or_insert_state(&guild_id).await?; &mut self,
http: &Http,
guild_id: GuildId,
mongo_client: &Mongo,
) -> Result<Response> {
let state = mongo_client
.find_or_insert_state(&guild_id.to_string())
.await?;
Ok(()) let free_room = state.court_rooms.iter().find(|r| !r.ongoing_lawsuit);
match (free_room, &state.court_category) {
(Some(_room), _) => Ok(Response::Simple("a free room? rip".to_owned())),
(None, Some(category)) => {
// create room
create_room(
http,
guild_id,
state.court_rooms.len(),
ChannelId::from_str(category).wrap_err("invalid channel_id stored")?,
mongo_client,
)
.await
.wrap_err("create new room")?;
Ok(Response::Simple("no free room? rip".to_owned()))
}
(None, None) => Ok(Response::Simple(
"Zuerst eine Kategorie für die Gerichtsräume festlegen mit `/lawsuit set_category`"
.to_owned(),
)),
}
} }
} }
async fn create_room(
http: &Http,
guild_id: GuildId,
room_len: usize,
category_id: ChannelId,
mongo_client: &Mongo,
) -> Result<()> {
let room_number = room_len + 1;
let room_name = format!("gerichtsraum-{room_number}");
let role_name = format!("Gerichtsprozess {room_number}");
let guild = guild_id
.to_partial_guild(http)
.await
.wrap_err("fetch partial guild")?;
let court_role = guild
.create_role(http, |role| {
role.name(role_name).permissions(Permissions::empty())
})
.await
.wrap_err("create role")?;
let channel = guild
.create_channel(http, |channel| {
channel
.name(room_name)
.category(category_id)
.permissions(vec![PermissionOverwrite {
allow: Permissions::SEND_MESSAGES,
deny: Permissions::empty(),
kind: PermissionOverwriteType::Role(court_role.id),
}])
})
.await
.wrap_err("create channel")?;
let room = CourtRoom {
channel_id: channel.id.to_string(),
ongoing_lawsuit: false,
role_id: court_role.id.to_string(),
};
mongo_client
.add_court_room(&guild_id.to_string(), room)
.await
.wrap_err("add court room to database")?;
info!(guild_id = %guild_id, channel_id = %channel.id, "Created new court room");
Ok(())
}

View file

@ -21,6 +21,7 @@ pub struct State {
pub struct CourtRoom { pub struct CourtRoom {
pub channel_id: String, pub channel_id: String,
pub ongoing_lawsuit: bool, pub ongoing_lawsuit: bool,
pub role_id: String,
} }
pub struct Mongo { pub struct Mongo {
@ -97,6 +98,19 @@ impl Mongo {
Ok(()) Ok(())
} }
pub async fn add_court_room(&self, guild_id: &str, room: CourtRoom) -> Result<()> {
let _ = self.find_or_insert_state(guild_id).await?;
let coll = self.state_coll();
coll.update_one(
doc! {"guild_id": &guild_id },
doc! {"$push": { "court_rooms": &serde_json::to_string(&room).unwrap() }},
None,
)
.await
.wrap_err("push court room")?;
Ok(())
}
fn state_coll(&self) -> Collection<State> { fn state_coll(&self) -> Collection<State> {
self.db.collection("state") self.db.collection("state")
} }