Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63e4d85cbb
|
||
|
|
d79713eae9
|
||
|
|
cfb6930ccc
|
||
|
|
6250ba601f | ||
|
|
0bc97f89fd | ||
|
|
ec34590cf7 |
No files matched your search
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"warnOnUnsupportedTypeScriptVersion": false,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"env": {
|
||||
"browser": false,
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
|
||||
"plugins": ["@typescript-eslint", "import", "simple-import-sort"],
|
||||
"ignorePatterns": ["**/node_modules/**", "/dist/**", "/tests/**"],
|
||||
"rules": {
|
||||
"curly": ["error", "all"],
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error"
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20.x]
|
||||
pnpm-version: [8]
|
||||
node-version: [22.x]
|
||||
pnpm-version: [9]
|
||||
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
@@ -35,11 +35,6 @@ jobs:
|
||||
- name: ESLint & Prettier
|
||||
run: pnpm run lint
|
||||
|
||||
- name: Prisma Migration
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
run: pnpm exec prisma migrate deploy
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
@@ -54,6 +49,12 @@ jobs:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||
with:
|
||||
@@ -65,7 +66,7 @@ jobs:
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
unknowableshade/quetza
|
||||
deytenit/quetza
|
||||
# generate Docker tags based on the following events/attributes
|
||||
# on tag event: tag using git tag, and as latest if the tag doesn't contain hyphens (pre-releases)
|
||||
# on push event: tag using git sha, branch name and as latest-dev
|
||||
@@ -82,5 +83,6 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Privacy Policy of Quetza
|
||||
|
||||
This privacy policy applies to the Discord bot Quetza (hereby referred to as "Quetza")
|
||||
that was created by Vladimir Eremin (hereby referred to as "Service Provider")
|
||||
as an Open Source service.
|
||||
|
||||
Quetza is intended for use "AS IS",
|
||||
in compliance with [Discord Privacy Policy](https://discord.com/privacy).
|
||||
|
||||
## What information does Quetza store and how is it used?
|
||||
|
||||
Quetza does not store any information.
|
||||
|
||||
## Do third parties see and/or have access to information obtained by the Quetza?
|
||||
|
||||
Since Quetza does not store any information, no data is shared with third parties.
|
||||
|
||||
## Changes
|
||||
|
||||
This Privacy Policy may be updated from time to time for any reason.
|
||||
The Service Provider will notify you of any changes to their Privacy Policy
|
||||
by updating this page with the new Privacy Policy.
|
||||
You are advised to consult this Privacy Policy regularly for any changes,
|
||||
as continued use is deemed approval of all changes.
|
||||
|
||||
_This privacy policy is effective as of 2024-11-08_
|
||||
|
||||
## Your Consent
|
||||
|
||||
By using Quetza, you are consenting to the processing of your information
|
||||
as set forth in this Privacy Policy now and as amended by the Service Provider.
|
||||
|
||||
## Contact Us
|
||||
|
||||
If you have any questions regarding privacy while using Quetza, or have questions
|
||||
about the practices, please contact the Service Provider via email at [personal@ermnvldmr.com](mailto:personal@ermnvldmr.com).
|
||||
@@ -0,0 +1,44 @@
|
||||
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
||||
import globals from "globals";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import js from "@eslint/js";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all
|
||||
});
|
||||
|
||||
export default [
|
||||
{ ignores: ["**/node_modules/**/*", "dist/**/*", "tests/**/*"] },
|
||||
...compat.extends("eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"),
|
||||
{
|
||||
plugins: {
|
||||
"@typescript-eslint": typescriptEslint
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...Object.fromEntries(Object.entries(globals.browser).map(([key]) => [key, "off"])),
|
||||
...globals.node
|
||||
},
|
||||
|
||||
parser: tsParser,
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
|
||||
parserOptions: {
|
||||
warnOnUnsupportedTypeScriptVersion: false
|
||||
}
|
||||
},
|
||||
|
||||
rules: {
|
||||
curly: ["error", "all"]
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -4,8 +4,6 @@
|
||||
* Replies module listing as well as description of each.
|
||||
*
|
||||
* Just for the information I guess...
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
* Replies websocket ping (ping between bot and discord) and real ping (ping to fetch + process).
|
||||
*
|
||||
* @remarks Probably should double their value as two ways, but nvm.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
* Resolves creation of an interaction by users.
|
||||
*
|
||||
* @remark Only {@link ChatInputCommand} currently being resolved.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import { Events, Interaction } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
*
|
||||
* @remarks Will push slash commands, set activity status,
|
||||
* and log bot's initials.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import { generateDependencyReport } from "@discordjs/voice";
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
* There a lot of speaking because it's as important as $lib.
|
||||
*
|
||||
* @packageDocumentation
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
const name = "core";
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
/**
|
||||
* /clear
|
||||
*
|
||||
* Clears Player queue entirely.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with amount of tracks deleted.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction): Promise<void> {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
/**
|
||||
* /connect
|
||||
*
|
||||
* Connects bot to the voice channel.
|
||||
*
|
||||
* Just like play but without query.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with Voice Channel bot connected to.
|
||||
* - Requester does not connected to the Voice Channel.
|
||||
*
|
||||
* @deprecated Does not make sense.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction): Promise<void> {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
/**
|
||||
* /filter <filter id>
|
||||
*
|
||||
* Toggles filter that will be applied to the playback.
|
||||
* Such as nightcore, etc.
|
||||
*
|
||||
* If no filter id was provided clears them all.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with chosen filter status or filters being cleared.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import Filter from "../lib/filter.js";
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
@@ -36,7 +53,7 @@ const data = new SlashCommandBuilder()
|
||||
option
|
||||
.setName("filter")
|
||||
.setDescription("Filter to apply.")
|
||||
.setChoices(...Object.values(Filter.FILTERS))
|
||||
.setChoices(...Filter.filterChoices())
|
||||
)
|
||||
.setDMPermission(false);
|
||||
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
/**
|
||||
* /info
|
||||
*
|
||||
* Replies with very stylish player info card.
|
||||
*
|
||||
* Playback status bar with title, thumbnail and duration.
|
||||
* Queue length and duration.
|
||||
* Applied filters.
|
||||
* Current loop option.
|
||||
* Player lifetime.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with info card.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
/**
|
||||
* /insert (query) (position)
|
||||
*
|
||||
* Inserts specified track/album to the position specified.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with first added track info.
|
||||
* - Player does not exists.
|
||||
* - No track was added.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
/**
|
||||
* /jump (query)
|
||||
*
|
||||
* Jumps to the specified Track from the queue.
|
||||
* If number was provided - resolves as position at where queue position should be set.
|
||||
* If string was provided - jumps to the most similar if terms of {@link ../lib/misc#LargestCommonSequence} Track title.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with selected track data.
|
||||
* - Such track does not exists, though cannot be jumped to.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
/**
|
||||
* /loop (option)
|
||||
*
|
||||
* Changes loop option.
|
||||
*
|
||||
* @remarks
|
||||
* @see {@link ../lib/types} for LoopOption definition.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with new loop option.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { LoopOption } from "../lib/types.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
/**
|
||||
* /next
|
||||
*
|
||||
* Skips current track.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with confirmation of skip. (even there is nothing to skip)
|
||||
* - Player does not exists.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
/**
|
||||
* /pause
|
||||
*
|
||||
* Toggles playback pause.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with setted state (paused, resumed).
|
||||
* - Player does not exists.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
/**
|
||||
* /play <query>
|
||||
*
|
||||
* Starts up the Player.
|
||||
* If query provided searches corresponding track/album and adds it to the queue end.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with first added track info.
|
||||
* - Denies if requester is not connected to the Voice Channel.
|
||||
* - No track was added, but player was set.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/**
|
||||
* /queue
|
||||
*
|
||||
* Replies interactive queue with current playing track at the top and 10 tracks from queue on each page.
|
||||
* Interactiveness provided by buttons:
|
||||
* - First page.
|
||||
* - Previous page.
|
||||
* - Next page.
|
||||
* - Last page.
|
||||
*
|
||||
* Buttons live up to 30 seconds.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with interactive queue.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import {
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
@@ -10,11 +27,15 @@ import {
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
/**
|
||||
* /remove (query)
|
||||
*
|
||||
* Removes Track from the queue.
|
||||
* If number was provided - resolves as position at where deletion should occurr.
|
||||
* If string was provided - removes most similar if terms of {@link ../lib/misc#LargestCommonSequence} Track title.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with removed track data.
|
||||
* - Such track does not exists, though cannot be removed.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
/**
|
||||
* /reshuffle
|
||||
* Shuffles the queue, so real order is changed.
|
||||
* DO NOT Confuse it with AUTO LoopOption.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with queue being reshuffled.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,31 @@
|
||||
/**
|
||||
* /seek <hrs> <mins> <secs>
|
||||
*
|
||||
* Changes current Track playback duration to value given.
|
||||
*
|
||||
* @remarks
|
||||
* If not stated - default value for all imputs is 0.
|
||||
* Input resolution is defined by FFmpeg.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with previous and new playback duration.
|
||||
* - Player does not exists.
|
||||
* - No resource is currently playing.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
/**
|
||||
* /stop
|
||||
*
|
||||
* Destroys player of the Guild where it was emitted.
|
||||
* Also disconnects user from Voice Channel Quetza was in.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with player being destroyed.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
|
||||
@@ -1,19 +1,34 @@
|
||||
/**
|
||||
* /volume (amount)
|
||||
*
|
||||
* Sets volume of {@link ../lib/player#Player | Player} in percent scale,
|
||||
* clamping it in range defined in Player.
|
||||
*
|
||||
* Possible replies:
|
||||
* - Success with new volume value.
|
||||
* - Player does not exists.
|
||||
*/
|
||||
|
||||
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
import Client from "$lib/client.js";
|
||||
import logger from "$lib/logger.js";
|
||||
import Music from "$mlib/music.js";
|
||||
|
||||
import replies from "../lib/replies.js";
|
||||
import { controller } from "../module.js";
|
||||
|
||||
async function execute(client: Client, interaction: ChatInputCommandInteraction) {
|
||||
async function execute(
|
||||
_: Client,
|
||||
interaction: ChatInputCommandInteraction,
|
||||
controller: Music
|
||||
): Promise<void> {
|
||||
if (!interaction.isChatInputCommand() || !interaction.inCachedGuild() || !interaction.channel) {
|
||||
logger.warn("Interaction rejected.", { interaction });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const volume = interaction.options.getInteger("volume") ?? 100;
|
||||
const volume = interaction.options.getInteger("volume", true);
|
||||
|
||||
const player = controller.get(interaction.guild, interaction.channel);
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
*
|
||||
* Monitors voice states of attended guilds.
|
||||
* If Quetza happens to be alone in the Voice Channel - destroys guilds player and disconnects.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import { BaseGuildVoiceChannel, User, VoiceState } from "discord.js";
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/**
|
||||
* @see ../../../src/lib/error.ts
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import QuetzaError from "$lib/error.js";
|
||||
|
||||
@@ -52,6 +52,18 @@ export default class Filter {
|
||||
*/
|
||||
private switches_ = new Map<filterPreset, filterValue>();
|
||||
|
||||
/**
|
||||
* Returns filters as Discord API Choices compatible array.
|
||||
*
|
||||
* @returns {@link Filter#FILTERS} as { name: FILTERS[key].name, value: key }.
|
||||
*/
|
||||
public static filterChoices(): { name: string; value: string }[] {
|
||||
return Object.entries(Filter.FILTERS).map(([key, value]) => ({
|
||||
name: value.name,
|
||||
value: key
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts active {@link filterValue | filterValues} to array.
|
||||
*
|
||||
@@ -101,9 +113,9 @@ export default class Filter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts active filters to FFmpeg compatable argument.
|
||||
* Converts active filters to FFmpeg compatible argument.
|
||||
*
|
||||
* @returns FFmpeg compatable argument representing active filters.
|
||||
* @returns FFmpeg compatible argument representing active filters.
|
||||
*/
|
||||
public toString(): string {
|
||||
return this.toggled()
|
||||
|
||||
+21
-18
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "quetza",
|
||||
"version": "2024.3.0",
|
||||
"version": "2024.11.0",
|
||||
"description": "Awesome Discord bot that performs various duties",
|
||||
"type": "module",
|
||||
"main": "./dist/src/index.js",
|
||||
@@ -15,7 +15,7 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/unknowableshade/Quetza.git"
|
||||
"url": "git+https://github.com/deytenit/Quetza.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Vladimir Eremin",
|
||||
@@ -23,32 +23,35 @@
|
||||
"url": "https://ermnvldmr.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/unknowableshade/Quetza/issues"
|
||||
"url": "https://github.com/deytenit/Quetza/issues"
|
||||
},
|
||||
"readme": "https://github.com/unknowableshade/Quetza#readme",
|
||||
"readme": "https://github.com/deytenit/Quetza#readme",
|
||||
"engines": {
|
||||
"node": "20.x.x",
|
||||
"node": "22.x.x",
|
||||
"npm": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordjs/opus": "^0.9.0",
|
||||
"@discordjs/voice": "^0.16.1",
|
||||
"discord.js": "^14.14.1",
|
||||
"@discordjs/voice": "^0.17.0",
|
||||
"discord.js": "^14.16.3",
|
||||
"prism-media": "^1.3.5",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"winston": "^3.11.0"
|
||||
"winston": "^3.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.24",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"eslint": "^8.57.0",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.14.0",
|
||||
"@types/node": "^22.9.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.13.0",
|
||||
"@typescript-eslint/parser": "^8.13.0",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-simple-import-sort": "^12.0.0",
|
||||
"mocha": "^10.3.0",
|
||||
"prettier": "^3.2.5",
|
||||
"tsc-alias": "^1.8.8",
|
||||
"typescript": "^5.3.3"
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"globals": "^15.12.0",
|
||||
"mocha": "^10.8.2",
|
||||
"prettier": "^3.3.3",
|
||||
"tsc-alias": "^1.8.10",
|
||||
"typescript": "^5.6.3"
|
||||
}
|
||||
}
|
||||
Generated
+2496
-1999
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p .git/hooks
|
||||
|
||||
HOOK_CONTENT="#!/bin/sh
|
||||
pnpm run lint
|
||||
if [ \$? -ne 0 ]; then
|
||||
echo 'Pre-commit hook failed. Please fix the issues and commit again.'
|
||||
exit 1
|
||||
fi
|
||||
"
|
||||
|
||||
echo "$HOOK_CONTENT" > .git/hooks/pre-commit
|
||||
|
||||
chmod +x .git/hooks/pre-commit
|
||||
|
||||
echo "Pre-commit hook installed successfully!"
|
||||
Reference in new issue
Block a user