mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Update author API endpoints to load library items from DB
This commit is contained in:
		
							parent
							
								
									56e3449db6
								
							
						
					
					
						commit
						345ff1aa66
					
				| @ -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)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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
 | ||||||
|  | |||||||
| @ -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)}` | ||||||
|  | |||||||
| @ -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 | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -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'], | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user