added model magic functions
This commit is contained in:
parent
3879562e82
commit
92217ad3a4
@ -11,7 +11,7 @@ logger = logging.getLogger('spotframework')
|
||||
|
||||
log_format = '%(asctime)s %(levelname)s %(name)s - %(funcName)s - %(message)s'
|
||||
|
||||
file_handler = logging.FileHandler(".spot/resort_playlist.log")
|
||||
file_handler = logging.FileHandler(".spot/sort_playlist.log")
|
||||
formatter = logging.Formatter(log_format)
|
||||
file_handler.setFormatter(formatter)
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import List
|
||||
from spotframework.util.console import Color
|
||||
if TYPE_CHECKING:
|
||||
from spotframework.model.artist import Artist
|
||||
|
||||
@ -23,6 +24,10 @@ class Album:
|
||||
|
||||
return f'{self.name} / {artists}'
|
||||
|
||||
def __repr__(self):
|
||||
return Color.DARKCYAN + Color.BOLD + 'Album' + Color.END + \
|
||||
f': {self.name}, [{self.artists}]'
|
||||
|
||||
|
||||
class SpotifyAlbum(Album):
|
||||
def __init__(self,
|
||||
@ -56,3 +61,7 @@ class SpotifyAlbum(Album):
|
||||
|
||||
self.label = label
|
||||
self.popularity = popularity
|
||||
|
||||
def __repr__(self):
|
||||
return Color.DARKCYAN + Color.BOLD + 'SpotifyAlbum' + Color.END + \
|
||||
f': {self.name}, {self.artists}, {self.uri}, {self.tracks}'
|
||||
|
@ -1,4 +1,5 @@
|
||||
from typing import List
|
||||
from spotframework.util.console import Color
|
||||
|
||||
|
||||
class Artist:
|
||||
@ -8,6 +9,10 @@ class Artist:
|
||||
def __str__(self):
|
||||
return f'{self.name}'
|
||||
|
||||
def __repr__(self):
|
||||
return Color.PURPLE + Color.BOLD + 'Artist' + Color.END + \
|
||||
f': {self.name}'
|
||||
|
||||
|
||||
class SpotifyArtist(Artist):
|
||||
def __init__(self,
|
||||
@ -30,3 +35,7 @@ class SpotifyArtist(Artist):
|
||||
self.genres = genres
|
||||
|
||||
self.popularity = popularity
|
||||
|
||||
def __repr__(self):
|
||||
return Color.PURPLE + Color.BOLD + 'SpotifyArtist' + Color.END + \
|
||||
f': {self.name}, {self.uri}'
|
||||
|
@ -1,5 +1,6 @@
|
||||
from spotframework.model.user import User
|
||||
from spotframework.model.track import Track, SpotifyTrack, PlaylistTrack
|
||||
from spotframework.util.console import Color
|
||||
from tabulate import tabulate
|
||||
from typing import List
|
||||
import logging
|
||||
@ -50,9 +51,46 @@ class Playlist:
|
||||
prefix = f'\n==={self.name}===\n\n' if self.name is not None else ''
|
||||
|
||||
table = prefix + self.get_tracks_string() + '\n' + f'total: {len(self)}'
|
||||
|
||||
return table
|
||||
|
||||
def __repr__(self):
|
||||
return Color.GREEN + Color.BOLD + 'Playlist' + Color.END + \
|
||||
f': {self.name}, ({len(self)})'
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, Track):
|
||||
self.tracks.append(other)
|
||||
return self
|
||||
|
||||
elif isinstance(other, list):
|
||||
if all((isinstance(i, Track) for i in other)):
|
||||
self.tracks += other
|
||||
return self
|
||||
else:
|
||||
logger.error('list not full of tracks')
|
||||
raise TypeError('list not full of tracks')
|
||||
|
||||
else:
|
||||
logger.error('list of tracks needed to add')
|
||||
raise TypeError('list of tracks needed to add')
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, Track):
|
||||
self.tracks.remove(other)
|
||||
return self
|
||||
|
||||
elif isinstance(other, list):
|
||||
if all((isinstance(i, Track) for i in other)):
|
||||
self.tracks -= other
|
||||
return self
|
||||
else:
|
||||
logger.error('list not full of tracks')
|
||||
raise TypeError('list not full of tracks')
|
||||
|
||||
else:
|
||||
logger.error('list of tracks needed to subtract')
|
||||
raise TypeError('list of tracks needed to subtract')
|
||||
|
||||
def get_tracks_string(self):
|
||||
|
||||
rows = []
|
||||
@ -109,3 +147,7 @@ class SpotifyPlaylist(Playlist):
|
||||
table = prefix + self.get_tracks_string() + '\n' + f'total: {len(self)}'
|
||||
|
||||
return table
|
||||
|
||||
def __repr__(self):
|
||||
return Color.GREEN + Color.BOLD + 'SpotifyPlaylist' + Color.END + \
|
||||
f': {self.name} ({self.owner}), ({len(self)}), {self.uri}'
|
||||
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import List
|
||||
from datetime import datetime
|
||||
from spotframework.util.console import Color
|
||||
if TYPE_CHECKING:
|
||||
from spotframework.model.album import Album
|
||||
from spotframework.model.artist import Artist
|
||||
@ -44,6 +45,10 @@ class Track:
|
||||
|
||||
return f'{self.name} / {album} / {artists}'
|
||||
|
||||
def __repr__(self):
|
||||
return Color.YELLOW + Color.BOLD + 'Track' + Color.END + \
|
||||
f': {self.name}, ({self.album}), {self.artists}'
|
||||
|
||||
|
||||
class SpotifyTrack(Track):
|
||||
def __init__(self,
|
||||
@ -74,6 +79,10 @@ class SpotifyTrack(Track):
|
||||
|
||||
self.popularity = popularity
|
||||
|
||||
def __repr__(self):
|
||||
return Color.BOLD + Color.YELLOW + 'SpotifyTrack' + Color.END + \
|
||||
f': {self.name}, ({self.album}), {self.artists}, {self.uri}'
|
||||
|
||||
|
||||
class PlaylistTrack(SpotifyTrack):
|
||||
def __init__(self,
|
||||
@ -110,3 +119,7 @@ class PlaylistTrack(SpotifyTrack):
|
||||
self.added_at = datetime.fromisoformat(added_at.replace('T', ' ').replace('Z', ''))
|
||||
self.added_by = added_by
|
||||
self.is_local = is_local
|
||||
|
||||
def __repr__(self):
|
||||
return Color.BOLD + Color.YELLOW + 'PlaylistTrack' + Color.END + \
|
||||
f': {self.name}, ({self.album}), {self.artists}, {self.uri}, {self.added_at}'
|
||||
|
@ -1,3 +1,4 @@
|
||||
from spotframework.util.console import Color
|
||||
|
||||
|
||||
class User:
|
||||
@ -19,3 +20,7 @@ class User:
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.username}'
|
||||
|
||||
def __repr__(self):
|
||||
return Color.RED + Color.BOLD + 'User' + Color.END + \
|
||||
f': {self.username}, {self.display_name}, {self.uri}'
|
||||
|
@ -5,6 +5,7 @@ import time
|
||||
from typing import List, Optional
|
||||
from . import const
|
||||
from spotframework.net.parse import parse
|
||||
from spotframework.net.user import NetworkUser
|
||||
from spotframework.model.playlist import SpotifyPlaylist
|
||||
from spotframework.model.track import Track, PlaylistTrack
|
||||
from requests.models import Response
|
||||
@ -16,7 +17,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class Network:
|
||||
|
||||
def __init__(self, user):
|
||||
def __init__(self, user: NetworkUser):
|
||||
self.user = user
|
||||
|
||||
def _make_get_request(self, method, url, params=None, headers={}) -> Optional[dict]:
|
||||
@ -40,6 +41,11 @@ class Network:
|
||||
else:
|
||||
logger.error(f'{method} rate limit reached: cannot find Retry-After header')
|
||||
|
||||
elif req.status_code == 401:
|
||||
logger.warning(f'{method} access token expired, refreshing')
|
||||
self.user.refresh_token()
|
||||
return self._make_get_request(method, url, params, headers)
|
||||
|
||||
else:
|
||||
error_text = req.json()['error']['message']
|
||||
logger.error(f'{method} get {req.status_code} {error_text}')
|
||||
@ -67,6 +73,11 @@ class Network:
|
||||
else:
|
||||
logger.error(f'{method} rate limit reached: cannot find Retry-After header')
|
||||
|
||||
elif req.status_code == 401:
|
||||
logger.warning(f'{method} access token expired, refreshing')
|
||||
self.user.refresh_token()
|
||||
return self._make_post_request(method, url, params, json, headers)
|
||||
|
||||
else:
|
||||
error_text = str(req.text)
|
||||
logger.error(f'{method} post {req.status_code} {error_text}')
|
||||
@ -94,6 +105,11 @@ class Network:
|
||||
else:
|
||||
logger.error(f'{method} rate limit reached: cannot find Retry-After header')
|
||||
|
||||
elif req.status_code == 401:
|
||||
logger.warning(f'{method} access token expired, refreshing')
|
||||
self.user.refresh_token()
|
||||
return self._make_put_request(method, url, params, json, headers)
|
||||
|
||||
else:
|
||||
error_text = str(req.text)
|
||||
logger.error(f'{method} put {req.status_code} {error_text}')
|
||||
|
@ -1,5 +1,6 @@
|
||||
import requests
|
||||
from spotframework.model.user import User
|
||||
from spotframework.util.console import Color
|
||||
from base64 import b64encode
|
||||
import logging
|
||||
import time
|
||||
@ -22,6 +23,10 @@ class NetworkUser(User):
|
||||
self.refresh_token()
|
||||
self.refresh_info()
|
||||
|
||||
def __repr__(self):
|
||||
return Color.RED + Color.BOLD + 'NetworkUser' + Color.END + \
|
||||
f': {self.username}, {self.display_name}, {self.uri}'
|
||||
|
||||
def refresh_token(self) -> None:
|
||||
|
||||
if self.refreshtoken is None:
|
||||
@ -53,7 +58,7 @@ class NetworkUser(User):
|
||||
time.sleep(int(retry_after) + 1)
|
||||
return self.refresh_token()
|
||||
else:
|
||||
logger.error(f'refresh_token rate limit reached: cannot find Retry-After header')
|
||||
logger.error('refresh_token rate limit reached: cannot find Retry-After header')
|
||||
|
||||
else:
|
||||
error_text = req.json()['error']['message']
|
||||
@ -97,7 +102,12 @@ class NetworkUser(User):
|
||||
time.sleep(int(retry_after) + 1)
|
||||
return self.get_info()
|
||||
else:
|
||||
logger.error(f'get_info rate limit reached: cannot find Retry-After header')
|
||||
logger.error('get_info rate limit reached: cannot find Retry-After header')
|
||||
|
||||
elif req.status_code == 401:
|
||||
logger.warning('access token expired, refreshing')
|
||||
self.refresh_token()
|
||||
return self.get_info()
|
||||
|
||||
else:
|
||||
error_text = req.json()['error']['message']
|
||||
|
12
spotframework/util/console.py
Normal file
12
spotframework/util/console.py
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
class Color:
|
||||
PURPLE = '\033[95m'
|
||||
CYAN = '\033[96m'
|
||||
DARKCYAN = '\033[36m'
|
||||
BLUE = '\033[94m'
|
||||
GREEN = '\033[92m'
|
||||
YELLOW = '\033[93m'
|
||||
RED = '\033[91m'
|
||||
BOLD = '\033[1m'
|
||||
UNDERLINE = '\033[4m'
|
||||
END = '\033[0m'
|
Loading…
Reference in New Issue
Block a user