-
{{ podcast.title }}
+
by {{ podcast.artistName }}
{{ podcast.genres.join(', ') }}
{{ podcast.trackCount }} {{ $strings.HeaderEpisodes }}
@@ -68,10 +71,14 @@ export default {
selectedPodcast: null,
selectedPodcastFeed: null,
showOPMLFeedsModal: false,
- opmlFeeds: []
+ opmlFeeds: [],
+ existentPodcasts: []
}
},
computed: {
+ currentLibraryId() {
+ return this.$store.state.libraries.currentLibraryId
+ },
streamLibraryItem() {
return this.$store.state.streamLibraryItem
}
@@ -144,18 +151,29 @@ export default {
return []
})
console.log('Got results', results)
+ for (let result of results) {
+ let podcast = this.existentPodcasts.find((p) => p.itunesId === result.id || p.title === result.title.toLowerCase())
+ if (podcast) {
+ result.alreadyInLibrary = true
+ result.existentId = podcast.id
+ }
+ }
this.results = results
this.termSearched = term
this.processing = false
},
async selectPodcast(podcast) {
console.log('Selected podcast', podcast)
+ if(podcast.existentId){
+ this.$router.push(`/item/${podcast.existentId}`)
+ return
+ }
if (!podcast.feedUrl) {
this.$toast.error('Invalid podcast - no feed')
return
}
this.processing = true
- var payload = await this.$axios.$post(`/api/podcasts/feed`, { rssFeed: podcast.feedUrl }).catch((error) => {
+ var payload = await this.$axios.$post(`/api/podcasts/feed`, {rssFeed: podcast.feedUrl}).catch((error) => {
console.error('Failed to get feed', error)
this.$toast.error('Failed to get podcast feed')
return null
@@ -167,8 +185,26 @@ export default {
this.selectedPodcast = podcast
this.showNewPodcastModal = true
console.log('Got podcast feed', payload.podcast)
+ },
+ async fetchExistentPodcastsInYourLibrary() {
+ this.processing = true
+
+ const podcasts = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/items?page=0&minified=1`).catch((error) => {
+ console.error('Failed to fetch podcasts', error)
+ return []
+ })
+ this.existentPodcasts = podcasts.results.map((p) => {
+ return {
+ title: p.media.metadata.title.toLowerCase(),
+ itunesId: p.media.metadata.itunesId,
+ id: p.id
+ }
+ })
+ this.processing = false
}
},
- mounted() {}
+ mounted() {
+ this.fetchExistentPodcastsInYourLibrary()
+ }
}
-
\ No newline at end of file
+
diff --git a/client/plugins/constants.js b/client/plugins/constants.js
index f379c618..4a26bd5c 100644
--- a/client/plugins/constants.js
+++ b/client/plugins/constants.js
@@ -1,6 +1,6 @@
const SupportedFileTypes = {
image: ['png', 'jpg', 'jpeg', 'webp'],
- audio: ['m4b', 'mp3', 'm4a', 'flac', 'opus', 'ogg', 'oga', 'mp4', 'aac', 'wma', 'aiff', 'wav', 'webm', 'webma'],
+ audio: ['m4b', 'mp3', 'm4a', 'flac', 'opus', 'ogg', 'oga', 'mp4', 'aac', 'wma', 'aiff', 'wav', 'webm', 'webma', 'mka', 'awb'],
ebook: ['epub', 'pdf', 'mobi', 'azw3', 'cbr', 'cbz'],
info: ['nfo'],
text: ['txt'],
diff --git a/client/plugins/i18n.js b/client/plugins/i18n.js
index bb4131ce..a87669c5 100644
--- a/client/plugins/i18n.js
+++ b/client/plugins/i18n.js
@@ -7,7 +7,7 @@ const defaultCode = 'en-us'
const languageCodeMap = {
'de': { label: 'Deutsch', dateFnsLocale: 'de' },
'en-us': { label: 'English', dateFnsLocale: 'enUS' },
- // 'es': { label: 'Español', dateFnsLocale: 'es' },
+ 'es': { label: 'Español', dateFnsLocale: 'es' },
'fr': { label: 'Français', dateFnsLocale: 'fr' },
'hr': { label: 'Hrvatski', dateFnsLocale: 'hr' },
'it': { label: 'Italiano', dateFnsLocale: 'it' },
diff --git a/client/plugins/init.client.js b/client/plugins/init.client.js
index 553d9b2e..ea6db96a 100644
--- a/client/plugins/init.client.js
+++ b/client/plugins/init.client.js
@@ -23,6 +23,22 @@ Vue.prototype.$formatJsDate = (jsdate, fnsFormat = 'MM/dd/yyyy HH:mm') => {
if (!jsdate || !isDate(jsdate)) return ''
return format(jsdate, fnsFormat)
}
+Vue.prototype.$formatTime = (unixms, fnsFormat = 'HH:mm') => {
+ if (!unixms) return ''
+ return format(unixms, fnsFormat)
+}
+Vue.prototype.$formatJsTime = (jsdate, fnsFormat = 'HH:mm') => {
+ if (!jsdate || !isDate(jsdate)) return ''
+ return format(jsdate, fnsFormat)
+}
+Vue.prototype.$formatDatetime = (unixms, fnsDateFormart = 'MM/dd/yyyy', fnsTimeFormat = 'HH:mm') => {
+ if (!unixms) return ''
+ return format(unixms, `${fnsDateFormart} ${fnsTimeFormat}`)
+}
+Vue.prototype.$formatJsDatetime = (jsdate, fnsDateFormart = 'MM/dd/yyyy', fnsTimeFormat = 'HH:mm') => {
+ if (!jsdate || !isDate(jsdate)) return ''
+ return format(jsdate, `${fnsDateFormart} ${fnsTimeFormat}`)
+}
Vue.prototype.$addDaysToToday = (daysToAdd) => {
var date = addDays(new Date(), daysToAdd)
if (!date || !isDate(date)) return null
@@ -167,4 +183,4 @@ export default ({ app, store }, inject) => {
inject('isDev', process.env.NODE_ENV !== 'production')
store.commit('setRouterBasePath', app.$config.routerBasePath)
-}
\ No newline at end of file
+}
diff --git a/client/plugins/utils.js b/client/plugins/utils.js
index 76dda3c9..c9ece333 100644
--- a/client/plugins/utils.js
+++ b/client/plugins/utils.js
@@ -1,4 +1,5 @@
import Vue from 'vue'
+import cronParser from 'cron-parser'
Vue.prototype.$bytesPretty = (bytes, decimals = 2) => {
if (isNaN(bytes) || bytes == 0) {
@@ -136,6 +137,11 @@ Vue.prototype.$parseCronExpression = (expression) => {
}
}
+Vue.prototype.$getNextScheduledDate = (expression) => {
+ const interval = cronParser.parseExpression(expression);
+ return interval.next().toDate()
+}
+
export function supplant(str, subs) {
// source: http://crockford.com/javascript/remedial.html
return str.replace(/{([^{}]*)}/g,
@@ -144,4 +150,4 @@ export function supplant(str, subs) {
return typeof r === 'string' || typeof r === 'number' ? r : a
}
)
-}
\ No newline at end of file
+}
diff --git a/client/store/globals.js b/client/store/globals.js
index 13c6bb05..9c126a97 100644
--- a/client/store/globals.js
+++ b/client/store/globals.js
@@ -32,11 +32,50 @@ export const state = () => ({
text: 'DD/MM/YYYY',
value: 'dd/MM/yyyy'
},
+ {
+ text: 'DD.MM.YYYY',
+ value: 'dd.MM.yyyy'
+ },
{
text: 'YYYY-MM-DD',
value: 'yyyy-MM-dd'
+ },
+ {
+ text: 'MMM do, yyyy',
+ value: 'MMM do, yyyy'
+ },
+ {
+ text: 'MMMM do, yyyy',
+ value: 'MMMM do, yyyy'
+ },
+ {
+ text: 'dd MMM yyyy',
+ value: 'dd MMM yyyy'
+ },
+ {
+ text: 'dd MMMM yyyy',
+ value: 'dd MMMM yyyy'
}
],
+ timeFormats: [
+ {
+ text: 'h:mma (am/pm)',
+ value: 'h:mma'
+ },
+ {
+ text: 'HH:mm (24-hour)',
+ value: 'HH:mm'
+ }
+ ],
+ podcastTypes: [
+ { text: 'Episodic', value: 'episodic' },
+ { text: 'Serial', value: 'serial' }
+ ],
+ episodeTypes: [
+ { text: 'Full', value: 'full' },
+ { text: 'Trailer', value: 'trailer' },
+ { text: 'Bonus', value: 'bonus' }
+ ],
libraryIcons: ['database', 'audiobookshelf', 'books-1', 'books-2', 'book-1', 'microphone-1', 'microphone-3', 'radio', 'podcast', 'rss', 'headphones', 'music', 'file-picture', 'rocket', 'power', 'star', 'heart']
})
@@ -169,4 +208,4 @@ export const mutations = {
state.selectedMediaItems.push(item)
}
}
-}
\ No newline at end of file
+}
diff --git a/client/store/index.js b/client/store/index.js
index 1529d864..57710da2 100644
--- a/client/store/index.js
+++ b/client/store/index.js
@@ -13,6 +13,7 @@ export const state = () => ({
playerQueueAutoPlay: true,
playerIsFullscreen: false,
editModalTab: 'details',
+ editPodcastModalTab: 'details',
showEditModal: false,
showEReader: false,
selectedLibraryItem: null,
@@ -21,6 +22,7 @@ export const state = () => ({
previousPath: '/',
showExperimentalFeatures: false,
bookshelfBookIds: [],
+ episodeTableEpisodeIds: [],
openModal: null,
innerModalOpen: false,
lastBookshelfScrollData: {},
@@ -135,6 +137,9 @@ export const mutations = {
setBookshelfBookIds(state, val) {
state.bookshelfBookIds = val || []
},
+ setEpisodeTableEpisodeIds(state, val) {
+ state.episodeTableEpisodeIds = val || []
+ },
setPreviousPath(state, val) {
state.previousPath = val
},
@@ -198,6 +203,9 @@ export const mutations = {
setShowEditModal(state, val) {
state.showEditModal = val
},
+ setEditPodcastModalTab(state, tab) {
+ state.editPodcastModalTab = tab
+ },
showEReader(state, libraryItem) {
state.selectedLibraryItem = libraryItem
@@ -225,4 +233,4 @@ export const mutations = {
setInnerModalOpen(state, val) {
state.innerModalOpen = val
}
-}
\ No newline at end of file
+}
diff --git a/client/strings/de.json b/client/strings/de.json
index d47dd1cd..a829ffa5 100644
--- a/client/strings/de.json
+++ b/client/strings/de.json
@@ -17,9 +17,10 @@
"ButtonCloseFeed": "Feed schließen",
"ButtonCollections": "Sammlungen",
"ButtonConfigureScanner": "Scannereinstellungen",
- "ButtonCreate": "Ertsellen",
+ "ButtonCreate": "Erstellen",
"ButtonCreateBackup": "Sicherung erstellen",
"ButtonDelete": "Löschen",
+ "ButtonDownloadQueue": "Queue",
"ButtonEdit": "Bearbeiten",
"ButtonEditChapters": "Kapitel bearbeiten",
"ButtonEditPodcast": "Podcast bearbeiten",
@@ -92,7 +93,9 @@
"HeaderCollection": "Sammlungen",
"HeaderCollectionItems": "Sammlungseinträge",
"HeaderCover": "Titelbild",
+ "HeaderCurrentDownloads": "Current Downloads",
"HeaderDetails": "Details",
+ "HeaderDownloadQueue": "Download Queue",
"HeaderEpisodes": "Episoden",
"HeaderFiles": "Dateien",
"HeaderFindChapters": "Kapitel suchen",
@@ -126,6 +129,7 @@
"HeaderPreviewCover": "Vorschau Titelbild",
"HeaderRemoveEpisode": "Episode löschen",
"HeaderRemoveEpisodes": "Lösche {0} Episoden",
+ "HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "RSS-Feed ist geöffnet",
"HeaderSavedMediaProgress": "Gespeicherte Hörfortschritte",
"HeaderSchedule": "Zeitplan",
@@ -138,6 +142,7 @@
"HeaderSettingsGeneral": "Allgemein",
"HeaderSettingsScanner": "Scanner",
"HeaderSleepTimer": "Einschlaf-Timer",
+ "HeaderStatsLargestItems": "Largest Items",
"HeaderStatsLongestItems": "Längste Einträge (h)",
"HeaderStatsMinutesListeningChart": "Hörminuten (letzte 7 Tage)",
"HeaderStatsRecentSessions": "Neueste Ereignisse",
@@ -162,6 +167,7 @@
"LabelAddToPlaylistBatch": "Füge {0} Hörbüch(er)/Podcast(s) der Wiedergabeliste hinzu",
"LabelAll": "Alle",
"LabelAllUsers": "Alle Benutzer",
+ "LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Anhängen",
"LabelAuthor": "Autor",
"LabelAuthorFirstLast": "Autor (Vorname Nachname)",
@@ -192,6 +198,7 @@
"LabelCronExpression": "Cron Ausdruck",
"LabelCurrent": "Aktuell",
"LabelCurrently": "Aktuell:",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Datum & Uhrzeit",
"LabelDescription": "Beschreibung",
"LabelDeselectAll": "Alles abwählen",
@@ -209,6 +216,7 @@
"LabelEpisode": "Episode",
"LabelEpisodeTitle": "Episodentitel",
"LabelEpisodeType": "Episodentyp",
+ "LabelExample": "Example",
"LabelExplicit": "Explizit (Altersbeschränkung)",
"LabelFeedURL": "Feed URL",
"LabelFile": "Datei",
@@ -270,6 +278,8 @@
"LabelNewestAuthors": "Neuste Autoren",
"LabelNewestEpisodes": "Neueste Episoden",
"LabelNewPassword": "Neues Passwort",
+ "LabelNextBackupDate": "Next backup date",
+ "LabelNextScheduledRun": "Next scheduled run",
"LabelNotes": "Hinweise",
"LabelNotFinished": "nicht beendet",
"LabelNotificationAppriseURL": "Apprise URL(s)",
@@ -300,7 +310,9 @@
"LabelPlayMethod": "Abspielmethode",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts",
+ "LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)",
+ "LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
"LabelProgress": "Fortschritt",
"LabelProvider": "Anbieter",
"LabelPubDate": "Veröffentlichungsdatum",
@@ -312,7 +324,10 @@
"LabelRegion": "Region",
"LabelReleaseDate": "Veröffentlichungsdatum",
"LabelRemoveCover": "Lösche Titelbild",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "RSS Feed Offen",
+ "LabelRSSFeedPreventIndexing": "Prevent Indexing",
"LabelRSSFeedSlug": "RSS Feed Schlagwort",
"LabelRSSFeedURL": "RSS Feed URL",
"LabelSearchTerm": "Begriff suchen",
@@ -357,6 +372,7 @@
"LabelSettingsStoreCoversWithItemHelp": "Standardmäßig werden die Titelbilder in /metadata/items gespeichert. Wenn diese Option aktiviert ist, werden die Titelbilder als jpg Datei in dem gleichen Ordner gespeichert in welchem sich auch das Medium befindet. Es wird immer nur eine Datei mit dem Namen \"cover.jpg\" gespeichert.",
"LabelSettingsStoreMetadataWithItem": "Metadaten als OPF-Datei im Medienordner speichern",
"LabelSettingsStoreMetadataWithItemHelp": "Standardmäßig werden die Metadaten in /metadata/items gespeichert. Wenn diese Option aktiviert ist, werden die Metadaten als OPF-Datei (Textdatei) in dem gleichen Ordner gespeichert in welchem sich auch das Medium befindet. Es wird immer nur eine Datei mit dem Namen \"matadata.abs\" gespeichert.",
+ "LabelSettingsTimeFormat": "Time Format",
"LabelShowAll": "Alles anzeigen",
"LabelSize": "Größe",
"LabelSleepTimer": "Einschlaf-Timer",
@@ -381,9 +397,10 @@
"LabelStatsWeekListening": "Gehörte Wochen",
"LabelSubtitle": "Untertitel",
"LabelSupportedFileTypes": "Unterstützte Dateitypen",
- "LabelTag": "Tag",
+ "LabelTag": "Schlagwort",
"LabelTags": "Schlagwörter",
"LabelTagsAccessibleToUser": "Für Benutzer zugängliche Schlagwörter",
+ "LabelTasks": "Tasks Running",
"LabelTimeListened": "Gehörte Zeit",
"LabelTimeListenedToday": "Heute gehörte Zeit",
"LabelTimeRemaining": "{0} verbleibend",
@@ -485,6 +502,8 @@
"MessageNoCollections": "Keine Sammlungen",
"MessageNoCoversFound": "Keine Titelbilder gefunden",
"MessageNoDescription": "Keine Beschreibung",
+ "MessageNoDownloadsInProgress": "No downloads currently in progress",
+ "MessageNoDownloadsQueued": "No downloads queued",
"MessageNoEpisodeMatchesFound": "Keine Episodenübereinstimmungen gefunden",
"MessageNoEpisodes": "Keine Episoden",
"MessageNoFoldersAvailable": "Keine Ordner verfügbar",
@@ -501,6 +520,7 @@
"MessageNoSearchResultsFor": "Keine Suchergebnisse für \"{0}\"",
"MessageNoSeries": "Keine Serien",
"MessageNoTags": "Keine Tags",
+ "MessageNoTasksRunning": "No Tasks Running",
"MessageNotYetImplemented": "Noch nicht implementiert",
"MessageNoUpdateNecessary": "Keine Aktualisierung erforderlich",
"MessageNoUpdatesWereNecessary": "Keine Aktualisierungen waren notwendig",
@@ -616,4 +636,4 @@
"ToastSocketFailedToConnect": "Verbindung zum WebSocket fehlgeschlagen",
"ToastUserDeleteFailed": "Benutzer konnte nicht gelöscht werden",
"ToastUserDeleteSuccess": "Benutzer gelöscht"
-}
+}
\ No newline at end of file
diff --git a/client/strings/en-us.json b/client/strings/en-us.json
index 76093746..2c829514 100644
--- a/client/strings/en-us.json
+++ b/client/strings/en-us.json
@@ -20,6 +20,7 @@
"ButtonCreate": "Create",
"ButtonCreateBackup": "Create Backup",
"ButtonDelete": "Delete",
+ "ButtonDownloadQueue": "Queue",
"ButtonEdit": "Edit",
"ButtonEditChapters": "Edit Chapters",
"ButtonEditPodcast": "Edit Podcast",
@@ -92,7 +93,9 @@
"HeaderCollection": "Collection",
"HeaderCollectionItems": "Collection Items",
"HeaderCover": "Cover",
+ "HeaderCurrentDownloads": "Current Downloads",
"HeaderDetails": "Details",
+ "HeaderDownloadQueue": "Download Queue",
"HeaderEpisodes": "Episodes",
"HeaderFiles": "Files",
"HeaderFindChapters": "Find Chapters",
@@ -126,6 +129,7 @@
"HeaderPreviewCover": "Preview Cover",
"HeaderRemoveEpisode": "Remove Episode",
"HeaderRemoveEpisodes": "Remove {0} Episodes",
+ "HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "RSS Feed is Open",
"HeaderSavedMediaProgress": "Saved Media Progress",
"HeaderSchedule": "Schedule",
@@ -138,6 +142,7 @@
"HeaderSettingsGeneral": "General",
"HeaderSettingsScanner": "Scanner",
"HeaderSleepTimer": "Sleep Timer",
+ "HeaderStatsLargestItems": "Largest Items",
"HeaderStatsLongestItems": "Longest Items (hrs)",
"HeaderStatsMinutesListeningChart": "Minutes Listening (last 7 days)",
"HeaderStatsRecentSessions": "Recent Sessions",
@@ -162,6 +167,7 @@
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
"LabelAll": "All",
"LabelAllUsers": "All Users",
+ "LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Author",
"LabelAuthorFirstLast": "Author (First Last)",
@@ -192,6 +198,7 @@
"LabelCronExpression": "Cron Expression",
"LabelCurrent": "Current",
"LabelCurrently": "Currently:",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Datetime",
"LabelDescription": "Description",
"LabelDeselectAll": "Deselect All",
@@ -209,6 +216,7 @@
"LabelEpisode": "Episode",
"LabelEpisodeTitle": "Episode Title",
"LabelEpisodeType": "Episode Type",
+ "LabelExample": "Example",
"LabelExplicit": "Explicit",
"LabelFeedURL": "Feed URL",
"LabelFile": "File",
@@ -270,6 +278,8 @@
"LabelNewestAuthors": "Newest Authors",
"LabelNewestEpisodes": "Newest Episodes",
"LabelNewPassword": "New Password",
+ "LabelNextBackupDate": "Next backup date",
+ "LabelNextScheduledRun": "Next scheduled run",
"LabelNotes": "Notes",
"LabelNotFinished": "Not Finished",
"LabelNotificationAppriseURL": "Apprise URL(s)",
@@ -300,7 +310,9 @@
"LabelPlayMethod": "Play Method",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts",
+ "LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
+ "LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
"LabelProgress": "Progress",
"LabelProvider": "Provider",
"LabelPubDate": "Pub Date",
@@ -312,7 +324,10 @@
"LabelRegion": "Region",
"LabelReleaseDate": "Release Date",
"LabelRemoveCover": "Remove cover",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "RSS Feed Open",
+ "LabelRSSFeedPreventIndexing": "Prevent Indexing",
"LabelRSSFeedSlug": "RSS Feed Slug",
"LabelRSSFeedURL": "RSS Feed URL",
"LabelSearchTerm": "Search Term",
@@ -357,6 +372,7 @@
"LabelSettingsStoreCoversWithItemHelp": "By default covers are stored in /metadata/items, enabling this setting will store covers in your library item folder. Only one file named \"cover\" will be kept",
"LabelSettingsStoreMetadataWithItem": "Store metadata with item",
"LabelSettingsStoreMetadataWithItemHelp": "By default metadata files are stored in /metadata/items, enabling this setting will store metadata files in your library item folders. Uses .abs file extension",
+ "LabelSettingsTimeFormat": "Time Format",
"LabelShowAll": "Show All",
"LabelSize": "Size",
"LabelSleepTimer": "Sleep timer",
@@ -384,6 +400,7 @@
"LabelTag": "Tag",
"LabelTags": "Tags",
"LabelTagsAccessibleToUser": "Tags Accessible to User",
+ "LabelTasks": "Tasks Running",
"LabelTimeListened": "Time Listened",
"LabelTimeListenedToday": "Time Listened Today",
"LabelTimeRemaining": "{0} remaining",
@@ -485,6 +502,8 @@
"MessageNoCollections": "No Collections",
"MessageNoCoversFound": "No Covers Found",
"MessageNoDescription": "No description",
+ "MessageNoDownloadsInProgress": "No downloads currently in progress",
+ "MessageNoDownloadsQueued": "No downloads queued",
"MessageNoEpisodeMatchesFound": "No episode matches found",
"MessageNoEpisodes": "No Episodes",
"MessageNoFoldersAvailable": "No Folders Available",
@@ -501,6 +520,7 @@
"MessageNoSearchResultsFor": "No search results for \"{0}\"",
"MessageNoSeries": "No Series",
"MessageNoTags": "No Tags",
+ "MessageNoTasksRunning": "No Tasks Running",
"MessageNotYetImplemented": "Not yet implemented",
"MessageNoUpdateNecessary": "No update necessary",
"MessageNoUpdatesWereNecessary": "No updates were necessary",
diff --git a/client/strings/es.json b/client/strings/es.json
index 76093746..5d0f198c 100644
--- a/client/strings/es.json
+++ b/client/strings/es.json
@@ -1,619 +1,639 @@
{
- "ButtonAdd": "Add",
- "ButtonAddChapters": "Add Chapters",
- "ButtonAddPodcasts": "Add Podcasts",
- "ButtonAddYourFirstLibrary": "Add your first library",
- "ButtonApply": "Apply",
- "ButtonApplyChapters": "Apply Chapters",
- "ButtonAuthors": "Authors",
- "ButtonBrowseForFolder": "Browse for Folder",
- "ButtonCancel": "Cancel",
- "ButtonCancelEncode": "Cancel Encode",
- "ButtonChangeRootPassword": "Change Root Password",
- "ButtonCheckAndDownloadNewEpisodes": "Check & Download New Episodes",
- "ButtonChooseAFolder": "Choose a folder",
- "ButtonChooseFiles": "Choose files",
- "ButtonClearFilter": "Clear Filter",
- "ButtonCloseFeed": "Close Feed",
- "ButtonCollections": "Collections",
- "ButtonConfigureScanner": "Configure Scanner",
- "ButtonCreate": "Create",
- "ButtonCreateBackup": "Create Backup",
- "ButtonDelete": "Delete",
- "ButtonEdit": "Edit",
- "ButtonEditChapters": "Edit Chapters",
- "ButtonEditPodcast": "Edit Podcast",
- "ButtonForceReScan": "Force Re-Scan",
- "ButtonFullPath": "Full Path",
- "ButtonHide": "Hide",
- "ButtonHome": "Home",
- "ButtonIssues": "Issues",
- "ButtonLatest": "Latest",
- "ButtonLibrary": "Library",
- "ButtonLogout": "Logout",
- "ButtonLookup": "Lookup",
- "ButtonManageTracks": "Manage Tracks",
+ "ButtonAdd": "Agregar",
+ "ButtonAddChapters": "Agregar Capitulo",
+ "ButtonAddPodcasts": "Agregar Podcasts",
+ "ButtonAddYourFirstLibrary": "Agrega tu Primera Biblioteca",
+ "ButtonApply": "Aplicar",
+ "ButtonApplyChapters": "Aplicar Capítulos",
+ "ButtonAuthors": "Autores",
+ "ButtonBrowseForFolder": "Buscar por Carpeta",
+ "ButtonCancel": "Cancelar",
+ "ButtonCancelEncode": "Cancelar Codificador",
+ "ButtonChangeRootPassword": "Cambiar Contraseña Root",
+ "ButtonCheckAndDownloadNewEpisodes": "Verificar y Descargar Nuevos Episodios",
+ "ButtonChooseAFolder": "Escoger una Carpeta",
+ "ButtonChooseFiles": "Escoger un Archivo",
+ "ButtonClearFilter": "Quitar Filtros",
+ "ButtonCloseFeed": "Cerrar Fuente",
+ "ButtonCollections": "Colecciones",
+ "ButtonConfigureScanner": "Configurar Escáner",
+ "ButtonCreate": "Crear",
+ "ButtonCreateBackup": "Crear Respaldo",
+ "ButtonDelete": "Eliminar",
+ "ButtonDownloadQueue": "Queue",
+ "ButtonEdit": "Editar",
+ "ButtonEditChapters": "Editar Capitulo",
+ "ButtonEditPodcast": "Editar Podcast",
+ "ButtonForceReScan": "Forzar Re-Escanear",
+ "ButtonFullPath": "Ruta de Acceso Completa",
+ "ButtonHide": "Esconder",
+ "ButtonHome": "Inicio",
+ "ButtonIssues": "Problemas",
+ "ButtonLatest": "Últimos",
+ "ButtonLibrary": "Biblioteca",
+ "ButtonLogout": "Cerrar Sesión",
+ "ButtonLookup": "Buscar",
+ "ButtonManageTracks": "Administrar Pistas de Audio",
"ButtonMapChapterTitles": "Map Chapter Titles",
- "ButtonMatchAllAuthors": "Match All Authors",
- "ButtonMatchBooks": "Match Books",
- "ButtonNevermind": "Nevermind",
+ "ButtonMatchAllAuthors": "Encontrar Todos los Autores",
+ "ButtonMatchBooks": "Encontrar Libros",
+ "ButtonNevermind": "Olvidar",
"ButtonOk": "Ok",
- "ButtonOpenFeed": "Open Feed",
+ "ButtonOpenFeed": "Abrir Fuente",
"ButtonOpenManager": "Open Manager",
- "ButtonPlay": "Play",
- "ButtonPlaying": "Playing",
- "ButtonPlaylists": "Playlists",
- "ButtonPurgeAllCache": "Purge All Cache",
- "ButtonPurgeItemsCache": "Purge Items Cache",
- "ButtonPurgeMediaProgress": "Purge Media Progress",
- "ButtonQueueAddItem": "Add to queue",
- "ButtonQueueRemoveItem": "Remove from queue",
- "ButtonQuickMatch": "Quick Match",
- "ButtonRead": "Read",
- "ButtonRemove": "Remove",
- "ButtonRemoveAll": "Remove All",
- "ButtonRemoveAllLibraryItems": "Remove All Library Items",
- "ButtonRemoveFromContinueListening": "Remove from Continue Listening",
- "ButtonRemoveSeriesFromContinueSeries": "Remove Series from Continue Series",
- "ButtonReScan": "Re-Scan",
- "ButtonReset": "Reset",
- "ButtonRestore": "Restore",
- "ButtonSave": "Save",
- "ButtonSaveAndClose": "Save & Close",
- "ButtonSaveTracklist": "Save Tracklist",
- "ButtonScan": "Scan",
- "ButtonScanLibrary": "Scan Library",
- "ButtonSearch": "Search",
- "ButtonSelectFolderPath": "Select Folder Path",
+ "ButtonPlay": "Reproducir",
+ "ButtonPlaying": "Reproduciendo",
+ "ButtonPlaylists": "Listas de Reproducción",
+ "ButtonPurgeAllCache": "Purgar Todo el Cache",
+ "ButtonPurgeItemsCache": "Purgar Elementos de Cache",
+ "ButtonPurgeMediaProgress": "Purgar Progreso de Multimedia",
+ "ButtonQueueAddItem": "Agregar a la Fila",
+ "ButtonQueueRemoveItem": "Remover de la Fila",
+ "ButtonQuickMatch": "Encontrar Rápido",
+ "ButtonRead": "Leer",
+ "ButtonRemove": "Remover",
+ "ButtonRemoveAll": "Remover Todos",
+ "ButtonRemoveAllLibraryItems": "Remover Todos los Elementos de la Biblioteca",
+ "ButtonRemoveFromContinueListening": "Remover de Continuar Escuchando",
+ "ButtonRemoveSeriesFromContinueSeries": "Remover Serie de Continuar Series",
+ "ButtonReScan": "Re-Escanear",
+ "ButtonReset": "Reiniciar",
+ "ButtonRestore": "Restaurar",
+ "ButtonSave": "Guardar",
+ "ButtonSaveAndClose": "Guardar y Cerrar",
+ "ButtonSaveTracklist": "Guardar Tracklist",
+ "ButtonScan": "Escanear",
+ "ButtonScanLibrary": "Escanear Biblioteca",
+ "ButtonSearch": "Buscar",
+ "ButtonSelectFolderPath": "Seleccionar Ruta de Carpeta",
"ButtonSeries": "Series",
- "ButtonSetChaptersFromTracks": "Set chapters from tracks",
- "ButtonShiftTimes": "Shift Times",
- "ButtonShow": "Show",
- "ButtonStartM4BEncode": "Start M4B Encode",
- "ButtonStartMetadataEmbed": "Start Metadata Embed",
- "ButtonSubmit": "Submit",
- "ButtonUpload": "Upload",
- "ButtonUploadBackup": "Upload Backup",
- "ButtonUploadCover": "Upload Cover",
- "ButtonUploadOPMLFile": "Upload OPML File",
- "ButtonUserDelete": "Delete user {0}",
- "ButtonUserEdit": "Edit user {0}",
- "ButtonViewAll": "View All",
- "ButtonYes": "Yes",
- "HeaderAccount": "Account",
- "HeaderAdvanced": "Advanced",
- "HeaderAppriseNotificationSettings": "Apprise Notification Settings",
- "HeaderAudiobookTools": "Audiobook File Management Tools",
- "HeaderAudioTracks": "Audio Tracks",
- "HeaderBackups": "Backups",
- "HeaderChangePassword": "Change Password",
- "HeaderChapters": "Chapters",
- "HeaderChooseAFolder": "Choose a Folder",
- "HeaderCollection": "Collection",
- "HeaderCollectionItems": "Collection Items",
- "HeaderCover": "Cover",
- "HeaderDetails": "Details",
- "HeaderEpisodes": "Episodes",
- "HeaderFiles": "Files",
- "HeaderFindChapters": "Find Chapters",
- "HeaderIgnoredFiles": "Ignored Files",
- "HeaderItemFiles": "Item Files",
- "HeaderItemMetadataUtils": "Item Metadata Utils",
- "HeaderLastListeningSession": "Last Listening Session",
- "HeaderLatestEpisodes": "Latest episodes",
- "HeaderLibraries": "Libraries",
- "HeaderLibraryFiles": "Library Files",
- "HeaderLibraryStats": "Library Stats",
- "HeaderListeningSessions": "Listening Sessions",
- "HeaderListeningStats": "Listening Stats",
- "HeaderLogin": "Login",
+ "ButtonSetChaptersFromTracks": "Seleccionar Capítulos Según las Pistas",
+ "ButtonShiftTimes": "Desplazar Tiempos",
+ "ButtonShow": "Mostrar",
+ "ButtonStartM4BEncode": "Iniciar Codificación M4B",
+ "ButtonStartMetadataEmbed": "Iniciar la Inserción de Metadata",
+ "ButtonSubmit": "Enviar",
+ "ButtonUpload": "Subir",
+ "ButtonUploadBackup": "Subir Respaldo",
+ "ButtonUploadCover": "Subir Portada",
+ "ButtonUploadOPMLFile": "Subir Archivo OPML ",
+ "ButtonUserDelete": "Eliminar Usuario {0}",
+ "ButtonUserEdit": "Editar Usuario {0}",
+ "ButtonViewAll": "Ver Todos",
+ "ButtonYes": "Aceptar",
+ "HeaderAccount": "Cuenta",
+ "HeaderAdvanced": "Avanzado",
+ "HeaderAppriseNotificationSettings": "Ajustes de Notificaciones de Apprise",
+ "HeaderAudiobookTools": "Herramientas de Gestión de Archivos de Audiolibro",
+ "HeaderAudioTracks": "Pistas de Audio",
+ "HeaderBackups": "Respaldos",
+ "HeaderChangePassword": "Cambiar Contraseña",
+ "HeaderChapters": "Capítulos",
+ "HeaderChooseAFolder": "Escoger una Carpeta",
+ "HeaderCollection": "Colección",
+ "HeaderCollectionItems": "Elementos en la Colección",
+ "HeaderCover": "Portada",
+ "HeaderCurrentDownloads": "Descargando Actualmente",
+ "HeaderDetails": "Detalles",
+ "HeaderDownloadQueue": "Lista de Descarga",
+ "HeaderEpisodes": "Episodios",
+ "HeaderFiles": "Elemento",
+ "HeaderFindChapters": "Buscar Capitulo",
+ "HeaderIgnoredFiles": "Ignorar Elemento",
+ "HeaderItemFiles": "Carpetas de Elementos",
+ "HeaderItemMetadataUtils": "Utilidades de Metadata de Elementos",
+ "HeaderLastListeningSession": "Ultimas Sesiones",
+ "HeaderLatestEpisodes": "Últimos Episodios",
+ "HeaderLibraries": "Bibliotecas",
+ "HeaderLibraryFiles": "Archivos de Biblioteca",
+ "HeaderLibraryStats": "Estáticas de Biblioteca",
+ "HeaderListeningSessions": "Sesión",
+ "HeaderListeningStats": "Estadísticas de Tiempo Escuchado",
+ "HeaderLogin": "Iniciar Session",
"HeaderLogs": "Logs",
- "HeaderManageGenres": "Manage Genres",
- "HeaderManageTags": "Manage Tags",
+ "HeaderManageGenres": "Administrar Géneros",
+ "HeaderManageTags": "Administrar Etiquetas",
"HeaderMapDetails": "Map details",
- "HeaderMatch": "Match",
- "HeaderMetadataToEmbed": "Metadata to embed",
- "HeaderNewAccount": "New Account",
- "HeaderNewLibrary": "New Library",
- "HeaderNotifications": "Notifications",
- "HeaderOpenRSSFeed": "Open RSS Feed",
- "HeaderOtherFiles": "Other Files",
- "HeaderPermissions": "Permissions",
+ "HeaderMatch": "Encontrar",
+ "HeaderMetadataToEmbed": "Metadatos para Insertar",
+ "HeaderNewAccount": "Nueva Cuenta",
+ "HeaderNewLibrary": "Nueva Biblioteca",
+ "HeaderNotifications": "Notificaciones",
+ "HeaderOpenRSSFeed": "Abrir fuente RSS",
+ "HeaderOtherFiles": "Otros Archivos",
+ "HeaderPermissions": "Permisos",
"HeaderPlayerQueue": "Player Queue",
- "HeaderPlaylist": "Playlist",
- "HeaderPlaylistItems": "Playlist Items",
- "HeaderPodcastsToAdd": "Podcasts to Add",
- "HeaderPreviewCover": "Preview Cover",
- "HeaderRemoveEpisode": "Remove Episode",
- "HeaderRemoveEpisodes": "Remove {0} Episodes",
- "HeaderRSSFeedIsOpen": "RSS Feed is Open",
- "HeaderSavedMediaProgress": "Saved Media Progress",
- "HeaderSchedule": "Schedule",
- "HeaderScheduleLibraryScans": "Schedule Automatic Library Scans",
+ "HeaderPlaylist": "Lista de Reproducción",
+ "HeaderPlaylistItems": "Elementos de Lista de Reproducción",
+ "HeaderPodcastsToAdd": "Podcasts para agregar",
+ "HeaderPreviewCover": "Vista Previa de Portada",
+ "HeaderRemoveEpisode": "Remover Episodio",
+ "HeaderRemoveEpisodes": "Remover {0} Episodios",
+ "HeaderRSSFeedGeneral": "Detalles RSS",
+ "HeaderRSSFeedIsOpen": "Fuente RSS esta abierta",
+ "HeaderSavedMediaProgress": "Guardar Progreso de multimedia",
+ "HeaderSchedule": "Horario",
+ "HeaderScheduleLibraryScans": "Programar Escaneo Automático de Biblioteca",
"HeaderSession": "Session",
- "HeaderSetBackupSchedule": "Set Backup Schedule",
- "HeaderSettings": "Settings",
+ "HeaderSetBackupSchedule": "Programar Respaldo",
+ "HeaderSettings": "Configuraciones",
"HeaderSettingsDisplay": "Display",
- "HeaderSettingsExperimental": "Experimental Features",
+ "HeaderSettingsExperimental": "Funciones Experimentales",
"HeaderSettingsGeneral": "General",
- "HeaderSettingsScanner": "Scanner",
- "HeaderSleepTimer": "Sleep Timer",
- "HeaderStatsLongestItems": "Longest Items (hrs)",
- "HeaderStatsMinutesListeningChart": "Minutes Listening (last 7 days)",
- "HeaderStatsRecentSessions": "Recent Sessions",
- "HeaderStatsTop10Authors": "Top 10 Authors",
- "HeaderStatsTop5Genres": "Top 5 Genres",
- "HeaderTools": "Tools",
- "HeaderUpdateAccount": "Update Account",
- "HeaderUpdateAuthor": "Update Author",
- "HeaderUpdateDetails": "Update Details",
- "HeaderUpdateLibrary": "Update Library",
- "HeaderUsers": "Users",
- "HeaderYourStats": "Your Stats",
- "LabelAccountType": "Account Type",
- "LabelAccountTypeAdmin": "Admin",
- "LabelAccountTypeGuest": "Guest",
- "LabelAccountTypeUser": "User",
- "LabelActivity": "Activity",
- "LabelAddedAt": "Added At",
- "LabelAddToCollection": "Add to Collection",
- "LabelAddToCollectionBatch": "Add {0} Books to Collection",
- "LabelAddToPlaylist": "Add to Playlist",
- "LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
- "LabelAll": "All",
- "LabelAllUsers": "All Users",
- "LabelAppend": "Append",
- "LabelAuthor": "Author",
- "LabelAuthorFirstLast": "Author (First Last)",
- "LabelAuthorLastFirst": "Author (Last, First)",
- "LabelAuthors": "Authors",
- "LabelAutoDownloadEpisodes": "Auto Download Episodes",
- "LabelBackToUser": "Back to User",
- "LabelBackupsEnableAutomaticBackups": "Enable automatic backups",
- "LabelBackupsEnableAutomaticBackupsHelp": "Backups saved in /metadata/backups",
- "LabelBackupsMaxBackupSize": "Maximum backup size (in GB)",
- "LabelBackupsMaxBackupSizeHelp": "As a safeguard against misconfiguration, backups will fail if they exceed the configured size.",
- "LabelBackupsNumberToKeep": "Number of backups to keep",
- "LabelBackupsNumberToKeepHelp": "Only 1 backup will be removed at a time so if you already have more backups than this you should manually remove them.",
- "LabelBooks": "Books",
- "LabelChangePassword": "Change Password",
- "LabelChaptersFound": "chapters found",
- "LabelChapterTitle": "Chapter Title",
+ "HeaderSettingsScanner": "Escáner",
+ "HeaderSleepTimer": "Temporizador para Dormir",
+ "HeaderStatsLargestItems": "Artículos mas Grandes",
+ "HeaderStatsLongestItems": "Artículos mas Largos (h)",
+ "HeaderStatsMinutesListeningChart": "Minutos Escuchando (Últimos 7 días)",
+ "HeaderStatsRecentSessions": "Sesiones Recientes",
+ "HeaderStatsTop10Authors": "Top 10 Autores",
+ "HeaderStatsTop5Genres": "Top 5 Géneros",
+ "HeaderTools": "Herramientas",
+ "HeaderUpdateAccount": "Actualizar Cuenta",
+ "HeaderUpdateAuthor": "Actualizar Autor",
+ "HeaderUpdateDetails": "Actualizar Detalles",
+ "HeaderUpdateLibrary": "Actualizar Biblioteca",
+ "HeaderUsers": "Usuarios",
+ "HeaderYourStats": "Tus Estáticas",
+ "LabelAccountType": "Tipo de Cuenta",
+ "LabelAccountTypeAdmin": "Administrador",
+ "LabelAccountTypeGuest": "Invitado",
+ "LabelAccountTypeUser": "Usuario",
+ "LabelActivity": "Actividad",
+ "LabelAddedAt": "Añadido",
+ "LabelAddToCollection": "Añadido a la Colección",
+ "LabelAddToCollectionBatch": "Se Añadieron {0} Libros a la Colección",
+ "LabelAddToPlaylist": "Añadido a la Lista de Reproducción",
+ "LabelAddToPlaylistBatch": "Se Añadieron {0} Artículos a la Lista de Reproducción",
+ "LabelAll": "Todos",
+ "LabelAllUsers": "Todos los Usuarios",
+ "LabelAlreadyInYourLibrary": "Ya en la Biblioteca",
+ "LabelAppend": "Adjuntar",
+ "LabelAuthor": "Autor",
+ "LabelAuthorFirstLast": "Autor (Nombre Apellido)",
+ "LabelAuthorLastFirst": "Autor (Apellido, Nombre)",
+ "LabelAuthors": "Autores",
+ "LabelAutoDownloadEpisodes": "Descargar Episodios Automáticamente",
+ "LabelBackToUser": "Regresar a Usuario",
+ "LabelBackupsEnableAutomaticBackups": "Habilitar Respaldo Automático",
+ "LabelBackupsEnableAutomaticBackupsHelp": "Respaldo Guardado en /metadata/backups",
+ "LabelBackupsMaxBackupSize": "Tamaño Máximo de Respaldos (en GB)",
+ "LabelBackupsMaxBackupSizeHelp": "Como protección contra una configuración errónea, los respaldos fallaran si se excede el tamaño configurado.",
+ "LabelBackupsNumberToKeep": "Numero de respaldos para conservar",
+ "LabelBackupsNumberToKeepHelp": "Solamente 1 respaldo se removerá a la vez. Si tiene mas respaldos guardados, necesita removerlos manualmente.",
+ "LabelBooks": "Libros",
+ "LabelChangePassword": "Cambiar Contraseña",
+ "LabelChaptersFound": "Capitulo Encontrado",
+ "LabelChapterTitle": "Titulo del Capitulo",
"LabelClosePlayer": "Close player",
- "LabelCollapseSeries": "Collapse Series",
- "LabelCollections": "Collections",
- "LabelComplete": "Complete",
- "LabelConfirmPassword": "Confirm Password",
- "LabelContinueListening": "Continue Listening",
- "LabelContinueSeries": "Continue Series",
- "LabelCover": "Cover",
- "LabelCoverImageURL": "Cover Image URL",
- "LabelCreatedAt": "Created At",
+ "LabelCollapseSeries": "Colapsar Series",
+ "LabelCollections": "Colecciones",
+ "LabelComplete": "Completo",
+ "LabelConfirmPassword": "Confirmar Contraseña",
+ "LabelContinueListening": "Continuar Escuchando",
+ "LabelContinueSeries": "Continuar Series",
+ "LabelCover": "Portada",
+ "LabelCoverImageURL": "URL de Imagen de Portada",
+ "LabelCreatedAt": "Creado",
"LabelCronExpression": "Cron Expression",
- "LabelCurrent": "Current",
- "LabelCurrently": "Currently:",
+ "LabelCurrent": "Actual",
+ "LabelCurrently": "En este momento:",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Datetime",
- "LabelDescription": "Description",
- "LabelDeselectAll": "Deselect All",
- "LabelDevice": "Device",
- "LabelDeviceInfo": "Device Info",
- "LabelDirectory": "Directory",
- "LabelDiscFromFilename": "Disc from Filename",
- "LabelDiscFromMetadata": "Disc from Metadata",
- "LabelDownload": "Download",
- "LabelDuration": "Duration",
- "LabelDurationFound": "Duration found:",
- "LabelEdit": "Edit",
- "LabelEnable": "Enable",
- "LabelEnd": "End",
- "LabelEpisode": "Episode",
- "LabelEpisodeTitle": "Episode Title",
- "LabelEpisodeType": "Episode Type",
- "LabelExplicit": "Explicit",
- "LabelFeedURL": "Feed URL",
- "LabelFile": "File",
- "LabelFileBirthtime": "File Birthtime",
- "LabelFileModified": "File Modified",
- "LabelFilename": "Filename",
- "LabelFilterByUser": "Filter by User",
- "LabelFindEpisodes": "Find Episodes",
- "LabelFinished": "Finished",
- "LabelFolder": "Folder",
- "LabelFolders": "Folders",
- "LabelGenre": "Genre",
- "LabelGenres": "Genres",
- "LabelHardDeleteFile": "Hard delete file",
- "LabelHour": "Hour",
- "LabelIcon": "Icon",
- "LabelIncludeInTracklist": "Include in Tracklist",
- "LabelIncomplete": "Incomplete",
- "LabelInProgress": "In Progress",
- "LabelInterval": "Interval",
- "LabelIntervalCustomDailyWeekly": "Custom daily/weekly",
- "LabelIntervalEvery12Hours": "Every 12 hours",
- "LabelIntervalEvery15Minutes": "Every 15 minutes",
- "LabelIntervalEvery2Hours": "Every 2 hours",
- "LabelIntervalEvery30Minutes": "Every 30 minutes",
- "LabelIntervalEvery6Hours": "Every 6 hours",
- "LabelIntervalEveryDay": "Every day",
- "LabelIntervalEveryHour": "Every hour",
- "LabelInvalidParts": "Invalid Parts",
- "LabelItem": "Item",
- "LabelLanguage": "Language",
- "LabelLanguageDefaultServer": "Default Server Language",
- "LabelLastSeen": "Last Seen",
- "LabelLastTime": "Last Time",
- "LabelLastUpdate": "Last Update",
- "LabelLess": "Less",
- "LabelLibrariesAccessibleToUser": "Libraries Accessible to User",
- "LabelLibrary": "Library",
- "LabelLibraryItem": "Library Item",
- "LabelLibraryName": "Library Name",
- "LabelLimit": "Limit",
- "LabelListenAgain": "Listen Again",
+ "LabelDescription": "Descripción",
+ "LabelDeselectAll": "Deseleccionar Todos",
+ "LabelDevice": "Dispositivo",
+ "LabelDeviceInfo": "Información de Dispositivo",
+ "LabelDirectory": "Directorio",
+ "LabelDiscFromFilename": "Disco a partir del Nombre del Archivo",
+ "LabelDiscFromMetadata": "Disco a partir de Metadata",
+ "LabelDownload": "Descargar",
+ "LabelDuration": "Duración",
+ "LabelDurationFound": "Duración Comprobada:",
+ "LabelEdit": "Editar",
+ "LabelEnable": "Habilitar",
+ "LabelEnd": "Fin",
+ "LabelEpisode": "Episodio",
+ "LabelEpisodeTitle": "Titulo de Episodio",
+ "LabelEpisodeType": "Tipo de Episodio",
+ "LabelExample": "Ejemplo",
+ "LabelExplicit": "Explicito",
+ "LabelFeedURL": "Fuente de URL",
+ "LabelFile": "Archivo",
+ "LabelFileBirthtime": "Archivo Creado en",
+ "LabelFileModified": "Archivo modificado",
+ "LabelFilename": "Nombre del Archivo",
+ "LabelFilterByUser": "Filtrar por Usuario",
+ "LabelFindEpisodes": "Buscar Episodio",
+ "LabelFinished": "Terminado",
+ "LabelFolder": "Carpeta",
+ "LabelFolders": "Carpetas",
+ "LabelGenre": "Genero",
+ "LabelGenres": "Géneros",
+ "LabelHardDeleteFile": "Eliminar Definitivamente",
+ "LabelHour": "Hora",
+ "LabelIcon": "Icono",
+ "LabelIncludeInTracklist": "Incluir en Tracklist",
+ "LabelIncomplete": "Incompleto",
+ "LabelInProgress": "En Proceso",
+ "LabelInterval": "Intervalo",
+ "LabelIntervalCustomDailyWeekly": "Personalizar diario/semanal",
+ "LabelIntervalEvery12Hours": "Cada 12 Horas",
+ "LabelIntervalEvery15Minutes": "Cada 15 minutos",
+ "LabelIntervalEvery2Hours": "Cada 2 Horas",
+ "LabelIntervalEvery30Minutes": "Cada 30 minutos",
+ "LabelIntervalEvery6Hours": "Cada 6 Horas",
+ "LabelIntervalEveryDay": "Cada Dia",
+ "LabelIntervalEveryHour": "Cada Hora",
+ "LabelInvalidParts": "Partes Invalidas",
+ "LabelItem": "Elemento",
+ "LabelLanguage": "Lenguaje",
+ "LabelLanguageDefaultServer": "Lenguaje Predeterminado del Servidor",
+ "LabelLastSeen": "Ultima Vez Visto",
+ "LabelLastTime": "Ultima Vez",
+ "LabelLastUpdate": "Ultima Actualización",
+ "LabelLess": "Menos",
+ "LabelLibrariesAccessibleToUser": "Bibliotecas Disponibles para el Usuario",
+ "LabelLibrary": "Biblioteca",
+ "LabelLibraryItem": "Elemento de Biblioteca",
+ "LabelLibraryName": "Nombre de Biblioteca",
+ "LabelLimit": "Limites",
+ "LabelListenAgain": "Escuchar Otra Vez",
"LabelLogLevelDebug": "Debug",
"LabelLogLevelInfo": "Info",
- "LabelLogLevelWarn": "Warn",
- "LabelLookForNewEpisodesAfterDate": "Look for new episodes after this date",
+ "LabelLogLevelWarn": "Advertencia",
+ "LabelLookForNewEpisodesAfterDate": "Buscar Nuevos Episodios a partir de esta Fecha",
"LabelMediaPlayer": "Media Player",
- "LabelMediaType": "Media Type",
- "LabelMetadataProvider": "Metadata Provider",
+ "LabelMediaType": "Tipo de Multimedia",
+ "LabelMetadataProvider": "Proveedor de Metadata",
"LabelMetaTag": "Meta Tag",
- "LabelMinute": "Minute",
- "LabelMissing": "Missing",
- "LabelMissingParts": "Missing Parts",
- "LabelMore": "More",
- "LabelName": "Name",
- "LabelNarrator": "Narrator",
- "LabelNarrators": "Narrators",
- "LabelNew": "New",
- "LabelNewestAuthors": "Newest Authors",
- "LabelNewestEpisodes": "Newest Episodes",
- "LabelNewPassword": "New Password",
- "LabelNotes": "Notes",
- "LabelNotFinished": "Not Finished",
+ "LabelMinute": "Minuto",
+ "LabelMissing": "Ausente",
+ "LabelMissingParts": "Partes Ausentes",
+ "LabelMore": "Mas",
+ "LabelName": "Nombre",
+ "LabelNarrator": "Narrador",
+ "LabelNarrators": "Narradores",
+ "LabelNew": "Nuevo",
+ "LabelNewestAuthors": "Nuevos Autores",
+ "LabelNewestEpisodes": "Nuevos Episodios",
+ "LabelNewPassword": "Nueva Contraseña",
+ "LabelNextBackupDate": "Fecha del Siguiente Respaldo",
+ "LabelNextScheduledRun": "Próxima Ejecución Programada",
+ "LabelNotes": "Notas",
+ "LabelNotFinished": "No Terminado",
"LabelNotificationAppriseURL": "Apprise URL(s)",
- "LabelNotificationAvailableVariables": "Available variables",
- "LabelNotificationBodyTemplate": "Body Template",
- "LabelNotificationEvent": "Notification Event",
- "LabelNotificationsMaxFailedAttempts": "Max failed attempts",
- "LabelNotificationsMaxFailedAttemptsHelp": "Notifications are disabled once they fail to send this many times",
- "LabelNotificationsMaxQueueSize": "Max queue size for notification events",
- "LabelNotificationsMaxQueueSizeHelp": "Events are limited to firing 1 per second. Events will be ignored if the queue is at max size. This prevents notification spamming.",
- "LabelNotificationTitleTemplate": "Title Template",
- "LabelNotStarted": "Not Started",
- "LabelNumberOfBooks": "Number of Books",
- "LabelNumberOfEpisodes": "# of Episodes",
- "LabelOpenRSSFeed": "Open RSS Feed",
- "LabelOverwrite": "Overwrite",
- "LabelPassword": "Password",
- "LabelPath": "Path",
- "LabelPermissionsAccessAllLibraries": "Can Access All Libraries",
- "LabelPermissionsAccessAllTags": "Can Access All Tags",
- "LabelPermissionsAccessExplicitContent": "Can Access Explicit Content",
- "LabelPermissionsDelete": "Can Delete",
- "LabelPermissionsDownload": "Can Download",
- "LabelPermissionsUpdate": "Can Update",
- "LabelPermissionsUpload": "Can Upload",
- "LabelPhotoPathURL": "Photo Path/URL",
- "LabelPlaylists": "Playlists",
- "LabelPlayMethod": "Play Method",
+ "LabelNotificationAvailableVariables": "Variables Disponibles",
+ "LabelNotificationBodyTemplate": "Plantilla de Cuerpo",
+ "LabelNotificationEvent": "Evento de Notificación",
+ "LabelNotificationsMaxFailedAttempts": "Máximo de Intentos Fallidos",
+ "LabelNotificationsMaxFailedAttemptsHelp": "Las notificaciones se desactivan después de fallar este numero de veces",
+ "LabelNotificationsMaxQueueSize": "Tamaño máximo de la cola de notificación",
+ "LabelNotificationsMaxQueueSizeHelp": "Las notificaciones están limitadas a 1 por segundo. Las notificaciones serán ignorados si llegan al numero máximo de cola para prevenir spam de eventos.",
+ "LabelNotificationTitleTemplate": "Plantilla de Titulo",
+ "LabelNotStarted": "Sin Iniciar",
+ "LabelNumberOfBooks": "Numero de Libros",
+ "LabelNumberOfEpisodes": "# de Episodios",
+ "LabelOpenRSSFeed": "Abrir Fuente RSS",
+ "LabelOverwrite": "Sobrescribir",
+ "LabelPassword": "Contraseña",
+ "LabelPath": "Ruta de Carpeta",
+ "LabelPermissionsAccessAllLibraries": "Puede Accesar a Todas las bibliotecas",
+ "LabelPermissionsAccessAllTags": "Pueda Accesar a Todas las Etiquetas",
+ "LabelPermissionsAccessExplicitContent": "Puede Accesar a Contenido Explicito",
+ "LabelPermissionsDelete": "Puede Eliminar",
+ "LabelPermissionsDownload": "Puede Descargar",
+ "LabelPermissionsUpdate": "Puede Actualizar",
+ "LabelPermissionsUpload": "Puede Subir",
+ "LabelPhotoPathURL": "Ruta de Acceso/URL de Foto",
+ "LabelPlaylists": "Lista de Reproducción",
+ "LabelPlayMethod": "Método de Reproducción",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts",
- "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
- "LabelProgress": "Progress",
- "LabelProvider": "Provider",
- "LabelPubDate": "Pub Date",
- "LabelPublisher": "Publisher",
- "LabelPublishYear": "Publish Year",
- "LabelRecentlyAdded": "Recently Added",
- "LabelRecentSeries": "Recent Series",
- "LabelRecommended": "Recommended",
+ "LabelPodcastType": "Tipo Podcast",
+ "LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)",
+ "LabelPreventIndexing": "Evite que su fuente sea indexado por iTunes y Google podcast directories",
+ "LabelProgress": "Progreso",
+ "LabelProvider": "Proveedor",
+ "LabelPubDate": "Fecha de Publicación",
+ "LabelPublisher": "Editor",
+ "LabelPublishYear": "Año de Publicación",
+ "LabelRecentlyAdded": "Agregado Reciente",
+ "LabelRecentSeries": "Series Recientes",
+ "LabelRecommended": "Recomendados",
"LabelRegion": "Region",
- "LabelReleaseDate": "Release Date",
- "LabelRemoveCover": "Remove cover",
- "LabelRSSFeedOpen": "RSS Feed Open",
- "LabelRSSFeedSlug": "RSS Feed Slug",
- "LabelRSSFeedURL": "RSS Feed URL",
- "LabelSearchTerm": "Search Term",
- "LabelSearchTitle": "Search Title",
- "LabelSearchTitleOrASIN": "Search Title or ASIN",
- "LabelSeason": "Season",
- "LabelSequence": "Sequence",
+ "LabelReleaseDate": "Fecha de Estreno",
+ "LabelRemoveCover": "Remover Portada",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
+ "LabelRSSFeedOpen": "Fuente RSS Abierta",
+ "LabelRSSFeedPreventIndexing": "Prevenir Indaxación",
+ "LabelRSSFeedSlug": "Fuente RSS Slug",
+ "LabelRSSFeedURL": "URL de Fuente RSS",
+ "LabelSearchTerm": "Buscar Termino",
+ "LabelSearchTitle": "Buscar Titulo",
+ "LabelSearchTitleOrASIN": "Buscar Titulo o ASIN",
+ "LabelSeason": "Temporada",
+ "LabelSequence": "Secuencia",
"LabelSeries": "Series",
- "LabelSeriesName": "Series Name",
- "LabelSeriesProgress": "Series Progress",
- "LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
- "LabelSettingsChromecastSupport": "Chromecast support",
- "LabelSettingsDateFormat": "Date Format",
- "LabelSettingsDisableWatcher": "Disable Watcher",
- "LabelSettingsDisableWatcherForLibrary": "Disable folder watcher for library",
- "LabelSettingsDisableWatcherHelp": "Disables the automatic adding/updating of items when file changes are detected. *Requires server restart",
- "LabelSettingsEnableEReader": "Enable e-reader for all users",
- "LabelSettingsEnableEReaderHelp": "E-reader is still a work in progress, but use this setting to open it up to all your users (or use the \"Experimental Features\" toggle just for use by you)",
- "LabelSettingsExperimentalFeatures": "Experimental features",
- "LabelSettingsExperimentalFeaturesHelp": "Features in development that could use your feedback and help testing. Click to open github discussion.",
- "LabelSettingsFindCovers": "Find covers",
- "LabelSettingsFindCoversHelp": "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",
- "LabelSettingsHomePageBookshelfView": "Home page use bookshelf view",
- "LabelSettingsLibraryBookshelfView": "Library use bookshelf view",
- "LabelSettingsOverdriveMediaMarkers": "Use Overdrive Media Markers for chapters",
- "LabelSettingsOverdriveMediaMarkersHelp": "MP3 files from Overdrive come with chapter timings embedded as custom metadata. Enabling this will use these tags for chapter timings automatically",
+ "LabelSeriesName": "Nombre de la Serie",
+ "LabelSeriesProgress": "Progreso de la Serie",
+ "LabelSettingsBookshelfViewHelp": "Diseño Skeumorphic con Estantes de Madera",
+ "LabelSettingsChromecastSupport": "Soporte para Chromecast",
+ "LabelSettingsDateFormat": "Formato de Fecha",
+ "LabelSettingsDisableWatcher": "Deshabilitar Watcher",
+ "LabelSettingsDisableWatcherForLibrary": "Deshabilitar Watcher de Carpetas para esta biblioteca",
+ "LabelSettingsDisableWatcherHelp": "Deshabilitar la función automática de agregar/actualizar los elementos, cuando se detecta cambio en los archivos. *Require Reiniciar el Servidor",
+ "LabelSettingsEnableEReader": "Habilitar e-reader para todos los usuarios",
+ "LabelSettingsEnableEReaderHelp": "E-reader sigue en proceso, pero use esta configuración para hacerlo disponible a todos los usuarios. (o use las \"Funciones Experimentales\" para habilitarla para solo este usuario)",
+ "LabelSettingsExperimentalFeatures": "Funciones Experimentales",
+ "LabelSettingsExperimentalFeaturesHelp": "Funciones en desarrollo sobre las que esperamos sus comentarios y experiencia. Haga click aquí para abrir una conversación en Github.",
+ "LabelSettingsFindCovers": "Buscar Portadas",
+ "LabelSettingsFindCoversHelp": "Si tu audiolibro no tiene una portada incluida o la portada no esta dentro de la carpeta, el escaneador tratara de encontrar una portada.
Nota: Esto extenderá el tiempo de escaneo",
+ "LabelSettingsHomePageBookshelfView": "La pagina de inicio usa la vista de librero",
+ "LabelSettingsLibraryBookshelfView": "La biblioteca usa la vista de librero",
+ "LabelSettingsOverdriveMediaMarkers": "Usar Markers de multimedia en Overdrive para estos capítulos",
+ "LabelSettingsOverdriveMediaMarkersHelp": "Archivos MP3 de Overdrive vienen con capítulos con tiempos incrustados como metadata personalizada. Habilitar esto utilizará estas etiquetas para los tiempos de los capítulos automáticamente.",
"LabelSettingsParseSubtitles": "Parse subtitles",
- "LabelSettingsParseSubtitlesHelp": "Extract subtitles from audiobook folder names.
Subtitle must be seperated by \" - \"
i.e. \"Book Title - A Subtitle Here\" has the subtitle \"A Subtitle Here\"",
- "LabelSettingsPreferAudioMetadata": "Prefer audio metadata",
- "LabelSettingsPreferAudioMetadataHelp": "Audio file ID3 meta tags will be used for book details over folder names",
+ "LabelSettingsParseSubtitlesHelp": "Extraiga subtítulos de los nombres de las carpetas de los audiolibros.
Los subtítulos deben estar separados por \" - \"
ejemplo. \"Titulo Libro - Este Subtitulo\" tiene el subtitulo \"Este Subtitulo\"",
+ "LabelSettingsPreferAudioMetadata": "Preferir metadata del audio",
+ "LabelSettingsPreferAudioMetadataHelp": "Archivos de Audio ID3 meta tags se utilizarán para detalles de libros en vez de los nombres de carpetas",
"LabelSettingsPreferMatchedMetadata": "Prefer matched metadata",
- "LabelSettingsPreferMatchedMetadataHelp": "Matched data will overide item details when using Quick Match. By default Quick Match will only fill in missing details.",
- "LabelSettingsPreferOPFMetadata": "Prefer OPF metadata",
- "LabelSettingsPreferOPFMetadataHelp": "OPF file metadata will be used for book details over folder names",
- "LabelSettingsSkipMatchingBooksWithASIN": "Skip matching books that already have an ASIN",
- "LabelSettingsSkipMatchingBooksWithISBN": "Skip matching books that already have an ISBN",
- "LabelSettingsSortingIgnorePrefixes": "Ignore prefixes when sorting",
- "LabelSettingsSortingIgnorePrefixesHelp": "i.e. for prefix \"the\" book title \"The Book Title\" would sort as \"Book Title, The\"",
- "LabelSettingsSquareBookCovers": "Use square book covers",
- "LabelSettingsSquareBookCoversHelp": "Prefer to use square covers over standard 1.6:1 book covers",
- "LabelSettingsStoreCoversWithItem": "Store covers with item",
- "LabelSettingsStoreCoversWithItemHelp": "By default covers are stored in /metadata/items, enabling this setting will store covers in your library item folder. Only one file named \"cover\" will be kept",
- "LabelSettingsStoreMetadataWithItem": "Store metadata with item",
- "LabelSettingsStoreMetadataWithItemHelp": "By default metadata files are stored in /metadata/items, enabling this setting will store metadata files in your library item folders. Uses .abs file extension",
- "LabelShowAll": "Show All",
- "LabelSize": "Size",
- "LabelSleepTimer": "Sleep timer",
- "LabelStart": "Start",
- "LabelStarted": "Started",
- "LabelStartedAt": "Started At",
- "LabelStartTime": "Start Time",
- "LabelStatsAudioTracks": "Audio Tracks",
- "LabelStatsAuthors": "Authors",
- "LabelStatsBestDay": "Best Day",
- "LabelStatsDailyAverage": "Daily Average",
- "LabelStatsDays": "Days",
- "LabelStatsDaysListened": "Days Listened",
- "LabelStatsHours": "Hours",
- "LabelStatsInARow": "in a row",
- "LabelStatsItemsFinished": "Items Finished",
- "LabelStatsItemsInLibrary": "Items in Library",
- "LabelStatsMinutes": "minutes",
- "LabelStatsMinutesListening": "Minutes Listening",
- "LabelStatsOverallDays": "Overall Days",
- "LabelStatsOverallHours": "Overall Hours",
- "LabelStatsWeekListening": "Week Listening",
- "LabelSubtitle": "Subtitle",
- "LabelSupportedFileTypes": "Supported File Types",
- "LabelTag": "Tag",
- "LabelTags": "Tags",
- "LabelTagsAccessibleToUser": "Tags Accessible to User",
- "LabelTimeListened": "Time Listened",
- "LabelTimeListenedToday": "Time Listened Today",
- "LabelTimeRemaining": "{0} remaining",
- "LabelTimeToShift": "Time to shift in seconds",
- "LabelTitle": "Title",
- "LabelToolsEmbedMetadata": "Embed Metadata",
- "LabelToolsEmbedMetadataDescription": "Embed metadata into audio files including cover image and chapters.",
- "LabelToolsMakeM4b": "Make M4B Audiobook File",
- "LabelToolsMakeM4bDescription": "Generate a .M4B audiobook file with embedded metadata, cover image, and chapters.",
- "LabelToolsSplitM4b": "Split M4B to MP3's",
- "LabelToolsSplitM4bDescription": "Create MP3's from an M4B split by chapters with embedded metadata, cover image, and chapters.",
- "LabelTotalDuration": "Total Duration",
- "LabelTotalTimeListened": "Total Time Listened",
- "LabelTrackFromFilename": "Track from Filename",
- "LabelTrackFromMetadata": "Track from Metadata",
- "LabelTracks": "Tracks",
+ "LabelSettingsPreferMatchedMetadataHelp": "Los datos coincidentes anularán los detalles del elemento cuando se utilice Quick Match. Por defecto, Quick Match solo completará los detalles faltantes.",
+ "LabelSettingsPreferOPFMetadata": "Preferir OPF metadata",
+ "LabelSettingsPreferOPFMetadataHelp": "Los archivos de metadata OPF serán usados para los detalles del libro en vez de el nombre de las carpetas",
+ "LabelSettingsSkipMatchingBooksWithASIN": "Omitir libros coincidentes que ya tengan un ASIN",
+ "LabelSettingsSkipMatchingBooksWithISBN": "Omitir libros coincidentes que ya tengan un ISBN",
+ "LabelSettingsSortingIgnorePrefixes": "Ignorar prefijos al ordenando",
+ "LabelSettingsSortingIgnorePrefixesHelp": "ejemplo. el prefijo \"el\" del titulo \"El titulo del libro\" sera ordenado como \"Titulo del Libro, el\"",
+ "LabelSettingsSquareBookCovers": "Usar portadas cuadradas",
+ "LabelSettingsSquareBookCoversHelp": "Prefiere usar portadas cuadradas sobre las portadas estándar 1.6:1",
+ "LabelSettingsStoreCoversWithItem": "Guardar portada con elemento",
+ "LabelSettingsStoreCoversWithItemHelp": "Por defecto, las portadas se almacenan en /metadata/items, si habilita esta configuración, las portadas se almacenará en la carpeta de elementos de su biblioteca. Solamente un archivo llamado \"cover\" sera guardado.",
+ "LabelSettingsStoreMetadataWithItem": "Guardar metadata con elemento",
+ "LabelSettingsStoreMetadataWithItemHelp": "Por defecto, los archivos de metadatos se almacenan en /metadata/items, si habilita esta configuración, los archivos de metadata se guardaran en la carpeta de elementos de tu biblioteca. Usa la extension .abs",
+ "LabelSettingsTimeFormat": "Format de Tiempo",
+ "LabelShowAll": "Mostrar Todos",
+ "LabelSize": "Tamaño",
+ "LabelSleepTimer": "Temporizador para Dormir",
+ "LabelStart": "Iniciar",
+ "LabelStarted": "Indiciado",
+ "LabelStartedAt": "Iniciado En",
+ "LabelStartTime": "Tiempo de Inicio",
+ "LabelStatsAudioTracks": "Pistas de Audio",
+ "LabelStatsAuthors": "Autores",
+ "LabelStatsBestDay": "Mejor Dia",
+ "LabelStatsDailyAverage": "Promedio Diario",
+ "LabelStatsDays": "Dias",
+ "LabelStatsDaysListened": "Dias Escuchando",
+ "LabelStatsHours": "Horas",
+ "LabelStatsInARow": "seguidos",
+ "LabelStatsItemsFinished": "Elementos Terminados",
+ "LabelStatsItemsInLibrary": "Elementos en biblioteca",
+ "LabelStatsMinutes": "minutos",
+ "LabelStatsMinutesListening": "Minutos Escuchando",
+ "LabelStatsOverallDays": "Total de Dias",
+ "LabelStatsOverallHours": "Total de Horas",
+ "LabelStatsWeekListening": "Escuchando en la Semana",
+ "LabelSubtitle": "Subtitulo",
+ "LabelSupportedFileTypes": "Tipo de Archivos Soportados",
+ "LabelTag": "Etiqueta",
+ "LabelTags": "Etiquetas",
+ "LabelTagsAccessibleToUser": "Etiquetas Accessible para el Usuario",
+ "LabelTasks": "Tareas Corriendo",
+ "LabelTimeListened": "Tiempo Escuchando",
+ "LabelTimeListenedToday": "Tiempo Escuchando Hoy",
+ "LabelTimeRemaining": "{0} restante",
+ "LabelTimeToShift": "Tiempo para Cambiar en Segundos",
+ "LabelTitle": "Titulo",
+ "LabelToolsEmbedMetadata": "Incorporar Metadata",
+ "LabelToolsEmbedMetadataDescription": "Incorpora metadata en archivos de audio incluyendo la portada y capítulos.",
+ "LabelToolsMakeM4b": "Hacer Archivo M4B de Audiolibro",
+ "LabelToolsMakeM4bDescription": "Generar archivo .M4B de audiolibro con metadata, imágenes de portada y capítulos incorporados.",
+ "LabelToolsSplitM4b": "Dividir M4B en Archivos MP3",
+ "LabelToolsSplitM4bDescription": "Dividir M4B en Archivos MP3 y incorporar metadata, images de portada y capítulos.",
+ "LabelTotalDuration": "Duración Total",
+ "LabelTotalTimeListened": "Tiempo Total Escuchado",
+ "LabelTrackFromFilename": "Pista desde el Nombre del Archivo",
+ "LabelTrackFromMetadata": "Pista desde Metadata",
+ "LabelTracks": "Pistas",
"LabelTracksMultiTrack": "Multi-track",
"LabelTracksSingleTrack": "Single-track",
- "LabelType": "Type",
- "LabelUnknown": "Unknown",
- "LabelUpdateCover": "Update Cover",
- "LabelUpdateCoverHelp": "Allow overwriting of existing covers for the selected books when a match is located",
- "LabelUpdatedAt": "Updated At",
- "LabelUpdateDetails": "Update Details",
- "LabelUpdateDetailsHelp": "Allow overwriting of existing details for the selected books when a match is located",
- "LabelUploaderDragAndDrop": "Drag & drop files or folders",
- "LabelUploaderDropFiles": "Drop files",
- "LabelUseChapterTrack": "Use chapter track",
- "LabelUseFullTrack": "Use full track",
- "LabelUser": "User",
- "LabelUsername": "Username",
- "LabelValue": "Value",
- "LabelVersion": "Version",
- "LabelViewBookmarks": "View bookmarks",
- "LabelViewChapters": "View chapters",
- "LabelViewQueue": "View player queue",
- "LabelVolume": "Volume",
- "LabelWeekdaysToRun": "Weekdays to run",
- "LabelYourAudiobookDuration": "Your audiobook duration",
- "LabelYourBookmarks": "Your Bookmarks",
- "LabelYourPlaylists": "Your Playlists",
- "LabelYourProgress": "Your Progress",
- "MessageAddToPlayerQueue": "Add to player queue",
- "MessageAppriseDescription": "To use this feature you will need to have an instance of
Apprise API running or an api that will handle those same requests.
The Apprise API Url should be the full URL path to send the notification, e.g., if your API instance is served at
http://192.168.1.1:8337
then you would put
http://192.168.1.1:8337/notify
.",
- "MessageBackupsDescription": "Backups include users, user progress, library item details, server settings, and images stored in
/metadata/items
&
/metadata/authors
. Backups
do not include any files stored in your library folders.",
- "MessageBatchQuickMatchDescription": "Quick Match will attempt to add missing covers and metadata for the selected items. Enable the options below to allow Quick Match to overwrite existing covers and/or metadata.",
- "MessageBookshelfNoCollections": "You haven't made any collections yet",
- "MessageBookshelfNoResultsForFilter": "No Results for filter \"{0}: {1}\"",
- "MessageBookshelfNoRSSFeeds": "No RSS feeds are open",
- "MessageBookshelfNoSeries": "You have no series",
- "MessageChapterEndIsAfter": "Chapter end is after the end of your audiobook",
- "MessageChapterErrorFirstNotZero": "First chapter must start at 0",
- "MessageChapterErrorStartGteDuration": "Invalid start time must be less than audiobook duration",
- "MessageChapterErrorStartLtPrev": "Invalid start time must be greater than or equal to previous chapter start time",
- "MessageChapterStartIsAfter": "Chapter start is after the end of your audiobook",
+ "LabelType": "Tipo",
+ "LabelUnknown": "Desconocido",
+ "LabelUpdateCover": "Actualizar Portada",
+ "LabelUpdateCoverHelp": "Permitir sobrescribir portadas existentes de los libros seleccionados cuando sean encontrados.",
+ "LabelUpdatedAt": "Actualizado En",
+ "LabelUpdateDetails": "Actualizar Detalles",
+ "LabelUpdateDetailsHelp": "Permitir sobrescribir detalles existentes de los libros seleccionados cuando sean encontrados",
+ "LabelUploaderDragAndDrop": "Arrastre y suelte archivos o carpetas",
+ "LabelUploaderDropFiles": "Suelte los Archivos",
+ "LabelUseChapterTrack": "Usar pista por capitulo",
+ "LabelUseFullTrack": "Usar pista completa",
+ "LabelUser": "Usuario",
+ "LabelUsername": "Nombré de Usuario",
+ "LabelValue": "Valor",
+ "LabelVersion": "Versión",
+ "LabelViewBookmarks": "Ver Marcadores",
+ "LabelViewChapters": "Ver Capítulos",
+ "LabelViewQueue": "Ver player queue",
+ "LabelVolume": "Volumen",
+ "LabelWeekdaysToRun": "Correr en Dias de la Semana",
+ "LabelYourAudiobookDuration": "Duración de tu Audiolibro",
+ "LabelYourBookmarks": "Tus Marcadores Bookmarks",
+ "LabelYourPlaylists": "Tus Listas",
+ "LabelYourProgress": "Tu Progreso",
+ "MessageAddToPlayerQueue": "Agregar a player queue",
+ "MessageAppriseDescription": "Para usar esta función deberás tener
Apprise API corriendo o un API que maneje los mismos resultados.
El Apprise API URL debe tener la misma ruta de archivos que donde se envina las notificaciones, ejemplo, si su API esta en
http://192.168.1.1:8337
entonces pondría
http://192.168.1.1:8337/notify
.",
+ "MessageBackupsDescription": "Los respaldos incluyen, usuarios, el progreso del los usuarios, detalles de los elementos de la biblioteca, configuración del servidor y las imágenes en
/metadata/items
&
/metadata/authors
. Los Respaldo
NO incluyen ningún archivo guardado en la carpeta de tu biblioteca.",
+ "MessageBatchQuickMatchDescription": "Quick Match tratara de agregar porta y metadata faltantes de los elementos seleccionados. Habilite la opción de abajo para que Quick Match pueda sobrescribir portadas y/o metadata existentes.",
+ "MessageBookshelfNoCollections": "No tienes ninguna colección.",
+ "MessageBookshelfNoResultsForFilter": "Ningún Resultado para el filtro \"{0}: {1}\"",
+ "MessageBookshelfNoRSSFeeds": "Ninguna Fuente RSS esta abierta",
+ "MessageBookshelfNoSeries": "No tienes ninguna series",
+ "MessageChapterEndIsAfter": "El final del capítulo es después del final de su audiolibro.",
+ "MessageChapterErrorFirstNotZero": "El primer capitulo debe iniciar en 0",
+ "MessageChapterErrorStartGteDuration": "El tiempo de inicio no es válida debe ser inferior a la duración del audiolibro.",
+ "MessageChapterErrorStartLtPrev": "El tiempo de inicio no es válida debe ser mayor o igual que la hora de inicio del capítulo anterior",
+ "MessageChapterStartIsAfter": "El comienzo del capítulo es después del final de su audiolibro",
"MessageCheckingCron": "Checking cron...",
- "MessageConfirmDeleteBackup": "Are you sure you want to delete backup for {0}?",
- "MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?",
- "MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
- "MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
- "MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?",
- "MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?",
- "MessageConfirmRemoveCollection": "Are you sure you want to remove collection \"{0}\"?",
- "MessageConfirmRemoveEpisode": "Are you sure you want to remove episode \"{0}\"?",
- "MessageConfirmRemoveEpisodes": "Are you sure you want to remove {0} episodes?",
- "MessageConfirmRemovePlaylist": "Are you sure you want to remove your playlist \"{0}\"?",
- "MessageConfirmRenameGenre": "Are you sure you want to rename genre \"{0}\" to \"{1}\" for all items?",
- "MessageConfirmRenameGenreMergeNote": "Note: This genre already exists so they will be merged.",
- "MessageConfirmRenameGenreWarning": "Warning! A similar genre with a different casing already exists \"{0}\".",
- "MessageConfirmRenameTag": "Are you sure you want to rename tag \"{0}\" to \"{1}\" for all items?",
- "MessageConfirmRenameTagMergeNote": "Note: This tag already exists so they will be merged.",
- "MessageConfirmRenameTagWarning": "Warning! A similar tag with a different casing already exists \"{0}\".",
- "MessageDownloadingEpisode": "Downloading episode",
- "MessageDragFilesIntoTrackOrder": "Drag files into correct track order",
- "MessageEmbedFinished": "Embed Finished!",
- "MessageEpisodesQueuedForDownload": "{0} Episode(s) queued for download",
- "MessageFeedURLWillBe": "Feed URL will be {0}",
- "MessageFetching": "Fetching...",
- "MessageForceReScanDescription": "will scan all files again like a fresh scan. Audio file ID3 tags, OPF files, and text files will be scanned as new.",
- "MessageImportantNotice": "Important Notice!",
- "MessageInsertChapterBelow": "Insert chapter below",
- "MessageItemsSelected": "{0} Items Selected",
- "MessageItemsUpdated": "{0} Items Updated",
- "MessageJoinUsOn": "Join us on",
- "MessageListeningSessionsInTheLastYear": "{0} listening sessions in the last year",
- "MessageLoading": "Loading...",
- "MessageLoadingFolders": "Loading folders...",
- "MessageM4BFailed": "M4B Failed!",
- "MessageM4BFinished": "M4B Finished!",
+ "MessageConfirmDeleteBackup": "Esta seguro que desea eliminar el respaldo {0}?",
+ "MessageConfirmDeleteLibrary": "Esta seguro que desea eliminar permanentemente la biblioteca \"{0}\"?",
+ "MessageConfirmDeleteSession": "Esta seguro que desea eliminar esta session?",
+ "MessageConfirmForceReScan": "Esta seguro que desea forzar re-escanear?",
+ "MessageConfirmMarkSeriesFinished": "Esta seguro que desea marcar todos los libros en esta serie como terminados?",
+ "MessageConfirmMarkSeriesNotFinished": "Esta seguro que desea marcar todos los libros en esta serie como no terminados?",
+ "MessageConfirmRemoveCollection": "Esta seguro que desea remover la colección \"{0}\"?",
+ "MessageConfirmRemoveEpisode": "Esta seguro que desea remover el episodio \"{0}\"?",
+ "MessageConfirmRemoveEpisodes": "Esta seguro que desea remover {0} episodios?",
+ "MessageConfirmRemovePlaylist": "Esta seguro que desea remover su lista de reproducción \"{0}\"?",
+ "MessageConfirmRenameGenre": "Esta seguro que desea renombrar el genero \"{0}\" a \"{1}\" de todos los elementos?",
+ "MessageConfirmRenameGenreMergeNote": "Nota: Este genero ya existe por lo que se fusionarán.",
+ "MessageConfirmRenameGenreWarning": "Advertencia! un genero similar ya existe \"{0}\".",
+ "MessageConfirmRenameTag": "Esta seguro que desea renombrar la etiqueta \"{0}\" a \"{1}\" de todos los elementos?",
+ "MessageConfirmRenameTagMergeNote": "Nota: Esta etiqueta ya existe por lo que se fusionarán.",
+ "MessageConfirmRenameTagWarning": "Advertencia! Una etiqueta similar ya existe \"{0}\".",
+ "MessageDownloadingEpisode": "Descargando Capitulo",
+ "MessageDragFilesIntoTrackOrder": "Arrastras los archivos en el orden correcto de la pista.",
+ "MessageEmbedFinished": "Incorporación Terminada!",
+ "MessageEpisodesQueuedForDownload": "{0} Episodio(s) en cola para descargar",
+ "MessageFeedURLWillBe": "Fuente URL sera {0}",
+ "MessageFetching": "Buscando...",
+ "MessageForceReScanDescription": "Escaneara todos los archivos como un nuevo escaneo. Archivos de audio con etiqueta ID3, archivos OPF y archivos de texto serán escaneados como nuevos.",
+ "MessageImportantNotice": "Noticia importante!",
+ "MessageInsertChapterBelow": "Insertar Capítulo Abajo",
+ "MessageItemsSelected": "{0} Elementos Seleccionados",
+ "MessageItemsUpdated": "{0} Elementos Actualizados",
+ "MessageJoinUsOn": "Únete en",
+ "MessageListeningSessionsInTheLastYear": "{0} sesiones de escuchadas en el último año",
+ "MessageLoading": "Cargando...",
+ "MessageLoadingFolders": "Cargando archivos...",
+ "MessageM4BFailed": "M4B Fallo!",
+ "MessageM4BFinished": "M4B Terminado!",
"MessageMapChapterTitles": "Map chapter titles to your existing audiobook chapters without adjusting timestamps",
- "MessageMarkAsFinished": "Mark as Finished",
- "MessageMarkAsNotFinished": "Mark as Not Finished",
- "MessageMatchBooksDescription": "will attempt to match books in the library with a book from the selected search provider and fill in empty details and cover art. Does not overwrite details.",
- "MessageNoAudioTracks": "No audio tracks",
- "MessageNoAuthors": "No Authors",
- "MessageNoBackups": "No Backups",
- "MessageNoBookmarks": "No Bookmarks",
- "MessageNoChapters": "No Chapters",
- "MessageNoCollections": "No Collections",
- "MessageNoCoversFound": "No Covers Found",
- "MessageNoDescription": "No description",
- "MessageNoEpisodeMatchesFound": "No episode matches found",
- "MessageNoEpisodes": "No Episodes",
- "MessageNoFoldersAvailable": "No Folders Available",
- "MessageNoGenres": "No Genres",
- "MessageNoIssues": "No Issues",
- "MessageNoItems": "No Items",
- "MessageNoItemsFound": "No items found",
- "MessageNoListeningSessions": "No Listening Sessions",
+ "MessageMarkAsFinished": "Marcar como Terminado",
+ "MessageMarkAsNotFinished": "Marcar como No Terminado",
+ "MessageMatchBooksDescription": "intentará hacer coincidir los libros de la biblioteca con un libro del proveedor de búsqueda seleccionado y rellenará los detalles vacíos y la portada. No sobrescribe los detalles.",
+ "MessageNoAudioTracks": "Sin Pista de Audio",
+ "MessageNoAuthors": "Sin Autores",
+ "MessageNoBackups": "Sin Respaldos",
+ "MessageNoBookmarks": "Sin Marcadores",
+ "MessageNoChapters": "Sin Capítulos",
+ "MessageNoCollections": "Sin Colecciones",
+ "MessageNoCoversFound": "Ninguna Portada Encontrada",
+ "MessageNoDescription": "Sin Descripción",
+ "MessageNoDownloadsInProgress": "No hay descargas actualmente en curso",
+ "MessageNoDownloadsQueued": "Sin Lista de Descarga",
+ "MessageNoEpisodeMatchesFound": "No se encontraron episodios que coinciden",
+ "MessageNoEpisodes": "Sin Episodios",
+ "MessageNoFoldersAvailable": "No Carpetas Disponibles",
+ "MessageNoGenres": "Sin Géneros",
+ "MessageNoIssues": "Sin Problemas",
+ "MessageNoItems": "Sin Elementos",
+ "MessageNoItemsFound": "Ningún Elemento Encontrado",
+ "MessageNoListeningSessions": "Ninguna Session Escuchada",
"MessageNoLogs": "No Logs",
- "MessageNoMediaProgress": "No Media Progress",
- "MessageNoNotifications": "No Notifications",
- "MessageNoPodcastsFound": "No podcasts found",
- "MessageNoResults": "No Results",
- "MessageNoSearchResultsFor": "No search results for \"{0}\"",
- "MessageNoSeries": "No Series",
- "MessageNoTags": "No Tags",
- "MessageNotYetImplemented": "Not yet implemented",
- "MessageNoUpdateNecessary": "No update necessary",
- "MessageNoUpdatesWereNecessary": "No updates were necessary",
- "MessageNoUserPlaylists": "You have no playlists",
- "MessageOr": "or",
- "MessagePauseChapter": "Pause chapter playback",
- "MessagePlayChapter": "Listen to beginning of chapter",
- "MessagePlaylistCreateFromCollection": "Create playlist from collection",
- "MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching",
- "MessageQuickMatchDescription": "Populate empty item details & cover with first match result from '{0}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.",
- "MessageRemoveAllItemsWarning": "WARNING! This action will remove all library items from the database including any updates or matches you have made. This does not do anything to your actual files. Are you sure?",
- "MessageRemoveChapter": "Remove chapter",
- "MessageRemoveEpisodes": "Remove {0} episode(s)",
- "MessageRemoveFromPlayerQueue": "Remove from player queue",
- "MessageRemoveUserWarning": "Are you sure you want to permanently delete user \"{0}\"?",
- "MessageReportBugsAndContribute": "Report bugs, request features, and contribute on",
- "MessageResetChaptersConfirm": "Are you sure you want to reset chapters and undo the changes you made?",
- "MessageRestoreBackupConfirm": "Are you sure you want to restore the backup created on",
- "MessageRestoreBackupWarning": "Restoring a backup will overwrite the entire database located at /config and cover images in /metadata/items & /metadata/authors.
Backups do not modify any files in your library folders. If you have enabled server settings to store cover art and metadata in your library folders then those are not backed up or overwritten.
All clients using your server will be automatically refreshed.",
- "MessageSearchResultsFor": "Search results for",
- "MessageServerCouldNotBeReached": "Server could not be reached",
- "MessageSetChaptersFromTracksDescription": "Set chapters using each audio file as a chapter and chapter title as the audio file name",
- "MessageStartPlaybackAtTime": "Start playback for \"{0}\" at {1}?",
- "MessageThinking": "Thinking...",
- "MessageUploaderItemFailed": "Failed to upload",
- "MessageUploaderItemSuccess": "Successfully Uploaded!",
- "MessageUploading": "Uploading...",
+ "MessageNoMediaProgress": "Multimedia sin Progreso ",
+ "MessageNoNotifications": "Ninguna Notificación",
+ "MessageNoPodcastsFound": "Ningún podcasts encontrado",
+ "MessageNoResults": "Sin Resultados",
+ "MessageNoSearchResultsFor": "No hay resultados de la búsqueda para \"{0}\"",
+ "MessageNoSeries": "Sin Series",
+ "MessageNoTags": "Sin Etiquetas",
+ "MessageNoTasksRunning": "Ninguna Tarea Corriendo",
+ "MessageNotYetImplemented": "Aun no implementado",
+ "MessageNoUpdateNecessary": "No es necesario actualizar",
+ "MessageNoUpdatesWereNecessary": "No fue necesario actualizar",
+ "MessageNoUserPlaylists": "No tienes lista de reproducciones",
+ "MessageOr": "o",
+ "MessagePauseChapter": "Pausar la reproducción del capítulo",
+ "MessagePlayChapter": "Escuche para comenzar el capítulo",
+ "MessagePlaylistCreateFromCollection": "Crear lista de reproducción a partir de colección",
+ "MessagePodcastHasNoRSSFeedForMatching": "El podcast no tiene una URL de fuente RSS que pueda usar que coincida",
+ "MessageQuickMatchDescription": "Rellenar detalles de elementos vacíos y portada con los primeros resultados de '{0}'. No sobrescribe los detalles a menos que la configuración 'Prefer matched metadata' del servidor este habilita.",
+ "MessageRemoveAllItemsWarning": "ADVERTENCIA! Esta acción eliminará todos los elementos de la biblioteca de la base de datos incluyendo cualquier actualización o match. Esto no hace nada a sus archivos reales. Esta seguro que desea continuar?",
+ "MessageRemoveChapter": "Remover capítulos",
+ "MessageRemoveEpisodes": "Remover {0} episodio(s)",
+ "MessageRemoveFromPlayerQueue": "Remover de player queue",
+ "MessageRemoveUserWarning": "Esta seguro que desea eliminar el usuario \"{0}\"?",
+ "MessageReportBugsAndContribute": "Reporte erres, solicite funciones y contribuye en",
+ "MessageResetChaptersConfirm": "Esta seguro que desea reiniciar el capitulo y deshacer los cambios que hiciste?",
+ "MessageRestoreBackupConfirm": "Esta seguro que desea para restaurar del respaldo creado en",
+ "MessageRestoreBackupWarning": "Restaurar sobrescribirá toda la base de datos localizada en /config y las imágenes de portadas en /metadata/items & /metadata/authors.
El respaldo no modifica ningún archivo en las carpetas de tu biblioteca. Si ha habilitado la configuración del servidor para almacenar portadas y metadata en las carpetas de su biblioteca, entonces esos no se respaldan o sobrescribe.
Todos los clientes que usen su servidor se actualizarán automáticamente.",
+ "MessageSearchResultsFor": "Resultados de la búsqueda de",
+ "MessageServerCouldNotBeReached": "No se pude establecer la conexión con el servidor",
+ "MessageSetChaptersFromTracksDescription": "Establecer capítulos usando cada archivo de audio como un capítulo y el título del capítulo como el nombre del archivo de audio",
+ "MessageStartPlaybackAtTime": "Iniciar reproducción para \"{0}\" en {1}?",
+ "MessageThinking": "Pensando...",
+ "MessageUploaderItemFailed": "Error al Subir",
+ "MessageUploaderItemSuccess": "Éxito al Subir!",
+ "MessageUploading": "Subiendo...",
"MessageValidCronExpression": "Valid cron expression",
- "MessageWatcherIsDisabledGlobally": "Watcher is disabled globally in server settings",
- "MessageXLibraryIsEmpty": "{0} Library is empty!",
- "MessageYourAudiobookDurationIsLonger": "Your audiobook duration is longer than the duration found",
- "MessageYourAudiobookDurationIsShorter": "Your audiobook duration is shorter than duration found",
- "NoteChangeRootPassword": "Root user is the only user that can have an empty password",
- "NoteChapterEditorTimes": "Note: First chapter start time must remain at 0:00 and the last chapter start time cannot exceed this audiobooks duration.",
- "NoteFolderPicker": "Note: folders already mapped will not be shown",
- "NoteFolderPickerDebian": "Note: Folder picker for the debian install is not fully implemented. You should enter the path to your library directly.",
- "NoteRSSFeedPodcastAppsHttps": "Warning: Most podcast apps will require the RSS feed URL is using HTTPS",
- "NoteRSSFeedPodcastAppsPubDate": "Warning: 1 or more of your episodes do not have a Pub Date. Some podcast apps require this.",
- "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.",
- "PlaceholderNewCollection": "New collection name",
- "PlaceholderNewFolderPath": "New folder path",
- "PlaceholderNewPlaylist": "New playlist name",
- "PlaceholderSearch": "Search..",
+ "MessageWatcherIsDisabledGlobally": "Watcher es desactivado globalmente en la configuración del servidor",
+ "MessageXLibraryIsEmpty": "{0} La biblioteca esta vacía!",
+ "MessageYourAudiobookDurationIsLonger": "La duración de tu audiolibro es más larga que la duración encontrada",
+ "MessageYourAudiobookDurationIsShorter": "La duración de su audiolibro es más corta que la duración encontrada",
+ "NoteChangeRootPassword": "El usuario Root es el único usuario que puede no tener una contraseña",
+ "NoteChapterEditorTimes": "Nota: La hora de inicio del primer capítulo debe permanecer en 0:00 y la hora de inicio del último capítulo no puede exceder la duración de este audiolibro.",
+ "NoteFolderPicker": "Nota: las carpetas ya asignadas no se mostrarán",
+ "NoteFolderPickerDebian": "Nota: Folder picker for the debian install is not fully implemented. You should enter the path to your library directly.",
+ "NoteRSSFeedPodcastAppsHttps": "Advertencia: La mayoría de las aplicaciones de podcast requieren que URL de la fuente RSS use HTTPS",
+ "NoteRSSFeedPodcastAppsPubDate": "Advertencia: 1 o más de tus episodios no tienen fecha de publicación. Algunas aplicaciones de podcast lo requieren.",
+ "NoteUploaderFoldersWithMediaFiles": "Las carpetas con archivos multimedia se manejarán como elementos separados en la biblioteca.",
+ "NoteUploaderOnlyAudioFiles": "Si subes solamente un archivos de audio, cada archivo se manejara como un audiolibro.",
+ "NoteUploaderUnsupportedFiles": "Los archivos no soportados se ignoran. Al elegir o soltar una carpeta, los archivos que no estén en una carpeta serán ignorados.",
+ "PlaceholderNewCollection": "Nuevo nombre de la colección",
+ "PlaceholderNewFolderPath": "Nueva ruta de carpeta",
+ "PlaceholderNewPlaylist": "Nuevo nombre de la lista de reproducción",
+ "PlaceholderSearch": "Buscando..",
"PlaceholderSearchEpisode": "Search episode..",
- "ToastAccountUpdateFailed": "Failed to update account",
- "ToastAccountUpdateSuccess": "Account updated",
- "ToastAuthorImageRemoveFailed": "Failed to remove image",
- "ToastAuthorImageRemoveSuccess": "Author image removed",
- "ToastAuthorUpdateFailed": "Failed to update author",
- "ToastAuthorUpdateMerged": "Author merged",
- "ToastAuthorUpdateSuccess": "Author updated",
- "ToastAuthorUpdateSuccessNoImageFound": "Author updated (no image found)",
- "ToastBackupCreateFailed": "Failed to create backup",
- "ToastBackupCreateSuccess": "Backup created",
- "ToastBackupDeleteFailed": "Failed to delete backup",
- "ToastBackupDeleteSuccess": "Backup deleted",
- "ToastBackupRestoreFailed": "Failed to restore backup",
- "ToastBackupUploadFailed": "Failed to upload backup",
- "ToastBackupUploadSuccess": "Backup uploaded",
+ "ToastAccountUpdateFailed": "Error al actualizar cuenta",
+ "ToastAccountUpdateSuccess": "Cuenta actualizada",
+ "ToastAuthorImageRemoveFailed": "Error al eliminar la imagen",
+ "ToastAuthorImageRemoveSuccess": "Se eliminó la imagen del autor",
+ "ToastAuthorUpdateFailed": "Error al actualizar el autor",
+ "ToastAuthorUpdateMerged": "Autor combinado",
+ "ToastAuthorUpdateSuccess": "Autor actualizado",
+ "ToastAuthorUpdateSuccessNoImageFound": "Autor actualizado (Imagen no encontrada)",
+ "ToastBackupCreateFailed": "Error al crear respaldo",
+ "ToastBackupCreateSuccess": "Respaldo creado",
+ "ToastBackupDeleteFailed": "Error al eliminar respaldo",
+ "ToastBackupDeleteSuccess": "Respaldo eliminado",
+ "ToastBackupRestoreFailed": "Error al restaurar el respaldo",
+ "ToastBackupUploadFailed": "Error al subir el respaldo",
+ "ToastBackupUploadSuccess": "Respaldo cargado",
"ToastBatchUpdateFailed": "Batch update failed",
"ToastBatchUpdateSuccess": "Batch update success",
- "ToastBookmarkCreateFailed": "Failed to create bookmark",
- "ToastBookmarkCreateSuccess": "Bookmark added",
- "ToastBookmarkRemoveFailed": "Failed to remove bookmark",
- "ToastBookmarkRemoveSuccess": "Bookmark removed",
- "ToastBookmarkUpdateFailed": "Failed to update bookmark",
- "ToastBookmarkUpdateSuccess": "Bookmark updated",
- "ToastChaptersHaveErrors": "Chapters have errors",
- "ToastChaptersMustHaveTitles": "Chapters must have titles",
- "ToastCollectionItemsRemoveFailed": "Failed to remove item(s) from collection",
- "ToastCollectionItemsRemoveSuccess": "Item(s) removed from collection",
- "ToastCollectionRemoveFailed": "Failed to remove collection",
- "ToastCollectionRemoveSuccess": "Collection removed",
- "ToastCollectionUpdateFailed": "Failed to update collection",
- "ToastCollectionUpdateSuccess": "Collection updated",
- "ToastItemCoverUpdateFailed": "Failed to update item cover",
- "ToastItemCoverUpdateSuccess": "Item cover updated",
- "ToastItemDetailsUpdateFailed": "Failed to update item details",
- "ToastItemDetailsUpdateSuccess": "Item details updated",
- "ToastItemDetailsUpdateUnneeded": "No updates needed for item details",
- "ToastItemMarkedAsFinishedFailed": "Failed to mark as Finished",
- "ToastItemMarkedAsFinishedSuccess": "Item marked as Finished",
- "ToastItemMarkedAsNotFinishedFailed": "Failed to mark as Not Finished",
- "ToastItemMarkedAsNotFinishedSuccess": "Item marked as Not Finished",
- "ToastLibraryCreateFailed": "Failed to create library",
- "ToastLibraryCreateSuccess": "Library \"{0}\" created",
- "ToastLibraryDeleteFailed": "Failed to delete library",
- "ToastLibraryDeleteSuccess": "Library deleted",
- "ToastLibraryScanFailedToStart": "Failed to start scan",
- "ToastLibraryScanStarted": "Library scan started",
- "ToastLibraryUpdateFailed": "Failed to update library",
- "ToastLibraryUpdateSuccess": "Library \"{0}\" updated",
- "ToastPlaylistCreateFailed": "Failed to create playlist",
- "ToastPlaylistCreateSuccess": "Playlist created",
- "ToastPlaylistRemoveFailed": "Failed to remove playlist",
- "ToastPlaylistRemoveSuccess": "Playlist removed",
- "ToastPlaylistUpdateFailed": "Failed to update playlist",
- "ToastPlaylistUpdateSuccess": "Playlist updated",
- "ToastPodcastCreateFailed": "Failed to create podcast",
- "ToastPodcastCreateSuccess": "Podcast created successfully",
- "ToastRemoveItemFromCollectionFailed": "Failed to remove item from collection",
- "ToastRemoveItemFromCollectionSuccess": "Item removed from collection",
- "ToastRSSFeedCloseFailed": "Failed to close RSS feed",
- "ToastRSSFeedCloseSuccess": "RSS feed closed",
- "ToastSeriesUpdateFailed": "Series update failed",
- "ToastSeriesUpdateSuccess": "Series update success",
- "ToastSessionDeleteFailed": "Failed to delete session",
- "ToastSessionDeleteSuccess": "Session deleted",
- "ToastSocketConnected": "Socket connected",
- "ToastSocketDisconnected": "Socket disconnected",
- "ToastSocketFailedToConnect": "Socket failed to connect",
- "ToastUserDeleteFailed": "Failed to delete user",
- "ToastUserDeleteSuccess": "User deleted"
-}
+ "ToastBookmarkCreateFailed": "Error al crear marcador",
+ "ToastBookmarkCreateSuccess": "Marca Agregado",
+ "ToastBookmarkRemoveFailed": "Error al eliminar marcador",
+ "ToastBookmarkRemoveSuccess": "Marcador eliminado",
+ "ToastBookmarkUpdateFailed": "Error al eliminar el marcador",
+ "ToastBookmarkUpdateSuccess": "Marcador actualizado",
+ "ToastChaptersHaveErrors": "Los capítulos tienen errores",
+ "ToastChaptersMustHaveTitles": "Los capítulos tienen que tener titulo",
+ "ToastCollectionItemsRemoveFailed": "Error al remover elemento(s) de la colección",
+ "ToastCollectionItemsRemoveSuccess": "Elementos(s) removidos de la colección",
+ "ToastCollectionRemoveFailed": "Error al remover la colección",
+ "ToastCollectionRemoveSuccess": "Colección removida",
+ "ToastCollectionUpdateFailed": "Error al actualizar la colección",
+ "ToastCollectionUpdateSuccess": "Colección actualizada",
+ "ToastItemCoverUpdateFailed": "Error al actualizar la portada del elemento",
+ "ToastItemCoverUpdateSuccess": "Portada del elemento actualizada",
+ "ToastItemDetailsUpdateFailed": "Error al actualizar los detalles del elemento",
+ "ToastItemDetailsUpdateSuccess": "Detalles de Elemento Actualizados",
+ "ToastItemDetailsUpdateUnneeded": "No se necesitan actualizaciones para los detalles del Elemento",
+ "ToastItemMarkedAsFinishedFailed": "Error al marcar como Terminado",
+ "ToastItemMarkedAsFinishedSuccess": "Elemento marcado como terminado",
+ "ToastItemMarkedAsNotFinishedFailed": "Error al marcar como No Terminado",
+ "ToastItemMarkedAsNotFinishedSuccess": "Elemento marcado como No Terminado",
+ "ToastLibraryCreateFailed": "Error al crear biblioteca",
+ "ToastLibraryCreateSuccess": "Biblioteca \"{0}\" creada",
+ "ToastLibraryDeleteFailed": "Error al eliminar la biblioteca",
+ "ToastLibraryDeleteSuccess": "Biblioteca eliminada",
+ "ToastLibraryScanFailedToStart": "Error al iniciar la exploración",
+ "ToastLibraryScanStarted": "Se inició el escaneo de la biblioteca",
+ "ToastLibraryUpdateFailed": "Error al actualizar biblioteca",
+ "ToastLibraryUpdateSuccess": "Biblioteca \"{0}\" actualizada",
+ "ToastPlaylistCreateFailed": "Error al crear la lista de reproducción.",
+ "ToastPlaylistCreateSuccess": "Lista de reproducción creada",
+ "ToastPlaylistRemoveFailed": "Error al eliminar la lista de reproducción",
+ "ToastPlaylistRemoveSuccess": "Lista de reproducción eliminada",
+ "ToastPlaylistUpdateFailed": "Error al actualizar la lista de reproducción.",
+ "ToastPlaylistUpdateSuccess": "Lista de reproducción actualizada",
+ "ToastPodcastCreateFailed": "Error al crear podcast",
+ "ToastPodcastCreateSuccess": "Podcast creada",
+ "ToastRemoveItemFromCollectionFailed": "Error al eliminar el elemento de la colección",
+ "ToastRemoveItemFromCollectionSuccess": "Elemento eliminado de la colección.",
+ "ToastRSSFeedCloseFailed": "Error al cerrar fuente RSS",
+ "ToastRSSFeedCloseSuccess": "Fuente RSS cerrada",
+ "ToastSeriesUpdateFailed": "Error al actualizar la serie",
+ "ToastSeriesUpdateSuccess": "Series actualizada",
+ "ToastSessionDeleteFailed": "Error al eliminar sesión",
+ "ToastSessionDeleteSuccess": "Sesión eliminada",
+ "ToastSocketConnected": "Socket conectado",
+ "ToastSocketDisconnected": "Socket desconectado",
+ "ToastSocketFailedToConnect": "Error al conectar al Socket",
+ "ToastUserDeleteFailed": "Error al eliminar el usuario",
+ "ToastUserDeleteSuccess": "Usuario eliminado"
+}
\ No newline at end of file
diff --git a/client/strings/fr.json b/client/strings/fr.json
index fe6c21f7..9e22ed2b 100644
--- a/client/strings/fr.json
+++ b/client/strings/fr.json
@@ -8,18 +8,19 @@
"ButtonAuthors": "Auteurs",
"ButtonBrowseForFolder": "Naviguer vers le répertoire",
"ButtonCancel": "Annuler",
- "ButtonCancelEncode": "Annuler l'encodage",
- "ButtonChangeRootPassword": "Changer le mot de passe Administrateur",
- "ButtonCheckAndDownloadNewEpisodes": "Vérifier & télécharger de nouveaux épisodes",
+ "ButtonCancelEncode": "Annuler l’encodage",
+ "ButtonChangeRootPassword": "Modifier le mot de passe Administrateur",
+ "ButtonCheckAndDownloadNewEpisodes": "Vérifier et télécharger de nouveaux épisodes",
"ButtonChooseAFolder": "Choisir un dossier",
"ButtonChooseFiles": "Choisir les fichiers",
"ButtonClearFilter": "Effacer le filtre",
"ButtonCloseFeed": "Fermer le flux",
"ButtonCollections": "Collections",
- "ButtonConfigureScanner": "Configurer l'analyse",
+ "ButtonConfigureScanner": "Configurer l’analyse",
"ButtonCreate": "Créer",
"ButtonCreateBackup": "Créer une sauvegarde",
"ButtonDelete": "Effacer",
+ "ButtonDownloadQueue": "Queue",
"ButtonEdit": "Modifier",
"ButtonEditChapters": "Modifier les chapitres",
"ButtonEditPodcast": "Modifier les podcasts",
@@ -30,16 +31,16 @@
"ButtonIssues": "Parutions",
"ButtonLatest": "Dernière version",
"ButtonLibrary": "Bibliothèque",
- "ButtonLogout": "Se Déconnecter",
- "ButtonLookup": "Rechercher",
+ "ButtonLogout": "Me déconnecter",
+ "ButtonLookup": "Chercher",
"ButtonManageTracks": "Gérer les pistes",
"ButtonMapChapterTitles": "Correspondance des titres de chapitres",
- "ButtonMatchAllAuthors": "Rechercher tous les auteurs",
- "ButtonMatchBooks": "Rechercher les Livres",
- "ButtonNevermind": "Oubliez cela",
+ "ButtonMatchAllAuthors": "Chercher tous les auteurs",
+ "ButtonMatchBooks": "Chercher les livres",
+ "ButtonNevermind": "Non merci",
"ButtonOk": "Ok",
- "ButtonOpenFeed": "Ouvrir le Flux",
- "ButtonOpenManager": "Ouvrir le Gestionnaire",
+ "ButtonOpenFeed": "Ouvrir le flux",
+ "ButtonOpenManager": "Ouvrir le gestionnaire",
"ButtonPlay": "Écouter",
"ButtonPlaying": "En lecture",
"ButtonPlaylists": "Listes de lecture",
@@ -59,25 +60,25 @@
"ButtonReset": "Réinitialiser",
"ButtonRestore": "Rétablir",
"ButtonSave": "Sauvegarder",
- "ButtonSaveAndClose": "Sauvegarder & Fermer",
+ "ButtonSaveAndClose": "Sauvegarder et Fermer",
"ButtonSaveTracklist": "Sauvegarder la liste de lecture",
"ButtonScan": "Analyser",
"ButtonScanLibrary": "Analyser la bibliothèque",
- "ButtonSearch": "Rechercher",
+ "ButtonSearch": "Chercher",
"ButtonSelectFolderPath": "Sélectionner le chemin du dossier",
"ButtonSeries": "Séries",
"ButtonSetChaptersFromTracks": "Positionner les chapitres par rapports aux pistes",
- "ButtonShiftTimes": "Décaler le temps du livre",
+ "ButtonShiftTimes": "Décaler l’horodatage du livre",
"ButtonShow": "Afficher",
- "ButtonStartM4BEncode": "Démarrer l'encodage M4B",
+ "ButtonStartM4BEncode": "Démarrer l’encodage M4B",
"ButtonStartMetadataEmbed": "Démarrer les Métadonnées intégrées",
"ButtonSubmit": "Soumettre",
"ButtonUpload": "Téléverser",
"ButtonUploadBackup": "Téléverser une sauvegarde",
"ButtonUploadCover": "Téléverser une couverture",
"ButtonUploadOPMLFile": "Téléverser un fichier OPML",
- "ButtonUserDelete": "Effacer l'utilisateur {0}",
- "ButtonUserEdit": "Modifier l'utilisateur {0}",
+ "ButtonUserDelete": "Effacer l’utilisateur {0}",
+ "ButtonUserEdit": "Modifier l’utilisateur {0}",
"ButtonViewAll": "Afficher tout",
"ButtonYes": "Oui",
"HeaderAccount": "Compte",
@@ -86,32 +87,34 @@
"HeaderAudiobookTools": "Outils de Gestion de Fichier Audiobook",
"HeaderAudioTracks": "Pistes zudio",
"HeaderBackups": "Sauvegardes",
- "HeaderChangePassword": "Chager le mot de passe",
+ "HeaderChangePassword": "Modifier le mot de passe",
"HeaderChapters": "Chapitres",
"HeaderChooseAFolder": "Choisir un dossier",
"HeaderCollection": "Collection",
"HeaderCollectionItems": "Entrées de la Collection",
"HeaderCover": "Couverture",
+ "HeaderCurrentDownloads": "Current Downloads",
"HeaderDetails": "Détails",
+ "HeaderDownloadQueue": "Download Queue",
"HeaderEpisodes": "Épisodes",
"HeaderFiles": "Fichiers",
"HeaderFindChapters": "Trouver les chapitres",
"HeaderIgnoredFiles": "Fichiers Ignorés",
"HeaderItemFiles": "Fichiers des Articles",
"HeaderItemMetadataUtils": "Outils de gestion des métadonnées",
- "HeaderLastListeningSession": "Dernière Session d'écoute",
+ "HeaderLastListeningSession": "Dernière Session d’écoute",
"HeaderLatestEpisodes": "Dernier épisodes",
"HeaderLibraries": "Bibliothèque",
"HeaderLibraryFiles": "Fichier de bibliothèque",
"HeaderLibraryStats": "Statistiques de bibliothèque",
- "HeaderListeningSessions": "Sessions d'écoute",
- "HeaderListeningStats": "Statistiques d'écoute",
+ "HeaderListeningSessions": "Sessions d’écoute",
+ "HeaderListeningStats": "Statistiques d’écoute",
"HeaderLogin": "Connexion",
"HeaderLogs": "Journaux",
"HeaderManageGenres": "Gérer les genres",
"HeaderManageTags": "Gérer les étiquettes",
"HeaderMapDetails": "Édition en masse",
- "HeaderMatch": "Rechercher",
+ "HeaderMatch": "Chercher",
"HeaderMetadataToEmbed": "Métadonnée à intégrer",
"HeaderNewAccount": "Nouveau compte",
"HeaderNewLibrary": "Nouvelle bibliothèque",
@@ -119,13 +122,14 @@
"HeaderOpenRSSFeed": "Ouvrir Flux RSS",
"HeaderOtherFiles": "Autres fichiers",
"HeaderPermissions": "Permissions",
- "HeaderPlayerQueue": "Liste d'écoute",
+ "HeaderPlayerQueue": "Liste d’écoute",
"HeaderPlaylist": "Liste de lecture",
"HeaderPlaylistItems": "Éléments de la liste de lecture",
"HeaderPodcastsToAdd": "Podcasts à ajouter",
"HeaderPreviewCover": "Prévisualiser la couverture",
- "HeaderRemoveEpisode": "Supprimer l'épisode",
+ "HeaderRemoveEpisode": "Supprimer l’épisode",
"HeaderRemoveEpisodes": "Suppression de {0} épisodes",
+ "HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "Le Flux RSS est actif",
"HeaderSavedMediaProgress": "Progression de la sauvegarde des médias",
"HeaderSchedule": "Programmation",
@@ -138,14 +142,15 @@
"HeaderSettingsGeneral": "Général",
"HeaderSettingsScanner": "Scanneur",
"HeaderSleepTimer": "Minuterie",
+ "HeaderStatsLargestItems": "Articles les plus lourd",
"HeaderStatsLongestItems": "Articles les plus long (heures)",
- "HeaderStatsMinutesListeningChart": "Minutes d'écoute (7 derniers jours)",
+ "HeaderStatsMinutesListeningChart": "Minutes d’écoute (7 derniers jours)",
"HeaderStatsRecentSessions": "Sessions récentes",
"HeaderStatsTop10Authors": "Top 10 Auteurs",
"HeaderStatsTop5Genres": "Top 5 Genres",
"HeaderTools": "Outils",
"HeaderUpdateAccount": "Mettre à jour le compte",
- "HeaderUpdateAuthor": "Mettre à jour l'auteur",
+ "HeaderUpdateAuthor": "Mettre à jour l’auteur",
"HeaderUpdateDetails": "Mettre à jour les détails",
"HeaderUpdateLibrary": "Mettre à jour la bibliothèque",
"HeaderUsers": "Utilisateurs",
@@ -155,20 +160,21 @@
"LabelAccountTypeGuest": "Invité",
"LabelAccountTypeUser": "Utilisateur",
"LabelActivity": "Activité",
- "LabelAddedAt": "Date d'ajout",
+ "LabelAddedAt": "Date d’ajout",
"LabelAddToCollection": "Ajouter à la collection",
"LabelAddToCollectionBatch": "Ajout de {0} livres à la lollection",
"LabelAddToPlaylist": "Ajouter à la liste de lecture",
"LabelAddToPlaylistBatch": "{0} éléments ajoutés à la liste de lecture",
"LabelAll": "Tout",
"LabelAllUsers": "Tous les utilisateurs",
+ "LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Ajouter",
"LabelAuthor": "Auteur",
"LabelAuthorFirstLast": "Auteur (Prénom Nom)",
"LabelAuthorLastFirst": "Auteur (Nom, Prénom)",
"LabelAuthors": "Auteurs",
- "LabelAutoDownloadEpisodes": "Téléchargement automatique d'épisode",
- "LabelBackToUser": "Revenir à l'Utilisateur",
+ "LabelAutoDownloadEpisodes": "Téléchargement automatique d’épisode",
+ "LabelBackToUser": "Revenir à l’Utilisateur",
"LabelBackupsEnableAutomaticBackups": "Activer les sauvegardes automatiques",
"LabelBackupsEnableAutomaticBackupsHelp": "Sauvegardes Enregistrées dans /metadata/backups",
"LabelBackupsMaxBackupSize": "Taille maximale de la sauvegarde (en Go)",
@@ -176,7 +182,7 @@
"LabelBackupsNumberToKeep": "Nombre de sauvegardes à maintenir",
"LabelBackupsNumberToKeepHelp": "Une seule sauvegarde sera effacée à la fois. Si vous avez plus de sauvegardes à effacer, vous devrez le faire manuellement.",
"LabelBooks": "Livres",
- "LabelChangePassword": "Changer le mot de passe",
+ "LabelChangePassword": "Modifier le mot de passe",
"LabelChaptersFound": "Chapitres trouvés",
"LabelChapterTitle": "Titres du chapitre",
"LabelClosePlayer": "Fermer le lecteur",
@@ -187,16 +193,17 @@
"LabelContinueListening": "Continuer la lecture",
"LabelContinueSeries": "Continuer la série",
"LabelCover": "Couverture",
- "LabelCoverImageURL": "URL vers l'image de couverture",
+ "LabelCoverImageURL": "URL vers l’image de couverture",
"LabelCreatedAt": "Créé le",
"LabelCronExpression": "Expression Cron",
"LabelCurrent": "Courrant",
"LabelCurrently": "En ce moment :",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Datetime",
"LabelDescription": "Description",
"LabelDeselectAll": "Tout déselectionner",
"LabelDevice": "Appareil",
- "LabelDeviceInfo": "Détail de l'appareil",
+ "LabelDeviceInfo": "Détail de l’appareil",
"LabelDirectory": "Répertoire",
"LabelDiscFromFilename": "Disque depuis le fichier",
"LabelDiscFromMetadata": "Disque depuis les métadonnées",
@@ -207,15 +214,16 @@
"LabelEnable": "Activer",
"LabelEnd": "Fin",
"LabelEpisode": "Épisode",
- "LabelEpisodeTitle": "Titre de l'épisode",
- "LabelEpisodeType": "Type de l'épisode",
+ "LabelEpisodeTitle": "Titre de l’épisode",
+ "LabelEpisodeType": "Type de l’épisode",
+ "LabelExample": "Example",
"LabelExplicit": "Restriction",
"LabelFeedURL": "URL deu flux",
"LabelFile": "Fichier",
"LabelFileBirthtime": "Creation du fichier",
"LabelFileModified": "Modification du fichier",
"LabelFilename": "Nom de fichier",
- "LabelFilterByUser": "Filtrer par l'utilisateur",
+ "LabelFilterByUser": "Filtrer par l’utilisateur",
"LabelFindEpisodes": "Trouver des épisodes",
"LabelFinished": "Fini(e)",
"LabelFolder": "Dossier",
@@ -245,7 +253,7 @@
"LabelLastTime": "Progression",
"LabelLastUpdate": "Dernière mise à jour",
"LabelLess": "Moins",
- "LabelLibrariesAccessibleToUser": "Bibliothèque accessible à l'utilisateur",
+ "LabelLibrariesAccessibleToUser": "Bibliothèque accessible à l’utilisateur",
"LabelLibrary": "Bibliothèque",
"LabelLibraryItem": "Article de bibliothèque",
"LabelLibraryName": "Nom de la bibliothèque",
@@ -254,7 +262,7 @@
"LabelLogLevelDebug": "Debug",
"LabelLogLevelInfo": "Info",
"LabelLogLevelWarn": "Warn",
- "LabelLookForNewEpisodesAfterDate": "Rechercher de nouveaux épisode après cette date",
+ "LabelLookForNewEpisodesAfterDate": "Chercher de nouveaux épisode après cette date",
"LabelMediaPlayer": "Lecteur multimédia",
"LabelMediaType": "Type de média",
"LabelMetadataProvider": "Fournisseur de métadonnées",
@@ -270,50 +278,57 @@
"LabelNewestAuthors": "Nouveaux auteurs",
"LabelNewestEpisodes": "Derniers épisodes",
"LabelNewPassword": "Nouveau mot de passe",
+ "LabelNextBackupDate": "Next backup date",
+ "LabelNextScheduledRun": "Next scheduled run",
"LabelNotes": "Notes",
"LabelNotFinished": "Non terminé(e)",
- "LabelNotificationAppriseURL": "URL(s) d'apprise",
+ "LabelNotificationAppriseURL": "URL(s) d’apprise",
"LabelNotificationAvailableVariables": "Variables disponibles",
"LabelNotificationBodyTemplate": "Modèle de Message",
"LabelNotificationEvent": "Evènement de Notification",
- "LabelNotificationsMaxFailedAttempts": "Nombres de tentatives d'envoi",
+ "LabelNotificationsMaxFailedAttempts": "Nombres de tentatives d’envoi",
"LabelNotificationsMaxFailedAttemptsHelp": "La notification est abandonnée une fois ce seuil atteint",
"LabelNotificationsMaxQueueSize": "Nombres de notifications maximum à mettre en attente",
- "LabelNotificationsMaxQueueSizeHelp": "La limite de notification est de un évènement par seconde. Le notification seront ignorées si la file d'attente est à son maximum. Cela empêche un flot trop important.",
+ "LabelNotificationsMaxQueueSizeHelp": "La limite de notification est de un évènement par seconde. Le notification seront ignorées si la file d’attente est à son maximum. Cela empêche un flot trop important.",
"LabelNotificationTitleTemplate": "Modèle de Titre",
"LabelNotStarted": "Non Démarré(e)",
"LabelNumberOfBooks": "Nombre de Livres",
- "LabelNumberOfEpisodes": "Nombre d'Episodes",
+ "LabelNumberOfEpisodes": "Nombre d’Episodes",
"LabelOpenRSSFeed": "Ouvrir le flux RSS",
- "LabelOverwrite": "Ecraser",
- "LabelPassword": "Mot de Passe",
+ "LabelOverwrite": "Écraser",
+ "LabelPassword": "Mot de passe",
"LabelPath": "Chemin",
"LabelPermissionsAccessAllLibraries": "Peut accéder à toutes les bibliothèque",
"LabelPermissionsAccessAllTags": "Peut accéder à toutes les étiquettes",
- "LabelPermissionsAccessExplicitContent": "Peut acceter au contenu restreint",
+ "LabelPermissionsAccessExplicitContent": "Peut accéder au contenu restreint",
"LabelPermissionsDelete": "Peut supprimer",
"LabelPermissionsDownload": "Peut télécharger",
- "LabelPermissionsUpdate": "Peut mettre à Jour",
+ "LabelPermissionsUpdate": "Peut mettre à jour",
"LabelPermissionsUpload": "Peut téléverser",
"LabelPhotoPathURL": "Chemin / URL des photos",
"LabelPlaylists": "Listes de lecture",
- "LabelPlayMethod": "Méthode d'écoute",
+ "LabelPlayMethod": "Méthode d’écoute",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts",
+ "LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)",
+ "LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
"LabelProgress": "Progression",
"LabelProvider": "Fournisseur",
"LabelPubDate": "Date de publication",
"LabelPublisher": "Éditeur",
- "LabelPublishYear": "Année d'édition",
+ "LabelPublishYear": "Année d’édition",
"LabelRecentlyAdded": "Derniers ajouts",
"LabelRecentSeries": "Séries récentes",
"LabelRecommended": "Recommandé",
"LabelRegion": "Région",
"LabelReleaseDate": "Date de parution",
"LabelRemoveCover": "Supprimer la couverture",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "Flux RSS ouvert",
- "LabelRSSFeedSlug": "Identificateur d'adresse du Flux RSS ",
+ "LabelRSSFeedPreventIndexing": "Prevent Indexing",
+ "LabelRSSFeedSlug": "Identificateur d’adresse du Flux RSS ",
"LabelRSSFeedURL": "Adresse du flux RSS",
"LabelSearchTerm": "Terme de recherche",
"LabelSearchTitle": "Titre de recherche",
@@ -323,40 +338,41 @@
"LabelSeries": "Séries",
"LabelSeriesName": "Nom de la série",
"LabelSeriesProgress": "Progression de séries",
- "LabelSettingsBookshelfViewHelp": "Design Skeuomorphic avec une étagère en bois",
+ "LabelSettingsBookshelfViewHelp": "Interface Skeuomorphic avec une étagère en bois",
"LabelSettingsChromecastSupport": "Support du Chromecast",
"LabelSettingsDateFormat": "Format de date",
"LabelSettingsDisableWatcher": "Désactiver la surveillance",
"LabelSettingsDisableWatcherForLibrary": "Désactiver la surveillance des dossiers pour la bibliothèque",
"LabelSettingsDisableWatcherHelp": "Désactive la mise à jour automatique lorsque les fichiers changent. *Nécessite un redémarrage*",
"LabelSettingsEnableEReader": "Active E-reader pour tous les utilisateurs",
- "LabelSettingsEnableEReaderHelp": "E-reader est toujours en cours de développement, mais ce paramètre l'active pour tous les utilisateurs (ou utiliser l'interrupteur \"Fonctionnalités expérimentales\" pour l'activer seulement pour vous)",
+ "LabelSettingsEnableEReaderHelp": "E-reader est toujours en cours de développement, mais ce paramètre l’active pour tous les utilisateurs (ou utiliser l’interrupteur « Fonctionnalités expérimentales » pour l’activer seulement pour vous)",
"LabelSettingsExperimentalFeatures": "Fonctionnalités expérimentales",
"LabelSettingsExperimentalFeaturesHelp": "Fonctionnalités en cours de développement sur lesquels nous attendons votre retour et expérience. Cliquer pour ouvrir la discussion Github.",
"LabelSettingsFindCovers": "Chercher des couvertures de livre",
- "LabelSettingsFindCoversHelp": "Si votre livre audio ne possède pas de couverture intégrée ou une image de couverture dans le dossier, l'analyser tentera de récupérer une couverture.
Attention, cela peut augmenter le temps d'analyse.",
- "LabelSettingsHomePageBookshelfView": "La page d'accueil utilise la vue étagère",
+ "LabelSettingsFindCoversHelp": "Si votre livre audio ne possède pas de couverture intégrée ou une image de couverture dans le dossier, l’analyser tentera de récupérer une couverture.
Attention, cela peut augmenter le temps d’analyse.",
+ "LabelSettingsHomePageBookshelfView": "La page d’accueil utilise la vue étagère",
"LabelSettingsLibraryBookshelfView": "La bibliothèque utilise la vue étagère",
"LabelSettingsOverdriveMediaMarkers": "Utiliser Overdrive Media Marker pour les chapitres",
- "LabelSettingsOverdriveMediaMarkersHelp": "Les fichiers MP3 d'Overdrive viennent avec les minutages des chapitres intégrés en métadonnées. Activer ce paramètre utilisera ces minutages pour les chapitres automatiquement.",
+ "LabelSettingsOverdriveMediaMarkersHelp": "Les fichiers MP3 d’Overdrive viennent avec les minutages des chapitres intégrés en métadonnées. Activer ce paramètre utilisera ces minutages pour les chapitres automatiquement.",
"LabelSettingsParseSubtitles": "Analyse des sous-titres",
- "LabelSettingsParseSubtitlesHelp": "Extrait les sous-titres depuis le dossier du Livre Audio.
Les sous-titres doivent être séparés par \" - \"
i.e. \"Titre du Livre - Ceci est un sous-titre\" aura le sous-titre \"Ceci est un sous-titre\"",
+ "LabelSettingsParseSubtitlesHelp": "Extrait les sous-titres depuis le dossier du Livre Audio.
Les sous-titres doivent être séparés par « - »
i.e. « Titre du Livre - Ceci est un sous-titre » aura le sous-titre « Ceci est un sous-titre »",
"LabelSettingsPreferAudioMetadata": "Préférer les Métadonnées audio",
"LabelSettingsPreferAudioMetadataHelp": "Les méta étiquettes ID3 des fichiers audios seront utilisés à la place des noms de dossier pour les détails du livre audio",
"LabelSettingsPreferMatchedMetadata": "Préférer les Métadonnées par correspondance",
- "LabelSettingsPreferMatchedMetadataHelp": "Les métadonnées par correspondance écrase les détails de l'article lors d'une Recherche par Correspondance Rapide. Par défaut, la recherche par correspondance rapide ne comblera que les éléments manquant.",
+ "LabelSettingsPreferMatchedMetadataHelp": "Les métadonnées par correspondance écrase les détails de l’article lors d’une recherche par correspondance rapide. Par défaut, la recherche par correspondance rapide ne comblera que les éléments manquant.",
"LabelSettingsPreferOPFMetadata": "Préférer les Métadonnées OPF",
"LabelSettingsPreferOPFMetadataHelp": "Les fichiers de métadonnées OPF seront utilisés à la place des noms de dossier pour les détails du Livre Audio",
"LabelSettingsSkipMatchingBooksWithASIN": "Ignorer la recherche par correspondance sur les livres ayant déjà un ASIN",
"LabelSettingsSkipMatchingBooksWithISBN": "Ignorer la recherche par correspondance sur les livres ayant déjà un ISBN",
"LabelSettingsSortingIgnorePrefixes": "Ignorer les préfixes lors du tri",
- "LabelSettingsSortingIgnorePrefixesHelp": "i.e. pour le préfixe \"le\", le livre avec pour titre \"Le Titre du Livre\" sera trié en tant que \"Titre du Livre, Le\"",
+ "LabelSettingsSortingIgnorePrefixesHelp": "i.e. pour le préfixe « le », le livre avec pour titre « Le Titre du Livre » sera trié en tant que « Titre du Livre, Le »",
"LabelSettingsSquareBookCovers": "Utiliser des couvertures carrées",
"LabelSettingsSquareBookCoversHelp": "Préférer les couvertures carrées par rapport aux couvertures standardes de 1.6:1.",
"LabelSettingsStoreCoversWithItem": "Enregistrer la couverture avec les articles",
- "LabelSettingsStoreCoversWithItemHelp": "Par défaut, les couvertures sont enregistrées dans /metadata/items. Activer ce paramètre enregistrera les couvertures dans le dossier avec les fichiersde l'article. Seul un fichier nommé \"cover\" sera gardé.",
+ "LabelSettingsStoreCoversWithItemHelp": "Par défaut, les couvertures sont enregistrées dans /metadata/items. Activer ce paramètre enregistrera les couvertures dans le dossier avec les fichiers de l’article. Seul un fichier nommé « cover » sera conservé.",
"LabelSettingsStoreMetadataWithItem": "Enregistrer les Métadonnées avec les articles",
- "LabelSettingsStoreMetadataWithItemHelp": "Par défaut, les métadonnées sont enregistrées dans /metadata/items. Activer ce paramètre enregistrera les métadonnées dans le dossier de l'article avec une extension \".abs\".",
+ "LabelSettingsStoreMetadataWithItemHelp": "Par défaut, les métadonnées sont enregistrées dans /metadata/items. Activer ce paramètre enregistrera les métadonnées dans le dossier de l’article avec une extension « .abs ».",
+ "LabelSettingsTimeFormat": "Time Format",
"LabelShowAll": "Afficher Tout",
"LabelSize": "Taille",
"LabelSleepTimer": "Minuterie",
@@ -369,13 +385,13 @@
"LabelStatsBestDay": "Meilleur Jour",
"LabelStatsDailyAverage": "Moyenne Journalière",
"LabelStatsDays": "Jours",
- "LabelStatsDaysListened": "Jours d'écoute",
+ "LabelStatsDaysListened": "Jours d’écoute",
"LabelStatsHours": "Heures",
- "LabelStatsInARow": "d'affilé(s)",
+ "LabelStatsInARow": "d’affilé(s)",
"LabelStatsItemsFinished": "Articles terminés",
"LabelStatsItemsInLibrary": "Articles dans la Bibliothèque",
"LabelStatsMinutes": "minutes",
- "LabelStatsMinutesListening": "Minutes d'écoute",
+ "LabelStatsMinutesListening": "Minutes d’écoute",
"LabelStatsOverallDays": "Jours au total",
"LabelStatsOverallHours": "Heures au total",
"LabelStatsWeekListening": "Écoute de la semaine",
@@ -383,9 +399,10 @@
"LabelSupportedFileTypes": "Types de fichiers supportés",
"LabelTag": "Étiquette",
"LabelTags": "Étiquettes",
- "LabelTagsAccessibleToUser": "Étiquettes accessibles à l'utilisateur",
- "LabelTimeListened": "Temps d'écoute",
- "LabelTimeListenedToday": "Nombres d'écoutes Aujourd'hui",
+ "LabelTagsAccessibleToUser": "Étiquettes accessibles à l’utilisateur",
+ "LabelTasks": "Tasks Running",
+ "LabelTimeListened": "Temps d’écoute",
+ "LabelTimeListenedToday": "Nombres d’écoutes Aujourd’hui",
"LabelTimeRemaining": "{0} restantes",
"LabelTimeToShift": "Temps de décalage en secondes",
"LabelTitle": "Titre",
@@ -394,154 +411,157 @@
"LabelToolsMakeM4b": "Créer un fichier Livre Audio M4B",
"LabelToolsMakeM4bDescription": "Génère un fichier Livre Audio .M4B avec intégration des métadonnées, image de couverture et les chapitres.",
"LabelToolsSplitM4b": "Scinde le fichier M4B en fichiers MP3",
- "LabelToolsSplitM4bDescription": "Créer plusieurs fichier MP3 à partir du découpage par chapitre, en incluant les métadonnées, l'image de couverture et les chapitres.",
+ "LabelToolsSplitM4bDescription": "Créer plusieurs fichier MP3 à partir du découpage par chapitre, en incluant les métadonnées, l’image de couverture et les chapitres.",
"LabelTotalDuration": "Durée Totale",
- "LabelTotalTimeListened": "Temps d'écoute total",
+ "LabelTotalTimeListened": "Temps d’écoute total",
"LabelTrackFromFilename": "Piste depuis le fichier",
"LabelTrackFromMetadata": "Piste depuis les métadonnées",
"LabelTracks": "Pistes",
- "LabelTracksMultiTrack": "Piste Multiple",
- "LabelTracksSingleTrack": "Piste Simple",
+ "LabelTracksMultiTrack": "Piste multiple",
+ "LabelTracksSingleTrack": "Piste simple",
"LabelType": "Type",
"LabelUnknown": "Inconnu",
- "LabelUpdateCover": "Mettre à jour la Couverture",
- "LabelUpdateCoverHelp": "Autoriser la mise à jour de la couverture existante lorsqu'une correspondance est trouvée",
+ "LabelUpdateCover": "Mettre à jour la couverture",
+ "LabelUpdateCoverHelp": "Autoriser la mise à jour de la couverture existante lorsqu’une correspondance est trouvée",
"LabelUpdatedAt": "Mis à jour à",
- "LabelUpdateDetails": "Mettre à jours les Détails",
- "LabelUpdateDetailsHelp": "Autoriser la mise à jour des détails existants lorsqu'une correspondance est trouvée",
- "LabelUploaderDragAndDrop": "Glisser & Déposer des fichiers ou dossiers",
+ "LabelUpdateDetails": "Mettre à jours les détails",
+ "LabelUpdateDetailsHelp": "Autoriser la mise à jour des détails existants lorsqu’une correspondance est trouvée",
+ "LabelUploaderDragAndDrop": "Glisser et déposer des fichiers ou dossiers",
"LabelUploaderDropFiles": "Déposer des fichiers",
- "LabelUseChapterTrack": "Utiliser la Piste du Chapitre",
- "LabelUseFullTrack": "Utiliser la Piste Complète",
+ "LabelUseChapterTrack": "Utiliser la piste du chapitre",
+ "LabelUseFullTrack": "Utiliser la piste Complète",
"LabelUser": "Utilisateur",
- "LabelUsername": "Nom d'Utilisateur",
+ "LabelUsername": "Nom d’utilisateur",
"LabelValue": "Valeur",
"LabelVersion": "Version",
- "LabelViewBookmarks": "Afficher les Signets",
- "LabelViewChapters": "Afficher les Chapitres",
+ "LabelViewBookmarks": "Afficher les signets",
+ "LabelViewChapters": "Afficher les chapitres",
"LabelViewQueue": "Afficher la liste de lecture",
"LabelVolume": "Volume",
"LabelWeekdaysToRun": "Jours de la semaine à exécuter",
- "LabelYourAudiobookDuration": "Durée de vos Livres Audios",
- "LabelYourBookmarks": "Vos Signets",
+ "LabelYourAudiobookDuration": "Durée de vos livres audios",
+ "LabelYourBookmarks": "Vos signets",
"LabelYourPlaylists": "Vos listes de lecture",
"LabelYourProgress": "Votre progression",
- "MessageAddToPlayerQueue": "Ajouter en file d'attente",
- "MessageAppriseDescription": "Nécessite une instance d'
API Apprise pour utiliser cette fonctionnalité ou une api qui prend en charge les mêmes requêtes.
L'URL de l'API Apprise doit comprendre le chemin complet pour envoyer la notification. Par exemple, si votre instance écoute sur
http://192.168.1.1:8337
alors vous devez mettre
http://192.168.1.1:8337/notify
.",
- "MessageBackupsDescription": "Les sauvegardes incluent les utilisateurs, la progression de lecture par utilisateur, les détails des articles des bibliothèques, les paramètres du serveur et les images sauvegardées. Les Sauvegardes n'incluent pas les fichiers de votre bibliothèque.",
- "MessageBatchQuickMatchDescription": "La Recherche par Correspondance Rapide tentera d'ajouter les couvertures et les métadonnées manquantes pour les articles sélectionnés. Activer l'option suivante pour autoriser la Recherche par Correspondance à écraser les données existantes.",
- "MessageBookshelfNoCollections": "Vous n'avez pas encore de collections",
- "MessageBookshelfNoResultsForFilter": "Aucun résultat pour le filtre \"{0}: {1}\"",
- "MessageBookshelfNoRSSFeeds": "Aucun flux RSS n'est ouvert",
- "MessageBookshelfNoSeries": "Vous n'avez aucune séries",
+ "MessageAddToPlayerQueue": "Ajouter en file d’attente",
+ "MessageAppriseDescription": "Nécessite une instance d’
API Apprise pour utiliser cette fonctionnalité ou une api qui prend en charge les mêmes requêtes.
l’URL de l’API Apprise doit comprendre le chemin complet pour envoyer la notification. Par exemple, si votre instance écoute sur
http://192.168.1.1:8337
alors vous devez mettre
http://192.168.1.1:8337/notify
.",
+ "MessageBackupsDescription": "Les sauvegardes incluent les utilisateurs, la progression de lecture par utilisateur, les détails des articles des bibliothèques, les paramètres du serveur et les images sauvegardées. Les sauvegardes n’incluent pas les fichiers de votre bibliothèque.",
+ "MessageBatchQuickMatchDescription": "La recherche par correspondance rapide tentera d’ajouter les couvertures et les métadonnées manquantes pour les articles sélectionnés. Activer l’option suivante pour autoriser la recherche par correspondance à écraser les données existantes.",
+ "MessageBookshelfNoCollections": "Vous n’avez pas encore de collections",
+ "MessageBookshelfNoResultsForFilter": "Aucun résultat pour le filtre « {0}: {1} »",
+ "MessageBookshelfNoRSSFeeds": "Aucun flux RSS n’est ouvert",
+ "MessageBookshelfNoSeries": "Vous n’avez aucune séries",
"MessageChapterEndIsAfter": "Le Chapitre Fin est situé à la fin de votre Livre Audio",
"MessageChapterErrorFirstNotZero": "Le premier capitre doit débuter à 0",
"MessageChapterErrorStartGteDuration": "Horodatage invalide car il doit débuter avant la fin du livre",
"MessageChapterErrorStartLtPrev": "Horodatage invalide car il doit débuter au moins après le précédent chapitre",
"MessageChapterStartIsAfter": "Le Chapitre Début est situé au début de votre Livre Audio",
- "MessageCheckingCron": "Vérification du cron...",
+ "MessageCheckingCron": "Vérification du cron…",
"MessageConfirmDeleteBackup": "Êtes-vous sûr de vouloir supprimer la Sauvegarde de {0} ?",
- "MessageConfirmDeleteLibrary": "Êtes-vous sûr de vouloir supprimer définitivement la bibliothèque \"{0}\" ?",
+ "MessageConfirmDeleteLibrary": "Êtes-vous sûr de vouloir supprimer définitivement la bibliothèque « {0} » ?",
"MessageConfirmDeleteSession": "Êtes-vous sûr de vouloir supprimer cette session ?",
"MessageConfirmForceReScan": "Êtes-vous sûr de vouloir lancer une Analyse Forcée ?",
"MessageConfirmMarkSeriesFinished": "Êtes-vous sûr de vouloir marquer comme terminé tous les livres de cette série ?",
"MessageConfirmMarkSeriesNotFinished": "Êtes-vous sûr de vouloir marquer comme non terminé tous les livres de cette série ?",
- "MessageConfirmRemoveCollection": "Êtes-vous sûr de vouloir supprimer la collection \"{0}\" ?",
- "MessageConfirmRemoveEpisode": "Êtes-vous sûr de vouloir supprimer l'épisode \"{0}\" ?",
+ "MessageConfirmRemoveCollection": "Êtes-vous sûr de vouloir supprimer la collection « {0} » ?",
+ "MessageConfirmRemoveEpisode": "Êtes-vous sûr de vouloir supprimer l’épisode « {0} » ?",
"MessageConfirmRemoveEpisodes": "Êtes-vous sûr de vouloir supprimer {0} épisodes ?",
- "MessageConfirmRemovePlaylist": "Êtes-vous sûr de vouloir supprimer la liste de lecture \"{0}\" ?",
- "MessageConfirmRenameGenre": "Êtes-vous sûr de vouloir renommer le genre \"{0}\" vers \"{1}\" pour tous les articles ?",
+ "MessageConfirmRemovePlaylist": "Êtes-vous sûr de vouloir supprimer la liste de lecture « {0} » ?",
+ "MessageConfirmRenameGenre": "Êtes-vous sûr de vouloir renommer le genre « {0} » vers « {1} » pour tous les articles ?",
"MessageConfirmRenameGenreMergeNote": "Information: Ce genre existe déjà et sera fusionné.",
- "MessageConfirmRenameGenreWarning": "Attention ! Un genre similaire avec une casse différente existe déjà \"{0}\".",
- "MessageConfirmRenameTag": "Êtes-vous sûr de vouloir renommer l'étiquette \"{0}\" vers \"{1}\" pour tous les articles ?",
+ "MessageConfirmRenameGenreWarning": "Attention ! Un genre similaire avec une casse différente existe déjà « {0} ».",
+ "MessageConfirmRenameTag": "Êtes-vous sûr de vouloir renommer l’étiquette « {0} » vers « {1} » pour tous les articles ?",
"MessageConfirmRenameTagMergeNote": "Information: Cette étiquette existe déjà et sera fusionnée.",
- "MessageConfirmRenameTagWarning": "Attention ! Une étiquette similaire avec une casse différente existe déjà \"{0}\".",
- "MessageDownloadingEpisode": "Téléchargement de l'épisode",
- "MessageDragFilesIntoTrackOrder": "Faire glisser les fichiers dans l'ordre correct",
+ "MessageConfirmRenameTagWarning": "Attention ! Une étiquette similaire avec une casse différente existe déjà « {0} ».",
+ "MessageDownloadingEpisode": "Téléchargement de l’épisode",
+ "MessageDragFilesIntoTrackOrder": "Faire glisser les fichiers dans l’ordre correct",
"MessageEmbedFinished": "Intégration Terminée !",
"MessageEpisodesQueuedForDownload": "{0} épisode(s) mis en file pour téléchargement",
- "MessageFeedURLWillBe": "L'URL du Flux sera {0}",
- "MessageFetching": "Récupération...",
- "MessageForceReScanDescription": "Analysera tous les fichiers de nouveau. Les étiquettes ID3 des fichiers audios, fichiers OPF, et les fichiers textes seront analysés comme s'ils étaient nouveaux.",
+ "MessageFeedURLWillBe": "l’URL du Flux sera {0}",
+ "MessageFetching": "Récupération…",
+ "MessageForceReScanDescription": "Analysera tous les fichiers de nouveau. Les étiquettes ID3 des fichiers audios, fichiers OPF, et les fichiers textes seront analysés comme s’ils étaient nouveaux.",
"MessageImportantNotice": "Information Importante !",
"MessageInsertChapterBelow": "Insérer le chapitre ci-dessous",
"MessageItemsSelected": "{0} articles sélectionnés",
"MessageItemsUpdated": "{0} articles mis à jour",
"MessageJoinUsOn": "Rejoignez-nous sur",
- "MessageListeningSessionsInTheLastYear": "{0} sessions d'écoute l'an dernier",
- "MessageLoading": "Chargement...",
- "MessageLoadingFolders": "Chargement des dossiers...",
+ "MessageListeningSessionsInTheLastYear": "{0} sessions d’écoute l’an dernier",
+ "MessageLoading": "Chargement…",
+ "MessageLoadingFolders": "Chargement des dossiers…",
"MessageM4BFailed": "M4B en échec !",
"MessageM4BFinished": "M4B terminé !",
- "MessageMapChapterTitles": "Faire correspondre les titres des chapitres aux chapitres existants de votre livre audio sans ajuster l'horodatage.",
+ "MessageMapChapterTitles": "Faire correspondre les titres des chapitres aux chapitres existants de votre livre audio sans ajuster l’horodatage.",
"MessageMarkAsFinished": "Marquer comme terminé",
"MessageMarkAsNotFinished": "Marquer comme non Terminé",
- "MessageMatchBooksDescription": "tentera de faire correspondre les livres de la bibliothèque avec les livres du fournisseur sélectionné pour combler les détails et couverture manquants. N'écrase pas les données existantes.",
- "MessageNoAudioTracks": "Pas de pistes audio",
- "MessageNoAuthors": "Pas d'Auteurs",
- "MessageNoBackups": "Pas de Sauvegardes",
- "MessageNoBookmarks": "Pas de signets",
- "MessageNoChapters": "Pas de chapitres",
- "MessageNoCollections": "Pas de collections",
+ "MessageMatchBooksDescription": "tentera de faire correspondre les livres de la bibliothèque avec les livres du fournisseur sélectionné pour combler les détails et couverture manquants. N’écrase pas les données existantes.",
+ "MessageNoAudioTracks": "Aucune piste audio",
+ "MessageNoAuthors": "Aucun auteur",
+ "MessageNoBackups": "Aucune sauvegarde",
+ "MessageNoBookmarks": "Aucun signet",
+ "MessageNoChapters": "Aucun chapitre",
+ "MessageNoCollections": "Aucune collection",
"MessageNoCoversFound": "Aucune couverture trouvée",
- "MessageNoDescription": "Pas de description",
- "MessageNoEpisodeMatchesFound": "Pas de correspondance d'épisode trouvée",
+ "MessageNoDescription": "Aucune description",
+ "MessageNoDownloadsInProgress": "Aucun téléchargement en cours",
+ "MessageNoDownloadsQueued": "Aucun téléchargement en file d’attente",
+ "MessageNoEpisodeMatchesFound": "Aucune correspondance d’épisode trouvée",
"MessageNoEpisodes": "Aucun épisode",
"MessageNoFoldersAvailable": "Aucun dossier disponible",
- "MessageNoGenres": "Pas de genres",
- "MessageNoIssues": "Pas de parution",
- "MessageNoItems": "Pas d'Articles",
- "MessageNoItemsFound": "Pas d'Articles Trouvés",
- "MessageNoListeningSessions": "Pas de sessions d'écoutes",
- "MessageNoLogs": "Pas de journaux",
- "MessageNoMediaProgress": "Pas de Média en cours",
- "MessageNoNotifications": "Pas de Notifications",
- "MessageNoPodcastsFound": "Pas de podcasts trouvés",
- "MessageNoResults": "Pas de résultats",
- "MessageNoSearchResultsFor": "Pas de résultats de recherche pour \"{0}\"",
- "MessageNoSeries": "Pas de séries",
- "MessageNoTags": "Pas d'étiquettes",
+ "MessageNoGenres": "Aucun genre",
+ "MessageNoIssues": "Aucune parution",
+ "MessageNoItems": "Aucun article",
+ "MessageNoItemsFound": "Aucun article trouvé",
+ "MessageNoListeningSessions": "Aucune session d’écoute en cours",
+ "MessageNoLogs": "Aucun journaux",
+ "MessageNoMediaProgress": "Aucun média en cours",
+ "MessageNoNotifications": "Aucune notification",
+ "MessageNoPodcastsFound": "Aucun podcast trouvé",
+ "MessageNoResults": "Aucun résultat",
+ "MessageNoSearchResultsFor": "Aucun résultat pour la recherche « {0} »",
+ "MessageNoSeries": "Aucune série",
+ "MessageNoTags": "Aucune d’étiquettes",
+ "MessageNoTasksRunning": "No Tasks Running",
"MessageNotYetImplemented": "Non implémenté",
- "MessageNoUpdateNecessary": "Pas de mise à jour nécessaire",
- "MessageNoUpdatesWereNecessary": "Aucune mise à jour n'était nécessaire",
- "MessageNoUserPlaylists": "Vous n'avez aucune liste de lecture",
+ "MessageNoUpdateNecessary": "Aucune mise à jour nécessaire",
+ "MessageNoUpdatesWereNecessary": "Aucune mise à jour n’était nécessaire",
+ "MessageNoUserPlaylists": "Vous n’avez aucune liste de lecture",
"MessageOr": "ou",
"MessagePauseChapter": "Suspendre la lecture du chapitre",
"MessagePlayChapter": "Écouter depuis le début du chapitre",
"MessagePlaylistCreateFromCollection": "Créer une liste de lecture depuis la collection",
- "MessagePodcastHasNoRSSFeedForMatching": "Le Podcast n'a pas d'URL de flux RSS à utiliser pour la correspondance",
- "MessageQuickMatchDescription": "Renseigne les détails manquants ainsi que la couverture avec la première correspondance de '{0}'. N'écrase pas les données présentes à moins que le paramètre 'Préférer les Métadonnées par correspondance' soit activé.",
- "MessageRemoveAllItemsWarning": "ATTENTION ! Cette action supprimera toute la base de données de la bibliothèque ainsi que les mises à jour ou correspondances qui auraient été effectuées. Cela n'a aucune incidence sur les fichiers de la bibliothèque. Souhaitez-vous continuer ?",
+ "MessagePodcastHasNoRSSFeedForMatching": "Le Podcast n’a pas d’URL de flux RSS à utiliser pour la correspondance",
+ "MessageQuickMatchDescription": "Renseigne les détails manquants ainsi que la couverture avec la première correspondance de « {0} ». N’écrase pas les données présentes à moins que le paramètre « Préférer les Métadonnées par correspondance » soit activé.",
+ "MessageRemoveAllItemsWarning": "ATTENTION ! Cette action supprimera toute la base de données de la bibliothèque ainsi que les mises à jour ou correspondances qui auraient été effectuées. Cela n’a aucune incidence sur les fichiers de la bibliothèque. Souhaitez-vous continuer ?",
"MessageRemoveChapter": "Supprimer le chapitre",
"MessageRemoveEpisodes": "Suppression de {0} épisode(s)",
- "MessageRemoveFromPlayerQueue": "Supprimer de la liste d'écoute",
- "MessageRemoveUserWarning": "Êtes-vous certain de vouloir supprimer définitivement l'utilisateur \"{0}\" ?",
+ "MessageRemoveFromPlayerQueue": "Supprimer de la liste d’écoute",
+ "MessageRemoveUserWarning": "Êtes-vous certain de vouloir supprimer définitivement l’utilisateur « {0} » ?",
"MessageReportBugsAndContribute": "Remonter des anomalies, demander des fonctionnalités et contribuer sur",
"MessageResetChaptersConfirm": "Êtes-vous certain de vouloir réinitialiser les chapitres et annuler les changements effectués ?",
"MessageRestoreBackupConfirm": "Êtes-vous certain de vouloir restaurer la sauvegarde créée le",
- "MessageRestoreBackupWarning": "Restaurer la sauvegarde écrasera la base de donnée située dans le dossier /config ainsi que les images sur /metadata/items & /metadata/authors.
Les sauvegardes ne touchent pas aux fichiers de la bibliothèque. Si vous avez activé le paramètre pour sauvegarder les métadonnées et les images de couverture dans le même dossier que les fichiers, ceux-ci ne ni sauvegardés, ni écrasés lors de la restauration.
Tous les clients utilisant votre serveur seront automatiquement mis à jour.",
+ "MessageRestoreBackupWarning": "Restaurer la sauvegarde écrasera la base de donnée située dans le dossier /config ainsi que les images sur /metadata/items et /metadata/authors.
Les sauvegardes ne touchent pas aux fichiers de la bibliothèque. Si vous avez activé le paramètre pour sauvegarder les métadonnées et les images de couverture dans le même dossier que les fichiers, ceux-ci ne ni sauvegardés, ni écrasés lors de la restauration.
Tous les clients utilisant votre serveur seront automatiquement mis à jour.",
"MessageSearchResultsFor": "Résultats de recherche pour",
"MessageServerCouldNotBeReached": "Serveur inaccessible",
"MessageSetChaptersFromTracksDescription": "Positionne un chapitre par fichier audio, avec le titre du fichier comme titre de chapitre",
- "MessageStartPlaybackAtTime": "Démarrer la lecture pour \"{0}\" à {1} ?",
- "MessageThinking": "On réfléchit...",
+ "MessageStartPlaybackAtTime": "Démarrer la lecture pour « {0} » à {1} ?",
+ "MessageThinking": "Je cherche…",
"MessageUploaderItemFailed": "Échec du téléversement",
"MessageUploaderItemSuccess": "Téléversement effectué !",
- "MessageUploading": "Téléversement...",
+ "MessageUploading": "Téléversement…",
"MessageValidCronExpression": "Expression cron valide",
- "MessageWatcherIsDisabledGlobally": "La Surveillance est désactivée par un paramètre global du serveur",
+ "MessageWatcherIsDisabledGlobally": "La surveillance est désactivée par un paramètre global du serveur",
"MessageXLibraryIsEmpty": "La bibliothèque {0} est vide !",
"MessageYourAudiobookDurationIsLonger": "La durée de votre Livre Audio est plus longue que la durée trouvée",
"MessageYourAudiobookDurationIsShorter": "La durée de votre Livre Audio est plus courte que la durée trouvée",
- "NoteChangeRootPassword": "L'utilisateur Root est le seul a pouvoir utiliser un mote de passe vide",
- "NoteChapterEditorTimes": "Information: L'horodatage du premier chapitre doit être à 0:00 et celui du dernier chapitre ne peut se situer au-delà de la durée du Livre Audio.",
- "NoteFolderPicker": "Information: Les dossiers déjà surveillés ne sont pas affichés",
- "NoteFolderPickerDebian": "Information: La sélection de dossier sur une installation debian n'est pas finalisée. Merci de renseigner le chemin complet vers votre bibliothèque manuellement.",
+ "NoteChangeRootPassword": "seul l’utilisateur « root » peut utiliser un mot de passe vide",
+ "NoteChapterEditorTimes": "Information : l’horodatage du premier chapitre doit être à 0:00 et celui du dernier chapitre ne peut se situer au-delà de la durée du Livre Audio.",
+ "NoteFolderPicker": "Information : Les dossiers déjà surveillés ne sont pas affichés",
+ "NoteFolderPickerDebian": "Information : La sélection de dossier sur une installation debian n’est pas finalisée. Merci de renseigner le chemin complet vers votre bibliothèque manuellement.",
"NoteRSSFeedPodcastAppsHttps": "Attention : la majorité des application de podcast nécessite une adresse de flux en HTTPS.",
"NoteRSSFeedPodcastAppsPubDate": "Attention : un ou plusieurs de vos épisodes ne possèdent pas de date de publication. Certaines applications de podcast le requièrent.",
"NoteUploaderFoldersWithMediaFiles": "Les dossiers contenant des fichiers multimédias seront traités comme des éléments distincts de la bibliothèque.",
"NoteUploaderOnlyAudioFiles": "Si vous téléverser uniquement des fichiers audio, chaque fichier audio sera traité comme un livre audio distinct.",
- "NoteUploaderUnsupportedFiles": "Les fichiers non pris en charge sont ignorés. Lorsque vous choisissez ou déposez un dossier, les autres fichiers qui ne sont pas dans un dossier d'élément sont ignorés.",
+ "NoteUploaderUnsupportedFiles": "Les fichiers non pris en charge sont ignorés. Lorsque vous choisissez ou déposez un dossier, les autres fichiers qui ne sont pas dans un dossier d’élément sont ignorés.",
"PlaceholderNewCollection": "Nom de la nouvelle collection",
"PlaceholderNewFolderPath": "Nouveau chemin de dossier",
"PlaceholderNewPlaylist": "Nouveau nom de liste de lecture",
@@ -549,12 +569,12 @@
"PlaceholderSearchEpisode": "Search episode...",
"ToastAccountUpdateFailed": "Échec de la mise à jour du compte",
"ToastAccountUpdateSuccess": "Compte mis à jour",
- "ToastAuthorImageRemoveFailed": "Échec de la suppression de l'image",
- "ToastAuthorImageRemoveSuccess": "Image de l'auteur supprimée",
- "ToastAuthorUpdateFailed": "Échec de la mise à jour de l'auteur",
+ "ToastAuthorImageRemoveFailed": "Échec de la suppression de l’image",
+ "ToastAuthorImageRemoveSuccess": "Image de l’auteur supprimée",
+ "ToastAuthorUpdateFailed": "Échec de la mise à jour de l’auteur",
"ToastAuthorUpdateMerged": "Auteur fusionné",
"ToastAuthorUpdateSuccess": "Auteur mis à jour",
- "ToastAuthorUpdateSuccessNoImageFound": "Auteur mis à jour (pas d'image trouvée)",
+ "ToastAuthorUpdateSuccessNoImageFound": "Auteur mis à jour (aucune image trouvée)",
"ToastBackupCreateFailed": "Échec de la création de sauvegarde",
"ToastBackupCreateSuccess": "Sauvegarde créée",
"ToastBackupDeleteFailed": "Échec de la suppression de sauvegarde",
@@ -578,23 +598,23 @@
"ToastCollectionRemoveSuccess": "Collection supprimée",
"ToastCollectionUpdateFailed": "Échec de la mise à jour de la collection",
"ToastCollectionUpdateSuccess": "Collection mise à jour",
- "ToastItemCoverUpdateFailed": "Échec de la mise à jour de la couverture de l'article",
- "ToastItemCoverUpdateSuccess": "Couverture de l'article mise à jour",
- "ToastItemDetailsUpdateFailed": "Échec de la mise à jour des détails de l'article",
- "ToastItemDetailsUpdateSuccess": "Détails de l'article mis à jour",
- "ToastItemDetailsUpdateUnneeded": "Pas de mise à jour nécessaire pour les détails de l'article",
- "ToastItemMarkedAsFinishedFailed": "Échec de l'annotation terminée",
+ "ToastItemCoverUpdateFailed": "Échec de la mise à jour de la couverture de l’article",
+ "ToastItemCoverUpdateSuccess": "Couverture de l’article mise à jour",
+ "ToastItemDetailsUpdateFailed": "Échec de la mise à jour des détails de l’article",
+ "ToastItemDetailsUpdateSuccess": "Détails de l’article mis à jour",
+ "ToastItemDetailsUpdateUnneeded": "Pas de mise à jour nécessaire sur les détails de l’article",
+ "ToastItemMarkedAsFinishedFailed": "Échec de l’annotation terminée",
"ToastItemMarkedAsFinishedSuccess": "Article marqué comme terminé",
- "ToastItemMarkedAsNotFinishedFailed": "Échec de l'annotation non-terminée",
+ "ToastItemMarkedAsNotFinishedFailed": "Échec de l’annotation non-terminée",
"ToastItemMarkedAsNotFinishedSuccess": "Article marqué comme non-terminé",
"ToastLibraryCreateFailed": "Échec de la création de bibliothèque",
- "ToastLibraryCreateSuccess": "Bibliothèque \"{0}\" créée",
+ "ToastLibraryCreateSuccess": "Bibliothèque « {0} » créée",
"ToastLibraryDeleteFailed": "Échec de la suppression de la bibliothèque",
"ToastLibraryDeleteSuccess": "Bibliothèque supprimée",
- "ToastLibraryScanFailedToStart": "Échec du démarrage de l'analyse",
+ "ToastLibraryScanFailedToStart": "Échec du démarrage de l’analyse",
"ToastLibraryScanStarted": "Analyse de la bibliothèque démarrée",
"ToastLibraryUpdateFailed": "Échec de la mise à jour de la bibliothèque",
- "ToastLibraryUpdateSuccess": "Bibliothèque \"{0}\" mise à jour",
+ "ToastLibraryUpdateSuccess": "Bibliothèque « {0} » mise à jour",
"ToastPlaylistCreateFailed": "Échec de la création de la liste de lecture",
"ToastPlaylistCreateSuccess": "Liste de lecture créée",
"ToastPlaylistRemoveFailed": "Échec de la suppression de la liste de lecture",
@@ -603,17 +623,17 @@
"ToastPlaylistUpdateSuccess": "Liste de lecture mise à jour",
"ToastPodcastCreateFailed": "Échec de la création du Podcast",
"ToastPodcastCreateSuccess": "Podcast créé",
- "ToastRemoveItemFromCollectionFailed": "Échec de la suppression de l'article de la collection",
+ "ToastRemoveItemFromCollectionFailed": "Échec de la suppression de l’article de la collection",
"ToastRemoveItemFromCollectionSuccess": "Article supprimé de la collection",
"ToastRSSFeedCloseFailed": "Échec de la fermeture du flux RSS",
"ToastRSSFeedCloseSuccess": "Flux RSS fermé",
- "ToastSeriesUpdateFailed": "Echec de la mise à jour de la série",
+ "ToastSeriesUpdateFailed": "Échec de la mise à jour de la série",
"ToastSeriesUpdateSuccess": "Mise à jour de la série réussie",
"ToastSessionDeleteFailed": "Échec de la suppression de session",
"ToastSessionDeleteSuccess": "Session supprimée",
"ToastSocketConnected": "WebSocket connecté",
"ToastSocketDisconnected": "WebSocket déconnecté",
"ToastSocketFailedToConnect": "Échec de la connexion WebSocket",
- "ToastUserDeleteFailed": "Échec de la suppression de l'utilisateur",
+ "ToastUserDeleteFailed": "Échec de la suppression de l’utilisateur",
"ToastUserDeleteSuccess": "Utilisateur supprimé"
-}
+}
\ No newline at end of file
diff --git a/client/strings/hr.json b/client/strings/hr.json
index 9f6532b7..395219f4 100644
--- a/client/strings/hr.json
+++ b/client/strings/hr.json
@@ -20,6 +20,7 @@
"ButtonCreate": "Napravi",
"ButtonCreateBackup": "Napravi backup",
"ButtonDelete": "Obriši",
+ "ButtonDownloadQueue": "Queue",
"ButtonEdit": "Edit",
"ButtonEditChapters": "Uredi poglavlja",
"ButtonEditPodcast": "Uredi podcast",
@@ -92,7 +93,9 @@
"HeaderCollection": "Kolekcija",
"HeaderCollectionItems": "Stvari u kolekciji",
"HeaderCover": "Cover",
+ "HeaderCurrentDownloads": "Current Downloads",
"HeaderDetails": "Detalji",
+ "HeaderDownloadQueue": "Download Queue",
"HeaderEpisodes": "Epizode",
"HeaderFiles": "Datoteke",
"HeaderFindChapters": "Pronađi poglavlja",
@@ -126,6 +129,7 @@
"HeaderPreviewCover": "Pregledaj Cover",
"HeaderRemoveEpisode": "Ukloni epizodu",
"HeaderRemoveEpisodes": "Ukloni {0} epizoda/-e",
+ "HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "RSS Feed je otvoren",
"HeaderSavedMediaProgress": "Spremljen Media Progress",
"HeaderSchedule": "Schedule",
@@ -138,6 +142,7 @@
"HeaderSettingsGeneral": "Opčenito",
"HeaderSettingsScanner": "Scanner",
"HeaderSleepTimer": "Sleep Timer",
+ "HeaderStatsLargestItems": "Largest Items",
"HeaderStatsLongestItems": "Najduže stavke (sati)",
"HeaderStatsMinutesListeningChart": "Minuta odslušanih (posljednjih 7 dana)",
"HeaderStatsRecentSessions": "Nedavne sesije",
@@ -162,6 +167,7 @@
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
"LabelAll": "All",
"LabelAllUsers": "Svi korisnici",
+ "LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Autor",
"LabelAuthorFirstLast": "Author (First Last)",
@@ -192,6 +198,7 @@
"LabelCronExpression": "Cron Expression",
"LabelCurrent": "Trenutan",
"LabelCurrently": "Trenutno:",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Datetime",
"LabelDescription": "Opis",
"LabelDeselectAll": "Odznači sve",
@@ -209,6 +216,7 @@
"LabelEpisode": "Epizoda",
"LabelEpisodeTitle": "Naslov epizode",
"LabelEpisodeType": "Vrsta epizode",
+ "LabelExample": "Example",
"LabelExplicit": "Explicit",
"LabelFeedURL": "Feed URL",
"LabelFile": "Datoteka",
@@ -270,6 +278,8 @@
"LabelNewestAuthors": "Najnoviji autori",
"LabelNewestEpisodes": "Najnovije epizode",
"LabelNewPassword": "Nova lozinka",
+ "LabelNextBackupDate": "Next backup date",
+ "LabelNextScheduledRun": "Next scheduled run",
"LabelNotes": "Bilješke",
"LabelNotFinished": "Nedovršeno",
"LabelNotificationAppriseURL": "Apprise URL(s)",
@@ -300,7 +310,9 @@
"LabelPlayMethod": "Vrsta reprodukcije",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts",
+ "LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Prefiksi za ignorirati (mala i velika slova nisu bitna)",
+ "LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
"LabelProgress": "Napredak",
"LabelProvider": "Dobavljač",
"LabelPubDate": "Datam izdavanja",
@@ -312,7 +324,10 @@
"LabelRegion": "Regija",
"LabelReleaseDate": "Datum izlaska",
"LabelRemoveCover": "Remove cover",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "RSS Feed Open",
+ "LabelRSSFeedPreventIndexing": "Prevent Indexing",
"LabelRSSFeedSlug": "RSS Feed Slug",
"LabelRSSFeedURL": "RSS Feed URL",
"LabelSearchTerm": "Traži pojam",
@@ -357,6 +372,7 @@
"LabelSettingsStoreCoversWithItemHelp": "By default covers are stored in /metadata/items, enabling this setting will store covers in your library item folder. Only one file named \"cover\" will be kept",
"LabelSettingsStoreMetadataWithItem": "Spremi metapodatke uz stavku",
"LabelSettingsStoreMetadataWithItemHelp": "Po defaultu metapodatci su spremljeni u /metadata/items, uključujućite li ovu postavku, metapodatci će biti spremljeni u folderima od biblioteke. Koristi .abs ekstenziju.",
+ "LabelSettingsTimeFormat": "Time Format",
"LabelShowAll": "Prikaži sve",
"LabelSize": "Veličina",
"LabelSleepTimer": "Sleep timer",
@@ -384,6 +400,7 @@
"LabelTag": "Tag",
"LabelTags": "Tags",
"LabelTagsAccessibleToUser": "Tags dostupni korisniku",
+ "LabelTasks": "Tasks Running",
"LabelTimeListened": "Vremena odslušano",
"LabelTimeListenedToday": "Vremena odslušano danas",
"LabelTimeRemaining": "{0} preostalo",
@@ -485,6 +502,8 @@
"MessageNoCollections": "Nema kolekcija",
"MessageNoCoversFound": "Covers nisu pronađeni",
"MessageNoDescription": "Nema opisa",
+ "MessageNoDownloadsInProgress": "No downloads currently in progress",
+ "MessageNoDownloadsQueued": "No downloads queued",
"MessageNoEpisodeMatchesFound": "Nijedna epizoda pronađena",
"MessageNoEpisodes": "Nema epizoda",
"MessageNoFoldersAvailable": "Nema dostupnih foldera",
@@ -501,6 +520,7 @@
"MessageNoSearchResultsFor": "Nema rezultata pretragee za \"{0}\"",
"MessageNoSeries": "No Series",
"MessageNoTags": "No Tags",
+ "MessageNoTasksRunning": "No Tasks Running",
"MessageNotYetImplemented": "Not yet implemented",
"MessageNoUpdateNecessary": "Aktualiziranje nije potrebno",
"MessageNoUpdatesWereNecessary": "Aktualiziranje nije bilo potrebno",
@@ -616,4 +636,4 @@
"ToastSocketFailedToConnect": "Socket failed to connect",
"ToastUserDeleteFailed": "Neuspješno brisanje korisnika",
"ToastUserDeleteSuccess": "Korisnik obrisan"
-}
+}
\ No newline at end of file
diff --git a/client/strings/it.json b/client/strings/it.json
index 01a8a215..f7d1bda4 100644
--- a/client/strings/it.json
+++ b/client/strings/it.json
@@ -20,6 +20,7 @@
"ButtonCreate": "Crea",
"ButtonCreateBackup": "Crea un Backup",
"ButtonDelete": "Elimina",
+ "ButtonDownloadQueue": "Queue",
"ButtonEdit": "Edit",
"ButtonEditChapters": "Modifica Capitoli",
"ButtonEditPodcast": "Modifica Podcast",
@@ -92,7 +93,9 @@
"HeaderCollection": "Raccolta",
"HeaderCollectionItems": "Elementi della Raccolta",
"HeaderCover": "Cover",
+ "HeaderCurrentDownloads": "Current Downloads",
"HeaderDetails": "Dettagli",
+ "HeaderDownloadQueue": "Download Queue",
"HeaderEpisodes": "Episodi",
"HeaderFiles": "File",
"HeaderFindChapters": "Trova Capitoli",
@@ -126,6 +129,7 @@
"HeaderPreviewCover": "Anteprima Cover",
"HeaderRemoveEpisode": "Rimuovi Episodi",
"HeaderRemoveEpisodes": "Rimuovi {0} Episodi",
+ "HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "RSS Feed è aperto",
"HeaderSavedMediaProgress": "Progressi salvati",
"HeaderSchedule": "Schedula",
@@ -138,6 +142,7 @@
"HeaderSettingsGeneral": "Generale",
"HeaderSettingsScanner": "Scanner",
"HeaderSleepTimer": "Sveglia",
+ "HeaderStatsLargestItems": "Largest Items",
"HeaderStatsLongestItems": "libri più lunghi (ore)",
"HeaderStatsMinutesListeningChart": "Minuti ascoltati (Ultimi 7 Giorni)",
"HeaderStatsRecentSessions": "Sessioni Recenti",
@@ -162,6 +167,7 @@
"LabelAddToPlaylistBatch": "Aggiungi {0} file alla Playlist",
"LabelAll": "Tutti",
"LabelAllUsers": "Tutti gli Utenti",
+ "LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Appese",
"LabelAuthor": "Autore",
"LabelAuthorFirstLast": "Autore (Per Nome)",
@@ -192,6 +198,7 @@
"LabelCronExpression": "Espressione Cron",
"LabelCurrent": "Attuale",
"LabelCurrently": "Attualmente:",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Data & Ora",
"LabelDescription": "Descrizione",
"LabelDeselectAll": "Deseleziona Tutto",
@@ -209,6 +216,7 @@
"LabelEpisode": "Episodio",
"LabelEpisodeTitle": "Titolo Episodio",
"LabelEpisodeType": "Tipo Episodio",
+ "LabelExample": "Example",
"LabelExplicit": "Esplicito",
"LabelFeedURL": "Feed URL",
"LabelFile": "File",
@@ -270,6 +278,8 @@
"LabelNewestAuthors": "Autori Recenti",
"LabelNewestEpisodes": "Episodi Recenti",
"LabelNewPassword": "Nuova Password",
+ "LabelNextBackupDate": "Next backup date",
+ "LabelNextScheduledRun": "Next scheduled run",
"LabelNotes": "Note",
"LabelNotFinished": "Da Completare",
"LabelNotificationAppriseURL": "Apprendi URL(s)",
@@ -300,7 +310,9 @@
"LabelPlayMethod": "Metodo di riproduzione",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts",
+ "LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Suffissi da ignorare (specificando maiuscole e minuscole)",
+ "LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
"LabelProgress": "Cominciati",
"LabelProvider": "Provider",
"LabelPubDate": "Data Pubblicazione",
@@ -312,7 +324,10 @@
"LabelRegion": "Regione",
"LabelReleaseDate": "Data Release",
"LabelRemoveCover": "Remove cover",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "RSS Feed Aperto",
+ "LabelRSSFeedPreventIndexing": "Prevent Indexing",
"LabelRSSFeedSlug": "RSS Feed Slug",
"LabelRSSFeedURL": "RSS Feed URL",
"LabelSearchTerm": "Ricerca",
@@ -357,6 +372,7 @@
"LabelSettingsStoreCoversWithItemHelp": "Di default, le immagini di copertina sono salvate dentro /metadata/items, abilitando questa opzione le copertine saranno archiviate nella cartella della libreria corrispondente. Verrà conservato solo un file denominato \"cover\"",
"LabelSettingsStoreMetadataWithItem": "Archivia i metadata con il file",
"LabelSettingsStoreMetadataWithItemHelp": "Di default, i metadati sono salvati dentro /metadata/items, abilitando questa opzione si memorizzeranno i metadata nella cartella della libreria. I file avranno estensione .abs",
+ "LabelSettingsTimeFormat": "Time Format",
"LabelShowAll": "Mostra Tutto",
"LabelSize": "Dimensione",
"LabelSleepTimer": "Sleep timer",
@@ -384,6 +400,7 @@
"LabelTag": "Tag",
"LabelTags": "Tags",
"LabelTagsAccessibleToUser": "Tags permessi agli Utenti",
+ "LabelTasks": "Tasks Running",
"LabelTimeListened": "Tempo di Ascolto",
"LabelTimeListenedToday": "Tempo di Ascolto Oggi",
"LabelTimeRemaining": "{0} rimanente",
@@ -485,6 +502,8 @@
"MessageNoCollections": "Nessuna Raccolta",
"MessageNoCoversFound": "Nessuna Cover Trovata",
"MessageNoDescription": "Nessuna descrizione",
+ "MessageNoDownloadsInProgress": "No downloads currently in progress",
+ "MessageNoDownloadsQueued": "No downloads queued",
"MessageNoEpisodeMatchesFound": "Nessun episodio corrispondente trovato",
"MessageNoEpisodes": "Nessun Episodio",
"MessageNoFoldersAvailable": "Nessuna Cartella disponibile",
@@ -501,6 +520,7 @@
"MessageNoSearchResultsFor": "Nessun risultato per \"{0}\"",
"MessageNoSeries": "Nessuna Serie",
"MessageNoTags": "No Tags",
+ "MessageNoTasksRunning": "No Tasks Running",
"MessageNotYetImplemented": "Non Ancora Implementato",
"MessageNoUpdateNecessary": "Nessun aggiornamento necessario",
"MessageNoUpdatesWereNecessary": "Nessun aggiornamento necessario",
@@ -616,4 +636,4 @@
"ToastSocketFailedToConnect": "Socket non riesce a connettersi",
"ToastUserDeleteFailed": "Errore eliminazione utente",
"ToastUserDeleteSuccess": "Utente eliminato"
-}
+}
\ No newline at end of file
diff --git a/client/strings/pl.json b/client/strings/pl.json
index f1df9a3a..7d8e3573 100644
--- a/client/strings/pl.json
+++ b/client/strings/pl.json
@@ -20,6 +20,7 @@
"ButtonCreate": "Utwórz",
"ButtonCreateBackup": "Utwórz kopię zapasową",
"ButtonDelete": "Usuń",
+ "ButtonDownloadQueue": "Queue",
"ButtonEdit": "Edit",
"ButtonEditChapters": "Edytuj rozdziały",
"ButtonEditPodcast": "Edytuj podcast",
@@ -92,7 +93,9 @@
"HeaderCollection": "Kolekcja",
"HeaderCollectionItems": "Elementy kolekcji",
"HeaderCover": "Okładka",
+ "HeaderCurrentDownloads": "Current Downloads",
"HeaderDetails": "Szczegóły",
+ "HeaderDownloadQueue": "Download Queue",
"HeaderEpisodes": "Rozdziały",
"HeaderFiles": "Pliki",
"HeaderFindChapters": "Wyszukaj rozdziały",
@@ -126,6 +129,7 @@
"HeaderPreviewCover": "Podgląd okładki",
"HeaderRemoveEpisode": "Usuń odcinek",
"HeaderRemoveEpisodes": "Usuń {0} odcinków",
+ "HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "Kanał RSS jest otwarty",
"HeaderSavedMediaProgress": "Zapisany postęp",
"HeaderSchedule": "Harmonogram",
@@ -138,6 +142,7 @@
"HeaderSettingsGeneral": "Ogólne",
"HeaderSettingsScanner": "Skanowanie",
"HeaderSleepTimer": "Wyłącznik czasowy",
+ "HeaderStatsLargestItems": "Largest Items",
"HeaderStatsLongestItems": "Najdłuższe pozycje (hrs)",
"HeaderStatsMinutesListeningChart": "Czas słuchania w minutach (ostatnie 7 dni)",
"HeaderStatsRecentSessions": "Ostatnie sesje",
@@ -162,6 +167,7 @@
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
"LabelAll": "All",
"LabelAllUsers": "Wszyscy użytkownicy",
+ "LabelAlreadyInYourLibrary": "Already in your library",
"LabelAppend": "Append",
"LabelAuthor": "Autor",
"LabelAuthorFirstLast": "Autor (Rosnąco)",
@@ -192,6 +198,7 @@
"LabelCronExpression": "Wyrażenie CRON",
"LabelCurrent": "Aktualny",
"LabelCurrently": "Obecnie:",
+ "LabelCustomCronExpression": "Custom Cron Expression:",
"LabelDatetime": "Data i godzina",
"LabelDescription": "Opis",
"LabelDeselectAll": "Odznacz wszystko",
@@ -209,6 +216,7 @@
"LabelEpisode": "Odcinek",
"LabelEpisodeTitle": "Tytuł odcinka",
"LabelEpisodeType": "Typ odcinka",
+ "LabelExample": "Example",
"LabelExplicit": "Nieprzyzwoite",
"LabelFeedURL": "URL kanału",
"LabelFile": "Plik",
@@ -270,6 +278,8 @@
"LabelNewestAuthors": "Najnowsi autorzy",
"LabelNewestEpisodes": "Najnowsze odcinki",
"LabelNewPassword": "Nowe hasło",
+ "LabelNextBackupDate": "Next backup date",
+ "LabelNextScheduledRun": "Next scheduled run",
"LabelNotes": "Uwagi",
"LabelNotFinished": "Nieukończone",
"LabelNotificationAppriseURL": "URLe Apprise",
@@ -300,7 +310,9 @@
"LabelPlayMethod": "Metoda odtwarzania",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasty",
+ "LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)",
+ "LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
"LabelProgress": "Postęp",
"LabelProvider": "Dostawca",
"LabelPubDate": "Data publikacji",
@@ -312,7 +324,10 @@
"LabelRegion": "Region",
"LabelReleaseDate": "Data wydania",
"LabelRemoveCover": "Remove cover",
+ "LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
+ "LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "RSS Feed otwarty",
+ "LabelRSSFeedPreventIndexing": "Prevent Indexing",
"LabelRSSFeedSlug": "RSS Feed Slug",
"LabelRSSFeedURL": "URL kanały RSS",
"LabelSearchTerm": "Wyszukiwanie frazy",
@@ -357,6 +372,7 @@
"LabelSettingsStoreCoversWithItemHelp": "Domyślnie okładki są przechowywane w folderze /metadata/items, włączenie tej opcji spowoduje, że okładka będzie przechowywana w folderze ksiązki. Tylko jedna okładka o nazwie pliku \"cover\" będzie przechowywana.",
"LabelSettingsStoreMetadataWithItem": "Przechowuj metadane w folderze książki",
"LabelSettingsStoreMetadataWithItemHelp": "Domyślnie metadane są przechowywane w folderze /metadata/items, włączenie tej opcji spowoduje, że okładka będzie przechowywana w folderze ksiązki. Tylko jedna okładka o nazwie pliku \"cover\" będzie przechowywana. Rozszerzenie pliku metadanych: .abs",
+ "LabelSettingsTimeFormat": "Time Format",
"LabelShowAll": "Pokaż wszystko",
"LabelSize": "Rozmiar",
"LabelSleepTimer": "Wyłącznik czasowy",
@@ -384,6 +400,7 @@
"LabelTag": "Tag",
"LabelTags": "Tagi",
"LabelTagsAccessibleToUser": "Tagi dostępne dla użytkownika",
+ "LabelTasks": "Tasks Running",
"LabelTimeListened": "Czas odtwarzania",
"LabelTimeListenedToday": "Czas odtwarzania dzisiaj",
"LabelTimeRemaining": "Pozostało {0}",
@@ -485,6 +502,8 @@
"MessageNoCollections": "Brak kolekcji",
"MessageNoCoversFound": "Okładki nieznalezione",
"MessageNoDescription": "Brak opisu",
+ "MessageNoDownloadsInProgress": "No downloads currently in progress",
+ "MessageNoDownloadsQueued": "No downloads queued",
"MessageNoEpisodeMatchesFound": "Nie znaleziono pasujących odcinków",
"MessageNoEpisodes": "Brak odcinków",
"MessageNoFoldersAvailable": "Brak dostępnych folderów",
@@ -501,6 +520,7 @@
"MessageNoSearchResultsFor": "Brak wyników wyszukiwania dla \"{0}\"",
"MessageNoSeries": "No Series",
"MessageNoTags": "No Tags",
+ "MessageNoTasksRunning": "No Tasks Running",
"MessageNotYetImplemented": "Jeszcze nie zaimplementowane",
"MessageNoUpdateNecessary": "Brak konieczności aktualizacji",
"MessageNoUpdatesWereNecessary": "Brak aktualizacji",
@@ -616,4 +636,4 @@
"ToastSocketFailedToConnect": "Poączenie z serwerem nie powiodło się",
"ToastUserDeleteFailed": "Nie udało się usunąć użytkownika",
"ToastUserDeleteSuccess": "Użytkownik usunięty"
-}
+}
\ No newline at end of file
diff --git a/client/strings/ru.json b/client/strings/ru.json
index 0c3c298b..b5660db2 100644
--- a/client/strings/ru.json
+++ b/client/strings/ru.json
@@ -1,30 +1,31 @@
{
"ButtonAdd": "Добавить",
- "ButtonAddChapters": "Добавить Главы",
- "ButtonAddPodcasts": "Добавить Подкасты",
+ "ButtonAddChapters": "Добавить главы",
+ "ButtonAddPodcasts": "Добавить подкасты",
"ButtonAddYourFirstLibrary": "Добавьте Вашу первую библиотеку",
"ButtonApply": "Применить",
- "ButtonApplyChapters": "Применить Главы",
+ "ButtonApplyChapters": "Применить главы",
"ButtonAuthors": "Авторы",
- "ButtonBrowseForFolder": "Выбрать Папку",
+ "ButtonBrowseForFolder": "Выбрать папку",
"ButtonCancel": "Отмена",
- "ButtonCancelEncode": "Отменить Кодирование",
- "ButtonChangeRootPassword": "Поменять Мастер Пароль",
- "ButtonCheckAndDownloadNewEpisodes": "Проверка и Загрузка Новых Эпизодов",
+ "ButtonCancelEncode": "Отменить кодирование",
+ "ButtonChangeRootPassword": "Поменять мастер пароль",
+ "ButtonCheckAndDownloadNewEpisodes": "Проверка и Загрузка новых эпизодов",
"ButtonChooseAFolder": "Выбор папки",
"ButtonChooseFiles": "Выбор файлов",
- "ButtonClearFilter": "Очистить Фильтр",
- "ButtonCloseFeed": "Закрыть Канал",
+ "ButtonClearFilter": "Очистить фильтр",
+ "ButtonCloseFeed": "Закрыть канал",
"ButtonCollections": "Коллекции",
- "ButtonConfigureScanner": "Конфигурация Сканера",
+ "ButtonConfigureScanner": "Конфигурация сканера",
"ButtonCreate": "Создать",
"ButtonCreateBackup": "Создать бэкап",
"ButtonDelete": "Удалить",
+ "ButtonDownloadQueue": "Очередь",
"ButtonEdit": "Редактировать",
- "ButtonEditChapters": "Редактировать Главы",
- "ButtonEditPodcast": "Редактировать Подкаст",
- "ButtonForceReScan": "Принудительно Пере сканировать",
- "ButtonFullPath": "Полный Путь",
+ "ButtonEditChapters": "Редактировать главы",
+ "ButtonEditPodcast": "Редактировать подкаст",
+ "ButtonForceReScan": "Принудительно пересканировать",
+ "ButtonFullPath": "Полный путь",
"ButtonHide": "Скрыть",
"ButtonHome": "Домой",
"ButtonIssues": "Проблемы",
@@ -32,143 +33,148 @@
"ButtonLibrary": "Библиотека",
"ButtonLogout": "Выход",
"ButtonLookup": "Найти",
- "ButtonManageTracks": "Управление Треками",
- "ButtonMapChapterTitles": "Найти Названия Глав",
- "ButtonMatchAllAuthors": "Найти Всех Авторов",
- "ButtonMatchBooks": "Найти Книги",
+ "ButtonManageTracks": "Управление треками",
+ "ButtonMapChapterTitles": "Найти названия глав",
+ "ButtonMatchAllAuthors": "Найти всех авторов",
+ "ButtonMatchBooks": "Найти книги",
"ButtonNevermind": "Не важно",
"ButtonOk": "Ok",
- "ButtonOpenFeed": "Открыть Канал",
- "ButtonOpenManager": "Открыть Менеджер",
+ "ButtonOpenFeed": "Открыть канал",
+ "ButtonOpenManager": "Открыть менеджер",
"ButtonPlay": "Слушать",
"ButtonPlaying": "Проигрывается",
"ButtonPlaylists": "Плейлисты",
- "ButtonPurgeAllCache": "Очистить Весь Кэш",
- "ButtonPurgeItemsCache": "Очистить Кэш Элементов",
- "ButtonPurgeMediaProgress": "Очистить Прогресс Медиа",
+ "ButtonPurgeAllCache": "Очистить весь кэш",
+ "ButtonPurgeItemsCache": "Очистить кэш элементов",
+ "ButtonPurgeMediaProgress": "Очистить прогресс медиа",
"ButtonQueueAddItem": "Добавить в очередь",
"ButtonQueueRemoveItem": "Удалить из очереди",
- "ButtonQuickMatch": "Быстрый Поиск",
+ "ButtonQuickMatch": "Быстрый поиск",
"ButtonRead": "Читать",
"ButtonRemove": "Удалить",
- "ButtonRemoveAll": "Удалить Всё",
- "ButtonRemoveAllLibraryItems": "Удалить Все Элементы Библиотеки",
- "ButtonRemoveFromContinueListening": "Удалить из Продолжить Слушать",
- "ButtonRemoveSeriesFromContinueSeries": "Удалить Серию из Продолжить Серию",
- "ButtonReScan": "Пере сканировать",
+ "ButtonRemoveAll": "Удалить всё",
+ "ButtonRemoveAllLibraryItems": "Удалить все элементы библиотеки",
+ "ButtonRemoveFromContinueListening": "Удалить из Продолжить слушать",
+ "ButtonRemoveSeriesFromContinueSeries": "Удалить серию из Продолжить серию",
+ "ButtonReScan": "Пересканировать",
"ButtonReset": "Сбросить",
"ButtonRestore": "Восстановить",
"ButtonSave": "Сохранить",
- "ButtonSaveAndClose": "Сохранить и Закрыть",
- "ButtonSaveTracklist": "Сохранить Список треков",
+ "ButtonSaveAndClose": "Сохранить и закрыть",
+ "ButtonSaveTracklist": "Сохранить список треков",
"ButtonScan": "Сканировать",
- "ButtonScanLibrary": "Сканировать Библиотеку",
+ "ButtonScanLibrary": "Сканировать библиотеку",
"ButtonSearch": "Поиск",
- "ButtonSelectFolderPath": "Выберите Путь Папки",
+ "ButtonSelectFolderPath": "Выберите путь папки",
"ButtonSeries": "Серии",
"ButtonSetChaptersFromTracks": "Установить главы из треков",
"ButtonShiftTimes": "Смещение",
"ButtonShow": "Показать",
- "ButtonStartM4BEncode": "Начать Кодирование M4B",
- "ButtonStartMetadataEmbed": "Начать Встраивание Метаданных",
+ "ButtonStartM4BEncode": "Начать кодирование M4B",
+ "ButtonStartMetadataEmbed": "Начать встраивание метаданных",
"ButtonSubmit": "Применить",
"ButtonUpload": "Загрузить",
- "ButtonUploadBackup": "Загрузить Бэкап",
- "ButtonUploadCover": "Загрузить Обложку",
+ "ButtonUploadBackup": "Загрузить бэкап",
+ "ButtonUploadCover": "Загрузить обложку",
"ButtonUploadOPMLFile": "Загрузить Файл OPML",
"ButtonUserDelete": "Удалить пользователя {0}",
"ButtonUserEdit": "Редактировать пользователя {0}",
- "ButtonViewAll": "Посмотреть Все",
+ "ButtonViewAll": "Посмотреть все",
"ButtonYes": "Да",
"HeaderAccount": "Учетная запись",
"HeaderAdvanced": "Дополнительно",
- "HeaderAppriseNotificationSettings": "Настройки Оповещений",
- "HeaderAudiobookTools": "Инструменты Файлов Аудиокниг",
- "HeaderAudioTracks": "Аудио Треки",
+ "HeaderAppriseNotificationSettings": "Настройки оповещений",
+ "HeaderAudiobookTools": "Инструменты файлов аудиокниг",
+ "HeaderAudioTracks": "Аудио треки",
"HeaderBackups": "Бэкапы",
- "HeaderChangePassword": "Изменить Пароль",
+ "HeaderChangePassword": "Изменить пароль",
"HeaderChapters": "Главы",
- "HeaderChooseAFolder": "Выберите Папку",
+ "HeaderChooseAFolder": "Выберите папку",
"HeaderCollection": "Коллекция",
- "HeaderCollectionItems": "Элементы Коллекции",
+ "HeaderCollectionItems": "Элементы коллекции",
"HeaderCover": "Обложка",
+ "HeaderCurrentDownloads": "Текущие закачки",
"HeaderDetails": "Подробности",
+ "HeaderDownloadQueue": "Очередь скачивания",
"HeaderEpisodes": "Эпизоды",
"HeaderFiles": "Файлы",
- "HeaderFindChapters": "Найти Главы",
+ "HeaderFindChapters": "Найти главы",
"HeaderIgnoredFiles": "Игнорируемые Файлы",
- "HeaderItemFiles": "Файлы Элемента",
+ "HeaderItemFiles": "Файлы элемента",
"HeaderItemMetadataUtils": "Утилиты",
- "HeaderLastListeningSession": "Последний Сеанс Прослушивания",
+ "HeaderLastListeningSession": "Последний сеанс прослушивания",
"HeaderLatestEpisodes": "Последние эпизоды",
"HeaderLibraries": "Библиотеки",
- "HeaderLibraryFiles": "Файлы Библиотеки",
- "HeaderLibraryStats": "Статистика Библиотеки",
+ "HeaderLibraryFiles": "Файлы библиотеки",
+ "HeaderLibraryStats": "Статистика библиотеки",
"HeaderListeningSessions": "Сеансы",
- "HeaderListeningStats": "Статистика Прослушивания",
+ "HeaderListeningStats": "Статистика прослушивания",
"HeaderLogin": "Логин",
"HeaderLogs": "Логи",
- "HeaderManageGenres": "Редактировать Жанры",
- "HeaderManageTags": "Редактировать Теги",
+ "HeaderManageGenres": "Редактировать жанры",
+ "HeaderManageTags": "Редактировать теги",
"HeaderMapDetails": "Найти подробности",
"HeaderMatch": "Поиск",
"HeaderMetadataToEmbed": "Метаинформация для встраивания",
- "HeaderNewAccount": "Новая Учетная запись",
- "HeaderNewLibrary": "Новая Библиотека",
+ "HeaderNewAccount": "Новая учетная запись",
+ "HeaderNewLibrary": "Новая библиотека",
"HeaderNotifications": "Уведомления",
"HeaderOpenRSSFeed": "Открыть RSS-канал",
- "HeaderOtherFiles": "Другие Файлы",
+ "HeaderOtherFiles": "Другие файлы",
"HeaderPermissions": "Разрешения",
- "HeaderPlayerQueue": "Очередь Воспроизведения",
+ "HeaderPlayerQueue": "Очередь воспроизведения",
"HeaderPlaylist": "Плейлист",
- "HeaderPlaylistItems": "Элементы Списка Воспроизведения",
- "HeaderPodcastsToAdd": "Подкасты для Добавления",
- "HeaderPreviewCover": "Предпросмотр Обложки",
- "HeaderRemoveEpisode": "Удалить Эпизод",
- "HeaderRemoveEpisodes": "Удалить {0} Эпизодов",
- "HeaderRSSFeedIsOpen": "RSS-канал Открыт",
- "HeaderSavedMediaProgress": "Прогресс Медиа Сохранен",
+ "HeaderPlaylistItems": "Элементы списка воспроизведения",
+ "HeaderPodcastsToAdd": "Подкасты для добавления",
+ "HeaderPreviewCover": "Предпросмотр обложки",
+ "HeaderRemoveEpisode": "Удалить эпизод",
+ "HeaderRemoveEpisodes": "Удалить {0} эпизодов",
+ "HeaderRSSFeedGeneral": "Сведения о RSS",
+ "HeaderRSSFeedIsOpen": "RSS-канал открыт",
+ "HeaderSavedMediaProgress": "Прогресс медиа сохранен",
"HeaderSchedule": "Планировщик",
- "HeaderScheduleLibraryScans": "Планировщик Автоматического Сканирования Библиотеки",
+ "HeaderScheduleLibraryScans": "Планировщик автоматического сканирования библиотеки",
"HeaderSession": "Сеансы",
- "HeaderSetBackupSchedule": "Установить Планировщик Бэкапов",
+ "HeaderSetBackupSchedule": "Установить планировщик бэкапов",
"HeaderSettings": "Настройки",
"HeaderSettingsDisplay": "Дисплей",
- "HeaderSettingsExperimental": "Экспериментальные Функции",
+ "HeaderSettingsExperimental": "Экспериментальные функции",
"HeaderSettingsGeneral": "Основные",
"HeaderSettingsScanner": "Сканер",
- "HeaderSleepTimer": "Таймер Сна",
- "HeaderStatsLongestItems": "Самые Длинные Книги (часов)",
+ "HeaderSleepTimer": "Таймер сна",
+ "HeaderStatsLargestItems": "Самые большые элементы",
+ "HeaderStatsLongestItems": "Самые длинные элементы (часов)",
"HeaderStatsMinutesListeningChart": "Минут прослушивания (последние 7 дней)",
- "HeaderStatsRecentSessions": "Последние Сеансы",
- "HeaderStatsTop10Authors": "Топ 10 Авторов",
- "HeaderStatsTop5Genres": "Топ 5 Жанров",
+ "HeaderStatsRecentSessions": "Последние сеансы",
+ "HeaderStatsTop10Authors": "Топ 10 авторов",
+ "HeaderStatsTop5Genres": "Топ 5 жанров",
"HeaderTools": "Инструменты",
- "HeaderUpdateAccount": "Обновить Учетную запись",
- "HeaderUpdateAuthor": "Обновить Автора",
- "HeaderUpdateDetails": "Обновить Детали",
- "HeaderUpdateLibrary": "Обновить Библиотеку",
+ "HeaderUpdateAccount": "Обновить учетную запись",
+ "HeaderUpdateAuthor": "Обновить автора",
+ "HeaderUpdateDetails": "Обновить детали",
+ "HeaderUpdateLibrary": "Обновить библиотеку",
"HeaderUsers": "Пользователи",
- "HeaderYourStats": "Ваша Статистика",
- "LabelAccountType": "Тип Учетной записи",
+ "HeaderYourStats": "Ваша статистика",
+ "LabelAccountType": "Тип учетной записи",
"LabelAccountTypeAdmin": "Администратор",
"LabelAccountTypeGuest": "Гость",
"LabelAccountTypeUser": "Пользователь",
"LabelActivity": "Активность",
- "LabelAddedAt": "Добавить В",
- "LabelAddToCollection": "Добавить в Коллекцию",
- "LabelAddToCollectionBatch": "Добавить {0} Книг в Коллекцию",
- "LabelAddToPlaylist": "Добавить в Плейлист",
- "LabelAddToPlaylistBatch": "Добавить {0} Элементов в Плейлист",
+ "LabelAddedAt": "Дата добавления",
+ "LabelAddToCollection": "Добавить в коллекцию",
+ "LabelAddToCollectionBatch": "Добавить {0} книг в коллекцию",
+ "LabelAddToPlaylist": "Добавить в плейлист",
+ "LabelAddToPlaylistBatch": "Добавить {0} элементов в плейлист",
"LabelAll": "Все",
"LabelAllUsers": "Все пользователи",
+ "LabelAlreadyInYourLibrary": "Уже в Вашей библиотеке",
"LabelAppend": "Добавить",
"LabelAuthor": "Автор",
"LabelAuthorFirstLast": "Автор (Имя Фамилия)",
"LabelAuthorLastFirst": "Автор (Фамилия, Имя)",
"LabelAuthors": "Авторы",
- "LabelAutoDownloadEpisodes": "Скачивать Эпизоды Автоматически",
- "LabelBackToUser": "Назад к Пользователю",
+ "LabelAutoDownloadEpisodes": "Скачивать эпизоды автоматически",
+ "LabelBackToUser": "Назад к пользователю",
"LabelBackupsEnableAutomaticBackups": "Включить автоматическое бэкапирование",
"LabelBackupsEnableAutomaticBackupsHelp": "Бэкапы сохраняются в /metadata/backups",
"LabelBackupsMaxBackupSize": "Максимальный размер бэкапа (в GB)",
@@ -176,27 +182,28 @@
"LabelBackupsNumberToKeep": "Сохранять бэкапов",
"LabelBackupsNumberToKeepHelp": "За один раз только 1 бэкап будет удален, так что если у вас будет больше бэкапов, то их нужно удалить вручную.",
"LabelBooks": "Книги",
- "LabelChangePassword": "Изменить Пароль",
+ "LabelChangePassword": "Изменить пароль",
"LabelChaptersFound": "глав найдено",
- "LabelChapterTitle": "Название Главы",
+ "LabelChapterTitle": "Название главы",
"LabelClosePlayer": "Закрыть проигрыватель",
- "LabelCollapseSeries": "Свернуть Серии",
+ "LabelCollapseSeries": "Свернуть серии",
"LabelCollections": "Коллекции",
"LabelComplete": "Завершить",
- "LabelConfirmPassword": "Подтвердить Пароль",
- "LabelContinueListening": "Продолжить Слушать",
- "LabelContinueSeries": "Продолжить Серию",
+ "LabelConfirmPassword": "Подтвердить пароль",
+ "LabelContinueListening": "Продолжить слушать",
+ "LabelContinueSeries": "Продолжить серию",
"LabelCover": "Обложка",
- "LabelCoverImageURL": "URL Изображения Обложки",
+ "LabelCoverImageURL": "URL изображения обложки",
"LabelCreatedAt": "Создано",
"LabelCronExpression": "Выражение Cron",
"LabelCurrent": "Текущий",
"LabelCurrently": "Текущее:",
+ "LabelCustomCronExpression": "Пользовательское выражение Cron:",
"LabelDatetime": "Дата и время",
"LabelDescription": "Описание",
- "LabelDeselectAll": "Снять Выделение",
+ "LabelDeselectAll": "Снять выделение",
"LabelDevice": "Устройство",
- "LabelDeviceInfo": "Информация об Устройстве",
+ "LabelDeviceInfo": "Информация об устройстве",
"LabelDirectory": "Каталог",
"LabelDiscFromFilename": "Диск из Имени файла",
"LabelDiscFromMetadata": "Диск из Метаданных",
@@ -207,16 +214,17 @@
"LabelEnable": "Включить",
"LabelEnd": "Конец",
"LabelEpisode": "Эпизод",
- "LabelEpisodeTitle": "Имя Эпизода",
- "LabelEpisodeType": "Тип Эпизода",
+ "LabelEpisodeTitle": "Имя эпизода",
+ "LabelEpisodeType": "Тип эпизода",
+ "LabelExample": "Пример",
"LabelExplicit": "Явный",
- "LabelFeedURL": "URL Канала",
+ "LabelFeedURL": "URL канала",
"LabelFile": "Файл",
- "LabelFileBirthtime": "Дата Создания",
- "LabelFileModified": "Дата Модификации",
+ "LabelFileBirthtime": "Дата создания",
+ "LabelFileModified": "Дата модификации",
"LabelFilename": "Имя файла",
- "LabelFilterByUser": "Фильтр по Пользователю",
- "LabelFindEpisodes": "Найти Эпизоды",
+ "LabelFilterByUser": "Фильтр по пользователю",
+ "LabelFindEpisodes": "Найти эпизоды",
"LabelFinished": "Закончен",
"LabelFolder": "Папка",
"LabelFolders": "Папки",
@@ -225,7 +233,7 @@
"LabelHardDeleteFile": "Жесткое удаление файла",
"LabelHour": "Часы",
"LabelIcon": "Иконка",
- "LabelIncludeInTracklist": "Включать в Список воспроизведения",
+ "LabelIncludeInTracklist": "Включать в список воспроизведения",
"LabelIncomplete": "Не завершен",
"LabelInProgress": "В процессе",
"LabelInterval": "Интервал",
@@ -237,96 +245,103 @@
"LabelIntervalEvery6Hours": "Каждые 6 часов",
"LabelIntervalEveryDay": "Каждый день",
"LabelIntervalEveryHour": "Каждый час",
- "LabelInvalidParts": "Неверные Части",
+ "LabelInvalidParts": "Неверные части",
"LabelItem": "Элемент",
"LabelLanguage": "Язык",
- "LabelLanguageDefaultServer": "Язык Сервера по Умолчанию",
- "LabelLastSeen": "Последнее Сканирование",
- "LabelLastTime": "Последний по Времени",
- "LabelLastUpdate": "Последний Обновленный",
+ "LabelLanguageDefaultServer": "Язык сервера по умолчанию",
+ "LabelLastSeen": "Последнее сканирование",
+ "LabelLastTime": "Последний по времени",
+ "LabelLastUpdate": "Последний обновленный",
"LabelLess": "Менее",
- "LabelLibrariesAccessibleToUser": "Библиотеки Доступные для Пользователя",
+ "LabelLibrariesAccessibleToUser": "Библиотеки доступные для пользователя",
"LabelLibrary": "Библиотека",
- "LabelLibraryItem": "Элемент Библиотеки",
- "LabelLibraryName": "Имя Библиотеки",
+ "LabelLibraryItem": "Элемент библиотеки",
+ "LabelLibraryName": "Имя библиотеки",
"LabelLimit": "Лимит",
- "LabelListenAgain": "Послушать Снова",
+ "LabelListenAgain": "Послушать снова",
"LabelLogLevelDebug": "Debug",
"LabelLogLevelInfo": "Info",
"LabelLogLevelWarn": "Warn",
"LabelLookForNewEpisodesAfterDate": "Искать новые эпизоды после этой даты",
- "LabelMediaPlayer": "Медиа Проигрыватель",
- "LabelMediaType": "Тип Медиа",
+ "LabelMediaPlayer": "Медиа проигрыватель",
+ "LabelMediaType": "Тип медиа",
"LabelMetadataProvider": "Провайдер",
- "LabelMetaTag": "Мета Тег",
+ "LabelMetaTag": "Мета тег",
"LabelMinute": "Минуты",
"LabelMissing": "Потеряно",
- "LabelMissingParts": "Потерянные Части",
+ "LabelMissingParts": "Потерянные части",
"LabelMore": "Еще",
"LabelName": "Имя",
"LabelNarrator": "Читает",
"LabelNarrators": "Чтецы",
"LabelNew": "Новый",
- "LabelNewestAuthors": "Новые Авторы",
- "LabelNewestEpisodes": "Новые Эпизоды",
- "LabelNewPassword": "Новый Пароль",
+ "LabelNewestAuthors": "Новые авторы",
+ "LabelNewestEpisodes": "Новые эпизоды",
+ "LabelNewPassword": "Новый пароль",
+ "LabelNextBackupDate": "Следующая дата бэкапирования",
+ "LabelNextScheduledRun": "Следущий запланированный запуск",
"LabelNotes": "Заметки",
- "LabelNotFinished": "Не Завершено",
+ "LabelNotFinished": "Не завершено",
"LabelNotificationAppriseURL": "URL(ы) для извещений",
"LabelNotificationAvailableVariables": "Доступные переменные",
- "LabelNotificationBodyTemplate": "Шаблон Тела",
- "LabelNotificationEvent": "Событие Оповещения",
+ "LabelNotificationBodyTemplate": "Шаблон тела",
+ "LabelNotificationEvent": "Событие оповещения",
"LabelNotificationsMaxFailedAttempts": "Макс. попыток",
"LabelNotificationsMaxFailedAttemptsHelp": "Уведомления будут выключены если произойдет ошибка отправки данное количество раз",
"LabelNotificationsMaxQueueSize": "Макс. размер очереди для событий уведомлений",
"LabelNotificationsMaxQueueSizeHelp": "События ограничены 1 в секунду. События будут игнорированы если в очереди максимальное количество. Это предотвращает спам сообщениями.",
- "LabelNotificationTitleTemplate": "Шаблон Заголовка",
- "LabelNotStarted": "Не Запущено",
- "LabelNumberOfBooks": "Количество Книг",
+ "LabelNotificationTitleTemplate": "Шаблон заголовка",
+ "LabelNotStarted": "Не запущено",
+ "LabelNumberOfBooks": "Количество книг",
"LabelNumberOfEpisodes": "# Эпизодов",
"LabelOpenRSSFeed": "Открыть RSS-канал",
"LabelOverwrite": "Перезаписать",
"LabelPassword": "Пароль",
"LabelPath": "Путь",
- "LabelPermissionsAccessAllLibraries": "Есть Доступ ко всем Библиотекам",
- "LabelPermissionsAccessAllTags": "Есть Доступ ко всем Тегам",
- "LabelPermissionsAccessExplicitContent": "Есть Доступ к Явному Содержимому",
- "LabelPermissionsDelete": "Может Удалять",
- "LabelPermissionsDownload": "Может Скачивать",
- "LabelPermissionsUpdate": "Может Обновлять",
- "LabelPermissionsUpload": "Может Закачивать",
- "LabelPhotoPathURL": "Путь к Фото/URL",
+ "LabelPermissionsAccessAllLibraries": "Есть доступ ко всем библиотекам",
+ "LabelPermissionsAccessAllTags": "Есть доступ ко всем тегам",
+ "LabelPermissionsAccessExplicitContent": "Есть доступ к явному содержимому",
+ "LabelPermissionsDelete": "Может удалять",
+ "LabelPermissionsDownload": "Может скачивать",
+ "LabelPermissionsUpdate": "Может обновлять",
+ "LabelPermissionsUpload": "Может закачивать",
+ "LabelPhotoPathURL": "Путь к фото/URL",
"LabelPlaylists": "Плейлисты",
- "LabelPlayMethod": "Метод Воспроизведения",
+ "LabelPlayMethod": "Метод воспроизведения",
"LabelPodcast": "Подкаст",
"LabelPodcasts": "Подкасты",
- "LabelPrefixesToIgnore": "Игнорируемые Префиксы (без учета регистра)",
+ "LabelPodcastType": "Тип подкаста",
+ "LabelPrefixesToIgnore": "Игнорируемые префиксы (без учета регистра)",
+ "LabelPreventIndexing": "Запретить индексацию фида каталогами подкастов iTunes и Google",
"LabelProgress": "Прогресс",
"LabelProvider": "Провайдер",
- "LabelPubDate": "Дата Публикации",
+ "LabelPubDate": "Дата публикации",
"LabelPublisher": "Издатель",
- "LabelPublishYear": "Год Публикации",
- "LabelRecentlyAdded": "Недавно Добавленные",
- "LabelRecentSeries": "Последние Серии",
+ "LabelPublishYear": "Год публикации",
+ "LabelRecentlyAdded": "Недавно добавленные",
+ "LabelRecentSeries": "Последние серии",
"LabelRecommended": "Рекомендованное",
"LabelRegion": "Регион",
- "LabelReleaseDate": "Дата Выхода",
+ "LabelReleaseDate": "Дата выхода",
"LabelRemoveCover": "Удалить обложку",
+ "LabelRSSFeedCustomOwnerEmail": "Пользовательский Email владельца",
+ "LabelRSSFeedCustomOwnerName": "Пользовательское Имя владельца",
"LabelRSSFeedOpen": "Открыть RSS-канал",
+ "LabelRSSFeedPreventIndexing": "Запретить индексирование",
"LabelRSSFeedSlug": "Встроить RSS-канал",
"LabelRSSFeedURL": "URL RSS-канала",
- "LabelSearchTerm": "Поисковый Запрос",
- "LabelSearchTitle": "Поиск по Названию",
- "LabelSearchTitleOrASIN": "Поиск по Названию или ASIN",
+ "LabelSearchTerm": "Поисковый запрос",
+ "LabelSearchTitle": "Поиск по названию",
+ "LabelSearchTitleOrASIN": "Поиск по названию или ASIN",
"LabelSeason": "Сезон",
"LabelSequence": "Последовательность",
"LabelSeries": "Серия",
- "LabelSeriesName": "Имя Серии",
- "LabelSeriesProgress": "Прогресс Серии",
+ "LabelSeriesName": "Имя серии",
+ "LabelSeriesProgress": "Прогресс серии",
"LabelSettingsBookshelfViewHelp": "Конструкция с деревянными полками",
"LabelSettingsChromecastSupport": "Поддержка Chromecast",
- "LabelSettingsDateFormat": "Формат Даты",
- "LabelSettingsDisableWatcher": "Отключить Отслеживание",
+ "LabelSettingsDateFormat": "Формат даты",
+ "LabelSettingsDisableWatcher": "Отключить отслеживание",
"LabelSettingsDisableWatcherForLibrary": "Отключить отслеживание для библиотеки",
"LabelSettingsDisableWatcherHelp": "Отключает автоматическое добавление/обновление элементов, когда обнаружено изменение файлов. *Требуется перезапуск сервера",
"LabelSettingsEnableEReader": "Включить e-reader для всех пользователей",
@@ -335,7 +350,7 @@
"LabelSettingsExperimentalFeaturesHelp": "Функционал в разработке на который Вы могли бы дать отзыв или помочь в тестировании. Нажмите для открытия обсуждения на github.",
"LabelSettingsFindCovers": "Найти обложки",
"LabelSettingsFindCoversHelp": "Если у Ваших аудиокниг нет встроенной обложки или файла обложки в папке книги, то сканер попробует найти обложку.
Примечание: Это увеличит время сканирования",
- "LabelSettingsHomePageBookshelfView": "Вид книжной полки на Домашней Странице",
+ "LabelSettingsHomePageBookshelfView": "Вид книжной полки на Домашней странице",
"LabelSettingsLibraryBookshelfView": "Вид книжной полки в Библиотеке",
"LabelSettingsOverdriveMediaMarkers": "Overdrive Media Markers для глав",
"LabelSettingsOverdriveMediaMarkersHelp": "MP3 файлы из Overdrive поставляется с таймингами глав, встроенными в виде пользовательских метаданных. При включении этого параметра эти теги будут автоматически использоваться для таймингов глав",
@@ -357,46 +372,48 @@
"LabelSettingsStoreCoversWithItemHelp": "По умолчанию обложки сохраняются в папке /metadata/items, при включении этой настройки обложка будет храниться в папке элемента. Будет сохраняться только один файл с именем \"cover\"",
"LabelSettingsStoreMetadataWithItem": "Хранить метаинформацию с элементом",
"LabelSettingsStoreMetadataWithItemHelp": "По умолчанию метаинформация сохраняется в папке /metadata/items, при включении этой настройки метаинформация будет храниться в папке элемента. Используется расширение файла .abs",
- "LabelShowAll": "Показать Все",
+ "LabelSettingsTimeFormat": "Формат времени",
+ "LabelShowAll": "Показать все",
"LabelSize": "Размер",
"LabelSleepTimer": "Таймер сна",
"LabelStart": "Начало",
"LabelStarted": "Начат",
"LabelStartedAt": "Начато В",
- "LabelStartTime": "Время Начала",
- "LabelStatsAudioTracks": "Аудио Треки",
+ "LabelStartTime": "Время начала",
+ "LabelStatsAudioTracks": "Аудио треки",
"LabelStatsAuthors": "Авторы",
"LabelStatsBestDay": "Лучший День",
- "LabelStatsDailyAverage": "В среднем в День",
+ "LabelStatsDailyAverage": "В среднем в день",
"LabelStatsDays": "Дней",
- "LabelStatsDaysListened": "Дней Прослушано",
+ "LabelStatsDaysListened": "Дней прослушано",
"LabelStatsHours": "Часов",
- "LabelStatsInARow": "в строке",
- "LabelStatsItemsFinished": "Элементов Завершено",
- "LabelStatsItemsInLibrary": "Элементов в Библиотеке",
+ "LabelStatsInARow": "беспрерывно",
+ "LabelStatsItemsFinished": "Элементов завершено",
+ "LabelStatsItemsInLibrary": "Элементов в библиотеке",
"LabelStatsMinutes": "минут",
- "LabelStatsMinutesListening": "Минут Прослушано",
- "LabelStatsOverallDays": "Всего Дней",
- "LabelStatsOverallHours": "Всего Часов",
- "LabelStatsWeekListening": "Недель Прослушано",
+ "LabelStatsMinutesListening": "Минут прослушано",
+ "LabelStatsOverallDays": "Всего дней",
+ "LabelStatsOverallHours": "Всего сасов",
+ "LabelStatsWeekListening": "Недель прослушано",
"LabelSubtitle": "Подзаголовок",
"LabelSupportedFileTypes": "Поддерживаемые типы файлов",
"LabelTag": "Тег",
"LabelTags": "Теги",
- "LabelTagsAccessibleToUser": "Теги Доступные для Пользователя",
- "LabelTimeListened": "Время Прослушивания",
- "LabelTimeListenedToday": "Время Прослушивания Сегодня",
+ "LabelTagsAccessibleToUser": "Теги доступные для пользователя",
+ "LabelTasks": "Запущенные задачи",
+ "LabelTimeListened": "Время прослушивания",
+ "LabelTimeListenedToday": "Время прослушивания сегодня",
"LabelTimeRemaining": "{0} осталось",
"LabelTimeToShift": "Время смещения в сек.",
"LabelTitle": "Название",
- "LabelToolsEmbedMetadata": "Встроить Метаданные",
+ "LabelToolsEmbedMetadata": "Встроить метаданные",
"LabelToolsEmbedMetadataDescription": "Встроить метаданные в аудио файлы, включая обложку и главы.",
- "LabelToolsMakeM4b": "Создать M4B Файл Аудиокниги",
+ "LabelToolsMakeM4b": "Создать M4B файл аудиокниги",
"LabelToolsMakeM4bDescription": "Создает .M4B файл аудиокниги с встроенными метаданными, обложкой и главами.",
"LabelToolsSplitM4b": "Разделить M4B на MP3 файлы",
"LabelToolsSplitM4bDescription": "Создает MP3 файла из M4B, разделяет на главы с встроенными метаданными, обложкой и главами.",
- "LabelTotalDuration": "Общая Длина",
- "LabelTotalTimeListened": "Всего Прослушано",
+ "LabelTotalDuration": "Общая длина",
+ "LabelTotalTimeListened": "Всего прослушано",
"LabelTrackFromFilename": "Трек из Имени файла",
"LabelTrackFromMetadata": "Трек из Метаданных",
"LabelTracks": "Треков",
@@ -404,10 +421,10 @@
"LabelTracksSingleTrack": "Один трек",
"LabelType": "Тип",
"LabelUnknown": "Неизвестно",
- "LabelUpdateCover": "Обновить Обложку",
+ "LabelUpdateCover": "Обновить обложку",
"LabelUpdateCoverHelp": "Позволяет перезаписывать существующие обложки для выбранных книг если будут найдены",
"LabelUpdatedAt": "Обновлено в",
- "LabelUpdateDetails": "Обновить Подробности",
+ "LabelUpdateDetails": "Обновить подробности",
"LabelUpdateDetailsHelp": "Позволяет перезаписывать текущие подробности для выбранных книг если будут найдены",
"LabelUploaderDragAndDrop": "Перетащите файлы или каталоги",
"LabelUploaderDropFiles": "Перетащите файлы",
@@ -422,10 +439,10 @@
"LabelViewQueue": "Очередь воспроизведения",
"LabelVolume": "Громкость",
"LabelWeekdaysToRun": "Дни недели для запуска",
- "LabelYourAudiobookDuration": "Продолжительность Вашей Книги",
- "LabelYourBookmarks": "Ваши Закладки",
- "LabelYourPlaylists": "Ваши Плейлисты",
- "LabelYourProgress": "Ваш Прогресс",
+ "LabelYourAudiobookDuration": "Продолжительность Вашей книги",
+ "LabelYourBookmarks": "Ваши закладки",
+ "LabelYourPlaylists": "Ваши плейлисты",
+ "LabelYourProgress": "Ваш прогресс",
"MessageAddToPlayerQueue": "Добавить в очередь проигрывателя",
"MessageAppriseDescription": "Для использования этой функции необходимо иметь запущенный экземпляр
Apprise API или api которое обрабатывает те же самые запросы.
URL-адрес API Apprise должен быть полным URL-адресом для отправки уведомления, т.е., если API запущено по адресу
http://192.168.1.1:8337
тогда нужно указать
http://192.168.1.1:8337/notify
.",
"MessageBackupsDescription": "Бэкап включает пользователей, прогресс пользователей, данные элементов библиотеки, настройки сервера и изображения хранящиеся в
/metadata/items
и
/metadata/authors
. Бэкапы
НЕ сохраняют файлы из папок библиотек.",
@@ -465,8 +482,8 @@
"MessageForceReScanDescription": "будет сканировать все файлы снова, как свежее сканирование. Теги ID3 аудиофайлов, OPF-файлы и текстовые файлы будут сканироваться как новые.",
"MessageImportantNotice": "Важное замечание!",
"MessageInsertChapterBelow": "Вставить главу ниже",
- "MessageItemsSelected": "{0} Элементов Выделено",
- "MessageItemsUpdated": "{0} Элементов Обновлено",
+ "MessageItemsSelected": "{0} Элементов выделено",
+ "MessageItemsUpdated": "{0} Элементов обновлено",
"MessageJoinUsOn": "Присоединяйтесь к нам в",
"MessageListeningSessionsInTheLastYear": "{0} сеансов прослушивания в прошлом году",
"MessageLoading": "Загрузка...",
@@ -474,33 +491,36 @@
"MessageM4BFailed": "M4B Ошибка!",
"MessageM4BFinished": "M4B Завершено!",
"MessageMapChapterTitles": "Сопоставление названий глав с существующими главами аудиокниги без корректировки временных меток",
- "MessageMarkAsFinished": "Отметить, как Завершенную",
- "MessageMarkAsNotFinished": "Отметить, как Не Завершенную",
+ "MessageMarkAsFinished": "Отметить, как завершенную",
+ "MessageMarkAsNotFinished": "Отметить, как не завершенную",
"MessageMatchBooksDescription": "попытается сопоставить книги в библиотеке с книгой из выбранного поставщика поиска и заполнить пустые детали и обложку. Не перезаписывает сведения.",
"MessageNoAudioTracks": "Нет аудио треков",
- "MessageNoAuthors": "Нет Авторов",
- "MessageNoBackups": "Нет Бэкапов",
- "MessageNoBookmarks": "Нет Закладок",
- "MessageNoChapters": "Нет Глав",
- "MessageNoCollections": "Нет Коллекций",
+ "MessageNoAuthors": "Нет авторов",
+ "MessageNoBackups": "Нет бэкапов",
+ "MessageNoBookmarks": "Нет закладок",
+ "MessageNoChapters": "Нет глав",
+ "MessageNoCollections": "Нет коллекций",
"MessageNoCoversFound": "Обложек не найдено",
"MessageNoDescription": "Нет описания",
+ "MessageNoDownloadsInProgress": "В настоящее время загрузка не выполняется",
+ "MessageNoDownloadsQueued": "Нет загрузок в очереди",
"MessageNoEpisodeMatchesFound": "Совпадения эпизодов не найдены",
- "MessageNoEpisodes": "Нет Эпизодов",
+ "MessageNoEpisodes": "Нет эпизодов",
"MessageNoFoldersAvailable": "Нет доступных папок",
- "MessageNoGenres": "Нет Жанров",
- "MessageNoIssues": "Нет Проблем",
- "MessageNoItems": "Нет Элементов",
+ "MessageNoGenres": "Нет жанров",
+ "MessageNoIssues": "Нет проблем",
+ "MessageNoItems": "Нет элементов",
"MessageNoItemsFound": "Элементы не найдены",
- "MessageNoListeningSessions": "Нет Сеансов Прослушивания",
- "MessageNoLogs": "Нет Логов",
- "MessageNoMediaProgress": "Нет Прогресса Медиа",
- "MessageNoNotifications": "Нет Уведомлений",
+ "MessageNoListeningSessions": "Нет сеансов прослушивания",
+ "MessageNoLogs": "Нет логов",
+ "MessageNoMediaProgress": "Нет прогресса медиа",
+ "MessageNoNotifications": "Нет уведомлений",
"MessageNoPodcastsFound": "Подкасты не найдены",
- "MessageNoResults": "Нет Результатов",
+ "MessageNoResults": "Нет результатов",
"MessageNoSearchResultsFor": "Нет результатов поиска для \"{0}\"",
- "MessageNoSeries": "Нет Серий",
- "MessageNoTags": "Нет Тегов",
+ "MessageNoSeries": "Нет серий",
+ "MessageNoTags": "Нет тегов",
+ "MessageNoTasksRunning": "Нет выполняемых задач",
"MessageNotYetImplemented": "Пока не реализовано",
"MessageNoUpdateNecessary": "Обновление не требуется",
"MessageNoUpdatesWereNecessary": "Обновления не требовались",
@@ -526,7 +546,7 @@
"MessageStartPlaybackAtTime": "Начать воспроизведение для \"{0}\" с {1}?",
"MessageThinking": "Думаю...",
"MessageUploaderItemFailed": "Не удалось загрузить",
- "MessageUploaderItemSuccess": "Успешно Загружено!",
+ "MessageUploaderItemSuccess": "Успешно загружено!",
"MessageUploading": "Загрузка...",
"MessageValidCronExpression": "Верное cron выражение",
"MessageWatcherIsDisabledGlobally": "Наблюдатель отключен глобально в настройках сервера",
@@ -616,4 +636,4 @@
"ToastSocketFailedToConnect": "Не удалось подключить сокет",
"ToastUserDeleteFailed": "Не удалось удалить пользователя",
"ToastUserDeleteSuccess": "Пользователь удален"
-}
+}
\ No newline at end of file
diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json
index 7c5e49e8..9933d13f 100644
--- a/client/strings/zh-cn.json
+++ b/client/strings/zh-cn.json
@@ -20,6 +20,7 @@
"ButtonCreate": "创建",
"ButtonCreateBackup": "创建备份",
"ButtonDelete": "删除",
+ "ButtonDownloadQueue": "下载队列",
"ButtonEdit": "编辑",
"ButtonEditChapters": "编辑章节",
"ButtonEditPodcast": "编辑播客",
@@ -92,13 +93,15 @@
"HeaderCollection": "收藏",
"HeaderCollectionItems": "收藏项目",
"HeaderCover": "封面",
+ "HeaderCurrentDownloads": "当前下载",
"HeaderDetails": "详情",
+ "HeaderDownloadQueue": "下载队列",
"HeaderEpisodes": "剧集",
"HeaderFiles": "文件",
"HeaderFindChapters": "查找章节",
"HeaderIgnoredFiles": "忽略的文件",
"HeaderItemFiles": "项目文件",
- "HeaderItemMetadataUtils": "项目元数据管理程序",
+ "HeaderItemMetadataUtils": "项目元数据管理",
"HeaderLastListeningSession": "最后一次收听会话",
"HeaderLatestEpisodes": "最新剧集",
"HeaderLibraries": "媒体库",
@@ -126,6 +129,7 @@
"HeaderPreviewCover": "预览封面",
"HeaderRemoveEpisode": "移除剧集",
"HeaderRemoveEpisodes": "移除 {0} 剧集",
+ "HeaderRSSFeedGeneral": "RSS 详细信息",
"HeaderRSSFeedIsOpen": "RSS 源已打开",
"HeaderSavedMediaProgress": "保存媒体进度",
"HeaderSchedule": "计划任务",
@@ -138,6 +142,7 @@
"HeaderSettingsGeneral": "通用",
"HeaderSettingsScanner": "扫描",
"HeaderSleepTimer": "睡眠计时",
+ "HeaderStatsLargestItems": "最大的项目",
"HeaderStatsLongestItems": "项目时长(小时)",
"HeaderStatsMinutesListeningChart": "收听分钟数(最近7天)",
"HeaderStatsRecentSessions": "历史会话",
@@ -162,6 +167,7 @@
"LabelAddToPlaylistBatch": "添加 {0} 个项目到播放列表",
"LabelAll": "全部",
"LabelAllUsers": "所有用户",
+ "LabelAlreadyInYourLibrary": "已存在你的库中",
"LabelAppend": "附加",
"LabelAuthor": "作者",
"LabelAuthorFirstLast": "作者 (姓 名)",
@@ -192,6 +198,7 @@
"LabelCronExpression": "计划任务表达式",
"LabelCurrent": "当前",
"LabelCurrently": "当前:",
+ "LabelCustomCronExpression": "自定义计划任务表达式:",
"LabelDatetime": "日期时间",
"LabelDescription": "描述",
"LabelDeselectAll": "全部取消选择",
@@ -209,6 +216,7 @@
"LabelEpisode": "剧集",
"LabelEpisodeTitle": "剧集标题",
"LabelEpisodeType": "剧集类型",
+ "LabelExample": "示例",
"LabelExplicit": "信息准确",
"LabelFeedURL": "源 URL",
"LabelFile": "文件",
@@ -270,6 +278,8 @@
"LabelNewestAuthors": "最新作者",
"LabelNewestEpisodes": "最新剧集",
"LabelNewPassword": "新密码",
+ "LabelNextBackupDate": "下次备份日期",
+ "LabelNextScheduledRun": "下次任务运行",
"LabelNotes": "注释",
"LabelNotFinished": "未听完",
"LabelNotificationAppriseURL": "通知 URL(s)",
@@ -300,7 +310,9 @@
"LabelPlayMethod": "播放方法",
"LabelPodcast": "播客",
"LabelPodcasts": "播客",
+ "LabelPodcastType": "播客类型",
"LabelPrefixesToIgnore": "忽略的前缀 (不区分大小写)",
+ "LabelPreventIndexing": "防止 iTunes 和 Google 播客目录对你的源进行索引",
"LabelProgress": "进度",
"LabelProvider": "供应商",
"LabelPubDate": "出版日期",
@@ -312,7 +324,10 @@
"LabelRegion": "区域",
"LabelReleaseDate": "发布日期",
"LabelRemoveCover": "移除封面",
+ "LabelRSSFeedCustomOwnerEmail": "自定义所有者电子邮件",
+ "LabelRSSFeedCustomOwnerName": "自定义所有者名称",
"LabelRSSFeedOpen": "打开 RSS 源",
+ "LabelRSSFeedPreventIndexing": "防止索引",
"LabelRSSFeedSlug": "RSS 源段",
"LabelRSSFeedURL": "RSS 源 URL",
"LabelSearchTerm": "搜索项",
@@ -357,6 +372,7 @@
"LabelSettingsStoreCoversWithItemHelp": "默认情况下封面存储在/metadata/items文件夹中, 启用此设置将存储封面在你媒体项目文件夹中. 只保留一个名为 \"cover\" 的文件",
"LabelSettingsStoreMetadataWithItem": "存储项目元数据",
"LabelSettingsStoreMetadataWithItemHelp": "默认情况下元数据文件存储在/metadata/items文件夹中, 启用此设置将存储元数据在你媒体项目文件夹中. 使 .abs 文件护展名",
+ "LabelSettingsTimeFormat": "时间格式",
"LabelShowAll": "全部显示",
"LabelSize": "文件大小",
"LabelSleepTimer": "睡眠定时",
@@ -384,6 +400,7 @@
"LabelTag": "标签",
"LabelTags": "标签",
"LabelTagsAccessibleToUser": "用户可访问的标签",
+ "LabelTasks": "正在运行的任务",
"LabelTimeListened": "收听时间",
"LabelTimeListenedToday": "今日收听的时间",
"LabelTimeRemaining": "剩余 {0}",
@@ -485,6 +502,8 @@
"MessageNoCollections": "没有收藏",
"MessageNoCoversFound": "没有找到封面",
"MessageNoDescription": "没有描述",
+ "MessageNoDownloadsInProgress": "当前没有正在进行的下载",
+ "MessageNoDownloadsQueued": "下载队列无任务",
"MessageNoEpisodeMatchesFound": "没有找到任何剧集匹配项",
"MessageNoEpisodes": "没有剧集",
"MessageNoFoldersAvailable": "没有可用文件夹",
@@ -501,6 +520,7 @@
"MessageNoSearchResultsFor": "没有搜索到结果 \"{0}\"",
"MessageNoSeries": "无系列",
"MessageNoTags": "无标签",
+ "MessageNoTasksRunning": "没有正在运行的任务",
"MessageNotYetImplemented": "尚未实施",
"MessageNoUpdateNecessary": "无需更新",
"MessageNoUpdatesWereNecessary": "无需更新",
@@ -616,4 +636,4 @@
"ToastSocketFailedToConnect": "网络连接失败",
"ToastUserDeleteFailed": "删除用户失败",
"ToastUserDeleteSuccess": "用户已删除"
-}
+}
\ No newline at end of file
diff --git a/images/DemoLibrary.png b/images/DemoLibrary.png
new file mode 100644
index 00000000..16c55754
Binary files /dev/null and b/images/DemoLibrary.png differ
diff --git a/images/LibraryStream.png b/images/LibraryStream.png
deleted file mode 100644
index eb81a2cb..00000000
Binary files a/images/LibraryStream.png and /dev/null differ
diff --git a/package-lock.json b/package-lock.json
index 8edcbc01..366d4668 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "audiobookshelf",
- "version": "2.2.15",
+ "version": "2.2.16",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "audiobookshelf",
- "version": "2.2.15",
+ "version": "2.2.16",
"license": "GPL-3.0",
"dependencies": {
"axios": "^0.27.2",
diff --git a/package.json b/package.json
index a8b1c69b..0ca3d04d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "audiobookshelf",
- "version": "2.2.15",
+ "version": "2.2.16",
"description": "Self-hosted audiobook and podcast server",
"main": "index.js",
"scripts": {
diff --git a/readme.md b/readme.md
index 13f81ccc..ef4ecf5c 100644
--- a/readme.md
+++ b/readme.md
@@ -49,7 +49,7 @@ Check out the [API documentation](https://api.audiobookshelf.org/)
-

+
diff --git a/server/Server.js b/server/Server.js
index a5a0b8b5..4a900a68 100644
--- a/server/Server.js
+++ b/server/Server.js
@@ -72,7 +72,7 @@ class Server {
this.abMergeManager = new AbMergeManager(this.db, this.taskManager)
this.playbackSessionManager = new PlaybackSessionManager(this.db)
this.coverManager = new CoverManager(this.db, this.cacheManager)
- this.podcastManager = new PodcastManager(this.db, this.watcher, this.notificationManager)
+ this.podcastManager = new PodcastManager(this.db, this.watcher, this.notificationManager, this.taskManager)
this.audioMetadataManager = new AudioMetadataMangaer(this.db, this.taskManager)
this.rssFeedManager = new RssFeedManager(this.db)
this.eBookManager = new EBookManager(this.db)
diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js
index d09d52d4..bbc70f31 100644
--- a/server/controllers/LibraryController.js
+++ b/server/controllers/LibraryController.js
@@ -82,6 +82,11 @@ class LibraryController {
return res.json(req.library)
}
+ async getEpisodeDownloadQueue(req, res) {
+ const libraryDownloadQueueDetails = this.podcastManager.getDownloadQueueDetails(req.library.id)
+ return res.json(libraryDownloadQueueDetails)
+ }
+
async update(req, res) {
const library = req.library
@@ -229,6 +234,16 @@ class LibraryController {
if (payload.sortBy === 'book.volumeNumber') payload.sortBy = null // TODO: Remove temp fix after mobile release 0.9.60
if (filterSeries && !payload.sortBy) {
sortArray.push({ asc: (li) => li.media.metadata.getSeries(filterSeries).sequence })
+ // If no series sequence then fallback to sorting by title (or collapsed series name for sub-series)
+ sortArray.push({
+ asc: (li) => {
+ if (this.db.serverSettings.sortingIgnorePrefix) {
+ return li.collapsedSeries?.nameIgnorePrefix || li.media.metadata.titleIgnorePrefix
+ } else {
+ return li.collapsedSeries?.name || li.media.metadata.title
+ }
+ }
+ })
}
if (payload.sortBy) {
@@ -637,6 +652,7 @@ class LibraryController {
var authorsWithCount = libraryHelpers.getAuthorsWithCount(libraryItems)
var genresWithCount = libraryHelpers.getGenresWithCount(libraryItems)
var durationStats = libraryHelpers.getItemDurationStats(libraryItems)
+ var sizeStats = libraryHelpers.getItemSizeStats(libraryItems)
var stats = {
totalItems: libraryItems.length,
totalAuthors: Object.keys(authorsWithCount).length,
@@ -645,6 +661,7 @@ class LibraryController {
longestItems: durationStats.longestItems,
numAudioTracks: durationStats.numAudioTracks,
totalSize: libraryHelpers.getLibraryItemsTotalSize(libraryItems),
+ largestItems: sizeStats.largestItems,
authorsWithCount,
genresWithCount
}
@@ -755,4 +772,4 @@ class LibraryController {
next()
}
}
-module.exports = new LibraryController()
\ No newline at end of file
+module.exports = new LibraryController()
diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js
index 553095d6..05aee92d 100644
--- a/server/controllers/LibraryItemController.js
+++ b/server/controllers/LibraryItemController.js
@@ -36,8 +36,11 @@ class LibraryItemController {
}).filter(au => au)
}
} else if (includeEntities.includes('downloads')) {
- var downloadsInQueue = this.podcastManager.getEpisodeDownloadsInQueue(req.libraryItem.id)
- item.episodesDownloading = downloadsInQueue.map(d => d.toJSONForClient())
+ const downloadsInQueue = this.podcastManager.getEpisodeDownloadsInQueue(req.libraryItem.id)
+ item.episodeDownloadsQueued = downloadsInQueue.map(d => d.toJSONForClient())
+ if (this.podcastManager.currentDownload?.libraryItemId === req.libraryItem.id) {
+ item.episodesDownloading = [this.podcastManager.currentDownload.toJSONForClient()]
+ }
}
return res.json(item)
diff --git a/server/controllers/PodcastController.js b/server/controllers/PodcastController.js
index 23cec882..f19bba9f 100644
--- a/server/controllers/PodcastController.js
+++ b/server/controllers/PodcastController.js
@@ -225,6 +225,20 @@ class PodcastController {
res.json(libraryItem.toJSONExpanded())
}
+ // GET: api/podcasts/:id/episode/:episodeId
+ async getEpisode(req, res) {
+ const episodeId = req.params.episodeId
+ const libraryItem = req.libraryItem
+
+ const episode = libraryItem.media.episodes.find(ep => ep.id === episodeId)
+ if (!episode) {
+ Logger.error(`[PodcastController] getEpisode episode ${episodeId} not found for item ${libraryItem.id}`)
+ return res.sendStatus(404)
+ }
+
+ res.json(episode)
+ }
+
// DELETE: api/podcasts/:id/episode/:episodeId
async removeEpisode(req, res) {
var episodeId = req.params.episodeId
@@ -283,4 +297,4 @@ class PodcastController {
next()
}
}
-module.exports = new PodcastController()
\ No newline at end of file
+module.exports = new PodcastController()
diff --git a/server/controllers/RSSFeedController.js b/server/controllers/RSSFeedController.js
index 86c37d72..b9a08e11 100644
--- a/server/controllers/RSSFeedController.js
+++ b/server/controllers/RSSFeedController.js
@@ -134,4 +134,4 @@ class RSSFeedController {
next()
}
}
-module.exports = new RSSFeedController()
\ No newline at end of file
+module.exports = new RSSFeedController()
diff --git a/server/managers/PodcastManager.js b/server/managers/PodcastManager.js
index 74751d45..593d9754 100644
--- a/server/managers/PodcastManager.js
+++ b/server/managers/PodcastManager.js
@@ -14,12 +14,14 @@ const LibraryFile = require('../objects/files/LibraryFile')
const PodcastEpisodeDownload = require('../objects/PodcastEpisodeDownload')
const PodcastEpisode = require('../objects/entities/PodcastEpisode')
const AudioFile = require('../objects/files/AudioFile')
+const Task = require("../objects/Task")
class PodcastManager {
- constructor(db, watcher, notificationManager) {
+ constructor(db, watcher, notificationManager, taskManager) {
this.db = db
this.watcher = watcher
this.notificationManager = notificationManager
+ this.taskManager = taskManager
this.downloadQueue = []
this.currentDownload = null
@@ -56,18 +58,28 @@ class PodcastManager {
newPe.setData(ep, index++)
newPe.libraryItemId = libraryItem.id
var newPeDl = new PodcastEpisodeDownload()
- newPeDl.setData(newPe, libraryItem, isAutoDownload)
+ newPeDl.setData(newPe, libraryItem, isAutoDownload, libraryItem.libraryId)
this.startPodcastEpisodeDownload(newPeDl)
})
}
async startPodcastEpisodeDownload(podcastEpisodeDownload) {
+ SocketAuthority.emitter('episode_download_queue_updated', this.getDownloadQueueDetails())
if (this.currentDownload) {
this.downloadQueue.push(podcastEpisodeDownload)
SocketAuthority.emitter('episode_download_queued', podcastEpisodeDownload.toJSONForClient())
return
}
+ const task = new Task()
+ const taskDescription = `Downloading episode "${podcastEpisodeDownload.podcastEpisode.title}".`
+ const taskData = {
+ libraryId: podcastEpisodeDownload.libraryId,
+ libraryItemId: podcastEpisodeDownload.libraryItemId,
+ }
+ task.setData('download-podcast-episode', 'Downloading Episode', taskDescription, taskData)
+ this.taskManager.addTask(task)
+
SocketAuthority.emitter('episode_download_started', podcastEpisodeDownload.toJSONForClient())
this.currentDownload = podcastEpisodeDownload
@@ -81,7 +93,7 @@ class PodcastManager {
await filePerms.setDefault(this.currentDownload.libraryItem.path)
}
- var success = await downloadFile(this.currentDownload.url, this.currentDownload.targetPath).then(() => true).catch((error) => {
+ let success = await downloadFile(this.currentDownload.url, this.currentDownload.targetPath).then(() => true).catch((error) => {
Logger.error(`[PodcastManager] Podcast Episode download failed`, error)
return false
})
@@ -90,15 +102,21 @@ class PodcastManager {
if (!success) {
await fs.remove(this.currentDownload.targetPath)
this.currentDownload.setFinished(false)
+ task.setFailed('Failed to download episode')
} else {
Logger.info(`[PodcastManager] Successfully downloaded podcast episode "${this.currentDownload.podcastEpisode.title}"`)
this.currentDownload.setFinished(true)
+ task.setFinished()
}
} else {
+ task.setFailed('Failed to download episode')
this.currentDownload.setFinished(false)
}
+ this.taskManager.taskFinished(task)
+
SocketAuthority.emitter('episode_download_finished', this.currentDownload.toJSONForClient())
+ SocketAuthority.emitter('episode_download_queue_updated', this.getDownloadQueueDetails())
this.watcher.removeIgnoreDir(this.currentDownload.libraryItem.path)
this.currentDownload = null
@@ -329,5 +347,15 @@ class PodcastManager {
feeds: rssFeedData
}
}
+
+ getDownloadQueueDetails(libraryId = null) {
+ let _currentDownload = this.currentDownload
+ if (libraryId && _currentDownload?.libraryId !== libraryId) _currentDownload = null
+
+ return {
+ currentDownload: _currentDownload?.toJSONForClient(),
+ queue: this.downloadQueue.filter(item => !libraryId || item.libraryId === libraryId).map(item => item.toJSONForClient())
+ }
+ }
}
-module.exports = PodcastManager
\ No newline at end of file
+module.exports = PodcastManager
diff --git a/server/managers/RssFeedManager.js b/server/managers/RssFeedManager.js
index 1d842559..9325a7a2 100644
--- a/server/managers/RssFeedManager.js
+++ b/server/managers/RssFeedManager.js
@@ -188,9 +188,12 @@ class RssFeedManager {
async openFeedForItem(user, libraryItem, options) {
const serverAddress = options.serverAddress
const slug = options.slug
+ const preventIndexing = options.metadataDetails?.preventIndexing ?? true
+ const ownerName = options.metadataDetails?.ownerName
+ const ownerEmail = options.metadataDetails?.ownerEmail
const feed = new Feed()
- feed.setFromItem(user.id, slug, libraryItem, serverAddress)
+ feed.setFromItem(user.id, slug, libraryItem, serverAddress, preventIndexing, ownerName, ownerEmail)
this.feeds[feed.id] = feed
Logger.debug(`[RssFeedManager] Opened RSS feed "${feed.feedUrl}"`)
@@ -202,9 +205,12 @@ class RssFeedManager {
async openFeedForCollection(user, collectionExpanded, options) {
const serverAddress = options.serverAddress
const slug = options.slug
+ const preventIndexing = options.metadataDetails?.preventIndexing ?? true
+ const ownerName = options.metadataDetails?.ownerName
+ const ownerEmail = options.metadataDetails?.ownerEmail
const feed = new Feed()
- feed.setFromCollection(user.id, slug, collectionExpanded, serverAddress)
+ feed.setFromCollection(user.id, slug, collectionExpanded, serverAddress, preventIndexing, ownerName, ownerEmail)
this.feeds[feed.id] = feed
Logger.debug(`[RssFeedManager] Opened RSS feed "${feed.feedUrl}"`)
@@ -216,9 +222,12 @@ class RssFeedManager {
async openFeedForSeries(user, seriesExpanded, options) {
const serverAddress = options.serverAddress
const slug = options.slug
+ const preventIndexing = options.metadataDetails?.preventIndexing ?? true
+ const ownerName = options.metadataDetails?.ownerName
+ const ownerEmail = options.metadataDetails?.ownerEmail
const feed = new Feed()
- feed.setFromSeries(user.id, slug, seriesExpanded, serverAddress)
+ feed.setFromSeries(user.id, slug, seriesExpanded, serverAddress, preventIndexing, ownerName, ownerEmail)
this.feeds[feed.id] = feed
Logger.debug(`[RssFeedManager] Opened RSS feed "${feed.feedUrl}"`)
@@ -246,4 +255,4 @@ class RssFeedManager {
return this.handleCloseFeed(feed)
}
}
-module.exports = RssFeedManager
\ No newline at end of file
+module.exports = RssFeedManager
diff --git a/server/objects/Feed.js b/server/objects/Feed.js
index cc5e804f..10d6d282 100644
--- a/server/objects/Feed.js
+++ b/server/objects/Feed.js
@@ -70,17 +70,19 @@ class Feed {
id: this.id,
entityType: this.entityType,
entityId: this.entityId,
- feedUrl: this.feedUrl
+ feedUrl: this.feedUrl,
+ meta: this.meta.toJSONMinified(),
}
}
getEpisodePath(id) {
var episode = this.episodes.find(ep => ep.id === id)
+ console.log('getEpisodePath=', id, episode)
if (!episode) return null
return episode.fullPath
}
- setFromItem(userId, slug, libraryItem, serverAddress) {
+ setFromItem(userId, slug, libraryItem, serverAddress, preventIndexing = true, ownerName = null, ownerEmail = null) {
const media = libraryItem.media
const mediaMetadata = media.metadata
const isPodcast = libraryItem.mediaType === 'podcast'
@@ -106,6 +108,11 @@ class Feed {
this.meta.feedUrl = feedUrl
this.meta.link = `${serverAddress}/item/${libraryItem.id}`
this.meta.explicit = !!mediaMetadata.explicit
+ this.meta.type = mediaMetadata.type
+ this.meta.language = mediaMetadata.language
+ this.meta.preventIndexing = preventIndexing
+ this.meta.ownerName = ownerName
+ this.meta.ownerEmail = ownerEmail
this.episodes = []
if (isPodcast) { // PODCAST EPISODES
@@ -142,6 +149,8 @@ class Feed {
this.meta.author = author
this.meta.imageUrl = media.coverPath ? `${this.serverAddress}/feed/${this.slug}/cover` : `${this.serverAddress}/Logo.png`
this.meta.explicit = !!mediaMetadata.explicit
+ this.meta.type = mediaMetadata.type
+ this.meta.language = mediaMetadata.language
this.episodes = []
if (isPodcast) { // PODCAST EPISODES
@@ -333,4 +342,4 @@ class Feed {
return author
}
}
-module.exports = Feed
\ No newline at end of file
+module.exports = Feed
diff --git a/server/objects/FeedEpisode.js b/server/objects/FeedEpisode.js
index 8891aa07..0f5ac28c 100644
--- a/server/objects/FeedEpisode.js
+++ b/server/objects/FeedEpisode.js
@@ -14,6 +14,9 @@ class FeedEpisode {
this.author = null
this.explicit = null
this.duration = null
+ this.season = null
+ this.episode = null
+ this.episodeType = null
this.libraryItemId = null
this.episodeId = null
@@ -35,6 +38,9 @@ class FeedEpisode {
this.author = episode.author
this.explicit = episode.explicit
this.duration = episode.duration
+ this.season = episode.season
+ this.episode = episode.episode
+ this.episodeType = episode.episodeType
this.libraryItemId = episode.libraryItemId
this.episodeId = episode.episodeId || null
this.trackIndex = episode.trackIndex || 0
@@ -52,6 +58,9 @@ class FeedEpisode {
author: this.author,
explicit: this.explicit,
duration: this.duration,
+ season: this.season,
+ episode: this.episode,
+ episodeType: this.episodeType,
libraryItemId: this.libraryItemId,
episodeId: this.episodeId,
trackIndex: this.trackIndex,
@@ -77,25 +86,31 @@ class FeedEpisode {
this.author = meta.author
this.explicit = mediaMetadata.explicit
this.duration = episode.duration
+ this.season = episode.season
+ this.episode = episode.episode
+ this.episodeType = episode.episodeType
this.libraryItemId = libraryItem.id
this.episodeId = episode.id
this.trackIndex = 0
this.fullPath = episode.audioFile.metadata.path
}
- setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, meta, additionalOffset = 0) {
+ setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, meta, additionalOffset = null) {
// Example:
Fri, 04 Feb 2015 00:00:00 GMT
let timeOffset = isNaN(audioTrack.index) ? 0 : (Number(audioTrack.index) * 1000) // Offset pubdate to ensure correct order
+ let episodeId = String(audioTrack.index)
// Additional offset can be used for collections/series
- if (additionalOffset && !isNaN(additionalOffset)) {
+ if (additionalOffset !== null && !isNaN(additionalOffset)) {
timeOffset += Number(additionalOffset) * 1000
+
+ episodeId = String(additionalOffset) + '-' + episodeId
}
// e.g. Track 1 will have a pub date before Track 2
const audiobookPubDate = date.format(new Date(libraryItem.addedAt + timeOffset), 'ddd, DD MMM YYYY HH:mm:ss [GMT]')
- const contentUrl = `/feed/${slug}/item/${audioTrack.index}/${audioTrack.metadata.filename}`
+ const contentUrl = `/feed/${slug}/item/${episodeId}/${audioTrack.metadata.filename}`
const media = libraryItem.media
const mediaMetadata = media.metadata
@@ -110,7 +125,7 @@ class FeedEpisode {
}
}
- this.id = String(audioTrack.index)
+ this.id = episodeId
this.title = title
this.description = mediaMetadata.description || ''
this.enclosure = {
@@ -144,9 +159,12 @@ class FeedEpisode {
{ 'itunes:summary': this.description || '' },
{
"itunes:explicit": !!this.explicit
- }
+ },
+ { "itunes:episodeType": this.episodeType },
+ { "itunes:season": this.season },
+ { "itunes:episode": this.episode }
]
}
}
}
-module.exports = FeedEpisode
\ No newline at end of file
+module.exports = FeedEpisode
diff --git a/server/objects/FeedMeta.js b/server/objects/FeedMeta.js
index 6c029095..908d64fa 100644
--- a/server/objects/FeedMeta.js
+++ b/server/objects/FeedMeta.js
@@ -7,6 +7,11 @@ class FeedMeta {
this.feedUrl = null
this.link = null
this.explicit = null
+ this.type = null
+ this.language = null
+ this.preventIndexing = null
+ this.ownerName = null
+ this.ownerEmail = null
if (meta) {
this.construct(meta)
@@ -21,6 +26,11 @@ class FeedMeta {
this.feedUrl = meta.feedUrl
this.link = meta.link
this.explicit = meta.explicit
+ this.type = meta.type
+ this.language = meta.language
+ this.preventIndexing = meta.preventIndexing
+ this.ownerName = meta.ownerName
+ this.ownerEmail = meta.ownerEmail
}
toJSON() {
@@ -31,7 +41,22 @@ class FeedMeta {
imageUrl: this.imageUrl,
feedUrl: this.feedUrl,
link: this.link,
- explicit: this.explicit
+ explicit: this.explicit,
+ type: this.type,
+ language: this.language,
+ preventIndexing: this.preventIndexing,
+ ownerName: this.ownerName,
+ ownerEmail: this.ownerEmail
+ }
+ }
+
+ toJSONMinified() {
+ return {
+ title: this.title,
+ description: this.description,
+ preventIndexing: this.preventIndexing,
+ ownerName: this.ownerName,
+ ownerEmail: this.ownerEmail
}
}
@@ -43,16 +68,18 @@ class FeedMeta {
feed_url: this.feedUrl,
site_url: this.link,
image_url: this.imageUrl,
- language: 'en',
custom_namespaces: {
'itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd',
'psc': 'http://podlove.org/simple-chapters',
- 'podcast': 'https://podcastindex.org/namespace/1.0'
+ 'podcast': 'https://podcastindex.org/namespace/1.0',
+ 'googleplay': 'http://www.google.com/schemas/play-podcasts/1.0'
},
custom_elements: [
+ { 'language': this.language || 'en' },
{ 'author': this.author || 'advplyr' },
{ 'itunes:author': this.author || 'advplyr' },
{ 'itunes:summary': this.description || '' },
+ { 'itunes:type': this.type },
{
'itunes:image': {
_attr: {
@@ -62,15 +89,15 @@ class FeedMeta {
},
{
'itunes:owner': [
- { 'itunes:name': this.author || '' },
- { 'itunes:email': '' }
+ { 'itunes:name': this.ownerName || this.author || '' },
+ { 'itunes:email': this.ownerEmail || '' }
]
},
- {
- "itunes:explicit": !!this.explicit
- }
+ { 'itunes:explicit': !!this.explicit },
+ { 'itunes:block': this.preventIndexing?"Yes":"No" },
+ { 'googleplay:block': this.preventIndexing?"yes":"no" }
]
}
}
}
-module.exports = FeedMeta
\ No newline at end of file
+module.exports = FeedMeta
diff --git a/server/objects/LibraryItem.js b/server/objects/LibraryItem.js
index 95674288..b15e53c9 100644
--- a/server/objects/LibraryItem.js
+++ b/server/objects/LibraryItem.js
@@ -197,9 +197,15 @@ class LibraryItem {
if (key === 'libraryFiles') {
this.libraryFiles = payload.libraryFiles.map(lf => lf.clone())
- // Use first image library file as cover
- const firstImageFile = this.libraryFiles.find(lf => lf.fileType === 'image')
- if (firstImageFile) this.media.coverPath = firstImageFile.metadata.path
+ // Set cover image
+ const imageFiles = this.libraryFiles.filter(lf => lf.fileType === 'image')
+ const coverMatch = imageFiles.find(iFile => /\/cover\.[^.\/]*$/.test(iFile.metadata.path))
+ if (coverMatch) {
+ this.media.coverPath = coverMatch.metadata.path
+ } else if (imageFiles.length) {
+ this.media.coverPath = imageFiles[0].metadata.path
+ }
+
} else if (this[key] !== undefined && key !== 'media') {
this[key] = payload[key]
}
@@ -330,6 +336,7 @@ class LibraryItem {
}
if (dataFound.ino !== this.ino) {
+ Logger.warn(`[LibraryItem] Check scan item changed inode "${this.ino}" -> "${dataFound.ino}"`)
this.ino = dataFound.ino
hasUpdated = true
}
@@ -341,7 +348,7 @@ class LibraryItem {
}
if (dataFound.path !== this.path) {
- Logger.warn(`[LibraryItem] Check scan item changed path "${this.path}" -> "${dataFound.path}"`)
+ Logger.warn(`[LibraryItem] Check scan item changed path "${this.path}" -> "${dataFound.path}" (inode ${this.ino})`)
this.path = dataFound.path
this.relPath = dataFound.relPath
hasUpdated = true
@@ -444,8 +451,14 @@ class LibraryItem {
// Set cover image if not set
const imageFiles = this.libraryFiles.filter(lf => lf.fileType === 'image')
if (imageFiles.length && !this.media.coverPath) {
- this.media.coverPath = imageFiles[0].metadata.path
- Logger.debug('[LibraryItem] Set media cover path', this.media.coverPath)
+ // attempt to find a file called cover.
otherwise just fall back to the first image found
+ const coverMatch = imageFiles.find(iFile => /\/cover\.[^.\/]*$/.test(iFile.metadata.path))
+ if (coverMatch) {
+ this.media.coverPath = coverMatch.metadata.path
+ } else {
+ this.media.coverPath = imageFiles[0].metadata.path
+ }
+ Logger.info('[LibraryItem] Set media cover path', this.media.coverPath)
hasUpdated = true
}
diff --git a/server/objects/PodcastEpisodeDownload.js b/server/objects/PodcastEpisodeDownload.js
index 8c6ee62d..6c3be9ca 100644
--- a/server/objects/PodcastEpisodeDownload.js
+++ b/server/objects/PodcastEpisodeDownload.js
@@ -1,6 +1,7 @@
const Path = require('path')
const { getId } = require('../utils/index')
const { sanitizeFilename } = require('../utils/fileUtils')
+const globals = require('../utils/globals')
class PodcastEpisodeDownload {
constructor() {
@@ -8,9 +9,9 @@ class PodcastEpisodeDownload {
this.podcastEpisode = null
this.url = null
this.libraryItem = null
+ this.libraryId = null
this.isAutoDownload = false
- this.isDownloading = false
this.isFinished = false
this.failed = false
@@ -22,20 +23,32 @@ class PodcastEpisodeDownload {
toJSONForClient() {
return {
id: this.id,
- episodeDisplayTitle: this.podcastEpisode ? this.podcastEpisode.title : null,
+ episodeDisplayTitle: this.podcastEpisode?.title ?? null,
url: this.url,
- libraryItemId: this.libraryItem ? this.libraryItem.id : null,
- isDownloading: this.isDownloading,
+ libraryItemId: this.libraryItem?.id || null,
+ libraryId: this.libraryId || null,
isFinished: this.isFinished,
failed: this.failed,
startedAt: this.startedAt,
createdAt: this.createdAt,
- finishedAt: this.finishedAt
+ finishedAt: this.finishedAt,
+ podcastTitle: this.libraryItem?.media.metadata.title ?? null,
+ podcastExplicit: !!this.libraryItem?.media.metadata.explicit,
+ season: this.podcastEpisode?.season ?? null,
+ episode: this.podcastEpisode?.episode ?? null,
+ episodeType: this.podcastEpisode?.episodeType ?? 'full',
+ publishedAt: this.podcastEpisode?.publishedAt ?? null
}
}
+ get fileExtension() {
+ const extname = Path.extname(this.url).substring(1).toLowerCase()
+ if (globals.SupportedAudioTypes.includes(extname)) return extname
+ return 'mp3'
+ }
+
get targetFilename() {
- return sanitizeFilename(`${this.podcastEpisode.title}.mp3`)
+ return sanitizeFilename(`${this.podcastEpisode.title}.${this.fileExtension}`)
}
get targetPath() {
return Path.join(this.libraryItem.path, this.targetFilename)
@@ -47,13 +60,21 @@ class PodcastEpisodeDownload {
return this.libraryItem ? this.libraryItem.id : null
}
- setData(podcastEpisode, libraryItem, isAutoDownload) {
+ setData(podcastEpisode, libraryItem, isAutoDownload, libraryId) {
this.id = getId('epdl')
this.podcastEpisode = podcastEpisode
- this.url = podcastEpisode.enclosure.url
+
+ const url = podcastEpisode.enclosure.url
+ if (decodeURIComponent(url) !== url) { // Already encoded
+ this.url = url
+ } else {
+ this.url = encodeURI(url)
+ }
+
this.libraryItem = libraryItem
this.isAutoDownload = isAutoDownload
this.createdAt = Date.now()
+ this.libraryId = libraryId
}
setFinished(success) {
@@ -62,4 +83,4 @@ class PodcastEpisodeDownload {
this.failed = !success
}
}
-module.exports = PodcastEpisodeDownload
\ No newline at end of file
+module.exports = PodcastEpisodeDownload
diff --git a/server/objects/Stream.js b/server/objects/Stream.js
index 9558dd11..5d6442dc 100644
--- a/server/objects/Stream.js
+++ b/server/objects/Stream.js
@@ -82,7 +82,8 @@ class Stream extends EventEmitter {
AudioMimeType.WMA,
AudioMimeType.AIFF,
AudioMimeType.WEBM,
- AudioMimeType.WEBMA
+ AudioMimeType.WEBMA,
+ AudioMimeType.AWB
]
}
get codecsToForceAAC() {
diff --git a/server/objects/entities/PodcastEpisode.js b/server/objects/entities/PodcastEpisode.js
index 892a18e8..f1cfa77e 100644
--- a/server/objects/entities/PodcastEpisode.js
+++ b/server/objects/entities/PodcastEpisode.js
@@ -117,7 +117,7 @@ class PodcastEpisode {
this.enclosure = data.enclosure ? { ...data.enclosure } : null
this.season = data.season || ''
this.episode = data.episode || ''
- this.episodeType = data.episodeType || ''
+ this.episodeType = data.episodeType || 'full'
this.publishedAt = data.publishedAt || 0
this.addedAt = Date.now()
this.updatedAt = Date.now()
@@ -165,4 +165,4 @@ class PodcastEpisode {
return cleanStringForSearch(this.title).includes(query)
}
}
-module.exports = PodcastEpisode
\ No newline at end of file
+module.exports = PodcastEpisode
diff --git a/server/objects/mediaTypes/Book.js b/server/objects/mediaTypes/Book.js
index 3fa4c1be..2983faf7 100644
--- a/server/objects/mediaTypes/Book.js
+++ b/server/objects/mediaTypes/Book.js
@@ -296,7 +296,7 @@ class Book {
})
}
} else if (key === 'narrators') {
- if (opfMetadata.narrators && opfMetadata.narrators.length && (!this.metadata.narrators.length || opfMetadataOverrideDetails)) {
+ if (opfMetadata.narrators?.length && (!this.metadata.narrators.length || opfMetadataOverrideDetails)) {
metadataUpdatePayload.narrators = opfMetadata.narrators
}
} else if (key === 'series') {
@@ -356,9 +356,9 @@ class Book {
}
updateAudioTracks(orderedFileData) {
- var index = 1
+ let index = 1
this.audioFiles = orderedFileData.map((fileData) => {
- var audioFile = this.audioFiles.find(af => af.ino === fileData.ino)
+ const audioFile = this.audioFiles.find(af => af.ino === fileData.ino)
audioFile.manuallyVerified = true
audioFile.invalid = false
audioFile.error = null
@@ -376,11 +376,11 @@ class Book {
this.rebuildTracks()
}
- rebuildTracks(preferOverdriveMediaMarker) {
+ rebuildTracks() {
Logger.debug(`[Book] Tracks being rebuilt...!`)
this.audioFiles.sort((a, b) => a.index - b.index)
this.missingParts = []
- this.setChapters(preferOverdriveMediaMarker)
+ this.setChapters()
this.checkUpdateMissingTracks()
}
@@ -412,14 +412,16 @@ class Book {
return wasUpdated
}
- setChapters(preferOverdriveMediaMarker = false) {
+ setChapters() {
+ const preferOverdriveMediaMarker = !!global.ServerSettings.scannerPreferOverdriveMediaMarker
+
// If 1 audio file without chapters, then no chapters will be set
- var includedAudioFiles = this.audioFiles.filter(af => !af.exclude)
+ const includedAudioFiles = this.audioFiles.filter(af => !af.exclude)
if (!includedAudioFiles.length) return
// If overdrive media markers are present and preferred, use those instead
if (preferOverdriveMediaMarker) {
- var overdriveChapters = parseOverdriveMediaMarkersAsChapters(includedAudioFiles)
+ const overdriveChapters = parseOverdriveMediaMarkersAsChapters(includedAudioFiles)
if (overdriveChapters) {
Logger.info('[Book] Overdrive Media Markers and preference found! Using these for chapter definitions')
this.chapters = overdriveChapters
@@ -460,17 +462,26 @@ class Book {
})
}
} else if (includedAudioFiles.length > 1) {
+ const preferAudioMetadata = !!global.ServerSettings.scannerPreferAudioMetadata
+
// Build chapters from audio files
this.chapters = []
- var currChapterId = 0
- var currStartTime = 0
+ let currChapterId = 0
+ let currStartTime = 0
includedAudioFiles.forEach((file) => {
if (file.duration) {
+ let title = file.metadata.filename ? Path.basename(file.metadata.filename, Path.extname(file.metadata.filename)) : `Chapter ${currChapterId}`
+
+ // When prefer audio metadata server setting is set then use ID3 title tag as long as it is not the same as the book title
+ if (preferAudioMetadata && file.metaTags?.tagTitle && file.metaTags?.tagTitle !== this.metadata.title) {
+ title = file.metaTags.tagTitle
+ }
+
this.chapters.push({
id: currChapterId++,
start: currStartTime,
end: currStartTime + file.duration,
- title: file.metadata.filename ? Path.basename(file.metadata.filename, Path.extname(file.metadata.filename)) : `Chapter ${currChapterId}`
+ title
})
currStartTime += file.duration
}
diff --git a/server/objects/metadata/PodcastMetadata.js b/server/objects/metadata/PodcastMetadata.js
index 85e2c52d..59b5fa6f 100644
--- a/server/objects/metadata/PodcastMetadata.js
+++ b/server/objects/metadata/PodcastMetadata.js
@@ -15,6 +15,7 @@ class PodcastMetadata {
this.itunesArtistId = null
this.explicit = false
this.language = null
+ this.type = null
if (metadata) {
this.construct(metadata)
@@ -34,6 +35,7 @@ class PodcastMetadata {
this.itunesArtistId = metadata.itunesArtistId
this.explicit = metadata.explicit
this.language = metadata.language || null
+ this.type = metadata.type || 'episodic'
}
toJSON() {
@@ -49,7 +51,8 @@ class PodcastMetadata {
itunesId: this.itunesId,
itunesArtistId: this.itunesArtistId,
explicit: this.explicit,
- language: this.language
+ language: this.language,
+ type: this.type
}
}
@@ -67,7 +70,8 @@ class PodcastMetadata {
itunesId: this.itunesId,
itunesArtistId: this.itunesArtistId,
explicit: this.explicit,
- language: this.language
+ language: this.language,
+ type: this.type
}
}
@@ -112,6 +116,7 @@ class PodcastMetadata {
this.itunesArtistId = mediaMetadata.itunesArtistId || null
this.explicit = !!mediaMetadata.explicit
this.language = mediaMetadata.language || null
+ this.type = mediaMetadata.type || null
if (mediaMetadata.genres && mediaMetadata.genres.length) {
this.genres = [...mediaMetadata.genres]
}
@@ -132,4 +137,4 @@ class PodcastMetadata {
return hasUpdates
}
}
-module.exports = PodcastMetadata
\ No newline at end of file
+module.exports = PodcastMetadata
diff --git a/server/objects/settings/ServerSettings.js b/server/objects/settings/ServerSettings.js
index 38b75370..1dbd3417 100644
--- a/server/objects/settings/ServerSettings.js
+++ b/server/objects/settings/ServerSettings.js
@@ -51,6 +51,7 @@ class ServerSettings {
this.chromecastEnabled = false
this.enableEReader = false
this.dateFormat = 'MM/dd/yyyy'
+ this.timeFormat = 'HH:mm'
this.language = 'en-us'
this.logLevel = Logger.logLevel
@@ -96,6 +97,7 @@ class ServerSettings {
this.chromecastEnabled = !!settings.chromecastEnabled
this.enableEReader = !!settings.enableEReader
this.dateFormat = settings.dateFormat || 'MM/dd/yyyy'
+ this.timeFormat = settings.timeFormat || 'HH:mm'
this.language = settings.language || 'en-us'
this.logLevel = settings.logLevel || Logger.logLevel
this.version = settings.version || null
@@ -146,6 +148,7 @@ class ServerSettings {
chromecastEnabled: this.chromecastEnabled,
enableEReader: this.enableEReader,
dateFormat: this.dateFormat,
+ timeFormat: this.timeFormat,
language: this.language,
logLevel: this.logLevel,
version: this.version
@@ -178,4 +181,4 @@ class ServerSettings {
return hasUpdates
}
}
-module.exports = ServerSettings
\ No newline at end of file
+module.exports = ServerSettings
diff --git a/server/providers/iTunes.js b/server/providers/iTunes.js
index bdea2286..39f36ab2 100644
--- a/server/providers/iTunes.js
+++ b/server/providers/iTunes.js
@@ -95,7 +95,8 @@ class iTunes {
cover: this.getCoverArtwork(data),
trackCount: data.trackCount,
feedUrl: data.feedUrl,
- pageUrl: data.collectionViewUrl
+ pageUrl: data.collectionViewUrl,
+ explicit: data.trackExplicitness === 'explicit'
}
}
@@ -105,4 +106,4 @@ class iTunes {
})
}
}
-module.exports = iTunes
\ No newline at end of file
+module.exports = iTunes
diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js
index 41c26769..4c8569cf 100644
--- a/server/routers/ApiRouter.js
+++ b/server/routers/ApiRouter.js
@@ -76,6 +76,7 @@ class ApiRouter {
this.router.get('/libraries/:id/items', LibraryController.middleware.bind(this), LibraryController.getLibraryItems.bind(this))
this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this))
+ this.router.get('/libraries/:id/episode-downloads', LibraryController.middleware.bind(this), LibraryController.getEpisodeDownloadQueue.bind(this))
this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this))
this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this))
this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this))
@@ -235,6 +236,7 @@ class ApiRouter {
this.router.get('/podcasts/:id/search-episode', PodcastController.middleware.bind(this), PodcastController.findEpisode.bind(this))
this.router.post('/podcasts/:id/download-episodes', PodcastController.middleware.bind(this), PodcastController.downloadEpisodes.bind(this))
this.router.post('/podcasts/:id/match-episodes', PodcastController.middleware.bind(this), PodcastController.quickMatchEpisodes.bind(this))
+ this.router.get('/podcasts/:id/episode/:episodeId', PodcastController.middleware.bind(this), PodcastController.getEpisode.bind(this))
this.router.patch('/podcasts/:id/episode/:episodeId', PodcastController.middleware.bind(this), PodcastController.updateEpisode.bind(this))
this.router.delete('/podcasts/:id/episode/:episodeId', PodcastController.middleware.bind(this), PodcastController.removeEpisode.bind(this))
@@ -553,4 +555,4 @@ class ApiRouter {
}
}
}
-module.exports = ApiRouter
\ No newline at end of file
+module.exports = ApiRouter
diff --git a/server/scanner/MediaFileScanner.js b/server/scanner/MediaFileScanner.js
index e9a54b66..a10b949c 100644
--- a/server/scanner/MediaFileScanner.js
+++ b/server/scanner/MediaFileScanner.js
@@ -221,7 +221,7 @@ class MediaFileScanner {
*/
async scanMediaFiles(mediaLibraryFiles, libraryItem, libraryScan = null) {
const preferAudioMetadata = libraryScan ? !!libraryScan.preferAudioMetadata : !!global.ServerSettings.scannerPreferAudioMetadata
- const preferOverdriveMediaMarker = libraryScan ? !!libraryScan.preferOverdriveMediaMarker : !!global.ServerSettings.scannerPreferOverdriveMediaMarker
+ const preferOverdriveMediaMarker = !!global.ServerSettings.scannerPreferOverdriveMediaMarker
let hasUpdated = false
@@ -280,7 +280,7 @@ class MediaFileScanner {
}
if (hasUpdated) {
- libraryItem.media.rebuildTracks(preferOverdriveMediaMarker)
+ libraryItem.media.rebuildTracks()
}
} else if (libraryItem.mediaType === 'podcast') { // Podcast Media Type
const existingAudioFiles = mediaScanResult.audioFiles.filter(af => libraryItem.media.findFileWithInode(af.ino))
diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js
index 791a7140..0ac38b96 100644
--- a/server/scanner/Scanner.js
+++ b/server/scanner/Scanner.js
@@ -201,6 +201,7 @@ class Scanner {
const dataFound = libraryItemDataFound.find(lid => lid.ino === libraryItem.ino || comparePaths(lid.relPath, libraryItem.relPath))
if (!dataFound) {
libraryScan.addLog(LogLevel.WARN, `Library Item "${libraryItem.media.metadata.title}" is missing`)
+ Logger.warn(`[Scanner] Library item "${libraryItem.media.metadata.title}" is missing (inode "${libraryItem.ino}")`)
libraryScan.resultsMissing++
libraryItem.setMissing()
itemsToUpdate.push(libraryItem)
@@ -899,7 +900,7 @@ class Scanner {
description: episodeToMatch.description || '',
enclosure: episodeToMatch.enclosure || null,
episode: episodeToMatch.episode || '',
- episodeType: episodeToMatch.episodeType || '',
+ episodeType: episodeToMatch.episodeType || 'full',
season: episodeToMatch.season || '',
pubDate: episodeToMatch.pubDate || '',
publishedAt: episodeToMatch.publishedAt
@@ -993,4 +994,4 @@ class Scanner {
return MediaFileScanner.probeAudioFileWithTone(audioFile)
}
}
-module.exports = Scanner
\ No newline at end of file
+module.exports = Scanner
diff --git a/server/utils/constants.js b/server/utils/constants.js
index 7f7e324e..a650c7ab 100644
--- a/server/utils/constants.js
+++ b/server/utils/constants.js
@@ -46,7 +46,9 @@ module.exports.AudioMimeType = {
WMA: 'audio/x-ms-wma',
AIFF: 'audio/x-aiff',
WEBM: 'audio/webm',
- WEBMA: 'audio/webm'
+ WEBMA: 'audio/webm',
+ MKA: 'audio/x-matroska',
+ AWB: 'audio/amr-wb'
}
module.exports.VideoMimeType = {
diff --git a/server/utils/filePerms.js b/server/utils/filePerms.js
index c48b4261..85fa7e84 100644
--- a/server/utils/filePerms.js
+++ b/server/utils/filePerms.js
@@ -107,7 +107,6 @@ module.exports.setDefaultDirSync = (path, silent = false) => {
const uid = global.Uid
const gid = global.Gid
if (isNaN(uid) || isNaN(gid)) {
- if (!silent) Logger.debug('Not modifying permissions since no uid/gid is specified')
return true
}
if (!silent) Logger.debug(`[FilePerms] Setting dir permission "${mode}" for uid ${uid} and gid ${gid} | "${path}"`)
diff --git a/server/utils/globals.js b/server/utils/globals.js
index d8999152..71c1c2c0 100644
--- a/server/utils/globals.js
+++ b/server/utils/globals.js
@@ -1,6 +1,6 @@
const globals = {
SupportedImageTypes: ['png', 'jpg', 'jpeg', 'webp'],
- SupportedAudioTypes: ['m4b', 'mp3', 'm4a', 'flac', 'opus', 'ogg', 'oga', 'mp4', 'aac', 'wma', 'aiff', 'wav', 'webm', 'webma'],
+ SupportedAudioTypes: ['m4b', 'mp3', 'm4a', 'flac', 'opus', 'ogg', 'oga', 'mp4', 'aac', 'wma', 'aiff', 'wav', 'webm', 'webma', 'mka', 'awb'],
SupportedEbookTypes: ['epub', 'pdf', 'mobi', 'azw3', 'cbr', 'cbz'],
SupportedVideoTypes: ['mp4'],
TextFileTypes: ['txt', 'nfo'],
diff --git a/server/utils/htmlSanitizer.js b/server/utils/htmlSanitizer.js
index e9473d30..68d92c85 100644
--- a/server/utils/htmlSanitizer.js
+++ b/server/utils/htmlSanitizer.js
@@ -1,10 +1,10 @@
const sanitizeHtml = require('../libs/sanitizeHtml')
-const {entities} = require("./htmlEntities");
+const { entities } = require("./htmlEntities");
function sanitize(html) {
const sanitizerOptions = {
allowedTags: [
- 'p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del'
+ 'p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del', 'br'
],
disallowedTagsMode: 'discard',
allowedAttributes: {
diff --git a/server/utils/libraryHelpers.js b/server/utils/libraryHelpers.js
index 93d23466..47a7b9f5 100644
--- a/server/utils/libraryHelpers.js
+++ b/server/utils/libraryHelpers.js
@@ -95,17 +95,20 @@ module.exports = {
checkSeriesProgressFilter(series, filterBy, user) {
const filter = this.decode(filterBy.split('.')[1])
- var numBooksStartedOrFinished = 0
+ let someBookHasProgress = false
+ let someBookIsUnfinished = false
for (const libraryItem of series.books) {
const itemProgress = user.getMediaProgress(libraryItem.id)
- if (filter === 'Finished' && (!itemProgress || !itemProgress.isFinished)) return false
- if (filter === 'Not Started' && itemProgress) return false
- if (itemProgress) numBooksStartedOrFinished++
+ if (!itemProgress || !itemProgress.isFinished) someBookIsUnfinished = true
+ if (itemProgress && itemProgress.progress > 0) someBookHasProgress = true
+
+ if (filter === 'finished' && (!itemProgress || !itemProgress.isFinished)) return false
+ if (filter === 'not-started' && itemProgress) return false
}
- if (numBooksStartedOrFinished === series.books.length) { // Completely finished series
- if (filter === 'Not Finished') return false
- } else if (numBooksStartedOrFinished === 0 && filter === 'In Progress') { // Series not started
+ if (!someBookIsUnfinished && filter === 'not-finished') { // Completely finished series
+ return false
+ } else if (!someBookHasProgress && filter === 'in-progress') { // Series not started
return false
}
return true
@@ -280,6 +283,19 @@ module.exports = {
}
},
+ getItemSizeStats(libraryItems) {
+ var sorted = sort(libraryItems).desc(li => li.media.size)
+ var top10 = sorted.slice(0, 10).map(li => ({ id: li.id, title: li.media.metadata.title, size: li.media.size })).filter(i => i.size > 0)
+ var totalSize = 0
+ libraryItems.forEach((li) => {
+ totalSize += li.media.size
+ })
+ return {
+ totalSize,
+ largestItems: top10
+ }
+ },
+
getLibraryItemsTotalSize(libraryItems) {
var totalSize = 0
libraryItems.forEach((li) => {
@@ -843,4 +859,4 @@ module.exports = {
return Object.values(albums)
}
-}
\ No newline at end of file
+}
diff --git a/server/utils/parsers/parseNameString.js b/server/utils/parsers/parseNameString.js
index d2d80d2d..96aa4bbe 100644
--- a/server/utils/parsers/parseNameString.js
+++ b/server/utils/parsers/parseNameString.js
@@ -43,6 +43,8 @@ module.exports.parse = (nameString) => {
// Example &LF: Friedman, Milton & Friedman, Rose
if (nameString.includes('&')) {
nameString.split('&').forEach((asa) => splitNames = splitNames.concat(asa.split(',')))
+ } else if (nameString.includes(';')) {
+ nameString.split(';').forEach((asa) => splitNames = splitNames.concat(asa.split(',')))
} else {
splitNames = nameString.split(',')
}
diff --git a/server/utils/parsers/parseOpfMetadata.js b/server/utils/parsers/parseOpfMetadata.js
index f51a7e93..6788faae 100644
--- a/server/utils/parsers/parseOpfMetadata.js
+++ b/server/utils/parsers/parseOpfMetadata.js
@@ -111,7 +111,7 @@ function fetchVolumeNumber(metadataMeta) {
function fetchNarrators(creators, metadata) {
const narrators = fetchCreators(creators, 'nrt')
- if (typeof metadata.meta == "undefined" || narrators.length) return narrators
+ if (narrators?.length) return narrators
try {
const narratorsJSON = JSON.parse(fetchTagString(metadata.meta, "calibre:user_metadata:#narrators").replace(/"/g, '"'))
return narratorsJSON["#value#"]
@@ -150,7 +150,7 @@ module.exports.parseOpfMetadataXML = async (xml) => {
const metadataMeta = prefix ? metadata[`${prefix}:meta`] || metadata.meta : metadata.meta
metadata.meta = {}
- if (metadataMeta && metadataMeta.length) {
+ if (metadataMeta?.length) {
metadataMeta.forEach((meta) => {
if (meta && meta['$'] && meta['$'].name) {
metadata.meta[meta['$'].name] = [meta['$'].content || '']
diff --git a/server/utils/podcastUtils.js b/server/utils/podcastUtils.js
index ef7d54d1..bf7c4d4a 100644
--- a/server/utils/podcastUtils.js
+++ b/server/utils/podcastUtils.js
@@ -46,7 +46,8 @@ function extractPodcastMetadata(channel) {
categories: extractCategories(channel),
feedUrl: null,
description: null,
- descriptionPlain: null
+ descriptionPlain: null,
+ type: null
}
if (channel['itunes:new-feed-url']) {
@@ -61,7 +62,7 @@ function extractPodcastMetadata(channel) {
metadata.descriptionPlain = htmlSanitizer.stripAllTags(rawDescription)
}
- var arrayFields = ['title', 'language', 'itunes:explicit', 'itunes:author', 'pubDate', 'link']
+ var arrayFields = ['title', 'language', 'itunes:explicit', 'itunes:author', 'pubDate', 'link', 'itunes:type']
arrayFields.forEach((key) => {
var cleanKey = key.split(':').pop()
metadata[cleanKey] = extractFirstArrayItem(channel, key)
@@ -258,4 +259,4 @@ module.exports.findMatchingEpisodesInFeed = (feed, searchTitle) => {
}
})
return matches.sort((a, b) => a.levenshtein - b.levenshtein)
-}
\ No newline at end of file
+}