Compare commits
29 Commits
Author | SHA1 | Date |
---|---|---|
trivernis | 9bfb35dbce | 5 months ago |
trivernis | 048d6a5cba | 5 months ago |
trivernis | b2b09a3f4f | 5 months ago |
trivernis | e3250e1bc6 | 5 months ago |
trivernis | 2d869f3ea8 | 5 months ago |
trivernis | e6726e41c8 | 5 months ago |
trivernis | bc57733dbf | 5 months ago |
trivernis | 37b22a7d51 | 5 months ago |
trivernis | 6c9889e3e1 | 5 months ago |
trivernis | 8836f311c9 | 5 months ago |
trivernis | 06c8ac2446 | 2 years ago |
trivernis | 84eaf56810 | 2 years ago |
trivernis | 118832036e | 2 years ago |
trivernis | 065fc688ad | 2 years ago |
trivernis | 05aadf615d | 2 years ago |
trivernis | 52a956b2f7 | 2 years ago |
trivernis | 7a70e30c7e | 2 years ago |
Julius Riegel | e23a0bd325 | 2 years ago |
trivernis | 4089cd2305 | 2 years ago |
Julius Riegel | 6c100ad1e5 | 2 years ago |
trivernis | c217e65557 | 2 years ago |
Julius Riegel | 3c0cf99bef | 2 years ago |
trivernis | 09fd675df0 | 2 years ago |
trivernis | 898353ed57 | 2 years ago |
trivernis | 34b41b78b5 | 2 years ago |
Julius Riegel | 45c7f0b147 | 2 years ago |
trivernis | 30097e624e | 2 years ago |
trivernis | 26c7df783b | 2 years ago |
trivernis | 9819b58243 | 2 years ago |
@ -0,0 +1,39 @@
|
||||
version: 1
|
||||
when:
|
||||
- event: [pull_request]
|
||||
- event: push
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
- release/*
|
||||
- fix/*
|
||||
steps:
|
||||
test:
|
||||
image: rust:alpine
|
||||
commands:
|
||||
- apk add --no-cache --force-overwrite \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libopusenc-dev \
|
||||
libpq-dev \
|
||||
curl \
|
||||
bash
|
||||
- rustup default stable
|
||||
- rustup component add clippy --toolchain stable-x86_64-unknown-linux-musl
|
||||
- cargo clippy
|
||||
- cargo test --verbose --package bot-coreutils
|
||||
- cargo test --verbose --package bot-database
|
||||
- cargo test --verbose
|
||||
|
||||
build:
|
||||
image: rust:alpine
|
||||
commands:
|
||||
- apk add --no-cache --force-overwrite \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libopusenc-dev \
|
||||
libpq-dev \
|
||||
curl \
|
||||
bash
|
||||
- cargo build
|
||||
when:
|
||||
- event: [pull_request]
|
@ -0,0 +1,20 @@
|
||||
version: 1
|
||||
when:
|
||||
- event: [tag]
|
||||
branch:
|
||||
- ${CI_REPO_DEFAULT_BRANCH}
|
||||
steps:
|
||||
build:
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
secrets: [forgejo_token]
|
||||
settings:
|
||||
dockerfile: Containerfile
|
||||
tag: ${CI_COMMIT_TAG##v}
|
||||
repo: git.trivernis.net/trivernis/2b-rs
|
||||
registry: git.trivernis.net
|
||||
platforms: linux/amd64
|
||||
username:
|
||||
from_secret: forgejo_id
|
||||
password:
|
||||
from_secret: forgejo_token
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
# For documentation on how to configure this file,
|
||||
# see diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
sea-orm-migration = "0.9.3"
|
||||
tokio = { version = "1.21.2", features = ["rt", "net", "tracing"] }
|
@ -0,0 +1,37 @@
|
||||
# Running Migrator CLI
|
||||
|
||||
- Apply all pending migrations
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
```sh
|
||||
cargo run -- up
|
||||
```
|
||||
- Apply first 10 pending migrations
|
||||
```sh
|
||||
cargo run -- up -n 10
|
||||
```
|
||||
- Rollback last applied migrations
|
||||
```sh
|
||||
cargo run -- down
|
||||
```
|
||||
- Rollback last 10 applied migrations
|
||||
```sh
|
||||
cargo run -- down -n 10
|
||||
```
|
||||
- Drop all tables from the database, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- fresh
|
||||
```
|
||||
- Rollback all applied migrations, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- refresh
|
||||
```
|
||||
- Rollback all applied migrations
|
||||
```sh
|
||||
cargo run -- reset
|
||||
```
|
||||
- Check the status of all migrations
|
||||
```sh
|
||||
cargo run -- status
|
||||
```
|
@ -0,0 +1,16 @@
|
||||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20220029_164527_change_timestamp_format;
|
||||
mod m20220101_000001_create_table;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![
|
||||
Box::new(m20220101_000001_create_table::Migration),
|
||||
Box::new(m20220029_164527_change_timestamp_format::Migration),
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
use crate::{DbErr, Table};
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum Statistics {
|
||||
Table,
|
||||
ExecutedAt,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum EphemeralMessages {
|
||||
Table,
|
||||
Timeout,
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220029_164527_change_timestamp_format"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(Statistics::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(Statistics::ExecutedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(EphemeralMessages::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(EphemeralMessages::Timeout)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(Statistics::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(Statistics::ExecutedAt)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(EphemeralMessages::Table)
|
||||
.modify_column(
|
||||
ColumnDef::new(EphemeralMessages::Timeout)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -0,0 +1,287 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum EphemeralMessages {
|
||||
Table,
|
||||
ChannelId,
|
||||
MessageId,
|
||||
Timeout,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum GuildPlaylists {
|
||||
Table,
|
||||
GuildId,
|
||||
Name,
|
||||
Url,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum GuildSettings {
|
||||
Table,
|
||||
GuildId,
|
||||
Key,
|
||||
Value,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum Media {
|
||||
Table,
|
||||
Id,
|
||||
Category,
|
||||
Name,
|
||||
Url,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum Statistics {
|
||||
Table,
|
||||
Id,
|
||||
Version,
|
||||
Command,
|
||||
ExecutedAt,
|
||||
Success,
|
||||
ErrorMsg,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
pub enum YoutubeSongs {
|
||||
Table,
|
||||
Id,
|
||||
SpotifyId,
|
||||
Artist,
|
||||
Title,
|
||||
Album,
|
||||
Url,
|
||||
Score,
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220101_000001_create_table"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager.create_table(ephemeral_messages()).await?;
|
||||
manager.create_table(guild_playlists()).await?;
|
||||
manager.create_table(guild_settings()).await?;
|
||||
manager.create_table(media()).await?;
|
||||
manager.create_table(statistics()).await?;
|
||||
manager.create_table(youtube_songs()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(EphemeralMessages::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(GuildPlaylists::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(GuildSettings::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Media::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Statistics::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(YoutubeSongs::Table).to_owned())
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn ephemeral_messages() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(EphemeralMessages::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(EphemeralMessages::ChannelId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(EphemeralMessages::MessageId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(EphemeralMessages::Timeout)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(EphemeralMessages::ChannelId)
|
||||
.col(EphemeralMessages::MessageId),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn guild_playlists() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(GuildPlaylists::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(GuildPlaylists::GuildId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildPlaylists::Name)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildPlaylists::Url)
|
||||
.string_len(1204)
|
||||
.not_null(),
|
||||
)
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(GuildPlaylists::GuildId)
|
||||
.col(GuildPlaylists::Name),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn guild_settings() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(GuildSettings::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(GuildSettings::GuildId)
|
||||
.big_integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildSettings::Key)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(GuildSettings::Value)
|
||||
.string_len(1024)
|
||||
.not_null(),
|
||||
)
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(GuildSettings::GuildId)
|
||||
.col(GuildSettings::Key),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn media() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(Media::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Media::Id)
|
||||
.big_integer()
|
||||
.auto_increment()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Media::Category).string_len(128))
|
||||
.col(ColumnDef::new(Media::Name).string_len(128))
|
||||
.col(ColumnDef::new(Media::Url).string_len(128))
|
||||
.index(
|
||||
Index::create()
|
||||
.unique()
|
||||
.col(Media::Category)
|
||||
.col(Media::Name),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn statistics() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(Statistics::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Id)
|
||||
.big_integer()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Version)
|
||||
.string_len(32)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Command)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::ExecutedAt)
|
||||
.timestamp()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Statistics::Success)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(true),
|
||||
)
|
||||
.col(ColumnDef::new(Statistics::ErrorMsg).string())
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn youtube_songs() -> TableCreateStatement {
|
||||
Table::create()
|
||||
.table(YoutubeSongs::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Id)
|
||||
.big_integer()
|
||||
.primary_key()
|
||||
.auto_increment(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::SpotifyId)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Artist)
|
||||
.string_len(128)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Title)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Album)
|
||||
.string_len(255)
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(YoutubeSongs::Url).string_len(128).not_null())
|
||||
.col(
|
||||
ColumnDef::new(YoutubeSongs::Score)
|
||||
.integer()
|
||||
.default(0)
|
||||
.not_null(),
|
||||
)
|
||||
.index(
|
||||
Index::create()
|
||||
.unique()
|
||||
.col(YoutubeSongs::SpotifyId)
|
||||
.col(YoutubeSongs::Url),
|
||||
)
|
||||
.to_owned()
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
use migration::Migrator;
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
cli::run_cli(Migrator).await;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
@ -1,36 +0,0 @@
|
||||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
|
||||
|
||||
|
||||
-- Sets up a trigger for the given table to automatically set a column called
|
||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||
-- in the modified columns)
|
||||
--
|
||||
-- # Example
|
||||
--
|
||||
-- ```sql
|
||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||
--
|
||||
-- SELECT diesel_manage_updated_at('users');
|
||||
-- ```
|
||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||
BEGIN
|
||||
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF (
|
||||
NEW IS DISTINCT FROM OLD AND
|
||||
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||
) THEN
|
||||
NEW.updated_at := current_timestamp;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE guild_settings;
|
@ -1,6 +0,0 @@
|
||||
CREATE TABLE guild_settings (
|
||||
guild_id BIGINT NOT NULL,
|
||||
key VARCHAR(255) NOT NULL,
|
||||
value VARCHAR(1024),
|
||||
PRIMARY KEY (guild_id, key)
|
||||
);
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE guild_playlists;
|
@ -1,7 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE guild_playlists (
|
||||
guild_id BIGINT NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
url VARCHAR(1024) NOT NULL,
|
||||
PRIMARY KEY (guild_id, name)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE gifs;
|
@ -1,8 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE gifs (
|
||||
id BIGSERIAL PRIMARY KEY ,
|
||||
category VARCHAR(128),
|
||||
name VARCHAR(128),
|
||||
url VARCHAR(128) NOT NULL,
|
||||
UNIQUE (category, name)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE statistics;
|
@ -1,9 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE statistics (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
version VARCHAR(32) NOT NULL,
|
||||
command VARCHAR(255) NOT NULL,
|
||||
executed_at TIMESTAMP NOT NULL,
|
||||
success BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
error_msg TEXT
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE youtube_songs;
|
@ -1,11 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE youtube_songs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
spotify_id VARCHAR(255) NOT NULL,
|
||||
artist VARCHAR(128) NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
album VARCHAR(255) NOT NULL,
|
||||
url VARCHAR(128) NOT NULL,
|
||||
score INTEGER DEFAULT 0 NOT NULL,
|
||||
UNIQUE (spotify_id, url)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE ephemeral_messages;
|
@ -1,7 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
CREATE TABLE ephemeral_messages (
|
||||
channel_id BIGINT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
timeout TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (channel_id, message_id)
|
||||
)
|
@ -1,2 +0,0 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
ALTER TABLE media RENAME TO gifs;
|
@ -1,2 +0,0 @@
|
||||
-- Your SQL goes here
|
||||
ALTER TABLE gifs RENAME TO media;
|
@ -1,50 +1,49 @@
|
||||
use crate::entity::statistics;
|
||||
use crate::error::DatabaseResult;
|
||||
use sea_orm::prelude::*;
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::{FromQueryResult, QuerySelect};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use diesel::dsl::count;
|
||||
use diesel::insert_into;
|
||||
use diesel::prelude::*;
|
||||
use tokio_diesel::*;
|
||||
|
||||
use crate::error::DatabaseResult;
|
||||
use crate::models::*;
|
||||
use crate::schema::*;
|
||||
use crate::Database;
|
||||
#[derive(FromQueryResult)]
|
||||
struct CommandCount {
|
||||
count: i64,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
impl super::BotDatabase {
|
||||
/// Adds a command statistic to the database
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub async fn add_statistic(
|
||||
&self,
|
||||
version: &str,
|
||||
command: &str,
|
||||
version: String,
|
||||
command: String,
|
||||
executed_at: SystemTime,
|
||||
success: bool,
|
||||
error_msg: Option<String>,
|
||||
) -> DatabaseResult<()> {
|
||||
use statistics::dsl;
|
||||
log::trace!("Adding statistic to database");
|
||||
insert_into(dsl::statistics)
|
||||
.values(StatisticInsert {
|
||||
version: version.to_string(),
|
||||
command: command.to_string(),
|
||||
executed_at,
|
||||
success,
|
||||
error_msg,
|
||||
})
|
||||
.execute_async(&self.pool)
|
||||
.await?;
|
||||
let model = statistics::ActiveModel {
|
||||
version: Set(version),
|
||||
command: Set(command),
|
||||
executed_at: Set(DateTimeLocal::from(executed_at).into()),
|
||||
success: Set(success),
|
||||
error_msg: Set(error_msg),
|
||||
..Default::default()
|
||||
};
|
||||
model.insert(&self.db).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the total number of commands executed
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub async fn get_total_commands_statistic(&self) -> DatabaseResult<u64> {
|
||||
use statistics::dsl;
|
||||
log::trace!("Querying total number of commands");
|
||||
let total_count: i64 = dsl::statistics
|
||||
.select(count(dsl::id))
|
||||
.first_async::<i64>(&self.pool)
|
||||
let total_count: Option<CommandCount> = statistics::Entity::find()
|
||||
.select_only()
|
||||
.column_as(statistics::Column::Id.count(), "count")
|
||||
.into_model::<CommandCount>()
|
||||
.one(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(total_count as u64)
|
||||
Ok(total_count.unwrap().count as u64)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "ephemeral_messages")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub channel_id: i64,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub message_id: i64,
|
||||
pub timeout: DateTimeWithTimeZone,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "guild_playlists")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub guild_id: i64,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "guild_settings")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub guild_id: i64,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub key: String,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,24 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "media")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i64,
|
||||
pub category: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,10 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod ephemeral_messages;
|
||||
pub mod guild_playlists;
|
||||
pub mod guild_settings;
|
||||
pub mod media;
|
||||
pub mod statistics;
|
||||
pub mod youtube_songs;
|
@ -0,0 +1,8 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
pub use super::ephemeral_messages::Entity as EphemeralMessages;
|
||||
pub use super::guild_playlists::Entity as GuildPlaylists;
|
||||
pub use super::guild_settings::Entity as GuildSettings;
|
||||
pub use super::media::Entity as Media;
|
||||
pub use super::statistics::Entity as Statistics;
|
||||
pub use super::youtube_songs::Entity as YoutubeSongs;
|
@ -0,0 +1,27 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "statistics")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i64,
|
||||
pub version: String,
|
||||
pub command: String,
|
||||
pub executed_at: DateTimeWithTimeZone,
|
||||
pub success: bool,
|
||||
#[sea_orm(column_type = "Text", nullable)]
|
||||
pub error_msg: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,27 @@
|
||||
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "youtube_songs")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i64,
|
||||
pub spotify_id: String,
|
||||
pub artist: String,
|
||||
pub title: String,
|
||||
pub album: String,
|
||||
pub url: String,
|
||||
pub score: i32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!("No RelationDef")
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
@ -1,47 +1,31 @@
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
|
||||
use crate::error::{DatabaseError, DatabaseResult};
|
||||
use diesel::prelude::*;
|
||||
use diesel::r2d2::{ConnectionManager, ManageConnection, Pool};
|
||||
use crate::error::DatabaseResult;
|
||||
use std::env;
|
||||
|
||||
pub mod database;
|
||||
pub mod entity;
|
||||
pub mod error;
|
||||
pub mod models;
|
||||
pub mod schema;
|
||||
|
||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub use database::Database;
|
||||
|
||||
type PoolConnection = Pool<ConnectionManager<PgConnection>>;
|
||||
pub use database::BotDatabase as Database;
|
||||
use migration::MigratorTrait;
|
||||
use sea_orm::{ConnectOptions, Database as SeaDatabase, DatabaseConnection};
|
||||
|
||||
embed_migrations!("../bot-database/migrations");
|
||||
|
||||
fn get_connection() -> DatabaseResult<PoolConnection> {
|
||||
#[tracing::instrument]
|
||||
async fn get_connection() -> DatabaseResult<DatabaseConnection> {
|
||||
let database_url = env::var("DATABASE_URL").expect("No DATABASE_URL in path");
|
||||
log::debug!("Establishing database connection...");
|
||||
let manager = ConnectionManager::<PgConnection>::new(database_url);
|
||||
log::trace!("Connecting...");
|
||||
manager
|
||||
.connect()
|
||||
.map_err(|e| DatabaseError::Msg(format!("{:?}", e)))?;
|
||||
log::trace!("Creating pool...");
|
||||
let pool = Pool::builder().max_size(16).build(manager)?;
|
||||
log::trace!("Getting one connection to run migrations...");
|
||||
let connection = pool.get()?;
|
||||
log::debug!("Running migrations...");
|
||||
embedded_migrations::run(&connection)?;
|
||||
log::debug!("Migrations finished");
|
||||
log::info!("Database connection initialized");
|
||||
|
||||
Ok(pool)
|
||||
tracing::debug!("Establishing database connection...");
|
||||
let opt = ConnectOptions::new(database_url);
|
||||
let db = SeaDatabase::connect(opt).await?;
|
||||
tracing::debug!("Running migrations...");
|
||||
migration::Migrator::up(&db, None).await?;
|
||||
tracing::debug!("Migrations finished");
|
||||
tracing::info!("Database connection initialized");
|
||||
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
pub fn get_database() -> DatabaseResult<Database> {
|
||||
let conn = get_connection()?;
|
||||
pub async fn get_database() -> DatabaseResult<Database> {
|
||||
let conn = get_connection().await?;
|
||||
Ok(Database::new(conn))
|
||||
}
|
||||
|
@ -1,94 +1,8 @@
|
||||
use crate::schema::*;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
pub struct GuildSetting {
|
||||
pub guild_id: i64,
|
||||
pub key: String,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "guild_settings"]
|
||||
pub struct GuildSettingInsert {
|
||||
pub guild_id: i64,
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug)]
|
||||
pub struct GuildPlaylist {
|
||||
pub guild_id: i64,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "guild_playlists"]
|
||||
pub struct GuildPlaylistInsert {
|
||||
pub guild_id: i64,
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Clone)]
|
||||
pub struct Media {
|
||||
pub id: i64,
|
||||
pub category: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "media"]
|
||||
pub struct MediaInsert {
|
||||
pub category: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "statistics"]
|
||||
pub struct StatisticInsert {
|
||||
pub version: String,
|
||||
pub command: String,
|
||||
pub executed_at: SystemTime,
|
||||
pub success: bool,
|
||||
pub error_msg: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Clone)]
|
||||
pub struct YoutubeSong {
|
||||
pub id: i64,
|
||||
pub spotify_id: String,
|
||||
pub artist: String,
|
||||
pub title: String,
|
||||
pub album: String,
|
||||
pub url: String,
|
||||
pub score: i32,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "youtube_songs"]
|
||||
pub struct YoutubeSongInsert {
|
||||
pub spotify_id: String,
|
||||
pub artist: String,
|
||||
pub title: String,
|
||||
pub album: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Debug, Clone)]
|
||||
pub struct EphemeralMessage {
|
||||
pub channel_id: i64,
|
||||
pub message_id: i64,
|
||||
pub timeout: SystemTime,
|
||||
}
|
||||
|
||||
#[derive(Insertable, Debug)]
|
||||
#[table_name = "ephemeral_messages"]
|
||||
pub struct EphemeralMessageInsert {
|
||||
pub channel_id: i64,
|
||||
pub message_id: i64,
|
||||
pub timeout: SystemTime,
|
||||
}
|
||||
use super::entity;
|
||||
|
||||
pub use entity::ephemeral_messages::Model as EphemeralMessage;
|
||||
pub use entity::guild_playlists::Model as GuildPlaylist;
|
||||
pub use entity::guild_settings::Model as GuildSetting;
|
||||
pub use entity::media::Model as Media;
|
||||
pub use entity::statistics::Model as Statistic;
|
||||
pub use entity::youtube_songs::Model as YoutubeSong;
|
||||
|
@ -1,64 +0,0 @@
|
||||
table! {
|
||||
ephemeral_messages (channel_id, message_id) {
|
||||
channel_id -> Int8,
|
||||
message_id -> Int8,
|
||||
timeout -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
guild_playlists (guild_id, name) {
|
||||
guild_id -> Int8,
|
||||
name -> Varchar,
|
||||
url -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
guild_settings (guild_id, key) {
|
||||
guild_id -> Int8,
|
||||
key -> Varchar,
|
||||
value -> Nullable<Varchar>,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
media (id) {
|
||||
id -> Int8,
|
||||
category -> Nullable<Varchar>,
|
||||
name -> Nullable<Varchar>,
|
||||
url -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
statistics (id) {
|
||||
id -> Int8,
|
||||
version -> Varchar,
|
||||
command -> Varchar,
|
||||
executed_at -> Timestamp,
|
||||
success -> Bool,
|
||||
error_msg -> Nullable<Text>,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
youtube_songs (id) {
|
||||
id -> Int8,
|
||||
spotify_id -> Varchar,
|
||||
artist -> Varchar,
|
||||
title -> Varchar,
|
||||
album -> Varchar,
|
||||
url -> Varchar,
|
||||
score -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
allow_tables_to_appear_in_same_query!(
|
||||
ephemeral_messages,
|
||||
guild_playlists,
|
||||
guild_settings,
|
||||
media,
|
||||
statistics,
|
||||
youtube_songs,
|
||||
);
|
@ -1,40 +0,0 @@
|
||||
use serenity::client::Context;
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::CommandResult;
|
||||
use serenity::model::channel::Message;
|
||||
|
||||
use crate::commands::common::handle_autodelete;
|
||||
use crate::providers::music::lavalink::Lavalink;
|
||||
use crate::utils::initialize_lavalink;
|
||||
use serenity_rich_interaction::core::SHORT_TIMEOUT;
|
||||
use serenity_rich_interaction::ephemeral_message::EphemeralMessage;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[command]
|
||||
#[description("Resets the lavalink connection")]
|
||||
#[aliases("reconnect_lavalink", "reset-lavalink", "reconnect-lavalink")]
|
||||
#[num_args(0)]
|
||||
#[owners_only]
|
||||
async fn reset_lavalink(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let app_info = ctx.http.get_current_application_info().await?;
|
||||
destroy_lavalink(ctx).await;
|
||||
|
||||
initialize_lavalink(Arc::clone(&ctx.data), app_info).await?;
|
||||
|
||||
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {
|
||||
m.content("Reconnected to lavalink")
|
||||
})
|
||||
.await?;
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn destroy_lavalink(ctx: &Context) {
|
||||
let mut data = ctx.data.write().await;
|
||||
{
|
||||
let lava_client = data.remove::<Lavalink>().unwrap();
|
||||
mem::drop(lava_client);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::{Args, CommandError, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::handle_autodelete;
|
||||
use crate::commands::music::{get_music_player_for_guild, DJ_CHECK};
|
||||
use crate::messages::music::no_voicechannel::create_no_voicechannel_message;
|
||||
use serenity_rich_interaction::core::{MEDIUM_TIMEOUT, SHORT_TIMEOUT};
|
||||
use serenity_rich_interaction::ephemeral_message::EphemeralMessage;
|
||||
|
||||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[description("Loads an equalizer preset")]
|
||||
#[usage("<preset>")]
|
||||
#[num_args(1)]
|
||||
#[example("bass")]
|
||||
#[bucket("general")]
|
||||
#[checks(DJ)]
|
||||
async fn equalize(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||
tracing::debug!("Changing equalizer for {}", guild.id);
|
||||
let preset = args.single::<String>().unwrap();
|
||||
|
||||
let player = if let Some(player) = get_music_player_for_guild(ctx, guild.id).await {
|
||||
player
|
||||
} else {
|
||||
return create_no_voicechannel_message(&ctx.http, msg.channel_id)
|
||||
.await
|
||||
.map_err(CommandError::from);
|
||||
};
|
||||
|
||||
let bands = match preset.to_lowercase().as_str() {
|
||||
"metal" => lavalink_rs::EQ_METAL,
|
||||
"boost" => lavalink_rs::EQ_BOOST,
|
||||
"base" => lavalink_rs::EQ_BASE,
|
||||
"piano" => lavalink_rs::EQ_PIANO,
|
||||
_ => {
|
||||
EphemeralMessage::create(&ctx.http, msg.channel_id, MEDIUM_TIMEOUT, |m| {
|
||||
m.content(format!(
|
||||
"Unknown preset '{}'. Available are 'metal', 'boost', 'base' and 'piano'",
|
||||
preset
|
||||
))
|
||||
})
|
||||
.await?;
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
{
|
||||
let mut player = player.lock().await;
|
||||
player.equalize_all(bands).await?;
|
||||
}
|
||||
EphemeralMessage::create(&ctx.http, msg.channel_id, SHORT_TIMEOUT, |m| {
|
||||
m.content(format!("🎛️ Changed equalizer to '{}'", preset))
|
||||
})
|
||||
.await?;
|
||||
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
use serenity::framework::standard::macros::command;
|
||||
use serenity::framework::standard::{CommandError, CommandResult};
|
||||
use serenity::model::channel::Message;
|
||||
use serenity::prelude::*;
|
||||
|
||||
use crate::commands::common::handle_autodelete;
|
||||
use crate::commands::music::{get_music_player_for_guild, DJ_CHECK};
|
||||
use crate::messages::music::equalizer::create_equalizer_message;
|
||||
use crate::messages::music::no_voicechannel::create_no_voicechannel_message;
|
||||
|
||||
#[command]
|
||||
#[only_in(guilds)]
|
||||
#[description("Displays the equalizer for the music player")]
|
||||
#[usage("")]
|
||||
#[bucket("general")]
|
||||
#[checks(DJ)]
|
||||
async fn equalizer(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||
tracing::debug!("Displaying equalizer for guild {}", guild.id);
|
||||
|
||||
let player = if let Some(player) = get_music_player_for_guild(ctx, guild.id).await {
|
||||
player
|
||||
} else {
|
||||
return create_no_voicechannel_message(&ctx.http, msg.channel_id)
|
||||
.await
|
||||
.map_err(CommandError::from);
|
||||
};
|
||||
|
||||
create_equalizer_message(&ctx, msg.channel_id, player).await?;
|
||||
handle_autodelete(ctx, msg).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
pub mod equalizer;
|
||||
pub mod no_voicechannel;
|
||||
pub mod now_playing;
|
||||
pub mod queue;
|
||||
|
@ -1,53 +0,0 @@
|
||||
use crate::utils::context_data::MusicPlayers;
|
||||
use lavalink_rs::gateway::LavalinkEventHandler;
|
||||
use lavalink_rs::model::{PlayerUpdate, Stats, TrackFinish, TrackStart};
|
||||
use lavalink_rs::LavalinkClient;
|
||||
use serenity::async_trait;
|
||||
use serenity::prelude::TypeMapKey;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use typemap_rev::TypeMap;
|
||||
|
||||
pub struct LavalinkHandler {
|
||||
pub data: Arc<RwLock<TypeMap>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl LavalinkEventHandler for LavalinkHandler {
|
||||
async fn track_start(&self, _client: LavalinkClient, event: TrackStart) {
|
||||
tracing::info!("Track started!\nGuild: {}", event.guild_id);
|
||||
}
|
||||
|
||||
async fn track_finish(&self, _: LavalinkClient, event: TrackFinish) {
|
||||
tracing::info!("Track finished!\nGuild: {}", event.guild_id);
|
||||
let player = {
|
||||
let data = self.data.read().await;
|
||||
let players = data.get::<MusicPlayers>().unwrap();
|
||||
|
||||
players.get(&event.guild_id.0).cloned()
|
||||
};
|
||||
if let Some(player) = player {
|
||||
let mut player = player.lock().await;
|
||||
if let Err(e) = player.play_next().await {
|
||||
tracing::error!("Failed to play next song: {:?}", e);
|
||||
}
|
||||
if let Err(e) = player.update_now_playing().await {
|
||||
tracing::error!("Failed to update now playing embed: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn player_update(&self, _: LavalinkClient, event: PlayerUpdate) {
|
||||
tracing::debug!("Received player update event: {:?}", event);
|
||||
}
|
||||
|
||||
async fn stats(&self, _: LavalinkClient, event: Stats) {
|
||||
tracing::debug!("Received stats event: {:?}", event);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Lavalink;
|
||||
|
||||
impl TypeMapKey for Lavalink {
|
||||
type Value = Arc<LavalinkClient>;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue