You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

148 lines
5.8 KiB

import * as api from '../../client/src/api';
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types';
import Knex from 'knex';
export const ModifyAlbumEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => {
if (!api.checkModifyAlbumRequest(req)) {
const e: EndpointError = {
internalMessage: 'Invalid ModifyAlbum request: ' + JSON.stringify(req.body),
httpStatus: 400
};
throw e;
}
const reqObject: api.ModifyAlbumRequest = req.body;
const { id: userId } = req.user;
console.log("User ", userId, ": Modify Album ", reqObject);
await knex.transaction(async (trx) => {
try {
// Start retrieving the album itself.
const albumPromise = trx.select('id')
.from('albums')
.where({ 'user': userId })
.where({ id: req.params.id })
.then((r: any) => (r && r[0]) ? r[0]['id'] : undefined);
// Start retrieving artists.
const artistIdsPromise = reqObject.artistIds ?
trx.select('artistId')
.from('artists_albums')
.whereIn('id', reqObject.artistIds)
.then((as: any) => as.map((a: any) => a['artistId'])) :
(async () => { return undefined })();
// Start retrieving tags.
const tagIdsPromise = reqObject.tagIds ?
trx.select('id')
.from('albums_tags')
.whereIn('id', reqObject.tagIds)
.then((ts: any) => ts.map((t: any) => t['tagId'])) :
(async () => { return undefined })();
// Wait for the requests to finish.
var [album, artists, tags] = await Promise.all([albumPromise, artistIdsPromise, tagIdsPromise]);;
// Check that we found all objects we need.
if ((reqObject.artistIds && artists.length !== reqObject.artistIds.length) ||
(reqObject.tagIds && tags.length !== reqObject.tagIds.length) ||
!album) {
const e: EndpointError = {
internalMessage: 'Not all albums and/or artists and/or tags exist for ModifyAlbum request: ' + JSON.stringify(req.body),
httpStatus: 400
};
throw e;
}
// Modify the album.
var update: any = {};
if ("name" in reqObject) { update["name"] = reqObject.name; }
if ("storeLinks" in reqObject) { update["storeLinks"] = JSON.stringify(reqObject.storeLinks || []); }
const modifyAlbumPromise = trx('albums')
.where({ 'user': userId })
.where({ 'id': req.params.id })
.update(update)
// Remove unlinked artists.
// TODO: test this!
const removeUnlinkedArtists = artists ? trx('artists_albums')
.where({ 'albumId': req.params.id })
.whereNotIn('artistId', reqObject.artistIds || [])
.delete() : undefined;
// Remove unlinked tags.
// TODO: test this!
const removeUnlinkedTags = tags ? trx('albums_tags')
.where({ 'albumId': req.params.id })
.whereNotIn('tagId', reqObject.tagIds || [])
.delete() : undefined;
// Link new artists.
// TODO: test this!
const addArtists = artists ? trx('artists_albums')
.where({ 'albumId': req.params.id })
.then((as: any) => as.map((a: any) => a['artistId']))
.then((doneArtistIds: number[]) => {
// Get the set of artists that are not yet linked
const toLink = artists.filter((id: number) => {
return !doneArtistIds.includes(id);
});
const insertObjects = toLink.map((artistId: number) => {
return {
artistId: artistId,
albumId: req.params.id,
}
})
// Link them
return Promise.all(
insertObjects.map((obj: any) =>
trx('artists_albums').insert(obj)
)
);
}) : undefined;
// Link new tags.
// TODO: test this!
const addTags = tags ? trx('albums_tags')
.where({ 'albumId': req.params.id })
.then((ts: any) => ts.map((t: any) => t['tagId']))
.then((doneTagIds: number[]) => {
// Get the set of tags that are not yet linked
const toLink = tags.filter((id: number) => {
return !doneTagIds.includes(id);
});
const insertObjects = toLink.map((tagId: number) => {
return {
tagId: tagId,
albumId: req.params.id,
}
})
// Link them
return Promise.all(
insertObjects.map((obj: any) =>
trx('albums_tags').insert(obj)
)
);
}) : undefined;
// Wait for all operations to finish.
await Promise.all([
modifyAlbumPromise,
removeUnlinkedArtists,
removeUnlinkedTags,
addArtists,
addTags
]);
// Respond to the request.
res.status(200).send();
} catch (e) {
catchUnhandledErrors(e);
trx.rollback();
}
})
}