Add:Server setting to disable folder watcher #378

This commit is contained in:
advplyr 2022-02-23 17:52:21 -06:00
parent 1a89b6e493
commit 7f1fc1901b
4 changed files with 47 additions and 58 deletions

View File

@ -9,7 +9,7 @@
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="storeCoversInAudiobookDir" :disabled="updatingServerSettings" @input="updateCoverStorageDestination" /> <ui-toggle-switch v-model="storeCoversInAudiobookDir" :disabled="updatingServerSettings" @input="updateCoverStorageDestination" />
<ui-tooltip :text="coverDestinationTooltip"> <ui-tooltip :text="tooltips.coverDestination">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Store covers with audiobook Store covers with audiobook
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
@ -19,7 +19,7 @@
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="useSquareBookCovers" :disabled="updatingServerSettings" @input="updateBookCoverAspectRatio" /> <ui-toggle-switch v-model="useSquareBookCovers" :disabled="updatingServerSettings" @input="updateBookCoverAspectRatio" />
<ui-tooltip :text="coverAspectRatioTooltip"> <ui-tooltip :text="tooltips.coverAspectRatio">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Use square book covers Use square book covers
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
@ -29,7 +29,7 @@
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="useAlternativeBookshelfView" :disabled="updatingServerSettings" @input="updateAlternativeBookshelfView" /> <ui-toggle-switch v-model="useAlternativeBookshelfView" :disabled="updatingServerSettings" @input="updateAlternativeBookshelfView" />
<ui-tooltip :text="bookshelfViewTooltip"> <ui-tooltip :text="tooltips.bookshelfView">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Use alternative library bookshelf view Use alternative library bookshelf view
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
@ -52,8 +52,8 @@
</div> </div>
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="newServerSettings.scannerParseSubtitle" small :disabled="updatingServerSettings" @input="updateScannerParseSubtitle" /> <ui-toggle-switch v-model="newServerSettings.scannerParseSubtitle" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerParseSubtitle', val)" />
<ui-tooltip :text="parseSubtitleTooltip"> <ui-tooltip :text="tooltips.scannerParseSubtitle">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Scanner parse subtitles Scanner parse subtitles
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
@ -62,8 +62,8 @@
</div> </div>
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="newServerSettings.scannerFindCovers" :disabled="updatingServerSettings" @input="updateScannerFindCovers" /> <ui-toggle-switch v-model="newServerSettings.scannerFindCovers" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerFindCovers', val)" />
<ui-tooltip :text="scannerFindCoversTooltip"> <ui-tooltip :text="tooltips.scannerFindCovers">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Scanner find covers Scanner find covers
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
@ -76,8 +76,8 @@
</div> </div>
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="newServerSettings.scannerPreferAudioMetadata" :disabled="updatingServerSettings" @input="updateScannerPreferAudioMeta" /> <ui-toggle-switch v-model="newServerSettings.scannerPreferAudioMetadata" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerPreferAudioMetadata', val)" />
<ui-tooltip :text="scannerPreferAudioMetaTooltip"> <ui-tooltip :text="tooltips.scannerPreferAudioMetadata">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Scanner prefer audio metadata Scanner prefer audio metadata
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
@ -86,14 +86,24 @@
</div> </div>
<div class="flex items-center py-2"> <div class="flex items-center py-2">
<ui-toggle-switch v-model="newServerSettings.scannerPreferOpfMetadata" :disabled="updatingServerSettings" @input="updateScannerPreferOpfMeta" /> <ui-toggle-switch v-model="newServerSettings.scannerPreferOpfMetadata" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerPreferOpfMetadata', val)" />
<ui-tooltip :text="scannerPreferOpfMetaTooltip"> <ui-tooltip :text="tooltips.scannerPreferOpfMetadata">
<p class="pl-4 text-lg"> <p class="pl-4 text-lg">
Scanner prefer OPF metadata Scanner prefer OPF metadata
<span class="material-icons icon-text">info_outlined</span> <span class="material-icons icon-text">info_outlined</span>
</p> </p>
</ui-tooltip> </ui-tooltip>
</div> </div>
<div class="flex items-center py-2">
<ui-toggle-switch v-model="newServerSettings.scannerDisableWatcher" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerDisableWatcher', val)" />
<ui-tooltip :text="tooltips.scannerDisableWatcher">
<p class="pl-4 text-lg">
Disable Watcher
<span class="material-icons icon-text">info_outlined</span>
</p>
</ui-tooltip>
</div>
</div> </div>
<div class="h-0.5 bg-primary bg-opacity-30 w-full" /> <div class="h-0.5 bg-primary bg-opacity-30 w-full" />
@ -167,7 +177,17 @@ export default {
useSquareBookCovers: false, useSquareBookCovers: false,
useAlternativeBookshelfView: false, useAlternativeBookshelfView: false,
isPurgingCache: false, isPurgingCache: false,
newServerSettings: {} newServerSettings: {},
tooltips: {
scannerDisableWatcher: 'Disables the automatic adding/updating of audiobooks when file changes are detected. *Requires server restart',
scannerPreferOpfMetadata: 'OPF file metadata will be used for book details over folder names',
scannerPreferAudioMetadata: 'Audio file ID3 meta tags will be used for book details over folder names',
scannerParseSubtitle: 'Extract subtitles from audiobook directory names.<br>Subtitle must be seperated by " - "<br>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.<br>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.',
coverAspectRatio: 'Prefer to use square covers over standard 1.6:1 book covers'
}
} }
}, },
watch: { watch: {
@ -179,36 +199,12 @@ export default {
} }
}, },
computed: { computed: {
scannerPreferAudioMetaTooltip() {
return 'Audio file ID3 meta tags will be used for book details over folder names'
},
scannerPreferOpfMetaTooltip() {
return 'OPF file metadata will be used for book details over folder names'
},
saveMetadataTooltip() {
return 'This will write a "metadata.nfo" file in all of your audiobook directories.'
},
experimentalFeaturesTooltip() { experimentalFeaturesTooltip() {
return 'Features in development that could use your feedback and help testing.' return 'Features in development that could use your feedback and help testing.'
}, },
serverSettings() { serverSettings() {
return this.$store.state.serverSettings return this.$store.state.serverSettings
}, },
parseSubtitleTooltip() {
return 'Extract subtitles from audiobook directory names.<br>Subtitle must be seperated by " - "<br>i.e. "Book Title - A Subtitle Here" has the subtitle "A Subtitle Here"'
},
coverDestinationTooltip() {
return '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.'
},
scannerFindCoversTooltip() {
return 'If your audiobook does not have an embedded cover or a cover image inside the folder, the scanner will attempt to find a cover.<br>Note: This will extend scan time'
},
coverAspectRatioTooltip() {
return 'Prefer to use square covers over standard 1.6:1 book covers'
},
bookshelfViewTooltip() {
return 'Alternative bookshelf view that shows title & author under book covers'
},
providers() { providers() {
return this.$store.state.scanners.providers return this.$store.state.scanners.providers
}, },
@ -225,11 +221,6 @@ export default {
updateEnableChromecast(val) { updateEnableChromecast(val) {
this.updateServerSettings({ enableChromecast: val }) this.updateServerSettings({ enableChromecast: val })
}, },
updateScannerFindCovers(val) {
this.updateServerSettings({
scannerFindCovers: !!val
})
},
updateScannerCoverProvider(val) { updateScannerCoverProvider(val) {
this.updateServerSettings({ this.updateServerSettings({
scannerCoverProvider: val scannerCoverProvider: val
@ -241,21 +232,6 @@ export default {
coverDestination: this.newServerSettings.coverDestination coverDestination: this.newServerSettings.coverDestination
}) })
}, },
updateScannerParseSubtitle(val) {
this.updateServerSettings({
scannerParseSubtitle: !!val
})
},
updateScannerPreferAudioMeta(val) {
this.updateServerSettings({
scannerPreferAudioMetadata: !!val
})
},
updateScannerPreferOpfMeta(val) {
this.updateServerSettings({
scannerPreferOpfMetadata: !!val
})
},
updateBookCoverAspectRatio(val) { updateBookCoverAspectRatio(val) {
this.updateServerSettings({ this.updateServerSettings({
coverAspectRatio: val ? this.$constants.BookCoverAspectRatio.SQUARE : this.$constants.BookCoverAspectRatio.STANDARD coverAspectRatio: val ? this.$constants.BookCoverAspectRatio.SQUARE : this.$constants.BookCoverAspectRatio.STANDARD

View File

@ -127,8 +127,13 @@ class Server {
await this.scanner.fixDuplicateIds() await this.scanner.fixDuplicateIds()
} }
this.watcher.initWatcher(this.libraries) if (this.db.serverSettings.scannerDisableWatcher) {
this.watcher.on('files', this.filesChanged.bind(this)) Logger.info(`[Server] Watcher is disabled`)
this.watcher.disabled = true
} else {
this.watcher.initWatcher(this.libraries)
this.watcher.on('files', this.filesChanged.bind(this))
}
} }
async start() { async start() {

View File

@ -13,6 +13,8 @@ class FolderWatcher extends EventEmitter {
this.pendingFileUpdates = [] this.pendingFileUpdates = []
this.pendingDelay = 4000 this.pendingDelay = 4000
this.pendingTimeout = null this.pendingTimeout = null
this.disabled = false
} }
get pendingFilePaths() { get pendingFilePaths() {
@ -71,10 +73,12 @@ class FolderWatcher extends EventEmitter {
} }
addLibrary(library) { addLibrary(library) {
if (this.disabled) return
this.buildLibraryWatcher(library) this.buildLibraryWatcher(library)
} }
updateLibrary(library) { updateLibrary(library) {
if (this.disabled) return
var libwatcher = this.libraryWatchers.find(lib => lib.id === library.id) var libwatcher = this.libraryWatchers.find(lib => lib.id === library.id)
if (libwatcher) { if (libwatcher) {
libwatcher.name = library.name libwatcher.name = library.name
@ -90,6 +94,7 @@ class FolderWatcher extends EventEmitter {
} }
removeLibrary(library) { removeLibrary(library) {
if (this.disabled) return
var libwatcher = this.libraryWatchers.find(lib => lib.id === library.id) var libwatcher = this.libraryWatchers.find(lib => lib.id === library.id)
if (libwatcher) { if (libwatcher) {
Logger.info(`[Watcher] Removed watcher for "${library.name}"`) Logger.info(`[Watcher] Removed watcher for "${library.name}"`)

View File

@ -15,6 +15,7 @@ class ServerSettings {
this.scannerCoverProvider = 'google' this.scannerCoverProvider = 'google'
this.scannerPreferAudioMetadata = false this.scannerPreferAudioMetadata = false
this.scannerPreferOpfMetadata = false this.scannerPreferOpfMetadata = false
this.scannerDisableWatcher = false
// Metadata // Metadata
this.coverDestination = CoverDestination.METADATA this.coverDestination = CoverDestination.METADATA
@ -56,6 +57,7 @@ class ServerSettings {
this.scannerParseSubtitle = settings.scannerParseSubtitle this.scannerParseSubtitle = settings.scannerParseSubtitle
this.scannerPreferAudioMetadata = !!settings.scannerPreferAudioMetadata this.scannerPreferAudioMetadata = !!settings.scannerPreferAudioMetadata
this.scannerPreferOpfMetadata = !!settings.scannerPreferOpfMetadata this.scannerPreferOpfMetadata = !!settings.scannerPreferOpfMetadata
this.scannerDisableWatcher = !!settings.scannerDisableWatcher
this.coverDestination = settings.coverDestination || CoverDestination.METADATA this.coverDestination = settings.coverDestination || CoverDestination.METADATA
this.saveMetadataFile = !!settings.saveMetadataFile this.saveMetadataFile = !!settings.saveMetadataFile
@ -92,6 +94,7 @@ class ServerSettings {
scannerParseSubtitle: this.scannerParseSubtitle, scannerParseSubtitle: this.scannerParseSubtitle,
scannerPreferAudioMetadata: this.scannerPreferAudioMetadata, scannerPreferAudioMetadata: this.scannerPreferAudioMetadata,
scannerPreferOpfMetadata: this.scannerPreferOpfMetadata, scannerPreferOpfMetadata: this.scannerPreferOpfMetadata,
scannerDisableWatcher: this.scannerDisableWatcher,
coverDestination: this.coverDestination, coverDestination: this.coverDestination,
saveMetadataFile: !!this.saveMetadataFile, saveMetadataFile: !!this.saveMetadataFile,
rateLimitLoginRequests: this.rateLimitLoginRequests, rateLimitLoginRequests: this.rateLimitLoginRequests,