deemix-js/deemix/itemgen.js

307 lines
9.1 KiB
JavaScript
Raw Normal View History

2021-04-08 15:39:33 +00:00
const {
Single,
Collection
2021-04-08 15:39:33 +00:00
} = require('./types/DownloadObjects.js')
2021-08-02 19:33:58 +00:00
const { GenerationError, ISRCnotOnDeezer, InvalidID, NotYourPrivatePlaylist } = require('./errors.js');
const { map_user_playlist, map_track, map_album } = require('deezer-js').utils
2021-05-13 17:20:03 +00:00
const { each } = require('async')
2021-04-08 15:39:33 +00:00
2021-04-01 11:38:59 +00:00
async function generateTrackItem(dz, id, bitrate, trackAPI, albumAPI){
// Get essential track info
if (!trackAPI){
if (String(id).startsWith("isrc") || parseInt(id) > 0){
try {
trackAPI = await dz.api.get_track(id)
} catch (e){
console.trace(e)
throw new GenerationError(`https://deezer.com/track/${id}`, e.message)
}
// Check if is an isrc: url
if (String(id).startsWith("isrc")){
if (trackAPI.id && trackAPI.title) id = trackAPI.id
else throw new ISRCnotOnDeezer(`https://deezer.com/track/${id}`)
}
2021-04-01 11:38:59 +00:00
} else {
let trackAPI_gw = await dz.gw.get_track(id)
trackAPI = map_track(trackAPI_gw)
2021-04-01 11:38:59 +00:00
}
} else {
id = trackAPI.id
2021-04-01 11:38:59 +00:00
}
2021-07-27 20:27:07 +00:00
if (!(/^-?\d+$/.test(id))) throw new InvalidID(`https://deezer.com/track/${id}`)
2021-04-01 11:38:59 +00:00
let cover
if (trackAPI.album.cover_small){
cover = trackAPI.album.cover_small.slice(0, -24) + '/75x75-000000-80-0-0.jpg'
}else{
cover = `https://e-cdns-images.dzcdn.net/images/cover/${trackAPI.md5_image}/75x75-000000-80-0-0.jpg`
2021-04-01 11:38:59 +00:00
}
delete trackAPI.track_token
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: trackAPI.title,
artist: trackAPI.artist.name,
cover: cover,
explicit: trackAPI.explicit_lyrics,
2021-04-01 11:38:59 +00:00
single: {
trackAPI: trackAPI,
albumAPI: albumAPI
}
})
}
async function generateAlbumItem(dz, id, bitrate, rootArtist){
// Get essential album info
let albumAPI
2021-06-08 09:16:49 +00:00
if (String(id).startsWith('upc')){
let upcs = [id.slice(4)]
upcs.push(parseInt(upcs[0])) // Try UPC without leading zeros as well
let lastError
await each(upcs, async (upc)=>{
try {
albumAPI = await dz.api.get_album(`upc:${upc}`)
} catch (e) {
lastError = e
albumAPI = null
}
})
if (!albumAPI){
console.trace(lastError)
throw new GenerationError(`https://deezer.com/album/${id}`, lastError.message)
}
id = albumAPI.id
} else {
try{
2021-12-22 12:01:07 +00:00
let albumAPI_gw_page = await dz.gw.get_album_page(id)
if (albumAPI_gw_page.DATA){
albumAPI = map_album(albumAPI_gw_page.DATA)
2021-12-22 12:01:07 +00:00
id = albumAPI_gw_page.DATA.ALB_ID
let albumAPI_new = await dz.api.get_album(id)
albumAPI = {...albumAPI, ...albumAPI_new}
2021-12-22 12:01:07 +00:00
} else {
throw new GenerationError(`https://deezer.com/album/${id}`, "Can't find the album")
}
2021-06-08 09:16:49 +00:00
} catch (e){
console.trace(e)
throw new GenerationError(`https://deezer.com/album/${id}`, e.message)
}
2021-04-01 11:38:59 +00:00
}
2021-06-05 16:26:19 +00:00
if (!(/^\d+$/.test(id))) throw new InvalidID(`https://deezer.com/album/${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)
albumAPI_gw = map_album(albumAPI_gw)
albumAPI = {...albumAPI_gw, ...albumAPI}
2021-04-01 11:38:59 +00:00
albumAPI.root_artist = rootArtist
// If the album is a single download as a track
if (albumAPI.nb_tracks == 1){
2021-06-07 18:14:41 +00:00
if (albumAPI.tracks.data.length)
return generateTrackItem(dz, albumAPI.tracks.data[0].id, bitrate, null, albumAPI)
2021-06-07 18:14:41 +00:00
throw new GenerationError(`https://deezer.com/album/${id}`, "Single has no tracks.")
2021-04-01 11:38:59 +00:00
}
let tracksArray = await dz.gw.get_album_tracks(id)
2021-04-01 11:38:59 +00:00
let cover
2021-04-01 11:38:59 +00:00
if (albumAPI.cover_small){
2021-04-21 17:00:51 +00:00
cover = albumAPI.cover_small.slice(0, -24) + '/75x75-000000-80-0-0.jpg'
2021-04-01 11:38:59 +00:00
}else{
cover = `https://e-cdns-images.dzcdn.net/images/cover/${albumAPI.md5_image}/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 = map_track(trackAPI)
delete trackAPI.track_token
trackAPI.position = pos+1
2021-04-01 11:38:59 +00:00
collection.push(trackAPI)
})
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,
2021-12-23 18:02:14 +00:00
explicit: albumAPI.explicit_lyrics,
2021-04-01 11:38:59 +00:00
size: totalSize,
collection: {
tracks: collection,
2021-04-01 11:38:59 +00:00
albumAPI: albumAPI
}
})
}
async function generatePlaylistItem(dz, id, bitrate, playlistAPI, playlistTracksAPI){
if (!playlistAPI){
2021-06-05 16:26:19 +00:00
if (!(/^\d+$/.test(id))) throw new InvalidID(`https://deezer.com/playlist/${id}`)
2021-04-01 11:38:59 +00:00
// Get essential playlist info
try{
2021-04-08 15:39:33 +00:00
playlistAPI = await dz.api.get_playlist(id)
}catch (e){
2021-06-05 16:20:22 +00:00
console.trace(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){
2021-06-05 16:20:22 +00:00
console.trace(e)
throw new GenerationError(`https://deezer.com/playlist/${id}`, e.message)
2021-04-01 11:38:59 +00:00
}
}
// Check if private playlist and owner
if (!playlistAPI.public && playlistAPI.creator.id != dz.current_user.id){
2021-06-05 16:20:22 +00:00
throw new NotYourPrivatePlaylist(`https://deezer.com/playlist/${id}`)
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) => {
trackAPI = map_track(trackAPI)
if (trackAPI.explicit_lyrics)
2021-05-19 21:03:47 +00:00
playlistAPI.explicit = true
delete trackAPI.track_token
trackAPI.position = pos+1
2021-04-01 11:38:59 +00:00
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,
2021-04-27 20:24:57 +00:00
cover: playlistAPI.picture_small.slice(0, -24) + '/75x75-000000-80-0-0.jpg',
2021-04-01 11:38:59 +00:00
explicit: playlistAPI.explicit,
size: totalSize,
collection: {
tracks: collection,
2021-04-01 11:38:59 +00:00
playlistAPI: playlistAPI
}
})
}
async function generateArtistItem(dz, id, bitrate, listener, tab = "all"){
let path = ""
if (tab != "all") path = '/'+tab
2021-04-08 15:39:33 +00:00
if (!(/^\d+$/.test(id))) throw new InvalidID(`https://deezer.com/artist/${id}${path}`)
2021-04-08 15:39:33 +00:00
// Get essential artist info
let artistAPI
try{
artistAPI = await dz.api.get_artist(id)
}catch (e){
2021-06-05 16:20:22 +00:00
console.trace(e)
throw new GenerationError(`https://deezer.com/artist/${id}${path}`, e.message)
2021-04-08 15:39:33 +00:00
}
const rootArtist = {
id: artistAPI.id,
2021-05-13 17:20:03 +00:00
name: artistAPI.name,
picture_small: artistAPI.picture_small
2021-04-08 15:39:33 +00:00
}
if (listener) { listener.send("startAddingArtist", rootArtist) }
let artistDiscographyAPI = await dz.gw.get_artist_discography_tabs(id, 100)
2021-04-08 15:39:33 +00:00
let albumList = []
if (tab === "discography"){
delete artistDiscographyAPI.all
await each(artistDiscographyAPI, async(type) => {
await each(type, async (album) =>{
try{
let albumData = await generateAlbumItem(dz, album.id, bitrate, rootArtist)
albumList.push(albumData)
}catch (e){
console.warn(album.id, "No Data", e)
}
});
});
} else {
const tabReleases = artistDiscographyAPI[tab] || []
await each(tabReleases, async (album) =>{
2021-04-08 15:39:33 +00:00
try{
let albumData = await generateAlbumItem(dz, album.id, bitrate, rootArtist)
2021-05-13 16:11:56 +00:00
albumList.push(albumData)
2021-04-08 15:39:33 +00:00
}catch (e){
console.warn(album.id, "No Data", e)
2021-04-08 15:39:33 +00:00
}
})
}
2021-04-08 15:39:33 +00:00
if (listener) { listener.send("finishAddingArtist", rootArtist) }
return albumList
}
async function generateArtistTopItem(dz, id, bitrate){
2021-06-05 16:26:19 +00:00
if (!(/^\d+$/.test(id))) throw new InvalidID(`https://deezer.com/artist/${id}/top_track`)
2021-04-08 15:39:33 +00:00
// Get essential artist info
let artistAPI
try{
artistAPI = await dz.api.get_artist(id)
2021-04-08 15:39:33 +00:00
}catch (e){
2021-06-05 16:20:22 +00:00
console.trace(e)
throw new GenerationError(`https://deezer.com/artist/${id}/top_track`, e.message)
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 = {
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,
public: true,
is_loved_track: false,
collaborative: false,
2021-04-08 15:39:33 +00:00
nb_tracks: 0,
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: {
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_top_tracks(id)
2021-04-08 15:39:33 +00:00
return generatePlaylistItem(dz, playlistAPI.id, bitrate, playlistAPI, artistTopTracksAPI_gw)
}
module.exports = {
generateTrackItem,
generateAlbumItem,
generatePlaylistItem,
generateArtistItem,
2021-08-02 19:33:58 +00:00
generateArtistTopItem
2021-04-08 15:39:33 +00:00
}