reimplementing playlist engine in functions

closes #2
This commit is contained in:
aj 2020-06-16 20:44:36 +01:00
parent fbd8b3eeb7
commit 144f198424
5 changed files with 162 additions and 4 deletions

View File

@ -0,0 +1,16 @@
from typing import List
def remove_local(tracks: List, include_malformed=True) -> List:
prop = 'is_local'
return_tracks = []
for track in tracks:
if hasattr(track, prop) and isinstance(getattr(track, prop), bool):
if getattr(track, prop) is False:
return_tracks.append(track)
else:
if include_malformed:
return_tracks.append(track)
return return_tracks

View File

@ -0,0 +1,35 @@
import logging
from typing import List
from datetime import datetime
logger = logging.getLogger(__name__)
def added_before(tracks: List, boundary: datetime, include_malformed=True) -> List:
prop = 'added_at'
return_tracks = []
for track in tracks:
if hasattr(track, prop) and isinstance(getattr(track, prop), datetime):
if getattr(track, prop) < boundary:
return_tracks.append(track)
else:
if include_malformed:
return_tracks.append(track)
return return_tracks
def added_after(tracks: List, boundary: datetime, include_malformed=True) -> List:
prop = 'added_at'
return_tracks = []
for track in tracks:
if hasattr(track, prop) and isinstance(getattr(track, prop), datetime):
if getattr(track, prop) > boundary:
return_tracks.append(track)
else:
if include_malformed:
return_tracks.append(track)
return return_tracks

View File

@ -0,0 +1,60 @@
import logging
from typing import List
from spotframework.model.track import SpotifyTrack
from spotframework.model.album import SpotifyAlbum
from spotframework.model.uri import Uri
logger = logging.getLogger(__name__)
def deduplicate_by_id(tracks: List, include_malformed=True) -> List:
prop = 'uri'
return_tracks = []
for track in tracks:
if hasattr(track, prop) and isinstance(getattr(track, prop), Uri):
if getattr(track, prop) not in [getattr(i, prop) for i in return_tracks]:
return_tracks.append(track)
else:
if include_malformed:
return_tracks.append(track)
return return_tracks
def deduplicate_by_name(tracks: List, include_malformed=True) -> List:
return_tracks = []
for track in tracks:
if isinstance(track, SpotifyTrack):
to_check_artists = [i.name.lower() for i in track.artists]
for index, _track in enumerate(return_tracks):
if track.name.lower() == _track.name.lower():
_track_artists = [i.name.lower() for i in _track.artists]
if all((i in _track_artists for i in to_check_artists)): # CHECK ARTISTS MATCH
if not isinstance(track.album, SpotifyAlbum):
logger.warning(f'{track.name} album not of type SpotifyAlbum')
continue
if not isinstance(_track.album, SpotifyAlbum):
logger.warning(f'{_track.name} album not of type SpotifyAlbum')
continue
# CHECK ALBUM TYPE, PREFER ALBUMS OVER SINGLES ETC
if track.album.album_type.value > _track.album.album_type.value:
logger.debug(f'better track source found, {track} ({track.album.album_type}) '
f'> {_track} ({_track.album.album_type})')
return_tracks[index] = track # REPLACE
break # FOUND, ESCAPE
else:
return_tracks.append(track) # NOT FOUND, ADD TO RETURN
else:
if include_malformed:
return_tracks.append(track)
return return_tracks

View File

@ -0,0 +1,47 @@
import logging
from typing import List
from spotframework.model.track import Track
logger = logging.getLogger(__name__)
def sort_by_popularity(tracks: List, reverse: bool = False, include_malformed=False) -> List:
prop = 'popularity'
return_tracks = sorted([i for i in tracks if hasattr(i, prop) and isinstance(getattr(i, prop), int)],
key=lambda x: x.popularity, reverse=reverse)
if include_malformed:
return_tracks += [i for i in tracks
if not hasattr(i, prop)
or (hasattr(i, prop) and not isinstance(getattr(i, prop), int))]
return return_tracks
def sort_by_release_date(tracks: List, reverse: bool = False) -> List:
return sorted(sort_artist_album_track_number(tracks),
key=lambda x: x.album.release_date, reverse=reverse)
def sort_by_artist_name(tracks: List, reverse: bool = False) -> List:
return_tracks = sorted([i for i in tracks if isinstance(i, Track)],
key=lambda x: (x.album.name.lower(),
x.track_number))
return_tracks.sort(key=lambda x: x.artists[0].name.lower(), reverse=reverse)
return return_tracks
def sort_by_added_date(tracks: List, reverse: bool = False) -> List:
return sorted(sort_artist_album_track_number(tracks),
key=lambda x: x.added_at,
reverse=reverse)
def sort_artist_album_track_number(tracks: List) -> List:
return sorted([i for i in tracks if isinstance(i, Track)],
key=lambda x: (x.artists[0].name.lower(),
x.album.name.lower(),
x.track_number))

View File

@ -731,8 +731,8 @@ class Network:
return [] return []
def get_recommendations(self, def get_recommendations(self,
tracks: List[Track] = None, tracks: List[str] = None,
artists: List[SpotifyArtist] = None, artists: List[str] = None,
response_limit=10) -> Optional[List[Track]]: response_limit=10) -> Optional[List[Track]]:
logger.info(f'getting {response_limit} recommendations, ' logger.info(f'getting {response_limit} recommendations, '
@ -743,10 +743,10 @@ class Network:
if tracks: if tracks:
random.shuffle(tracks) random.shuffle(tracks)
params['seed_tracks'] = tracks[:100] params['seed_tracks'] = tracks[:5]
if artists: if artists:
random.shuffle(artists) random.shuffle(artists)
params['seed_artists'] = artists[:100] params['seed_artists'] = artists[:5]
if len(params) == 1: if len(params) == 1:
logger.warning('update dictionairy length 0') logger.warning('update dictionairy length 0')