More code cleanup
This commit is contained in:
parent
975fdf95dd
commit
4a573233a1
|
@ -12,6 +12,32 @@ import json
|
||||||
USER_AGENT_HEADER = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " \
|
USER_AGENT_HEADER = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " \
|
||||||
"Chrome/79.0.3945.130 Safari/537.36"
|
"Chrome/79.0.3945.130 Safari/537.36"
|
||||||
|
|
||||||
|
class LyricsStatus():
|
||||||
|
"""Explicit Content Lyrics"""
|
||||||
|
|
||||||
|
NOT_EXPLICIT = 0
|
||||||
|
"""Not Explicit"""
|
||||||
|
|
||||||
|
EXPLICIT = 1
|
||||||
|
"""Explicit"""
|
||||||
|
|
||||||
|
UNKNOWN = 2
|
||||||
|
"""Unknown"""
|
||||||
|
|
||||||
|
EDITED = 3
|
||||||
|
"""Edited"""
|
||||||
|
|
||||||
|
PARTIALLY_EXPLICIT = 4
|
||||||
|
"""Partially Explicit (Album "lyrics" only)"""
|
||||||
|
|
||||||
|
PARTIALLY_UNKNOWN = 5
|
||||||
|
"""Partially Unknown (Album "lyrics" only)"""
|
||||||
|
|
||||||
|
NO_ADVICE = 6
|
||||||
|
"""No Advice Available"""
|
||||||
|
|
||||||
|
PARTIALLY_NO_ADVICE = 7
|
||||||
|
"""Partially No Advice Available (Album "lyrics" only)"""
|
||||||
|
|
||||||
class Deezer:
|
class Deezer:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -12,7 +12,7 @@ from os import makedirs, remove, system as execute
|
||||||
from tempfile import gettempdir
|
from tempfile import gettempdir
|
||||||
|
|
||||||
from deemix.app.queueitem import QISingle, QICollection
|
from deemix.app.queueitem import QISingle, QICollection
|
||||||
from deemix.app.track import Track
|
from deemix.app.track import Track, AlbumDoesntExsists
|
||||||
from deemix.utils import changeCase
|
from deemix.utils import changeCase
|
||||||
from deemix.utils.pathtemplates import generateFilename, generateFilepath, settingsRegexAlbum, settingsRegexArtist, settingsRegexPlaylistFile
|
from deemix.utils.pathtemplates import generateFilename, generateFilepath, settingsRegexAlbum, settingsRegexArtist, settingsRegexPlaylistFile
|
||||||
from deemix.api.deezer import USER_AGENT_HEADER
|
from deemix.api.deezer import USER_AGENT_HEADER
|
||||||
|
@ -49,7 +49,8 @@ errorMessages = {
|
||||||
'no360RA': "Track is not available in Reality Audio 360.",
|
'no360RA': "Track is not available in Reality Audio 360.",
|
||||||
'notAvailable': "Track not available on deezer's servers!",
|
'notAvailable': "Track not available on deezer's servers!",
|
||||||
'notAvailableNoAlternative': "Track not available on deezer's servers and no alternative found!",
|
'notAvailableNoAlternative': "Track not available on deezer's servers and no alternative found!",
|
||||||
'noSpaceLeft': "No space left on target drive, clean up some space for the tracks"
|
'noSpaceLeft': "No space left on target drive, clean up some space for the tracks",
|
||||||
|
'albumDoesntExsists': "Track's album does not exsist, failed to gather info"
|
||||||
}
|
}
|
||||||
def downloadImage(url, path, overwrite="n"):
|
def downloadImage(url, path, overwrite="n"):
|
||||||
if not os.path.isfile(path) or overwrite in ['y', 't', 'b']:
|
if not os.path.isfile(path) or overwrite in ['y', 't', 'b']:
|
||||||
|
@ -220,12 +221,15 @@ class DownloadJob:
|
||||||
# Create Track object
|
# Create Track object
|
||||||
if not track:
|
if not track:
|
||||||
logger.info(f"[{trackAPI_gw['ART_NAME']} - {trackAPI_gw['SNG_TITLE']}] Getting the tags")
|
logger.info(f"[{trackAPI_gw['ART_NAME']} - {trackAPI_gw['SNG_TITLE']}] Getting the tags")
|
||||||
|
try:
|
||||||
track = Track(self.dz,
|
track = Track(self.dz,
|
||||||
settings=self.settings,
|
settings=self.settings,
|
||||||
trackAPI_gw=trackAPI_gw,
|
trackAPI_gw=trackAPI_gw,
|
||||||
trackAPI=trackAPI_gw['_EXTRA_TRACK'] if '_EXTRA_TRACK' in trackAPI_gw else None,
|
trackAPI=trackAPI_gw['_EXTRA_TRACK'] if '_EXTRA_TRACK' in trackAPI_gw else None,
|
||||||
albumAPI=trackAPI_gw['_EXTRA_ALBUM'] if '_EXTRA_ALBUM' in trackAPI_gw else None
|
albumAPI=trackAPI_gw['_EXTRA_ALBUM'] if '_EXTRA_ALBUM' in trackAPI_gw else None
|
||||||
)
|
)
|
||||||
|
except AlbumDoesntExsists:
|
||||||
|
raise DownloadError('albumDoesntExsists')
|
||||||
if self.queueItem.cancel: raise DownloadCancelled
|
if self.queueItem.cancel: raise DownloadCancelled
|
||||||
|
|
||||||
if track.MD5 == '':
|
if track.MD5 == '':
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from deemix.api.deezer import APIError
|
from deemix.api.deezer import APIError, LyricsStatus
|
||||||
from deemix.utils import removeFeatures, andCommaConcat, uniqueArray
|
from deemix.utils import removeFeatures, andCommaConcat, uniqueArray, generateReplayGainString
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
logger = logging.getLogger('deemix')
|
logger = logging.getLogger('deemix')
|
||||||
|
|
||||||
|
VARIOUS_ARTISTS = 5080
|
||||||
|
|
||||||
class Track:
|
class Track:
|
||||||
def __init__(self, dz, settings, trackAPI_gw, trackAPI=None, albumAPI_gw=None, albumAPI=None):
|
def __init__(self, dz, settings, trackAPI_gw, trackAPI=None, albumAPI_gw=None, albumAPI=None):
|
||||||
self.parseEssentialData(dz, trackAPI_gw)
|
self.parseEssentialData(dz, trackAPI_gw)
|
||||||
|
@ -22,6 +24,7 @@ class Track:
|
||||||
else:
|
else:
|
||||||
self.parseData(dz, settings, trackAPI_gw, trackAPI, albumAPI_gw, albumAPI)
|
self.parseData(dz, settings, trackAPI_gw, trackAPI, albumAPI_gw, albumAPI)
|
||||||
|
|
||||||
|
# Make sure there is at least one artist
|
||||||
if not 'Main' in self.artist:
|
if not 'Main' in self.artist:
|
||||||
self.artist['Main'] = [self.mainArtist['name']]
|
self.artist['Main'] = [self.mainArtist['name']]
|
||||||
|
|
||||||
|
@ -38,6 +41,297 @@ class Track:
|
||||||
# Add playlist data if track is in a playlist
|
# Add playlist data if track is in a playlist
|
||||||
self.playlist = None
|
self.playlist = None
|
||||||
if "_EXTRA_PLAYLIST" in trackAPI_gw:
|
if "_EXTRA_PLAYLIST" in trackAPI_gw:
|
||||||
|
self.parsePlaylistData()
|
||||||
|
|
||||||
|
self.generateMainFeatStrings()
|
||||||
|
|
||||||
|
# Bits useful for later
|
||||||
|
self.searched = False
|
||||||
|
self.selectedFormat = 0
|
||||||
|
self.dateString = None
|
||||||
|
self.album['picUrl'] = None
|
||||||
|
self.album['picPath'] = None
|
||||||
|
self.album['bitrate'] = 0
|
||||||
|
self.album['dateString'] = None
|
||||||
|
self.artistsString = ""
|
||||||
|
|
||||||
|
def parseEssentialData(self, dz, trackAPI_gw):
|
||||||
|
self.id = trackAPI_gw['SNG_ID']
|
||||||
|
self.duration = trackAPI_gw['DURATION']
|
||||||
|
self.MD5 = trackAPI_gw['MD5_ORIGIN']
|
||||||
|
self.mediaVersion = trackAPI_gw['MEDIA_VERSION']
|
||||||
|
self.fallbackId = "0"
|
||||||
|
if 'FALLBACK' in trackAPI_gw:
|
||||||
|
self.fallbackId = trackAPI_gw['FALLBACK']['SNG_ID']
|
||||||
|
self.filesizes = dz.get_track_filesizes(self.id)
|
||||||
|
|
||||||
|
def parseLocalTrackData(self, trackAPI_gw):
|
||||||
|
# Local tracks has only the trackAPI_gw page and
|
||||||
|
# contains only the tags provided by the file
|
||||||
|
self.album = {
|
||||||
|
'id': "0",
|
||||||
|
'title': trackAPI_gw['ALB_TITLE'],
|
||||||
|
'pic': trackAPI_gw.get('ALB_PICTURE', "")
|
||||||
|
}
|
||||||
|
self.mainArtist = {
|
||||||
|
'id': "0",
|
||||||
|
'name': trackAPI_gw['ART_NAME'],
|
||||||
|
'pic': ""
|
||||||
|
}
|
||||||
|
self.artists = [trackAPI_gw['ART_NAME']]
|
||||||
|
self.artist = {
|
||||||
|
'Main': [trackAPI_gw['ART_NAME']]
|
||||||
|
}
|
||||||
|
self.date = {
|
||||||
|
'day': "00",
|
||||||
|
'month': "00",
|
||||||
|
'year': "XXXX"
|
||||||
|
}
|
||||||
|
# Defaulting all the missing data
|
||||||
|
self.ISRC = ""
|
||||||
|
self.album['artist'] = self.artist
|
||||||
|
self.album['artists'] = self.artists
|
||||||
|
self.album['barcode'] = "Unknown"
|
||||||
|
self.album['date'] = self.date
|
||||||
|
self.album['discTotal'] = "0"
|
||||||
|
self.album['explicit'] = False
|
||||||
|
self.album['genre'] = []
|
||||||
|
self.album['label'] = "Unknown"
|
||||||
|
self.album['mainArtist'] = self.mainArtist
|
||||||
|
self.album['recordType'] = "album"
|
||||||
|
self.album['trackTotal'] = "0"
|
||||||
|
self.bpm = 0
|
||||||
|
self.contributors = {}
|
||||||
|
self.copyright = ""
|
||||||
|
self.discNumber = "0"
|
||||||
|
self.explicit = False
|
||||||
|
self.lyrics = {}
|
||||||
|
self.replayGain = ""
|
||||||
|
self.trackNumber = "0"
|
||||||
|
|
||||||
|
def parseData(self, dz, settings, trackAPI_gw, trackAPI, albumAPI_gw, albumAPI):
|
||||||
|
self.discNumber = trackAPI_gw.get('DISK_NUMBER')
|
||||||
|
self.explicit = bool(int(trackAPI_gw.get('EXPLICIT_LYRICS', "0")))
|
||||||
|
self.copyright = trackAPI_gw.get('COPYRIGHT')
|
||||||
|
self.replayGain = ""
|
||||||
|
if 'GAIN' in trackAPI_gw:
|
||||||
|
self.replayGain = generateReplayGainString(trackAPI_gw['GAIN'])
|
||||||
|
self.ISRC = trackAPI_gw.get('ISRC')
|
||||||
|
self.trackNumber = trackAPI_gw['TRACK_NUMBER']
|
||||||
|
self.contributors = trackAPI_gw['SNG_CONTRIBUTORS']
|
||||||
|
|
||||||
|
self.lyrics = {
|
||||||
|
'id': int(trackAPI_gw.get('LYRICS_ID', "0")),
|
||||||
|
'unsync': None,
|
||||||
|
'sync': None,
|
||||||
|
'syncID3': None
|
||||||
|
}
|
||||||
|
if not "LYRICS" in trackAPI_gw and self.lyrics['id'] != 0:
|
||||||
|
logger.info(f"[{trackAPI_gw['ART_NAME']} - {self.title}] Getting lyrics")
|
||||||
|
trackAPI_gw["LYRICS"] = dz.get_lyrics_gw(self.id)
|
||||||
|
if self.lyrics['id'] != 0:
|
||||||
|
self.lyrics['unsync'] = trackAPI_gw["LYRICS"].get("LYRICS_TEXT")
|
||||||
|
if "LYRICS_SYNC_JSON" in trackAPI_gw["LYRICS"]:
|
||||||
|
syncLyricsJson = trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"]
|
||||||
|
self.lyrics['sync'] = ""
|
||||||
|
self.lyrics['syncID3'] = []
|
||||||
|
timestamp = ""
|
||||||
|
milliseconds = 0
|
||||||
|
for line in range(len(syncLyricsJson)):
|
||||||
|
if syncLyricsJson[line]["line"] != "":
|
||||||
|
timestamp = syncLyricsJson[line]["lrc_timestamp"]
|
||||||
|
milliseconds = int(syncLyricsJson[line]["milliseconds"])
|
||||||
|
else:
|
||||||
|
notEmptyLine = line + 1
|
||||||
|
while syncLyricsJson[notEmptyLine]["line"] == "":
|
||||||
|
notEmptyLine = notEmptyLine + 1
|
||||||
|
timestamp = syncLyricsJson[notEmptyLine]["lrc_timestamp"]
|
||||||
|
milliseconds = int(syncLyricsJson[notEmptyLine]["milliseconds"])
|
||||||
|
self.lyrics['sync'] += timestamp + syncLyricsJson[line]["line"] + "\r\n"
|
||||||
|
self.lyrics['syncID3'].append((syncLyricsJson[line]["line"], milliseconds))
|
||||||
|
|
||||||
|
self.mainArtist = {
|
||||||
|
'id': trackAPI_gw['ART_ID'],
|
||||||
|
'name': trackAPI_gw['ART_NAME'],
|
||||||
|
'pic': trackAPI_gw.get('ART_PICTURE')
|
||||||
|
}
|
||||||
|
|
||||||
|
self.date = None
|
||||||
|
if 'PHYSICAL_RELEASE_DATE' in trackAPI_gw:
|
||||||
|
self.date = {
|
||||||
|
'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.album = {
|
||||||
|
'id': trackAPI_gw['ALB_ID'],
|
||||||
|
'title': trackAPI_gw['ALB_TITLE'],
|
||||||
|
'pic': trackAPI_gw.get('ALB_PICTURE'),
|
||||||
|
'barcode': "Unknown",
|
||||||
|
'label': "Unknown",
|
||||||
|
'explicit': False,
|
||||||
|
'date': None,
|
||||||
|
'genre': []
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try the public API first (as it has more data)
|
||||||
|
if not albumAPI:
|
||||||
|
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting album infos")
|
||||||
|
try:
|
||||||
|
albumAPI = dz.get_album(self.album['id'])
|
||||||
|
except APIError:
|
||||||
|
albumAPI = None
|
||||||
|
|
||||||
|
if albumAPI:
|
||||||
|
self.album['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]
|
||||||
|
self.album['mainArtist'] = {
|
||||||
|
'id': albumAPI['artist']['id'],
|
||||||
|
'name': albumAPI['artist']['name'],
|
||||||
|
'pic': artistPicture
|
||||||
|
}
|
||||||
|
|
||||||
|
self.album['artist'] = {}
|
||||||
|
self.album['artists'] = []
|
||||||
|
for artist in albumAPI['contributors']:
|
||||||
|
isVariousArtists = artist['id'] == VARIOUS_ARTISTS
|
||||||
|
isMainArtist = artist['role'] == "Main"
|
||||||
|
|
||||||
|
if not isVariousArtists or settings['albumVariousArtists'] and isVariousArtists:
|
||||||
|
if artist['name'] not in self.album['artists']:
|
||||||
|
self.album['artists'].append(artist['name'])
|
||||||
|
|
||||||
|
if isMainArtist or artist['name'] not in self.album['artist']['Main'] and not isMainArtist:
|
||||||
|
if not artist['role'] in self.album['artist']:
|
||||||
|
self.album['artist'][artist['role']] = []
|
||||||
|
self.album['artist'][artist['role']].append(artist['name'])
|
||||||
|
|
||||||
|
if settings['removeDuplicateArtists']:
|
||||||
|
self.album['artists'] = uniqueArray(self.album['artists'])
|
||||||
|
for role in self.album['artist'].keys():
|
||||||
|
self.album['artist'][role] = uniqueArray(self.album['artist'][role])
|
||||||
|
|
||||||
|
self.album['trackTotal'] = albumAPI['nb_tracks']
|
||||||
|
self.album['recordType'] = albumAPI['record_type']
|
||||||
|
|
||||||
|
self.album['barcode'] = albumAPI.get('upc', self.album['barcode'])
|
||||||
|
self.album['label'] = albumAPI.get('label', self.album['label'])
|
||||||
|
self.album['explicit'] = bool(albumAPI.get('explicit_lyrics', False))
|
||||||
|
if 'release_date' in albumAPI:
|
||||||
|
self.album['date'] = {
|
||||||
|
'day': albumAPI["release_date"][8:10],
|
||||||
|
'month': albumAPI["release_date"][5:7],
|
||||||
|
'year': albumAPI["release_date"][0:4]
|
||||||
|
}
|
||||||
|
self.album['discTotal'] = albumAPI.get('nb_disk', "1")
|
||||||
|
self.copyright = albumAPI.get('copyright')
|
||||||
|
|
||||||
|
if not self.album['pic']:
|
||||||
|
# Getting album cover ID
|
||||||
|
# ex: https://e-cdns-images.dzcdn.net/images/cover/2e018122cb56986277102d2041a592c8/56x56-000000-80-0-0.jpg
|
||||||
|
self.album['pic'] = albumAPI['cover_small'][albumAPI['cover_small'].find('cover/') + 6:-24]
|
||||||
|
|
||||||
|
if albumAPI.get('genres') and len(albumAPI['genres'].get('data', [])) > 0:
|
||||||
|
for genre in albumAPI['genres']['data']:
|
||||||
|
self.album['genre'].append(genre['name'])
|
||||||
|
else:
|
||||||
|
if not albumAPI_gw:
|
||||||
|
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting more album infos")
|
||||||
|
try:
|
||||||
|
albumAPI_gw = dz.get_album_gw(self.album['id'])
|
||||||
|
except APIError:
|
||||||
|
albumAPI_gw = None
|
||||||
|
raise AlbumDoesntExsists
|
||||||
|
|
||||||
|
self.album['title'] = albumAPI_gw['ALB_TITLE']
|
||||||
|
self.album['mainArtist'] = {
|
||||||
|
'id': albumAPI_gw['ART_ID'],
|
||||||
|
'name': albumAPI_gw['ART_NAME'],
|
||||||
|
'pic': None
|
||||||
|
}
|
||||||
|
|
||||||
|
# albumAPI_gw doesn't contain the artist cover
|
||||||
|
# Getting artist image ID
|
||||||
|
# ex: https://e-cdns-images.dzcdn.net/images/artist/f2bc007e9133c946ac3c3907ddc5d2ea/56x56-000000-80-0-0.jpg
|
||||||
|
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting artist picture fallback")
|
||||||
|
artistAPI = dz.get_artist(self.album['mainArtist']['id'])
|
||||||
|
self.album['mainArtist']['pic'] = artistAPI['picture_small'][artistAPI['picture_small'].find('artist/') + 7:-24]
|
||||||
|
|
||||||
|
self.album['artists'] = [albumAPI_gw['ART_NAME']]
|
||||||
|
self.album['trackTotal'] = albumAPI_gw['NUMBER_TRACK']
|
||||||
|
self.album['discTotal'] = albumAPI_gw['NUMBER_DISK']
|
||||||
|
self.album['recordType'] = "album"
|
||||||
|
self.album['label'] = albumAPI_gw.get('LABEL_NAME', self.album['label'])
|
||||||
|
|
||||||
|
if albumAPI_gw.get('EXPLICIT_ALBUM_CONTENT') and albumAPI_gw['EXPLICIT_ALBUM_CONTENT'].get('EXPLICIT_LYRICS_STATUS'):
|
||||||
|
explicitLyricsStatus = albumAPI_gw['EXPLICIT_ALBUM_CONTENT']['EXPLICIT_LYRICS_STATUS']
|
||||||
|
self.album['explicit'] = explicitLyricsStatus in [LyricsStatus.EXPLICIT, LyricsStatus.PARTIALLY_EXPLICIT]
|
||||||
|
|
||||||
|
if not self.album['pic']:
|
||||||
|
self.album['pic'] = albumAPI_gw['ALB_PICTURE']
|
||||||
|
if 'PHYSICAL_RELEASE_DATE' in albumAPI_gw:
|
||||||
|
self.album['date'] = {
|
||||||
|
'day': albumAPI_gw["PHYSICAL_RELEASE_DATE"][8:10],
|
||||||
|
'month': albumAPI_gw["PHYSICAL_RELEASE_DATE"][5:7],
|
||||||
|
'year': albumAPI_gw["PHYSICAL_RELEASE_DATE"][0:4]
|
||||||
|
}
|
||||||
|
|
||||||
|
isAlbumArtistVariousArtists = self.album['mainArtist']['id'] == VARIOUS_ARTISTS
|
||||||
|
self.album['mainArtist']['save'] = not isAlbumArtistVariousArtists or settings['albumVariousArtists'] and isAlbumArtistVariousArtists
|
||||||
|
|
||||||
|
if self.album['date'] and not self.date:
|
||||||
|
self.date = self.album['date']
|
||||||
|
|
||||||
|
if not trackAPI:
|
||||||
|
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting extra track infos")
|
||||||
|
trackAPI = dz.get_track(self.id)
|
||||||
|
self.bpm = trackAPI['bpm']
|
||||||
|
|
||||||
|
if not self.replayGain and 'gain' in trackAPI:
|
||||||
|
self.replayGain = generateReplayGainString(trackAPI['gain'])
|
||||||
|
if not self.explicit:
|
||||||
|
self.explicit = trackAPI['explicit_lyrics']
|
||||||
|
if not self.discNumber:
|
||||||
|
self.discNumber = trackAPI['disk_number']
|
||||||
|
|
||||||
|
self.artist = {}
|
||||||
|
self.artists = []
|
||||||
|
for artist in trackAPI['contributors']:
|
||||||
|
isVariousArtists = artist['id'] == VARIOUS_ARTISTS
|
||||||
|
isMainArtist = artist['role'] == "Main"
|
||||||
|
|
||||||
|
if not isVariousArtists or len(trackAPI['contributors']) == 1 and isVariousArtists:
|
||||||
|
if artist['name'] not in self.artists:
|
||||||
|
self.artists.append(artist['name'])
|
||||||
|
|
||||||
|
if isMainArtist or artist['name'] not in self.artist['Main'] and not isMainArtist:
|
||||||
|
if not artist['role'] in self.artist:
|
||||||
|
self.artist[artist['role']] = []
|
||||||
|
self.artist[artist['role']].append(artist['name'])
|
||||||
|
|
||||||
|
if settings['removeDuplicateArtists']:
|
||||||
|
self.artists = uniqueArray(self.artists)
|
||||||
|
for role in self.artist.keys():
|
||||||
|
self.artist[role] = uniqueArray(self.artist[role])
|
||||||
|
|
||||||
|
if not self.album['discTotal']:
|
||||||
|
if not albumAPI_gw:
|
||||||
|
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting more album infos")
|
||||||
|
albumAPI_gw = dz.get_album_gw(self.album['id'])
|
||||||
|
self.album['discTotal'] = albumAPI_gw['NUMBER_DISK']
|
||||||
|
|
||||||
|
if not self.copyright:
|
||||||
|
if not albumAPI_gw:
|
||||||
|
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting more album infos")
|
||||||
|
albumAPI_gw = dz.get_album_gw(self.album['id'])
|
||||||
|
self.copyright = albumAPI_gw['COPYRIGHT']
|
||||||
|
|
||||||
|
def parsePlaylistData(self):
|
||||||
self.playlist = {}
|
self.playlist = {}
|
||||||
if 'dzcdn.net' in trackAPI_gw["_EXTRA_PLAYLIST"]['picture_small']:
|
if 'dzcdn.net' in trackAPI_gw["_EXTRA_PLAYLIST"]['picture_small']:
|
||||||
self.playlist['pic'] = trackAPI_gw["_EXTRA_PLAYLIST"]['picture_small'][:-24]
|
self.playlist['pic'] = trackAPI_gw["_EXTRA_PLAYLIST"]['picture_small'][:-24]
|
||||||
|
@ -74,255 +368,6 @@ class Track:
|
||||||
}
|
}
|
||||||
self.playlist['discTotal'] = "1"
|
self.playlist['discTotal'] = "1"
|
||||||
|
|
||||||
self.generateMainFeatStrings()
|
|
||||||
|
|
||||||
# Bits useful for later
|
|
||||||
self.searched = False
|
|
||||||
self.selectedFormat = 0
|
|
||||||
self.dateString = None
|
|
||||||
self.album['picUrl'] = None
|
|
||||||
self.album['picPath'] = None
|
|
||||||
self.album['bitrate'] = 0
|
|
||||||
self.album['dateString'] = None
|
|
||||||
|
|
||||||
self.artistsString = ""
|
|
||||||
|
|
||||||
def parseEssentialData(self, dz, trackAPI_gw):
|
|
||||||
self.id = trackAPI_gw['SNG_ID']
|
|
||||||
self.duration = trackAPI_gw['DURATION']
|
|
||||||
self.MD5 = trackAPI_gw['MD5_ORIGIN']
|
|
||||||
self.mediaVersion = trackAPI_gw['MEDIA_VERSION']
|
|
||||||
self.fallbackId = "0"
|
|
||||||
if 'FALLBACK' in trackAPI_gw:
|
|
||||||
self.fallbackId = trackAPI_gw['FALLBACK']['SNG_ID']
|
|
||||||
self.filesizes = dz.get_track_filesizes(self.id)
|
|
||||||
|
|
||||||
def parseLocalTrackData(self, trackAPI_gw):
|
|
||||||
self.album = {
|
|
||||||
'id': "0",
|
|
||||||
'title': trackAPI_gw['ALB_TITLE'],
|
|
||||||
}
|
|
||||||
self.album['pic'] = trackAPI_gw.get('ALB_PICTURE')
|
|
||||||
self.mainArtist = {
|
|
||||||
'id': "0",
|
|
||||||
'name': trackAPI_gw['ART_NAME'],
|
|
||||||
'pic': ""
|
|
||||||
}
|
|
||||||
self.artists = [trackAPI_gw['ART_NAME']]
|
|
||||||
self.artist = {
|
|
||||||
'Main': [trackAPI_gw['ART_NAME']]
|
|
||||||
}
|
|
||||||
self.date = {
|
|
||||||
'day': "00",
|
|
||||||
'month': "00",
|
|
||||||
'year': "XXXX"
|
|
||||||
}
|
|
||||||
# All the missing data
|
|
||||||
self.ISRC = ""
|
|
||||||
self.album['artist'] = self.artist
|
|
||||||
self.album['artists'] = self.artists
|
|
||||||
self.album['barcode'] = "Unknown"
|
|
||||||
self.album['date'] = self.date
|
|
||||||
self.album['discTotal'] = "0"
|
|
||||||
self.album['explicit'] = False
|
|
||||||
self.album['genre'] = []
|
|
||||||
self.album['label'] = "Unknown"
|
|
||||||
self.album['mainArtist'] = self.mainArtist
|
|
||||||
self.album['recordType'] = "album"
|
|
||||||
self.album['trackTotal'] = "0"
|
|
||||||
self.bpm = 0
|
|
||||||
self.contributors = {}
|
|
||||||
self.copyright = ""
|
|
||||||
self.discNumber = "0"
|
|
||||||
self.explicit = False
|
|
||||||
self.lyrics = {}
|
|
||||||
self.replayGain = ""
|
|
||||||
self.trackNumber = "0"
|
|
||||||
|
|
||||||
def parseData(self, dz, settings, trackAPI_gw, trackAPI, albumAPI_gw, albumAPI):
|
|
||||||
self.discNumber = trackAPI_gw.get('DISK_NUMBER')
|
|
||||||
self.explicit = bool(int(trackAPI_gw.get('EXPLICIT_LYRICS', "0")))
|
|
||||||
self.copyright = trackAPI_gw.get('COPYRIGHT')
|
|
||||||
self.replayGain = ""
|
|
||||||
if 'GAIN' in trackAPI_gw:
|
|
||||||
self.replayGain = "{0:.2f} dB".format((float(trackAPI_gw['GAIN']) + 18.4) * -1)
|
|
||||||
self.ISRC = trackAPI_gw['ISRC']
|
|
||||||
self.trackNumber = trackAPI_gw['TRACK_NUMBER']
|
|
||||||
self.contributors = trackAPI_gw['SNG_CONTRIBUTORS']
|
|
||||||
|
|
||||||
self.lyrics = {
|
|
||||||
'id': trackAPI_gw.get('LYRICS_ID', "0"),
|
|
||||||
'unsync': None,
|
|
||||||
'sync': None,
|
|
||||||
'syncID3': None
|
|
||||||
}
|
|
||||||
if not "LYRICS" in trackAPI_gw and int(self.lyrics['id']) != 0:
|
|
||||||
logger.info(f"[{trackAPI_gw['ART_NAME']} - {self.title}] Getting lyrics")
|
|
||||||
trackAPI_gw["LYRICS"] = dz.get_lyrics_gw(self.id)
|
|
||||||
if int(self.lyrics['id']) != 0:
|
|
||||||
self.lyrics['unsync'] = trackAPI_gw["LYRICS"].get("LYRICS_TEXT")
|
|
||||||
if "LYRICS_SYNC_JSON" in trackAPI_gw["LYRICS"]:
|
|
||||||
self.lyrics['sync'] = ""
|
|
||||||
self.lyrics['syncID3'] = []
|
|
||||||
timestamp = ""
|
|
||||||
milliseconds = 0
|
|
||||||
for i in range(len(trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"])):
|
|
||||||
if trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][i]["line"] != "":
|
|
||||||
timestamp = trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][i]["lrc_timestamp"]
|
|
||||||
milliseconds = int(trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][i]["milliseconds"])
|
|
||||||
else:
|
|
||||||
j=i+1
|
|
||||||
while trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][j]["line"] == "":
|
|
||||||
j=j+1
|
|
||||||
timestamp = trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][j]["lrc_timestamp"]
|
|
||||||
milliseconds = int(trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][j]["milliseconds"])
|
|
||||||
self.lyrics['sync'] += timestamp + trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][i]["line"] + "\r\n"
|
|
||||||
self.lyrics['syncID3'].append((trackAPI_gw["LYRICS"]["LYRICS_SYNC_JSON"][i]["line"], milliseconds))
|
|
||||||
|
|
||||||
self.mainArtist = {
|
|
||||||
'id': trackAPI_gw['ART_ID'],
|
|
||||||
'name': trackAPI_gw['ART_NAME'],
|
|
||||||
'pic': trackAPI_gw.get('ART_PICTURE')
|
|
||||||
}
|
|
||||||
|
|
||||||
self.date = None
|
|
||||||
if 'PHYSICAL_RELEASE_DATE' in trackAPI_gw:
|
|
||||||
self.date = {
|
|
||||||
'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.album = {
|
|
||||||
'id': trackAPI_gw['ALB_ID'],
|
|
||||||
'title': trackAPI_gw['ALB_TITLE'],
|
|
||||||
'pic': trackAPI_gw.get('ALB_PICTURE'),
|
|
||||||
'barcode': "Unknown",
|
|
||||||
'label': "Unknown",
|
|
||||||
'explicit': False,
|
|
||||||
'date': None,
|
|
||||||
'genre': []
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
# Try the public API first (as it has more data)
|
|
||||||
if not albumAPI:
|
|
||||||
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting album infos")
|
|
||||||
albumAPI = dz.get_album(self.album['id'])
|
|
||||||
self.album['title'] = albumAPI['title']
|
|
||||||
self.album['mainArtist'] = {
|
|
||||||
'id': albumAPI['artist']['id'],
|
|
||||||
'name': albumAPI['artist']['name'],
|
|
||||||
'pic': albumAPI['artist']['picture_small'][albumAPI['artist']['picture_small'].find('artist/') + 7:-24]
|
|
||||||
}
|
|
||||||
|
|
||||||
self.album['artist'] = {}
|
|
||||||
self.album['artists'] = []
|
|
||||||
for artist in albumAPI['contributors']:
|
|
||||||
if artist['id'] != 5080 or artist['id'] == 5080 and settings['albumVariousArtists']:
|
|
||||||
if artist['name'] not in self.album['artists']:
|
|
||||||
self.album['artists'].append(artist['name'])
|
|
||||||
if artist['role'] == "Main" or artist['role'] != "Main" and artist['name'] not in self.album['artist']['Main']:
|
|
||||||
if not artist['role'] in self.album['artist']:
|
|
||||||
self.album['artist'][artist['role']] = []
|
|
||||||
self.album['artist'][artist['role']].append(artist['name'])
|
|
||||||
if settings['removeDuplicateArtists']:
|
|
||||||
self.album['artists'] = uniqueArray(self.album['artists'])
|
|
||||||
for role in self.album['artist'].keys():
|
|
||||||
self.album['artist'][role] = uniqueArray(self.album['artist'][role])
|
|
||||||
|
|
||||||
self.album['trackTotal'] = albumAPI['nb_tracks']
|
|
||||||
self.album['recordType'] = albumAPI['record_type']
|
|
||||||
|
|
||||||
self.album['barcode'] = albumAPI.get('upc', self.album['barcode'])
|
|
||||||
self.album['label'] = albumAPI.get('label', self.album['label'])
|
|
||||||
self.album['explicit'] = bool(albumAPI.get('explicit_lyrics', False))
|
|
||||||
if 'release_date' in albumAPI:
|
|
||||||
self.album['date'] = {
|
|
||||||
'day': albumAPI["release_date"][8:10],
|
|
||||||
'month': albumAPI["release_date"][5:7],
|
|
||||||
'year': albumAPI["release_date"][0:4]
|
|
||||||
}
|
|
||||||
self.album['discTotal'] = albumAPI.get('nb_disk', "1")
|
|
||||||
self.copyright = albumAPI.get('copyright')
|
|
||||||
|
|
||||||
if not self.album['pic']:
|
|
||||||
self.album['pic'] = albumAPI['cover_small'][albumAPI['cover_small'].find('cover/') + 6:-24]
|
|
||||||
|
|
||||||
if 'genres' in albumAPI and 'data' in albumAPI['genres'] and len(albumAPI['genres']['data']) > 0:
|
|
||||||
for genre in albumAPI['genres']['data']:
|
|
||||||
self.album['genre'].append(genre['name'])
|
|
||||||
except APIError:
|
|
||||||
if not albumAPI_gw:
|
|
||||||
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting more album infos")
|
|
||||||
albumAPI_gw = dz.get_album_gw(self.album['id'])
|
|
||||||
self.album['title'] = albumAPI_gw['ALB_TITLE']
|
|
||||||
self.album['mainArtist'] = {
|
|
||||||
'id': albumAPI_gw['ART_ID'],
|
|
||||||
'name': albumAPI_gw['ART_NAME'],
|
|
||||||
'pic': None
|
|
||||||
}
|
|
||||||
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting artist picture fallback")
|
|
||||||
artistAPI = dz.get_artist(self.album['mainArtist']['id'])
|
|
||||||
self.album['artists'] = [albumAPI_gw['ART_NAME']]
|
|
||||||
self.album['mainArtist']['pic'] = artistAPI['picture_small'][artistAPI['picture_small'].find('artist/') + 7:-24]
|
|
||||||
self.album['trackTotal'] = albumAPI_gw['NUMBER_TRACK']
|
|
||||||
self.album['discTotal'] = albumAPI_gw['NUMBER_DISK']
|
|
||||||
self.album['recordType'] = "album"
|
|
||||||
self.album['label'] = albumAPI_gw.get('LABEL_NAME', self.album['label'])
|
|
||||||
if 'EXPLICIT_ALBUM_CONTENT' in albumAPI_gw and 'EXPLICIT_LYRICS_STATUS' in albumAPI_gw['EXPLICIT_ALBUM_CONTENT']:
|
|
||||||
self.album['explicit'] = albumAPI_gw['EXPLICIT_ALBUM_CONTENT']['EXPLICIT_LYRICS_STATUS'] in [1,4]
|
|
||||||
if not self.album['pic']:
|
|
||||||
self.album['pic'] = albumAPI_gw['ALB_PICTURE']
|
|
||||||
if 'PHYSICAL_RELEASE_DATE' in albumAPI_gw:
|
|
||||||
self.album['date'] = {
|
|
||||||
'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.album['mainArtist']['save'] = self.album['mainArtist']['id'] != 5080 or self.album['mainArtist']['id'] == 5080 and settings['albumVariousArtists']
|
|
||||||
|
|
||||||
if self.album['date'] and not self.date:
|
|
||||||
self.date = self.album['date']
|
|
||||||
|
|
||||||
if not trackAPI:
|
|
||||||
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting extra track infos")
|
|
||||||
trackAPI = dz.get_track(self.id)
|
|
||||||
self.bpm = trackAPI['bpm']
|
|
||||||
|
|
||||||
if not self.replayGain and 'gain' in trackAPI:
|
|
||||||
self.replayGain = "{0:.2f} dB".format((float(trackAPI['gain']) + 18.4) * -1)
|
|
||||||
if not self.explicit:
|
|
||||||
self.explicit = trackAPI['explicit_lyrics']
|
|
||||||
if not self.discNumber:
|
|
||||||
self.discNumber = trackAPI['disk_number']
|
|
||||||
|
|
||||||
self.artist = {}
|
|
||||||
self.artists = []
|
|
||||||
for artist in trackAPI['contributors']:
|
|
||||||
if artist['id'] != 5080 or artist['id'] == 5080 and len(trackAPI['contributors']) == 1:
|
|
||||||
if artist['name'] not in self.artists:
|
|
||||||
self.artists.append(artist['name'])
|
|
||||||
if artist['role'] != "Main" and artist['name'] not in self.artist['Main'] or artist['role'] == "Main":
|
|
||||||
if not artist['role'] in self.artist:
|
|
||||||
self.artist[artist['role']] = []
|
|
||||||
self.artist[artist['role']].append(artist['name'])
|
|
||||||
if settings['removeDuplicateArtists']:
|
|
||||||
self.artists = uniqueArray(self.artists)
|
|
||||||
for role in self.artist.keys():
|
|
||||||
self.artist[role] = uniqueArray(self.artist[role])
|
|
||||||
|
|
||||||
if not self.album['discTotal']:
|
|
||||||
if not albumAPI_gw:
|
|
||||||
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting more album infos")
|
|
||||||
albumAPI_gw = dz.get_album_gw(self.album['id'])
|
|
||||||
self.album['discTotal'] = albumAPI_gw['NUMBER_DISK']
|
|
||||||
if not self.copyright:
|
|
||||||
if not albumAPI_gw:
|
|
||||||
logger.info(f"[{self.mainArtist['name']} - {self.title}] Getting more album infos")
|
|
||||||
albumAPI_gw = dz.get_album_gw(self.album['id'])
|
|
||||||
self.copyright = albumAPI_gw['COPYRIGHT']
|
|
||||||
|
|
||||||
# Removes featuring from the title
|
# Removes featuring from the title
|
||||||
def getCleanTitle(self):
|
def getCleanTitle(self):
|
||||||
return removeFeatures(self.title)
|
return removeFeatures(self.title)
|
||||||
|
@ -341,3 +386,10 @@ class Track:
|
||||||
self.featArtistsString = None
|
self.featArtistsString = None
|
||||||
if 'Featured' in self.artist:
|
if 'Featured' in self.artist:
|
||||||
self.featArtistsString = "feat. "+andCommaConcat(self.artist['Featured'])
|
self.featArtistsString = "feat. "+andCommaConcat(self.artist['Featured'])
|
||||||
|
|
||||||
|
class TrackError(Exception):
|
||||||
|
"""Base class for exceptions in this module."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class AlbumDoesntExsists(TrackError):
|
||||||
|
pass
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
def generateReplayGainString(trackGain):
|
||||||
|
return "{0:.2f} dB".format((float(trackGain) + 18.4) * -1)
|
||||||
|
|
||||||
def getBitrateInt(txt):
|
def getBitrateInt(txt):
|
||||||
txt = str(txt).lower()
|
txt = str(txt).lower()
|
||||||
if txt in ['flac', 'lossless', '9']:
|
if txt in ['flac', 'lossless', '9']:
|
||||||
|
|
Loading…
Reference in New Issue