mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Change:Series volume numbers to use language sensitive sorting #261
This commit is contained in:
		
							parent
							
								
									49fcaefd01
								
							
						
					
					
						commit
						ef94a6bb29
					
				| @ -15,6 +15,7 @@ const BackupController = require('./controllers/BackupController') | ||||
| 
 | ||||
| const BookFinder = require('./BookFinder') | ||||
| const AuthorFinder = require('./AuthorFinder') | ||||
| const FileSystemController = require('./controllers/FileSystemController') | ||||
| 
 | ||||
| class ApiController { | ||||
|   constructor(MetadataPath, db, auth, streamManager, rssFeeds, downloadManager, coverController, backupManager, watcher, cacheManager, emitter, clientEmitter) { | ||||
| @ -145,6 +146,11 @@ class ApiController { | ||||
|     this.router.get('/search/covers', this.findCovers.bind(this)) | ||||
|     this.router.get('/search/books', this.findBooks.bind(this)) | ||||
| 
 | ||||
|     //
 | ||||
|     // File System Routes
 | ||||
|     //
 | ||||
|     this.router.get('/filesystem', FileSystemController.getPaths.bind(this)) | ||||
| 
 | ||||
|     //
 | ||||
|     // Others
 | ||||
|     //
 | ||||
| @ -163,8 +169,6 @@ class ApiController { | ||||
| 
 | ||||
|     this.router.get('/download/:id', this.download.bind(this)) | ||||
| 
 | ||||
|     this.router.get('/filesystem', this.getFileSystemPaths.bind(this)) | ||||
| 
 | ||||
|     this.router.post('/syncUserAudiobookData', this.syncUserAudiobookData.bind(this)) | ||||
| 
 | ||||
|     this.router.post('/purgecache', this.purgeCache.bind(this)) | ||||
| @ -339,25 +343,6 @@ class ApiController { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   async getFileSystemPaths(req, res) { | ||||
|     var excludedDirs = ['node_modules', 'client', 'server', '.git', 'static', 'build', 'dist', 'metadata', 'config', 'sys', 'proc'].map(dirname => { | ||||
|       return Path.sep + dirname | ||||
|     }) | ||||
| 
 | ||||
|     // Do not include existing mapped library paths in response
 | ||||
|     this.db.libraries.forEach(lib => { | ||||
|       lib.folders.forEach((folder) => { | ||||
|         var dir = folder.fullPath | ||||
|         if (dir.includes(global.appRoot)) dir = dir.replace(global.appRoot, '') | ||||
|         excludedDirs.push(dir) | ||||
|       }) | ||||
|     }) | ||||
| 
 | ||||
|     Logger.debug(`[Server] get file system paths, excluded: ${excludedDirs.join(', ')}`) | ||||
|     var dirs = await this.getDirectories(global.appRoot, '/', excludedDirs) | ||||
|     res.json(dirs) | ||||
|   } | ||||
| 
 | ||||
|   async syncUserAudiobookData(req, res) { | ||||
|     if (!req.body.data) { | ||||
|       return res.status(403).send('Invalid local user audiobook data') | ||||
|  | ||||
							
								
								
									
										25
									
								
								server/controllers/FileSystemController.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								server/controllers/FileSystemController.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| const Logger = require('../Logger') | ||||
| 
 | ||||
| class FileSystemController { | ||||
|   constructor() { } | ||||
| 
 | ||||
|   async getPaths(req, res) { | ||||
|     var excludedDirs = ['node_modules', 'client', 'server', '.git', 'static', 'build', 'dist', 'metadata', 'config', 'sys', 'proc'].map(dirname => { | ||||
|       return Path.sep + dirname | ||||
|     }) | ||||
| 
 | ||||
|     // Do not include existing mapped library paths in response
 | ||||
|     this.db.libraries.forEach(lib => { | ||||
|       lib.folders.forEach((folder) => { | ||||
|         var dir = folder.fullPath | ||||
|         if (dir.includes(global.appRoot)) dir = dir.replace(global.appRoot, '') | ||||
|         excludedDirs.push(dir) | ||||
|       }) | ||||
|     }) | ||||
| 
 | ||||
|     Logger.debug(`[Server] get file system paths, excluded: ${excludedDirs.join(', ')}`) | ||||
|     var dirs = await this.getDirectories(global.appRoot, '/', excludedDirs) | ||||
|     res.json(dirs) | ||||
|   } | ||||
| } | ||||
| module.exports = new FileSystemController() | ||||
| @ -189,12 +189,9 @@ class LibraryController { | ||||
|     if (!audiobooks.length) { | ||||
|       return res.status(404).send('Series not found') | ||||
|     } | ||||
|     audiobooks = sort(audiobooks).asc(ab => { | ||||
|       if (!isNaN(ab.book.volumeNumber) && ab.book.volumeNumber !== null) return Number(ab.book.volumeNumber) | ||||
|       return ab.book.volumeNumber | ||||
|     }) | ||||
|     var sortedBooks = libraryHelpers.sortSeriesBooks(audiobooks, false) | ||||
|     res.json({ | ||||
|       results: audiobooks.map(ab => ab.toJSONExpanded()), | ||||
|       results: sortedBooks, | ||||
|       total: audiobooks.length | ||||
|     }) | ||||
|   } | ||||
|  | ||||
| @ -1,4 +1,7 @@ | ||||
| const { sort } = require('fast-sort') | ||||
| const { sort, createNewSortInstance } = require('fast-sort') | ||||
| const naturalSort = createNewSortInstance({ | ||||
|   comparer: new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare | ||||
| }) | ||||
| 
 | ||||
| module.exports = { | ||||
|   decode(text) { | ||||
| @ -92,14 +95,18 @@ module.exports = { | ||||
|       } | ||||
|     }) | ||||
|     return Object.values(_series).map((series) => { | ||||
|       series.books = sort(series.books).asc(ab => { | ||||
|         if (!isNaN(ab.book.volumeNumber) && ab.book.volumeNumber !== null) return Number(ab.book.volumeNumber) | ||||
|         return ab.book.volumeNumber | ||||
|       }) | ||||
|       series.books = naturalSort(series.books).asc(ab => ab.book.volumeNumber) | ||||
|       return series | ||||
|     }) | ||||
|   }, | ||||
| 
 | ||||
|   sortSeriesBooks(books, minified = false) { | ||||
|     return naturalSort(books).asc(ab => ab.book.volumeNumber).map(ab => { | ||||
|       if (minified) return ab.toJSONMinified() | ||||
|       return ab.toJSONExpanded() | ||||
|     }) | ||||
|   }, | ||||
| 
 | ||||
|   getBooksWithUserAudiobook(user, books) { | ||||
|     return books.map(book => { | ||||
|       return { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user