2020-09-20 08:35:05 +00:00
|
|
|
import string
|
2020-11-19 21:08:35 +00:00
|
|
|
from deezer import TrackFormats
|
2020-10-08 11:26:17 +00:00
|
|
|
import os
|
2021-08-02 21:45:08 +00:00
|
|
|
from deemix.errors import ErrorMessages
|
2020-09-20 08:35:05 +00:00
|
|
|
|
2021-06-27 20:29:41 +00:00
|
|
|
USER_AGENT_HEADER = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " \
|
|
|
|
"Chrome/79.0.3945.130 Safari/537.36"
|
|
|
|
|
|
|
|
def canWrite(folder):
|
|
|
|
return os.access(folder, os.W_OK)
|
|
|
|
|
2020-09-24 17:20:01 +00:00
|
|
|
def generateReplayGainString(trackGain):
|
|
|
|
return "{0:.2f} dB".format((float(trackGain) + 18.4) * -1)
|
|
|
|
|
2021-06-27 20:29:41 +00:00
|
|
|
def getBitrateNumberFromText(txt):
|
2020-09-20 08:35:05 +00:00
|
|
|
txt = str(txt).lower()
|
|
|
|
if txt in ['flac', 'lossless', '9']:
|
2020-10-02 17:20:23 +00:00
|
|
|
return TrackFormats.FLAC
|
2021-06-27 20:29:41 +00:00
|
|
|
if txt in ['mp3', '320', '3']:
|
2020-10-02 17:20:23 +00:00
|
|
|
return TrackFormats.MP3_320
|
2021-06-27 20:29:41 +00:00
|
|
|
if txt in ['128', '1']:
|
2020-10-02 17:20:23 +00:00
|
|
|
return TrackFormats.MP3_128
|
2021-06-27 20:29:41 +00:00
|
|
|
if txt in ['360', '360_hq', '15']:
|
2020-10-02 17:20:23 +00:00
|
|
|
return TrackFormats.MP4_RA3
|
2021-06-27 20:29:41 +00:00
|
|
|
if txt in ['360_mq', '14']:
|
2020-10-02 17:20:23 +00:00
|
|
|
return TrackFormats.MP4_RA2
|
2021-06-27 20:29:41 +00:00
|
|
|
if txt in ['360_lq', '13']:
|
2020-10-02 17:20:23 +00:00
|
|
|
return TrackFormats.MP4_RA1
|
2021-06-27 20:29:41 +00:00
|
|
|
return None
|
|
|
|
|
|
|
|
def changeCase(txt, case_type):
|
|
|
|
if case_type == "lower":
|
|
|
|
return txt.lower()
|
|
|
|
if case_type == "upper":
|
|
|
|
return txt.upper()
|
|
|
|
if case_type == "start":
|
2021-09-21 07:12:15 +00:00
|
|
|
txt = txt.split(" ")
|
|
|
|
for i, word in enumerate(txt):
|
|
|
|
if word[0] in ['(', '{', '[']:
|
|
|
|
txt[i] = word[0] + word[1:].capitalize()
|
|
|
|
else:
|
|
|
|
txt[i] = word.capitalize()
|
|
|
|
return " ".join(txt)
|
2021-06-27 20:29:41 +00:00
|
|
|
if case_type == "sentence":
|
|
|
|
return txt.capitalize()
|
|
|
|
return str
|
2020-09-20 08:35:05 +00:00
|
|
|
|
|
|
|
def removeFeatures(title):
|
|
|
|
clean = title
|
|
|
|
if "(feat." in clean.lower():
|
|
|
|
pos = clean.lower().find("(feat.")
|
|
|
|
tempTrack = clean[:pos]
|
|
|
|
if ")" in clean:
|
|
|
|
tempTrack += clean[clean.find(")", pos + 1) + 1:]
|
|
|
|
clean = tempTrack.strip()
|
2021-02-01 11:33:40 +00:00
|
|
|
clean = ' '.join(clean.split())
|
2020-09-20 08:35:05 +00:00
|
|
|
return clean
|
|
|
|
|
|
|
|
def andCommaConcat(lst):
|
|
|
|
tot = len(lst)
|
|
|
|
result = ""
|
|
|
|
for i, art in enumerate(lst):
|
|
|
|
result += art
|
|
|
|
if tot != i + 1:
|
|
|
|
if tot - 1 == i + 1:
|
|
|
|
result += " & "
|
|
|
|
else:
|
|
|
|
result += ", "
|
|
|
|
return result
|
|
|
|
|
|
|
|
def uniqueArray(arr):
|
|
|
|
for iPrinc, namePrinc in enumerate(arr):
|
|
|
|
for iRest, nRest in enumerate(arr):
|
|
|
|
if iPrinc!=iRest and namePrinc.lower() in nRest.lower():
|
|
|
|
del arr[iRest]
|
|
|
|
return arr
|
2020-10-08 11:26:17 +00:00
|
|
|
|
2021-01-31 16:59:15 +00:00
|
|
|
def removeDuplicateArtists(artist, artists):
|
|
|
|
artists = uniqueArray(artists)
|
|
|
|
for role in artist.keys():
|
|
|
|
artist[role] = uniqueArray(artist[role])
|
|
|
|
return (artist, artists)
|
2021-08-02 21:45:08 +00:00
|
|
|
|
|
|
|
def formatListener(key, data=None):
|
|
|
|
if key == "startAddingArtist":
|
2021-08-05 17:27:28 +00:00
|
|
|
return f"Started gathering {data['name']}'s albums ({data['id']})"
|
2021-08-02 21:45:08 +00:00
|
|
|
if key == "finishAddingArtist":
|
2021-08-05 17:27:28 +00:00
|
|
|
return f"Finished gathering {data['name']}'s albums ({data['id']})"
|
2021-08-02 21:45:08 +00:00
|
|
|
if key == "updateQueue":
|
|
|
|
uuid = f"[{data['uuid']}]"
|
|
|
|
if data.get('downloaded'):
|
|
|
|
shortFilepath = data['downloadPath'][len(data['extrasPath']):]
|
|
|
|
return f"{uuid} Completed download of {shortFilepath}"
|
|
|
|
if data.get('failed'):
|
|
|
|
return f"{uuid} {data['data']['artist']} - {data['data']['title']} :: {data['error']}"
|
|
|
|
if data.get('progress'):
|
|
|
|
return f"{uuid} Download at {data['progress']}%"
|
|
|
|
if data.get('conversion'):
|
|
|
|
return f"{uuid} Conversion at {data['conversion']}%"
|
|
|
|
return uuid
|
|
|
|
if key == "downloadInfo":
|
|
|
|
message = data['state']
|
|
|
|
if data['state'] == "getTags": message = "Getting tags."
|
|
|
|
elif data['state'] == "gotTags": message = "Tags got."
|
|
|
|
elif data['state'] == "getBitrate": message = "Getting download URL."
|
|
|
|
elif data['state'] == "bitrateFallback": message = "Desired bitrate not found, falling back to lower bitrate."
|
|
|
|
elif data['state'] == "searchFallback": message = "This track has been searched for, result might not be 100% exact."
|
|
|
|
elif data['state'] == "gotBitrate": message = "Download URL got."
|
|
|
|
elif data['state'] == "getAlbumArt": message = "Downloading album art."
|
|
|
|
elif data['state'] == "gotAlbumArt": message = "Album art downloaded."
|
|
|
|
elif data['state'] == "downloading":
|
|
|
|
message = "Downloading track."
|
|
|
|
if data['alreadyStarted']:
|
|
|
|
message += f" Recovering download from {data['value']}."
|
|
|
|
else:
|
|
|
|
message += f" Downloading {data['value']} bytes."
|
|
|
|
elif data['state'] == "downloaded": message = "Track downloaded."
|
|
|
|
elif data['state'] == "alreadyDownloaded": message = "Track already downloaded."
|
|
|
|
elif data['state'] == "tagging": message = "Tagging track."
|
|
|
|
elif data['state'] == "tagged": message = "Track tagged."
|
|
|
|
return f"[{data['uuid']}] {data['data']['artist']} - {data['data']['title']} :: {message}"
|
|
|
|
if key == "downloadWarn":
|
|
|
|
errorMessage = ErrorMessages[data['state']]
|
|
|
|
solutionMessage = ""
|
|
|
|
if data['solution'] == 'fallback': solutionMessage = "Using fallback id."
|
|
|
|
if data['solution'] == 'search': solutionMessage = "Searching for alternative."
|
|
|
|
return f"[{data['uuid']}] {data['data']['artist']} - {data['data']['title']} :: {errorMessage} {solutionMessage}"
|
|
|
|
if key == "currentItemCancelled":
|
2021-08-02 21:54:15 +00:00
|
|
|
return f"Current item cancelled ({data})"
|
2021-08-02 21:45:08 +00:00
|
|
|
if key == "removedFromQueue":
|
2021-08-02 21:54:15 +00:00
|
|
|
return f"[{data}] Removed from the queue"
|
2021-08-02 21:45:08 +00:00
|
|
|
if key == "finishDownload":
|
2021-08-02 21:54:15 +00:00
|
|
|
return f"[{data}] Finished downloading"
|
2021-08-02 21:45:08 +00:00
|
|
|
if key == "startConversion":
|
2021-08-02 21:54:15 +00:00
|
|
|
return f"[{data}] Started converting"
|
2021-08-02 21:45:08 +00:00
|
|
|
if key == "finishConversion":
|
2021-08-04 19:36:34 +00:00
|
|
|
return f"[{data['uuid']}] Finished converting"
|
2021-08-02 21:45:08 +00:00
|
|
|
return ""
|