From 31a734422601c487e6435e8fcf22227019049452 Mon Sep 17 00:00:00 2001 From: RemixDev Date: Thu, 8 Apr 2021 17:39:33 +0200 Subject: [PATCH] Finished porting itemgen.js --- deemix/index.js | 21 +-- deemix/itemgen.js | 247 +++++++++++++++++++------------- deemix/types/DownloadObjects.js | 32 ++--- deemix/types/Picture.js | 4 +- deemix/types/Track.js | 4 +- deemix/types/index.js | 4 + package-lock.json | 26 ++-- package.json | 2 +- 8 files changed, 196 insertions(+), 144 deletions(-) diff --git a/deemix/index.js b/deemix/index.js index aac1deb..11e8e4c 100644 --- a/deemix/index.js +++ b/deemix/index.js @@ -9,7 +9,10 @@ const { } = require('./itemgen.js') async function parseLink(link){ - if (link.indexOf('deezer.page.link') != -1) link = await got.get(link).url // Resolve URL shortner + if (link.indexOf('deezer.page.link') != -1){ + link = await got.get(link) // Resolve URL shortner + link = link.url + } // Remove extra stuff if (link.indexOf('?') != -1) link = link.substring(0, link.indexOf('?')) if (link.indexOf('&') != -1) link = link.substring(0, link.indexOf('&')) @@ -21,29 +24,30 @@ async function parseLink(link){ if (link.search(/\/track\/(.+)/g) != -1){ type = 'track' - id = link.match(/\/track\/(.+)/g)[1] + id = /\/track\/(.+)/g.exec(link)[1] }else if (link.search(/\/playlist\/(\d+)/g) != -1){ type = 'playlist' - id = link.match(/\/playlist\/(\d+)/g)[1] + id = /\/playlist\/(\d+)/g.exec(link)[1] }else if (link.search(/\/album\/(.+)/g) != -1){ type = 'album' - id = link.match(/\/album\/(.+)/g)[1] + id = /\/album\/(.+)/g.exec(link)[1] }else if (link.search(/\/artist\/(\d+)\/top_track/g) != -1){ type = 'artist_top' - id = link.match(/\/artist\/(\d+)\/top_track/g)[1] + id = /\/artist\/(\d+)\/top_track/g.exec(link)[1] }else if (link.search(/\/artist\/(\d+)\/discography/g) != -1){ type = 'artist_discography' - id = link.match(/\/artist\/(\d+)\/discography/g)[1] + id = /\/artist\/(\d+)\/discography/g.exec(link)[1] }else if (link.search(/\/artist\/(\d+)/g) != -1){ type = 'artist' - id = link.match(/\/artist\/(\d+)/g)[1] + id = /\/artist\/(\d+)/g.exec(link)[1] } return [link, type, id] } async function generateDownloadObject(dz, link, bitrate){ - let [link, type, id] = await parseLink(link) + let type, id + [link, type, id] = await parseLink(link) if (type == null || id == null) return null @@ -67,7 +71,6 @@ async function generateDownloadObject(dz, link, bitrate){ module.exports = { parseLink, generateDownloadObject, - VARIOUS_ARTISTS, types: { ...require('./types/index.js'), ...require('./types/Album.js'), diff --git a/deemix/itemgen.js b/deemix/itemgen.js index 7e061f8..1fa4de3 100644 --- a/deemix/itemgen.js +++ b/deemix/itemgen.js @@ -1,33 +1,41 @@ +const { + Single, + Collection, + Convertable +} = require('./types/DownloadObjects.js') + async function generateTrackItem(dz, id, bitrate, trackAPI, albumAPI){ // Check if is an isrc: url - if (str(id).startsWith("isrc")){ + if (id.startsWith("isrc")){ try { trackAPI = await dz.api.get_track(id) - } catch { - throw Exception("WrongURL") + } catch (e){ + console.error(e) + throw "WrongURL" } if (trackAPI.id && trackAPI.title){ id = trackAPI.id } else { - throw Exception("ISRCnotOnDeezer") + throw "ISRCnotOnDeezer" } } // Get essential track info try { trackAPI_gw = await dz.gw.get_track_with_fallback(id) - } catch { - throw Exception("WrongURL") + } catch (e){ + console.error(e) + throw "WrongURL" } let title = trackAPI_gw.SNG_TITLE.trim() if (trackAPI_gw.VERSION && title.indexOf(trackAPI_gw.VERSION.trim()) == -1){ title += ` ${trackAPI_gw.VERSION.trim()}` } - const explicit = bool(int(trackAPI_gw.EXPLICIT_LYRICS || "0")) + const explicit = Boolean(parseInt(trackAPI_gw.EXPLICIT_LYRICS || "0")) - return Single({ + return new Single({ type: 'track', id: id, bitrate: bitrate, @@ -47,16 +55,17 @@ async function generateAlbumItem(dz, id, bitrate, rootArtist){ // Get essential album info let albumAPI try{ - albumAPI = dz.api.get_album(id) - } catch { - throw Exception("WrongURL") + albumAPI = await dz.api.get_album(id) + } catch (e){ + console.error(e) + throw "WrongURL" } - if str(id).startswith('upc') { id = albumAPI['id'] } + if (id.startswith('upc')) { id = albumAPI['id'] } // Get extra info about album // This saves extra api calls when downloading - let albumAPI_gw = dz.gw.get_album(id) + let albumAPI_gw = await dz.gw.get_album(id) albumAPI.nb_disk = albumAPI_gw.NUMBER_DISK albumAPI.copyright = albumAPI_gw.COPYRIGHT albumAPI.root_artist = rootArtist @@ -66,7 +75,7 @@ async function generateAlbumItem(dz, id, bitrate, rootArtist){ return generateTrackItem(dz, albumAPI.tracks.data[0].id, bitrate, null, albumAPI) } - tracksArray = dz.gw.get_album_tracks(id) + tracksArray = await dz.gw.get_album_tracks(id) if (albumAPI.cover_small){ const cover = albumAPI.cover_small.substring(0, albumAPI.cover_small.length-24) + '/75x75-000000-80-0-0.jpg' @@ -83,9 +92,9 @@ async function generateAlbumItem(dz, id, bitrate, rootArtist){ collection.push(trackAPI) }) - explicit = albumAPI_gw.get('EXPLICIT_ALBUM_CONTENT', {}).get('EXPLICIT_LYRICS_STATUS', LyricsStatus.UNKNOWN) in [LyricsStatus.EXPLICIT, LyricsStatus.PARTIALLY_EXPLICIT] + explicit = [LyricsStatus.EXPLICIT, LyricsStatus.PARTIALLY_EXPLICIT].includes(albumAPI_gw.EXPLICIT_ALBUM_CONTENT.EXPLICIT_LYRICS_STATUS || LyricsStatus.UNKNOWN) - return Collection({ + return new Collection({ type: 'album', id: id, bitrate: bitrate, @@ -105,29 +114,31 @@ async function generatePlaylistItem(dz, id, bitrate, playlistAPI, playlistTracks if (!playlistAPI){ // Get essential playlist info try{ - playlistAPI = dz.api.get_playlist(id) - }catch{ + playlistAPI = await dz.api.get_playlist(id) + }catch (e){ + console.error(e) playlistAPI = null } // Fallback to gw api if the playlist is private if (!playlistAPI){ try{ - let userPlaylist = dz.gw.get_playlist_page(id) + let userPlaylist = await dz.gw.get_playlist_page(id) playlistAPI = map_user_playlist(userPlaylist['DATA']) - }catch{ - throw Exception("WrongURL") + }catch (e){ + console.error(e) + throw "WrongURL" } } // Check if private playlist and owner if (!playlsitAPI.public && playlistAPI.creator.id != dz.current_user.id){ - throw Exception("notYourPrivatePlaylist") + throw "notYourPrivatePlaylist" } } if (!playlistTracksAPI){ - playlistTracksAPI = dz.gw.get_playlist_tracks(id) + playlistTracksAPI = await dz.gw.get_playlist_tracks(id) } - playlistAPI.various_artist = dz.api.get_artist(5080) // Useful for save as compilation + playlistAPI.various_artist = await dz.api.get_artist(5080) // Useful for save as compilation const totalSize = playlistTracksAPI.length playlistAPI.nb_tracks = totalSize @@ -141,7 +152,7 @@ async function generatePlaylistItem(dz, id, bitrate, playlistAPI, playlistTracks if (!playlistAPI.explicit) playlistAPI.explicit = false - return Collection({ + return new Collection({ type: 'playlist', id: id, bitrate: bitrate, @@ -157,90 +168,124 @@ async function generatePlaylistItem(dz, id, bitrate, playlistAPI, playlistTracks }) } -async function generateArtistItem(dz, id, bitrate, interface=None): - // Get essential artist info - try: - artistAPI = dz.api.get_artist(id) - except APIError as e: - e = str(e) - raise GenerationError("https://deezer.com/artist/"+str(id), f"Wrong URL: {e}") +async function generateArtistItem(dz, id, bitrate, listener){ + // Get essential artist info + let artistAPI + try{ + artistAPI = await dz.api.get_artist(id) + }catch (e){ + console.error(e) + throw "https://deezer.com/artist/"+id, `Wrong URL: ${e}` + } - if interface: interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) - rootArtist = { - 'id': artistAPI['id'], - 'name': artistAPI['name'] + const rootArtist = { + id: artistAPI.id, + name: artistAPI.name + } + if (listener) { listener.send("startAddingArtist", rootArtist) } + + const artistDiscographyAPI = await dz.gw.get_artist_discography_tabs(id, 100) + const allReleases = artistDiscographyAPI.pop('all', []) + let albumList = [] + allReleases.forEach(async (album) => { + try{ + let albumData = await generateAlbumItem(dz, album.id, bitrate, rootArtist) + albumList.append(albumData) + }catch (e){ + console.error(e) + console.error(album.id, "No Data") } + }) - artistDiscographyAPI = dz.gw.get_artist_discography_tabs(id, 100) - allReleases = artistDiscographyAPI.pop('all', []) - albumList = [] - for album in allReleases: - albumList.append(generateAlbumItem(dz, album['id'], bitrate, rootArtist=rootArtist)) + if (listener) { listener.send("finishAddingArtist", rootArtist) } + return albumList +} - if interface: interface.send("finishAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) - return albumList +async function generateArtistDiscographyItem(dz, id, bitrate, listener){ + // Get essential artist info + let artistAPI + try{ + artistAPI = await dz.api.get_artist(id) + }catch (e){ + console.error(e) + throw "https://deezer.com/artist/"+id+"/discography", `Wrong URL: ${e}` + } -async function generateArtistDiscographyItem(dz, id, bitrate, interface=None): - // Get essential artist info - try: - artistAPI = dz.api.get_artist(id) - except APIError as e: - e = str(e) - raise GenerationError("https://deezer.com/artist/"+str(id)+"/discography", f"Wrong URL: {e}") + const rootArtist = { + id: artistAPI.id, + name: artistAPI.name + } + if (listener) { listener.send("startAddingArtist", rootArtist) } - if interface: interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) - rootArtist = { - 'id': artistAPI['id'], - 'name': artistAPI['name'] - } + let artistDiscographyAPI = dz.gw.get_artist_discography_tabs(id, 100) + artistDiscographyAPI.pop('all', None) + let albumList = [] + artistDiscographyAPI.forEach((type) => { + type.forEach(async (album) => { + try{ + let albumData = await generateAlbumItem(dz, album.id, bitrate, rootArtist) + albumList.append(albumData) + }catch (e){ + console.error(e) + console.error(album.id, "No Data") + } + }); + }); - artistDiscographyAPI = dz.gw.get_artist_discography_tabs(id, 100) - artistDiscographyAPI.pop('all', None) // all contains albums and singles, so its all duplicates. This removes them - albumList = [] - for type in artistDiscographyAPI: - for album in artistDiscographyAPI[type]: - albumList.append(generateAlbumItem(dz, album['id'], bitrate, rootArtist=rootArtist)) + if (listener) { listener.send("finishAddingArtist", rootArtist) } - if interface: interface.send("finishAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) - return albumList + return albumList +} -async function generateArtistTopItem(dz, id, bitrate, interface=None): - // Get essential artist info - try: - artistAPI = dz.api.get_artist(id) - except APIError as e: - e = str(e) - raise GenerationError("https://deezer.com/artist/"+str(id)+"/top_track", f"Wrong URL: {e}") +async function generateArtistTopItem(dz, id, bitrate){ + // Get essential artist info + let artistAPI + try{ + artistAPI = dz.api.get_artist(id) + }catch (e){ + console.error(e) + throw "https://deezer.com/artist/"+id+"/top_track", `Wrong URL: ${e}` + } - // Emulate the creation of a playlist - // Can't use generatePlaylistItem directly as this is not a real playlist - playlistAPI = { - 'id': str(artistAPI['id'])+"_top_track", - 'title': artistAPI['name']+" - Top Tracks", - 'description': "Top Tracks for "+artistAPI['name'], - 'duration': 0, - 'public': True, - 'is_loved_track': False, - 'collaborative': False, - 'nb_tracks': 0, - 'fans': artistAPI['nb_fan'], - 'link': "https://www.deezer.com/artist/"+str(artistAPI['id'])+"/top_track", - 'share': None, - 'picture': artistAPI['picture'], - 'picture_small': artistAPI['picture_small'], - 'picture_medium': artistAPI['picture_medium'], - 'picture_big': artistAPI['picture_big'], - 'picture_xl': artistAPI['picture_xl'], - 'checksum': None, - 'tracklist': "https://api.deezer.com/artist/"+str(artistAPI['id'])+"/top", - 'creation_date': "XXXX-00-00", - 'creator': { - 'id': "art_"+str(artistAPI['id']), - 'name': artistAPI['name'], - 'type': "user" - }, - 'type': "playlist" - } + // Emulate the creation of a playlist + // Can't use generatePlaylistItem directly as this is not a real playlist + const playlistAPI = { + id: artistAPI['id']+"_top_track", + title: artistAPI['name']+" - Top Tracks", + description: "Top Tracks for "+artistAPI['name'], + duration: 0, + public: True, + is_loved_track: False, + collaborative: False, + nb_tracks: 0, + fans: artistAPI['nb_fan'], + link: "https://www.deezer.com/artist/"+artistAPI['id']+"/top_track", + share: None, + picture: artistAPI['picture'], + picture_small: artistAPI['picture_small'], + picture_medium: artistAPI['picture_medium'], + picture_big: artistAPI['picture_big'], + picture_xl: artistAPI['picture_xl'], + checksum: None, + tracklist: "https://api.deezer.com/artist/"+artistAPI['id']+"/top", + creation_date: "XXXX-00-00", + creator: { + id: "art_"+artistAPI['id'], + name: artistAPI['name'], + type: "user" + }, + type: "playlist" + } - artistTopTracksAPI_gw = dz.gw.get_artist_toptracks(id) - return generatePlaylistItem(dz, playlistAPI['id'], bitrate, playlistAPI=playlistAPI, playlistTracksAPI=artistTopTracksAPI_gw) + let artistTopTracksAPI_gw = await dz.gw.get_artist_toptracks(id) + return generatePlaylistItem(dz, playlistAPI.id, bitrate, playlistAPI, artistTopTracksAPI_gw) +} + +module.exports = { + generateTrackItem, + generateAlbumItem, + generatePlaylistItem, + generateArtistItem, + generateArtistDiscographyItem, + generateArtistTopItem +} diff --git a/deemix/types/DownloadObjects.js b/deemix/types/DownloadObjects.js index c748d64..6999fdb 100644 --- a/deemix/types/DownloadObjects.js +++ b/deemix/types/DownloadObjects.js @@ -61,16 +61,16 @@ class IDownloadObject{ return light } - updateProgress(interface){ + updateProgress(listener){ if (Math.round(this.progressNext) != this.progress && Math.round(this.progressNext) % 2 == 0){ this.progress = Math.round(this.progressNext) - if (interface) interface.emit('updateQueue', {uuid: this.uuid, progress: this.progress}) + if (listener) listener.emit('updateQueue', {uuid: this.uuid, progress: this.progress}) } } } -class Single(IDownloadObject){ +class Single extends IDownloadObject{ constructor(obj){ super(obj) this.size = 1 @@ -79,23 +79,23 @@ class Single(IDownloadObject){ } toDict(){ - item = super().toDict() + item = super.toDict() item.single = this.single return item } - completeTrackProgress(interface){ + completeTrackProgress(listener){ this.progressNext = 100 - this.updateProgress(interface) + this.updateProgress(listener) } - removeTrackProgress(interface){ + removeTrackProgress(listener){ this.progressNext = 0 - this.updateProgress(interface) + this.updateProgress(listener) } } -class Collection(IDownloadObject){ +class Collection extends IDownloadObject{ constructor(obj){ super(obj) this.collection = obj.collection @@ -103,23 +103,23 @@ class Collection(IDownloadObject){ } toDict(){ - item = super().toDict() + item = super.toDict() item.collection = this.collection return item } - completeTrackProgress(interface){ + completeTrackProgress(listener){ this.progressNext += (1 / this.size) * 100 - this.updateProgress(interface) + this.updateProgress(listener) } - removeTrackProgress(interface){ + removeTrackProgress(listener){ this.progressNext -= (1 / this.size) * 100 - this.updateProgress(interface) + this.updateProgress(listener) } } -class Convertable(Collection){ +class Convertable extends Collection{ constructor(obj){ super(obj) this.plugin = obj.plugin @@ -128,7 +128,7 @@ class Convertable(Collection){ } toDict(){ - item = super().toDict() + item = super.toDict() item.plugin = this.plugin item.conversion_data = this.conversion_data } diff --git a/deemix/types/Picture.js b/deemix/types/Picture.js index 6a3ab13..c3d11dd 100644 --- a/deemix/types/Picture.js +++ b/deemix/types/Picture.js @@ -8,10 +8,10 @@ class Picture { getURL(size, format) { if (this.staticUrl) return this.staticUrl - let url: string = `https://e-cdns-images.dzcdn.net/images/${this.type}/${this.md5}/${str(size)}x${str(size)}` + let url = `https://e-cdns-images.dzcdn.net/images/${this.type}/${this.md5}/${str(size)}x${str(size)}` if (format.startsWith('jpg')){ - let quality: number = 80 + let quality = 80 if (format.indexOf('-') != -1) quality = int(format.substr(4)) format = 'jpg' return url+`-000000-${str(quality)}-0-0.jpg` diff --git a/deemix/types/Track.js b/deemix/types/Track.js index 0a9b19f..e7d0c17 100644 --- a/deemix/types/Track.js +++ b/deemix/types/Track.js @@ -1,6 +1,6 @@ const got = require('got') -class Track(){ +class Track { constructor(){ this.id = "0", this.title = "", @@ -104,7 +104,7 @@ class Track(){ this.parseTrackGW(trackAPI_gw) // Get Lyrics Data - if (!trackAPI_gw.LYRICS and this.lyrics.id != "0"){ + if (!trackAPI_gw.LYRICS && this.lyrics.id != "0"){ try { trackAPI_gw.LYRICS = await dz.gw.get_track_lyrics(this.id) } catch { this.lyrics.id = "0" } } diff --git a/deemix/types/index.js b/deemix/types/index.js index 3376bfa..2fd8dd5 100644 --- a/deemix/types/index.js +++ b/deemix/types/index.js @@ -1 +1,5 @@ const VARIOUS_ARTISTS = "5080" + +module.exports = { + VARIOUS_ARTISTS +} diff --git a/package-lock.json b/package-lock.json index 3060170..d059db3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "GPL-3.0-or-later", "dependencies": { - "deezer-js": "^0.0.2", + "deezer-js": "^0.0.3", "got": "^11.8.2" } }, @@ -60,9 +60,9 @@ } }, "node_modules/@types/node": { - "version": "14.14.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.34.tgz", - "integrity": "sha512-dBPaxocOK6UVyvhbnpFIj2W+S+1cBTkHQbFQfeeJhoKFbzYcVUGHvddeWPSucKATb3F0+pgDq0i6ghEaZjsugA==" + "version": "14.14.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==" }, "node_modules/@types/responselike": { "version": "1.0.0", @@ -131,9 +131,9 @@ } }, "node_modules/deezer-js": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/deezer-js/-/deezer-js-0.0.2.tgz", - "integrity": "sha512-v78DXcqeeui6wWEKd+6vVDITT76ck3pp8p+fSUZrvX3P8N6fQXGFzHqjgHaGm2rJpEnG5Ad8a8KTesDKZ56A6Q==", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/deezer-js/-/deezer-js-0.0.3.tgz", + "integrity": "sha512-Nr3ZKZb4NN0onOcFEpUYvSx01Ka7CgJEGgdHcqD9Mlk+KRtMcrWIcmKwheLtHEyZq/W+KTZW3sNG6wPTeWdj+w==", "dependencies": { "got": "^11.8.2", "tough-cookie": "^4.0.0" @@ -375,9 +375,9 @@ } }, "@types/node": { - "version": "14.14.34", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.34.tgz", - "integrity": "sha512-dBPaxocOK6UVyvhbnpFIj2W+S+1cBTkHQbFQfeeJhoKFbzYcVUGHvddeWPSucKATb3F0+pgDq0i6ghEaZjsugA==" + "version": "14.14.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==" }, "@types/responselike": { "version": "1.0.0", @@ -430,9 +430,9 @@ } }, "deezer-js": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/deezer-js/-/deezer-js-0.0.2.tgz", - "integrity": "sha512-v78DXcqeeui6wWEKd+6vVDITT76ck3pp8p+fSUZrvX3P8N6fQXGFzHqjgHaGm2rJpEnG5Ad8a8KTesDKZ56A6Q==", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/deezer-js/-/deezer-js-0.0.3.tgz", + "integrity": "sha512-Nr3ZKZb4NN0onOcFEpUYvSx01Ka7CgJEGgdHcqD9Mlk+KRtMcrWIcmKwheLtHEyZq/W+KTZW3sNG6wPTeWdj+w==", "requires": { "got": "^11.8.2", "tough-cookie": "^4.0.0" diff --git a/package.json b/package.json index 38078b9..6a8b903 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "author": "RemixDev", "license": "GPL-3.0-or-later", "dependencies": { - "deezer-js": "^0.0.2", + "deezer-js": "^0.0.3", "got": "^11.8.2" } }