Update author API endpoints to load library items from DB

This commit is contained in:
advplyr 2023-08-06 15:06:45 -05:00
parent 56e3449db6
commit 345ff1aa66
5 changed files with 80 additions and 22 deletions

View File

@ -15,18 +15,13 @@ class AuthorController {
constructor() { } constructor() { }
async findOne(req, res) { async findOne(req, res) {
const libraryId = req.query.library
const include = (req.query.include || '').split(',') const include = (req.query.include || '').split(',')
const authorJson = req.author.toJSON() const authorJson = req.author.toJSON()
// Used on author landing page to include library items and items grouped in series // Used on author landing page to include library items and items grouped in series
if (include.includes('items')) { if (include.includes('items')) {
authorJson.libraryItems = Database.libraryItems.filter(li => { authorJson.libraryItems = await Database.models.libraryItem.getForAuthor(req.author, req.user)
if (libraryId && li.libraryId !== libraryId) return false
if (!req.user.checkCanAccessLibraryItem(li)) return false // filter out library items user cannot access
return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(req.author.id)
})
if (include.includes('series')) { if (include.includes('series')) {
const seriesMap = {} const seriesMap = {}
@ -101,7 +96,7 @@ class AuthorController {
const existingAuthor = authorNameUpdate ? Database.authors.find(au => au.id !== req.author.id && payload.name === au.name) : false const existingAuthor = authorNameUpdate ? Database.authors.find(au => au.id !== req.author.id && payload.name === au.name) : false
if (existingAuthor) { if (existingAuthor) {
const bookAuthorsToCreate = [] const bookAuthorsToCreate = []
const itemsWithAuthor = Database.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasAuthor(req.author.id)) const itemsWithAuthor = await Database.models.libraryItem.getForAuthor(req.author)
itemsWithAuthor.forEach(libraryItem => { // Replace old author with merging author for each book itemsWithAuthor.forEach(libraryItem => { // Replace old author with merging author for each book
libraryItem.media.metadata.replaceAuthor(req.author, existingAuthor) libraryItem.media.metadata.replaceAuthor(req.author, existingAuthor)
bookAuthorsToCreate.push({ bookAuthorsToCreate.push({
@ -120,9 +115,7 @@ class AuthorController {
SocketAuthority.emitter('author_removed', req.author.toJSON()) SocketAuthority.emitter('author_removed', req.author.toJSON())
// Send updated num books for merged author // Send updated num books for merged author
const numBooks = Database.libraryItems.filter(li => { const numBooks = await Database.models.libraryItem.getForAuthor(existingAuthor).length
return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(existingAuthor.id)
}).length
SocketAuthority.emitter('author_updated', existingAuthor.toJSONExpanded(numBooks)) SocketAuthority.emitter('author_updated', existingAuthor.toJSONExpanded(numBooks))
res.json({ res.json({
@ -137,8 +130,8 @@ class AuthorController {
if (hasUpdated) { if (hasUpdated) {
req.author.updatedAt = Date.now() req.author.updatedAt = Date.now()
const itemsWithAuthor = await Database.models.libraryItem.getForAuthor(req.author)
if (authorNameUpdate) { // Update author name on all books if (authorNameUpdate) { // Update author name on all books
const itemsWithAuthor = Database.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasAuthor(req.author.id))
itemsWithAuthor.forEach(libraryItem => { itemsWithAuthor.forEach(libraryItem => {
libraryItem.media.metadata.updateAuthor(req.author) libraryItem.media.metadata.updateAuthor(req.author)
}) })
@ -148,10 +141,7 @@ class AuthorController {
} }
await Database.updateAuthor(req.author) await Database.updateAuthor(req.author)
const numBooks = Database.libraryItems.filter(li => { SocketAuthority.emitter('author_updated', req.author.toJSONExpanded(itemsWithAuthor.length))
return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(req.author.id)
}).length
SocketAuthority.emitter('author_updated', req.author.toJSONExpanded(numBooks))
} }
res.json({ res.json({
@ -211,9 +201,8 @@ class AuthorController {
req.author.updatedAt = Date.now() req.author.updatedAt = Date.now()
await Database.updateAuthor(req.author) await Database.updateAuthor(req.author)
const numBooks = Database.libraryItems.filter(li => {
return li.media.metadata.hasAuthor && li.media.metadata.hasAuthor(req.author.id) const numBooks = await Database.models.libraryItem.getForAuthor(req.author).length
}).length
SocketAuthority.emitter('author_updated', req.author.toJSONExpanded(numBooks)) SocketAuthority.emitter('author_updated', req.author.toJSONExpanded(numBooks))
} }

View File

@ -679,8 +679,8 @@ class LibraryItemController {
res.sendStatus(200) res.sendStatus(200)
} }
middleware(req, res, next) { async middleware(req, res, next) {
req.libraryItem = Database.libraryItems.find(li => li.id === req.params.id) req.libraryItem = await Database.models.libraryItem.getOldById(req.params.id)
if (!req.libraryItem?.media) return res.sendStatus(404) if (!req.libraryItem?.media) return res.sendStatus(404)
// Check user can access this library item // Check user can access this library item

View File

@ -400,6 +400,46 @@ module.exports = (sequelize) => {
}) })
} }
/**
* Get old library item by id
* @param {string} libraryItemId
* @returns {oldLibraryItem}
*/
static async getOldById(libraryItemId) {
if (!libraryItemId) return null
const libraryItem = await this.findByPk(libraryItemId, {
include: [
{
model: sequelize.models.book,
include: [
{
model: sequelize.models.author,
through: {
attributes: []
}
},
{
model: sequelize.models.series,
through: {
attributes: ['sequence']
}
}
]
},
{
model: sequelize.models.podcast,
include: [
{
model: sequelize.models.podcastEpisode
}
]
}
]
})
if (!libraryItem) return null
return this.getOldLibraryItem(libraryItem)
}
/** /**
* Get library items using filter and sort * Get library items using filter and sort
* @param {oldLibrary} library * @param {oldLibrary} library
@ -609,6 +649,17 @@ module.exports = (sequelize) => {
return shelves return shelves
} }
/**
* Get book library items for author, optional use user permissions
* @param {oldAuthor} author
* @param {[oldUser]} user
* @returns {oldLibraryItem[]}
*/
static async getForAuthor(author, user = null) {
const { libraryItems } = await libraryFilters.getLibraryItemsForAuthor(author, user, undefined, undefined)
return libraryItems.map(li => this.getOldLibraryItem(li))
}
getMedia(options) { getMedia(options) {
if (!this.mediaType) return Promise.resolve(null) if (!this.mediaType) return Promise.resolve(null)
const mixinMethodName = `get${sequelize.uppercaseFirst(this.mediaType)}` const mixinMethodName = `get${sequelize.uppercaseFirst(this.mediaType)}`

View File

@ -357,5 +357,21 @@ module.exports = {
return oldLibraryItem return oldLibraryItem
}) })
} }
},
/**
* Get library items for an author, optional use user permissions
* @param {oldAuthor} author
* @param {[oldUser]} user
* @param {number} limit
* @param {number} offset
* @returns {object} { libraryItems:LibraryItem[], count:number }
*/
async getLibraryItemsForAuthor(author, user, limit, offset) {
const { libraryItems, count } = await libraryItemsBookFilters.getFilteredLibraryItems(author.libraryId, user, 'authors', author.id, 'addedAt', true, false, [], limit, offset)
return {
count,
libraryItems
}
} }
} }

View File

@ -11,6 +11,8 @@ module.exports = {
getUserPermissionBookWhereQuery(user) { getUserPermissionBookWhereQuery(user) {
const bookWhere = [] const bookWhere = []
const replacements = {} const replacements = {}
if (!user) return { bookWhere, replacements }
if (!user.canAccessExplicitContent) { if (!user.canAccessExplicitContent) {
bookWhere.push({ bookWhere.push({
explicit: false explicit: false
@ -325,7 +327,7 @@ module.exports = {
/** /**
* Get library items for book media type using filter and sort * Get library items for book media type using filter and sort
* @param {string} libraryId * @param {string} libraryId
* @param {oldUser} user * @param {[oldUser]} user
* @param {[string]} filterGroup * @param {[string]} filterGroup
* @param {[string]} filterValue * @param {[string]} filterValue
* @param {string} sortBy * @param {string} sortBy
@ -467,7 +469,7 @@ module.exports = {
isInvalid: true isInvalid: true
} }
] ]
} else if (filterGroup === 'progress') { } else if (filterGroup === 'progress' && user) {
bookIncludes.push({ bookIncludes.push({
model: Database.models.mediaProgress, model: Database.models.mediaProgress,
attributes: ['id', 'isFinished', 'currentTime', 'ebookProgress', 'updatedAt'], attributes: ['id', 'isFinished', 'currentTime', 'ebookProgress', 'updatedAt'],