interfaces for dealing with audio files + move stuff around
parent
752ce3f16c
commit
a1b3bbb999
|
|
@ -3,6 +3,14 @@ name = "memejoin-rs"
|
|||
version = "0.2.2-alpha"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "memejoin-rs"
|
||||
path = "src/main.rs"
|
||||
|
||||
[lib]
|
||||
name = "memejoin_rs"
|
||||
path = "src/lib/mod.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
160
src/db/mod.rs
160
src/db/mod.rs
|
|
@ -249,66 +249,66 @@ impl Database {
|
|||
intros
|
||||
}
|
||||
|
||||
pub(crate) fn get_all_user_permissions(
|
||||
&self,
|
||||
guild_id: u64,
|
||||
) -> Result<Vec<(String, auth::Permissions)>> {
|
||||
let mut query = self.conn.prepare(
|
||||
"
|
||||
SELECT
|
||||
username,
|
||||
permissions
|
||||
FROM UserPermission
|
||||
WHERE
|
||||
guild_id = :guild_id
|
||||
",
|
||||
)?;
|
||||
// pub(crate) fn get_all_user_permissions(
|
||||
// &self,
|
||||
// guild_id: u64,
|
||||
// ) -> Result<Vec<(String, auth::Permissions)>> {
|
||||
// let mut query = self.conn.prepare(
|
||||
// "
|
||||
// SELECT
|
||||
// username,
|
||||
// permissions
|
||||
// FROM UserPermission
|
||||
// WHERE
|
||||
// guild_id = :guild_id
|
||||
// ",
|
||||
// )?;
|
||||
//
|
||||
// let permissions = query
|
||||
// .query_map(
|
||||
// &[
|
||||
// // :vomit:
|
||||
// (":guild_id", &guild_id.to_string()),
|
||||
// ],
|
||||
// |row| Ok((row.get(0)?, auth::Permissions(row.get(1)?))),
|
||||
// )?
|
||||
// .collect::<Result<Vec<(String, auth::Permissions)>>>()?;
|
||||
//
|
||||
// Ok(permissions)
|
||||
// }
|
||||
|
||||
let permissions = query
|
||||
.query_map(
|
||||
&[
|
||||
// :vomit:
|
||||
(":guild_id", &guild_id.to_string()),
|
||||
],
|
||||
|row| Ok((row.get(0)?, auth::Permissions(row.get(1)?))),
|
||||
)?
|
||||
.collect::<Result<Vec<(String, auth::Permissions)>>>()?;
|
||||
// pub(crate) fn get_user_permissions(
|
||||
// &self,
|
||||
// username: &str,
|
||||
// guild_id: u64,
|
||||
// ) -> Result<auth::Permissions> {
|
||||
// self.conn.query_row(
|
||||
// "
|
||||
// SELECT
|
||||
// permissions
|
||||
// FROM UserPermission
|
||||
// WHERE
|
||||
// username = ?1
|
||||
// AND guild_id = ?2
|
||||
// ",
|
||||
// [username, &guild_id.to_string()],
|
||||
// |row| Ok(auth::Permissions(row.get(0)?)),
|
||||
// )
|
||||
// }
|
||||
|
||||
Ok(permissions)
|
||||
}
|
||||
|
||||
pub(crate) fn get_user_permissions(
|
||||
&self,
|
||||
username: &str,
|
||||
guild_id: u64,
|
||||
) -> Result<auth::Permissions> {
|
||||
self.conn.query_row(
|
||||
"
|
||||
SELECT
|
||||
permissions
|
||||
FROM UserPermission
|
||||
WHERE
|
||||
username = ?1
|
||||
AND guild_id = ?2
|
||||
",
|
||||
[username, &guild_id.to_string()],
|
||||
|row| Ok(auth::Permissions(row.get(0)?)),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn get_user_app_permissions(&self, username: &str) -> Result<auth::AppPermissions> {
|
||||
self.conn.query_row(
|
||||
"
|
||||
SELECT
|
||||
permissions
|
||||
FROM UserAppPermission
|
||||
WHERE
|
||||
username = ?1
|
||||
",
|
||||
[username],
|
||||
|row| Ok(auth::AppPermissions(row.get(0)?)),
|
||||
)
|
||||
}
|
||||
// pub(crate) fn get_user_app_permissions(&self, username: &str) -> Result<auth::AppPermissions> {
|
||||
// self.conn.query_row(
|
||||
// "
|
||||
// SELECT
|
||||
// permissions
|
||||
// FROM UserAppPermission
|
||||
// WHERE
|
||||
// username = ?1
|
||||
// ",
|
||||
// [username],
|
||||
// |row| Ok(auth::AppPermissions(row.get(0)?)),
|
||||
// )
|
||||
// }
|
||||
|
||||
pub(crate) fn get_guild_channels(&self, guild_id: u64) -> Result<Vec<String>> {
|
||||
let mut query = self.conn.prepare(
|
||||
|
|
@ -476,28 +476,29 @@ impl Database {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn insert_user_permission(
|
||||
&self,
|
||||
username: &str,
|
||||
guild_id: u64,
|
||||
permissions: auth::Permissions,
|
||||
) -> Result<()> {
|
||||
let affected = self.conn.execute(
|
||||
"
|
||||
INSERT INTO
|
||||
UserPermission (username, guild_id, permissions)
|
||||
VALUES (?1, ?2, ?3)
|
||||
ON CONFLICT(username, guild_id) DO UPDATE SET permissions = ?3",
|
||||
[username, &guild_id.to_string(), &permissions.0.to_string()],
|
||||
)?;
|
||||
|
||||
if affected < 1 {
|
||||
warn!("no rows affected when attempting to insert user permissions");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// pub(crate) fn insert_user_permission(
|
||||
// &self,
|
||||
// username: &str,
|
||||
// guild_id: u64,
|
||||
// permissions: auth::Permissions,
|
||||
// ) -> Result<()> {
|
||||
// let affected = self.conn.execute(
|
||||
// "
|
||||
// INSERT INTO
|
||||
// UserPermission (username, guild_id, permissions)
|
||||
// VALUES (?1, ?2, ?3)
|
||||
// ON CONFLICT(username, guild_id) DO UPDATE SET permissions = ?3",
|
||||
// [username, &guild_id.to_string(), &permissions.0.to_string()],
|
||||
// )?;
|
||||
//
|
||||
// if affected < 1 {
|
||||
// warn!("no rows affected when attempting to insert user permissions");
|
||||
// }
|
||||
//
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
/*
|
||||
pub(crate) fn insert_user_app_permission(
|
||||
&self,
|
||||
username: &str,
|
||||
|
|
@ -518,6 +519,7 @@ impl Database {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn delete_user_intro(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
#[derive(Clone)]
|
||||
pub struct DiscordSecret {
|
||||
pub client_id: String,
|
||||
pub client_secret: String,
|
||||
pub bot_token: String,
|
||||
}
|
||||
|
||||
/*
|
||||
use std::str::FromStr;
|
||||
|
||||
use enum_iterator::Sequence;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::routes::Error;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub(crate) struct Discord {
|
||||
pub(crate) access_token: String,
|
||||
|
|
@ -14,13 +20,6 @@ pub(crate) struct Discord {
|
|||
pub(crate) scope: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct DiscordSecret {
|
||||
pub(crate) client_id: String,
|
||||
pub(crate) client_secret: String,
|
||||
pub(crate) bot_token: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub(crate) struct User {
|
||||
pub(crate) auth: Discord,
|
||||
|
|
@ -143,3 +142,4 @@ impl FromStr for Permission {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use chrono::{Duration, Utc};
|
||||
|
||||
use crate::lib::domain::intro_tool::{
|
||||
use crate::domain::intro_tool::{
|
||||
models::{self, guild::IntroId},
|
||||
ports::{IntroToolRepository, IntroToolService},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{collections::HashMap, future::Future};
|
||||
|
||||
use crate::lib::domain::intro_tool::models::guild::{ChannelName, IntroId};
|
||||
use crate::domain::intro_tool::models::guild::{ChannelName, IntroId};
|
||||
|
||||
use super::models::guild::{
|
||||
AddIntroToGuildError, AddIntroToGuildRequest, AddIntroToUserError, AddIntroToUserRequest,
|
||||
|
|
@ -116,3 +116,19 @@ pub trait IntroToolRepository: Send + Sync + Clone + 'static {
|
|||
req: AddIntroToUserRequest,
|
||||
) -> Result<(), AddIntroToUserError>;
|
||||
}
|
||||
|
||||
pub trait RemoteAudioFetcher: Send + Sync + Clone + 'static {
|
||||
fn fetch_remote_audio(
|
||||
&self,
|
||||
url: &str,
|
||||
name: &str,
|
||||
) -> impl Future<Output = Result<String, anyhow::Error>> + Send;
|
||||
}
|
||||
|
||||
pub trait LocalAudioFetcher: Send + Sync + Clone + 'static {
|
||||
fn save_local_audio(
|
||||
&self,
|
||||
bytes: &[u8],
|
||||
name: &str,
|
||||
) -> impl Future<Output = Result<String, anyhow::Error>> + Send;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,42 @@
|
|||
use anyhow::{anyhow, Context};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
lib::domain::intro_tool::{
|
||||
models::guild::{self, GetUserError, GuildId, IntroId, User},
|
||||
ports::{IntroToolRepository, IntroToolService},
|
||||
},
|
||||
media,
|
||||
use crate::domain::intro_tool::{
|
||||
models::guild::{self, GetUserError, GuildId, IntroId, User},
|
||||
ports::{IntroToolRepository, IntroToolService, LocalAudioFetcher, RemoteAudioFetcher},
|
||||
};
|
||||
|
||||
use super::models;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Service<R>
|
||||
pub struct Service<R, RA, LA>
|
||||
where
|
||||
R: IntroToolRepository,
|
||||
RA: RemoteAudioFetcher,
|
||||
LA: LocalAudioFetcher,
|
||||
{
|
||||
repo: R,
|
||||
remote_audio_fetcher: RA,
|
||||
local_audio_fetcher: LA,
|
||||
}
|
||||
|
||||
impl<R> Service<R>
|
||||
impl<R, RA, LA> Service<R, RA, LA>
|
||||
where
|
||||
R: IntroToolRepository,
|
||||
RA: RemoteAudioFetcher,
|
||||
LA: LocalAudioFetcher,
|
||||
{
|
||||
pub fn new(repo: R) -> Self {
|
||||
Self { repo }
|
||||
pub fn new(repo: R, remote_audio_fetcher: RA, local_audio_fetcher: LA) -> Self {
|
||||
Self {
|
||||
repo,
|
||||
remote_audio_fetcher,
|
||||
local_audio_fetcher,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> IntroToolService for Service<R>
|
||||
impl<R, RA, LA> IntroToolService for Service<R, RA, LA>
|
||||
where
|
||||
R: IntroToolRepository,
|
||||
RA: RemoteAudioFetcher,
|
||||
LA: LocalAudioFetcher,
|
||||
{
|
||||
async fn needs_setup(&self) -> bool {
|
||||
let Ok(guild_count) = self.repo.get_guild_count().await else {
|
||||
|
|
@ -102,42 +108,14 @@ where
|
|||
) -> Result<IntroId, guild::AddIntroToGuildError> {
|
||||
let file_name = match &req.data {
|
||||
guild::IntroRequestData::Data(bytes) => {
|
||||
// TODO: put this behind an interface
|
||||
let uuid = Uuid::new_v4().to_string();
|
||||
let temp_path = format!("./sounds/temp/{uuid}");
|
||||
let dest_path = format!("./sounds/{uuid}.mp3");
|
||||
|
||||
// Write original file so its ready for codec conversion
|
||||
std::fs::write(&temp_path, bytes).context("failed to write temp file")?;
|
||||
media::normalize(&temp_path, &dest_path)
|
||||
.await
|
||||
.context("failed to normalize file")?;
|
||||
std::fs::remove_file(&temp_path).context("failed to remove temp file")?;
|
||||
|
||||
dest_path
|
||||
self.local_audio_fetcher
|
||||
.save_local_audio(bytes, Uuid::new_v4().to_string().as_str())
|
||||
.await?
|
||||
}
|
||||
guild::IntroRequestData::Url(url) => {
|
||||
let uuid = Uuid::new_v4().to_string();
|
||||
let file_name = format!("sounds/{uuid}");
|
||||
|
||||
// TODO: put this behind an interface
|
||||
let child = tokio::process::Command::new("yt-dlp")
|
||||
.arg(url)
|
||||
.args(["-o", &file_name])
|
||||
.args(["-x", "--audio-format", "mp3"])
|
||||
.spawn()
|
||||
.context("failed to spawn yt-dlp process")?
|
||||
.wait()
|
||||
.await
|
||||
.context("yt-dlp process failed")?;
|
||||
|
||||
if !child.success() {
|
||||
return Err(guild::AddIntroToGuildError::Unknown(anyhow!(
|
||||
"yt-dlp terminated unsuccessfully"
|
||||
)));
|
||||
}
|
||||
|
||||
file_name
|
||||
self.remote_audio_fetcher
|
||||
.fetch_remote_audio(url, Uuid::new_v4().to_string().as_str())
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use tracing::info;
|
|||
|
||||
use crate::{
|
||||
auth,
|
||||
lib::domain::intro_tool::{models::guild::User, ports::IntroToolService},
|
||||
domain::intro_tool::{models::guild::User, ports::IntroToolService},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use axum::{
|
|||
http::{HeaderMap, HeaderValue},
|
||||
};
|
||||
|
||||
use crate::lib::{
|
||||
use crate::{
|
||||
domain::intro_tool::{
|
||||
models::guild::{AddIntroToGuildRequest, GuildId, IntroRequestData, User},
|
||||
ports::IntroToolService,
|
||||
|
|
|
|||
|
|
@ -4,14 +4,12 @@ use axum::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
htmx::{Build, HtmxBuilder, Tag},
|
||||
lib::{
|
||||
domain::intro_tool::{
|
||||
models::guild::{ChannelName, GuildRef, Intro, User},
|
||||
ports::IntroToolService,
|
||||
},
|
||||
inbound::{http::ApiState, response::ErrorAsRedirect},
|
||||
domain::intro_tool::{
|
||||
models::guild::{ChannelName, GuildRef, Intro, User},
|
||||
ports::IntroToolService,
|
||||
},
|
||||
htmx::{Build, HtmxBuilder, Tag},
|
||||
inbound::{http::ApiState, response::ErrorAsRedirect},
|
||||
};
|
||||
|
||||
pub async fn home<S: IntroToolService>(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use axum::{
|
|||
use reqwest::StatusCode;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::lib::domain::intro_tool::models::guild::{
|
||||
use crate::domain::intro_tool::models::guild::{
|
||||
AddIntroToGuildError, GetChannelError, GetGuildError, GetIntroError,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
pub mod auth;
|
||||
pub mod domain;
|
||||
pub mod htmx;
|
||||
pub mod inbound;
|
||||
pub mod outbound;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
use anyhow::{anyhow, Context};
|
||||
|
||||
use crate::domain::intro_tool::ports::LocalAudioFetcher;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Ffmpeg;
|
||||
|
||||
impl LocalAudioFetcher for Ffmpeg {
|
||||
async fn save_local_audio(&self, bytes: &[u8], name: &str) -> Result<String, anyhow::Error> {
|
||||
let temp_path = format!("./sounds/temp/{name}");
|
||||
let dest_path = format!("./sounds/{name}.mp3");
|
||||
|
||||
// Write original file so its ready for codec conversion
|
||||
std::fs::write(&temp_path, bytes).context("failed to write temp file")?;
|
||||
let child = tokio::process::Command::new("ffmpeg")
|
||||
.args(["-i", &temp_path])
|
||||
.arg("-vn")
|
||||
.args(["-map", "0:a"])
|
||||
.arg(&dest_path)
|
||||
.spawn()
|
||||
.map_err(|err| anyhow!(err.to_string()))?
|
||||
.wait()
|
||||
.await
|
||||
.map_err(|err| anyhow!(err.to_string()))?;
|
||||
|
||||
if !child.success() {
|
||||
return Err(anyhow!("ffmpeg terminated unsuccessfully"));
|
||||
}
|
||||
std::fs::remove_file(&temp_path).context("failed to remove temp file")?;
|
||||
|
||||
Ok(dest_path)
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,3 @@
|
|||
pub mod ffmpeg;
|
||||
pub mod sqlite;
|
||||
pub mod ytdlp;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use tokio::sync::Mutex;
|
|||
use anyhow::Context;
|
||||
use rusqlite::Connection;
|
||||
|
||||
use crate::lib::domain::intro_tool::{
|
||||
use crate::domain::intro_tool::{
|
||||
models::guild::{
|
||||
self, AddIntroToGuildError, AddIntroToGuildRequest, AddIntroToUserRequest, Channel,
|
||||
ChannelName, CreateChannelError, CreateChannelRequest, CreateGuildError,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
use anyhow::{anyhow, Context};
|
||||
|
||||
use crate::domain::intro_tool::ports::RemoteAudioFetcher;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Ytdlp;
|
||||
|
||||
impl RemoteAudioFetcher for Ytdlp {
|
||||
async fn fetch_remote_audio(&self, url: &str, name: &str) -> Result<String, anyhow::Error> {
|
||||
let file_name = format!("sounds/{name}");
|
||||
|
||||
let child = tokio::process::Command::new("yt-dlp")
|
||||
.arg(url)
|
||||
.args(["-o", &file_name])
|
||||
.args(["-x", "--audio-format", "mp3"])
|
||||
.spawn()
|
||||
.context("failed to spawn yt-dlp process")?
|
||||
.wait()
|
||||
.await
|
||||
.context("yt-dlp process failed")?;
|
||||
|
||||
if !child.success() {
|
||||
return Err(anyhow!("yt-dlp terminated unsuccessfully"));
|
||||
}
|
||||
|
||||
Ok(format!("{file_name}.mp3"))
|
||||
}
|
||||
}
|
||||
94
src/main.rs
94
src/main.rs
|
|
@ -1,26 +1,9 @@
|
|||
// #![feature(stmt_expr_attributes)]
|
||||
// #![feature(proc_macro_hygiene)]
|
||||
// #![feature(async_closure)]
|
||||
|
||||
mod lib;
|
||||
|
||||
mod auth;
|
||||
mod db;
|
||||
mod htmx;
|
||||
mod media;
|
||||
mod page;
|
||||
mod routes;
|
||||
pub mod settings;
|
||||
|
||||
use axum::http::Method;
|
||||
use axum::routing::{get, post};
|
||||
use axum::Router;
|
||||
use settings::ApiState;
|
||||
use std::env;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
|
||||
use serenity::async_trait;
|
||||
use serenity::model::prelude::{Channel, ChannelId, GuildId, Member, Ready};
|
||||
|
|
@ -30,9 +13,7 @@ use serenity::prelude::*;
|
|||
use songbird::SerenityInit;
|
||||
use tracing::*;
|
||||
|
||||
use crate::lib::domain::intro_tool;
|
||||
use crate::lib::{inbound, outbound};
|
||||
use crate::settings::Settings;
|
||||
use memejoin_rs::{auth, domain::intro_tool, inbound, outbound};
|
||||
|
||||
enum HandlerMessage {
|
||||
Ready(Context),
|
||||
|
|
@ -120,67 +101,6 @@ impl EventHandler for Handler {
|
|||
}
|
||||
}
|
||||
|
||||
fn spawn_api(db: Arc<tokio::sync::Mutex<db::Database>>) {
|
||||
let secrets = auth::DiscordSecret {
|
||||
client_id: env::var("DISCORD_CLIENT_ID").expect("expected DISCORD_CLIENT_ID env var"),
|
||||
client_secret: env::var("DISCORD_CLIENT_SECRET")
|
||||
.expect("expected DISCORD_CLIENT_SECRET env var"),
|
||||
bot_token: env::var("DISCORD_TOKEN").expect("expected DISCORD_TOKEN env var"),
|
||||
};
|
||||
let origin = env::var("APP_ORIGIN").expect("expected APP_ORIGIN");
|
||||
|
||||
let state = ApiState {
|
||||
db,
|
||||
secrets,
|
||||
origin: origin.clone(),
|
||||
};
|
||||
|
||||
tokio::spawn(async move {
|
||||
let api = Router::new()
|
||||
.route("/", get(page::home))
|
||||
.route("/index.html", get(page::home))
|
||||
.route("/login", get(page::login))
|
||||
.route("/guild/:guild_id", get(page::guild_dashboard))
|
||||
.route("/guild/:guild_id/setup", get(routes::guild_setup))
|
||||
.route(
|
||||
"/guild/:guild_id/add_channel",
|
||||
post(routes::guild_add_channel),
|
||||
)
|
||||
.route(
|
||||
"/guild/:guild_id/permissions/update",
|
||||
post(routes::update_guild_permissions),
|
||||
)
|
||||
.route("/v2/auth", get(routes::v2_auth))
|
||||
.route(
|
||||
"/v2/intros/add/:guild_id/:channel",
|
||||
post(routes::v2_add_intro_to_user),
|
||||
)
|
||||
.route(
|
||||
"/v2/intros/remove/:guild_id/:channel",
|
||||
post(routes::v2_remove_intro_from_user),
|
||||
)
|
||||
.route("/v2/intros/:guild/add", get(routes::v2_add_guild_intro))
|
||||
.route(
|
||||
"/v2/intros/:guild/upload",
|
||||
post(routes::v2_upload_guild_intro),
|
||||
)
|
||||
.route("/health", get(routes::health))
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
.allow_origin([origin.parse().unwrap()])
|
||||
.allow_headers(Any)
|
||||
.allow_methods([Method::GET, Method::POST, Method::DELETE]),
|
||||
)
|
||||
.with_state(state);
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], 8100));
|
||||
info!("socket listening on {addr}");
|
||||
axum::Server::bind(&addr)
|
||||
.serve(api.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
async fn spawn_bot(db: Arc<tokio::sync::Mutex<db::Database>>) {
|
||||
let token = env::var("DISCORD_TOKEN").expect("expected DISCORD_TOKEN env var");
|
||||
let songbird = songbird::Songbird::serenity();
|
||||
|
|
@ -318,10 +238,6 @@ async fn main() -> std::io::Result<()> {
|
|||
dotenv::dotenv().ok();
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let settings = serde_json::from_str::<Settings>(
|
||||
&std::fs::read_to_string("config/settings.json").expect("no config/settings.json"),
|
||||
)
|
||||
.expect("error parsing settings file");
|
||||
let secrets = auth::DiscordSecret {
|
||||
client_id: env::var("DISCORD_CLIENT_ID").expect("expected DISCORD_CLIENT_ID env var"),
|
||||
client_secret: env::var("DISCORD_CLIENT_SECRET")
|
||||
|
|
@ -331,9 +247,12 @@ async fn main() -> std::io::Result<()> {
|
|||
let origin = env::var("APP_ORIGIN").expect("expected APP_ORIGIN");
|
||||
|
||||
let db = outbound::sqlite::Sqlite::new("./config/db.sqlite").expect("couldn't open sqlite db");
|
||||
let local_audio_fetcher = outbound::ffmpeg::Ffmpeg;
|
||||
let remote_audio_fetcher = outbound::ytdlp::Ytdlp;
|
||||
|
||||
if let Ok(impersonated_username) = env::var("IMPERSONATED_USERNAME") {
|
||||
let service = intro_tool::service::Service::new(db);
|
||||
let service =
|
||||
intro_tool::service::Service::new(db, remote_audio_fetcher, local_audio_fetcher);
|
||||
let service = intro_tool::debug_service::DebugService::new(service, impersonated_username);
|
||||
|
||||
let http_server = inbound::http::HttpServer::new(service, secrets, origin)
|
||||
|
|
@ -341,7 +260,8 @@ async fn main() -> std::io::Result<()> {
|
|||
|
||||
http_server.run().await;
|
||||
} else {
|
||||
let service = intro_tool::service::Service::new(db);
|
||||
let service =
|
||||
intro_tool::service::Service::new(db, remote_audio_fetcher, local_audio_fetcher);
|
||||
|
||||
let http_server = inbound::http::HttpServer::new(service, secrets, origin)
|
||||
.expect("couldn't start http server");
|
||||
|
|
|
|||
Loading…
Reference in New Issue