Collabify/discordbot.py

178 lines
6.4 KiB
Python
Raw Normal View History

2021-07-15 04:36:37 +00:00
from discord.ext import commands
from discord.utils import get
import spotipy, urllib, re, discord, json, os, asyncio, configparser
from spotipy.oauth2 import SpotifyOAuth
from spotipy import util
client = discord.Client()
bot = commands.Bot(command_prefix='>')
bot.mapping = {}
bot.playlist = {}
config = configparser.ConfigParser()
config.read('config.ini')
def authenticate():
scope = 'playlist-modify playlist-modify-private'
token = util.prompt_for_user_token(
username=config['spotify']['username'],
scope=scope,
client_id=config['spotify']['client_id'],
client_secret=config['spotify']['client_secret'],
redirect_uri=config['spotify']['redirect_uri']
)
return token
def addToPlaylist(authToken, username, playlistName, songName):
if authToken:
spotifyObject = spotipy.Spotify(authToken)
spotifyObject.trace = False
spotifyObject.user_playlist_add_tracks(username, playlistName, songName)
def lookupSong(authToken, *s):
s = s[0]
if authToken:
song_uri_list = []
spotifyObject = spotipy.Spotify(authToken)
spotifyObject.trace = False
if 'https://open.spotify.com' in s:
song_uri = re.split('\w+:\/\/\w+.\w+.\w+\/\w+\/(\w+)',s)
song_uri_list.append(song_uri[1])
else:
s_encode = urllib.parse.quote_plus(s)
ret = spotifyObject.search(s_encode, limit=5)
ret = ret['tracks']['items']
if ret == []:
ret = spotifyObject.search(s_encode, limit=5, market='GB')
ret = ret['tracks']['items']
for i in ret:
song_url = ret[ret.index(i)]['external_urls']['spotify']
song_uri = re.split('\w+:\/\/\w+.\w+.\w+\/\w+\/(\w+)',song_url)
song_uri_list.append(song_uri[1])
return song_uri_list
def createPlaylist(authToken, username, server):
sp = spotipy.Spotify(auth=authToken)
sp.user_playlist_create(username, name=str(server))
def setPlaylist(authToken,server,username):
playlist_id = ''
sp = spotipy.Spotify(authToken)
playlists = sp.user_playlists(username)
for playlist in playlists['items']:
if playlist['name'] == server:
playlist_id = playlist['id']
sp.playlist_change_details(playlist_id,public=False, collaborative=True)
return playlist_id
def deletePlaylist(authToken, playlist):
sp = spotipy.Spotify(authToken)
sp.user_playlist_unfollow(config['spotify']['username'],playlist)
@bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('-----')
activity = discord.Activity(name="type '>help' for help", type=discord.ActivityType.listening)
await bot.change_presence(activity=activity)
if os.path.isfile('playlist.json'):
j = open('playlist.json', "r")
bot.playlist = json.load(j)
@bot.command(brief='>resync',description='Forces the bot to resync with the local storage of users and playlists')
async def resync(ctx):
if os.path.isfile('playlist.json'):
f = open('playlist.json', "r")
bot.playlist = json.load(f)
@bot.command(brief='>removePlaylist', description='Removes the currently created playlist')
@commands.has_guild_permissions(administrator=True)
async def removePlaylist(ctx):
token = authenticate()
try:
deletePlaylist(token,bot.playlist[str(ctx.author.guild)])
except KeyError:
pass
try:
del bot.playlist[str(ctx.author.guild)]
if os.path.isfile('playlist.json'):
with open('playlist.json',"w") as outfile:
json.dump(bot.playlist,outfile)
await ctx.send('Playlist deleted!')
except KeyError:
await ctx.send('This server does not have a playlist')
@bot.command(brief='>playlist',description='Use to specify the playlist that songs should be added to')
@commands.has_guild_permissions(administrator=True)
async def playlist(ctx):
try:
bot.playlist[str(ctx.author.guild)]
except KeyError:
token = authenticate()
createPlaylist(token, config['spotify']['username'],str(ctx.author.guild))
bot.playlist[str(ctx.author.guild)] = setPlaylist(token,str(ctx.author.guild),config['spotify']['username'])
with open('playlist.json',"w") as outfile:
json.dump(bot.playlist,outfile)
await ctx.send('Playlist https://open.spotify.com/playlist/' + bot.playlist[str(ctx.author.guild)]+' has been created!')
return
await ctx.send('This server already has a playlist')
@bot.command(brief='>addsong [song_name]',description='Allows a user to add a song to the playlist')
async def addsong(ctx, *song):
if len(song) > 1:
song = ' '.join(song)
else:
song = song[0]
def check(m: discord.Message): # m = discord.Message.
return m.author.id == ctx.author.id and m.channel.id == ctx.channel.id
try:
authToken = authenticate()
except KeyError:
await ctx.send('You need to connect your account first with `>connect [account name]`')
return
uri_list = lookupSong(authToken,song)
i = 1
for uri in uri_list:
await ctx.send(str(i)+': https://open.spotify.com/track/'+uri)
i+=1
await ctx.send(f"***Send the number of the song to add to the playlist***")
try:
msg = await bot.wait_for('message', check=lambda message: message.author == ctx.author, timeout = 60.0)
except asyncio.TimeoutError:
# at this point, the check didn't become True, let's handle it.
await ctx.send(f"**{ctx.author}**, you didn't send any message that meets the check in this channel for 60 seconds..")
return
else:
if int(msg.content) == 1:
uri = uri_list[0]
elif int(msg.content) == 2:
uri = uri_list[1]
elif int(msg.content) == 3:
uri = uri_list[2]
elif int(msg.content) == 4:
uri = uri_list[3]
elif int(msg.content) == 5:
uri = uri_list[4]
try:
addToPlaylist(authToken, config['spotify']['username'], bot.playlist[str(ctx.author.guild)], [uri])
except KeyError:
await ctx.send('Playlist must be set with `>playlist [spotify_url]`')
return
playlist_url = 'https://open.spotify.com/playlist/'+bot.playlist[str(ctx.author.guild)]
await ctx.send('Playlist '+playlist_url+' has been updated!')
bot.run(config['discord']['bot_token'])