@@ -269,11 +269,11 @@ export default {
},
availableTools() {
if (this.isSingleM4b) {
- return [{ value: 'embed', text: 'Embed Metadata' }]
+ return [{ value: 'embed', text: this.$strings.LabelToolsEmbedMetadata }]
} else {
return [
- { value: 'embed', text: 'Embed Metadata' },
- { value: 'm4b', text: 'M4B Encoder' }
+ { value: 'embed', text: this.$strings.LabelToolsEmbedMetadata },
+ { value: 'm4b', text: this.$strings.LabelToolsM4bEncoder }
]
}
},
diff --git a/client/pages/library/_library/podcast/search.vue b/client/pages/library/_library/podcast/search.vue
index fd44df97..37ceeee0 100644
--- a/client/pages/library/_library/podcast/search.vue
+++ b/client/pages/library/_library/podcast/search.vue
@@ -5,7 +5,7 @@
@@ -108,7 +108,7 @@ export default {
if (!txt || !txt.includes(' tag not found OR an tag was not found')
+ this.$toast.error(this.$strings.MessageTaskOpmlParseFastFail)
this.processing = false
return
}
@@ -117,7 +117,7 @@ export default {
.$post(`/api/podcasts/opml/parse`, { opmlText: txt })
.then((data) => {
if (!data.feeds?.length) {
- this.$toast.error('No feeds found in OPML file')
+ this.$toast.error(this.$strings.MessageTaskOpmlParseNoneFound)
} else {
this.opmlFeeds = data.feeds || []
this.showOPMLFeedsModal = true
@@ -125,7 +125,7 @@ export default {
})
.catch((error) => {
console.error('Failed', error)
- this.$toast.error('Failed to parse OPML file')
+ this.$toast.error(this.$strings.MessageTaskOpmlParseFailed)
})
.finally(() => {
this.processing = false
@@ -191,7 +191,7 @@ export default {
return
}
if (!podcast.feedUrl) {
- this.$toast.error('Invalid podcast - no feed')
+ this.$toast.error(this.$strings.MessageNoPodcastFeed)
return
}
this.processing = true
diff --git a/client/strings/en-us.json b/client/strings/en-us.json
index 34b014dc..edad1672 100644
--- a/client/strings/en-us.json
+++ b/client/strings/en-us.json
@@ -66,6 +66,7 @@
"ButtonPurgeItemsCache": "Purge Items Cache",
"ButtonQueueAddItem": "Add to queue",
"ButtonQueueRemoveItem": "Remove from queue",
+ "ButtonQuickEmbed": "Quick Embed",
"ButtonQuickEmbedMetadata": "Quick Embed Metadata",
"ButtonQuickMatch": "Quick Match",
"ButtonReScan": "Re-Scan",
@@ -225,6 +226,9 @@
"LabelAllUsersIncludingGuests": "All users including guests",
"LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
+ "LabelAudioBitrate": "Audio Bitrate (e.g. 128k)",
+ "LabelAudioChannels": "Audio Channels (1 or 2)",
+ "LabelAudioCodec": "Audio Codec",
"LabelAuthor": "Author",
"LabelAuthorFirstLast": "Author (First Last)",
"LabelAuthorLastFirst": "Author (Last, First)",
@@ -237,6 +241,7 @@
"LabelAutoRegister": "Auto Register",
"LabelAutoRegisterDescription": "Automatically create new users after logging in",
"LabelBackToUser": "Back to User",
+ "LabelBackupAudioFiles": "Backup Audio Files",
"LabelBackupLocation": "Backup Location",
"LabelBackupsEnableAutomaticBackups": "Enable automatic backups",
"LabelBackupsEnableAutomaticBackupsHelp": "Backups saved in /metadata/backups",
@@ -303,6 +308,15 @@
"LabelEmailSettingsTestAddress": "Test Address",
"LabelEmbeddedCover": "Embedded Cover",
"LabelEnable": "Enable",
+ "LabelEncodingBackupLocation": "A backup of your original audio files will be stored in:",
+ "LabelEncodingChaptersNotEmbedded": "Chapters are not embedded in multi-track audiobooks.",
+ "LabelEncodingClearItemCache": "Make sure to periodically purge items cache.",
+ "LabelEncodingFinishedM4B": "Finished M4B will be put into your audiobook folder at:",
+ "LabelEncodingInfoEmbedded": "Metadata will be embedded in the audio tracks inside your audiobook folder.",
+ "LabelEncodingStartedNavigation": "Once the task is started you can navigate away from this page.",
+ "LabelEncodingTimeWarning": "Encoding can take up to 30 minutes.",
+ "LabelEncodingWarningAdvancedSettings": "Warning: Do not update these settings unless you are familiar with ffmpeg encoding options.",
+ "LabelEncodingWatcherDisabled": "If you have the watcher disabled you will need to re-scan this audiobook afterwards.",
"LabelEnd": "End",
"LabelEndOfChapter": "End of Chapter",
"LabelEpisode": "Episode",
@@ -596,6 +610,7 @@
"LabelTitle": "Title",
"LabelToolsEmbedMetadata": "Embed Metadata",
"LabelToolsEmbedMetadataDescription": "Embed metadata into audio files including cover image and chapters.",
+ "LabelToolsM4bEncoder": "M4B Encoder",
"LabelToolsMakeM4b": "Make M4B Audiobook File",
"LabelToolsMakeM4bDescription": "Generate a .M4B audiobook file with embedded metadata, cover image, and chapters.",
"LabelToolsSplitM4b": "Split M4B to MP3's",
@@ -621,6 +636,7 @@
"LabelUploaderDragAndDrop": "Drag & drop files or folders",
"LabelUploaderDropFiles": "Drop files",
"LabelUploaderItemFetchMetadataHelp": "Automatically fetch title, author, and series",
+ "LabelUseAdvancedOptions": "Use Advanced Options",
"LabelUseChapterTrack": "Use chapter track",
"LabelUseFullTrack": "Use full track",
"LabelUser": "User",
@@ -702,6 +718,7 @@
"MessageDragFilesIntoTrackOrder": "Drag files into correct track order",
"MessageEmbedFailed": "Embed Failed!",
"MessageEmbedFinished": "Embed Finished!",
+ "MessageEmbedQueue": "Queued for metadata embed ({0} in queue)",
"MessageEpisodesQueuedForDownload": "{0} Episode(s) queued for download",
"MessageEreaderDevices": "To ensure delivery of ebooks, you may need to add the above email address as a valid sender for each device listed below.",
"MessageFeedURLWillBe": "Feed URL will be {0}",
@@ -746,6 +763,7 @@
"MessageNoLogs": "No Logs",
"MessageNoMediaProgress": "No Media Progress",
"MessageNoNotifications": "No Notifications",
+ "MessageNoPodcastFeed": "Invalid podcast: No Feed",
"MessageNoPodcastsFound": "No podcasts found",
"MessageNoResults": "No Results",
"MessageNoSearchResultsFor": "No search results for \"{0}\"",
@@ -762,6 +780,9 @@
"MessagePlaylistCreateFromCollection": "Create playlist from collection",
"MessagePleaseWait": "Please wait...",
"MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching",
+ "MessagePodcastSearchField": "Enter search term or RSS feed URL",
+ "MessageQuickEmbedInProgress": "Quick embed in progress",
+ "MessageQuickEmbedQueue": "Queued for quick embed ({0} in queue)",
"MessageQuickMatchDescription": "Populate empty item details & cover with first match result from '{0}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.",
"MessageRemoveChapter": "Remove chapter",
"MessageRemoveEpisodes": "Remove {0} episode(s)",
@@ -804,6 +825,9 @@
"MessageTaskOpmlImportFeedPodcastExists": "Podcast already exists at path",
"MessageTaskOpmlImportFeedPodcastFailed": "Failed to create podcast",
"MessageTaskOpmlImportFinished": "Added {0} podcasts",
+ "MessageTaskOpmlParseFailed": "Failed to parse OPML file",
+ "MessageTaskOpmlParseFastFail": "Invalid OPML file tag not found OR an tag was not found",
+ "MessageTaskOpmlParseNoneFound": "No feeds found in OPML file",
"MessageTaskScanItemsAdded": "{0} added",
"MessageTaskScanItemsMissing": "{0} missing",
"MessageTaskScanItemsUpdated": "{0} updated",
@@ -828,6 +852,10 @@
"NoteUploaderFoldersWithMediaFiles": "Folders with media files will be handled as separate library items.",
"NoteUploaderOnlyAudioFiles": "If uploading only audio files then each audio file will be handled as a separate audiobook.",
"NoteUploaderUnsupportedFiles": "Unsupported files are ignored. When choosing or dropping a folder, other files that are not in an item folder are ignored.",
+ "NotificationOnBackupCompletedDescription": "Triggered when a backup is completed",
+ "NotificationOnBackupFailedDescription": "Triggered when a backup fails",
+ "NotificationOnEpisodeDownloadedDescription": "Triggered when a podcast episode is auto-downloaded",
+ "NotificationOnTestDescription": "Event for testing the notification system",
"PlaceholderNewCollection": "New collection name",
"PlaceholderNewFolderPath": "New folder path",
"PlaceholderNewPlaylist": "New playlist name",
diff --git a/server/utils/notifications.js b/server/utils/notifications.js
index 96e8ddf8..7a3e1198 100644
--- a/server/utils/notifications.js
+++ b/server/utils/notifications.js
@@ -7,6 +7,7 @@ module.exports.notificationData = {
requiresLibrary: true,
libraryMediaType: 'podcast',
description: 'Triggered when a podcast episode is auto-downloaded',
+ descriptionKey: 'NotificationOnEpisodeDownloadedDescription',
variables: ['libraryItemId', 'libraryId', 'podcastTitle', 'podcastAuthor', 'podcastDescription', 'podcastGenres', 'episodeTitle', 'episodeSubtitle', 'episodeDescription', 'libraryName', 'episodeId', 'mediaTags'],
defaults: {
title: 'New {{podcastTitle}} Episode!',
@@ -31,6 +32,7 @@ module.exports.notificationData = {
name: 'onBackupCompleted',
requiresLibrary: false,
description: 'Triggered when a backup is completed',
+ descriptionKey: 'NotificationOnBackupCompletedDescription',
variables: ['completionTime', 'backupPath', 'backupSize', 'backupCount', 'removedOldest'],
defaults: {
title: 'Backup Completed',
@@ -48,6 +50,7 @@ module.exports.notificationData = {
name: 'onBackupFailed',
requiresLibrary: false,
description: 'Triggered when a backup fails',
+ descriptionKey: 'NotificationOnBackupFailedDescription',
variables: ['errorMsg'],
defaults: {
title: 'Backup Failed',
@@ -61,6 +64,7 @@ module.exports.notificationData = {
name: 'onTest',
requiresLibrary: false,
description: 'Event for testing the notification system',
+ descriptionKey: 'NotificationOnTestDescription',
variables: ['version'],
defaults: {
title: 'Test Notification on Abs {{version}}',