123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- import config from "config";
- import async from "async";
- import axios from "axios";
- import isLoginRequired from "../hooks/loginRequired";
- import { hasPermission, useHasPermission } from "../hooks/hasPermission";
- // eslint-disable-next-line
- import moduleManager from "../../index";
- const UtilsModule = moduleManager.modules.utils;
- const WSModule = moduleManager.modules.ws;
- const YouTubeModule = moduleManager.modules.youtube;
- const SpotifyModule = moduleManager.modules.spotify;
- const CacheModule = moduleManager.modules.cache;
- export default {
- /**
- * Fetches a list of songs from Youtube's API
- *
- * @param {object} session - user session
- * @param {string} query - the query we'll pass to youtubes api
- * @param {Function} cb - callback
- * @returns {{status: string, data: object}} - returns an object
- */
- searchYoutube: isLoginRequired(function searchYoutube(session, query, cb) {
- return YouTubeModule.runJob("SEARCH", { query }, this)
- .then(data => {
- this.log("SUCCESS", "APIS_SEARCH_YOUTUBE", `Searching YouTube successful with query "${query}".`);
- return cb({ status: "success", data });
- })
- .catch(async err => {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log("ERROR", "APIS_SEARCH_YOUTUBE", `Searching youtube failed with query "${query}". "${err}"`);
- return cb({ status: "error", message: err });
- });
- }),
- /**
- * Fetches a specific page of search results from Youtube's API
- *
- * @param {object} session - user session
- * @param {string} query - the query we'll pass to youtubes api
- * @param {string} pageToken - identifies a specific page in the result set that should be retrieved
- * @param {Function} cb - callback
- * @returns {{status: string, data: object}} - returns an object
- */
- searchYoutubeForPage: isLoginRequired(function searchYoutubeForPage(session, query, pageToken, cb) {
- return YouTubeModule.runJob("SEARCH", { query, pageToken }, this)
- .then(data => {
- this.log(
- "SUCCESS",
- "APIS_SEARCH_YOUTUBE_FOR_PAGE",
- `Searching YouTube successful with query "${query}".`
- );
- return cb({ status: "success", data });
- })
- .catch(async err => {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log(
- "ERROR",
- "APIS_SEARCH_YOUTUBE_FOR_PAGE",
- `Searching youtube failed with query "${query}". "${err}"`
- );
- return cb({ status: "error", message: err });
- });
- }),
- /**
- * Gets Discogs data
- *
- * @param session
- * @param query - the query
- * @param {Function} cb
- */
- searchDiscogs: useHasPermission("apis.searchDiscogs", function searchDiscogs(session, query, page, cb) {
- async.waterfall(
- [
- next => {
- const options = {
- params: { q: query, per_page: 20, page },
- headers: {
- "User-Agent": "Request",
- Authorization: `Discogs key=${config.get("apis.discogs.client")}, secret=${config.get(
- "apis.discogs.secret"
- )}`
- }
- };
- axios
- .get("https://api.discogs.com/database/search", options)
- .then(res => next(null, res.data))
- .catch(err => next(err));
- }
- ],
- async (err, body) => {
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log(
- "ERROR",
- "APIS_SEARCH_DISCOGS",
- `Searching discogs failed with query "${query}". "${err}"`
- );
- return cb({ status: "error", message: err });
- }
- this.log(
- "SUCCESS",
- "APIS_SEARCH_DISCOGS",
- `User "${session.userId}" searched Discogs succesfully for query "${query}".`
- );
- return cb({
- status: "success",
- data: {
- results: body.results,
- pages: body.pagination.pages
- }
- });
- }
- );
- }),
- // /**
- // *
- // *
- // * @param session
- // * @param ISRC - the ISRC
- // * @param {Function} cb
- // */
- // searchMusicBrainzISRC: useHasPermission("admin.view.spotify", function searchMusicBrainzISRC(session, ISRC, cb) {
- // async.waterfall(
- // [
- // next => {
- // if (!ISRC) {
- // next("Invalid ISRC provided.");
- // return;
- // }
- // CacheModule.runJob("HGET", { table: "musicbrainz-isrc-2", key: ISRC })
- // .then(response => {
- // if (response) next(null, response);
- // else next(null, null);
- // })
- // .catch(err => {
- // next(err);
- // });
- // },
- // (body, next) => {
- // if (body) {
- // next(null, body);
- // return;
- // }
- // const options = {
- // params: { fmt: "json", inc: "url-rels+work-rels" },
- // headers: {
- // "User-Agent": "Musare/3.9.0-fork ( https://git.kvos.dev/kris/MusareFork )" // TODO set this in accordance to https://musicbrainz.org/doc/MusicBrainz_API/Rate_Limiting
- // }
- // };
- // console.log("KRIS101", options, `https://musicbrainz.org/ws/2/isrc/${ISRC}`);
- // axios
- // .get(`https://musicbrainz.org/ws/2/isrc/${ISRC}`, options)
- // .then(res => next(null, res.data))
- // .catch(err => next(err));
- // },
- // (body, next) => {
- // console.log("KRIS222", body);
- // CacheModule.runJob("HSET", { table: "musicbrainz-isrc-2", key: ISRC, value: body })
- // .then(() => {})
- // .catch(() => {});
- // next(null, body);
- // },
- // (body, next) => {
- // const response = {};
- // const recordingUrls = Array.from(
- // new Set(
- // body.recordings
- // .map(recording =>
- // recording.relations
- // .filter(
- // relation =>
- // relation["target-type"] === "url" &&
- // relation.url &&
- // // relation["type-id"] === "7e41ef12-a124-4324-afdb-fdbae687a89c" &&
- // (relation.url.resource.indexOf("youtu.be") !== -1 ||
- // relation.url.resource.indexOf("youtube.com") !== -1 ||
- // relation.url.resource.indexOf("soundcloud.com") !== -1)
- // )
- // .map(relation => relation.url.resource)
- // )
- // .flat()
- // )
- // );
- // const workIds = Array.from(
- // new Set(
- // body.recordings
- // .map(recording =>
- // recording.relations
- // .filter(relation => relation["target-type"] === "work" && relation.work)
- // .map(relation => relation.work.id)
- // )
- // .flat()
- // )
- // );
- // response.recordingUrls = recordingUrls;
- // response.workIds = workIds;
- // response.raw = body;
- // next(null, response);
- // }
- // ],
- // async (err, response) => {
- // if (err && err !== true) {
- // err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- // this.log(
- // "ERROR",
- // "APIS_SEARCH_MUSICBRAINZ_ISRC",
- // `Searching MusicBrainz ISRC failed with ISRC "${ISRC}". "${err}"`
- // );
- // return cb({ status: "error", message: err });
- // }
- // this.log(
- // "SUCCESS",
- // "APIS_SEARCH_MUSICBRAINZ_ISRC",
- // `User "${session.userId}" searched MusicBrainz ISRC succesfully for ISRC "${ISRC}".`
- // );
- // return cb({
- // status: "success",
- // data: {
- // response
- // }
- // });
- // }
- // );
- // }),
- // /**
- // *
- // *
- // * @param session
- // * @param trackId - the trackId
- // * @param {Function} cb
- // */
- // searchWikidataBySpotifyTrackId: useHasPermission(
- // "admin.view.spotify",
- // function searchWikidataBySpotifyTrackId(session, trackId, cb) {
- // async.waterfall(
- // [
- // next => {
- // if (!trackId) {
- // next("Invalid trackId provided.");
- // return;
- // }
- // CacheModule.runJob("HGET", { table: "wikidata-spotify-track", key: trackId })
- // .then(response => {
- // if (response) next(null, response);
- // else next(null, null);
- // })
- // .catch(err => {
- // console.log("WOW", err);
- // next(err);
- // });
- // },
- // (body, next) => {
- // if (body) {
- // next(null, body);
- // return;
- // }
- // // const options = {
- // // params: { fmt: "json", inc: "url-rels" },
- // // headers: {
- // // "User-Agent": "Musare/3.9.0-fork ( https://git.kvos.dev/kris/MusareFork )" // TODO set this in accordance to https://musicbrainz.org/doc/MusicBrainz_API/Rate_Limiting
- // // }
- // // };
- // // axios
- // // .get(`https://musicbrainz.org/ws/2/isrc/${ISRC}`, options)
- // // .then(res => next(null, res.data))
- // // .catch(err => next(err));
- // },
- // (body, next) => {
- // CacheModule.runJob("HSET", { table: "musicbrainz-isrc", key: ISRC, value: body })
- // .then(() => {})
- // .catch(() => {});
- // next(null, body);
- // },
- // (body, next) => {
- // const response = {};
- // const recordingUrls = Array.from(
- // new Set(
- // body.recordings
- // .map(recording =>
- // recording.relations
- // .filter(
- // relation =>
- // relation["target-type"] === "url" &&
- // relation.url &&
- // // relation["type-id"] === "7e41ef12-a124-4324-afdb-fdbae687a89c" &&
- // (relation.url.resource.indexOf("youtu.be") !== -1 ||
- // relation.url.resource.indexOf("youtube.com") !== -1 ||
- // relation.url.resource.indexOf("soundcloud.com") !== -1)
- // )
- // .map(relation => relation.url.resource)
- // )
- // .flat()
- // )
- // );
- // response.recordingUrls = recordingUrls;
- // response.raw = body;
- // next(null, response);
- // }
- // ],
- // async (err, response) => {
- // if (err && err !== true) {
- // err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- // this.log(
- // "ERROR",
- // "APIS_SEARCH_TODO",
- // `Searching MusicBrainz ISRC failed with ISRC "${ISRC}". "${err}"`
- // );
- // return cb({ status: "error", message: err });
- // }
- // this.log(
- // "SUCCESS",
- // "APIS_SEARCH_TODO",
- // `User "${session.userId}" searched MusicBrainz ISRC succesfully for ISRC "${ISRC}".`
- // );
- // return cb({
- // status: "success",
- // data: {
- // response
- // }
- // });
- // }
- // );
- // }
- // ),
- // /**
- // *
- // *
- // * @param session
- // * @param trackId - the trackId
- // * @param {Function} cb
- // */
- // searchWikidataByMusicBrainzWorkId: useHasPermission(
- // "admin.view.spotify",
- // function searchWikidataByMusicBrainzWorkId(session, workId, cb) {
- // async.waterfall(
- // [
- // next => {
- // if (!workId) {
- // next("Invalid workId provided.");
- // return;
- // }
- // CacheModule.runJob("HGET", { table: "wikidata-musicbrainz-work", key: workId })
- // .then(response => {
- // if (response) next(null, response);
- // else next(null, null);
- // })
- // .catch(err => {
- // next(err);
- // });
- // },
- // (body, next) => {
- // if (body) {
- // next(null, body);
- // return;
- // }
- // const endpointUrl = "https://query.wikidata.org/sparql";
- // const sparqlQuery = `SELECT DISTINCT ?item ?itemLabel ?YouTube_video_ID WHERE {
- // SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". }
- // {
- // SELECT DISTINCT ?item WHERE {
- // ?item p:P435 ?statement0.
- // ?statement0 ps:P435 "${workId}".
- // }
- // LIMIT 100
- // }
- // OPTIONAL { ?item wdt:P1651 ?YouTube_video_ID. }
- // }`;
- // // OPTIONAL { ?item wdt:P3040 ?SoundCloud_track_ID. }
- // const options = {
- // params: { query: sparqlQuery },
- // headers: {
- // Accept: "application/sparql-results+json"
- // }
- // };
- // axios
- // .get(endpointUrl, options)
- // .then(res => next(null, res.data))
- // .catch(err => next(err));
- // },
- // (body, next) => {
- // CacheModule.runJob("HSET", { table: "wikidata-musicbrainz-work", key: workId, value: body })
- // .then(() => {})
- // .catch(() => {});
- // next(null, body);
- // },
- // (body, next) => {
- // const response = {};
- // const youtubeIds = Array.from(
- // new Set(
- // body.results.bindings
- // .filter(binding => !!binding.YouTube_video_ID)
- // .map(binding => binding.YouTube_video_ID.value)
- // )
- // );
- // // const soundcloudIds = Array.from(new Set(body.results.bindings.filter(binding => !!binding["SoundCloud_track_ID"]).map(binding => binding["SoundCloud_track_ID"].value)))
- // response.youtubeIds = youtubeIds;
- // response.raw = body;
- // next(null, response);
- // }
- // ],
- // async (err, response) => {
- // if (err && err !== true) {
- // err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- // this.log(
- // "ERROR",
- // "APIS_SEARCH_TODO",
- // `Searching MusicBrainz ISRC failed with ISRC "${workId}". "${err}"`
- // );
- // return cb({ status: "error", message: err });
- // }
- // this.log(
- // "SUCCESS",
- // "APIS_SEARCH_TODO",
- // `User "${session.userId}" searched MusicBrainz ISRC succesfully for ISRC "${workId}".`
- // );
- // return cb({
- // status: "success",
- // data: {
- // response
- // }
- // });
- // }
- // );
- // }
- // ),
- /**
- *
- *
- * @param session
- * @param trackId - the trackId
- * @param {Function} cb
- */
- getAlternativeMediaSourcesForTracks: useHasPermission(
- "admin.view.spotify",
- function getAlternativeMediaSourcesForTracks(session, mediaSources, collectAlternativeMediaSourcesOrigins, cb) {
- async.waterfall(
- [
- next => {
- if (!mediaSources) {
- next("Invalid mediaSources provided.");
- return;
- }
- next();
- },
- async () => {
- this.keepLongJob();
- this.publishProgress({
- status: "started",
- title: "Getting alternative media sources for Spotify tracks",
- message: "Starting up",
- id: this.toString()
- });
- console.log("KRIS@4", this.toString());
- // await CacheModule.runJob(
- // "RPUSH",
- // { key: `longJobs.${session.userId}`, value: this.toString() },
- // this
- // );
- SpotifyModule.runJob(
- "GET_ALTERNATIVE_MEDIA_SOURCES_FOR_TRACKS",
- { mediaSources, collectAlternativeMediaSourcesOrigins },
- this
- );
- }
- ],
- async err => {
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log(
- "ERROR",
- "APIS_GET_ALTERNATIVE_SOURCES",
- `Getting alternative sources failed for "${mediaSources.join(", ")}". "${err}"`
- );
- return cb({ status: "error", message: err });
- }
- this.log(
- "SUCCESS",
- "APIS_GET_ALTERNATIVE_SOURCES",
- `User "${session.userId}" started getting alternatives for "${mediaSources.join(", ")}".`
- );
- return cb({
- status: "success"
- });
- }
- );
- }
- ),
- /**
- *
- *
- * @param session
- * @param trackId - the trackId
- * @param {Function} cb
- */
- getAlternativeAlbumSourcesForAlbums: useHasPermission(
- "admin.view.spotify",
- function getAlternativeAlbumSourcesForAlbums(session, albumIds, collectAlternativeAlbumSourcesOrigins, cb) {
- async.waterfall(
- [
- next => {
- if (!albumIds) {
- next("Invalid albumIds provided.");
- return;
- }
- next();
- },
- async () => {
- this.keepLongJob();
- this.publishProgress({
- status: "started",
- title: "Getting alternative album sources for Spotify albums",
- message: "Starting up",
- id: this.toString()
- });
- console.log("KRIS@4", this.toString());
- // await CacheModule.runJob(
- // "RPUSH",
- // { key: `longJobs.${session.userId}`, value: this.toString() },
- // this
- // );
- SpotifyModule.runJob(
- "GET_ALTERNATIVE_ALBUM_SOURCES_FOR_ALBUMS",
- { albumIds, collectAlternativeAlbumSourcesOrigins },
- this
- );
- }
- ],
- async err => {
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log(
- "ERROR",
- "APIS_GET_ALTERNATIVE_ALBUM_SOURCES",
- `Getting alternative album sources failed for "${albumIds.join(", ")}". "${err}"`
- );
- return cb({ status: "error", message: err });
- }
- this.log(
- "SUCCESS",
- "APIS_GET_ALTERNATIVE_ALBUM_SOURCES",
- `User "${session.userId}" started getting alternative album spirces for "${albumIds.join(
- ", "
- )}".`
- );
- return cb({
- status: "success"
- });
- }
- );
- }
- ),
- /**
- *
- *
- * @param session
- * @param trackId - the trackId
- * @param {Function} cb
- */
- getAlternativeArtistSourcesForArtists: useHasPermission(
- "admin.view.spotify",
- function getAlternativeArtistSourcesForArtists(session, artistIds, collectAlternativeArtistSourcesOrigins, cb) {
- async.waterfall(
- [
- next => {
- if (!artistIds) {
- next("Invalid artistIds provided.");
- return;
- }
- next();
- },
- async () => {
- this.keepLongJob();
- this.publishProgress({
- status: "started",
- title: "Getting alternative artist sources for Spotify artists",
- message: "Starting up",
- id: this.toString()
- });
- console.log("KRIS@4", this.toString());
- // await CacheModule.runJob(
- // "RPUSH",
- // { key: `longJobs.${session.userId}`, value: this.toString() },
- // this
- // );
- SpotifyModule.runJob(
- "GET_ALTERNATIVE_ARTIST_SOURCES_FOR_ARTISTS",
- { artistIds, collectAlternativeArtistSourcesOrigins },
- this
- );
- }
- ],
- async err => {
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log(
- "ERROR",
- "APIS_GET_ALTERNATIVE_ARTIST_SOURCES",
- `Getting alternative artist sources failed for "${artistIds.join(", ")}". "${err}"`
- );
- return cb({ status: "error", message: err });
- }
- this.log(
- "SUCCESS",
- "APIS_GET_ALTERNATIVE_ARTIST_SOURCES",
- `User "${session.userId}" started getting alternative artist spirces for "${artistIds.join(
- ", "
- )}".`
- );
- return cb({
- status: "success"
- });
- }
- );
- }
- ),
- /**
- * Joins a room
- *
- * @param {object} session - user session
- * @param {string} room - the room to join
- * @param {Function} cb - callback
- */
- joinRoom(session, room, cb) {
- const roomName = room.split(".")[0];
- // const roomId = room.split(".")[1];
- const rooms = {
- home: null,
- news: null,
- profile: null,
- "view-youtube-video": null,
- "manage-station": null,
- // "manage-station": "stations.view",
- "edit-song": "songs.update",
- "edit-songs": "songs.update",
- "import-album": "songs.update",
- // "edit-playlist": "playlists.update",
- "view-report": "reports.get",
- "edit-user": "users.update",
- "view-api-request": "youtube.getApiRequest",
- "view-punishment": "punishments.get"
- };
- const join = (status, error) => {
- if (status === "success")
- WSModule.runJob("SOCKET_JOIN_ROOM", {
- socketId: session.socketId,
- room
- })
- .then(() => cb({ status: "success", message: "Successfully joined room." }))
- .catch(err => join("error", err.message));
- else {
- this.log("ERROR", `Joining room failed: ${error}`);
- cb({ status: "error", message: error });
- }
- };
- if (rooms[roomName] === null) join("success");
- else if (rooms[roomName])
- hasPermission(rooms[roomName], session)
- .then(() => join("success"))
- .catch(err => join("error", err));
- else join("error", "Room not found");
- },
- /**
- * Leaves a room
- *
- * @param {object} session - user session
- * @param {string} room - the room to leave
- * @param {Function} cb - callback
- */
- leaveRoom(session, room, cb) {
- if (
- room === "home" ||
- room.startsWith("profile.") ||
- room.startsWith("manage-station.") ||
- room.startsWith("edit-song.") ||
- room.startsWith("view-report.") ||
- room === "import-album" ||
- room === "edit-songs"
- ) {
- WSModule.runJob("SOCKET_LEAVE_ROOM", {
- socketId: session.socketId,
- room
- })
- .then(() => {})
- .catch(err => {
- this.log("ERROR", `Leaving room failed: ${err.message}`);
- });
- }
- cb({ status: "success", message: "Successfully left room." });
- },
- /**
- * Joins an admin room
- *
- * @param {object} session - user session
- * @param {string} page - the admin room to join
- * @param {Function} cb - callback
- */
- joinAdminRoom(session, page, cb) {
- if (
- page === "songs" ||
- page === "stations" ||
- page === "reports" ||
- page === "news" ||
- page === "playlists" ||
- page === "users" ||
- page === "statistics" ||
- page === "punishments" ||
- page === "youtube" ||
- page === "youtubeVideos" ||
- page === "youtubeChannels" ||
- page === "soundcloud" ||
- page === "soundcloudTracks" ||
- page === "import" ||
- page === "dataRequests"
- ) {
- hasPermission(`admin.view.${page}`, session.userId)
- .then(() =>
- WSModule.runJob("SOCKET_LEAVE_ROOMS", { socketId: session.socketId }).then(() => {
- WSModule.runJob(
- "SOCKET_JOIN_ROOM",
- {
- socketId: session.socketId,
- room: `admin.${page}`
- },
- this
- ).then(() => cb({ status: "success", message: "Successfully joined admin room." }));
- })
- )
- .catch(() => cb({ status: "error", message: "Failed to join admin room." }));
- }
- },
- /**
- * Leaves all rooms
- *
- * @param {object} session - user session
- * @param {Function} cb - callback
- */
- leaveRooms(session, cb) {
- WSModule.runJob("SOCKET_LEAVE_ROOMS", { socketId: session.socketId });
- cb({ status: "success", message: "Successfully left all rooms." });
- },
- /**
- * Returns current date
- *
- * @param {object} session - user session
- * @param {Function} cb - callback
- */
- ping(session, cb) {
- cb({ status: "success", message: "Successfully pinged.", data: { date: Date.now() } });
- }
- };
|