mirror of
https://github.com/20kaushik02/spotify-manager.git
synced 2025-12-06 11:04:07 +00:00
minor: refined scopes, some more graphing, ocd
This commit is contained in:
parent
9bc0cb651d
commit
149965a15b
20
constants.js
20
constants.js
@ -4,22 +4,16 @@ const baseAPIURL = 'https://api.spotify.com/v1';
|
|||||||
const stateKey = 'spotify_auth_state';
|
const stateKey = 'spotify_auth_state';
|
||||||
|
|
||||||
const scopes = {
|
const scopes = {
|
||||||
ImageUpload: 'ugc-image-upload',
|
// ImageUpload: 'ugc-image-upload',
|
||||||
ControlPlayback: 'user-modify-playback-state',
|
AccessPrivatePlaylists: 'playlist-read-private',
|
||||||
ViewPlaybackState: 'user-read-playback-state',
|
AccessCollaborativePlaylists: 'playlist-read-collaborative',
|
||||||
ViewCurrentlyPlaying: 'user-read-currently-playing',
|
|
||||||
ModifyFollow: 'user-follow-modify',
|
|
||||||
ViewFollow: 'user-follow-read',
|
|
||||||
ViewRecentlyPlayed: 'user-read-recently-played',
|
|
||||||
ViewPlaybackPosition: 'user-read-playback-position',
|
|
||||||
ViewTop: 'user-top-read',
|
|
||||||
ViewPrivatePlaylists: 'playlist-read-private',
|
|
||||||
IncludeCollaborative: 'playlist-read-collaborative',
|
|
||||||
ModifyPublicPlaylists: 'playlist-modify-public',
|
ModifyPublicPlaylists: 'playlist-modify-public',
|
||||||
ModifyPrivatePlaylists: 'playlist-modify-private',
|
ModifyPrivatePlaylists: 'playlist-modify-private',
|
||||||
ControlRemotePlayback: 'app-remote-control',
|
// ModifyFollow: 'user-follow-modify',
|
||||||
|
AccessFollow: 'user-follow-read',
|
||||||
ModifyLibrary: 'user-library-modify',
|
ModifyLibrary: 'user-library-modify',
|
||||||
ViewLibrary: 'user-library-read'
|
AccessLibrary: 'user-library-read',
|
||||||
|
AccessUser: 'user-read-private',
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ const updateUser = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let oldPlaylists = await Playlists.findAll({
|
let oldPlaylists = await Playlists.findAll({
|
||||||
attributes: ["playlistID", "playlistName"],
|
attributes: ["playlistID"],
|
||||||
raw: true,
|
raw: true,
|
||||||
where: {
|
where: {
|
||||||
userID: userURI.id
|
userID: userURI.id
|
||||||
@ -97,6 +97,7 @@ const updateUser = async (req, res) => {
|
|||||||
let removedLinks = 0;
|
let removedLinks = 0;
|
||||||
|
|
||||||
if (toRemove.length) {
|
if (toRemove.length) {
|
||||||
|
// clean up any links dependent on the playlists
|
||||||
removedLinks = await Links.destroy({
|
removedLinks = await Links.destroy({
|
||||||
where: {
|
where: {
|
||||||
[Op.and]: [
|
[Op.and]: [
|
||||||
@ -110,6 +111,8 @@ const updateUser = async (req, res) => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// only then remove
|
||||||
const cleanedUser = await Playlists.destroy({
|
const cleanedUser = await Playlists.destroy({
|
||||||
where: { playlistID: toRemoveIDs }
|
where: { playlistID: toRemoveIDs }
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,7 +2,7 @@ const logger = require("../utils/logger")(module);
|
|||||||
|
|
||||||
const typedefs = require("../typedefs");
|
const typedefs = require("../typedefs");
|
||||||
const { axiosInstance } = require('../utils/axios');
|
const { axiosInstance } = require('../utils/axios');
|
||||||
const { parseSpotifyUri, parseSpotifyLink } = require("../utils/spotifyUriTransformer");
|
const { parseSpotifyURI, parseSpotifyLink } = require("../utils/spotifyURITransformer");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve list of all of user's playlists
|
* Retrieve list of all of user's playlists
|
||||||
@ -15,7 +15,7 @@ const getUserPlaylists = async (req, res) => {
|
|||||||
|
|
||||||
// get first 50
|
// get first 50
|
||||||
const response = await axiosInstance.get(
|
const response = await axiosInstance.get(
|
||||||
`/users/${parseSpotifyUri(req.session.user.uri).id}/playlists`,
|
`/users/${parseSpotifyURI(req.session.user.uri).id}/playlists`,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
@ -89,7 +89,7 @@ const getPlaylistDetails = async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
/** @type {typedefs.Playlist} */
|
/** @type {typedefs.Playlist} */
|
||||||
let playlist = {};
|
let playlist = {};
|
||||||
/** @type {typedefs.UriObject} */
|
/** @type {typedefs.URIObject} */
|
||||||
let uri;
|
let uri;
|
||||||
let initialFields = ["collaborative", "description", "images", "name", "owner(uri,display_name)", "public",
|
let initialFields = ["collaborative", "description", "images", "name", "owner(uri,display_name)", "public",
|
||||||
"snapshot_id", "tracks(next,total,items(is_local,track(name,uri)))"];
|
"snapshot_id", "tracks(next,total,items(is_local,track(name,uri)))"];
|
||||||
|
|||||||
1
index.js
1
index.js
@ -64,6 +64,7 @@ app.use((_req, res) => {
|
|||||||
const port = process.env.PORT || 3000;
|
const port = process.env.PORT || 3000;
|
||||||
|
|
||||||
const server = app.listen(port, () => {
|
const server = app.listen(port, () => {
|
||||||
|
logger.debug("-", { _: "_".repeat(100) });
|
||||||
logger.info(`App Listening on port ${port}`);
|
logger.info(`App Listening on port ${port}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
* album?: string,
|
* album?: string,
|
||||||
* title?: string,
|
* title?: string,
|
||||||
* duration?: number
|
* duration?: number
|
||||||
* }} UriObject
|
* }} URIObject
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* display_name: string,
|
* display_name: string,
|
||||||
|
|||||||
@ -6,7 +6,21 @@ const typedefs = require("../typedefs");
|
|||||||
* Directed graph, may or may not be connected.
|
* Directed graph, may or may not be connected.
|
||||||
*
|
*
|
||||||
* NOTE: Assumes that nodes and edges are valid.
|
* NOTE: Assumes that nodes and edges are valid.
|
||||||
*/
|
*
|
||||||
|
* Example:
|
||||||
|
* ```javascript
|
||||||
|
* let nodes = ['a', 'b', 'c', 'd', 'e'];
|
||||||
|
* let edges = [
|
||||||
|
* { from: 'a', to: 'b' },
|
||||||
|
* { from: 'b', to: 'c' },
|
||||||
|
* { from: 'c', to: 'd' },
|
||||||
|
* { from: 'd', to: 'a' },
|
||||||
|
* { from: 'e', to: 'a' }
|
||||||
|
* ];
|
||||||
|
* let g = new myGraph(nodes, edges);
|
||||||
|
* console.log(g.detectCycle()); // true
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
class myGraph {
|
class myGraph {
|
||||||
/**
|
/**
|
||||||
* @param {string[]} nodes Graph nodes IDs
|
* @param {string[]} nodes Graph nodes IDs
|
||||||
@ -21,7 +35,15 @@ class myGraph {
|
|||||||
* @param {type} node
|
* @param {type} node
|
||||||
* @returns {string[]}
|
* @returns {string[]}
|
||||||
*/
|
*/
|
||||||
getNeighbors(node) {
|
getDirectHeads(node) {
|
||||||
|
return this.edges.filter(edge => edge.to == node).map(edge => edge.from);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {type} node
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
getDirectTails(node) {
|
||||||
return this.edges.filter(edge => edge.from == node).map(edge => edge.to);
|
return this.edges.filter(edge => edge.from == node).map(edge => edge.to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +78,10 @@ class myGraph {
|
|||||||
let node = zeroInDegreeQueue.shift();
|
let node = zeroInDegreeQueue.shift();
|
||||||
topologicalOrder.push(node);
|
topologicalOrder.push(node);
|
||||||
|
|
||||||
for (let neighbor of this.getNeighbors(node)) {
|
for (let tail of this.getDirectTails(node)) {
|
||||||
inDegree[neighbor]--;
|
inDegree[tail]--;
|
||||||
if (inDegree[neighbor] === 0) {
|
if (inDegree[tail] === 0) {
|
||||||
zeroInDegreeQueue.push(neighbor);
|
zeroInDegreeQueue.push(tail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,10 +7,10 @@ const base62Pattern = /^[A-Za-z0-9]+$/;
|
|||||||
* Returns type and ID from a Spotify URI
|
* Returns type and ID from a Spotify URI
|
||||||
* @see {@link https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids|Spotify URIs and IDs}
|
* @see {@link https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids|Spotify URIs and IDs}
|
||||||
* @param {string} uri Spotify URI - can be of an album, track, playlist, user, episode, etc.
|
* @param {string} uri Spotify URI - can be of an album, track, playlist, user, episode, etc.
|
||||||
* @returns {typedefs.UriObject}
|
* @returns {typedefs.URIObject}
|
||||||
* @throws {TypeError} If the input is not a valid Spotify URI
|
* @throws {TypeError} If the input is not a valid Spotify URI
|
||||||
*/
|
*/
|
||||||
const parseSpotifyUri = (uri) => {
|
const parseSpotifyURI = (uri) => {
|
||||||
const parts = uri.split(":");
|
const parts = uri.split(":");
|
||||||
|
|
||||||
if (parts[0] !== "spotify") {
|
if (parts[0] !== "spotify") {
|
||||||
@ -56,7 +56,7 @@ const parseSpotifyUri = (uri) => {
|
|||||||
/**
|
/**
|
||||||
* Returns type and ID from a Spotify link
|
* Returns type and ID from a Spotify link
|
||||||
* @param {string} link Spotify URL - can be of an album, track, playlist, user, episode, etc.
|
* @param {string} link Spotify URL - can be of an album, track, playlist, user, episode, etc.
|
||||||
* @returns {typedefs.UriObject}
|
* @returns {typedefs.URIObject}
|
||||||
* @throws {TypeError} If the input is not a valid Spotify link
|
* @throws {TypeError} If the input is not a valid Spotify link
|
||||||
*/
|
*/
|
||||||
const parseSpotifyLink = (link) => {
|
const parseSpotifyLink = (link) => {
|
||||||
@ -103,10 +103,10 @@ const parseSpotifyLink = (link) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds URI string from a URIObject
|
* Builds URI string from a URIObject
|
||||||
* @param {typedefs.UriObject} uriObj
|
* @param {typedefs.URIObject} uriObj
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
const buildSpotifyUri = (uriObj) => {
|
const buildSpotifyURI = (uriObj) => {
|
||||||
if (uriObj.is_local) {
|
if (uriObj.is_local) {
|
||||||
const artist = encodeURIComponent(uriObj.artist ?? '');
|
const artist = encodeURIComponent(uriObj.artist ?? '');
|
||||||
const album = encodeURIComponent(uriObj.album ?? '');
|
const album = encodeURIComponent(uriObj.album ?? '');
|
||||||
@ -119,7 +119,7 @@ const buildSpotifyUri = (uriObj) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds link from a URIObject
|
* Builds link from a URIObject
|
||||||
* @param {typedefs.UriObject} uriObj
|
* @param {typedefs.URIObject} uriObj
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
const buildSpotifyLink = (uriObj) => {
|
const buildSpotifyLink = (uriObj) => {
|
||||||
@ -134,8 +134,8 @@ const buildSpotifyLink = (uriObj) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parseSpotifyUri,
|
parseSpotifyURI,
|
||||||
parseSpotifyLink,
|
parseSpotifyLink,
|
||||||
buildSpotifyUri,
|
buildSpotifyURI,
|
||||||
buildSpotifyLink
|
buildSpotifyLink
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user