Skip to content

Instantly share code, notes, and snippets.

@NNKTV28
Last active December 5, 2023 21:13
Show Gist options
  • Save NNKTV28/6bb7bcf444939b268bc5aed4cc7a9d72 to your computer and use it in GitHub Desktop.
Save NNKTV28/6bb7bcf444939b268bc5aed4cc7a9d72 to your computer and use it in GitHub Desktop.
import os
import re
import time
import discord
import sqlite3
import lavalink
import itertools
from lavalink import Client
from dotenv import load_dotenv
from discord.ext import commands
from lavalink.filters import LowPass
con = sqlite3.connect("AngelMusic.db")
cur = con.cursor()
url_rx = re.compile(r'https?://(?:www\.)?.+')
load_dotenv()
class List_playlists(commands.Cog):
def __init__(self, bot, cur, con):
self.bot = bot
self.cur = cur
self.con = con
class LavalinkVoiceClient(discord.VoiceClient):
"""
This is the preferred way to handle external voice sending
This client will be created via a cls in the connect method of the channel
see the following documentation:
https://discordpy.readthedocs.io/en/latest/api.html#voiceprotocol
"""
def __init__(self, client: discord.Client, channel: discord.abc.Connectable):
self.client = client
self.channel = channel
# ensure a client already exists
if hasattr(self.client, 'lavalink'):
self.lavalink = self.client.lavalink
else:
self.client.lavalink = lavalink.Client(client.user.id)
self.client.lavalink.add_node(
'localhost',
2333,
'youshallnotpass',
'us',
'default-node'
)
self.lavalink = self.client.lavalink
async def on_voice_server_update(self, data):
# the data needs to be transformed before being handed down to
# voice_update_handler
lavalink_data = {
't': 'VOICE_SERVER_UPDATE',
'd': data
}
await self.lavalink.voice_update_handler(lavalink_data)
async def on_voice_state_update(self, data):
# the data needs to be transformed before being handed down to
# voice_update_handler
lavalink_data = {
't': 'VOICE_STATE_UPDATE',
'd': data
}
await self.lavalink.voice_update_handler(lavalink_data)
async def connect(self, *, timeout: float, reconnect: bool, self_deaf: bool = False, self_mute: bool = False) -> None:
"""
Connect the bot to the voice channel and create a player_manager
if it doesn't exist yet.
"""
# ensure there is a player_manager when creating a new voice_client
self.lavalink.player_manager.create(guild_id=self.channel.guild.id)
await self.channel.guild.change_voice_state(channel=self.channel, self_mute=self_mute, self_deaf=self_deaf)
async def disconnect(self, *, force: bool = False) -> None:
"""
Handles the disconnect.
Cleans up running player and leaves the voice client.
"""
player = self.lavalink.player_manager.get(self.channel.guild.id)
# no need to disconnect if we are not connected
if not force and not player.is_connected:
return
# None means disconnect
await self.channel.guild.change_voice_state(channel=None)
# update the channel_id of the player to None
# this must be done because the on_voice_state_update that would set channel_id
# to None doesn't get dispatched after the disconnect
player.channel_id = None
self.cleanup()
class Music_commands(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.cur = cur
self.con = con
if not hasattr(bot, 'lavalink'): # This ensures the client isn't overwritten during cog reloads.
bot.lavalink = lavalink.Client(bot.user.id)
bot.lavalink.add_node('lava1.horizxon.studio', 80, 'horizxon.studio', 'eu', 'default-node') # Host, Port, Password, Region, Name
lavalink.add_event_hook(self.track_hook)
def cog_unload(self):
""" Cog unload handler. This removes any event hooks that were registered. """
self.bot.lavalink._event_hooks.clear()
async def cog_command_error(self, ctx, error):
if isinstance(error, commands.CommandInvokeError):
await ctx.send(error.original)
# The above handles errors thrown in this cog and shows them to the user.
# This shouldn't be a problem as the only errors thrown in this cog are from `ensure_voice`
# which contain a reason string, such as "Join a voicechannel" etc. You can modify the above
# if you want to do things differently.
async def ensure_voice(ctx):
""" This check ensures that the bot and command author are in the same voicechannel. """
player = ctx.bot.lavalink.player_manager.create(ctx.guild.id)
# Create returns a player if one exists, otherwise creates.
# This line is important because it ensures that a player always exists for a guild.
# Most people might consider this a waste of resources for guilds that aren't playing, but this is
# the easiest and simplest way of ensuring players are created.
# These are commands that require the bot to join a voicechannel (i.e. initiating playback).
# Commands such as volume/skip etc don't require the bot to be in a voicechannel so don't need listing here.
should_connect = ctx.command.name in ('Play', 'play_playlist')
if not ctx.author.voice or not ctx.author.voice.channel:
# Our cog_command_error handler catches this and sends it to the voicechannel.
# Exceptions allow us to "short-circuit" command invocation via checks so the
# execution state of the command goes no further.
raise commands.CommandInvokeError('Join a voicechannel first.')
v_client = ctx.voice_client
if not v_client:
if not should_connect:
raise commands.CommandInvokeError('Not connected.')
permissions = ctx.author.voice.channel.permissions_for(ctx.me)
if not permissions.connect or not permissions.speak: # Check user limit too?
raise commands.CommandInvokeError('I need the `CONNECT` and `SPEAK` permissions.')
player.store('channel', ctx.channel.id)
await ctx.author.voice.channel.connect(cls=LavalinkVoiceClient)
else:
if v_client.channel.id != ctx.author.voice.channel.id:
raise commands.CommandInvokeError('You need to be in my voicechannel.')
async def track_hook(self, event):
if isinstance(event, lavalink.events.QueueEndEvent):
# When this track_hook receives a "QueueEndEvent" from lavalink.py
# it indicates that there are no tracks left in the player's queue.
# To save on resources, we can tell the bot to disconnect from the voicechannel.
guild_id = event.player.guild_id
guild = self.bot.get_guild(guild_id)
time.sleep(300)
await guild.voice_client.disconnect(force=True)
@commands.check(ensure_voice)
@commands.command(name='Play',description='play, p', aliases=['p'], category = "Music")
async def play(self, ctx, *, query: str):
"Searches and plays a song from a given query."
# Get the player for this guild from cache.
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
# Remove leading and trailing <>. <> may be used to suppress embedding links in Discord.
query = query.strip('<>')
# Check if guild is premium
guild_id = ctx.guild.id
self.cur.execute("SELECT guild_id FROM premium_guilds WHERE guild_id = ?", (guild_id,))
is_premium = self.cur.fetchone() is not None
# Check if the user input might be a URL. If it isn't, we can Lavalink do a YouTube search for it instead.
# SoundCloud searching is possible by prefixing "scsearch:" instead.
if not url_rx.match(query):
query = f'ytsearch:{query}'
# Get the results for the query from Lavalink.
results = await player.node.get_tracks(query)
# Results could be None if Lavalink returns an invalid response (non-JSON/non-200 (OK)).
# Alternatively, results.tracks could be an empty array if the query yielded no tracks.
if not results or not results.tracks:
embed = discord.Embed(
title=f"Search Errpr",
description="❌ | Nothing found.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
#embed = discord.Embed(color=discord.Color.blurple())
# Valid loadTypes are:
# TRACK_LOADED - single video/direct URL)
# PLAYLIST_LOADED - direct URL to playlist)
# SEARCH_RESULT - query prefixed with either ytsearch: or scsearch:.
# NO_MATCHES - query yielded no results
# LOAD_FAILED - most likely, the video encountered an exception during loading.
if results.load_type == 'PLAYLIST_LOADED':
tracks = results.tracks
if is_premium or len(tracks) <= 10:
for track in tracks:
# Add all of the tracks from the playlist to the queue.
player.add(requester=ctx.author.id, track=track)
embed = discord.Embed(
title='Playlist Enqueued!',
description=f'▶️ | [{results.playlist_info.name} - {len(tracks)} tracks',
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
else:
embed = discord.Embed(
title='Playlist Not Enqueued!',
description=f'❌ | Playlist has {len(tracks)} tracks, which is more than the limit of 10 for non-premium servers',
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
else:
track = results.tracks[0]
if is_premium or len(player.queue) + 1 <= 10:
player.add(requester=ctx.author.id, track=track)
embed = discord.Embed(
title="Track Enqueued",
description=f"▶️ | [{track.title}]({track.uri})",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
# We don't want to call .play() if the player is playing as that will effectively skip
# the current track.
if not player.is_playing:
await player.play()
@commands.command(name = 'Disconnect', description='disconnect, d', aliases=['d'], category="Music")
async def disconnect(self, ctx):
"Disconnects the player from the voice channel and clears its queue."
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
if not ctx.voice_client:
# We can't disconnect, if we're not connected.
embed = discord.Embed(
title= "Disconnect",
description=f"📡| Not connected",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
if not ctx.author.voice or (player.is_connected and ctx.author.voice.channel.id != int(player.channel_id)):
# Abuse prevention. Users not in voice channels, or not in the same voice channel as the bot
# may not disconnect the bot.
embed = discord.Embed(
title= "Disconnect",
description=f"📡| You're not in my voicechannel!",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
# Clear the queue to ensure old tracks don't start playing
# when someone else queues something.
player.queue.clear()
# Stop the current track so Lavalink consumes less resources.
await player.stop()
# Disconnect from the voice channel.
await ctx.voice_client.disconnect(force=True)
embed = discord.Embed(
title= "Disconnected",
description=f"📡 | Disconnected from <#{ctx.author.voice.channel.id}>.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
@commands.command(name = 'Lowpass filter', description='lowpass, lf', aliases=['lf'], category = "Music")
async def lowpass(self, ctx, strength: float):
" Sets the strength of the low pass filter. "
# Get the player for this guild from cache.
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
# This enforces that strength should be a minimum of 0.
# There's no upper limit on this filter.
strength = max(0.0, strength)
# Even though there's no upper limit, we will enforce one anyway to prevent
# extreme values from being entered. This will enforce a maximum of 100.
strength = min(100, strength)
# A strength of 0 effectively means this filter won't function, so we can disable it.
if strength == 0.0:
await player.remove_filter('lowpass')
embed = discord.Embed(
title="Low Pass Filter",
description=f"Disabled **Low Pass Filter**",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
# Set the filter strength to the user's desired level.
self.low_pass.update(smoothing=strength)
# This applies our filter. If the filter is already enabled on the player, then this will
# just overwrite the filter with the new values.
await player.set_filter(self.low_pass)
embed = discord.Embed(
title="Low Pass Filter",
description=f"Set **Low Pass Filter** strength to {strength}",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
@commands.command(name='Pause', description='pause, s', aliases=['s'], category="Music")
async def pause(self, ctx):
"Pause the current song"
voice_state = ctx.author.voice
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
if not voice_state or not voice_state.channel:
embed = discord.Embed(
title=f"Pause Error",
description=F"❌ | You need to be in a voice channel to use this command.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
if not player:
embed = discord.Embed(
title=f"Pause Error",
description=F"❌ | There is no player for this guild.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
if player.paused:
embed = discord.Embed(
title=f"Pause",
description=F"⏸ | The player is already paused.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
await player.set_pause(True)
embed = discord.Embed(
title=f"Paused",
description=F"⏸ | Paused the current song",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
@commands.command(name='Resume', description='resume, r', aliases=['r'], category="Music")
async def resume(self, ctx):
"Resumes the current song thats paused"
voice_state = ctx.author.voice
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
if not voice_state or not voice_state.channel:
embed = discord.Embed(
title=f"Resume Error",
description=F"❌ You need to be in a voice channel to use this command.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
if not player:
embed = discord.Embed(
title=f"Resume Error",
description=F"❌ There is no player for this guild.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
if not player.paused:
embed = discord.Embed(
title=f"Resume",
description="▶️ The player is not paused.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
await player.set_pause(False)
embed = discord.Embed(
title=f'Resumed',
description="▶️ Resumed the player",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
@commands.command(name='Queue', description='queue, q', aliases=['q'], category='Music')
async def queue_(self, ctx):
"See the list of songs that will play next"
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
if not player.queue:
embed = discord.Embed(
title=f"No tracks",
description="❌ | There are no songs in the queue.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
#fix this
upcoming = list(itertools.islice(player.queue, 0, 100))
queue_list = ''
for i, track in enumerate(upcoming):
queue_list += f"{i + 1}) [{track.title}]({track.uri})\n"
embed = discord.Embed(
title=f"Upcoming Tracks - {len(player.queue)}",
description=queue_list,
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
@commands.command(name='Create playlist', description = 'create_playlist, cp',aliases=['create_playlist', 'cp'], category="Music")
async def create_playlist(self, ctx, name: str, link: str):
"Creates a playlist"
guild_id = ctx.guild.id
# Check if playlist with the given name already exists for this guild
self.cur.execute('SELECT * FROM custom_playlists WHERE guild_id = ? AND name = ?', (guild_id, name,))
playlist = self.cur.fetchone()
if playlist:
embed = discord.Embed(
title="Playlist create Error",
description=f'❌ | A playlist with the name "{name}" already exists.',
color=discord.Color.red(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
return
# If the playlist doesn't already exist, add it to the database
self.cur.execute('INSERT INTO custom_playlists (guild_id, name, link) VALUES (?, ?, ?)', (guild_id, name, link,))
self.con.commit()
embed = discord.Embed(
title="Playlist created",
description=f'Playlist "{name}" added successfully.',
color=discord.Color.green(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
@commands.command(name='List playlists', description='playlists, lpt', aliases=['playlists', 'lpt'], category="Music")
async def playlists(self, ctx):
"List all custom playlists for this guild."
guild_id = ctx.guild.id
# Get all playlists and their corresponding songs for this guild
self.cur.execute("SELECT name, link FROM custom_playlists WHERE guild_id=?", (guild_id,))
playlists = cur.fetchall()
if not playlists:
embed = discord.Embed(
title="Playlist search Error",
description=f'❌ | There are no custom playlists for this guild.',
color=discord.Color.red(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
return
embed = discord.Embed(
title="Custom Playlists",
color=discord.Color.green(),
timestamp=ctx.message.created_at
)
for i, p in enumerate(playlists):
playlist_name = p[0]
playlist_songs = p[1].split(",")
# Create list of songs in the playlist
song_list = [f"{j+1}. {link}" for j, link in enumerate(playlist_songs)]
song_str = "\n".join(song_list)
# Add playlist and its songs to the embed
embed.add_field(
name=f"{i+1}. {playlist_name}",
value=f"{song_str}",
inline=False
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
@commands.command(name = 'Skip', description = 'skip, sk', aliases = ['sk'], category="Music")
async def skip(self, ctx):
"Skips the current song"
# Get the Lavalink player for this guild
#player = self.lavalink_client.player_manager(ctx.guild_id)
player = self.lavalink.player_manager.get(self.channel.guild.id)
query = query.strip('<>')
results = await player.node.get_tracks(query)
track = results.tracks
# Check if there is a player and if the requester is in the same voice channel
if not player or not ctx.author.voice or player.channel_id != ctx.author.voice.channel.id:
embed = discord.Embed(
title=f"Skip",
description=f"❌ You are not in the same voice channel as me",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
# Skip the current track
try:
votes = votes + 1
embed = discord.Embed(
title=f"Skip",
description=f"⏭️ {votes}/3 to skip current track",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
if votes == 3:
await player.skip()
embed = discord.Embed(
title=f'Skip',
description=f"⏭️ Song {track.title}]({track.uri} skipped",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
votes = 0
except not player or not player.playing:
if not player or not player.playing:
embed = discord.Embed(
title=f'Skip',
description=f"⏭️ No track is currently playing.",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
await ctx.send(embed=embed)
return await ctx.send("not playing")
@commands.command(name='Play playlist', description='play_playlist, pp', aliases=['play_playlist', 'pp'], category="Music")
async def play_playlist(self, ctx, name: str):
guild_id = ctx.guild.id
player = self.lavalink.player_manager.get(self.channel.guild.id)
# Check if playlist with the given name exists for this guild
self.cur.execute('SELECT * FROM custom_playlists WHERE guild_id = ? AND name = ?', (guild_id, name,))
playlist_row = self.cur.fetchone()
if playlist_row is None:
await ctx.send(f'A playlist with the name "{name}" does not exist.')
return
playlist_id, playlist_name, playlist_link, playlist_owner_id = playlist_row
playlist = await self.bot.lavalink.get_tracks(playlist_link)
# If the playlist exists, add all of its tracks to the queue
if not playlist.tracks:
await ctx.send(f'Failed to fetch tracks for playlist "{name}".')
return
for track in playlist.tracks:
await self.player.add(ctx, track)
await ctx.send(f'Playlist "{name}" added to queue.')
# Start playing the first track in the queue if nothing is already playing
if not self.player.current:
await self.player.play(ctx)
@commands.command(name = 'Volume', description='volume, v', aliases=['v'], category= "Music")
async def volume(self, ctx, vol: int):
"Sets the volume of the player."
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
if not player.is_playing:
embed = discord.Embed(
title= "Volume Error",
description="❌ | Nothing playing.",
color=discord.Color.red(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
if not 0 < vol < 101:
embed = discord.Embed(
title= "Volume Error",
description="❌ | Please enter a value between 1 and 100.",
color=discord.Color.red(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
await player.set_volume(vol)
embed = discord.Embed(
title= "Volume",
description=f"🔊 | Set volume to {vol}%",
color=discord.Color.dark_blue(),
timestamp=ctx.message.created_at
)
embed.set_author(
name=self.bot.user.name,
icon_url=self.bot.user.display_avatar.url
)
embed.set_footer(text="Made by NNKtv28")
await ctx.send(embed=embed)
@commands.command(name = 'Add to playlist', description = 'addtoplaylist, adp', aliases=['adp', 'addtoplaylist'], category='Music')
async def addtoplaylist(self, ctx, playlist_name: str, song_name: str, song_link: str):
"Add a song to an existing playlist."
guild_id = ctx.guild.id
#player = self.bot.lavalink.player_manager.get(ctx.guild.id)
# Check if playlist exists
cur = self.bot.cur.execute("SELECT id FROM custom_playlists WHERE name=? AND guild_id=?", (playlist_name, guild_id))
playlist_id = cur.fetchone()
if not playlist_id:
await ctx.send(f"Playlist '{playlist_name}' not found.")
return
# Check if song already exists in playlist
cur = self.bot.db_cur.execute("SELECT id FROM songs WHERE name=? AND link=? AND playlist_id=?", (song_name, song_link, playlist_id[0]))
song_id = cur.fetchone()
if song_id:
await ctx.send("Song already exists in the playlist.")
return
# Add song to playlist
self.cur.execute("INSERT INTO songs (name, link, playlist_id) VALUES (?, ?, ?)", (song_name, song_link, playlist_id[0]))
self.con.commit()
await ctx.send(f"Song '{song_name}' added to playlist '{playlist_name}'.")
async def setup(bot):
await bot.add_cog(Music_commands(bot))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment