From f15be4c96eec8a5bdd9420f75f1c7bf8d11fab57 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 13 Feb 2022 15:00:59 -0600 Subject: [PATCH] Add:Server setting to ignore "The" infront of titles and series when sorting #361 --- client/components/app/LazyBookshelf.vue | 8 ++-- client/pages/config/index.vue | 57 ++++++++++++++++++++----- server/controllers/LibraryController.js | 20 ++++++++- server/objects/Book.js | 14 ++++++ server/objects/ServerSettings.js | 5 +++ server/utils/prober.js | 9 ++-- 6 files changed, 93 insertions(+), 20 deletions(-) diff --git a/client/components/app/LazyBookshelf.vue b/client/components/app/LazyBookshelf.vue index e9e75f37..e99fbbc7 100644 --- a/client/components/app/LazyBookshelf.vue +++ b/client/components/app/LazyBookshelf.vue @@ -4,7 +4,7 @@
+
-->
@@ -26,7 +26,9 @@
-

Texture

+
+

Texture

+
@@ -245,7 +247,7 @@ export default { console.error('failed to fetch books', error) return null }) - console.log('payload', payload) + this.isFetchingEntities = false if (this.pendingReset) { this.pendingReset = false diff --git a/client/pages/config/index.vue b/client/pages/config/index.vue index a09fb046..6f1d5e9a 100644 --- a/client/pages/config/index.vue +++ b/client/pages/config/index.vue @@ -10,24 +10,38 @@
-

Store covers with audiobook info_outlined

+

+ Store covers with audiobook + info_outlined +

-

Use square book covers info_outlined

+

+ Use square book covers + info_outlined +

-

Use alternative library bookshelf view info_outlined

+

+ Use alternative library bookshelf view + info_outlined +

+
+ +

Ignore prefix "The" when sorting title and series

+
+

Scanner Settings

@@ -35,14 +49,20 @@
-

Scanner parse subtitles info_outlined

+

+ Scanner parse subtitles + info_outlined +

-

Scanner find covers info_outlined

+

+ Scanner find covers + info_outlined +

@@ -53,14 +73,20 @@
-

Scanner prefer audio metadata info_outlined

+

+ Scanner prefer audio metadata + info_outlined +

-

Scanner prefer OPF metadata info_outlined

+

+ Scanner prefer OPF metadata + info_outlined +

@@ -71,7 +97,10 @@
-

Report bugs, request features, provide feedback, and contribute on github.

+

+ Report bugs, request features, provide feedback, and contribute on + github. +

-

Experimental Features info_outlined

+

+ Experimental Features + info_outlined +

+ --> @@ -166,6 +198,11 @@ export default { } }, methods: { + updateSortIgnorePrefix(val) { + this.updateServerSettings({ + sortingIgnorePrefix: val + }) + }, updateScannerFindCovers(val) { this.updateServerSettings({ scannerFindCovers: !!val diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index baf9c1bb..771b1960 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -144,10 +144,19 @@ class LibraryController { } if (payload.sortBy) { + var sortKey = payload.sortBy + + // Handle server setting sortingIgnorePrefix + if ((sortKey === 'book.series' || sortKey === 'book.title') && this.db.serverSettings.sortingIgnorePrefix) { + // Book.js has seriesIgnorePrefix and titleIgnorePrefix getters + sortKey += 'IgnorePrefix' + } + var direction = payload.sortDesc ? 'desc' : 'asc' audiobooks = naturalSort(audiobooks)[direction]((ab) => { + // Supports dot notation strings i.e. "book.title" - return payload.sortBy.split('.').reduce((a, b) => a[b], ab) + return sortKey.split('.').reduce((a, b) => a[b], ab) }) } @@ -202,7 +211,14 @@ class LibraryController { } var series = libraryHelpers.getSeriesFromBooks(audiobooks, payload.minified) - series = sort(series).asc(s => s.name) + + var sortingIgnorePrefix = this.db.serverSettings.sortingIgnorePrefix + series = sort(series).asc(s => { + if (sortingIgnorePrefix && s.name.toLowerCase().startsWith('the')) { + return s.name.substr(4) + } + return s.name + }) payload.total = series.length if (payload.limit) { diff --git a/server/objects/Book.js b/server/objects/Book.js index 6023feea..f932cc17 100644 --- a/server/objects/Book.js +++ b/server/objects/Book.js @@ -49,6 +49,20 @@ class Book { get _asin() { return this.asin || '' } get genresCommaSeparated() { return this._genres.join(', ') } + get titleIgnorePrefix() { + if (this._title.toLowerCase().startsWith('the ')) { + return this._title.substr(4) + ', The' + } + return this._title + } + + get seriesIgnorePrefix() { + if (this._series.toLowerCase().startsWith('the ')) { + return this._series.substr(4) + ', The' + } + return this._series + } + get shouldSearchForCover() { if (this.cover) return false if (this.authorFL !== this.lastCoverSearchAuthor || this.title !== this.lastCoverSearchTitle || !this.lastCoverSearch) return true diff --git a/server/objects/ServerSettings.js b/server/objects/ServerSettings.js index 371a58e1..8df6fdcd 100644 --- a/server/objects/ServerSettings.js +++ b/server/objects/ServerSettings.js @@ -38,6 +38,8 @@ class ServerSettings { this.coverAspectRatio = BookCoverAspectRatio.SQUARE this.bookshelfView = BookshelfView.STANDARD + this.sortingIgnorePrefix = false + this.logLevel = Logger.logLevel this.version = null @@ -70,6 +72,8 @@ class ServerSettings { this.coverAspectRatio = !isNaN(settings.coverAspectRatio) ? settings.coverAspectRatio : BookCoverAspectRatio.SQUARE this.bookshelfView = settings.bookshelfView || BookshelfView.STANDARD + this.sortingIgnorePrefix = !!settings.sortingIgnorePrefix + this.logLevel = settings.logLevel || Logger.logLevel this.version = settings.version || null @@ -99,6 +103,7 @@ class ServerSettings { loggerScannerLogsToKeep: this.loggerScannerLogsToKeep, coverAspectRatio: this.coverAspectRatio, bookshelfView: this.bookshelfView, + sortingIgnorePrefix: this.sortingIgnorePrefix, logLevel: this.logLevel, version: this.version } diff --git a/server/utils/prober.js b/server/utils/prober.js index bc8623e1..a8053a5d 100644 --- a/server/utils/prober.js +++ b/server/utils/prober.js @@ -1,9 +1,4 @@ const ffprobe = require('node-ffprobe') - -if (process.env.FFPROBE_PATH) { - ffprobe.FFPROBE_PATH = process.env.FFPROBE_PATH -} - const AudioProbeData = require('../scanner/AudioProbeData') const Logger = require('../Logger') @@ -281,6 +276,10 @@ function parseProbeData(data, verbose = false) { // Updated probe returns AudioProbeData object function probe(filepath, verbose = false) { + if (process.env.FFPROBE_PATH) { + ffprobe.FFPROBE_PATH = process.env.FFPROBE_PATH + } + return ffprobe(filepath) .then(raw => { var rawProbeData = parseProbeData(raw, verbose)