Spotify integration works again. Youtube music not yet.

editsong
Sander Vocke 5 years ago
parent dfd8549bf0
commit af5a742d7c
  1. 3
      client/src/components/windows/manage_links/BatchLinkDialog.tsx
  2. 6
      client/src/lib/saveChanges.tsx
  3. 2
      server/app.ts
  4. 18
      server/db/Artist.ts
  5. 4
      server/db/Integration.ts
  6. 16
      server/integrations/integrations.ts

@ -195,7 +195,8 @@ async function doLinking(
await modifyFuncs[t.itemType]( await modifyFuncs[t.itemType](
t.itemId, t.itemId,
{ {
storeLinks: [...item.storeLinks, candidates[0].url] mbApi_typename: t.itemType,
storeLinks: [...item.storeLinks, candidates[0].url],
} }
) )
success = true; success = true;

@ -3,7 +3,7 @@ import backendRequest from './backend/request';
export async function modifyTrack(id: number, change: serverApi.PatchTrackRequest) { export async function modifyTrack(id: number, change: serverApi.PatchTrackRequest) {
const requestOpts = { const requestOpts = {
method: 'PUT', method: 'PATCH',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(change), body: JSON.stringify(change),
}; };
@ -17,7 +17,7 @@ export async function modifyTrack(id: number, change: serverApi.PatchTrackReques
export async function modifyArtist(id: number, change: serverApi.PatchArtistRequest) { export async function modifyArtist(id: number, change: serverApi.PatchArtistRequest) {
const requestOpts = { const requestOpts = {
method: 'PUT', method: 'PATCH',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(change), body: JSON.stringify(change),
}; };
@ -31,7 +31,7 @@ export async function modifyArtist(id: number, change: serverApi.PatchArtistRequ
export async function modifyAlbum(id: number, change: serverApi.PatchAlbumRequest) { export async function modifyAlbum(id: number, change: serverApi.PatchAlbumRequest) {
const requestOpts = { const requestOpts = {
method: 'PUT', method: 'PATCH',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(change), body: JSON.stringify(change),
}; };

@ -101,7 +101,7 @@ const SetupApp = (app: any, knex: Knex, apiBaseUrl: string) => {
} }
// Set up integration proxies // Set up integration proxies
app.use('/integrations', checkLogin(), createIntegrations(knex)); app.use(apiBaseUrl + '/integrations', checkLogin(), createIntegrations(knex, apiBaseUrl));
// Set up auth endpoints // Set up auth endpoints
app.post(apiBaseUrl + api.LoginEndpoint, passport.authenticate('local'), (req: any, res: any) => { app.post(apiBaseUrl + api.LoginEndpoint, passport.authenticate('local'), (req: any, res: any) => {

@ -160,21 +160,21 @@ export async function createArtist(userId: number, artist: ArtistWithRefs, knex:
export async function modifyArtist(userId: number, artistId: number, artist: ArtistBaseWithRefs, knex: Knex): Promise<void> { export async function modifyArtist(userId: number, artistId: number, artist: ArtistBaseWithRefs, knex: Knex): Promise<void> {
await knex.transaction(async (trx) => { await knex.transaction(async (trx) => {
// Start retrieving the artist itself. // Start retrieving the artist itself.
const artistIdPromise: Promise<number | undefined> = const artistIdPromise: Promise<number | undefined | null> =
trx.select('id') trx.select('id')
.from('artists') .from('artists')
.where({ 'user': userId }) .where({ 'user': userId })
.where({ id: artistId }) .where({ id: artistId })
.then((r: any) => (r && r[0]) ? r[0]['id'] : undefined); .then((r: any) => (r && r[0]) ? r[0]['id'] : null);
// Start retrieving albums if we are modifying those. // Start retrieving albums if we are modifying those.
const albumIdsPromise: Promise<number[] | undefined> = const albumIdsPromise: Promise<number[] | undefined | null> =
artist.albumIds ? artist.albumIds ?
trx.select('id') trx.select('id')
.from('albums') .from('albums')
.whereIn('id', artist.albumIds) .whereIn('id', artist.albumIds)
.then((as: any) => as.map((a: any) => a['id'])) .then((as: any) => as.map((a: any) => a['id']))
: (async () => undefined)(); : (async () => null)();
// Start retrieving tracks if we are modifying those. // Start retrieving tracks if we are modifying those.
const trackIdsPromise: Promise<number[] | undefined> = const trackIdsPromise: Promise<number[] | undefined> =
@ -183,7 +183,7 @@ export async function modifyArtist(userId: number, artistId: number, artist: Art
.from('tracks') .from('tracks')
.whereIn('id', artist.trackIds) .whereIn('id', artist.trackIds)
.then((as: any) => as.map((a: any) => a['id'])) .then((as: any) => as.map((a: any) => a['id']))
: (async () => undefined)(); : (async () => null)();
// Start retrieving tags if we are modifying those. // Start retrieving tags if we are modifying those.
const tagIdsPromise = const tagIdsPromise =
@ -192,15 +192,15 @@ export async function modifyArtist(userId: number, artistId: number, artist: Art
.from('tags') .from('tags')
.whereIn('id', artist.tagIds) .whereIn('id', artist.tagIds)
.then((ts: any) => ts.map((t: any) => t['id'])) : .then((ts: any) => ts.map((t: any) => t['id'])) :
(async () => undefined)(); (async () => null)();
// Wait for the requests to finish. // Wait for the requests to finish.
var [oldArtist, albums, tags, tracks] = await Promise.all([artistIdPromise, albumIdsPromise, tagIdsPromise, trackIdsPromise]);; var [oldArtist, albums, tags, tracks] = await Promise.all([artistIdPromise, albumIdsPromise, tagIdsPromise, trackIdsPromise]);;
// Check that we found all objects we need. // Check that we found all objects we need.
if ((!albums || !_.isEqual(albums.sort(), (artist.albumIds || []).sort())) || if ((albums === undefined || !_.isEqual((albums || []).sort(), (artist.albumIds || []).sort())) ||
(!tags || !_.isEqual(tags.sort(), (artist.tagIds || []).sort())) || (tags === undefined || !_.isEqual((tags || []).sort(), (artist.tagIds || []).sort())) ||
(!tracks || !_.isEqual(tracks.sort(), (artist.trackIds || []).sort())) || (tracks === undefined || !_.isEqual((tracks || []).sort(), (artist.trackIds || []).sort())) ||
!oldArtist) { !oldArtist) {
throw makeNotFoundError(); throw makeNotFoundError();
} }

@ -8,7 +8,7 @@ import { makeNotFoundError } from './common';
export async function createIntegration(userId: number, integration: api.IntegrationDataWithSecret, knex: Knex): Promise<number> { export async function createIntegration(userId: number, integration: api.IntegrationDataWithSecret, knex: Knex): Promise<number> {
return await knex.transaction(async (trx) => { return await knex.transaction(async (trx) => {
// Create the new integration. // Create the new integration.
var integration: any = { var dbIntegration: any = {
name: integration.name, name: integration.name,
user: userId, user: userId,
type: integration.type, type: integration.type,
@ -16,7 +16,7 @@ export async function createIntegration(userId: number, integration: api.Integra
secretDetails: JSON.stringify(integration.secretDetails), secretDetails: JSON.stringify(integration.secretDetails),
} }
const integrationId = (await trx('integrations') const integrationId = (await trx('integrations')
.insert(integration) .insert(dbIntegration)
.returning('id') // Needed for Postgres .returning('id') // Needed for Postgres
)[0]; )[0];

@ -29,7 +29,7 @@ async function getSpotifyCCAuthToken(clientId: string, clientSecret: string) {
return (await response).data.access_token; return (await response).data.access_token;
} }
export function createIntegrations(knex: Knex) { export function createIntegrations(knex: Knex, apiBaseUrl: string) {
// This will enable the app to redirect requests like: // This will enable the app to redirect requests like:
// /integrations/5/v1/search?q=query // /integrations/5/v1/search?q=query
// To the external API represented by integration 5, e.g. for spotify: // To the external API represented by integration 5, e.g. for spotify:
@ -41,9 +41,10 @@ export function createIntegrations(knex: Knex) {
changeOrigin: true, changeOrigin: true,
logLevel: 'debug', logLevel: 'debug',
pathRewrite: (path: string, req: any) => { pathRewrite: (path: string, req: any) => {
// Remove e.g. "/integrations/5" // Remove e.g. "/api/integrations/5"
console.log("Rewrite URL:", path); let replaced = path.replace(new RegExp(`${apiBaseUrl}/integrations/[0-9]+/`), '');
return path.replace(/^\/integrations\/[0-9]+/, ''); console.log("Rewrite URL:", path, replaced);
return replaced;
} }
}); });
@ -52,9 +53,10 @@ export function createIntegrations(knex: Knex) {
changeOrigin: true, changeOrigin: true,
logLevel: 'debug', logLevel: 'debug',
pathRewrite: (path: string, req: any) => { pathRewrite: (path: string, req: any) => {
// Remove e.g. "/integrations/5" // Remove e.g. "/api/integrations/5"
console.log("Rewrite URL:", path); let replaced = path.replace(new RegExp(`${apiBaseUrl}/integrations/[0-9]+/`), '');
return path.replace(/^\/integrations\/[0-9]+/, ''); console.log("Rewrite URL:", path, replaced);
return replaced;
} }
}) })

Loading…
Cancel
Save