Vulkan/vulkanbot/music/Spotify.py
2021-12-25 01:38:39 -04:00

150 lines
4.6 KiB
Python

import spotipy
import re
from spotipy.oauth2 import SpotifyClientCredentials
from bs4 import BeautifulSoup
from config import config
import aiohttp
class Browser():
def __init__(self) -> None:
self.__url_regex = re.compile(
"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+")
self.__session = aiohttp.ClientSession(
headers={'User-Agent': 'python-requests/2.20.0'})
async def search(self, url) -> str:
"""Convert the external_url link to the title of music using browser"""
if re.search(self.__url_regex, url):
result = self.__url_regex.search(url)
url = result.group(0)
async with self.__session.get(url) as response:
page = await response.text()
soup = BeautifulSoup(page, 'html.parser')
title = soup.find('title')
title = title.string
title = title.replace('- song by', '')
title = title.replace('| Spotify', '')
return title
class SpotifySearch():
"""Search a Spotify music or playlist and return the musics names"""
def __init__(self) -> None:
self.__connected = False
self.__browser = Browser()
def connect(self) -> bool:
try:
# Initialize the connection with Spotify API
self.__api = spotipy.Spotify(auth_manager=SpotifyClientCredentials(
client_id=config.SPOTIFY_ID, client_secret=config.SPOTIFY_SECRET))
self.__connected = True
return True
except:
return False
def search(self, music) -> list:
"""Search and return the title of musics on Spotify"""
type = music.split('/')[3].split('?')[0]
code = music.split('/')[4].split('?')[0]
if type == 'album':
musics = self.__get_album(code)
elif type == 'playlist':
musics = self.__get_playlist(code)
elif type == 'track':
musics = self.__get_track(code)
else:
return None
return musics
def __get_album(self, code) -> list:
"""Get the externals urls of a album
ARG: Spotify Code of the Album
"""
if self.__connected == True:
try:
# Load all music objects
results = self.__api.album_tracks(code)
musics = results['items']
while results['next']: # Get the next pages
results = self.__api.next(results)
musics.extend(results['items'])
musicsTitle = []
for music in musics:
try:
title = self.__extract_title(music)
musicsTitle.append(title)
except:
pass
return musicsTitle
except Exception as e:
raise e
def __get_playlist(self, code) -> list:
"""Get the externals urls of a playlist
Arg: Spotify Code of the Playlist
"""
try:
results = self.__api.playlist_items(code)
itens = results['items']
while results['next']: # Load the next pages
results = self.__api.next(results)
itens.extend(results['items'])
musics = []
for item in itens:
musics.append(item['track'])
titles = []
for music in musics:
try:
title = self.__extract_title(music)
titles.append(title)
except Exception as e:
raise e
return titles
except Exception as e:
raise e
def __get_track(self, code) -> list:
"""Convert a external_url track to the title of the music
ARG: Spotify Code of the Music
"""
results = self.__api.track(code)
name = results['name']
artists = ''
for artist in results['artists']:
artists += f'{artist["name"]} '
return [f'{name} {artists}']
def __extract_title(self, music: dict) -> str:
"""Receive a spotify music object and return his title
ARG: music dict returned by Spotify
"""
title = f'{music["name"]} '
for artist in music['artists']:
title += f'{artist["name"]} '
return title
async def __convert_spotify(self, url) -> str:
"""(Experimental) - Convert the external_url link to the title of music using browser"""
title = self.__browser(url)
return title