Fallback corrupted FLAC files

This adds #3
This commit is contained in:
RemixDev 2020-07-29 01:00:16 +02:00
parent 0ad552ef2d
commit b450929553
3 changed files with 33 additions and 7 deletions

View File

@ -1,3 +1,3 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
__version__ = "1.1.21" __version__ = "1.1.22"

View File

@ -15,6 +15,7 @@ from deemix.api.deezer import APIError, USER_AGENT_HEADER
from deemix.utils.misc import changeCase, uniqueArray from deemix.utils.misc import changeCase, uniqueArray
from deemix.utils.pathtemplates import generateFilename, generateFilepath, settingsRegexAlbum, settingsRegexArtist, settingsRegexPlaylistFile from deemix.utils.pathtemplates import generateFilename, generateFilepath, settingsRegexAlbum, settingsRegexArtist, settingsRegexPlaylistFile
from deemix.utils.taggers import tagID3, tagFLAC from deemix.utils.taggers import tagID3, tagFLAC
from mutagen.flac import FLACNoHeaderError
import logging import logging
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
@ -86,6 +87,18 @@ def trackCompletePercentage(trackAPI, queueItem, interface):
if interface: if interface:
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage}) interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage})
def trackRemovePercentage(trackAPI, queueItem, interface):
global downloadPercentage, lastPercentage
if 'SINGLE_TRACK' in trackAPI:
downloadPercentage = 0
else:
downloadPercentage -= 1 / trackAPI['SIZE'] * 100
if round(downloadPercentage) != lastPercentage and round(downloadPercentage) % 2 == 0:
lastPercentage = round(downloadPercentage)
queueItem['progress'] = lastPercentage
if interface:
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage})
def downloadImage(url, path, overwrite="n"): def downloadImage(url, path, overwrite="n"):
if not os.path.isfile(path) or overwrite in ['y', 't']: if not os.path.isfile(path) or overwrite in ['y', 't']:
@ -157,7 +170,7 @@ def getPreferredBitrate(dz, track, bitrate, fallback=True):
for format_num, format in formats.items(): for format_num, format in formats.items():
if format_num <= int(bitrate): if format_num <= int(bitrate):
if f"FILESIZE_{format}" in filesizes and int(filesizes[f"FILESIZE_{format}"]) != 0: if f"FILESIZE_{format}" in filesizes and int(filesizes[f"FILESIZE_{format}"]) != 0 and ((format_num == 9 and not 'flacCorrupted' in track) or format_num != 9):
return format_num return format_num
else: else:
if fallback: if fallback:
@ -177,7 +190,6 @@ def parseEssentialTrackData(track, trackAPI):
track['fallbackId'] = trackAPI['FALLBACK']['SNG_ID'] track['fallbackId'] = trackAPI['FALLBACK']['SNG_ID']
else: else:
track['fallbackId'] = 0 track['fallbackId'] = 0
return track return track
@ -507,6 +519,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded, using fallback id") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded, using fallback id")
trackNew = dz.get_track_gw(track['fallbackId']) trackNew = dz.get_track_gw(track['fallbackId'])
track = parseEssentialTrackData(track, trackNew) track = parseEssentialTrackData(track, trackNew)
if 'flacCorrupted' in track: del track['flacCorrupted']
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface) return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface)
elif not 'searched' in track and settings['fallbackSearch']: elif not 'searched' in track and settings['fallbackSearch']:
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded, searching for alternative") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not yet encoded, searching for alternative")
@ -515,6 +528,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
if searchedId != 0: if searchedId != 0:
trackNew = dz.get_track_gw(searchedId) trackNew = dz.get_track_gw(searchedId)
track = parseEssentialTrackData(track, trackNew) track = parseEssentialTrackData(track, trackNew)
if 'flacCorrupted' in track: del track['flacCorrupted']
track['searched'] = True track['searched'] = True
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track,
interface=interface) interface=interface)
@ -562,6 +576,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not found at desired bitrate, using fallback id") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not found at desired bitrate, using fallback id")
trackNew = dz.get_track_gw(track['fallbackId']) trackNew = dz.get_track_gw(track['fallbackId'])
track = parseEssentialTrackData(track, trackNew) track = parseEssentialTrackData(track, trackNew)
if 'flacCorrupted' in track: del track['flacCorrupted']
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface) return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface)
elif not 'searched' in track and settings['fallbackSearch']: elif not 'searched' in track and settings['fallbackSearch']:
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not found at desired bitrate, searching for alternative") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not found at desired bitrate, searching for alternative")
@ -570,6 +585,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
if searchedId != 0: if searchedId != 0:
trackNew = dz.get_track_gw(searchedId) trackNew = dz.get_track_gw(searchedId)
track = parseEssentialTrackData(track, trackNew) track = parseEssentialTrackData(track, trackNew)
if 'flacCorrupted' in track: del track['flacCorrupted']
track['searched'] = True track['searched'] = True
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track,
interface=interface) interface=interface)
@ -815,6 +831,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, using fallback id") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, using fallback id")
trackNew = dz.get_track_gw(track['fallbackId']) trackNew = dz.get_track_gw(track['fallbackId'])
track = parseEssentialTrackData(track, trackNew) track = parseEssentialTrackData(track, trackNew)
if 'flacCorrupted' in track: del track['flacCorrupted']
return 2 return 2
elif not 'searched' in track and settings['fallbackSearch']: elif not 'searched' in track and settings['fallbackSearch']:
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, searching for alternative") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available, searching for alternative")
@ -823,6 +840,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
if searchedId != 0: if searchedId != 0:
trackNew = dz.get_track_gw(searchedId) trackNew = dz.get_track_gw(searchedId)
track = parseEssentialTrackData(track, trackNew) track = parseEssentialTrackData(track, trackNew)
if 'flacCorrupted' in track: del track['flacCorrupted']
track['searched'] = True track['searched'] = True
return 2 return 2
else: else:
@ -861,7 +879,8 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'],
'error': result['error']['message'], 'errid': result['error']['errid']}) 'error': result['error']['message'], 'errid': result['error']['errid']})
return 1 return 1
except: except Exception as e:
logger.exception(str(e))
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Error while downloading the track, trying again in 5s...") logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Error while downloading the track, trying again in 5s...")
sleep(5) sleep(5)
return downloadMusic(dz, track, trackAPI, queueItem, interface, writepath, result, settings) return downloadMusic(dz, track, trackAPI, queueItem, interface, writepath, result, settings)
@ -879,7 +898,14 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
if track['selectedFormat'] in [3, 1, 8]: if track['selectedFormat'] in [3, 1, 8]:
tagID3(writepath, track, settings['tags']) tagID3(writepath, track, settings['tags'])
elif track['selectedFormat'] == 9: elif track['selectedFormat'] == 9:
try:
tagFLAC(writepath, track, settings['tags']) tagFLAC(writepath, track, settings['tags'])
except FLACNoHeaderError:
remove(writepath)
logger.warn(f"[{track['mainArtist']['name']} - {track['title']}] Track not available in FLAC, falling back if necessary")
trackRemovePercentage(trackAPI, queueItem, interface)
track['flacCorrupted'] = True
return downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=track, interface=interface)
if 'searched' in track: if 'searched' in track:
result['searched'] = f'{track["mainArtist"]["name"]} - {track["title"]}' 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")

View File

@ -7,7 +7,7 @@ README = (HERE / "README.md").read_text()
setup( setup(
name="deemix", name="deemix",
version="1.1.21", version="1.1.22",
description="A barebone deezer downloader library", description="A barebone deezer downloader library",
long_description=README, long_description=README,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",