diff --git a/client/components/modals/item/tabs/Tools.vue b/client/components/modals/item/tabs/Tools.vue index 4a76482a4..b61a9b5ab 100644 --- a/client/components/modals/item/tabs/Tools.vue +++ b/client/components/modals/item/tabs/Tools.vue @@ -62,6 +62,24 @@ + + +
+
+
+

{{ $strings.LabelToolsRenamer }}

+

{{ $strings.LabelToolsRenamerDescription }}

+
+
+
+ {{ $strings.ButtonOpenManager }} + launch + +
+
+
+

{{ $strings.MessageNoAudioTracks }}

@@ -82,6 +100,9 @@ export default { showExperimentalFeatures() { return this.$store.state.showExperimentalFeatures }, + userIsAdminOrUp() { + return this.$store.getters['user/getIsAdminOrUp'] + }, libraryItemId() { return this.libraryItem?.id || null }, diff --git a/client/pages/audiobook/_id/manage.vue b/client/pages/audiobook/_id/manage.vue index cc5f97528..acf66d90a 100644 --- a/client/pages/audiobook/_id/manage.vue +++ b/client/pages/audiobook/_id/manage.vue @@ -10,25 +10,207 @@ - -
-
-

{{ $strings.HeaderMetadataToEmbed }}

-

audiobookshelf uses tone to write metadata.

-
-
-
- -
-
-
-
{{ $strings.LabelMetaTag }}
-
{{ $strings.LabelValue }}
+
+
+
+

{{ $strings.HeaderMetadataToEmbed }}

+

audiobookshelf uses tone to write metadata.

-
- @@ -217,7 +266,10 @@ export default { bitrate: '64k', channels: '2', codec: 'aac' - } + }, + renameFormat: '', + sampleFormatObject: null, + directorySeperatorChar: '/' } }, watch: { @@ -236,6 +288,12 @@ export default { isM4BTool() { return this.selectedTool === 'm4b' }, + isM4BorEmbedTool() { + return this.isM4BTool || this.isEmbedTool + }, + isRenameTool() { + return this.selectedTool === 'renamer' + }, libraryItemId() { return this.libraryItem.id }, @@ -257,18 +315,22 @@ export default { streamLibraryItem() { return this.$store.state.streamLibraryItem }, + defaultRenameString() { + return this.$store.state.defaultRenameString + }, metadataChapters() { return this.media.chapters || [] }, availableTools() { + var tools = [ + { value: 'embed', text: 'Embed Metadata' }, + { value: 'renamer', text: 'Rename Folder' }, + { value: 'm4b', text: 'M4B Encoder' } + ] if (this.isSingleM4b) { - return [{ value: 'embed', text: 'Embed Metadata' }] - } else { - return [ - { value: 'embed', text: 'Embed Metadata' }, - { value: 'm4b', text: 'M4B Encoder' } - ] + tools.pop() } + return tools }, taskFailed() { return this.isTaskFinished && this.task.isFailed @@ -361,6 +423,40 @@ export default { } this.$store.commit('globals/setConfirmPrompt', payload) }, + async previewRenameClick() { + this.processing = true + const renameObject = await this.$axios + .$get(`/api/tools/item/${this.libraryItemId}/renameFolder?strFormat=${this.renameFormat}${this.sampleFormatObject == null ? '&includeSampleTemplate=1' : ''}`) + .then((renameObject) => { + return renameObject + }) + .catch((error) => { + console.error('Failed to Rename', error) + }) + this.directorySeperatorChar = renameObject.directorySeperatorChar + this.$refs.newFolderRelPath.setHTML('...' + this.directorySeperatorChar + renameObject.newRelativeDirectory + this.directorySeperatorChar) + if (renameObject.templateSample) { + this.sampleFormatObject = renameObject.templateSample + } + this.processing = false + }, + async renameClick() { + const renameObject = await this.$axios + .$post(`/api/tools/item/${this.libraryItemId}/renameFolder?strFormat=${this.renameFormat}`) + .then((renameObject) => { + return renameObject + }) + .catch((error) => { + console.error('Failed to Rename', error) + }) + if (renameObject.success) { + this.$refs.renameStatus.setHTML('Folder for Book updated to ...' + this.directorySeperatorChar + renameObject.details.newRelativeDirectory + this.directorySeperatorChar + ' from ' + renameObject.details.oldRelativeDirectory) + this.$refs.currentRelPath.setHTML('...' + this.directorySeperatorChar + renameObject.details.newRelativeDirectory + this.directorySeperatorChar) + } else { + this.$refs.renameStatus.setHTML('Failed to Rename: ' + JSON.stringify(renameObject.details)) + } + this.processing = false + }, updateAudioFileMetadata() { this.processing = true this.$axios @@ -385,6 +481,9 @@ export default { selectedToolUpdated() { let newurl = window.location.protocol + '//' + window.location.host + window.location.pathname + `?tool=${this.selectedTool}` window.history.replaceState({ path: newurl }, '', newurl) + if (this.selectedTool == 'renamer') { + this.previewRenameClick() + } }, init() { this.fetchToneObject() @@ -394,12 +493,20 @@ export default { } else { this.selectedToolUpdated() } + } else if (this.$route.query.tool === 'renamer') { + if (this.availableTools.some((t) => t.value === 'renamer')) { + this.previewRenameClick() + this.selectedTool = 'renamer' + } else { + this.selectedToolUpdated() + } } - if (this.task) this.taskUpdated(this.task) const shouldBackupAudioFiles = localStorage.getItem('embedMetadataShouldBackup') this.shouldBackupAudioFiles = shouldBackupAudioFiles != 0 + const defaultRenameString = localStorage.getItem('defaultRenameString') + this.renameFormat = defaultRenameString ? defaultRenameString : '$authorName/$bookName' }, fetchToneObject() { this.$axios diff --git a/client/pages/config/index.vue b/client/pages/config/index.vue index 2ff594228..0f5fab94f 100644 --- a/client/pages/config/index.vue +++ b/client/pages/config/index.vue @@ -192,6 +192,16 @@
+
+ + +

+ + info_outlined +

+
+
+