Code parity with deemix-js
This commit is contained in:
@ -10,21 +10,21 @@ class Album:
|
||||
def __init__(self, alb_id="0", title="", pic_md5=""):
|
||||
self.id = alb_id
|
||||
self.title = title
|
||||
self.pic = Picture(md5=pic_md5, type="cover")
|
||||
self.pic = Picture(pic_md5, "cover")
|
||||
self.artist = {"Main": []}
|
||||
self.artists = []
|
||||
self.mainArtist = None
|
||||
self.date = None
|
||||
self.dateString = None
|
||||
self.date = Date()
|
||||
self.dateString = ""
|
||||
self.trackTotal = "0"
|
||||
self.discTotal = "0"
|
||||
self.embeddedCoverPath = None
|
||||
self.embeddedCoverURL = None
|
||||
self.embeddedCoverPath = ""
|
||||
self.embeddedCoverURL = ""
|
||||
self.explicit = False
|
||||
self.genre = []
|
||||
self.barcode = "Unknown"
|
||||
self.label = "Unknown"
|
||||
self.copyright = None
|
||||
self.copyright = ""
|
||||
self.recordType = "album"
|
||||
self.bitrate = 0
|
||||
self.rootArtist = None
|
||||
@ -32,26 +32,29 @@ class Album:
|
||||
|
||||
self.playlistId = None
|
||||
self.owner = None
|
||||
self.isPlaylist = False
|
||||
|
||||
def parseAlbum(self, albumAPI):
|
||||
self.title = albumAPI['title']
|
||||
|
||||
# Getting artist image ID
|
||||
# ex: https://e-cdns-images.dzcdn.net/images/artist/f2bc007e9133c946ac3c3907ddc5d2ea/56x56-000000-80-0-0.jpg
|
||||
artistPicture = albumAPI['artist']['picture_small']
|
||||
artistPicture = artistPicture[artistPicture.find('artist/') + 7:-24]
|
||||
art_pic = albumAPI['artist']['picture_small']
|
||||
art_pic = art_pic[art_pic.find('artist/') + 7:-24]
|
||||
self.mainArtist = Artist(
|
||||
id = albumAPI['artist']['id'],
|
||||
name = albumAPI['artist']['name'],
|
||||
pic_md5 = artistPicture
|
||||
albumAPI['artist']['id'],
|
||||
albumAPI['artist']['name'],
|
||||
"Main",
|
||||
art_pic
|
||||
)
|
||||
if albumAPI.get('root_artist'):
|
||||
artistPicture = albumAPI['root_artist']['picture_small']
|
||||
artistPicture = artistPicture[artistPicture.find('artist/') + 7:-24]
|
||||
art_pic = albumAPI['root_artist']['picture_small']
|
||||
art_pic = art_pic[art_pic.find('artist/') + 7:-24]
|
||||
self.rootArtist = Artist(
|
||||
id = albumAPI['root_artist']['id'],
|
||||
name = albumAPI['root_artist']['name'],
|
||||
pic_md5 = artistPicture
|
||||
albumAPI['root_artist']['id'],
|
||||
albumAPI['root_artist']['name'],
|
||||
"Root",
|
||||
art_pic
|
||||
)
|
||||
|
||||
for artist in albumAPI['contributors']:
|
||||
@ -60,7 +63,7 @@ class Album:
|
||||
|
||||
if isVariousArtists:
|
||||
self.variousArtists = Artist(
|
||||
id = artist['id'],
|
||||
art_id = artist['id'],
|
||||
name = artist['name'],
|
||||
role = artist['role']
|
||||
)
|
||||
@ -81,10 +84,10 @@ class Album:
|
||||
self.label = albumAPI.get('label', self.label)
|
||||
self.explicit = bool(albumAPI.get('explicit_lyrics', False))
|
||||
if 'release_date' in albumAPI:
|
||||
day = albumAPI["release_date"][8:10]
|
||||
month = albumAPI["release_date"][5:7]
|
||||
year = albumAPI["release_date"][0:4]
|
||||
self.date = Date(day, month, year)
|
||||
self.date.day = albumAPI["release_date"][8:10]
|
||||
self.date.month = albumAPI["release_date"][5:7]
|
||||
self.date.year = albumAPI["release_date"][0:4]
|
||||
self.date.fixDayMonth()
|
||||
|
||||
self.discTotal = albumAPI.get('nb_disk')
|
||||
self.copyright = albumAPI.get('copyright')
|
||||
@ -92,7 +95,8 @@ class Album:
|
||||
if self.pic.md5 == "":
|
||||
# Getting album cover MD5
|
||||
# ex: https://e-cdns-images.dzcdn.net/images/cover/2e018122cb56986277102d2041a592c8/56x56-000000-80-0-0.jpg
|
||||
self.pic.md5 = albumAPI['cover_small'][albumAPI['cover_small'].find('cover/') + 6:-24]
|
||||
alb_pic = albumAPI['cover_small']
|
||||
self.pic.md5 = alb_pic[alb_pic.find('cover/') + 6:-24]
|
||||
|
||||
if albumAPI.get('genres') and len(albumAPI['genres'].get('data', [])) > 0:
|
||||
for genre in albumAPI['genres']['data']:
|
||||
@ -101,8 +105,9 @@ class Album:
|
||||
def parseAlbumGW(self, albumAPI_gw):
|
||||
self.title = albumAPI_gw['ALB_TITLE']
|
||||
self.mainArtist = Artist(
|
||||
id = albumAPI_gw['ART_ID'],
|
||||
name = albumAPI_gw['ART_NAME']
|
||||
art_id = albumAPI_gw['ART_ID'],
|
||||
name = albumAPI_gw['ART_NAME'],
|
||||
role = "Main"
|
||||
)
|
||||
|
||||
self.artists = [albumAPI_gw['ART_NAME']]
|
||||
@ -113,13 +118,16 @@ class Album:
|
||||
explicitLyricsStatus = albumAPI_gw.get('EXPLICIT_ALBUM_CONTENT', {}).get('EXPLICIT_LYRICS_STATUS', LyricsStatus.UNKNOWN)
|
||||
self.explicit = explicitLyricsStatus in [LyricsStatus.EXPLICIT, LyricsStatus.PARTIALLY_EXPLICIT]
|
||||
|
||||
self.addExtraAlbumGWData(albumAPI_gw)
|
||||
|
||||
def addExtraAlbumGWData(self, albumAPI_gw):
|
||||
if self.pic.md5 == "":
|
||||
self.pic.md5 = albumAPI_gw['ALB_PICTURE']
|
||||
if 'PHYSICAL_RELEASE_DATE' in albumAPI_gw:
|
||||
day = albumAPI_gw["PHYSICAL_RELEASE_DATE"][8:10]
|
||||
month = albumAPI_gw["PHYSICAL_RELEASE_DATE"][5:7]
|
||||
year = albumAPI_gw["PHYSICAL_RELEASE_DATE"][0:4]
|
||||
self.date = Date(day, month, year)
|
||||
self.date.day = albumAPI_gw["PHYSICAL_RELEASE_DATE"][8:10]
|
||||
self.date.month = albumAPI_gw["PHYSICAL_RELEASE_DATE"][5:7]
|
||||
self.date.year = albumAPI_gw["PHYSICAL_RELEASE_DATE"][0:4]
|
||||
self.date.fixDayMonth()
|
||||
|
||||
def makePlaylistCompilation(self, playlist):
|
||||
self.variousArtists = playlist.variousArtists
|
||||
@ -138,6 +146,7 @@ class Album:
|
||||
self.playlistId = playlist.playlistId
|
||||
self.owner = playlist.owner
|
||||
self.pic = playlist.pic
|
||||
self.isPlaylist = True
|
||||
|
||||
def removeDuplicateArtists(self):
|
||||
"""Removes duplicate artists for both artist array and artists dict"""
|
||||
|
@ -5,7 +5,7 @@ class Artist:
|
||||
def __init__(self, art_id="0", name="", role="", pic_md5=""):
|
||||
self.id = str(art_id)
|
||||
self.name = name
|
||||
self.pic = Picture(md5=pic_md5, type="artist")
|
||||
self.pic = Picture(md5=pic_md5, pic_type="artist")
|
||||
self.role = role
|
||||
self.save = True
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
class Date:
|
||||
def __init__(self, day="00", month="00", year="XXXX"):
|
||||
self.year = year
|
||||
self.month = month
|
||||
self.day = day
|
||||
self.month = month
|
||||
self.year = year
|
||||
self.fixDayMonth()
|
||||
|
||||
# Fix incorrect day month when detectable
|
||||
|
@ -1,5 +1,5 @@
|
||||
class IDownloadObject:
|
||||
"""DownloadObject interface"""
|
||||
"""DownloadObject Interface"""
|
||||
def __init__(self, obj):
|
||||
self.type = obj['type']
|
||||
self.id = obj['id']
|
||||
@ -16,7 +16,6 @@ class IDownloadObject:
|
||||
self.files = obj.get('files', [])
|
||||
self.progressNext = 0
|
||||
self.uuid = f"{self.type}_{self.id}_{self.bitrate}"
|
||||
self.ack = None
|
||||
self.__type__ = None
|
||||
|
||||
def toDict(self):
|
||||
@ -35,7 +34,6 @@ class IDownloadObject:
|
||||
'progress': self.progress,
|
||||
'errors': self.errors,
|
||||
'files': self.files,
|
||||
'ack': self.ack,
|
||||
'__type__': self.__type__
|
||||
}
|
||||
|
||||
@ -50,16 +48,29 @@ class IDownloadObject:
|
||||
|
||||
def getSlimmedDict(self):
|
||||
light = self.toDict()
|
||||
propertiesToDelete = ['single', 'collection', 'convertable']
|
||||
propertiesToDelete = ['single', 'collection', 'plugin', 'conversion_data']
|
||||
for prop in propertiesToDelete:
|
||||
if prop in light:
|
||||
del light[prop]
|
||||
return light
|
||||
|
||||
def updateProgress(self, interface=None):
|
||||
def getEssentialDict(self):
|
||||
return {
|
||||
'type': self.type,
|
||||
'id': self.id,
|
||||
'bitrate': self.bitrate,
|
||||
'uuid': self.uuid,
|
||||
'title': self.title,
|
||||
'artist': self.artist,
|
||||
'cover': self.cover,
|
||||
'explicit': self.explicit,
|
||||
'size': self.size
|
||||
}
|
||||
|
||||
def updateProgress(self, listener=None):
|
||||
if round(self.progressNext) != self.progress and round(self.progressNext) % 2 == 0:
|
||||
self.progress = round(self.progressNext)
|
||||
if interface: interface.send("updateQueue", {'uuid': self.uuid, 'progress': self.progress})
|
||||
if listener: listener.send("updateQueue", {'uuid': self.uuid, 'progress': self.progress})
|
||||
|
||||
class Single(IDownloadObject):
|
||||
def __init__(self, obj):
|
||||
@ -73,13 +84,13 @@ class Single(IDownloadObject):
|
||||
item['single'] = self.single
|
||||
return item
|
||||
|
||||
def completeTrackProgress(self, interface=None):
|
||||
def completeTrackProgress(self, listener=None):
|
||||
self.progressNext = 100
|
||||
self.updateProgress(interface)
|
||||
self.updateProgress(listener)
|
||||
|
||||
def removeTrackProgress(self, interface=None):
|
||||
def removeTrackProgress(self, listener=None):
|
||||
self.progressNext = 0
|
||||
self.updateProgress(interface)
|
||||
self.updateProgress(listener)
|
||||
|
||||
class Collection(IDownloadObject):
|
||||
def __init__(self, obj):
|
||||
@ -92,13 +103,13 @@ class Collection(IDownloadObject):
|
||||
item['collection'] = self.collection
|
||||
return item
|
||||
|
||||
def completeTrackProgress(self, interface=None):
|
||||
def completeTrackProgress(self, listener=None):
|
||||
self.progressNext += (1 / self.size) * 100
|
||||
self.updateProgress(interface)
|
||||
self.updateProgress(listener)
|
||||
|
||||
def removeTrackProgress(self, interface=None):
|
||||
def removeTrackProgress(self, listener=None):
|
||||
self.progressNext -= (1 / self.size) * 100
|
||||
self.updateProgress(interface)
|
||||
self.updateProgress(listener)
|
||||
|
||||
class Convertable(Collection):
|
||||
def __init__(self, obj):
|
||||
|
@ -19,6 +19,6 @@ class Lyrics:
|
||||
else:
|
||||
notEmptyLine = line + 1
|
||||
while syncLyricsJson[notEmptyLine]["line"] == "":
|
||||
notEmptyLine = notEmptyLine + 1
|
||||
notEmptyLine += 1
|
||||
timestamp = syncLyricsJson[notEmptyLine]["lrc_timestamp"]
|
||||
self.sync += timestamp + syncLyricsJson[line]["line"] + "\r\n"
|
||||
|
@ -1,12 +1,9 @@
|
||||
class Picture:
|
||||
def __init__(self, md5="", pic_type="", url=None):
|
||||
def __init__(self, md5="", pic_type=""):
|
||||
self.md5 = md5
|
||||
self.type = pic_type
|
||||
self.staticUrl = url
|
||||
|
||||
def generatePictureURL(self, size, pic_format):
|
||||
if self.staticUrl: return self.staticUrl
|
||||
|
||||
def getURL(self, size, pic_format):
|
||||
url = "https://e-cdns-images.dzcdn.net/images/{}/{}/{size}x{size}".format(
|
||||
self.type,
|
||||
self.md5,
|
||||
@ -23,3 +20,10 @@ class Picture:
|
||||
return url + '-none-100-0-0.png'
|
||||
|
||||
return url+'.jpg'
|
||||
|
||||
class StaticPicture:
|
||||
def __init__(self, url):
|
||||
self.staticURL = url
|
||||
|
||||
def getURL(self):
|
||||
return self.staticURL
|
||||
|
@ -1,6 +1,6 @@
|
||||
from deemix.types.Artist import Artist
|
||||
from deemix.types.Date import Date
|
||||
from deemix.types.Picture import Picture
|
||||
from deemix.types.Picture import Picture, StaticPicture
|
||||
|
||||
class Playlist:
|
||||
def __init__(self, playlistAPI):
|
||||
@ -30,20 +30,17 @@ class Playlist:
|
||||
picType = url[url.find('images/')+7:]
|
||||
picType = picType[:picType.find('/')]
|
||||
md5 = url[url.find(picType+'/') + len(picType)+1:-24]
|
||||
self.pic = Picture(
|
||||
md5 = md5,
|
||||
pic_type = picType
|
||||
)
|
||||
self.pic = Picture(md5, picType)
|
||||
else:
|
||||
self.pic = Picture(url = playlistAPI['picture_xl'])
|
||||
self.pic = StaticPicture(playlistAPI['picture_xl'])
|
||||
|
||||
if 'various_artist' in playlistAPI:
|
||||
pic_md5 = playlistAPI['various_artist']['picture_small']
|
||||
pic_md5 = pic_md5[pic_md5.find('artist/') + 7:-24]
|
||||
self.variousArtists = Artist(
|
||||
art_id = playlistAPI['various_artist']['id'],
|
||||
name = playlistAPI['various_artist']['name'],
|
||||
role = "Main",
|
||||
pic_md5 = pic_md5
|
||||
playlistAPI['various_artist']['id'],
|
||||
playlistAPI['various_artist']['name'],
|
||||
"Main",
|
||||
pic_md5
|
||||
)
|
||||
self.mainArtist = self.variousArtists
|
||||
|
@ -26,14 +26,14 @@ class Track:
|
||||
self.duration = 0
|
||||
self.fallbackID = "0"
|
||||
self.filesizes = {}
|
||||
self.localTrack = False
|
||||
self.local = False
|
||||
self.mainArtist = None
|
||||
self.artist = {"Main": []}
|
||||
self.artists = []
|
||||
self.album = None
|
||||
self.trackNumber = "0"
|
||||
self.discNumber = "0"
|
||||
self.date = None
|
||||
self.date = Date()
|
||||
self.lyrics = None
|
||||
self.bpm = 0
|
||||
self.contributors = {}
|
||||
@ -64,7 +64,7 @@ class Track:
|
||||
self.fallbackID = "0"
|
||||
if 'FALLBACK' in trackAPI_gw:
|
||||
self.fallbackID = trackAPI_gw['FALLBACK']['SNG_ID']
|
||||
self.localTrack = int(self.id) < 0
|
||||
self.local = int(self.id) < 0
|
||||
|
||||
def retriveFilesizes(self, dz):
|
||||
guest_sid = dz.session.cookies.get('sid')
|
||||
@ -87,8 +87,8 @@ class Track:
|
||||
sleep(2)
|
||||
self.retriveFilesizes(dz)
|
||||
if len(result_json['error']):
|
||||
raise APIError(result_json.dumps(result_json['error']))
|
||||
response = result_json.get("results")
|
||||
raise TrackError(result_json.dumps(result_json['error']))
|
||||
response = result_json.get("results", {})
|
||||
filesizes = {}
|
||||
for key, value in response.items():
|
||||
if key.startswith("FILESIZE_"):
|
||||
@ -96,8 +96,8 @@ class Track:
|
||||
filesizes[key+"_TESTED"] = False
|
||||
self.filesizes = filesizes
|
||||
|
||||
def parseData(self, dz, id=None, trackAPI_gw=None, trackAPI=None, albumAPI_gw=None, albumAPI=None, playlistAPI=None):
|
||||
if id and not trackAPI_gw: trackAPI_gw = dz.gw.get_track_with_fallback(id)
|
||||
def parseData(self, dz, track_id=None, trackAPI_gw=None, trackAPI=None, albumAPI_gw=None, albumAPI=None, playlistAPI=None):
|
||||
if track_id and not trackAPI_gw: trackAPI_gw = dz.gw.get_track_with_fallback(track_id)
|
||||
elif not trackAPI_gw: raise NoDataToParse
|
||||
if not trackAPI:
|
||||
try: trackAPI = dz.api.get_track(trackAPI_gw['SNG_ID'])
|
||||
@ -105,7 +105,7 @@ class Track:
|
||||
|
||||
self.parseEssentialData(trackAPI_gw, trackAPI)
|
||||
|
||||
if self.localTrack:
|
||||
if self.local:
|
||||
self.parseLocalTrackData(trackAPI_gw)
|
||||
else:
|
||||
self.retriveFilesizes(dz)
|
||||
@ -147,6 +147,7 @@ class Track:
|
||||
raise AlbumDoesntExists
|
||||
|
||||
# Fill missing data
|
||||
if albumAPI_gw: self.album.addExtraAlbumGWData(albumAPI_gw)
|
||||
if self.album.date and not self.date: self.date = self.album.date
|
||||
if not self.album.discTotal: self.album.discTotal = albumAPI_gw.get('NUMBER_DISK', "1")
|
||||
if not self.copyright: self.copyright = albumAPI_gw['COPYRIGHT']
|
||||
@ -157,10 +158,9 @@ class Track:
|
||||
self.title = ' '.join(self.title.split())
|
||||
|
||||
# Make sure there is at least one artist
|
||||
if not len(self.artist['Main']):
|
||||
if len(self.artist['Main']) == 0:
|
||||
self.artist['Main'] = [self.mainArtist['name']]
|
||||
|
||||
self.singleDownload = trackAPI_gw.get('SINGLE_TRACK', False) # TODO: Change
|
||||
self.position = trackAPI_gw.get('POSITION')
|
||||
|
||||
# Add playlist data if track is in a playlist
|
||||
@ -178,12 +178,11 @@ class Track:
|
||||
md5 = trackAPI_gw.get('ALB_PICTURE', ""),
|
||||
pic_type = "cover"
|
||||
)
|
||||
self.mainArtist = Artist(name=trackAPI_gw['ART_NAME'])
|
||||
self.mainArtist = Artist(name=trackAPI_gw['ART_NAME'], role="Main")
|
||||
self.artists = [trackAPI_gw['ART_NAME']]
|
||||
self.artist = {
|
||||
'Main': [trackAPI_gw['ART_NAME']]
|
||||
}
|
||||
self.date = Date()
|
||||
self.album.artist = self.artist
|
||||
self.album.artists = self.artists
|
||||
self.album.date = self.date
|
||||
@ -207,14 +206,15 @@ class Track:
|
||||
self.mainArtist = Artist(
|
||||
art_id = trackAPI_gw['ART_ID'],
|
||||
name = trackAPI_gw['ART_NAME'],
|
||||
role = "Main",
|
||||
pic_md5 = trackAPI_gw.get('ART_PICTURE')
|
||||
)
|
||||
|
||||
if 'PHYSICAL_RELEASE_DATE' in trackAPI_gw:
|
||||
day = trackAPI_gw["PHYSICAL_RELEASE_DATE"][8:10]
|
||||
month = trackAPI_gw["PHYSICAL_RELEASE_DATE"][5:7]
|
||||
year = trackAPI_gw["PHYSICAL_RELEASE_DATE"][0:4]
|
||||
self.date = Date(day, month, year)
|
||||
self.date.day = trackAPI_gw["PHYSICAL_RELEASE_DATE"][8:10]
|
||||
self.date.month = trackAPI_gw["PHYSICAL_RELEASE_DATE"][5:7]
|
||||
self.date.year = trackAPI_gw["PHYSICAL_RELEASE_DATE"][0:4]
|
||||
self.date.fixDayMonth()
|
||||
|
||||
def parseTrack(self, trackAPI):
|
||||
self.bpm = trackAPI['bpm']
|
||||
@ -249,7 +249,7 @@ class Track:
|
||||
return removeFeatures(self.title)
|
||||
|
||||
def getFeatTitle(self):
|
||||
if self.featArtistsString and not "feat." in self.title.lower():
|
||||
if self.featArtistsString and "feat." not in self.title.lower():
|
||||
return f"{self.title} ({self.featArtistsString})"
|
||||
return self.title
|
||||
|
||||
@ -259,26 +259,15 @@ class Track:
|
||||
if 'Featured' in self.artist:
|
||||
self.featArtistsString = "feat. "+andCommaConcat(self.artist['Featured'])
|
||||
|
||||
def applySettings(self, settings, TEMPDIR, embeddedImageFormat):
|
||||
def applySettings(self, settings):
|
||||
|
||||
# Check if should save the playlist as a compilation
|
||||
if self.playlist and settings['tags']['savePlaylistAsCompilation']:
|
||||
self.trackNumber = self.position
|
||||
self.discNumber = "1"
|
||||
self.album.makePlaylistCompilation(self.playlist)
|
||||
self.album.embeddedCoverURL = self.playlist.pic.generatePictureURL(settings['embeddedArtworkSize'], embeddedImageFormat)
|
||||
|
||||
ext = self.album.embeddedCoverURL[-4:]
|
||||
if ext[0] != ".": ext = ".jpg" # Check for Spotify images
|
||||
|
||||
# TODO: FIX
|
||||
# self.album.embeddedCoverPath = TEMPDIR / f"pl{trackAPI_gw['_EXTRA_PLAYLIST']['id']}_{settings['embeddedArtworkSize']}{ext}"
|
||||
else:
|
||||
if self.album.date: self.date = self.album.date
|
||||
self.album.embeddedCoverURL = self.album.pic.generatePictureURL(settings['embeddedArtworkSize'], embeddedImageFormat)
|
||||
|
||||
ext = self.album.embeddedCoverURL[-4:]
|
||||
self.album.embeddedCoverPath = TEMPDIR / f"alb{self.album.id}_{settings['embeddedArtworkSize']}{ext}"
|
||||
|
||||
self.dateString = self.date.format(settings['dateFormat'])
|
||||
self.album.dateString = self.album.date.format(settings['dateFormat'])
|
||||
@ -311,9 +300,8 @@ class Track:
|
||||
self.album.title = self.album.getCleanTitle()
|
||||
|
||||
# Remove (Album Version) from tracks that have that
|
||||
if settings['removeAlbumVersion']:
|
||||
if "Album Version" in self.title:
|
||||
self.title = re.sub(r' ?\(Album Version\)', "", self.title).strip()
|
||||
if settings['removeAlbumVersion'] and "Album Version" in self.title:
|
||||
self.title = re.sub(r' ?\(Album Version\)', "", self.title).strip()
|
||||
|
||||
# Change Title and Artists casing if needed
|
||||
if settings['titleCasing'] != "nothing":
|
||||
|
Reference in New Issue
Block a user