1.1.14 - importing and what not

This commit is contained in:
exttex
2021-01-25 21:00:06 +01:00
parent def6d5286d
commit b0ebe66d54
16 changed files with 500 additions and 51 deletions

View File

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

View File

@ -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);

View File

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

View File

@ -43,6 +43,7 @@ class Settings {
this.forceWhiteTrayIcon = false;
this.contentLanguage = 'en';
this.contentCountry = 'US';
this.sidebarOpen = false;
}
//Based on electorn app.getPath