diff --git a/Cargo.toml b/Cargo.toml index 4317c94..fde71d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,10 @@ readme = "README.md" license = "GPL-3.0-or-later" [dependencies] +actix-web = "4.4.0" +actix-rt = "2.9.0" +actix-web-httpauth = "0.8.1" +chrono = { version = "0.4.31", features = ["serde"] } dotenv = "0.15.0" serde_json = "1.0.107" log = "0.4.20" diff --git a/migrations/000001_create_races/down.sql b/migrations/000001_create_races/down.sql new file mode 100644 index 0000000..f075840 --- /dev/null +++ b/migrations/000001_create_races/down.sql @@ -0,0 +1 @@ +DROP TABLE races; \ No newline at end of file diff --git a/migrations/000001_create_races/up.sql b/migrations/000001_create_races/up.sql new file mode 100644 index 0000000..5ec4de7 --- /dev/null +++ b/migrations/000001_create_races/up.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS races ( + id INTEGER GENERATED ALWAYS AS IDENTITY, + name TEXT NOT NULL, + size TEXT NOT NULL, + source TEXT NOT NULL, + data JSON NOT NULL +); \ No newline at end of file diff --git a/migrations/000002_create_classes/down.sql b/migrations/000002_create_classes/down.sql new file mode 100644 index 0000000..288ada8 --- /dev/null +++ b/migrations/000002_create_classes/down.sql @@ -0,0 +1 @@ +DROP TABLE classes; \ No newline at end of file diff --git a/migrations/000002_create_classes/up.sql b/migrations/000002_create_classes/up.sql new file mode 100644 index 0000000..36f79bf --- /dev/null +++ b/migrations/000002_create_classes/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS classes ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/migrations/000003_create_feats/down.sql b/migrations/000003_create_feats/down.sql new file mode 100644 index 0000000..4afe0e1 --- /dev/null +++ b/migrations/000003_create_feats/down.sql @@ -0,0 +1 @@ +DROP TABLE feats; \ No newline at end of file diff --git a/migrations/000003_create_feats/up.sql b/migrations/000003_create_feats/up.sql new file mode 100644 index 0000000..0193ae4 --- /dev/null +++ b/migrations/000003_create_feats/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS feats ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/migrations/000004_create_options_features/down.sql b/migrations/000004_create_options_features/down.sql new file mode 100644 index 0000000..0fcca0f --- /dev/null +++ b/migrations/000004_create_options_features/down.sql @@ -0,0 +1 @@ +DROP TABLE options_features; \ No newline at end of file diff --git a/migrations/000004_create_options_features/up.sql b/migrations/000004_create_options_features/up.sql new file mode 100644 index 0000000..d64ba24 --- /dev/null +++ b/migrations/000004_create_options_features/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS options_features ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/migrations/000005_create_backgrounds/down.sql b/migrations/000005_create_backgrounds/down.sql new file mode 100644 index 0000000..74f4344 --- /dev/null +++ b/migrations/000005_create_backgrounds/down.sql @@ -0,0 +1 @@ +DROP TABLE backgrounds; \ No newline at end of file diff --git a/migrations/000005_create_backgrounds/up.sql b/migrations/000005_create_backgrounds/up.sql new file mode 100644 index 0000000..0d4bb7f --- /dev/null +++ b/migrations/000005_create_backgrounds/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS backgrounds ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/migrations/000006_create_items/down.sql b/migrations/000006_create_items/down.sql new file mode 100644 index 0000000..9f8e6a3 --- /dev/null +++ b/migrations/000006_create_items/down.sql @@ -0,0 +1 @@ +DROP TABLE items; \ No newline at end of file diff --git a/migrations/000006_create_items/up.sql b/migrations/000006_create_items/up.sql new file mode 100644 index 0000000..f12f9b2 --- /dev/null +++ b/migrations/000006_create_items/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS items ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/migrations/000007_create_spells/down.sql b/migrations/000007_create_spells/down.sql new file mode 100644 index 0000000..1b09bdf --- /dev/null +++ b/migrations/000007_create_spells/down.sql @@ -0,0 +1 @@ +DROP TABLE spells; \ No newline at end of file diff --git a/migrations/000007_create_spells/up.sql b/migrations/000007_create_spells/up.sql new file mode 100644 index 0000000..8312c69 --- /dev/null +++ b/migrations/000007_create_spells/up.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS spells ( + id INTEGER GENERATED ALWAYS AS IDENTITY, + name TEXT NOT NULL, + school TEXT NOT NULL, + level TEXT NOT NULL, + ritual BOOLEAN DEFAULT FALSE, + casting_time TEXT NOT NULL, + range TEXT NOT NULL, + components_verbal BOOLEAN DEFAULT FALSE, + components_somatic BOOLEAN DEFAULT FALSE, + components_material BOOLEAN DEFAULT FALSE, + components_materials_needed TEXT + duration TEXT NOT NULL, + classes TEXT[] NOT NULL, + sources TEXT[] NOT NULL, + tags TEXT[] + description TEXT NOT NULL +); \ No newline at end of file diff --git a/migrations/000008_create_conditions/down.sql b/migrations/000008_create_conditions/down.sql new file mode 100644 index 0000000..4cf8449 --- /dev/null +++ b/migrations/000008_create_conditions/down.sql @@ -0,0 +1 @@ +DROP TABLE conditions; \ No newline at end of file diff --git a/migrations/000008_create_conditions/up.sql b/migrations/000008_create_conditions/up.sql new file mode 100644 index 0000000..76b5220 --- /dev/null +++ b/migrations/000008_create_conditions/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS conditions ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/migrations/000009_create_bestiary/down.sql b/migrations/000009_create_bestiary/down.sql new file mode 100644 index 0000000..9bbe034 --- /dev/null +++ b/migrations/000009_create_bestiary/down.sql @@ -0,0 +1 @@ +DROP TABLE bestiary; \ No newline at end of file diff --git a/migrations/000009_create_bestiary/up.sql b/migrations/000009_create_bestiary/up.sql new file mode 100644 index 0000000..a6019df --- /dev/null +++ b/migrations/000009_create_bestiary/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS bestiary ( + id INTEGER GENERATED ALWAYS AS IDENTITY +); \ No newline at end of file diff --git a/src/commands/oai.rs b/src/commands/oai.rs index 7bb702e..13a2e01 100644 --- a/src/commands/oai.rs +++ b/src/commands/oai.rs @@ -12,8 +12,7 @@ use serenity::model::channel::Message; use serenity::model::prelude::{ChannelType, PermissionOverwrite, PermissionOverwriteType}; use serenity::prelude::*; -use crate::db; -use crate::messages::{NewMessageDB, MessageDB}; +use crate::db::{connection, NewMessageDB, MessageDB}; pub struct OAI { pub client: reqwest::Client, @@ -189,7 +188,7 @@ impl OAI { pub async fn generate_response(ctx: &Context, msg: &Message, oai: &OAI) { debug!("Generating response for message: {}", msg.content); - let mut connection = db::connection().unwrap(); + let mut connection = connection().unwrap(); let guild_id = msg.guild_id.unwrap(); let channel_id = msg.channel_id; @@ -200,13 +199,13 @@ pub async fn generate_response(ctx: &Context, msg: &Message, oai: &OAI) { let parsed_content = msg.content.replace(bot_mention.as_str(), ""); // Setup the request messages - let result: Result, diesel::result::Error> = crate::schema::messages::table + let result: Result, diesel::result::Error> = crate::db::schema::messages::table .select(MessageDB::as_select()) - .filter((crate::schema::messages::guild_id.eq(guild_id.0 as i64)) - .and(crate::schema::messages::channel_id.eq(channel_id.0 as i64)) - .and(crate::schema::messages::user_id.eq(author_id.0 as i64)) + .filter((crate::db::schema::messages::guild_id.eq(guild_id.0 as i64)) + .and(crate::db::schema::messages::channel_id.eq(channel_id.0 as i64)) + .and(crate::db::schema::messages::user_id.eq(author_id.0 as i64)) ) - .order(crate::schema::messages::created.asc()) + .order(crate::db::schema::messages::created.asc()) .limit(oai.max_context_questions) .load(&mut connection); @@ -284,7 +283,7 @@ pub async fn generate_response(ctx: &Context, msg: &Message, oai: &OAI) { if !r.choices.is_empty() { let res = r.choices[0].message.content.clone(); // Insert the message into the messages database table - if let Err(err) = insert_into(crate::schema::messages::table).values(NewMessageDB { + if let Err(err) = insert_into(crate::db::schema::messages::table).values(NewMessageDB { id: &r.id, guild_id: guild_id.0 as i64, channel_id: response_channel.0 as i64, diff --git a/src/db/backgrounds/mod.rs b/src/db/backgrounds/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/bestiary/mod.rs b/src/db/bestiary/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/classes/mod.rs b/src/db/classes/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/conditions/mod.rs b/src/db/conditions/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/feats/mod.rs b/src/db/feats/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/items/mod.rs b/src/db/items/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/messages/mod.rs b/src/db/messages/mod.rs similarity index 100% rename from src/messages/mod.rs rename to src/db/messages/mod.rs diff --git a/src/messages/model.rs b/src/db/messages/model.rs similarity index 95% rename from src/messages/model.rs rename to src/db/messages/model.rs index f1120ef..3714ed5 100644 --- a/src/messages/model.rs +++ b/src/db/messages/model.rs @@ -1,6 +1,6 @@ use diesel::prelude::*; -use crate::schema::messages; +use crate::db::schema::messages; #[derive(Queryable, Selectable)] #[diesel(table_name = messages)] diff --git a/src/db.rs b/src/db/mod.rs similarity index 89% rename from src/db.rs rename to src/db/mod.rs index bb22870..991ff2b 100644 --- a/src/db.rs +++ b/src/db/mod.rs @@ -6,6 +6,21 @@ use log::{error, info}; use r2d2; use std::env; +mod backgrounds; +mod bestiary; +mod classes; +mod conditions; +mod feats; +mod items; +mod messages; +mod options; +mod races; +mod spells; +mod users; +pub mod schema; + +pub use messages::*; + type Pool = r2d2::Pool>; pub type DbConnection = r2d2::PooledConnection>; diff --git a/src/db/options/mod.rs b/src/db/options/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/races/mod.rs b/src/db/races/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/db/schema.rs b/src/db/schema.rs new file mode 100644 index 0000000..17e2dc8 --- /dev/null +++ b/src/db/schema.rs @@ -0,0 +1,35 @@ +diesel::table! { + messages (id) { + id -> Text, + guild_id -> BigInt, + channel_id -> BigInt, + user_id -> BigInt, + created -> BigInt, + model -> Text, + request -> Text, + response -> Text, + request_tags -> Array, + response_tags -> Array, + } +} + +diesel::table! { + spells (id) { + id -> Integer, + name -> Text, + school -> Text, + level -> Integer, + ritual -> Bool, + casting_time -> Text, + range -> Text, + components_verbal -> Bool, + components_somatic -> Bool, + components_material -> Bool, + components_materials_needed -> Nullable, + duration -> Text, + classes -> Array, + sources -> Array, + tags -> Array, + description -> Text + } +} \ No newline at end of file diff --git a/src/db/spells/mod.rs b/src/db/spells/mod.rs new file mode 100644 index 0000000..4a7ebf6 --- /dev/null +++ b/src/db/spells/mod.rs @@ -0,0 +1,3 @@ +mod model; + +pub use model::*; diff --git a/src/db/spells/model.rs b/src/db/spells/model.rs new file mode 100644 index 0000000..b5081be --- /dev/null +++ b/src/db/spells/model.rs @@ -0,0 +1,120 @@ +use diesel::prelude::*; +use serde::{Deserialize, Serialize}; + +use crate::db::schema::spells; + +#[derive(Queryable, QueryableByName)] +#[diesel(table_name = spells)] +pub struct QuerySpell { + pub id: i32, + pub name: String, + pub school: String, + pub level: i32, + pub ritual: bool, + pub casting_time: String, + pub range: String, + pub components_verbal: bool, + pub components_somatic: bool, + pub components_material: bool, + pub components_materials_needed: Option, + pub duration: String, + pub classes: Vec, + pub sources: Vec, + pub tags: Vec, + pub description: String +} + +#[derive(Insertable, AsChangeset)] +#[diesel(table_name = spells)] +pub struct InsertSpell { + pub name: String, + pub school: String, + pub level: i32, + pub ritual: bool, + pub casting_time: String, + pub range: String, + pub components_verbal: bool, + pub components_somatic: bool, + pub components_material: bool, + pub components_materials_needed: Option, + pub duration: String, + pub classes: Vec, + pub sources: Vec, + pub tags: Vec, + pub description: String +} + +#[derive(Serialize, Deserialize)] +pub struct Spell { + pub name: String, + pub school: String, + pub level: i32, + pub ritual: bool, + pub casting_time: String, + pub range: String, + pub components: Components, + pub duration: String, + pub classes: Vec, + pub sources: Vec, + pub description: String +} + +#[derive(Serialize, Deserialize)] +pub struct Components { + pub verbal: bool, + pub somatic: bool, + pub material: bool, + pub materials_needed: Option +} + +impl Spell { + /// Convert spell to insertable struct + pub fn to_insert(self) -> InsertSpell { + return InsertSpell { + name: self.name, + school: self.school, + level: self.level, + ritual: self.ritual, + casting_time: self.casting_time, + range: self.range, + components_verbal: self.components.verbal, + components_somatic: self.components.somatic, + components_material: self.components.material, + components_materials_needed: self.components.materials_needed, + duration: self.duration, + classes: self.classes, + sources: self.sources, + tags: vec![], + description: self.description + } + } + + /// Convert query struct to spell + pub fn from_query(query: QuerySpell) -> Self { + return Self { + name: query.name, + school: query.school, + level: query.level, + ritual: query.ritual, + casting_time: query.casting_time, + range: query.range, + components: Components { + verbal: query.components_verbal, + somatic: query.components_somatic, + material: query.components_material, + materials_needed: query.components_materials_needed + }, + duration: query.duration, + classes: query.classes, + sources: query.sources, + description: query.description + } + } + + /// Convert file to spell + pub fn from_file(file: String) -> Self { + let data = std::fs::read_to_string(file).unwrap(); + let spell: Spell = serde_json::from_str(&data).unwrap(); + return spell; + } +} diff --git a/src/db/users/mod.rs b/src/db/users/mod.rs new file mode 100644 index 0000000..4a7ebf6 --- /dev/null +++ b/src/db/users/mod.rs @@ -0,0 +1,3 @@ +mod model; + +pub use model::*; diff --git a/src/db/users/model.rs b/src/db/users/model.rs new file mode 100644 index 0000000..5b2f343 --- /dev/null +++ b/src/db/users/model.rs @@ -0,0 +1,3 @@ +pub struct User { + pub id: i32 +} diff --git a/src/main.rs b/src/main.rs index 2e1a248..03a755c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,8 +22,6 @@ use songbird::SerenityInit; mod commands; mod error_handler; mod db; -mod messages; -mod schema; struct Handler { // Open AI Config oai: Option diff --git a/src/schema.rs b/src/schema.rs deleted file mode 100644 index 825d574..0000000 --- a/src/schema.rs +++ /dev/null @@ -1,14 +0,0 @@ -diesel::table! { - messages (id) { - id -> Text, - guild_id -> BigInt, - channel_id -> BigInt, - user_id -> BigInt, - created -> BigInt, - model -> Text, - request -> Text, - response -> Text, - request_tags -> Array, - response_tags -> Array, - } -} \ No newline at end of file