RedValis's picture
Upload 19 files
f3f431f verified
# THIS FILE IS RESPONSABLE FOR MANY CLASS DECLARATIONS
import json
import math
from base64 import b64encode
from urllib.request import urlretrieve
from . import constructor
from . import calls
# AUTHENTICATION AND TOKENS
class Authenticator:
def __init__(self, client_id:str, client_secret:str):
self.credentials = self.encode_credentials(client_id, client_secret)
def encode_credentials(self, client_id, client_secret):
credentials = f'{client_id}:{client_secret}'
encoded_credentials = b64encode(credentials.encode('utf-8'))
return str(encoded_credentials, 'utf-8')
def get_acess_token(self):
response = calls.call_acess_token(self.credentials)
return response.json()['access_token']
# OBJECTS
# Base class for all classes
class Base:
def __init__(self, data, type, name, url, id):
self.data = data
self.type = type
self.name = name
self.url = url
self.id = id
def export_json(self, path:str):
file = open(path, 'w')
json.dump(self.data, file, indent=4)
file.close()
# Base class for track-like objects
class TrackBase(Base):
def __init__(self, data, type, name, url, id, explicit, duration_ms):
super().__init__(data, type, name, url, id)
self.explicit = explicit
self.duration_ms = duration_ms
def get_formatted_duration(self) -> dict:
duration_in_seconds = self.duration_ms / 1000
hours = 0
mins = math.floor(duration_in_seconds // 60)
if mins >= 60:
hours = math.floor(mins // 60)
mins = math.floor(mins % 60)
secs = math.floor(duration_in_seconds % 60)
return {'hours':hours, 'minutes':mins, 'seconds':secs}
def get_string_duration(self) -> str:
duration = self.get_formatted_duration()
format = self.__format_duration
hours = format(str(duration['hours']))
mins = format(str(duration['minutes']))
secs = format(str(duration['seconds']))
if int(hours):
return f'{hours}:{mins}:{secs}'
else:
return f'{mins}:{secs}'
def __format_duration(self, value:str):
if len(value) < 2:
return ('0' + value)
else: return value
class Artist(Base):
def __init__(self, data:dict, type:str, name:str, url:str, id:str):
super().__init__(data, type, name, url, id)
class AlbumCover:
def __init__(self, width, height, url):
self.width = width
self.height = height
self.url = url
def export_image(self, path):
urlretrieve(self.url, path)
class Album(Base):
def __init__(self, data:dict, type:str, name:str, url:str, id:str,
images:list, artists:list, available_markets:list, release_date:str, total_tracks:int):
super().__init__(data, type, name, url, id)
self.images = images
self.artists = artists
self.available_markets = available_markets
self.release_date = release_date
self.total_tracks = total_tracks
class TrackPreview:
def __init__(self, url):
self.url = url
def export_audio(self, path):
urlretrieve(self.url, path)
class Track(TrackBase):
def __init__(self, data:dict, type:str, name:str, url:str, id:str, explicit:bool,
duration_ms:int, preview:TrackPreview, artists:list, album:Album, available_markets:list,
disc_number:int, popularity:int):
super().__init__(data, type, name, url, id, explicit, duration_ms)
self.preview = preview
self.artists = artists
self.album = album
self.available_markets = available_markets
self.disc_number = disc_number
self.popularity = popularity
class Episode(TrackBase):
def __init__(self, data:dict, type:str, name:str, url:str, id:str,
explicit:bool, duration_ms:int, preview:str, description:str, html_description:str,
images:list, language:str, languages:list, release_date:str):
super().__init__(data, type, name, url, id, explicit, duration_ms)
self.preview = preview
self.description = description
self.html_description = html_description
self.images = images
self.language = language
self.languages = languages
self.release_date = release_date
# CLIENT OBJECTS
class Results(Base):
def __init__(self, data):
self.data = data
def __get_items(self, type):
if type == 'artist':
try:
data = self.data['artists']['items']
func = constructor.artist
except KeyError:
return []
elif type == 'track':
try:
data = self.data['tracks']['items']
func = constructor.track
except KeyError:
return []
elif type == 'album':
try:
data = self.data['albums']['items']
func = constructor.album
except KeyError:
return []
elif type == 'episode':
try:
data = self.data['episodes']['items']
func = constructor.episode
except KeyError:
return []
return [func(item) for item in data]
def get_tracks(self) -> list:
return self.__get_items('track')
def get_artists(self) -> list:
return self.__get_items('artist')
def get_albums(self) -> list:
return self.__get_items('album')
def get_episodes(self) -> list:
return self.__get_items('episode')