1.1.14 - importing and what not
This commit is contained in:
@ -10,7 +10,6 @@ const sanitize = require('sanitize-filename');
|
||||
const ID3Writer = require('browser-id3-writer');
|
||||
const Metaflac = require('metaflac-js2');
|
||||
const { Track, Lyrics, DeezerImage } = require('./definitions');
|
||||
const { throwDeprecation } = require('process');
|
||||
|
||||
let deezer;
|
||||
|
||||
@ -377,7 +376,7 @@ class DownloadThread {
|
||||
async tagTrack(path) {
|
||||
let cover;
|
||||
try {
|
||||
cover = await this.downloadCover(this.track.albumArt.hash, 'cover', this.settings.coverResolution);
|
||||
cover = await this.downloadCover(DeezerImage.url(this.track.albumArt.hash, 'cover', this.settings.coverResolution), 'cover', this.settings.coverResolution);
|
||||
} catch (e) {}
|
||||
|
||||
//Genre tag
|
||||
|
94
app/src/importer.js
Normal file
94
app/src/importer.js
Normal file
@ -0,0 +1,94 @@
|
||||
const {EventEmitter} = require('events');
|
||||
const axios = require('axios');
|
||||
const cheerio = require('cheerio');
|
||||
const logger = require('./winston');
|
||||
|
||||
class Importer extends EventEmitter {
|
||||
constructor(deezer) {
|
||||
super();
|
||||
this.deezer = deezer;
|
||||
this.tracks = [];
|
||||
}
|
||||
|
||||
//Conver spotify URL to URI
|
||||
async getSpotifyURI(inputUrl) {
|
||||
let url = new URL(inputUrl);
|
||||
return 'spotify' + url.pathname.replace(new RegExp('/', 'g'), ':');
|
||||
}
|
||||
|
||||
//Import spotify playlist
|
||||
async importSpotifyPlaylist(url) {
|
||||
//Clean
|
||||
this.tracks = [];
|
||||
try {
|
||||
//Fetch
|
||||
let uri = await this.getSpotifyURI(url);
|
||||
let spotifyData = await Spotify.getEmbedData(uri);
|
||||
if (!spotifyData.tracks.items) throw Error("No items!");
|
||||
|
||||
for (let track of spotifyData.tracks.items) {
|
||||
//Output track
|
||||
let out = new ImporterTrack(
|
||||
track.track.name,
|
||||
track.track.artists.map(a => a.name).join(', '),
|
||||
(track.track.album.images.length > 0) ? track.track.album.images[0].url : null
|
||||
);
|
||||
//Match
|
||||
try {
|
||||
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;
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(`Error importing: Spotify: ${track.track.id} ${e}`);
|
||||
}
|
||||
//Send back
|
||||
this.emit('imported', out);
|
||||
this.tracks.push(out);
|
||||
}
|
||||
//Emit done with playlist details
|
||||
this.emit('done', {
|
||||
title: spotifyData.name,
|
||||
description: spotifyData.description,
|
||||
tracks: this.tracks
|
||||
});
|
||||
} catch (e) {
|
||||
//Emit error on error
|
||||
logger.error(`Error importing: ${e}`);
|
||||
this.emit('error', `${e}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Track only with most important metadata for UI
|
||||
class ImporterTrack {
|
||||
constructor(title, artist, art) {
|
||||
this.id = null;
|
||||
this.title = title;
|
||||
this.artist = artist;
|
||||
this.art = art;
|
||||
this.ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
class Spotify {
|
||||
constructor() {}
|
||||
|
||||
//Fetch JSON data from embeded spotify
|
||||
static async getEmbedData(uri) {
|
||||
//Fetch
|
||||
let url = `https://embed.spotify.com/?uri=${uri}`;
|
||||
let res = await axios.get(url);
|
||||
const $ = cheerio.load(res.data);
|
||||
|
||||
//Get JSON
|
||||
let data = JSON.parse(decodeURIComponent($('#resource').html()));
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {Importer};
|
@ -6,7 +6,6 @@ const logger = require('./winston');
|
||||
class Integrations extends EventEmitter {
|
||||
|
||||
//LastFM, Discord etc
|
||||
|
||||
constructor(settings) {
|
||||
super();
|
||||
|
||||
@ -67,7 +66,7 @@ class Integrations extends EventEmitter {
|
||||
//Connect to discord client
|
||||
connectDiscord() {
|
||||
//Don't steal, k ty
|
||||
const CLIENTID = '759835951450292324';
|
||||
const CLIENTID = '803292927227854878';
|
||||
|
||||
this.discordReady = false;
|
||||
DiscordRPC.register(CLIENTID);
|
||||
|
@ -10,6 +10,7 @@ const {Settings} = require('./settings');
|
||||
const {Track, Album, Artist, Playlist, DeezerProfile, SearchResults, DeezerLibrary, DeezerPage, Lyrics} = require('./definitions');
|
||||
const {DownloadManager} = require('./downloads');
|
||||
const {Integrations} = require('./integrations');
|
||||
const {Importer} = require('./importer');
|
||||
|
||||
let settings;
|
||||
let deezer;
|
||||
@ -464,6 +465,69 @@ app.post('/log', async (req, res) => {
|
||||
res.status(200).end();
|
||||
});
|
||||
|
||||
//Importer
|
||||
app.post('/import', async (req, res) => {
|
||||
//Importer status
|
||||
sockets.forEach(s => s.emit('importerInit', {
|
||||
done: false,
|
||||
active: true,
|
||||
error: false,
|
||||
tracks: []
|
||||
}));
|
||||
let type = req.body.type;
|
||||
|
||||
//Create importer
|
||||
let importer = new Importer(deezer);
|
||||
//Error
|
||||
importer.on('error', t => {
|
||||
sockets.forEach(s => s.emit('importerError'));
|
||||
})
|
||||
//New track imported
|
||||
importer.on('imported', t => {
|
||||
sockets.forEach(s => s.emit('importerTrack', t));
|
||||
});
|
||||
//Finished
|
||||
importer.on('done', async (i) => {
|
||||
//Create playlist
|
||||
let playlistRaw = await deezer.callApi('playlist.create', {
|
||||
description: i.description,
|
||||
title: i.title,
|
||||
status: 1,
|
||||
songs: i.tracks.map(t => [parseInt(t.id, 10)])
|
||||
});
|
||||
//Download
|
||||
if (type == 'download') {
|
||||
//Fetch playlist
|
||||
let data = await deezer.callApi('deezer.pagePlaylist', {
|
||||
playlist_id: playlistRaw.results.toString(),
|
||||
lang: settings.contentLanguage,
|
||||
nb: 10000,
|
||||
start: 0,
|
||||
tags: true
|
||||
});
|
||||
let playlist = new Playlist(data.results.DATA, data.results.SONGS);
|
||||
//Enqueue
|
||||
await downloadManager.addBatch({
|
||||
tracks: playlist.tracks,
|
||||
quality: settings.downloadsQuality,
|
||||
playlistName: i.title
|
||||
});
|
||||
//Delete
|
||||
await deezer.callApi('playlist.delete', {playlist_id: parseInt(playlist.id.toString(),10)});
|
||||
downloadManager.start();
|
||||
}
|
||||
|
||||
//Send to UI
|
||||
sockets.forEach(s => {
|
||||
s.emit('importerDone');
|
||||
});
|
||||
})
|
||||
|
||||
importer.importSpotifyPlaylist(req.body.url);
|
||||
|
||||
res.status(200).end();
|
||||
});
|
||||
|
||||
//Last.FM authorization callback
|
||||
app.get('/lastfm', async (req, res) => {
|
||||
//Got token
|
||||
|
@ -43,6 +43,7 @@ class Settings {
|
||||
this.forceWhiteTrayIcon = false;
|
||||
this.contentLanguage = 'en';
|
||||
this.contentCountry = 'US';
|
||||
this.sidebarOpen = false;
|
||||
}
|
||||
|
||||
//Based on electorn app.getPath
|
||||
|
Reference in New Issue
Block a user