From 731295a317bc336fd04645c0a8a1027e2848c5cc Mon Sep 17 00:00:00 2001 From: RemixDev Date: Sat, 29 May 2021 12:06:26 +0200 Subject: [PATCH] Implemented spotify plugin on server --- server/dist/main.js | 19 +++++--- server/dist/routes/api/get/getSettings.js | 2 +- server/dist/routes/api/get/getTracklist.js | 42 ++++++++++++++++++ .../routes/api/get/getUserSpotifyPlaylists.js | 39 ++++++++++++++++ server/dist/routes/api/get/index.js | 2 + .../routes/api/post/cancelAllDownloads.js | 18 ++++++++ server/dist/routes/api/post/index.js | 16 ++++++- server/dist/routes/api/post/login-arl.js | 2 +- .../routes/api/post/loginWithCredentials.js | 8 ++-- server/dist/routes/api/post/logout.js | 20 +++++++++ .../api/post/removeFinishedDownloads.js | 18 ++++++++ .../dist/routes/api/post/removeFromQueue.js | 24 ++++++++++ server/dist/routes/api/post/saveSettings.js | 21 +++++++++ server/dist/websocket/modules/saveSettings.js | 2 +- server/package.json | 2 +- server/src/main.ts | 17 +++++-- server/src/routes/api/get/getSettings.ts | 4 +- server/src/routes/api/get/getTracklist.ts | 44 ++++++++++++++++++- .../routes/api/get/getUserSpotifyPlaylists.ts | 34 ++++++++++++++ server/src/routes/api/get/index.ts | 2 + server/src/routes/api/post/index.ts | 4 +- server/src/routes/api/post/saveSettings.ts | 21 +++++++++ server/src/websocket/modules/saveSettings.ts | 2 +- server/yarn.lock | 16 +++++-- webui | 2 +- 25 files changed, 353 insertions(+), 28 deletions(-) create mode 100644 server/dist/routes/api/post/saveSettings.js create mode 100644 server/src/routes/api/post/saveSettings.ts diff --git a/server/dist/main.js b/server/dist/main.js index 8949592..12c90c4 100644 --- a/server/dist/main.js +++ b/server/dist/main.js @@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.restoreQueueFromDisk = exports.clearCompletedDownloads = exports.cancelAllDownloads = exports.cancelDownload = exports.startQueue = exports.addToQueue = exports.currentJob = exports.queue = exports.queueOrder = exports.saveSettings = exports.listener = exports.getArlFromAccessToken = exports.getAccessToken = exports.sessionDZ = exports.settings = exports.configFolder = exports.defaultSettings = void 0; +exports.restoreQueueFromDisk = exports.clearCompletedDownloads = exports.cancelAllDownloads = exports.cancelDownload = exports.startQueue = exports.addToQueue = exports.currentJob = exports.queue = exports.queueOrder = exports.saveSettings = exports.getSettings = exports.listener = exports.plugins = exports.getArlFromAccessToken = exports.getAccessToken = exports.sessionDZ = exports.settings = exports.configFolder = exports.defaultSettings = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = require("path"); const uuid_1 = require("uuid"); @@ -29,7 +29,10 @@ exports.settings = deemix_1.default.settings.load(exports.configFolder); exports.sessionDZ = {}; exports.getAccessToken = deemix_1.default.utils.deezer.getAccessToken; exports.getArlFromAccessToken = deemix_1.default.utils.deezer.getArlFromAccessToken; -const deemixPlugins = {}; +exports.plugins = { + spotify: new deemix_1.default.plugins.spotify() +}; +exports.plugins.spotify.setup(); exports.listener = { send(key, data) { console.log(key, data); @@ -40,9 +43,14 @@ exports.listener = { }); } }; -function saveSettings(newSettings) { +function getSettings() { + return { settings: exports.settings, defaultSettings: exports.defaultSettings, spotifySettings: exports.plugins.spotify.getCredentials() }; +} +exports.getSettings = getSettings; +function saveSettings(newSettings, newSpotifySettings) { deemix_1.default.settings.save(newSettings, exports.configFolder); exports.settings = newSettings; + exports.plugins.spotify.setCredentials(newSpotifySettings); } exports.saveSettings = saveSettings; exports.queueOrder = []; @@ -62,7 +70,7 @@ function addToQueue(dz, url, bitrate) { for (let i = 0; i < url.length; i++) { link = url[i]; console.log(`Adding ${link} to queue`); - let downloadObj = yield deemix_1.default.generateDownloadObject(dz, link, bitrate, deemixPlugins, exports.listener); + let downloadObj = yield deemix_1.default.generateDownloadObject(dz, link, bitrate, exports.plugins, exports.listener); if (Array.isArray(downloadObj)) { downloadObjs.concat(downloadObj); } @@ -122,7 +130,8 @@ function startQueue(dz) { break; case 'Convertable': downloadObject = new Convertable(currentItem); - // Convert object here + downloadObject = yield exports.plugins[downloadObject.plugin].convert(dz, downloadObject, exports.settings, exports.listener); + fs_1.default.writeFileSync(exports.configFolder + `queue${path_1.sep}${downloadObject.uuid}.json`, JSON.stringify(Object.assign(Object.assign({}, downloadObject.toDict()), { status: 'inQueue' }))); break; } exports.currentJob = new Downloader(dz, downloadObject, exports.settings, exports.listener); diff --git a/server/dist/routes/api/get/getSettings.js b/server/dist/routes/api/get/getSettings.js index 274005b..c7352b0 100644 --- a/server/dist/routes/api/get/getSettings.js +++ b/server/dist/routes/api/get/getSettings.js @@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const main_1 = require("../../../main"); const path = '/getSettings'; const handler = (_, res) => { - res.send({ settings: main_1.settings, defaultSettings: main_1.defaultSettings }); + res.send(main_1.getSettings()); }; const apiHandler = { path, handler }; exports.default = apiHandler; diff --git a/server/dist/routes/api/get/getTracklist.js b/server/dist/routes/api/get/getTracklist.js index 4f94842..b8bdcf0 100644 --- a/server/dist/routes/api/get/getTracklist.js +++ b/server/dist/routes/api/get/getTracklist.js @@ -26,6 +26,48 @@ const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { res.send(artistAPI); break; } + case 'spotifyplaylist': + case 'spotify_playlist': { + if (!main_1.plugins.spotify.enabled) { + res.send({ + collaborative: false, + description: "", + external_urls: { spotify: null }, + followers: { total: 0, href: null }, + id: null, + images: [], + name: "Something went wrong", + owner: { + display_name: "Error", + id: null + }, + public: true, + tracks: [], + type: 'playlist', + uri: null + }); + break; + } + let sp = main_1.plugins.spotify.sp; + let playlist = yield sp.getPlaylist(list_id); + playlist = playlist.body; + let tracklist = playlist.tracks.items; + while (playlist.tracks.next) { + let regExec = /offset=(\d+)&limit=(\d+)/g.exec(playlist.tracks.next); + let offset = regExec[1]; + let limit = regExec[2]; + let playlistTracks = yield sp.getPlaylistTracks(list_id, { offset, limit }); + playlist.tracks = playlistTracks.body; + tracklist = tracklist.concat(playlist.tracks.items); + } + tracklist.forEach((item, i) => { + tracklist[i] = item.track; + tracklist[i].selected = false; + }); + playlist.tracks = tracklist; + res.send(playlist); + break; + } default: { const releaseAPI = yield dz.api[`get_${list_type}`](list_id); let releaseTracksAPI = yield dz.api[`get_${list_type}_tracks`](list_id); diff --git a/server/dist/routes/api/get/getUserSpotifyPlaylists.js b/server/dist/routes/api/get/getUserSpotifyPlaylists.js index 3918c74..2812f29 100644 --- a/server/dist/routes/api/get/getUserSpotifyPlaylists.js +++ b/server/dist/routes/api/get/getUserSpotifyPlaylists.js @@ -1 +1,40 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const main_1 = require("../../../main"); +const path = '/getUserSpotifyPlaylists'; +const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + let data; + if (main_1.plugins.spotify.enabled) { + let sp = main_1.plugins.spotify.sp; + const username = req.query.spotifyUser; + data = []; + let playlists = yield sp.getUserPlaylists(username); + let playlistList = playlists.body.items; + while (playlists.next) { + let regExec = /offset=(\d+)&limit=(\d+)/g.exec(playlists.next); + let offset = regExec[1]; + let limit = regExec[2]; + let newPlaylists = yield sp.getUserPlaylists(username, { offset, limit }); + playlists = newPlaylists.body; + playlistList = playlistList.concat(playlists.items); + } + playlistList.forEach((playlist) => { + data.push(main_1.plugins.spotify._convertPlaylistStructure(playlist)); + }); + } + else { + data = { error: 'spotifyNotEnabled' }; + } + res.send(data); +}); +const apiHandler = { path, handler }; +exports.default = apiHandler; diff --git a/server/dist/routes/api/get/index.js b/server/dist/routes/api/get/index.js index dbbd615..25db80f 100644 --- a/server/dist/routes/api/get/index.js +++ b/server/dist/routes/api/get/index.js @@ -15,6 +15,7 @@ const getUserTracks_1 = __importDefault(require("./getUserTracks")); const getUserAlbums_1 = __importDefault(require("./getUserAlbums")); const getUserArtists_1 = __importDefault(require("./getUserArtists")); const getUserPlaylists_1 = __importDefault(require("./getUserPlaylists")); +const getUserSpotifyPlaylists_1 = __importDefault(require("./getUserSpotifyPlaylists")); const getUserFavorites_1 = __importDefault(require("./getUserFavorites")); const getQueue_1 = __importDefault(require("./getQueue")); exports.default = [ @@ -30,6 +31,7 @@ exports.default = [ getUserAlbums_1.default, getUserArtists_1.default, getUserPlaylists_1.default, + getUserSpotifyPlaylists_1.default, getUserFavorites_1.default, getQueue_1.default ]; diff --git a/server/dist/routes/api/post/cancelAllDownloads.js b/server/dist/routes/api/post/cancelAllDownloads.js index 3918c74..6604e53 100644 --- a/server/dist/routes/api/post/cancelAllDownloads.js +++ b/server/dist/routes/api/post/cancelAllDownloads.js @@ -1 +1,19 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const main_1 = require("../../../main"); +const path = '/cancelAllDownloads'; +const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + main_1.cancelAllDownloads(); + res.send({ result: true }); +}); +const apiHandler = { path, handler }; +exports.default = apiHandler; diff --git a/server/dist/routes/api/post/index.js b/server/dist/routes/api/post/index.js index 4b86426..83a309b 100644 --- a/server/dist/routes/api/post/index.js +++ b/server/dist/routes/api/post/index.js @@ -6,4 +6,18 @@ Object.defineProperty(exports, "__esModule", { value: true }); const login_arl_1 = __importDefault(require("./login-arl")); const addToQueue_1 = __importDefault(require("./addToQueue")); const loginWithCredentials_1 = __importDefault(require("./loginWithCredentials")); -exports.default = [login_arl_1.default, addToQueue_1.default, loginWithCredentials_1.default]; +const cancelAllDownloads_1 = __importDefault(require("./cancelAllDownloads")); +const removeFinishedDownloads_1 = __importDefault(require("./removeFinishedDownloads")); +const removeFromQueue_1 = __importDefault(require("./removeFromQueue")); +const logout_1 = __importDefault(require("./logout")); +const saveSettings_1 = __importDefault(require("./saveSettings")); +exports.default = [ + login_arl_1.default, + addToQueue_1.default, + loginWithCredentials_1.default, + cancelAllDownloads_1.default, + removeFinishedDownloads_1.default, + removeFromQueue_1.default, + logout_1.default, + saveSettings_1.default +]; diff --git a/server/dist/routes/api/post/login-arl.js b/server/dist/routes/api/post/login-arl.js index e3f17b7..8db1483 100644 --- a/server/dist/routes/api/post/login-arl.js +++ b/server/dist/routes/api/post/login-arl.js @@ -19,7 +19,7 @@ const LoginStatus = { ALREADY_LOGGED: 2, FORCED_SUCCESS: 3 }; -const path = '/login-arl/'; +const path = '/login-arl'; const handler = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { if (!main_1.sessionDZ[req.session.id]) main_1.sessionDZ[req.session.id] = new deezer_js_1.Deezer(); diff --git a/server/dist/routes/api/post/loginWithCredentials.js b/server/dist/routes/api/post/loginWithCredentials.js index e811f99..fe3b565 100644 --- a/server/dist/routes/api/post/loginWithCredentials.js +++ b/server/dist/routes/api/post/loginWithCredentials.js @@ -12,15 +12,15 @@ Object.defineProperty(exports, "__esModule", { value: true }); const main_1 = require("../../../main"); const path = '/loginWithCredentials'; const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { - const { username, password } = req.body; + const { email, password } = req.body; let accessToken = req.body.accessToken; if (!accessToken) { - const accessToken = yield main_1.getAccessToken(username, password); - console.log({ accessToken }); + accessToken = yield main_1.getAccessToken(email, password); } let arl; if (accessToken) - arl = main_1.getArlFromAccessToken(accessToken); + arl = yield main_1.getArlFromAccessToken(accessToken); + console.log({ accessToken, arl }); res.send({ accessToken, arl }); }); const apiHandler = { path, handler }; diff --git a/server/dist/routes/api/post/logout.js b/server/dist/routes/api/post/logout.js index 3918c74..6bfcb26 100644 --- a/server/dist/routes/api/post/logout.js +++ b/server/dist/routes/api/post/logout.js @@ -1 +1,21 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// @ts-expect-error +const deezer_js_1 = require("deezer-js"); +const main_1 = require("../../../main"); +const path = '/logout'; +const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + main_1.sessionDZ[req.session.id] = new deezer_js_1.Deezer(); + res.send({ logged_out: true }); +}); +const apiHandler = { path, handler }; +exports.default = apiHandler; diff --git a/server/dist/routes/api/post/removeFinishedDownloads.js b/server/dist/routes/api/post/removeFinishedDownloads.js index 3918c74..dea5a50 100644 --- a/server/dist/routes/api/post/removeFinishedDownloads.js +++ b/server/dist/routes/api/post/removeFinishedDownloads.js @@ -1 +1,19 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const main_1 = require("../../../main"); +const path = '/removeFinishedDownloads'; +const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + main_1.clearCompletedDownloads(); + res.send({ result: true }); +}); +const apiHandler = { path, handler }; +exports.default = apiHandler; diff --git a/server/dist/routes/api/post/removeFromQueue.js b/server/dist/routes/api/post/removeFromQueue.js index 3918c74..202291d 100644 --- a/server/dist/routes/api/post/removeFromQueue.js +++ b/server/dist/routes/api/post/removeFromQueue.js @@ -1 +1,25 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const main_1 = require("../../../main"); +const path = '/removeFromQueue'; +const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { uuid } = req.query; + if (uuid) { + main_1.cancelDownload(uuid); + res.send({ result: true }); + } + else { + res.send({ result: false }); + } +}); +const apiHandler = { path, handler }; +exports.default = apiHandler; diff --git a/server/dist/routes/api/post/saveSettings.js b/server/dist/routes/api/post/saveSettings.js new file mode 100644 index 0000000..342a23b --- /dev/null +++ b/server/dist/routes/api/post/saveSettings.js @@ -0,0 +1,21 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const main_1 = require("../../../main"); +const path = '/saveSettings'; +const handler = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { settings, spotifySettings } = req.query; + main_1.saveSettings(settings, spotifySettings); + main_1.listener.send('updateSettings', { settings, spotifySettings }); + res.send({ result: true }); +}); +const apiHandler = { path, handler }; +exports.default = apiHandler; diff --git a/server/dist/websocket/modules/saveSettings.js b/server/dist/websocket/modules/saveSettings.js index 66fa56b..c26d1f1 100644 --- a/server/dist/websocket/modules/saveSettings.js +++ b/server/dist/websocket/modules/saveSettings.js @@ -5,7 +5,7 @@ const main_1 = require("../../main"); const eventName = 'saveSettings'; const cb = (data, _, __) => { const { settings, spotifySettings } = data; - main_1.saveSettings(settings); + main_1.saveSettings(settings, spotifySettings); errors_1.consoleInfo('Settings saved'); main_1.listener.send('updateSettings', { settings, spotifySettings }); }; diff --git a/server/package.json b/server/package.json index a8cd8ea..20aeb05 100644 --- a/server/package.json +++ b/server/package.json @@ -15,7 +15,7 @@ "dependencies": { "cookie-parser": "1.4.5", "debug": "2.6.9", - "deemix": "0.0.9", + "deemix": "0.0.10", "deezer-js": "0.0.10", "dotenv": "8.2.0", "express": "4.17.1", diff --git a/server/src/main.ts b/server/src/main.ts index 3e96635..e2fb289 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -18,7 +18,10 @@ export const sessionDZ: any = {} export const getAccessToken = deemix.utils.deezer.getAccessToken export const getArlFromAccessToken = deemix.utils.deezer.getArlFromAccessToken -const deemixPlugins = {} +export const plugins: any = { + spotify: new deemix.plugins.spotify() +} +plugins.spotify.setup() export const listener = { send(key: string, data?: any) { @@ -31,9 +34,14 @@ export const listener = { } } -export function saveSettings(newSettings: any) { +export function getSettings(): any { + return {settings, defaultSettings, spotifySettings: plugins.spotify.getCredentials()} +} + +export function saveSettings(newSettings: any, newSpotifySettings: any) { deemix.settings.save(newSettings, configFolder) settings = newSettings + plugins.spotify.setCredentials(newSpotifySettings) } export let queueOrder: string[] = [] @@ -56,7 +64,7 @@ export async function addToQueue(dz: any, url: string[], bitrate: number) { for (let i = 0; i < url.length; i++){ link = url[i] console.log(`Adding ${link} to queue`) - let downloadObj = await deemix.generateDownloadObject(dz, link, bitrate, deemixPlugins, listener) + let downloadObj = await deemix.generateDownloadObject(dz, link, bitrate, plugins, listener) if (Array.isArray(downloadObj)){ downloadObjs.concat(downloadObj) } else { @@ -119,7 +127,8 @@ export async function startQueue(dz: any): Promise { break case 'Convertable': downloadObject = new Convertable(currentItem) - // Convert object here + downloadObject = await plugins[downloadObject.plugin].convert(dz, downloadObject, settings, listener) + fs.writeFileSync(configFolder + `queue${sep}${downloadObject.uuid}.json`, JSON.stringify({...downloadObject.toDict(), status: 'inQueue'})) break } currentJob = new Downloader(dz, downloadObject, settings, listener) diff --git a/server/src/routes/api/get/getSettings.ts b/server/src/routes/api/get/getSettings.ts index 0457aae..e36901e 100644 --- a/server/src/routes/api/get/getSettings.ts +++ b/server/src/routes/api/get/getSettings.ts @@ -1,10 +1,10 @@ import { ApiHandler } from '../../../types' -import { settings, defaultSettings } from '../../../main' +import { getSettings } from '../../../main' const path: ApiHandler['path'] = '/getSettings' const handler: ApiHandler['handler'] = (_, res) => { - res.send({ settings, defaultSettings }) + res.send(getSettings()) } const apiHandler: ApiHandler = { path, handler } diff --git a/server/src/routes/api/get/getTracklist.ts b/server/src/routes/api/get/getTracklist.ts index b39843e..c68abb7 100644 --- a/server/src/routes/api/get/getTracklist.ts +++ b/server/src/routes/api/get/getTracklist.ts @@ -1,7 +1,7 @@ // @ts-expect-error import { Deezer } from 'deezer-js' import { ApiHandler } from '../../../types' -import { sessionDZ } from '../../../main' +import { sessionDZ, plugins } from '../../../main' const path: ApiHandler['path'] = '/getTracklist' @@ -18,6 +18,48 @@ const handler: ApiHandler['handler'] = async (req, res) => { res.send(artistAPI) break } + case 'spotifyplaylist': + case 'spotify_playlist': { + if (!plugins.spotify.enabled){ + res.send({ + collaborative: false, + description: "", + external_urls: {spotify: null}, + followers: {total: 0, href: null}, + id: null, + images: [], + name: "Something went wrong", + owner: { + display_name: "Error", + id: null + }, + public: true, + tracks : [], + type: 'playlist', + uri: null + }) + break + } + let sp = plugins.spotify.sp + let playlist = await sp.getPlaylist(list_id) + playlist = playlist.body + let tracklist = playlist.tracks.items + while (playlist.tracks.next) { + let regExec = /offset=(\d+)&limit=(\d+)/g.exec(playlist.tracks.next) + let offset = regExec![1] + let limit = regExec![2] + let playlistTracks = await sp.getPlaylistTracks(list_id, { offset, limit }) + playlist.tracks = playlistTracks.body + tracklist = tracklist.concat(playlist.tracks.items) + } + tracklist.forEach((item:any, i:number) => { + tracklist[i] = item.track + tracklist[i].selected = false + }); + playlist.tracks = tracklist + res.send(playlist) + break + } default: { const releaseAPI = await dz.api[`get_${list_type}`](list_id) let releaseTracksAPI = await dz.api[`get_${list_type}_tracks`](list_id) diff --git a/server/src/routes/api/get/getUserSpotifyPlaylists.ts b/server/src/routes/api/get/getUserSpotifyPlaylists.ts index e69de29..0aecd00 100644 --- a/server/src/routes/api/get/getUserSpotifyPlaylists.ts +++ b/server/src/routes/api/get/getUserSpotifyPlaylists.ts @@ -0,0 +1,34 @@ +import { ApiHandler } from '../../../types' +import { plugins } from '../../../main' + +const path: ApiHandler['path'] = '/getUserSpotifyPlaylists' + +const handler: ApiHandler['handler'] = async (req, res) => { + let data + + if (plugins.spotify.enabled){ + let sp = plugins.spotify.sp + const username = req.query.spotifyUser + data = [] + let playlists = await sp.getUserPlaylists(username) + let playlistList = playlists.body.items + while (playlists.next) { + let regExec = /offset=(\d+)&limit=(\d+)/g.exec(playlists.next) + let offset = regExec![1] + let limit = regExec![2] + let newPlaylists = await sp.getUserPlaylists(username, { offset, limit }) + playlists = newPlaylists.body + playlistList = playlistList.concat(playlists.items) + } + playlistList.forEach((playlist: any) => { + data.push(plugins.spotify._convertPlaylistStructure(playlist)) + }) + } else { + data = { error: 'spotifyNotEnabled'} + } + res.send(data) +} + +const apiHandler: ApiHandler = { path, handler } + +export default apiHandler diff --git a/server/src/routes/api/get/index.ts b/server/src/routes/api/get/index.ts index 6f9892f..f4a2f96 100644 --- a/server/src/routes/api/get/index.ts +++ b/server/src/routes/api/get/index.ts @@ -10,6 +10,7 @@ import getUserTracks from './getUserTracks' import getUserAlbums from './getUserAlbums' import getUserArtists from './getUserArtists' import getUserPlaylists from './getUserPlaylists' +import getUserSpotifyPlaylists from './getUserSpotifyPlaylists' import getUserFavorites from './getUserFavorites' import getQueue from './getQueue' @@ -26,6 +27,7 @@ export default [ getUserAlbums, getUserArtists, getUserPlaylists, + getUserSpotifyPlaylists, getUserFavorites, getQueue ] diff --git a/server/src/routes/api/post/index.ts b/server/src/routes/api/post/index.ts index 9a6c597..582c621 100644 --- a/server/src/routes/api/post/index.ts +++ b/server/src/routes/api/post/index.ts @@ -5,6 +5,7 @@ import cancelAllDownloads from './cancelAllDownloads' import removeFinishedDownloads from './removeFinishedDownloads' import removeFromQueue from './removeFromQueue' import logout from './logout' +import saveSettings from './saveSettings' export default [ loginArl, @@ -13,5 +14,6 @@ export default [ cancelAllDownloads, removeFinishedDownloads, removeFromQueue, - logout + logout, + saveSettings ] diff --git a/server/src/routes/api/post/saveSettings.ts b/server/src/routes/api/post/saveSettings.ts new file mode 100644 index 0000000..f1eec4e --- /dev/null +++ b/server/src/routes/api/post/saveSettings.ts @@ -0,0 +1,21 @@ +import { ApiHandler } from '../../../types' +import { saveSettings, listener } from '../../../main' +import { Settings, SpotifySettings } from '../../../types' + +const path = '/saveSettings' + +export interface SaveSettingsData { + settings: Settings + spotifySettings: SpotifySettings +} + +const handler: ApiHandler['handler'] = async (req, res) => { + const { settings, spotifySettings }: SaveSettingsData = req.query + saveSettings(settings, spotifySettings) + listener.send('updateSettings', { settings, spotifySettings }) + res.send({ result: true }) +} + +const apiHandler = { path, handler } + +export default apiHandler diff --git a/server/src/websocket/modules/saveSettings.ts b/server/src/websocket/modules/saveSettings.ts index 8941679..739484f 100644 --- a/server/src/websocket/modules/saveSettings.ts +++ b/server/src/websocket/modules/saveSettings.ts @@ -12,7 +12,7 @@ export interface SaveSettingsData { const cb = (data: SaveSettingsData, _: any, __: WsServer) => { const { settings, spotifySettings } = data - saveSettings(settings) + saveSettings(settings, spotifySettings) consoleInfo('Settings saved') listener.send('updateSettings', { settings, spotifySettings }) } diff --git a/server/yarn.lock b/server/yarn.lock index b34c298..c91178d 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -1883,10 +1883,10 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" -deemix@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/deemix/-/deemix-0.0.7.tgz#64ac4caa435d8dd373469c219e2557350afd4a03" - integrity sha512-iCi4MCnMoh2PSGvUteS8XISx62i/Y4qoE2plEm083z3tGEqU9VhEW6clUnHwpAyfCeCamRdbAzMUq9V4RxaVoA== +deemix@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/deemix/-/deemix-0.0.10.tgz#630244c7b454b684337a807437b14a20a605e0ff" + integrity sha512-dNGoJY3h8naxhtTNLH7d93wCTnk7yln6oMeseTcUOiizJvT0CfX8g2xN1BAnozlk0wzs948b6VOeCPbeOAhglA== dependencies: async "^3.2.0" browser-id3-writer "^4.4.0" @@ -1894,6 +1894,7 @@ deemix@0.0.7: deezer-js "^0.0.8" got "^11.8.2" metaflac-js2 "^1.0.7" + spotify-web-api-node "^5.0.2" deep-extend@^0.6.0: version "0.6.0" @@ -5576,6 +5577,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +spotify-web-api-node@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/spotify-web-api-node/-/spotify-web-api-node-5.0.2.tgz#683669b3ccc046a5a357300f151df93a2b3539fe" + integrity sha512-r82dRWU9PMimHvHEzL0DwEJrzFk+SMCVfq249SLt3I7EFez7R+jeoKQd+M1//QcnjqlXPs2am4DFsGk8/GCsrA== + dependencies: + superagent "^6.1.0" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" diff --git a/webui b/webui index 8479bf3..bd22aef 160000 --- a/webui +++ b/webui @@ -1 +1 @@ -Subproject commit 8479bf328cd399ed751ada61a2f5a2a9526f3930 +Subproject commit bd22aef8cc1c00d8446f5d3a518e5552acba133d