2025-01-18 21:45:25 -05:00
|
|
|
import discord
|
|
|
|
from discord import app_commands
|
2025-01-28 09:22:02 -05:00
|
|
|
import subprocess
|
|
|
|
import os
|
|
|
|
import sys
|
2025-01-20 10:35:28 -05:00
|
|
|
from audio import (
|
|
|
|
play_audio,
|
|
|
|
stop_audio,
|
|
|
|
set_volume,
|
|
|
|
join_voice,
|
|
|
|
leave_voice,
|
|
|
|
pause_audio,
|
|
|
|
resume_audio,
|
|
|
|
repeat_modes,
|
2025-01-27 17:34:47 -05:00
|
|
|
_247_mode,
|
2025-01-27 17:35:55 -05:00
|
|
|
generate_recommendations
|
|
|
|
)
|
2025-01-18 21:45:25 -05:00
|
|
|
|
|
|
|
|
2025-01-27 17:35:55 -05:00
|
|
|
async def setup_commands(client, guild_id=None):
|
2025-01-19 22:29:16 -05:00
|
|
|
@client.tree.command(name="join", description="Join the user's current voice channel.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def join(interaction: discord.Interaction):
|
2025-01-18 21:45:25 -05:00
|
|
|
await join_voice(interaction)
|
|
|
|
|
2025-01-19 22:29:16 -05:00
|
|
|
@client.tree.command(name="leave", description="Leave the current voice channel.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def leave(interaction: discord.Interaction):
|
2025-01-18 21:45:25 -05:00
|
|
|
await leave_voice(interaction)
|
|
|
|
|
2025-01-19 22:29:16 -05:00
|
|
|
@client.tree.command(name="play", description="Play a song by title or artist.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def play(interaction: discord.Interaction, query: str):
|
2025-01-18 21:45:25 -05:00
|
|
|
await play_audio(interaction, query)
|
|
|
|
|
2025-01-19 22:29:16 -05:00
|
|
|
@client.tree.command(name="stop", description="Stop playback and clear the queue.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def stop(interaction: discord.Interaction):
|
2025-01-19 22:29:16 -05:00
|
|
|
await stop_audio(interaction)
|
|
|
|
|
2025-01-19 23:19:16 -05:00
|
|
|
@client.tree.command(name="pause", description="Pause the current song.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def pause(interaction: discord.Interaction):
|
2025-01-19 23:19:16 -05:00
|
|
|
await pause_audio(interaction)
|
|
|
|
|
|
|
|
@client.tree.command(name="resume", description="Resume the paused song.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def resume(interaction: discord.Interaction):
|
2025-01-19 23:19:16 -05:00
|
|
|
await resume_audio(interaction)
|
|
|
|
|
2025-01-20 10:35:28 -05:00
|
|
|
@client.tree.command(name="repeat", description="Set the repeat mode for playback.")
|
|
|
|
@app_commands.describe(mode="Repeat mode: 'one', 'all', or 'off'")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def repeat(interaction: discord.Interaction, mode: str):
|
2025-01-20 10:35:28 -05:00
|
|
|
guild_id = interaction.guild.id
|
|
|
|
valid_modes = ["one", "all", "off"]
|
|
|
|
|
|
|
|
if mode not in valid_modes:
|
|
|
|
await interaction.response.send_message(f"❌ **Invalid mode. Use one of: {', '.join(valid_modes)}.**")
|
|
|
|
return
|
|
|
|
|
|
|
|
repeat_modes[guild_id] = mode
|
|
|
|
await interaction.response.send_message(f"🔄 **Repeat mode set to:** {mode.capitalize()}.")
|
2025-01-19 23:19:16 -05:00
|
|
|
|
2025-01-19 22:29:16 -05:00
|
|
|
@client.tree.command(name="volume", description="Set playback volume.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def volume(interaction: discord.Interaction, level: int):
|
2025-01-19 22:29:16 -05:00
|
|
|
await set_volume(interaction, level)
|
|
|
|
|
2025-01-27 17:34:47 -05:00
|
|
|
@client.tree.command(name="247", description="Enable or disable 24/7 mode.")
|
|
|
|
@app_commands.describe(mode="on/off")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def _247(interaction: discord.Interaction, mode: str):
|
2025-01-27 17:34:47 -05:00
|
|
|
guild_id = interaction.guild.id
|
|
|
|
if mode.lower() == "on":
|
|
|
|
_247_mode[guild_id] = True
|
|
|
|
await interaction.response.send_message("✅ **24/7 mode enabled. Amber will stay in the voice channel even when idle.**")
|
|
|
|
elif mode.lower() == "off":
|
|
|
|
_247_mode[guild_id] = False
|
|
|
|
await interaction.response.send_message("✅ **24/7 mode disabled. Amber will leave the voice channel when idle.**")
|
|
|
|
else:
|
|
|
|
await interaction.response.send_message("❌ **Invalid mode. Use 'on' or 'off'.**")
|
|
|
|
|
2025-01-19 23:19:16 -05:00
|
|
|
@client.tree.command(name="recommend", description="Get song recommendations based on your listening history.")
|
2025-01-27 17:35:55 -05:00
|
|
|
async def recommend(interaction: discord.Interaction):
|
2025-01-19 23:19:16 -05:00
|
|
|
user_id = interaction.user.id
|
|
|
|
recommendations = generate_recommendations(user_id)
|
|
|
|
|
|
|
|
embed = discord.Embed(
|
|
|
|
title="🎵 Recommended Songs",
|
|
|
|
description="\n".join(recommendations),
|
|
|
|
color=discord.Color.green()
|
|
|
|
)
|
|
|
|
await interaction.response.send_message(embed=embed)
|
|
|
|
|
2025-01-28 09:22:02 -05:00
|
|
|
@client.tree.command(name="check_update", description="Check if Quartessa has updates.")
|
|
|
|
async def check_update(interaction: discord.Interaction):
|
|
|
|
"""Check for updates and notify the token owner via DM."""
|
|
|
|
owner = (await client.application_info()).owner
|
|
|
|
|
|
|
|
try:
|
|
|
|
# Defer the interaction
|
|
|
|
await interaction.response.defer()
|
|
|
|
|
|
|
|
# Run git fetch to check for updates without pulling
|
|
|
|
subprocess.run(["git", "fetch"], check=True)
|
|
|
|
local_commit = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("utf-8").strip()
|
|
|
|
remote_commit = subprocess.check_output(["git", "rev-parse", "@{u}"]).decode("utf-8").strip()
|
|
|
|
|
|
|
|
if local_commit == remote_commit:
|
|
|
|
# No updates available
|
|
|
|
await interaction.followup.send("✅ **Quartessa is up to date.**")
|
|
|
|
else:
|
|
|
|
# Notify the token owner via DM
|
|
|
|
update_message = (
|
|
|
|
"🔄 **Quartessa has updates available!**\n\n"
|
|
|
|
f"Local Commit: `{local_commit}`\n"
|
|
|
|
f"Remote Commit: `{remote_commit}`\n\n"
|
|
|
|
"To update Quartessa, you can:\n"
|
|
|
|
"1. Run the `/update` command.\n"
|
|
|
|
"2. Reinstall or restart the bot.\n"
|
|
|
|
"3. Pull the latest changes manually using Git."
|
|
|
|
)
|
|
|
|
try:
|
|
|
|
await owner.send(update_message)
|
|
|
|
await interaction.followup.send("📩 **Update notification sent to the bot owner via DM.**")
|
|
|
|
except discord.Forbidden:
|
|
|
|
await interaction.followup.send(
|
|
|
|
"⚠️ **Quartessa has updates available, but I couldn't DM the owner.**\n"
|
|
|
|
f"Local Commit: `{local_commit}`\nRemote Commit: `{remote_commit}`"
|
|
|
|
)
|
|
|
|
except Exception as e:
|
|
|
|
await interaction.followup.send(f"⚠️ **Error checking for updates:** {e}")
|
|
|
|
|
|
|
|
@client.tree.command(name="update", description="Pull updates and restart Quartessa.")
|
|
|
|
async def update(interaction: discord.Interaction):
|
|
|
|
"""Manually check for updates, apply them, and restart the bot."""
|
|
|
|
owner = (await client.application_info()).owner
|
|
|
|
|
|
|
|
try:
|
|
|
|
# Defer response
|
|
|
|
await interaction.response.defer()
|
|
|
|
|
|
|
|
# Pull updates from the repository
|
|
|
|
result = subprocess.run(["git", "pull"], capture_output=True, text=True)
|
|
|
|
if "Already up to date." in result.stdout:
|
|
|
|
await interaction.followup.send("✅ **Quartessa is already up to date.**")
|
|
|
|
else:
|
|
|
|
# Notify the owner and restart the bot
|
|
|
|
commit_hash = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("utf-8").strip()
|
|
|
|
update_message = (
|
|
|
|
f"🔄 **Quartessa updated to the latest version:** `{commit_hash}`\n\n"
|
|
|
|
"Restarting to apply changes..."
|
|
|
|
)
|
|
|
|
await owner.send(update_message)
|
|
|
|
await interaction.followup.send("🔄 **Updates applied. Restarting Quartessa...**")
|
|
|
|
os.execv(sys.executable, ['python'] + sys.argv)
|
|
|
|
except Exception as e:
|
|
|
|
await interaction.followup.send(f"⚠️ **Error while updating Quartessa:** {e}")
|
|
|
|
|
2025-01-18 21:45:25 -05:00
|
|
|
await client.tree.sync()
|