mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Merge pull request #3584 from mikiher/author-image-performance
Improve author image performance
This commit is contained in:
		
						commit
						978c2b05f2
					
				| @ -56,7 +56,7 @@ export default { | ||||
|     }, | ||||
|     imgSrc() { | ||||
|       if (!this.imagePath) return null | ||||
|       return `${this.$config.routerBasePath}/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}` | ||||
|       return `${this.$config.routerBasePath}/api/authors/${this.authorId}/image?ts=${this.updatedAt}` | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|  | ||||
| @ -18,7 +18,7 @@ class Auth { | ||||
|   constructor() { | ||||
|     // Map of openId sessions indexed by oauth2 state-variable
 | ||||
|     this.openIdAuthSession = new Map() | ||||
|     this.ignorePattern = /\/api\/items\/[^/]+\/cover/ | ||||
|     this.ignorePatterns = [/\/api\/items\/[^/]+\/cover/, /\/api\/authors\/[^/]+\/image/] | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -28,7 +28,7 @@ class Auth { | ||||
|    * @private | ||||
|    */ | ||||
|   authNotNeeded(req) { | ||||
|     return req.method === 'GET' && this.ignorePattern.test(req.originalUrl) | ||||
|     return req.method === 'GET' && this.ignorePatterns.some((pattern) => pattern.test(req.originalUrl)) | ||||
|   } | ||||
| 
 | ||||
|   ifAuthNeeded(middleware) { | ||||
|  | ||||
| @ -381,16 +381,23 @@ class AuthorController { | ||||
|    */ | ||||
|   async getImage(req, res) { | ||||
|     const { | ||||
|       query: { width, height, format, raw }, | ||||
|       author | ||||
|       query: { width, height, format, raw } | ||||
|     } = req | ||||
| 
 | ||||
|     if (!author.imagePath || !(await fs.pathExists(author.imagePath))) { | ||||
|       Logger.warn(`[AuthorController] Author "${author.name}" has invalid imagePath: ${author.imagePath}`) | ||||
|       return res.sendStatus(404) | ||||
|     } | ||||
|     const authorId = req.params.id | ||||
| 
 | ||||
|     if (raw) { | ||||
|       const author = await Database.authorModel.findByPk(authorId) | ||||
|       if (!author) { | ||||
|         Logger.warn(`[AuthorController] Author "${authorId}" not found`) | ||||
|         return res.sendStatus(404) | ||||
|       } | ||||
| 
 | ||||
|       if (!author.imagePath || !(await fs.pathExists(author.imagePath))) { | ||||
|         Logger.warn(`[AuthorController] Author "${author.name}" has invalid imagePath: ${author.imagePath}`) | ||||
|         return res.sendStatus(404) | ||||
|       } | ||||
| 
 | ||||
|       return res.sendFile(author.imagePath) | ||||
|     } | ||||
| 
 | ||||
| @ -399,7 +406,7 @@ class AuthorController { | ||||
|       height: height ? parseInt(height) : null, | ||||
|       width: width ? parseInt(width) : null | ||||
|     } | ||||
|     return CacheManager.handleAuthorCache(res, author, options) | ||||
|     return CacheManager.handleAuthorCache(res, authorId, options) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|  | ||||
| @ -134,22 +134,22 @@ class CacheManager { | ||||
|   /** | ||||
|    * | ||||
|    * @param {import('express').Response} res | ||||
|    * @param {import('../models/Author')} author | ||||
|    * @param {String} authorId | ||||
|    * @param {{ format?: string, width?: number, height?: number }} options | ||||
|    * @returns | ||||
|    */ | ||||
|   async handleAuthorCache(res, author, options = {}) { | ||||
|   async handleAuthorCache(res, authorId, options = {}) { | ||||
|     const format = options.format || 'webp' | ||||
|     const width = options.width || 400 | ||||
|     const height = options.height || null | ||||
| 
 | ||||
|     res.type(`image/${format}`) | ||||
| 
 | ||||
|     var path = Path.join(this.ImageCachePath, `${author.id}_${width}${height ? `x${height}` : ''}`) + '.' + format | ||||
|     var cachePath = Path.join(this.ImageCachePath, `${authorId}_${width}${height ? `x${height}` : ''}`) + '.' + format | ||||
| 
 | ||||
|     // Cache exists
 | ||||
|     if (await fs.pathExists(path)) { | ||||
|       const r = fs.createReadStream(path) | ||||
|     if (await fs.pathExists(cachePath)) { | ||||
|       const r = fs.createReadStream(cachePath) | ||||
|       const ps = new stream.PassThrough() | ||||
|       stream.pipeline(r, ps, (err) => { | ||||
|         if (err) { | ||||
| @ -160,7 +160,12 @@ class CacheManager { | ||||
|       return ps.pipe(res) | ||||
|     } | ||||
| 
 | ||||
|     let writtenFile = await resizeImage(author.imagePath, path, width, height) | ||||
|     const author = await Database.authorModel.findByPk(authorId) | ||||
|     if (!author || !author.imagePath || !(await fs.pathExists(author.imagePath))) { | ||||
|       return res.sendStatus(404) | ||||
|     } | ||||
| 
 | ||||
|     let writtenFile = await resizeImage(author.imagePath, cachePath, width, height) | ||||
|     if (!writtenFile) return res.sendStatus(500) | ||||
| 
 | ||||
|     var readStream = fs.createReadStream(writtenFile) | ||||
|  | ||||
| @ -216,7 +216,7 @@ class ApiRouter { | ||||
|     this.router.patch('/authors/:id', AuthorController.middleware.bind(this), AuthorController.update.bind(this)) | ||||
|     this.router.delete('/authors/:id', AuthorController.middleware.bind(this), AuthorController.delete.bind(this)) | ||||
|     this.router.post('/authors/:id/match', AuthorController.middleware.bind(this), AuthorController.match.bind(this)) | ||||
|     this.router.get('/authors/:id/image', AuthorController.middleware.bind(this), AuthorController.getImage.bind(this)) | ||||
|     this.router.get('/authors/:id/image', AuthorController.getImage.bind(this)) | ||||
|     this.router.post('/authors/:id/image', AuthorController.middleware.bind(this), AuthorController.uploadImage.bind(this)) | ||||
|     this.router.delete('/authors/:id/image', AuthorController.middleware.bind(this), AuthorController.deleteImage.bind(this)) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user