added track_number and album_type to model, fixed sort and dedupe by name
This commit is contained in:
parent
af6d2529e2
commit
7f60f65403
@ -1,8 +1,11 @@
|
|||||||
from spotframework.engine.processor.abstract import BatchSingleProcessor, BatchSingleTypeAwareProcessor
|
from spotframework.engine.processor.abstract import BatchSingleProcessor, BatchSingleTypeAwareProcessor
|
||||||
from typing import List
|
from typing import List
|
||||||
|
import logging
|
||||||
from spotframework.model.track import Track, SpotifyTrack
|
from spotframework.model.track import Track, SpotifyTrack
|
||||||
from spotframework.model.uri import Uri
|
from spotframework.model.uri import Uri
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DeduplicateByID(BatchSingleTypeAwareProcessor):
|
class DeduplicateByID(BatchSingleTypeAwareProcessor):
|
||||||
|
|
||||||
@ -31,12 +34,21 @@ class DeduplicateByName(BatchSingleProcessor):
|
|||||||
return_tracks = []
|
return_tracks = []
|
||||||
|
|
||||||
for to_check in tracks:
|
for to_check in tracks:
|
||||||
|
to_check_artists = [i.name.lower() for i in to_check.artists]
|
||||||
|
|
||||||
for cache_track in return_tracks:
|
for index, _track in enumerate(return_tracks):
|
||||||
if to_check.name.lower() == cache_track.name.lower():
|
if to_check.name.lower() == _track.name.lower():
|
||||||
if to_check.artists[0].name.lower() == cache_track.artists[0].name.lower():
|
|
||||||
break
|
_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
|
||||||
|
|
||||||
|
# CHECK ALBUM TYPE, PREFER ALBUMS OVER SINGLES ETC
|
||||||
|
if to_check.album.album_type.value > _track.album.album_type.value:
|
||||||
|
logger.debug(f'better track source found, {to_check} ({to_check.album.album_type}) '
|
||||||
|
f'> {_track} ({_track.album.album_type})')
|
||||||
|
return_tracks[index] = to_check # REPLACE
|
||||||
|
break # FOUND, ESCAPE
|
||||||
else:
|
else:
|
||||||
return_tracks.append(to_check)
|
return_tracks.append(to_check) # NOT FOUND, ADD TO RETURN
|
||||||
|
|
||||||
return return_tracks
|
return return_tracks
|
||||||
|
@ -17,6 +17,9 @@ class BasicReversibleSort(AbstractProcessor, ABC):
|
|||||||
class SortReleaseDate(BasicReversibleSort):
|
class SortReleaseDate(BasicReversibleSort):
|
||||||
|
|
||||||
def process(self, tracks: List[Track]) -> List[Track]:
|
def process(self, tracks: List[Track]) -> List[Track]:
|
||||||
|
tracks.sort(key=lambda x: (x.artists[0].name.lower(),
|
||||||
|
x.album.name.lower(),
|
||||||
|
x.track_number))
|
||||||
tracks.sort(key=lambda x: x.album.release_date, reverse=self.reverse)
|
tracks.sort(key=lambda x: x.album.release_date, reverse=self.reverse)
|
||||||
return tracks
|
return tracks
|
||||||
|
|
||||||
@ -24,7 +27,9 @@ class SortReleaseDate(BasicReversibleSort):
|
|||||||
class SortArtistName(BasicReversibleSort):
|
class SortArtistName(BasicReversibleSort):
|
||||||
|
|
||||||
def process(self, tracks: List[Track]) -> List[Track]:
|
def process(self, tracks: List[Track]) -> List[Track]:
|
||||||
tracks.sort(key=lambda x: x.artists[0].name, reverse=self.reverse)
|
tracks.sort(key=lambda x: (x.album.name.lower(),
|
||||||
|
x.track_number))
|
||||||
|
tracks.sort(key=lambda x: x.artists[0].name.lower(), reverse=self.reverse)
|
||||||
return tracks
|
return tracks
|
||||||
|
|
||||||
|
|
||||||
@ -42,5 +47,8 @@ class SortAddedDate(BatchSingleTypeAwareProcessor):
|
|||||||
self.reverse = reverse
|
self.reverse = reverse
|
||||||
|
|
||||||
def process_batch(self, tracks: List[PlaylistTrack]) -> List[PlaylistTrack]:
|
def process_batch(self, tracks: List[PlaylistTrack]) -> List[PlaylistTrack]:
|
||||||
|
tracks.sort(key=lambda x: (x.artists[0].name.lower(),
|
||||||
|
x.album.name.lower(),
|
||||||
|
x.track_number))
|
||||||
tracks.sort(key=lambda x: x.added_at, reverse=self.reverse)
|
tracks.sort(key=lambda x: x.added_at, reverse=self.reverse)
|
||||||
return tracks
|
return tracks
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from enum import Enum
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
from spotframework.util.console import Color
|
from spotframework.util.console import Color
|
||||||
@ -45,9 +46,16 @@ class Album:
|
|||||||
|
|
||||||
|
|
||||||
class SpotifyAlbum(Album):
|
class SpotifyAlbum(Album):
|
||||||
|
|
||||||
|
class Type(Enum):
|
||||||
|
single = 0
|
||||||
|
compilation = 1
|
||||||
|
album = 2
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
album_type: Type,
|
||||||
|
|
||||||
href: str = None,
|
href: str = None,
|
||||||
uri: Union[str, Uri] = None,
|
uri: Union[str, Uri] = None,
|
||||||
@ -73,6 +81,8 @@ class SpotifyAlbum(Album):
|
|||||||
if self.uri.object_type != Uri.ObjectType.album:
|
if self.uri.object_type != Uri.ObjectType.album:
|
||||||
raise TypeError('provided uri not for an album')
|
raise TypeError('provided uri not for an album')
|
||||||
|
|
||||||
|
self.album_type = album_type
|
||||||
|
|
||||||
self.genres = genres
|
self.genres = genres
|
||||||
|
|
||||||
self.release_date = release_date
|
self.release_date = release_date
|
||||||
@ -101,6 +111,8 @@ class LibraryAlbum(SpotifyAlbum):
|
|||||||
name: str,
|
name: str,
|
||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
|
||||||
|
album_type: SpotifyAlbum.Type,
|
||||||
|
|
||||||
href: str = None,
|
href: str = None,
|
||||||
uri: Union[str, Uri] = None,
|
uri: Union[str, Uri] = None,
|
||||||
|
|
||||||
@ -117,6 +129,7 @@ class LibraryAlbum(SpotifyAlbum):
|
|||||||
):
|
):
|
||||||
super().__init__(name=name,
|
super().__init__(name=name,
|
||||||
artists=artists,
|
artists=artists,
|
||||||
|
album_type=album_type,
|
||||||
href=href,
|
href=href,
|
||||||
uri=uri,
|
uri=uri,
|
||||||
genres=genres,
|
genres=genres,
|
||||||
|
@ -7,7 +7,7 @@ from spotframework.util.console import Color
|
|||||||
from spotframework.util import convert_ms_to_minute_string
|
from spotframework.util import convert_ms_to_minute_string
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from spotframework.model.album import Album
|
from spotframework.model.album import Album, SpotifyAlbum
|
||||||
from spotframework.model.artist import Artist
|
from spotframework.model.artist import Artist
|
||||||
from spotframework.model.user import User
|
from spotframework.model.user import User
|
||||||
from spotframework.model.service import Context
|
from spotframework.model.service import Context
|
||||||
@ -20,6 +20,7 @@ class Track:
|
|||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
|
||||||
disc_number: int = None,
|
disc_number: int = None,
|
||||||
|
track_number: int = None,
|
||||||
duration_ms: int = None,
|
duration_ms: int = None,
|
||||||
excplicit: bool = None
|
excplicit: bool = None
|
||||||
):
|
):
|
||||||
@ -28,6 +29,7 @@ class Track:
|
|||||||
self.artists = artists
|
self.artists = artists
|
||||||
|
|
||||||
self.disc_number = disc_number
|
self.disc_number = disc_number
|
||||||
|
self.track_number = track_number
|
||||||
self.duration_ms = duration_ms
|
self.duration_ms = duration_ms
|
||||||
self.explicit = excplicit
|
self.explicit = excplicit
|
||||||
|
|
||||||
@ -69,13 +71,14 @@ class Track:
|
|||||||
class SpotifyTrack(Track):
|
class SpotifyTrack(Track):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
album: Album,
|
album: SpotifyAlbum,
|
||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
|
||||||
href: str = None,
|
href: str = None,
|
||||||
uri: Union[str, Uri] = None,
|
uri: Union[str, Uri] = None,
|
||||||
|
|
||||||
disc_number: int = None,
|
disc_number: int = None,
|
||||||
|
track_number: int = None,
|
||||||
duration_ms: int = None,
|
duration_ms: int = None,
|
||||||
explicit: bool = None,
|
explicit: bool = None,
|
||||||
is_playable: bool = None,
|
is_playable: bool = None,
|
||||||
@ -86,6 +89,7 @@ class SpotifyTrack(Track):
|
|||||||
):
|
):
|
||||||
super().__init__(name=name, album=album, artists=artists,
|
super().__init__(name=name, album=album, artists=artists,
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
excplicit=explicit)
|
excplicit=explicit)
|
||||||
|
|
||||||
@ -131,13 +135,14 @@ class SpotifyTrack(Track):
|
|||||||
class LibraryTrack(SpotifyTrack):
|
class LibraryTrack(SpotifyTrack):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
album: Album,
|
album: SpotifyAlbum,
|
||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
|
||||||
href: str = None,
|
href: str = None,
|
||||||
uri: Union[str, Uri] = None,
|
uri: Union[str, Uri] = None,
|
||||||
|
|
||||||
disc_number: int = None,
|
disc_number: int = None,
|
||||||
|
track_number: int = None,
|
||||||
duration_ms: int = None,
|
duration_ms: int = None,
|
||||||
explicit: bool = None,
|
explicit: bool = None,
|
||||||
is_playable: bool = None,
|
is_playable: bool = None,
|
||||||
@ -153,6 +158,7 @@ class LibraryTrack(SpotifyTrack):
|
|||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
@ -174,7 +180,7 @@ class LibraryTrack(SpotifyTrack):
|
|||||||
class PlaylistTrack(SpotifyTrack):
|
class PlaylistTrack(SpotifyTrack):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
album: Album,
|
album: SpotifyAlbum,
|
||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
|
||||||
added_at: datetime,
|
added_at: datetime,
|
||||||
@ -185,6 +191,7 @@ class PlaylistTrack(SpotifyTrack):
|
|||||||
uri: Union[str, Uri] = None,
|
uri: Union[str, Uri] = None,
|
||||||
|
|
||||||
disc_number: int = None,
|
disc_number: int = None,
|
||||||
|
track_number: int = None,
|
||||||
duration_ms: int = None,
|
duration_ms: int = None,
|
||||||
explicit: bool = None,
|
explicit: bool = None,
|
||||||
is_playable: bool = None,
|
is_playable: bool = None,
|
||||||
@ -198,6 +205,7 @@ class PlaylistTrack(SpotifyTrack):
|
|||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
@ -221,13 +229,14 @@ class PlaylistTrack(SpotifyTrack):
|
|||||||
class PlayedTrack(SpotifyTrack):
|
class PlayedTrack(SpotifyTrack):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
album: Album,
|
album: SpotifyAlbum,
|
||||||
artists: List[Artist],
|
artists: List[Artist],
|
||||||
|
|
||||||
href: str = None,
|
href: str = None,
|
||||||
uri: Union[str, Uri] = None,
|
uri: Union[str, Uri] = None,
|
||||||
|
|
||||||
disc_number: int = None,
|
disc_number: int = None,
|
||||||
|
track_number: int = None,
|
||||||
duration_ms: int = None,
|
duration_ms: int = None,
|
||||||
explicit: bool = None,
|
explicit: bool = None,
|
||||||
is_playable: bool = None,
|
is_playable: bool = None,
|
||||||
@ -245,6 +254,7 @@ class PlayedTrack(SpotifyTrack):
|
|||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
|
track_number=track_number,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
popularity=popularity,
|
popularity=popularity,
|
||||||
|
@ -1062,6 +1062,11 @@ class Network:
|
|||||||
|
|
||||||
artists = [self.parse_artist(i) for i in album.get('artists', [])]
|
artists = [self.parse_artist(i) for i in album.get('artists', [])]
|
||||||
|
|
||||||
|
if album.get("album_type") is not None:
|
||||||
|
album_type = SpotifyAlbum.Type[album.get('album_type').lower()]
|
||||||
|
else:
|
||||||
|
album_type = SpotifyAlbum.Type.single
|
||||||
|
|
||||||
href = album.get('href', None)
|
href = album.get('href', None)
|
||||||
uri = album.get('uri', None)
|
uri = album.get('uri', None)
|
||||||
|
|
||||||
@ -1092,6 +1097,8 @@ class Network:
|
|||||||
return LibraryAlbum(name=name,
|
return LibraryAlbum(name=name,
|
||||||
artists=artists,
|
artists=artists,
|
||||||
|
|
||||||
|
album_type=album_type,
|
||||||
|
|
||||||
href=href,
|
href=href,
|
||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
@ -1109,6 +1116,8 @@ class Network:
|
|||||||
return SpotifyAlbum(name=name,
|
return SpotifyAlbum(name=name,
|
||||||
artists=artists,
|
artists=artists,
|
||||||
|
|
||||||
|
album_type=album_type,
|
||||||
|
|
||||||
href=href,
|
href=href,
|
||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
@ -1143,6 +1152,7 @@ class Network:
|
|||||||
uri = track.get('uri', None)
|
uri = track.get('uri', None)
|
||||||
|
|
||||||
disc_number = track.get('disc_number', None)
|
disc_number = track.get('disc_number', None)
|
||||||
|
track_number = track.get('track_number', None)
|
||||||
duration_ms = track.get('duration_ms', None)
|
duration_ms = track.get('duration_ms', None)
|
||||||
explicit = track.get('explicit', None)
|
explicit = track.get('explicit', None)
|
||||||
is_playable = track.get('is_playable', None)
|
is_playable = track.get('is_playable', None)
|
||||||
@ -1175,6 +1185,7 @@ class Network:
|
|||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
@ -1189,6 +1200,7 @@ class Network:
|
|||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
@ -1204,6 +1216,7 @@ class Network:
|
|||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
@ -1220,6 +1233,7 @@ class Network:
|
|||||||
uri=uri,
|
uri=uri,
|
||||||
|
|
||||||
disc_number=disc_number,
|
disc_number=disc_number,
|
||||||
|
track_number=track_number,
|
||||||
duration_ms=duration_ms,
|
duration_ms=duration_ms,
|
||||||
explicit=explicit,
|
explicit=explicit,
|
||||||
is_playable=is_playable,
|
is_playable=is_playable,
|
||||||
|
Loading…
Reference in New Issue
Block a user