Spells endpoints
This commit is contained in:
@@ -1,8 +1,13 @@
|
|||||||
RUST_LOG=warn,siren=info
|
RUST_LOG=warn,siren=info
|
||||||
|
|
||||||
DATABASE_USER=siren
|
DATABASE_USER=siren
|
||||||
DATABASE_PASSWORD=
|
DATABASE_PASSWORD=
|
||||||
DATABASE_NAME=siren
|
DATABASE_NAME=siren
|
||||||
DATABASE_HOST=localhost
|
DATABASE_HOST=localhost
|
||||||
DATABASE_PORT=5432
|
DATABASE_PORT=5432
|
||||||
|
|
||||||
|
SERVICE_HOST=localhost
|
||||||
|
SERVICE_PORT=5000
|
||||||
|
|
||||||
DISCORD_TOKEN=
|
DISCORD_TOKEN=
|
||||||
OPENAI_API_KEY=
|
OPENAI_API_KEY=
|
||||||
@@ -14,6 +14,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
DATABASE_HOST: db
|
DATABASE_HOST: db
|
||||||
DATABASE_PORT: 5432
|
DATABASE_PORT: 5432
|
||||||
|
SERVICE_HOST: siren
|
||||||
|
SERVICE_PORT: 5000
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ CREATE TABLE IF NOT EXISTS spells (
|
|||||||
id INTEGER GENERATED ALWAYS AS IDENTITY,
|
id INTEGER GENERATED ALWAYS AS IDENTITY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
school TEXT NOT NULL,
|
school TEXT NOT NULL,
|
||||||
level TEXT NOT NULL,
|
level INTEGER NOT NULL,
|
||||||
ritual BOOLEAN DEFAULT FALSE,
|
ritual BOOLEAN DEFAULT FALSE,
|
||||||
casting_time TEXT NOT NULL,
|
casting_time TEXT NOT NULL,
|
||||||
range TEXT NOT NULL,
|
range TEXT NOT NULL,
|
||||||
components_verbal BOOLEAN DEFAULT FALSE,
|
components_verbal BOOLEAN DEFAULT FALSE,
|
||||||
components_somatic BOOLEAN DEFAULT FALSE,
|
components_somatic BOOLEAN DEFAULT FALSE,
|
||||||
components_material BOOLEAN DEFAULT FALSE,
|
components_material BOOLEAN DEFAULT FALSE,
|
||||||
components_materials_needed TEXT
|
components_materials_needed TEXT,
|
||||||
duration TEXT NOT NULL,
|
duration TEXT NOT NULL,
|
||||||
classes TEXT[] NOT NULL,
|
classes TEXT[] NOT NULL,
|
||||||
sources TEXT[] NOT NULL,
|
sources TEXT[] NOT NULL,
|
||||||
tags TEXT[]
|
tags TEXT[],
|
||||||
description TEXT NOT NULL
|
description TEXT NOT NULL
|
||||||
);
|
);
|
||||||
@@ -12,7 +12,7 @@ use serenity::model::channel::Message;
|
|||||||
use serenity::model::prelude::{ChannelType, PermissionOverwrite, PermissionOverwriteType};
|
use serenity::model::prelude::{ChannelType, PermissionOverwrite, PermissionOverwriteType};
|
||||||
use serenity::prelude::*;
|
use serenity::prelude::*;
|
||||||
|
|
||||||
use crate::db::{connection, NewMessageDB, MessageDB};
|
use crate::db::{connection, messages::{MessageDB, NewMessageDB}};
|
||||||
|
|
||||||
pub struct OAI {
|
pub struct OAI {
|
||||||
pub client: reqwest::Client,
|
pub client: reqwest::Client,
|
||||||
|
|||||||
@@ -1,26 +1,25 @@
|
|||||||
use crate::error_handler::ServiceError;
|
use crate::error_handler::ServiceError;
|
||||||
use diesel::{r2d2::ConnectionManager, PgConnection};
|
use diesel::{r2d2::ConnectionManager, PgConnection};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::diesel_migrations::MigrationHarness;
|
use crate::diesel_migrations::MigrationHarness;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use r2d2;
|
use r2d2;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
mod backgrounds;
|
pub mod backgrounds;
|
||||||
mod bestiary;
|
pub mod bestiary;
|
||||||
mod classes;
|
pub mod classes;
|
||||||
mod conditions;
|
pub mod conditions;
|
||||||
mod feats;
|
pub mod feats;
|
||||||
mod items;
|
pub mod items;
|
||||||
mod messages;
|
pub mod messages;
|
||||||
mod options;
|
pub mod options;
|
||||||
mod races;
|
pub mod races;
|
||||||
mod spells;
|
pub mod spells;
|
||||||
mod users;
|
pub mod users;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
|
||||||
pub use messages::*;
|
|
||||||
|
|
||||||
type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;
|
type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;
|
||||||
pub type DbConnection = r2d2::PooledConnection<ConnectionManager<PgConnection>>;
|
pub type DbConnection = r2d2::PooledConnection<ConnectionManager<PgConnection>>;
|
||||||
|
|
||||||
@@ -52,3 +51,21 @@ pub fn connection() -> Result<DbConnection, ServiceError> {
|
|||||||
POOL.get()
|
POOL.get()
|
||||||
.map_err(|e| ServiceError::new(500, format!("Failed getting db connection: {}", e)))
|
.map_err(|e| ServiceError::new(500, format!("Failed getting db connection: {}", e)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_data() {
|
||||||
|
spells::load_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct GetResponse<T> {
|
||||||
|
pub data: T,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub metadata: Option<Metadata>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Metadata {
|
||||||
|
pub total: i32,
|
||||||
|
pub limit: i32,
|
||||||
|
pub page: i32
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,43 @@
|
|||||||
mod model;
|
mod model;
|
||||||
|
mod routes;
|
||||||
|
|
||||||
pub use model::*;
|
pub use model::*;
|
||||||
|
pub use routes::init_routes;
|
||||||
|
|
||||||
|
pub fn load_data() {
|
||||||
|
let root_path = std::env::current_dir().unwrap();
|
||||||
|
let mut data_path = std::path::PathBuf::from(root_path);
|
||||||
|
data_path.push("data/spells.json");
|
||||||
|
match data_path.to_str() {
|
||||||
|
Some(path) => {
|
||||||
|
log::debug!("Loading spells from {}", path);
|
||||||
|
match std::fs::read_to_string(data_path) {
|
||||||
|
Ok(data) => {
|
||||||
|
match serde_json::from_str::<serde_json::Value>(&data) {
|
||||||
|
Ok(json) => {
|
||||||
|
match serde_json::from_value::<Vec<Spell>>(json) {
|
||||||
|
Ok(spells) => {
|
||||||
|
let count = QuerySpell::get_count().unwrap();
|
||||||
|
if count >= spells.len() as i64 {
|
||||||
|
log::warn!("Spell data is already loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for spell in spells {
|
||||||
|
match InsertSpell::insert(spell.into()) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(err) => log::error!("Failed to insert spell: {}", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => log::error!("Failed to parse spells data: {}", err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => log::error!("Failed to parse spells data to value: {}", err)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
Err(err) => log::error!("Failed to read spells data: {}", err)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
None => log::error!("Failed to find spells data directory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::db::schema::spells;
|
use crate::{db::schema::spells, error_handler::ServiceError};
|
||||||
|
|
||||||
#[derive(Queryable, QueryableByName)]
|
#[derive(Queryable, QueryableByName)]
|
||||||
#[diesel(table_name = spells)]
|
#[diesel(table_name = spells)]
|
||||||
@@ -24,6 +24,38 @@ pub struct QuerySpell {
|
|||||||
pub description: String
|
pub description: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl QuerySpell {
|
||||||
|
pub fn get_all(limit: i32, page: i32) -> Result<Vec<Self>, ServiceError> {
|
||||||
|
let mut conn = crate::db::connection()?;
|
||||||
|
let mut query = spells::table
|
||||||
|
.limit(limit as i64)
|
||||||
|
.into_boxed();
|
||||||
|
query = query.filter(spells::id.gt(std::cmp::max(0, page - 1) * limit));
|
||||||
|
let spells = query.load::<QuerySpell>(&mut conn)?;
|
||||||
|
Ok(spells)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_by_id(id: i32) -> Result<Self, ServiceError> {
|
||||||
|
let mut conn = crate::db::connection()?;
|
||||||
|
let spell = spells::table
|
||||||
|
.filter(spells::id.eq(id))
|
||||||
|
.first::<QuerySpell>(&mut conn)?;
|
||||||
|
Ok(spell)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_count() -> Result<i64, ServiceError> {
|
||||||
|
let mut conn = crate::db::connection()?;
|
||||||
|
let count = spells::table.count().get_result(&mut conn)?;
|
||||||
|
Ok(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(id: i32) -> Result<Self, ServiceError> {
|
||||||
|
let mut conn = crate::db::connection()?;
|
||||||
|
let spell = diesel::delete(spells::table.filter(spells::id.eq(id))).get_result(&mut conn)?;
|
||||||
|
Ok(spell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset)]
|
#[derive(Insertable, AsChangeset)]
|
||||||
#[diesel(table_name = spells)]
|
#[diesel(table_name = spells)]
|
||||||
pub struct InsertSpell {
|
pub struct InsertSpell {
|
||||||
@@ -44,6 +76,20 @@ pub struct InsertSpell {
|
|||||||
pub description: String
|
pub description: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InsertSpell {
|
||||||
|
pub fn insert(spell: Self) -> Result<QuerySpell, ServiceError> {
|
||||||
|
let mut conn = crate::db::connection()?;
|
||||||
|
let spell = diesel::insert_into(spells::table).values(spell).get_result(&mut conn)?;
|
||||||
|
Ok(spell)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(id: i32, spell: Self) -> Result<QuerySpell, ServiceError> {
|
||||||
|
let mut conn = crate::db::connection()?;
|
||||||
|
let spell = diesel::update(spells::table.filter(spells::id.eq(id))).set(spell).get_result(&mut conn)?;
|
||||||
|
Ok(spell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Spell {
|
pub struct Spell {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -56,6 +102,7 @@ pub struct Spell {
|
|||||||
pub duration: String,
|
pub duration: String,
|
||||||
pub classes: Vec<String>,
|
pub classes: Vec<String>,
|
||||||
pub sources: Vec<String>,
|
pub sources: Vec<String>,
|
||||||
|
pub tags: Vec<String>,
|
||||||
pub description: String
|
pub description: String
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,30 +114,8 @@ pub struct Components {
|
|||||||
pub materials_needed: Option<String>
|
pub materials_needed: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spell {
|
impl From<QuerySpell> for Spell {
|
||||||
/// Convert spell to insertable struct
|
fn from(query: QuerySpell) -> Self {
|
||||||
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 {
|
return Self {
|
||||||
name: query.name,
|
name: query.name,
|
||||||
school: query.school,
|
school: query.school,
|
||||||
@@ -107,14 +132,30 @@ impl Spell {
|
|||||||
duration: query.duration,
|
duration: query.duration,
|
||||||
classes: query.classes,
|
classes: query.classes,
|
||||||
sources: query.sources,
|
sources: query.sources,
|
||||||
|
tags: query.tags,
|
||||||
description: query.description
|
description: query.description
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert file to spell
|
impl Into<InsertSpell> for Spell {
|
||||||
pub fn from_file(file: String) -> Self {
|
fn into(self) -> InsertSpell {
|
||||||
let data = std::fs::read_to_string(file).unwrap();
|
return InsertSpell {
|
||||||
let spell: Spell = serde_json::from_str(&data).unwrap();
|
name: self.name,
|
||||||
return spell;
|
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: self.tags,
|
||||||
|
description: self.description
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
79
src/db/spells/routes.rs
Normal file
79
src/db/spells/routes.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use actix_web::{get, post, put, delete, web, HttpResponse, HttpRequest, ResponseError};
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
use crate::db::{spells::QuerySpell, GetResponse, Metadata};
|
||||||
|
|
||||||
|
use super::{Spell, InsertSpell};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct GetAllParams {
|
||||||
|
limit: Option<i32>,
|
||||||
|
page: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/spells")]
|
||||||
|
async fn get_all(req: HttpRequest) -> HttpResponse {
|
||||||
|
let params = web::Query::<GetAllParams>::from_query(req.query_string()).unwrap();
|
||||||
|
let limit = params.limit.unwrap_or(20);
|
||||||
|
let page = params.page.unwrap_or(1);
|
||||||
|
match web::block(move || QuerySpell::get_all(limit, page)).await.unwrap() {
|
||||||
|
Ok(spells) => {
|
||||||
|
let mut response: Vec<Spell> = Vec::new();
|
||||||
|
for spell in spells {
|
||||||
|
response.push(Spell::from(spell));
|
||||||
|
}
|
||||||
|
let total_count = QuerySpell::get_count().unwrap();
|
||||||
|
HttpResponse::Ok().json(GetResponse {
|
||||||
|
data: response,
|
||||||
|
metadata: Some(Metadata {
|
||||||
|
total: total_count as i32,
|
||||||
|
limit,
|
||||||
|
page
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
Err(err) => ResponseError::error_response(&err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/spells/{id}")]
|
||||||
|
async fn get_by_id(id: web::Path<i32>) -> HttpResponse {
|
||||||
|
match web::block(move || QuerySpell::get_by_id(id.into_inner())).await.unwrap() {
|
||||||
|
Ok(spell) => HttpResponse::Ok().json(GetResponse {
|
||||||
|
data: Spell::from(spell),
|
||||||
|
metadata: None
|
||||||
|
}),
|
||||||
|
Err(err) => ResponseError::error_response(&err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/spells")]
|
||||||
|
async fn create(spell: web::Json<Spell>) -> HttpResponse {
|
||||||
|
match InsertSpell::insert(spell.into_inner().into()) {
|
||||||
|
Ok(spell) => HttpResponse::Created().json(Spell::from(spell)),
|
||||||
|
Err(err) => ResponseError::error_response(&err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[put("/spells/{id}")]
|
||||||
|
async fn update(id: web::Path<i32>, spell: web::Json<Spell>) -> HttpResponse {
|
||||||
|
match web::block(move || InsertSpell::update(id.into_inner(), spell.into_inner().into())).await.unwrap() {
|
||||||
|
Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)),
|
||||||
|
Err(err) => ResponseError::error_response(&err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[delete("/spells/{id}")]
|
||||||
|
async fn delete(id: web::Path<i32>) -> HttpResponse {
|
||||||
|
match web::block(move || QuerySpell::delete(id.into_inner())).await.unwrap() {
|
||||||
|
Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)),
|
||||||
|
Err(err) => ResponseError::error_response(&err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_routes(config: &mut web::ServiceConfig) {
|
||||||
|
config.service(get_all);
|
||||||
|
config.service(get_by_id);
|
||||||
|
config.service(create);
|
||||||
|
config.service(delete);
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
|
use actix_web::{ResponseError, HttpResponse};
|
||||||
use diesel::result::Error as DieselError;
|
use diesel::result::Error as DieselError;
|
||||||
|
use reqwest::StatusCode;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -29,8 +31,27 @@ impl From<DieselError> for ServiceError {
|
|||||||
DieselError::DatabaseError(_, err) => ServiceError::new(409, err.message().to_string()),
|
DieselError::DatabaseError(_, err) => ServiceError::new(409, err.message().to_string()),
|
||||||
DieselError::NotFound => {
|
DieselError::NotFound => {
|
||||||
ServiceError::new(404, "The record was not found".to_string())
|
ServiceError::new(404, "The record was not found".to_string())
|
||||||
}
|
},
|
||||||
|
DieselError::SerializationError(err) => {
|
||||||
|
ServiceError::new(422, err.to_string())
|
||||||
|
},
|
||||||
err => ServiceError::new(500, format!("Unknown Diesel error: {}", err)),
|
err => ServiceError::new(500, format!("Unknown Diesel error: {}", err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResponseError for ServiceError {
|
||||||
|
fn error_response(&self) -> HttpResponse {
|
||||||
|
let status_code = match StatusCode::from_u16(self.error_status_code) {
|
||||||
|
Ok(status_code) => status_code,
|
||||||
|
Err(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
let error_message = match status_code.as_u16() < 500 {
|
||||||
|
true => self.error_message.clone(),
|
||||||
|
false => "Internal server error".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse::build(status_code).json(serde_json::json!({ "message": error_message }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
125
src/main.rs
125
src/main.rs
@@ -6,6 +6,7 @@ use std::collections::{HashSet, HashMap};
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use actix_web::{HttpServer, App};
|
||||||
use commands::audio::{create_response, AudioConfig, AudioConfigs};
|
use commands::audio::{create_response, AudioConfig, AudioConfigs};
|
||||||
|
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
@@ -111,60 +112,86 @@ impl EventHandler for Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[actix_web::main]
|
||||||
async fn main() {
|
async fn main() -> std::io::Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "warn,siren=info"));
|
env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "warn,siren=info"));
|
||||||
|
|
||||||
let token: String = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
|
|
||||||
let intents: GatewayIntents = GatewayIntents::all();
|
|
||||||
|
|
||||||
let http: Http = Http::new(&token);
|
|
||||||
let (owners, _bot_id) = match http.get_current_application_info().await {
|
|
||||||
Ok(info) => {
|
|
||||||
let mut owners: HashSet<serenity::model::id::UserId> = HashSet::new();
|
|
||||||
if let Some(team) = info.team {
|
|
||||||
owners.insert(team.owner_user_id);
|
|
||||||
} else {
|
|
||||||
owners.insert(info.owner.id);
|
|
||||||
}
|
|
||||||
match http.get_current_user().await {
|
|
||||||
Ok(bot) => (owners, bot.id),
|
|
||||||
Err(why) => panic!("Could not access the bot id: {:?}", why)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(why) => panic!("Could not access application info: {:?}", why)
|
|
||||||
};
|
|
||||||
|
|
||||||
db::init();
|
db::init();
|
||||||
|
db::load_data();
|
||||||
|
|
||||||
let handler = match env::var("OPENAI_API_KEY") {
|
// setup_discord_bot();
|
||||||
Ok(token) => {
|
|
||||||
info!("Loaded OpenAI token");
|
let host = env::var("SERVICE_HOST").unwrap_or("localhost".to_string());
|
||||||
Handler {
|
let port = env::var("SERVICE_PORT").unwrap_or("5000".to_string());
|
||||||
oai: Some(commands::oai::OAI { client: reqwest::Client::new(), base_url: "https://api.openai.com/v1".to_string(), max_attempts: 5, token , max_context_questions: 15 })
|
|
||||||
}
|
match HttpServer::new(|| {
|
||||||
}
|
App::new()
|
||||||
|
.configure(db::spells::init_routes)
|
||||||
|
})
|
||||||
|
.bind(format!("{}:{}", host, port)) {
|
||||||
|
Ok(b) => {
|
||||||
|
info!("Binding server to {}:{}", host, port);
|
||||||
|
b
|
||||||
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Could not load OpenAI token: {}", err);
|
error!("Could not bind server: {}", err);
|
||||||
Handler { oai: None }
|
return Err(err);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = Client::builder(token, intents)
|
|
||||||
.event_handler(handler)
|
|
||||||
.framework(StandardFramework::new()
|
|
||||||
.configure(|c| c.owners(owners)))
|
|
||||||
.register_songbird()
|
|
||||||
.await
|
|
||||||
.expect("Error creating client");
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut data = client.data.write().await;
|
|
||||||
data.insert::<AudioConfigs>(Arc::new(RwLock::new(HashMap::default())));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(why) = client.start_autosharded().await {
|
|
||||||
error!("An error occurred while running the client: {:?}", why);
|
|
||||||
}
|
}
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_discord_bot() {
|
||||||
|
tokio::spawn(async {
|
||||||
|
let token: String = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
|
||||||
|
let intents: GatewayIntents = GatewayIntents::all();
|
||||||
|
|
||||||
|
let http: Http = Http::new(&token);
|
||||||
|
let (owners, _bot_id) = match http.get_current_application_info().await {
|
||||||
|
Ok(info) => {
|
||||||
|
let mut owners: HashSet<serenity::model::id::UserId> = HashSet::new();
|
||||||
|
if let Some(team) = info.team {
|
||||||
|
owners.insert(team.owner_user_id);
|
||||||
|
} else {
|
||||||
|
owners.insert(info.owner.id);
|
||||||
|
}
|
||||||
|
match http.get_current_user().await {
|
||||||
|
Ok(bot) => (owners, bot.id),
|
||||||
|
Err(why) => panic!("Could not access the bot id: {:?}", why)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(why) => panic!("Could not access application info: {:?}", why)
|
||||||
|
};
|
||||||
|
|
||||||
|
let handler = match env::var("OPENAI_API_KEY") {
|
||||||
|
Ok(token) => {
|
||||||
|
info!("Loaded OpenAI token");
|
||||||
|
Handler {
|
||||||
|
oai: Some(commands::oai::OAI { client: reqwest::Client::new(), base_url: "https://api.openai.com/v1".to_string(), max_attempts: 5, token , max_context_questions: 15 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
warn!("Could not load OpenAI token: {}", err);
|
||||||
|
Handler { oai: None }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut client = Client::builder(token, intents)
|
||||||
|
.event_handler(handler)
|
||||||
|
.framework(StandardFramework::new()
|
||||||
|
.configure(|c| c.owners(owners)))
|
||||||
|
.register_songbird()
|
||||||
|
.await
|
||||||
|
.expect("Error creating client");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut data = client.data.write().await;
|
||||||
|
data.insert::<AudioConfigs>(Arc::new(RwLock::new(HashMap::default())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(why) = client.start_autosharded().await {
|
||||||
|
error!("An error occurred while running the client: {:?}", why);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user