2021-04-08 15:39:33 +00:00
|
|
|
const {
|
|
|
|
Single,
|
2021-04-09 16:45:57 +00:00
|
|
|
Collection
|
2021-04-08 15:39:33 +00:00
|
|
|
} = require('./types/DownloadObjects.js')
|
2021-04-09 16:45:57 +00:00
|
|
|
const { LyricsStatus } = require('deezer-js').gw
|
|
|
|
const { map_user_playlist } = require('deezer-js').utils
|
2021-04-08 15:39:33 +00:00
|
|
|
|
2021-04-01 11:38:59 +00:00
|
|
|
async function generateTrackItem(dz, id, bitrate, trackAPI, albumAPI){
|
|
|
|
// Check if is an isrc: url
|
2021-04-08 15:39:33 +00:00
|
|
|
if (id.startsWith("isrc")){
|
2021-04-01 11:38:59 +00:00
|
|
|
try {
|
|
|
|
trackAPI = await dz.api.get_track(id)
|
2021-04-08 15:39:33 +00:00
|
|
|
} catch (e){
|
|
|
|
console.error(e)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (trackAPI.id && trackAPI.title){
|
|
|
|
id = trackAPI.id
|
|
|
|
} else {
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new ISRCnotOnDeezer()
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get essential track info
|
2021-04-09 16:45:57 +00:00
|
|
|
let trackAPI_gw
|
2021-04-01 11:38:59 +00:00
|
|
|
try {
|
|
|
|
trackAPI_gw = await dz.gw.get_track_with_fallback(id)
|
2021-04-08 15:39:33 +00:00
|
|
|
} catch (e){
|
|
|
|
console.error(e)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let title = trackAPI_gw.SNG_TITLE.trim()
|
|
|
|
if (trackAPI_gw.VERSION && title.indexOf(trackAPI_gw.VERSION.trim()) == -1){
|
|
|
|
title += ` ${trackAPI_gw.VERSION.trim()}`
|
|
|
|
}
|
2021-04-08 15:39:33 +00:00
|
|
|
const explicit = Boolean(parseInt(trackAPI_gw.EXPLICIT_LYRICS || "0"))
|
2021-04-01 11:38:59 +00:00
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
return new Single({
|
2021-04-01 11:38:59 +00:00
|
|
|
type: 'track',
|
|
|
|
id: id,
|
|
|
|
bitrate: bitrate,
|
|
|
|
title: title,
|
|
|
|
artist: trackAPI_gw.ART_NAME,
|
|
|
|
cover: `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
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async function generateAlbumItem(dz, id, bitrate, rootArtist){
|
|
|
|
// Get essential album info
|
|
|
|
let albumAPI
|
|
|
|
try{
|
2021-04-08 15:39:33 +00:00
|
|
|
albumAPI = await dz.api.get_album(id)
|
|
|
|
} catch (e){
|
|
|
|
console.error(e)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
if (id.startswith('upc')) { id = albumAPI['id'] }
|
2021-04-01 11:38:59 +00:00
|
|
|
|
|
|
|
// Get extra info about album
|
|
|
|
// This saves extra api calls when downloading
|
2021-04-08 15:39:33 +00:00
|
|
|
let albumAPI_gw = await dz.gw.get_album(id)
|
2021-04-01 11:38:59 +00:00
|
|
|
albumAPI.nb_disk = albumAPI_gw.NUMBER_DISK
|
|
|
|
albumAPI.copyright = albumAPI_gw.COPYRIGHT
|
|
|
|
albumAPI.root_artist = rootArtist
|
|
|
|
|
|
|
|
// If the album is a single download as a track
|
|
|
|
if (albumAPI.nb_tracks == 1){
|
|
|
|
return generateTrackItem(dz, albumAPI.tracks.data[0].id, bitrate, null, albumAPI)
|
|
|
|
}
|
|
|
|
|
2021-04-09 16:45:57 +00:00
|
|
|
let tracksArray = await dz.gw.get_album_tracks(id)
|
2021-04-01 11:38:59 +00:00
|
|
|
|
2021-04-09 16:45:57 +00:00
|
|
|
let cover
|
2021-04-01 11:38:59 +00:00
|
|
|
if (albumAPI.cover_small){
|
2021-04-09 16:45:57 +00:00
|
|
|
cover = albumAPI.cover_small.substring(0, albumAPI.cover_small.length-24) + '/75x75-000000-80-0-0.jpg'
|
2021-04-01 11:38:59 +00:00
|
|
|
}else{
|
2021-04-09 16:45:57 +00:00
|
|
|
cover = `https://e-cdns-images.dzcdn.net/images/cover/${albumAPI_gw.ALB_PICTURE}/75x75-000000-80-0-0.jpg`
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const totalSize = tracksArray.length
|
|
|
|
albumAPI.nb_tracks = totalSize
|
|
|
|
let collection = []
|
|
|
|
tracksArray.forEach((trackAPI, pos) => {
|
|
|
|
trackAPI.POSITION = pos+1
|
|
|
|
trackAPI.SIZE = totalSize
|
|
|
|
collection.push(trackAPI)
|
|
|
|
})
|
|
|
|
|
2021-04-09 16:45:57 +00:00
|
|
|
let explicit = [LyricsStatus.EXPLICIT, LyricsStatus.PARTIALLY_EXPLICIT].includes(albumAPI_gw.EXPLICIT_ALBUM_CONTENT.EXPLICIT_LYRICS_STATUS || LyricsStatus.UNKNOWN)
|
2021-04-01 11:38:59 +00:00
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
return new Collection({
|
2021-04-01 11:38:59 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async function generatePlaylistItem(dz, id, bitrate, playlistAPI, playlistTracksAPI){
|
|
|
|
if (!playlistAPI){
|
|
|
|
// Get essential playlist info
|
|
|
|
try{
|
2021-04-08 15:39:33 +00:00
|
|
|
playlistAPI = await dz.api.get_playlist(id)
|
|
|
|
}catch (e){
|
|
|
|
console.error(e)
|
2021-04-01 11:38:59 +00:00
|
|
|
playlistAPI = null
|
|
|
|
}
|
|
|
|
// Fallback to gw api if the playlist is private
|
|
|
|
if (!playlistAPI){
|
|
|
|
try{
|
2021-04-08 15:39:33 +00:00
|
|
|
let userPlaylist = await dz.gw.get_playlist_page(id)
|
2021-04-01 11:38:59 +00:00
|
|
|
playlistAPI = map_user_playlist(userPlaylist['DATA'])
|
2021-04-08 15:39:33 +00:00
|
|
|
}catch (e){
|
|
|
|
console.error(e)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Check if private playlist and owner
|
2021-04-09 16:45:57 +00:00
|
|
|
if (!playlistAPI.public && playlistAPI.creator.id != dz.current_user.id){
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new NotYourPrivatePlaylist()
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!playlistTracksAPI){
|
2021-04-08 15:39:33 +00:00
|
|
|
playlistTracksAPI = await dz.gw.get_playlist_tracks(id)
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
2021-04-08 15:39:33 +00:00
|
|
|
playlistAPI.various_artist = await dz.api.get_artist(5080) // Useful for save as compilation
|
2021-04-01 11:38:59 +00:00
|
|
|
|
|
|
|
const totalSize = playlistTracksAPI.length
|
|
|
|
playlistAPI.nb_tracks = totalSize
|
|
|
|
let collection = []
|
|
|
|
playlistTracksAPI.forEach((trackAPI, pos) => {
|
|
|
|
//TODO: Add explicit check
|
|
|
|
trackAPI.POSITION = pos+1
|
|
|
|
trackAPI.SIZE = totalSize
|
|
|
|
collection.push(trackAPI)
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!playlistAPI.explicit) playlistAPI.explicit = false
|
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
return new Collection({
|
2021-04-01 11:38:59 +00:00
|
|
|
type: 'playlist',
|
|
|
|
id: id,
|
|
|
|
bitrate: bitrate,
|
|
|
|
title: playlistAPI.title,
|
|
|
|
artist: playlistAPI.creator.name,
|
|
|
|
cover: playlistAPI.cover_small.substring(0, playlistAPI.cover_small.length-24) + '/75x75-000000-80-0-0.jpg',
|
|
|
|
explicit: playlistAPI.explicit,
|
|
|
|
size: totalSize,
|
|
|
|
collection: {
|
|
|
|
tracks_gw: collection,
|
|
|
|
playlistAPI: playlistAPI
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
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)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-08 15:39:33 +00:00
|
|
|
}
|
2021-04-01 11:38:59 +00:00
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
const rootArtist = {
|
|
|
|
id: artistAPI.id,
|
|
|
|
name: artistAPI.name
|
|
|
|
}
|
|
|
|
if (listener) { listener.send("startAddingArtist", rootArtist) }
|
2021-04-01 11:38:59 +00:00
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
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){
|
2021-04-08 17:37:31 +00:00
|
|
|
console.warn(album.id, "No Data", e)
|
2021-04-01 11:38:59 +00:00
|
|
|
}
|
2021-04-08 15:39:33 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
if (listener) { listener.send("finishAddingArtist", rootArtist) }
|
|
|
|
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)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-08 15:39:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const rootArtist = {
|
|
|
|
id: artistAPI.id,
|
|
|
|
name: artistAPI.name
|
|
|
|
}
|
|
|
|
if (listener) { listener.send("startAddingArtist", rootArtist) }
|
2021-04-01 11:38:59 +00:00
|
|
|
|
2021-04-09 16:45:57 +00:00
|
|
|
let artistDiscographyAPI = await dz.gw.get_artist_discography_tabs(id, 100)
|
|
|
|
artistDiscographyAPI.pop('all', null)
|
2021-04-08 15:39:33 +00:00
|
|
|
let albumList = []
|
|
|
|
artistDiscographyAPI.forEach((type) => {
|
|
|
|
type.forEach(async (album) => {
|
|
|
|
try{
|
|
|
|
let albumData = await generateAlbumItem(dz, album.id, bitrate, rootArtist)
|
|
|
|
albumList.append(albumData)
|
|
|
|
}catch (e){
|
2021-04-08 17:37:31 +00:00
|
|
|
console.warn(album.id, "No Data", e)
|
2021-04-08 15:39:33 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
if (listener) { listener.send("finishAddingArtist", rootArtist) }
|
|
|
|
|
|
|
|
return albumList
|
|
|
|
}
|
|
|
|
|
|
|
|
async function generateArtistTopItem(dz, id, bitrate){
|
|
|
|
// Get essential artist info
|
|
|
|
let artistAPI
|
|
|
|
try{
|
|
|
|
artistAPI = dz.api.get_artist(id)
|
|
|
|
}catch (e){
|
|
|
|
console.error(e)
|
2021-04-08 17:37:31 +00:00
|
|
|
throw new GenerationError(e)
|
2021-04-08 15:39:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Emulate the creation of a playlist
|
|
|
|
// Can't use generatePlaylistItem directly as this is not a real playlist
|
|
|
|
const playlistAPI = {
|
2021-04-08 17:37:31 +00:00
|
|
|
id: artistAPI.id+"_top_track",
|
|
|
|
title: artistAPI.name+" - Top Tracks",
|
|
|
|
description: "Top Tracks for "+artistAPI.name,
|
2021-04-08 15:39:33 +00:00
|
|
|
duration: 0,
|
2021-04-08 17:37:31 +00:00
|
|
|
public: true,
|
|
|
|
is_loved_track: false,
|
|
|
|
collaborative: false,
|
2021-04-08 15:39:33 +00:00
|
|
|
nb_tracks: 0,
|
2021-04-08 17:37:31 +00:00
|
|
|
fans: artistAPI.nb_fan,
|
|
|
|
link: "https://www.deezer.com/artist/"+artistAPI.id+"/top_track",
|
|
|
|
share: null,
|
|
|
|
picture: artistAPI.picture,
|
|
|
|
picture_small: artistAPI.picture_small,
|
|
|
|
picture_medium: artistAPI.picture_medium,
|
|
|
|
picture_big: artistAPI.picture_big,
|
|
|
|
picture_xl: artistAPI.picture_xl,
|
|
|
|
checksum: null,
|
|
|
|
tracklist: "https://api.deezer.com/artist/"+artistAPI.id+"/top",
|
2021-04-08 15:39:33 +00:00
|
|
|
creation_date: "XXXX-00-00",
|
|
|
|
creator: {
|
2021-04-08 17:37:31 +00:00
|
|
|
id: "art_"+artistAPI.id,
|
|
|
|
name: artistAPI.name,
|
2021-04-08 15:39:33 +00:00
|
|
|
type: "user"
|
|
|
|
},
|
|
|
|
type: "playlist"
|
|
|
|
}
|
|
|
|
|
|
|
|
let artistTopTracksAPI_gw = await dz.gw.get_artist_toptracks(id)
|
|
|
|
return generatePlaylistItem(dz, playlistAPI.id, bitrate, playlistAPI, artistTopTracksAPI_gw)
|
|
|
|
}
|
|
|
|
|
2021-04-08 17:37:31 +00:00
|
|
|
class GenerationError extends Error {
|
|
|
|
constructor(message) {
|
|
|
|
super(message);
|
|
|
|
this.name = "GenerationError";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ISRCnotOnDeezer extends GenerationError {
|
|
|
|
constructor(message) {
|
|
|
|
super(message);
|
|
|
|
this.name = "ISRCnotOnDeezer";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class NotYourPrivatePlaylist extends GenerationError {
|
|
|
|
constructor(message) {
|
|
|
|
super(message);
|
|
|
|
this.name = "NotYourPrivatePlaylist";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-08 15:39:33 +00:00
|
|
|
module.exports = {
|
|
|
|
generateTrackItem,
|
|
|
|
generateAlbumItem,
|
|
|
|
generatePlaylistItem,
|
|
|
|
generateArtistItem,
|
|
|
|
generateArtistDiscographyItem,
|
2021-04-08 17:37:31 +00:00
|
|
|
generateArtistTopItem,
|
2021-04-09 16:45:57 +00:00
|
|
|
|
2021-04-08 17:37:31 +00:00
|
|
|
GenerationError,
|
|
|
|
ISRCnotOnDeezer,
|
|
|
|
NotYourPrivatePlaylist
|
2021-04-08 15:39:33 +00:00
|
|
|
}
|