parent
fbd8b3eeb7
commit
144f198424
16
spotframework/filter/__init__.py
Normal file
16
spotframework/filter/__init__.py
Normal 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
|
35
spotframework/filter/added.py
Normal file
35
spotframework/filter/added.py
Normal 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
|
60
spotframework/filter/deduplicate.py
Normal file
60
spotframework/filter/deduplicate.py
Normal 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
|
47
spotframework/filter/sort.py
Normal file
47
spotframework/filter/sort.py
Normal 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))
|
||||||
|
|
@ -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')
|
||||||
|
Loading…
Reference in New Issue
Block a user