Finished porting itemgen.js

This commit is contained in:
RemixDev 2021-04-08 17:39:33 +02:00
parent f19f744153
commit 31a7344226
8 changed files with 196 additions and 144 deletions

View file

@ -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'),

View file

@ -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
}

View file

@ -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
}

View file

@ -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`

View file

@ -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" }
}

View file

@ -1 +1,5 @@
const VARIOUS_ARTISTS = "5080"
module.exports = {
VARIOUS_ARTISTS
}

26
package-lock.json generated
View file

@ -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"

View file

@ -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"
}
}