Even more rework on the library

This commit is contained in:
RemixDev 2021-03-24 17:41:03 +01:00
parent dc6adc7887
commit eda8fd3d13
No known key found for this signature in database
GPG Key ID: B33962B465BDB51C
7 changed files with 95 additions and 129 deletions

View File

@ -23,13 +23,13 @@ def parseLink(link):
if '/track' in link:
type = 'track'
id = link[link.rfind("/") + 1:]
id = re.search("\/track\/(.+)", link).group(1)
elif '/playlist' in link:
type = 'playlist'
id = re.search("\/playlist\/(\d+)", link).group(1)
elif '/album' in link:
type = 'album'
id = link[link.rfind("/") + 1:]
id = re.search("\/album\/(.+)", link).group(1)
elif re.search("\/artist\/(\d+)\/top_track", link):
type = 'artist_top'
id = re.search("\/artist\/(\d+)\/top_track", link).group(1)
@ -42,7 +42,7 @@ def parseLink(link):
return (link, type, id)
def generateDownloadItem(dz, link, bitrate):
def generateDownloadObject(dz, link, bitrate):
(link, type, id) = parseLink(link)
if type == None or id == None: return None

View File

@ -5,7 +5,7 @@ from pathlib import Path
from deezer import Deezer
from deezer import TrackFormats
from deemix import generateDownloadItem
from deemix import generateDownloadObject
from deemix.settings import loadSettings
from deemix.utils import getBitrateNumberFromText
import deemix.utils.localpaths as localpaths
@ -49,8 +49,8 @@ def download(url, bitrate, portable, path):
links.append(link)
for link in links:
downloadItem = generateDownloadItem(dz, link, bitrate)
Downloader(dz, downloadItem, settings).start()
downloadObject = generateDownloadObject(dz, link, bitrate)
Downloader(dz, downloadObject, settings).start()
if path is not None:
if path == '': path = '.'

View File

@ -321,9 +321,9 @@ class Downloader:
raise DownloadCancelled
except (requests.exceptions.HTTPError, DownloadEmpty):
if writepath.is_file(): writepath.unlink()
if track.fallbackId != "0":
if track.fallbackID != "0":
logger.warn(f"[{track.mainArtist.name} - {track.title}] Track not available, using fallback id")
newTrack = self.dz.gw.get_track_with_fallback(track.fallbackId)
newTrack = self.dz.gw.get_track_with_fallback(track.fallbackID)
track.parseEssentialData(newTrack)
track.retriveFilesizes(self.dz)
return False
@ -418,9 +418,9 @@ class Downloader:
except DownloadFailed as error:
if error.track:
track = error.track
if track.fallbackId != "0":
if track.fallbackID != "0":
logger.warn(f"[{track.mainArtist.name} - {track.title}] {error.message} Using fallback id")
newTrack = self.dz.gw.get_track_with_fallback(track.fallbackId)
newTrack = self.dz.gw.get_track_with_fallback(track.fallbackID)
track.parseEssentialData(newTrack)
track.retriveFilesizes(self.dz)
return self.downloadWrapper(trackAPI_gw, trackAPI, albumAPI, playlistAPI, track)

View File

@ -42,18 +42,20 @@ def generateTrackItem(dz, id, bitrate, trackAPI=None, albumAPI=None):
title += f" {trackAPI_gw['VERSION']}".strip()
explicit = bool(int(trackAPI_gw.get('EXPLICIT_LYRICS', 0)))
return Single(
'track',
id,
bitrate,
title,
trackAPI_gw['ART_NAME'],
f"https://e-cdns-images.dzcdn.net/images/cover/{trackAPI_gw['ALB_PICTURE']}/75x75-000000-80-0-0.jpg",
explicit,
trackAPI_gw,
trackAPI,
albumAPI
)
return Single({
'type': 'track',
'id': id,
'bitrate': bitrate,
'title': title,
'artist': trackAPI_gw['ART_NAME'],
'cover': f"https://e-cdns-images.dzcdn.net/images/cover/{trackAPI_gw['ALB_PICTURE']}/75x75-000000-80-0-0.jpg",
'explicit': explicit,
'single': {
'trackAPI_gw': trackAPI_gw,
'trackAPI': trackAPI,
'albumAPI': albumAPI
}
})
def generateAlbumItem(dz, id, bitrate, rootArtist=None):
# Get essential album info
@ -93,18 +95,20 @@ def generateAlbumItem(dz, id, bitrate, rootArtist=None):
explicit = albumAPI_gw.get('EXPLICIT_ALBUM_CONTENT', {}).get('EXPLICIT_LYRICS_STATUS', LyricsStatus.UNKNOWN) in [LyricsStatus.EXPLICIT, LyricsStatus.PARTIALLY_EXPLICIT]
return Collection(
'album',
id,
bitrate,
albumAPI['title'],
albumAPI['artist']['name'],
cover,
explicit,
totalSize,
tracks_gw=collection,
albumAPI=albumAPI
)
return Collection({
'type': 'album',
'id': id,
'bitrate': bitrate,
'title': albumAPI['title'],
'artist': albumAPI['artist']['name'],
'cover': cover,
'explicit': explicit,
'size': totalSize,
'collection': {
'tracks_gw': collection,
'albumAPI': albumAPI
}
})
def generatePlaylistItem(dz, id, bitrate, playlistAPI=None, playlistTracksAPI=None):
if not playlistAPI:
@ -146,18 +150,20 @@ def generatePlaylistItem(dz, id, bitrate, playlistAPI=None, playlistTracksAPI=No
if not 'explicit' in playlistAPI: playlistAPI['explicit'] = False
return Collection(
'playlist',
id,
bitrate,
playlistAPI['title'],
playlistAPI['creator']['name'],
playlistAPI['picture_small'][:-24] + '/75x75-000000-80-0-0.jpg',
playlistAPI['explicit'],
totalSize,
tracks_gw=collection,
playlistAPI=playlistAPI
)
return Collection({
'type': 'playlist',
'id': id,
'bitrate': bitrate,
'title': playlistAPI['title'],
'artist': playlistAPI['creator']['name'],
'cover': playlistAPI['picture_small'][:-24] + '/75x75-000000-80-0-0.jpg',
'explicit': playlistAPI['explicit'],
'size': totalSize,
'collection': {
'tracks_gw': collection,
'playlistAPI': playlistAPI
}
})
def generateArtistItem(dz, id, bitrate, interface=None):
# Get essential artist info

View File

@ -1,33 +1,18 @@
class IDownloadObject:
def __init__(self, type=None, id=None, bitrate=None, title=None, artist=None, cover=None, explicit=False, size=None, dictItem=None):
if dictItem:
self.type = dictItem['type']
self.id = dictItem['id']
self.bitrate = dictItem['bitrate']
self.title = dictItem['title']
self.artist = dictItem['artist']
self.cover = dictItem['cover']
self.explicit = dictItem.get('explicit', False)
self.size = dictItem['size']
self.downloaded = dictItem['downloaded']
self.failed = dictItem['failed']
self.progress = dictItem['progress']
self.errors = dictItem['errors']
self.files = dictItem['files']
else:
self.type = type
self.id = id
self.bitrate = bitrate
self.title = title
self.artist = artist
self.cover = cover
self.explicit = explicit
self.size = size
self.downloaded = 0
self.failed = 0
self.progress = 0
self.errors = []
self.files = []
def __init__(self, obj):
self.type = obj['type']
self.id = obj['id']
self.bitrate = obj['bitrate']
self.title = obj['title']
self.artist = obj['artist']
self.cover = obj['cover']
self.explicit = obj.get('explicit', False)
self.size = obj['size']
self.downloaded = obj.get('downloaded', 0)
self.failed = obj.get('failed', 0)
self.progress = obj.get('progress', 0)
self.errors = obj.get('errors', [])
self.files = obj.get('files', [])
self.progressNext = 0
self.uuid = f"{self.type}_{self.id}_{self.bitrate}"
self.ack = None
@ -76,17 +61,10 @@ class IDownloadObject:
if interface: interface.send("updateQueue", {'uuid': self.uuid, 'progress': self.progress})
class Single(IDownloadObject):
def __init__(self, type=None, id=None, bitrate=None, title=None, artist=None, cover=None, explicit=False, trackAPI_gw=None, trackAPI=None, albumAPI=None, dictItem=None):
if dictItem:
super().__init__(dictItem=dictItem)
self.single = dictItem['single']
else:
super().__init__(type, id, bitrate, title, artist, cover, explicit, 1)
self.single = {
'trackAPI_gw': trackAPI_gw,
'trackAPI': trackAPI,
'albumAPI': albumAPI
}
def __init__(self, obj):
super().__init__(obj)
self.size = 1
self.single = obj['single']
self.__type__ = "Single"
def toDict(self):
@ -103,17 +81,9 @@ class Single(IDownloadObject):
self.updateProgress(interface)
class Collection(IDownloadObject):
def __init__(self, type=None, id=None, bitrate=None, title=None, artist=None, cover=None, explicit=False, size=None, tracks_gw=None, albumAPI=None, playlistAPI=None, dictItem=None):
if dictItem:
super().__init__(dictItem=dictItem)
self.collection = dictItem['collection']
else:
super().__init__(type, id, bitrate, title, artist, cover, explicit, size)
self.collection = {
'tracks_gw': tracks_gw,
'albumAPI': albumAPI,
'playlistAPI': playlistAPI
}
def __init__(self, obj):
super().__init__(obj)
self.collection = obj['collection']
self.__type__ = "Collection"
def toDict(self):
@ -130,15 +100,10 @@ class Collection(IDownloadObject):
self.updateProgress(interface)
class Convertable(Collection):
def __init__(self, type=None, id=None, bitrate=None, title=None, artist=None, cover=None, explicit=False, size=None, plugin=None, conversion_data=None, dictItem=None):
if dictItem:
super().__init__(dictItem=dictItem)
self.plugin = dictItem['plugin']
self.conversion_data = dictItem['conversion_data']
else:
super().__init__(type, id, bitrate, title, artist, cover, explicit, size)
self.plugin = plugin
self.conversion_data = conversion_data
def __init__(self, obj):
super().__init__(obj)
self.plugin = obj['plugin']
self.conversion_data = obj['conversion_data']
self.__type__ = "Convertable"
def toDict(self):

View File

@ -14,10 +14,9 @@ class Picture:
)
if format.startswith("jpg"):
quality = 80
if '-' in format:
quality = format[4:]
else:
quality = 80
format = 'jpg'
return url + f'-000000-{quality}-0-0.jpg'
if format == 'png':

View File

@ -1,12 +1,9 @@
from time import sleep
import requests
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('deemix')
from time import sleep
from deezer.gw import GWAPIError
from deezer.api import APIError
from deemix.utils import removeFeatures, andCommaConcat, removeDuplicateArtists, generateReplayGainString, changeCase
from deemix.types.Album import Album
@ -24,7 +21,7 @@ class Track:
self.MD5 = ""
self.mediaVersion = ""
self.duration = 0
self.fallbackId = "0"
self.fallbackID = "0"
self.filesizes = {}
self.localTrack = False
self.mainArtist = None
@ -46,7 +43,7 @@ class Track:
self.searched = False
self.selectedFormat = 0
self.singleDownload = False
self.dateString = None
self.dateString = ""
self.artistsString = ""
self.mainArtistsString = ""
self.featArtistsString = ""
@ -61,14 +58,14 @@ class Track:
else:
raise MD5NotFound
self.mediaVersion = trackAPI_gw['MEDIA_VERSION']
self.fallbackId = "0"
self.fallbackID = "0"
if 'FALLBACK' in trackAPI_gw:
self.fallbackId = trackAPI_gw['FALLBACK']['SNG_ID']
self.fallbackID = trackAPI_gw['FALLBACK']['SNG_ID']
self.localTrack = int(self.id) < 0
def retriveFilesizes(self, dz):
try:
guest_sid = dz.session.cookies.get('sid')
try:
site = requests.post(
"https://api.deezer.com/1.0/gateway.php",
params={
@ -97,8 +94,7 @@ class Track:
self.filesizes = filesizes
def parseData(self, dz, id=None, trackAPI_gw=None, trackAPI=None, albumAPI_gw=None, albumAPI=None, playlistAPI=None):
if id:
if not trackAPI_gw: trackAPI_gw = dz.gw.get_track_with_fallback(id)
if id and not trackAPI_gw: trackAPI_gw = dz.gw.get_track_with_fallback(id)
elif not trackAPI_gw: raise NoDataToParse
if not trackAPI:
try: trackAPI = dz.api.get_track(trackAPI_gw['SNG_ID'])
@ -110,15 +106,15 @@ class Track:
self.parseLocalTrackData(trackAPI_gw)
else:
self.retriveFilesizes(dz)
self.parseTrackGW(trackAPI_gw)
# Get Lyrics data
if not "LYRICS" in trackAPI_gw and self.lyrics.id != "0":
try: trackAPI_gw["LYRICS"] = dz.gw.get_track_lyrics(self.id)
except GWAPIError: self.lyrics.id = "0"
if self.lyrics.id != "0": self.lyrics.parseLyrics(trackAPI_gw["LYRICS"])
# Parse Album data
# Parse Album Data
self.album = Album(
id = trackAPI_gw['ALB_ID'],
title = trackAPI_gw['ALB_TITLE'],
@ -161,7 +157,7 @@ class Track:
if not len(self.artist['Main']):
self.artist['Main'] = [self.mainArtist['name']]
self.singleDownload = trackAPI_gw.get('SINGLE_TRACK', False)
self.singleDownload = trackAPI_gw.get('SINGLE_TRACK', False) # TODO: To change
self.position = trackAPI_gw.get('POSITION')
# Add playlist data if track is in a playlist
@ -184,16 +180,16 @@ class Track:
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
self.album.mainArtist = self.mainArtist
self.date = Date()
def parseTrackGW(self, trackAPI_gw):
self.title = trackAPI_gw['SNG_TITLE'].strip()
if trackAPI_gw.get('VERSION') and not trackAPI_gw['VERSION'] in trackAPI_gw['SNG_TITLE']:
self.title += " " + trackAPI_gw['VERSION'].strip()
if trackAPI_gw.get('VERSION') and not trackAPI_gw['VERSION'].strip() in this.title:
self.title += f" {trackAPI_gw['VERSION'].strip()}"
self.discNumber = trackAPI_gw.get('DISK_NUMBER')
self.explicit = bool(int(trackAPI_gw.get('EXPLICIT_LYRICS', "0")))
@ -215,7 +211,7 @@ class Track:
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(year, month, day)
self.date = Date(day, month, year)
def parseTrack(self, trackAPI):
self.bpm = trackAPI['bpm']
@ -250,8 +246,8 @@ class Track:
return removeFeatures(self.title)
def getFeatTitle(self):
if self.featArtistsString and not "(feat." in self.title.lower():
return self.title + " ({})".format(self.featArtistsString)
if self.featArtistsString and not "feat." in self.title.lower():
return f"{self.title} ({self.featArtistsString})"
return self.title
def generateMainFeatStrings(self):