minor: refined scopes, some more graphing, ocd

This commit is contained in:
Kaushik Narayan R 2024-08-01 00:01:27 +05:30
parent 9bc0cb651d
commit 149965a15b
7 changed files with 52 additions and 32 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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