Added overwriteFile and saveDownloadQueue options
This commit is contained in:
parent
ded4f9d2c0
commit
1a95f16ba0
|
@ -21,6 +21,8 @@
|
||||||
"fallbackSearch": false,
|
"fallbackSearch": false,
|
||||||
"logErrors": true,
|
"logErrors": true,
|
||||||
"logSearched": false,
|
"logSearched": false,
|
||||||
|
"saveDownloadQueue": false,
|
||||||
|
"overwriteFile": "n",
|
||||||
"createM3U8File": false,
|
"createM3U8File": false,
|
||||||
"syncedLyrics": false,
|
"syncedLyrics": false,
|
||||||
"embeddedArtworkSize": 800,
|
"embeddedArtworkSize": 800,
|
||||||
|
|
|
@ -65,7 +65,7 @@ def stream_track(dz, track, stream, trackAPI, queueItem, interface=None):
|
||||||
else:
|
else:
|
||||||
chunkProgres = (len(chunk) / complete) / trackAPI['SIZE'] * 100
|
chunkProgres = (len(chunk) / complete) / trackAPI['SIZE'] * 100
|
||||||
downloadPercentage += chunkProgres
|
downloadPercentage += chunkProgres
|
||||||
if round(downloadPercentage) != lastPercentage and round(percentage) % 5 == 0:
|
if round(downloadPercentage) != lastPercentage and round(downloadPercentage) % 2 == 0:
|
||||||
lastPercentage = round(downloadPercentage)
|
lastPercentage = round(downloadPercentage)
|
||||||
if interface:
|
if interface:
|
||||||
queueItem['progress'] = lastPercentage
|
queueItem['progress'] = lastPercentage
|
||||||
|
@ -73,8 +73,21 @@ def stream_track(dz, track, stream, trackAPI, queueItem, interface=None):
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
def downloadImage(url, path):
|
def trackCompletePercentage(trackAPI, queueItem, interface):
|
||||||
if not os.path.isfile(path):
|
global downloadPercentage, lastPercentage
|
||||||
|
if 'SINGLE_TRACK' in trackAPI:
|
||||||
|
downloadPercentage = 100
|
||||||
|
else:
|
||||||
|
downloadPercentage += 1 / trackAPI['SIZE'] * 100
|
||||||
|
if round(downloadPercentage) != lastPercentage and round(downloadPercentage) % 2 == 0:
|
||||||
|
lastPercentage = round(downloadPercentage)
|
||||||
|
if interface:
|
||||||
|
queueItem['progress'] = lastPercentage
|
||||||
|
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage})
|
||||||
|
|
||||||
|
|
||||||
|
def downloadImage(url, path, overwrite="n"):
|
||||||
|
if not os.path.isfile(path) or overwrite in ['y', 't']:
|
||||||
try:
|
try:
|
||||||
image = get(url, headers={'User-Agent': USER_AGENT_HEADER}, timeout=30)
|
image = get(url, headers={'User-Agent': USER_AGENT_HEADER}, timeout=30)
|
||||||
with open(path, 'wb') as f:
|
with open(path, 'wb') as f:
|
||||||
|
@ -82,7 +95,7 @@ def downloadImage(url, path):
|
||||||
return path
|
return path
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
sleep(1)
|
sleep(1)
|
||||||
return downloadImage(url, path)
|
return downloadImage(url, path, overwrite)
|
||||||
except HTTPError:
|
except HTTPError:
|
||||||
if 'cdns-images.dzcdn.net' in url:
|
if 'cdns-images.dzcdn.net' in url:
|
||||||
urlBase = url[:url.rfind("/")+1]
|
urlBase = url[:url.rfind("/")+1]
|
||||||
|
@ -91,7 +104,7 @@ def downloadImage(url, path):
|
||||||
if pictureSize > 1400:
|
if pictureSize > 1400:
|
||||||
logger.warn("Couldn't download "+str(pictureSize)+"x"+str(pictureSize)+" image, falling back to 1400x1400")
|
logger.warn("Couldn't download "+str(pictureSize)+"x"+str(pictureSize)+" image, falling back to 1400x1400")
|
||||||
sleep(1)
|
sleep(1)
|
||||||
return downloadImage(urlBase+pictureUrl.replace(str(pictureSize)+"x"+str(pictureSize), '1400x1400'), path)
|
return downloadImage(urlBase+pictureUrl.replace(str(pictureSize)+"x"+str(pictureSize), '1400x1400'), path, overwrite)
|
||||||
logger.error("Couldn't download Image: "+url)
|
logger.error("Couldn't download Image: "+url)
|
||||||
remove(path)
|
remove(path)
|
||||||
return None
|
return None
|
||||||
|
@ -450,6 +463,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
|
||||||
interface=interface)
|
interface=interface)
|
||||||
else:
|
else:
|
||||||
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded and no alternative found!")
|
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded and no alternative found!")
|
||||||
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
result['error'] = {
|
result['error'] = {
|
||||||
'message': "Track not yet encoded and no alternative found!",
|
'message': "Track not yet encoded and no alternative found!",
|
||||||
'data': track
|
'data': track
|
||||||
|
@ -461,6 +475,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded!")
|
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded!")
|
||||||
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
result['error'] = {
|
result['error'] = {
|
||||||
'message': "Track not yet encoded!",
|
'message': "Track not yet encoded!",
|
||||||
'data': track
|
'data': track
|
||||||
|
@ -475,6 +490,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
|
||||||
format = getPreferredBitrate(dz, track, bitrate, settings['fallbackBitrate'])
|
format = getPreferredBitrate(dz, track, bitrate, settings['fallbackBitrate'])
|
||||||
if format == -100:
|
if format == -100:
|
||||||
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not found at desired bitrate. Enable fallback to lower bitrates to fix this issue.")
|
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not found at desired bitrate. Enable fallback to lower bitrates to fix this issue.")
|
||||||
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
result['error'] = {
|
result['error'] = {
|
||||||
'message': "Track not found at desired bitrate.",
|
'message': "Track not found at desired bitrate.",
|
||||||
'data': track
|
'data': track
|
||||||
|
@ -486,6 +502,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
|
||||||
return result
|
return result
|
||||||
elif format == -200:
|
elif format == -200:
|
||||||
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] This track is not available in 360 Reality Audio format. Please select another format.")
|
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] This track is not available in 360 Reality Audio format. Please select another format.")
|
||||||
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
result['error'] = {
|
result['error'] = {
|
||||||
'message': "Track is not available in Reality Audio 360.",
|
'message': "Track is not available in Reality Audio 360.",
|
||||||
'data': track
|
'data': track
|
||||||
|
@ -593,8 +610,9 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
|
||||||
|
|
||||||
# Save lyrics in lrc file
|
# Save lyrics in lrc file
|
||||||
if settings['syncedLyrics'] and 'sync' in track['lyrics']:
|
if settings['syncedLyrics'] and 'sync' in track['lyrics']:
|
||||||
with open(os.path.join(filepath, filename + '.lrc'), 'wb') as f:
|
if not os.path.isfile(os.path.join(filepath, filename + '.lrc')) or settings['overwriteFile'] in ['y', 't']:
|
||||||
f.write(track['lyrics']['sync'].encode('utf-8'))
|
with open(os.path.join(filepath, filename + '.lrc'), 'wb') as f:
|
||||||
|
f.write(track['lyrics']['sync'].encode('utf-8'))
|
||||||
|
|
||||||
# Save local album art
|
# Save local album art
|
||||||
if coverPath:
|
if coverPath:
|
||||||
|
@ -619,64 +637,72 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
|
||||||
|
|
||||||
track['downloadUrl'] = dz.get_track_stream_url(track['id'], track['MD5'], track['mediaVersion'],
|
track['downloadUrl'] = dz.get_track_stream_url(track['id'], track['MD5'], track['mediaVersion'],
|
||||||
track['selectedFormat'])
|
track['selectedFormat'])
|
||||||
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Downloading the track")
|
trackAlreadyDownloaded = os.path.isfile(writepath)
|
||||||
try:
|
if not trackAlreadyDownloaded or settings['overwriteFile'] == 'y':
|
||||||
with open(writepath, 'wb') as stream:
|
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Downloading the track")
|
||||||
stream_track(dz, track, stream, trackAPI, queueItem, interface)
|
try:
|
||||||
except downloadCancelled:
|
with open(writepath, 'wb') as stream:
|
||||||
remove(writepath)
|
stream_track(dz, track, stream, trackAPI, queueItem, interface)
|
||||||
result['cancel'] = True
|
except downloadCancelled:
|
||||||
return result
|
remove(writepath)
|
||||||
except HTTPError:
|
result['cancel'] = True
|
||||||
remove(writepath)
|
return result
|
||||||
if track['fallbackId'] != 0:
|
except HTTPError:
|
||||||
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, using fallback id")
|
remove(writepath)
|
||||||
trackNew = dz.get_track_gw(track['fallbackId'])
|
if track['fallbackId'] != 0:
|
||||||
if not 'MD5_ORIGIN' in trackNew:
|
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, using fallback id")
|
||||||
trackNew['MD5_ORIGIN'] = dz.get_track_md5(trackNew['SNG_ID'])
|
trackNew = dz.get_track_gw(track['fallbackId'])
|
||||||
track = parseEssentialTrackData(track, trackNew)
|
|
||||||
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface)
|
|
||||||
elif not 'searched' in track and settings['fallbackSearch']:
|
|
||||||
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, searching for alternative")
|
|
||||||
searchedId = dz.get_track_from_metadata(track['mainArtist']['name'], track['title'],
|
|
||||||
track['album']['title'])
|
|
||||||
if searchedId != 0:
|
|
||||||
trackNew = dz.get_track_gw(searchedId)
|
|
||||||
if not 'MD5_ORIGIN' in trackNew:
|
if not 'MD5_ORIGIN' in trackNew:
|
||||||
trackNew['MD5_ORIGIN'] = dz.get_track_md5(trackNew['SNG_ID'])
|
trackNew['MD5_ORIGIN'] = dz.get_track_md5(trackNew['SNG_ID'])
|
||||||
track = parseEssentialTrackData(track, trackNew)
|
track = parseEssentialTrackData(track, trackNew)
|
||||||
track['searched'] = True
|
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface)
|
||||||
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track,
|
elif not 'searched' in track and settings['fallbackSearch']:
|
||||||
interface=interface)
|
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, searching for alternative")
|
||||||
|
searchedId = dz.get_track_from_metadata(track['mainArtist']['name'], track['title'],
|
||||||
|
track['album']['title'])
|
||||||
|
if searchedId != 0:
|
||||||
|
trackNew = dz.get_track_gw(searchedId)
|
||||||
|
if not 'MD5_ORIGIN' in trackNew:
|
||||||
|
trackNew['MD5_ORIGIN'] = dz.get_track_md5(trackNew['SNG_ID'])
|
||||||
|
track = parseEssentialTrackData(track, trackNew)
|
||||||
|
track['searched'] = True
|
||||||
|
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track,
|
||||||
|
interface=interface)
|
||||||
|
else:
|
||||||
|
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not available on deezer's servers and no alternative found!")
|
||||||
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
|
result['error'] = {
|
||||||
|
'message': "Track not available on deezer's servers and no alternative found!",
|
||||||
|
'data': track
|
||||||
|
}
|
||||||
|
if interface:
|
||||||
|
queueItem['failed'] += 1
|
||||||
|
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': track,
|
||||||
|
'error': "Track not available on deezer's servers and no alternative found!"})
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not available on deezer's servers and no alternative found!")
|
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not available on deezer's servers!")
|
||||||
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
result['error'] = {
|
result['error'] = {
|
||||||
'message': "Track not available on deezer's servers and no alternative found!",
|
'message': "Track not available on deezer's servers!",
|
||||||
'data': track
|
'data': track
|
||||||
}
|
}
|
||||||
if interface:
|
if interface:
|
||||||
queueItem['failed'] += 1
|
queueItem['failed'] += 1
|
||||||
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': track,
|
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': track,
|
||||||
'error': "Track not available on deezer's servers and no alternative found!"})
|
'error': "Track not available on deezer's servers!"})
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
logger.error(f"[{track['mainArtist']['name']} - {track['title']}] Track not available on deezer's servers!")
|
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Skipping track as it's already downloaded")
|
||||||
result['error'] = {
|
trackCompletePercentage(trackAPI, queueItem, interface)
|
||||||
'message': "Track not available on deezer's servers!",
|
if not trackAlreadyDownloaded or settings['overwriteFile'] in ['t', 'y']:
|
||||||
'data': track
|
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Applying tags to the track")
|
||||||
}
|
if track['selectedFormat'] in [3, 1, 8]:
|
||||||
if interface:
|
tagID3(writepath, track, settings['tags'])
|
||||||
queueItem['failed'] += 1
|
elif track['selectedFormat'] == 9:
|
||||||
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': track,
|
tagFLAC(writepath, track, settings['tags'])
|
||||||
'error': "Track not available on deezer's servers!"})
|
if 'searched' in track:
|
||||||
return result
|
result['searched'] = f'{track["mainArtist"]["name"]} - {track["title"]}'
|
||||||
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Applying tags to the track")
|
|
||||||
if track['selectedFormat'] in [3, 1, 8]:
|
|
||||||
tagID3(writepath, track, settings['tags'])
|
|
||||||
elif track['selectedFormat'] == 9:
|
|
||||||
tagFLAC(writepath, track, settings['tags'])
|
|
||||||
if 'searched' in track:
|
|
||||||
result['searched'] = f'{track["mainArtist"]["name"]} - {track["title"]}'
|
|
||||||
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Track download completed")
|
logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Track download completed")
|
||||||
if interface:
|
if interface:
|
||||||
queueItem['downloaded'] += 1
|
queueItem['downloaded'] += 1
|
||||||
|
@ -770,9 +796,9 @@ def after_download(tracks, settings, queueItem):
|
||||||
if not extrasPath and 'extrasPath' in result:
|
if not extrasPath and 'extrasPath' in result:
|
||||||
extrasPath = result['extrasPath']
|
extrasPath = result['extrasPath']
|
||||||
if settings['saveArtwork'] and 'albumPath' in result:
|
if settings['saveArtwork'] and 'albumPath' in result:
|
||||||
downloadImage(result['albumURL'], result['albumPath'])
|
downloadImage(result['albumURL'], result['albumPath'], settings['overwriteFile'])
|
||||||
if settings['saveArtworkArtist'] and 'artistPath' in result:
|
if settings['saveArtworkArtist'] and 'artistPath' in result:
|
||||||
downloadImage(result['artistURL'], result['artistPath'])
|
downloadImage(result['artistURL'], result['artistPath'], settings['overwriteFile'])
|
||||||
if 'playlistPosition' in result:
|
if 'playlistPosition' in result:
|
||||||
playlist[index] = result['playlistPosition']
|
playlist[index] = result['playlistPosition']
|
||||||
else:
|
else:
|
||||||
|
@ -800,9 +826,9 @@ def after_download_single(track, settings, queueItem):
|
||||||
if 'extrasPath' not in track:
|
if 'extrasPath' not in track:
|
||||||
track['extrasPath'] = settings['downloadLocation']
|
track['extrasPath'] = settings['downloadLocation']
|
||||||
if settings['saveArtwork'] and 'albumPath' in track:
|
if settings['saveArtwork'] and 'albumPath' in track:
|
||||||
downloadImage(track['albumURL'], track['albumPath'])
|
downloadImage(track['albumURL'], track['albumPath'], settings['overwriteFile'])
|
||||||
if settings['saveArtworkArtist'] and 'artistPath' in track:
|
if settings['saveArtworkArtist'] and 'artistPath' in track:
|
||||||
downloadImage(track['artistURL'], track['artistPath'])
|
downloadImage(track['artistURL'], track['artistPath'], settings['overwriteFile'])
|
||||||
if settings['logSearched'] and 'searched' in track:
|
if settings['logSearched'] and 'searched' in track:
|
||||||
with open(os.path.join(track['extrasPath'], 'searched.txt'), 'wb+') as f:
|
with open(os.path.join(track['extrasPath'], 'searched.txt'), 'wb+') as f:
|
||||||
orig = f.read().decode('utf-8')
|
orig = f.read().decode('utf-8')
|
||||||
|
|
|
@ -30,6 +30,22 @@ if its an album/playlist
|
||||||
collection
|
collection
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def resetQueueItems(items, q):
|
||||||
|
result = {}
|
||||||
|
for item in items.keys():
|
||||||
|
result[item] = items[item].copy()
|
||||||
|
if item in q:
|
||||||
|
result[item]['downloaded'] = 0
|
||||||
|
result[item]['failed'] = 0
|
||||||
|
result[item]['progress'] = 0
|
||||||
|
return result
|
||||||
|
|
||||||
|
def slimQueueItems(items):
|
||||||
|
result = {}
|
||||||
|
for item in items.keys():
|
||||||
|
result[item] = slimQueueItem(items[item])
|
||||||
|
return result
|
||||||
|
|
||||||
def slimQueueItem(item):
|
def slimQueueItem(item):
|
||||||
light = item.copy()
|
light = item.copy()
|
||||||
if 'single' in light:
|
if 'single' in light:
|
||||||
|
@ -306,6 +322,14 @@ def getQueue():
|
||||||
return (queue, queueComplete, queueList, currentItem)
|
return (queue, queueComplete, queueList, currentItem)
|
||||||
|
|
||||||
|
|
||||||
|
def restoreQueue(pqueue, pqueueComplete, pqueueList, dz, interface):
|
||||||
|
global currentItem, queueList, queue, queueComplete
|
||||||
|
queueComplete = pqueueComplete
|
||||||
|
queueList = pqueueList
|
||||||
|
queue = pqueue
|
||||||
|
nextItem(dz, interface)
|
||||||
|
|
||||||
|
|
||||||
def removeFromQueue(uuid, interface=None):
|
def removeFromQueue(uuid, interface=None):
|
||||||
global currentItem, queueList, queue, queueComplete
|
global currentItem, queueList, queue, queueComplete
|
||||||
if uuid == currentItem:
|
if uuid == currentItem:
|
||||||
|
|
Loading…
Reference in New Issue