mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-29 09:19:07 +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 BookFinder = require('./BookFinder')
|
||||||
const AuthorFinder = require('./AuthorFinder')
|
const AuthorFinder = require('./AuthorFinder')
|
||||||
|
const FileSystemController = require('./controllers/FileSystemController')
|
||||||
|
|
||||||
class ApiController {
|
class ApiController {
|
||||||
constructor(MetadataPath, db, auth, streamManager, rssFeeds, downloadManager, coverController, backupManager, watcher, cacheManager, emitter, clientEmitter) {
|
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/covers', this.findCovers.bind(this))
|
||||||
this.router.get('/search/books', this.findBooks.bind(this))
|
this.router.get('/search/books', this.findBooks.bind(this))
|
||||||
|
|
||||||
|
//
|
||||||
|
// File System Routes
|
||||||
|
//
|
||||||
|
this.router.get('/filesystem', FileSystemController.getPaths.bind(this))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Others
|
// Others
|
||||||
//
|
//
|
||||||
@ -163,8 +169,6 @@ class ApiController {
|
|||||||
|
|
||||||
this.router.get('/download/:id', this.download.bind(this))
|
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('/syncUserAudiobookData', this.syncUserAudiobookData.bind(this))
|
||||||
|
|
||||||
this.router.post('/purgecache', this.purgeCache.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) {
|
async syncUserAudiobookData(req, res) {
|
||||||
if (!req.body.data) {
|
if (!req.body.data) {
|
||||||
return res.status(403).send('Invalid local user audiobook 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) {
|
if (!audiobooks.length) {
|
||||||
return res.status(404).send('Series not found')
|
return res.status(404).send('Series not found')
|
||||||
}
|
}
|
||||||
audiobooks = sort(audiobooks).asc(ab => {
|
var sortedBooks = libraryHelpers.sortSeriesBooks(audiobooks, false)
|
||||||
if (!isNaN(ab.book.volumeNumber) && ab.book.volumeNumber !== null) return Number(ab.book.volumeNumber)
|
|
||||||
return ab.book.volumeNumber
|
|
||||||
})
|
|
||||||
res.json({
|
res.json({
|
||||||
results: audiobooks.map(ab => ab.toJSONExpanded()),
|
results: sortedBooks,
|
||||||
total: audiobooks.length
|
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 = {
|
module.exports = {
|
||||||
decode(text) {
|
decode(text) {
|
||||||
@ -92,14 +95,18 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return Object.values(_series).map((series) => {
|
return Object.values(_series).map((series) => {
|
||||||
series.books = sort(series.books).asc(ab => {
|
series.books = naturalSort(series.books).asc(ab => ab.book.volumeNumber)
|
||||||
if (!isNaN(ab.book.volumeNumber) && ab.book.volumeNumber !== null) return Number(ab.book.volumeNumber)
|
|
||||||
return ab.book.volumeNumber
|
|
||||||
})
|
|
||||||
return series
|
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) {
|
getBooksWithUserAudiobook(user, books) {
|
||||||
return books.map(book => {
|
return books.map(book => {
|
||||||
return {
|
return {
|
||||||
|
Loading…
Reference in New Issue
Block a user