#31 Rework spotify playlist importing for >100 tracks

Open
Zipdox wants to merge 1 commits from Zipdox/freezerpc:master into master
  1. +61
    -8
      app/src/importer.js
  2. +20
    -1
      app/src/server.js

+ 61
- 8
app/src/importer.js View File

@ -3,6 +3,12 @@ const axios = require('axios');
const cheerio = require('cheerio'); const cheerio = require('cheerio');
const logger = require('./winston'); const logger = require('./winston');
function asyncWait(delay){
return new Promise((resolve)=>{
setTimeout(resolve, delay);
});
}
class Importer extends EventEmitter { class Importer extends EventEmitter {
constructor(deezer) { constructor(deezer) {
super(); super();
@ -41,7 +47,7 @@ class Importer extends EventEmitter {
this.tracks = []; this.tracks = [];
try { try {
//Fetch //Fetch
let spotifyData = await Spotify.getEmbedData(uri);
let spotifyData = await Spotify.getPlaylist(uri);
if (!spotifyData.tracks.items) throw Error("No items!"); if (!spotifyData.tracks.items) throw Error("No items!");
for (let track of spotifyData.tracks.items) { for (let track of spotifyData.tracks.items) {
@ -52,15 +58,33 @@ class Importer extends EventEmitter {
(track.track.album.images.length > 0) ? track.track.album.images[0].url : null (track.track.album.images.length > 0) ? track.track.album.images[0].url : null
); );
//Match //Match
try {
let errorCount = 0;
while(true){
let deezerData = await this.deezer.callPublicApi('track', 'isrc:' + track.track.external_ids.isrc); let deezerData = await this.deezer.callPublicApi('track', 'isrc:' + track.track.external_ids.isrc);
if (deezerData.id.toString()) {
//Found track
out.id = deezerData.id.toString();
out.ok = true;
if(deezerData.error){
if(deezerData.error.message == 'Quota limit exceeded'){
await asyncWait(5000);
errorCount++;
if(errorCount >= 5){
logger.error(`Error importing: Spotify: ${track.track.id} ${deezerData.error.type}: ${deezerData.error.message}`);
break;
}
}else{
logger.error(`Error importing: Spotify: ${track.track.id} ${deezerData.error.type}: ${deezerData.error.message}`);
break;
}
}else{
try {
if (deezerData.id.toString()) {
//Found track
out.id = deezerData.id.toString();
out.ok = true;
}
} catch (e) {
logger.error(`Error importing: Spotify: ${track.track.id} ${e}`);
}
break;
} }
} catch (e) {
logger.error(`Error importing: Spotify: ${track.track.id} ${e}`);
} }
//Send back //Send back
this.emit('imported', out); this.emit('imported', out);
@ -96,6 +120,35 @@ class ImporterTrack {
class Spotify { class Spotify {
constructor() {} constructor() {}
static async getPlaylist(uri){
const playlistID = uri.split(':')[2];
const tokenRequest = await axios.get('https://open.spotify.com/get_access_token?reason=transport', {responseType: 'json'});
const token = tokenRequest.data.accessToken;
const playlistDataRequest = await axios.get(`https://api.spotify.com/v1/playlists/${playlistID}`, {
responseType: 'json',
headers: {
'authorization': 'Bearer ' + token
}
});
const playlistData = playlistDataRequest.data;
let next = playlistData.tracks.next
while(next){
const nextItemsRequest = await axios.get(next, {
responseType: 'json',
headers: {
'authorization': 'Bearer ' + token
}
});
next = nextItemsRequest.data.next;
playlistData.tracks.items.push(...nextItemsRequest.data.items);
}
return playlistData;
}
//Fetch JSON data from embeded spotify //Fetch JSON data from embeded spotify
static async getEmbedData(uri) { static async getEmbedData(uri) {
//Fetch //Fetch


+ 20
- 1
app/src/server.js View File

@ -550,8 +550,27 @@ app.post('/import', async (req, res) => {
description: i.description, description: i.description,
title: i.title, title: i.title,
status: 1, status: 1,
songs: i.tracks.map(t => [parseInt(t.id, 10)])
songs: []
}); });
let songIDs = i.tracks.map(t => [parseInt(t.id, 10), 0])
console.log('Adding', songIDs.length, 'to playlist', i.title);
while(songIDs.length > 1){
let songSelection = songIDs.splice(0, 10);
let resp = await deezer.callApi('playlist.addSongs', {
offset: -1,
playlist_id: playlistRaw.results,
songs: songSelection
});
if(resp.error.length > 0) logger.error(`Error adding to playlist: ${resp.error.type}: ${resp.error.message}`);
}
// let playlistRaw = await deezer.callApi('playlist.create', {
// description: i.description,
// title: i.title,
// status: 1,
// songs: i.tracks.map(t => [parseInt(t.id, 10), 0])
// });
//Download //Download
if (type == 'download') { if (type == 'download') {
//Fetch playlist //Fetch playlist


Loading…
Cancel
Save