From eb109c398f1eac9bad20b5f6cdc1621016148c9e Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 27 Feb 2022 12:47:56 -0600 Subject: [PATCH] Change:Server setting for coverDestination to storeCoverWithBook boolean, Add:abmetadata generator --- client/pages/config.vue | 10 ---------- client/pages/config/index.vue | 15 +++------------ client/plugins/constants.js | 6 ------ server/CoverController.js | 3 +-- server/objects/ServerSettings.js | 18 +++++++++++------- server/scanner/ScanOptions.js | 8 +++----- server/scanner/Scanner.js | 6 +++--- ...FileGenerator.js => abmetadataGenerator.js} | 13 ++++++++++++- server/utils/constants.js | 5 ----- 9 files changed, 33 insertions(+), 51 deletions(-) rename server/utils/{absFileGenerator.js => abmetadataGenerator.js} (71%) diff --git a/client/pages/config.vue b/client/pages/config.vue index db2c48ec..a033cc02 100644 --- a/client/pages/config.vue +++ b/client/pages/config.vue @@ -57,16 +57,6 @@ export default { this.$store.commit('setDeveloperMode', value) this.$toast.info(`Developer Mode ${value ? 'Enabled' : 'Disabled'}`) } - // saveMetadataComplete(result) { - // this.savingMetadata = false - // if (!result) return - // this.$toast.success(`Metadata saved for ${result.success} audiobooks`) - // }, - // saveMetadataFiles() { - // this.savingMetadata = true - // this.$root.socket.once('save_metadata_complete', this.saveMetadataComplete) - // this.$root.socket.emit('save_metadata') - // } }, mounted() {} } diff --git a/client/pages/config/index.vue b/client/pages/config/index.vue index 822f0978..9f09e750 100644 --- a/client/pages/config/index.vue +++ b/client/pages/config/index.vue @@ -8,8 +8,8 @@
- - + +

Store covers with audiobook info_outlined @@ -172,7 +172,6 @@ export default { data() { return { isResettingAudiobooks: false, - storeCoversInAudiobookDir: false, updatingServerSettings: false, useSquareBookCovers: false, useAlternativeBookshelfView: false, @@ -185,7 +184,7 @@ export default { scannerParseSubtitle: 'Extract subtitles from audiobook directory names.
Subtitle must be seperated by " - "
i.e. "Book Title - A Subtitle Here" has the subtitle "A Subtitle Here"', scannerFindCovers: 'If your audiobook does not have an embedded cover or a cover image inside the folder, the scanner will attempt to find a cover.
Note: This will extend scan time', bookshelfView: 'Alternative bookshelf view that shows title & author under book covers', - coverDestination: 'By default covers are stored in /metadata/books, enabling this setting will store covers inside your audiobooks directory. Only one file named "cover" will be kept.', + storeCoverWithBook: 'By default covers are stored in /metadata/books, enabling this setting will store covers inside your audiobooks directory. Only one file named "cover" will be kept.', coverAspectRatio: 'Prefer to use square covers over standard 1.6:1 book covers' } } @@ -226,12 +225,6 @@ export default { scannerCoverProvider: val }) }, - updateCoverStorageDestination(val) { - this.newServerSettings.coverDestination = val ? this.$constants.CoverDestination.AUDIOBOOK : this.$constants.CoverDestination.METADATA - this.updateServerSettings({ - coverDestination: this.newServerSettings.coverDestination - }) - }, updateBookCoverAspectRatio(val) { this.updateServerSettings({ coverAspectRatio: val ? this.$constants.BookCoverAspectRatio.SQUARE : this.$constants.BookCoverAspectRatio.STANDARD @@ -263,8 +256,6 @@ export default { initServerSettings() { this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {} - this.storeCoversInAudiobookDir = this.newServerSettings.coverDestination === this.$constants.CoverDestination.AUDIOBOOK - this.useSquareBookCovers = this.newServerSettings.coverAspectRatio === this.$constants.BookCoverAspectRatio.SQUARE this.useAlternativeBookshelfView = this.newServerSettings.bookshelfView === this.$constants.BookshelfView.TITLES diff --git a/client/plugins/constants.js b/client/plugins/constants.js index 4ac7a662..83122781 100644 --- a/client/plugins/constants.js +++ b/client/plugins/constants.js @@ -14,11 +14,6 @@ const DownloadStatus = { FAILED: 3 } -const CoverDestination = { - METADATA: 0, - AUDIOBOOK: 1 -} - const BookCoverAspectRatio = { STANDARD: 0, SQUARE: 1 @@ -32,7 +27,6 @@ const BookshelfView = { const Constants = { SupportedFileTypes, DownloadStatus, - CoverDestination, BookCoverAspectRatio, BookshelfView } diff --git a/server/CoverController.js b/server/CoverController.js index 18d81a8f..187b5a10 100644 --- a/server/CoverController.js +++ b/server/CoverController.js @@ -6,7 +6,6 @@ const readChunk = require('read-chunk') const imageType = require('image-type') const globals = require('./utils/globals') -const { CoverDestination } = require('./utils/constants') const { downloadFile } = require('./utils/fileUtils') class CoverController { @@ -20,7 +19,7 @@ class CoverController { } getCoverDirectory(audiobook) { - if (this.db.serverSettings.coverDestination === CoverDestination.AUDIOBOOK) { + if (this.db.serverSettings.storeCoverWithBook) { return { fullPath: audiobook.fullPath, relPath: '/s/book/' + audiobook.id diff --git a/server/objects/ServerSettings.js b/server/objects/ServerSettings.js index 64987909..09e3eb7f 100644 --- a/server/objects/ServerSettings.js +++ b/server/objects/ServerSettings.js @@ -1,4 +1,4 @@ -const { CoverDestination, BookCoverAspectRatio, BookshelfView } = require('../utils/constants') +const { BookCoverAspectRatio, BookshelfView } = require('../utils/constants') const Logger = require('../Logger') class ServerSettings { @@ -18,8 +18,8 @@ class ServerSettings { this.scannerDisableWatcher = false // Metadata - this.coverDestination = CoverDestination.METADATA - this.saveMetadataFile = false + this.storeCoverWithBook = false + this.storeMetadataWithBook = false // Security/Rate limits this.rateLimitLoginRequests = 10 @@ -59,8 +59,12 @@ class ServerSettings { this.scannerPreferOpfMetadata = !!settings.scannerPreferOpfMetadata this.scannerDisableWatcher = !!settings.scannerDisableWatcher - this.coverDestination = settings.coverDestination || CoverDestination.METADATA - this.saveMetadataFile = !!settings.saveMetadataFile + this.storeCoverWithBook = settings.storeCoverWithBook + if (this.storeCoverWithBook == undefined) { // storeCoverWithBook added in 1.7.1 to replace coverDestination + this.storeCoverWithBook = !!settings.coverDestination + } + this.storeMetadataWithBook = !!settings.storeCoverWithBook + this.rateLimitLoginRequests = !isNaN(settings.rateLimitLoginRequests) ? Number(settings.rateLimitLoginRequests) : 10 this.rateLimitLoginWindow = !isNaN(settings.rateLimitLoginWindow) ? Number(settings.rateLimitLoginWindow) : 10 * 60 * 1000 // 10 Minutes @@ -95,8 +99,8 @@ class ServerSettings { scannerPreferAudioMetadata: this.scannerPreferAudioMetadata, scannerPreferOpfMetadata: this.scannerPreferOpfMetadata, scannerDisableWatcher: this.scannerDisableWatcher, - coverDestination: this.coverDestination, - saveMetadataFile: !!this.saveMetadataFile, + storeCoverWithBook: this.storeCoverWithBook, + storeMetadataWithBook: this.storeMetadataWithBook, rateLimitLoginRequests: this.rateLimitLoginRequests, rateLimitLoginWindow: this.rateLimitLoginWindow, backupSchedule: this.backupSchedule, diff --git a/server/scanner/ScanOptions.js b/server/scanner/ScanOptions.js index 40b09fbb..f4543613 100644 --- a/server/scanner/ScanOptions.js +++ b/server/scanner/ScanOptions.js @@ -1,5 +1,3 @@ -const { CoverDestination } = require('../utils/constants') - class ScanOptions { constructor(options) { this.forceRescan = false @@ -7,7 +5,7 @@ class ScanOptions { // Server settings this.parseSubtitles = false this.findCovers = false - this.coverDestination = CoverDestination.METADATA + this.storeCoverWithBook = false this.preferAudioMetadata = false this.preferOpfMetadata = false @@ -32,7 +30,7 @@ class ScanOptions { metadataPrecedence: this.metadataPrecedence, parseSubtitles: this.parseSubtitles, findCovers: this.findCovers, - coverDestination: this.coverDestination, + storeCoverWithBook: this.storeCoverWithBook, preferAudioMetadata: this.preferAudioMetadata, preferOpfMetadata: this.preferOpfMetadata } @@ -43,7 +41,7 @@ class ScanOptions { this.parseSubtitles = !!serverSettings.scannerParseSubtitle this.findCovers = !!serverSettings.scannerFindCovers - this.coverDestination = serverSettings.coverDestination + this.storeCoverWithBook = serverSettings.storeCoverWithBook this.preferAudioMetadata = serverSettings.scannerPreferAudioMetadata this.preferOpfMetadata = serverSettings.scannerPreferOpfMetadata } diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index 627def2c..cf3ee485 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -5,8 +5,8 @@ const Path = require('path') const Logger = require('../Logger') const { version } = require('../../package.json') const { groupFilesIntoAudiobookPaths, getAudiobookFileData, scanRootDir } = require('../utils/scandir') -const { comparePaths, getIno, getId, msToTimestamp } = require('../utils/index') -const { ScanResult, CoverDestination, LogLevel } = require('../utils/constants') +const { comparePaths, getId } = require('../utils/index') +const { ScanResult, LogLevel } = require('../utils/constants') const AudioFileScanner = require('./AudioFileScanner') const BookFinder = require('../BookFinder') @@ -33,7 +33,7 @@ class Scanner { } getCoverDirectory(audiobook) { - if (this.db.serverSettings.coverDestination === CoverDestination.AUDIOBOOK) { + if (this.db.serverSettings.storeCoverWithBook) { return { fullPath: audiobook.fullPath, relPath: '/s/book/' + audiobook.id diff --git a/server/utils/absFileGenerator.js b/server/utils/abmetadataGenerator.js similarity index 71% rename from server/utils/absFileGenerator.js rename to server/utils/abmetadataGenerator.js index a74d78e2..668b7eee 100644 --- a/server/utils/absFileGenerator.js +++ b/server/utils/abmetadataGenerator.js @@ -20,13 +20,24 @@ const bookKeyMap = { } function generate(audiobook, outputPath, uid, gid) { - var fileString = `[audiobookshelf v${package.version}]\n` + var fileString = ';ABMETADATA1\n' + fileString += `#audiobookshelf v${package.version}\n\n` for (const key in bookKeyMap) { const value = audiobook.book[bookKeyMap[key]] || '' fileString += `${key}=${value}\n` } + if (audiobook.chapters.length) { + fileString += '\n' + audiobook.chapters.forEach((chapter) => { + fileString += `[CHAPTER]\n` + fileString += `start=${chapter.start}\n` + fileString += `end=${chapter.end}\n` + fileString += `title=${chapter.title}\n` + }) + } + return fs.writeFile(outputPath, fileString).then(() => { return filePerms(outputPath, 0o774, uid, gid).then(() => true) }).catch((error) => { diff --git a/server/utils/constants.js b/server/utils/constants.js index 7d0e094d..a114794d 100644 --- a/server/utils/constants.js +++ b/server/utils/constants.js @@ -6,11 +6,6 @@ module.exports.ScanResult = { UPTODATE: 4 } -module.exports.CoverDestination = { - METADATA: 0, - AUDIOBOOK: 1 -} - module.exports.BookCoverAspectRatio = { STANDARD: 0, // 1.6:1 SQUARE: 1