diff --git a/client/components/covers/AuthorImage.vue b/client/components/covers/AuthorImage.vue index af8a394f4..019263633 100644 --- a/client/components/covers/AuthorImage.vue +++ b/client/components/covers/AuthorImage.vue @@ -56,11 +56,7 @@ export default { }, imgSrc() { if (!this.imagePath) return null - if (process.env.NODE_ENV !== 'production') { - // Testing - return `http://localhost:3333${this.$config.routerBasePath}/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}` - } - return `/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}` + return `${this.$config.routerBasePath}/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}` } }, methods: { diff --git a/client/components/modals/ShareModal.vue b/client/components/modals/ShareModal.vue index 65ef4fc73..d0487fd38 100644 --- a/client/components/modals/ShareModal.vue +++ b/client/components/modals/ShareModal.vue @@ -112,11 +112,11 @@ export default { return this.$store.state.user.user }, demoShareUrl() { - return `${window.origin}/share/${this.newShareSlug}` + return `${window.origin}${this.$config.routerBasePath}/share/${this.newShareSlug}` }, currentShareUrl() { if (!this.currentShare) return '' - return `${window.origin}/share/${this.currentShare.slug}` + return `${window.origin}${this.$config.routerBasePath}/share/${this.currentShare.slug}` }, currentShareTimeRemaining() { if (!this.currentShare) return 'Error' diff --git a/client/components/modals/rssfeed/OpenCloseModal.vue b/client/components/modals/rssfeed/OpenCloseModal.vue index f15a8e8ed..53542cf55 100644 --- a/client/components/modals/rssfeed/OpenCloseModal.vue +++ b/client/components/modals/rssfeed/OpenCloseModal.vue @@ -139,7 +139,7 @@ export default { slug: this.newFeedSlug, metadataDetails: this.metadataDetails } - if (this.$isDev) payload.serverAddress = `http://localhost:3333${this.$config.routerBasePath}` + if (this.$isDev) payload.serverAddress = process.env.serverUrl console.log('Payload', payload) this.$axios diff --git a/client/layouts/default.vue b/client/layouts/default.vue index 95f8560d2..9121561e4 100644 --- a/client/layouts/default.vue +++ b/client/layouts/default.vue @@ -357,7 +357,8 @@ export default { teardown: false, transports: ['websocket'], upgrade: false, - reconnection: true + reconnection: true, + path: `${this.$config.routerBasePath}/socket.io` }) this.$root.socket = this.socket console.log('Socket initialized') diff --git a/client/nuxt.config.js b/client/nuxt.config.js index 0bca2a143..dce8c52aa 100644 --- a/client/nuxt.config.js +++ b/client/nuxt.config.js @@ -1,19 +1,22 @@ const pkg = require('./package.json') +const routerBasePath = process.env.ROUTER_BASE_PATH || '' +const serverHostUrl = process.env.NODE_ENV === 'production' ? '' : 'http://localhost:3333' + module.exports = { // Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode ssr: false, target: 'static', dev: process.env.NODE_ENV !== 'production', env: { - serverUrl: process.env.NODE_ENV === 'production' ? process.env.ROUTER_BASE_PATH || '' : 'http://localhost:3333', + serverUrl: serverHostUrl + routerBasePath, chromecastReceiver: 'FD1F76C5' }, telemetry: false, publicRuntimeConfig: { version: pkg.version, - routerBasePath: process.env.ROUTER_BASE_PATH || '' + routerBasePath }, // Global page headers: https://go.nuxtjs.dev/config-head @@ -22,38 +25,23 @@ module.exports = { htmlAttrs: { lang: 'en' }, - meta: [ - { charset: 'utf-8' }, - { name: 'viewport', content: 'width=device-width, initial-scale=1' }, - { hid: 'description', name: 'description', content: '' }, - { hid: 'robots', name: 'robots', content: 'noindex' } - ], + meta: [{ charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: '' }, { hid: 'robots', name: 'robots', content: 'noindex' }], script: [], link: [ - { rel: 'icon', type: 'image/x-icon', href: (process.env.ROUTER_BASE_PATH || '') + '/favicon.ico' }, - { rel: 'apple-touch-icon', href: (process.env.ROUTER_BASE_PATH || '') + '/ios_icon.png' } + { rel: 'icon', type: 'image/x-icon', href: routerBasePath + '/favicon.ico' }, + { rel: 'apple-touch-icon', href: routerBasePath + '/ios_icon.png' } ] }, router: { - base: process.env.ROUTER_BASE_PATH || '' + base: routerBasePath }, // Global CSS: https://go.nuxtjs.dev/config-css - css: [ - '@/assets/tailwind.css', - '@/assets/app.css' - ], + css: ['@/assets/tailwind.css', '@/assets/app.css'], // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins - plugins: [ - '@/plugins/constants.js', - '@/plugins/init.client.js', - '@/plugins/axios.js', - '@/plugins/toast.js', - '@/plugins/utils.js', - '@/plugins/i18n.js' - ], + plugins: ['@/plugins/constants.js', '@/plugins/init.client.js', '@/plugins/axios.js', '@/plugins/toast.js', '@/plugins/utils.js', '@/plugins/i18n.js'], // Auto import components: https://go.nuxtjs.dev/config-components components: true, @@ -65,30 +53,30 @@ module.exports = { ], // Modules: https://go.nuxtjs.dev/config-modules - modules: [ - 'nuxt-socket-io', - '@nuxtjs/axios', - '@nuxtjs/proxy' - ], + modules: ['nuxt-socket-io', '@nuxtjs/axios', '@nuxtjs/proxy'], proxy: { - '/api/': { target: process.env.NODE_ENV !== 'production' ? 'http://localhost:3333' : '/' }, - '/dev/': { target: 'http://localhost:3333', pathRewrite: { '^/dev/': '' } } + [`${routerBasePath}/api/`]: { target: process.env.NODE_ENV !== 'production' ? serverHostUrl : '/' }, + [`${routerBasePath}/public/`]: { target: process.env.NODE_ENV !== 'production' ? serverHostUrl : '/' }, + [`${routerBasePath}/hls/`]: { target: process.env.NODE_ENV !== 'production' ? serverHostUrl : '/' }, + [`${routerBasePath}/dev/`]: { target: process.env.NODE_ENV !== 'production' ? serverHostUrl : '/', pathRewrite: { '^/dev/': '' } } }, io: { - sockets: [{ - name: 'dev', - url: 'http://localhost:3333' - }, - { - name: 'prod' - }] + sockets: [ + { + name: 'dev', + url: serverHostUrl + }, + { + name: 'prod' + } + ] }, // Axios module configuration: https://go.nuxtjs.dev/config-axios axios: { - baseURL: process.env.ROUTER_BASE_PATH || '' + baseURL: routerBasePath }, // nuxt/pwa https://pwa.nuxtjs.org @@ -108,11 +96,11 @@ module.exports = { background_color: '#232323', icons: [ { - src: (process.env.ROUTER_BASE_PATH || '') + '/icon.svg', + src: routerBasePath + '/icon.svg', sizes: 'any' }, { - src: (process.env.ROUTER_BASE_PATH || '') + '/icon192.png', + src: routerBasePath + '/icon192.png', type: 'image/png', sizes: 'any' } @@ -132,7 +120,7 @@ module.exports = { postcssOptions: { plugins: { tailwindcss: {}, - autoprefixer: {}, + autoprefixer: {} } } } @@ -149,12 +137,12 @@ module.exports = { }, /** - * Temporary workaround for @nuxt-community/tailwindcss-module. - * - * Reported: 2022-05-23 - * See: [Issue tracker](https://github.com/nuxt-community/tailwindcss-module/issues/480) - */ + * Temporary workaround for @nuxt-community/tailwindcss-module. + * + * Reported: 2022-05-23 + * See: [Issue tracker](https://github.com/nuxt-community/tailwindcss-module/issues/480) + */ devServerHandlers: [], - ignore: ["**/*.test.*", "**/*.cy.*"] + ignore: ['**/*.test.*', '**/*.cy.*'] } diff --git a/client/pages/audiobook/_id/chapters.vue b/client/pages/audiobook/_id/chapters.vue index 3448479b9..43d64b90b 100644 --- a/client/pages/audiobook/_id/chapters.vue +++ b/client/pages/audiobook/_id/chapters.vue @@ -415,7 +415,7 @@ export default { const audioEl = this.audioEl || document.createElement('audio') var src = audioTrack.contentUrl + `?token=${this.userToken}` if (this.$isDev) { - src = `http://localhost:3333${this.$config.routerBasePath}${src}` + src = `${process.env.serverUrl}${src}` } audioEl.src = src diff --git a/client/pages/share/_slug.vue b/client/pages/share/_slug.vue index f4f93b1d1..cd990072b 100644 --- a/client/pages/share/_slug.vue +++ b/client/pages/share/_slug.vue @@ -61,16 +61,10 @@ export default { }, coverUrl() { if (!this.playbackSession.coverPath) return `${this.$config.routerBasePath}/book_placeholder.jpg` - if (process.env.NODE_ENV === 'development') { - return `http://localhost:3333/public/share/${this.mediaItemShare.slug}/cover` - } - return `/public/share/${this.mediaItemShare.slug}/cover` + return `${this.$config.routerBasePath}/public/share/${this.mediaItemShare.slug}/cover` }, audioTracks() { return (this.playbackSession.audioTracks || []).map((track) => { - if (process.env.NODE_ENV === 'development') { - track.contentUrl = `${process.env.serverUrl}${track.contentUrl}` - } track.relativeContentUrl = track.contentUrl return track }) diff --git a/client/players/AudioTrack.js b/client/players/AudioTrack.js index 78ddfd76b..9627d3cda 100644 --- a/client/players/AudioTrack.js +++ b/client/players/AudioTrack.js @@ -23,10 +23,6 @@ export default class AudioTrack { get relativeContentUrl() { if (!this.contentUrl || this.contentUrl.startsWith('http')) return this.contentUrl - if (process.env.NODE_ENV === 'development') { - return `${process.env.serverUrl}${this.contentUrl}?token=${this.userToken}` - } - return this.contentUrl + `?token=${this.userToken}` } } diff --git a/client/plugins/axios.js b/client/plugins/axios.js index 4ea9b85b4..2c21cc9b6 100644 --- a/client/plugins/axios.js +++ b/client/plugins/axios.js @@ -1,5 +1,5 @@ export default function ({ $axios, store, $config }) { - $axios.onRequest(config => { + $axios.onRequest((config) => { if (!config.url) { console.error('Axios request invalid config', config) return @@ -13,14 +13,14 @@ export default function ({ $axios, store, $config }) { } if (process.env.NODE_ENV === 'development') { - config.url = `/dev${config.url}` console.log('Making request to ' + config.url) + config.url = `/dev${config.url}` } }) - $axios.onError(error => { + $axios.onError((error) => { const code = parseInt(error.response && error.response.status) const message = error.response ? error.response.data || 'Unknown Error' : 'Unknown Error' console.error('Axios error', code, message) }) -} \ No newline at end of file +} diff --git a/client/store/globals.js b/client/store/globals.js index 8e98c56d6..553301f59 100644 --- a/client/store/globals.js +++ b/client/store/globals.js @@ -98,12 +98,6 @@ export const getters = { const userToken = rootGetters['user/getToken'] const lastUpdate = libraryItem.updatedAt || Date.now() const libraryItemId = libraryItem.libraryItemId || libraryItem.id // Workaround for /users/:id page showing media progress covers - - if (process.env.NODE_ENV !== 'production') { - // Testing - return `http://localhost:3333${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}${raw ? '&raw=1' : ''}` - } - return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}${raw ? '&raw=1' : ''}` }, getLibraryItemCoverSrcById: @@ -112,10 +106,6 @@ export const getters = { const placeholder = `${rootState.routerBasePath}/book_placeholder.jpg` if (!libraryItemId) return placeholder const userToken = rootGetters['user/getToken'] - if (process.env.NODE_ENV !== 'production') { - // Testing - return `http://localhost:3333${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}${raw ? '&raw=1' : ''}${timestamp ? `&ts=${timestamp}` : ''}` - } return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}${raw ? '&raw=1' : ''}${timestamp ? `&ts=${timestamp}` : ''}` }, getIsBatchSelectingMediaItems: (state) => { diff --git a/client/store/libraries.js b/client/store/libraries.js index 81d325774..8964d9f19 100644 --- a/client/store/libraries.js +++ b/client/store/libraries.js @@ -309,9 +309,9 @@ export const mutations = { } // Add publishedDecades - if (mediaMetadata.publishedYear) { + if (mediaMetadata.publishedYear && !isNaN(mediaMetadata.publishedYear)) { const publishedYear = parseInt(mediaMetadata.publishedYear, 10) - const decade = Math.floor(publishedYear / 10) * 10 + const decade = (Math.floor(publishedYear / 10) * 10).toString() if (!state.filterData.publishedDecades.includes(decade)) { state.filterData.publishedDecades.push(decade) state.filterData.publishedDecades.sort((a, b) => a - b) diff --git a/client/strings/de.json b/client/strings/de.json index e8ca3f595..37c48d8b6 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Lösche Medien-Cache", "ButtonQueueAddItem": "Zur Warteschlange hinzufügen", "ButtonQueueRemoveItem": "Aus der Warteschlange entfernen", + "ButtonQuickEmbed": "Schnelles Hinzufügen", "ButtonQuickEmbedMetadata": "Schnelles Hinzufügen von Metadaten", "ButtonQuickMatch": "Schnellabgleich", "ButtonReScan": "Neu scannen", @@ -225,6 +226,9 @@ "LabelAllUsersIncludingGuests": "Alle Benutzer und Gäste", "LabelAlreadyInYourLibrary": "Bereits in der Bibliothek", "LabelAppend": "Anhängen", + "LabelAudioBitrate": "Audiobitrate (z. B. 128 kbit/s)", + "LabelAudioChannels": "Audiokanäle (1 oder 2)", + "LabelAudioCodec": "Audiocodec", "LabelAuthor": "Autor", "LabelAuthorFirstLast": "Autor (Vorname Nachname)", "LabelAuthorLastFirst": "Autor (Nachname, Vorname)", @@ -237,6 +241,7 @@ "LabelAutoRegister": "Automatische Registrierung", "LabelAutoRegisterDescription": "Automatische neue Neutzer anlegen nach dem Registrieren", "LabelBackToUser": "Zurück zum Benutzer", + "LabelBackupAudioFiles": "Audio-Dateien sichern", "LabelBackupLocation": "Backup-Ort", "LabelBackupsEnableAutomaticBackups": "Automatische Sicherung aktivieren", "LabelBackupsEnableAutomaticBackupsHelp": "Backups werden in /metadata/backups gespeichert", @@ -303,6 +308,14 @@ "LabelEmailSettingsTestAddress": "Test-Adresse", "LabelEmbeddedCover": "Eingebettetes Cover", "LabelEnable": "Aktivieren", + "LabelEncodingBackupLocation": "Eine Sicherungskopie der originalen Audiodateien wird gespeichert in:", + "LabelEncodingChaptersNotEmbedded": "Kapitel sind in mehrspurigen Hörbüchern nicht eingebettet.", + "LabelEncodingClearItemCache": "Stelle sicher, dass der Cache regelmäßig geleert wird.", + "LabelEncodingFinishedM4B": "Die fertige M4B-Datei wird im Hörbuch-Ordner unter folgendem Pfad abgelegt:", + "LabelEncodingInfoEmbedded": "Metadaten werden in die Audiodateien innerhalb des Audiobook Ordners eingebunden.", + "LabelEncodingStartedNavigation": "Sobald die Aufgabe gestartet ist, kann die Seite verlassen werden.", + "LabelEncodingTimeWarning": "Kodierung kann bis zu 30 Minuten dauern.", + "LabelEncodingWarningAdvancedSettings": "Achtung: Ändere diese Einstellungen nur, wenn du dich mit ffmpeg Kodierung auskennst.", "LabelEnd": "Ende", "LabelEndOfChapter": "Ende des Kapitels", "LabelEpisode": "Episode", @@ -501,6 +514,7 @@ "LabelSeries": "Serien", "LabelSeriesName": "Serienname", "LabelSeriesProgress": "Serienfortschritt", + "LabelServerLogLevel": "Server Log Level", "LabelServerYearReview": "Server Jahr in Übersicht ({0})", "LabelSetEbookAsPrimary": "Als Hauptbuch setzen", "LabelSetEbookAsSupplementary": "Als Ergänzung setzen", @@ -569,7 +583,7 @@ "LabelStatsMinutesListening": "Gehörte Minuten", "LabelStatsOverallDays": "Gesamte Tage", "LabelStatsOverallHours": "Gesamte Stunden", - "LabelStatsWeekListening": "7-Tage-Durchschnitt", + "LabelStatsWeekListening": "Wochenhördauer", "LabelSubtitle": "Untertitel", "LabelSupportedFileTypes": "Unterstützte Dateitypen", "LabelTag": "Schlagwort", @@ -596,6 +610,7 @@ "LabelTitle": "Titel", "LabelToolsEmbedMetadata": "Metadaten einbetten", "LabelToolsEmbedMetadataDescription": "Bettet die Metadaten einschließlich des Titelbildes und der Kapitel in die Audiodatein ein.", + "LabelToolsM4bEncoder": "M4B Kodierer", "LabelToolsMakeM4b": "M4B-Datei erstellen", "LabelToolsMakeM4bDescription": "Erstellt eine M4B-Datei (Endung \".m4b\") welche mehrere mp3-Dateien in einer einzigen Datei inkl. derer Metadaten (Beschreibung, Titelbild, Kapitel, ...) zusammenfasst. M4B-Datei können darüber hinaus Lesezeichen speichern und mit einem Abspielschutz (Passwort) versehen werden.", "LabelToolsSplitM4b": "M4B in MP3s aufteilen", @@ -621,6 +636,7 @@ "LabelUploaderDragAndDrop": "Ziehen und Ablegen von Dateien oder Ordnern", "LabelUploaderDropFiles": "Dateien löschen", "LabelUploaderItemFetchMetadataHelp": "Automatisches Aktualisieren von Titel, Autor und Serie", + "LabelUseAdvancedOptions": "Nutze Erweiterte Optionen", "LabelUseChapterTrack": "Kapiteldatei verwenden", "LabelUseFullTrack": "Gesamte Datei verwenden", "LabelUser": "Benutzer", @@ -669,6 +685,7 @@ "MessageConfirmDeleteMetadataProvider": "Möchtest du den benutzerdefinierten Metadatenanbieter \"{0}\" wirklich löschen?", "MessageConfirmDeleteNotification": "Möchtest du diese Benachrichtigung wirklich löschen?", "MessageConfirmDeleteSession": "Sitzung wird gelöscht! Bist du dir sicher?", + "MessageConfirmEmbedMetadataInAudioFiles": "Bist du dir sicher, dass die Metadaten in {0} Audiodateien eingebettet werden sollen?", "MessageConfirmForceReScan": "Scanvorgang erzwingen! Bist du dir sicher?", "MessageConfirmMarkAllEpisodesFinished": "Alle Episoden werden als abgeschlossen markiert! Bist du dir sicher?", "MessageConfirmMarkAllEpisodesNotFinished": "Alle Episoden werden als nicht abgeschlossen markiert! Bist du dir sicher?", @@ -746,6 +763,7 @@ "MessageNoLogs": "Keine Protokolle", "MessageNoMediaProgress": "Kein Medienfortschritt", "MessageNoNotifications": "Keine Benachrichtigungen", + "MessageNoPodcastFeed": "Ungültiger Podcast: Kein Feed", "MessageNoPodcastsFound": "Keine Podcasts gefunden", "MessageNoResults": "Keine Ergebnisse", "MessageNoSearchResultsFor": "Keine Suchergebnisse für \"{0}\"", diff --git a/client/strings/es.json b/client/strings/es.json index cd9621bf0..218cf2b87 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Purgar Elementos de Cache", "ButtonQueueAddItem": "Agregar a la Fila", "ButtonQueueRemoveItem": "Remover de la Fila", + "ButtonQuickEmbed": "Inserción rápida", "ButtonQuickEmbedMetadata": "Agregue metadatos rápidamente", "ButtonQuickMatch": "Encontrar Rápido", "ButtonReScan": "Re-Escanear", @@ -225,6 +226,9 @@ "LabelAllUsersIncludingGuests": "Todos los usuarios e invitados", "LabelAlreadyInYourLibrary": "Ya existe en la Biblioteca", "LabelAppend": "Adjuntar", + "LabelAudioBitrate": "Tasa de bits del audio (por ejemplo, 128k)", + "LabelAudioChannels": "Canales de audio (1 o 2)", + "LabelAudioCodec": "Códec de audio", "LabelAuthor": "Autor", "LabelAuthorFirstLast": "Autor (Nombre Apellido)", "LabelAuthorLastFirst": "Autor (Apellido, Nombre)", @@ -237,6 +241,7 @@ "LabelAutoRegister": "Registro automático", "LabelAutoRegisterDescription": "Crear usuarios automáticamente tras iniciar sesión", "LabelBackToUser": "Regresar a Usuario", + "LabelBackupAudioFiles": "Copia de seguridad de archivos de audio", "LabelBackupLocation": "Ubicación del Respaldo", "LabelBackupsEnableAutomaticBackups": "Habilitar Respaldo Automático", "LabelBackupsEnableAutomaticBackupsHelp": "Respaldo Guardado en /metadata/backups", @@ -303,6 +308,15 @@ "LabelEmailSettingsTestAddress": "Probar Dirección", "LabelEmbeddedCover": "Portada Integrada", "LabelEnable": "Habilitar", + "LabelEncodingBackupLocation": "Se guardará una copia de seguridad de tus archivos de audio originales en:", + "LabelEncodingChaptersNotEmbedded": "Los capítulos no se incrustan en los audiolibros multipista.", + "LabelEncodingClearItemCache": "Asegúrese de purgar periódicamente la caché.", + "LabelEncodingFinishedM4B": "El M4B terminado se colocará en su carpeta de audiolibros en:", + "LabelEncodingInfoEmbedded": "Los metadatos se integrarán en las pistas de audio dentro de la carpeta de audiolibros.", + "LabelEncodingStartedNavigation": "Una vez iniciada la tarea, puedes salir de esta página.", + "LabelEncodingTimeWarning": "La codificación puede tardar hasta 30 minutos.", + "LabelEncodingWarningAdvancedSettings": "Advertencia: No actualice esta configuración a menos que esté familiarizado con las opciones de codificación de ffmpeg.", + "LabelEncodingWatcherDisabled": "Si ha desactivado la supervisión de los archivos, deberá volver a escanear este audiolibro más adelante.", "LabelEnd": "Fin", "LabelEndOfChapter": "Fin del capítulo", "LabelEpisode": "Episodio", @@ -465,7 +479,7 @@ "LabelPubDate": "Fecha de publicación", "LabelPublishYear": "Año de publicación", "LabelPublishedDate": "Publicado {0}", - "LabelPublishedDecade": "Una década de publicaciones", + "LabelPublishedDecade": "Década de publicación", "LabelPublishedDecades": "Décadas publicadas", "LabelPublisher": "Editor", "LabelPublishers": "Editores", @@ -501,6 +515,7 @@ "LabelSeries": "Series", "LabelSeriesName": "Nombre de la Serie", "LabelSeriesProgress": "Progreso de la Serie", + "LabelServerLogLevel": "Nivel de registro del servidor", "LabelServerYearReview": "Resumen del año del servidor ({0})", "LabelSetEbookAsPrimary": "Establecer como primario", "LabelSetEbookAsSupplementary": "Establecer como suplementario", @@ -596,6 +611,7 @@ "LabelTitle": "Título", "LabelToolsEmbedMetadata": "Incrustar Metadatos", "LabelToolsEmbedMetadataDescription": "Incrusta metadatos en los archivos de audio, incluyendo la portada y capítulos.", + "LabelToolsM4bEncoder": "Codificador M4B", "LabelToolsMakeM4b": "Hacer Archivo de Audiolibro M4B", "LabelToolsMakeM4bDescription": "Generar archivo de audiolibro .M4B con metadatos, imágenes de portada y capítulos incorporados.", "LabelToolsSplitM4b": "Dividir M4B en Archivos MP3", @@ -621,6 +637,7 @@ "LabelUploaderDragAndDrop": "Arrastre y suelte archivos o carpetas", "LabelUploaderDropFiles": "Suelte los Archivos", "LabelUploaderItemFetchMetadataHelp": "Buscar título, autor y series automáticamente", + "LabelUseAdvancedOptions": "Usar opciones avanzadas", "LabelUseChapterTrack": "Usar pista por capitulo", "LabelUseFullTrack": "Usar pista completa", "LabelUser": "Usuario", @@ -669,6 +686,7 @@ "MessageConfirmDeleteMetadataProvider": "¿Estás seguro de que deseas eliminar el proveedor de metadatos personalizado \"{0}\"?", "MessageConfirmDeleteNotification": "¿Estás seguro de que deseas eliminar esta notificación?", "MessageConfirmDeleteSession": "¿Está seguro de que desea eliminar esta sesión?", + "MessageConfirmEmbedMetadataInAudioFiles": "¿Está seguro de que desea incrustar metadatos en {0} archivos de audio?", "MessageConfirmForceReScan": "¿Está seguro de que desea forzar un re-escaneo?", "MessageConfirmMarkAllEpisodesFinished": "¿Está seguro de que desea marcar todos los episodios como terminados?", "MessageConfirmMarkAllEpisodesNotFinished": "¿Está seguro de que desea marcar todos los episodios como no terminados?", @@ -702,6 +720,7 @@ "MessageDragFilesIntoTrackOrder": "Arrastra los archivos al orden correcto de las pistas", "MessageEmbedFailed": "¡Error al insertar!", "MessageEmbedFinished": "Incrustación Terminada!", + "MessageEmbedQueue": "En cola para incrustar metadatos ({0} en cola)", "MessageEpisodesQueuedForDownload": "{0} Episodio(s) en cola para descargar", "MessageEreaderDevices": "Para garantizar la entrega de libros electrónicos, es posible que tenga que agregar la dirección de correo electrónico anterior como remitente válido para cada dispositivo enumerado a continuación.", "MessageFeedURLWillBe": "URL de la fuente será {0}", @@ -746,6 +765,7 @@ "MessageNoLogs": "No hay logs", "MessageNoMediaProgress": "Multimedia sin Progreso", "MessageNoNotifications": "Ninguna Notificación", + "MessageNoPodcastFeed": "Podcast no válido: Sin feed", "MessageNoPodcastsFound": "Ningún podcast encontrado", "MessageNoResults": "Sin Resultados", "MessageNoSearchResultsFor": "No hay resultados para la búsqueda \"{0}\"", @@ -762,6 +782,9 @@ "MessagePlaylistCreateFromCollection": "Crear una lista de reproducción a partir de una colección", "MessagePleaseWait": "Por favor, espera...", "MessagePodcastHasNoRSSFeedForMatching": "El podcast no tiene una URL de fuente RSS que pueda usar", + "MessagePodcastSearchField": "Introduzca el término de búsqueda o la URL de la fuente RSS", + "MessageQuickEmbedInProgress": "Integración rápida en proceso", + "MessageQuickEmbedQueue": "En cola para inserción rápida ({0} en cola)", "MessageQuickMatchDescription": "Rellenar detalles de elementos vacíos y portada con los primeros resultados de '{0}'. No sobrescribe los detalles a menos que la opción \"Preferir Metadatos Encontrados\" del servidor esté habilitada.", "MessageRemoveChapter": "Remover capítulos", "MessageRemoveEpisodes": "Remover {0} episodio(s)", @@ -804,6 +827,9 @@ "MessageTaskOpmlImportFeedPodcastExists": "Podcast ya existe en la ruta", "MessageTaskOpmlImportFeedPodcastFailed": "Error al crear podcast", "MessageTaskOpmlImportFinished": "Añadido {0} podcasts", + "MessageTaskOpmlParseFailed": "No se pudo analizar el archivo OPML", + "MessageTaskOpmlParseFastFail": "No se encontró la etiqueta del archivo OPML no válido O no se encontró la etiqueta ", + "MessageTaskOpmlParseNoneFound": "No se encontraron fuentes en el archivo OPML", "MessageTaskScanItemsAdded": "{0} añadido", "MessageTaskScanItemsMissing": "Falta {0}", "MessageTaskScanItemsUpdated": "{0} actualizado", @@ -828,6 +854,10 @@ "NoteUploaderFoldersWithMediaFiles": "Las carpetas con archivos multimedia se manejarán como elementos separados en la biblioteca.", "NoteUploaderOnlyAudioFiles": "Si sube solamente archivos de audio, cada archivo se manejará como un audiolibro por separado.", "NoteUploaderUnsupportedFiles": "Se ignorarán los archivos no soportados. Al elegir o arrastrar una carpeta, los archivos que no estén dentro de una subcarpeta serán ignorados.", + "NotificationOnBackupCompletedDescription": "Se activa cuando se completa una copia de seguridad", + "NotificationOnBackupFailedDescription": "Se activa cuando falla una copia de seguridad", + "NotificationOnEpisodeDownloadedDescription": "Se activa cuando se descarga automáticamente un episodio de un podcast", + "NotificationOnTestDescription": "Evento para probar el sistema de notificaciones", "PlaceholderNewCollection": "Nuevo nombre de la colección", "PlaceholderNewFolderPath": "Nueva ruta de carpeta", "PlaceholderNewPlaylist": "Nuevo nombre de la lista de reproducción", diff --git a/client/strings/fr.json b/client/strings/fr.json index 064597b3a..3674acc30 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Purger le cache des éléments", "ButtonQueueAddItem": "Ajouter à la liste de lecture", "ButtonQueueRemoveItem": "Supprimer de la liste de lecture", + "ButtonQuickEmbed": "Intégration rapide", "ButtonQuickEmbedMetadata": "Ajouter rapidement des métadonnées", "ButtonQuickMatch": "Recherche rapide", "ButtonReScan": "Nouvelle analyse", @@ -225,6 +226,9 @@ "LabelAllUsersIncludingGuests": "Tous les utilisateurs, y compris les invités", "LabelAlreadyInYourLibrary": "Déjà dans la bibliothèque", "LabelAppend": "Ajouter", + "LabelAudioBitrate": "Débit audio (par exemple 128k)", + "LabelAudioChannels": "Canaux audio (1 ou 2)", + "LabelAudioCodec": "Codec audio", "LabelAuthor": "Auteur", "LabelAuthorFirstLast": "Auteur (Prénom Nom)", "LabelAuthorLastFirst": "Auteur (Nom, Prénom)", @@ -237,6 +241,7 @@ "LabelAutoRegister": "Enregistrement automatique", "LabelAutoRegisterDescription": "Créer automatiquement de nouveaux utilisateurs après la connexion", "LabelBackToUser": "Retour à l’utilisateur", + "LabelBackupAudioFiles": "Sauvegarder les fichiers audio", "LabelBackupLocation": "Emplacement de la sauvegarde", "LabelBackupsEnableAutomaticBackups": "Activer les sauvegardes automatiques", "LabelBackupsEnableAutomaticBackupsHelp": "Sauvegardes enregistrées dans /metadata/backups", @@ -303,6 +308,15 @@ "LabelEmailSettingsTestAddress": "Adresse de test", "LabelEmbeddedCover": "Couverture du livre intégrée", "LabelEnable": "Activer", + "LabelEncodingBackupLocation": "Une sauvegarde de vos fichiers audio originaux sera stockée dans :", + "LabelEncodingChaptersNotEmbedded": "Les chapitres ne sont pas intégrés dans les livres audio multipistes.", + "LabelEncodingClearItemCache": "Assurez-vous de purger périodiquement le cache des éléments.", + "LabelEncodingFinishedM4B": "Le fichier M4B terminé sera placé dans votre dossier de livre audio à l'adresse suivante :", + "LabelEncodingInfoEmbedded": "Les métadonnées seront intégrées dans les pistes audio de votre dossier de livre audio.", + "LabelEncodingStartedNavigation": "Une fois la tâche démarrée, vous pouvez quitter cette page.", + "LabelEncodingTimeWarning": "L’encodage peut prendre jusqu’à 30 minutes.", + "LabelEncodingWarningAdvancedSettings": "Avertissement : ne mettez pas à jour ces paramètres à moins que vous ne soyez familier avec les options d'encodage « ffmpeg ».", + "LabelEncodingWatcherDisabled": "Si l'observateur est désactivé, vous devrez ensuite réanalyser ce livre audio.", "LabelEnd": "Fin", "LabelEndOfChapter": "Fin du chapitre", "LabelEpisode": "Épisode", @@ -501,6 +515,7 @@ "LabelSeries": "Séries", "LabelSeriesName": "Nom de la série", "LabelSeriesProgress": "Progression de séries", + "LabelServerLogLevel": "Niveau de journalisation du serveur", "LabelServerYearReview": "Bilan de l’année du serveur ({0})", "LabelSetEbookAsPrimary": "Définir comme principale", "LabelSetEbookAsSupplementary": "Définir comme supplémentaire", @@ -596,6 +611,7 @@ "LabelTitle": "Titre", "LabelToolsEmbedMetadata": "Métadonnées intégrées", "LabelToolsEmbedMetadataDescription": "Intègre les métadonnées au fichier audio avec la couverture et les chapitres.", + "LabelToolsM4bEncoder": "Encodeur M4B", "LabelToolsMakeM4b": "Créer un fichier livre audio M4B", "LabelToolsMakeM4bDescription": "Générer un fichier de livre audio .M4B avec des métadonnées intégrées, une image de couverture et des chapitres.", "LabelToolsSplitM4b": "Scinde le fichier M4B en fichiers MP3", @@ -621,6 +637,7 @@ "LabelUploaderDragAndDrop": "Glisser et déposer des fichiers ou dossiers", "LabelUploaderDropFiles": "Déposer des fichiers", "LabelUploaderItemFetchMetadataHelp": "Récupérer automatiquement le titre, l’auteur et la série", + "LabelUseAdvancedOptions": "Utiliser les options avancées", "LabelUseChapterTrack": "Utiliser la piste du chapitre", "LabelUseFullTrack": "Utiliser la piste complète", "LabelUser": "Utilisateur", @@ -669,6 +686,7 @@ "MessageConfirmDeleteMetadataProvider": "Êtes-vous sûr·e de vouloir supprimer le fournisseur de métadonnées personnalisées « {0} » ?", "MessageConfirmDeleteNotification": "Êtes-vous sûr·e de vouloir supprimer cette notification ?", "MessageConfirmDeleteSession": "Êtes-vous sûr·e de vouloir supprimer cette session ?", + "MessageConfirmEmbedMetadataInAudioFiles": "Souhaitez-vous vraiment intégrer des métadonnées dans {0} fichiers audio ?", "MessageConfirmForceReScan": "Êtes-vous sûr·e de vouloir lancer une analyse forcée ?", "MessageConfirmMarkAllEpisodesFinished": "Êtes-vous sûr·e de marquer tous les épisodes comme terminés ?", "MessageConfirmMarkAllEpisodesNotFinished": "Êtes-vous sûr·e de vouloir marquer tous les épisodes comme non terminés ?", @@ -702,6 +720,7 @@ "MessageDragFilesIntoTrackOrder": "Faites glisser les fichiers dans l’ordre correct des pistes", "MessageEmbedFailed": "Échec de l’intégration !", "MessageEmbedFinished": "Intégration terminée !", + "MessageEmbedQueue": "En file d'attente pour l'intégration des métadonnées ({0} dans la file d'attente)", "MessageEpisodesQueuedForDownload": "{0} épisode(s) mis en file pour téléchargement", "MessageEreaderDevices": "Pour garantir l’envoi des livres électroniques, vous devrez peut-être ajouter le courriel ci-dessus comme expéditeur valide pour chaque appareil répertorié ci-dessous.", "MessageFeedURLWillBe": "L’URL du flux sera {0}", @@ -746,6 +765,7 @@ "MessageNoLogs": "Aucun journaux", "MessageNoMediaProgress": "Aucun média en cours", "MessageNoNotifications": "Aucune notification", + "MessageNoPodcastFeed": "Podcast invalide : pas de flux", "MessageNoPodcastsFound": "Aucun podcast trouvé", "MessageNoResults": "Aucun résultat", "MessageNoSearchResultsFor": "Aucun résultat pour la recherche « {0} »", @@ -762,6 +782,9 @@ "MessagePlaylistCreateFromCollection": "Créer une liste de lecture depuis la collection", "MessagePleaseWait": "Merci de patienter…", "MessagePodcastHasNoRSSFeedForMatching": "Le Podcast n’a pas d’URL de flux RSS à utiliser pour la correspondance", + "MessagePodcastSearchField": "Saisissez le terme de recherche ou l'URL du flux RSS", + "MessageQuickEmbedInProgress": "Intégration rapide en cours", + "MessageQuickEmbedQueue": "En file d'attente pour une intégration rapide ({0} dans la file d'attente)", "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é.", "MessageRemoveChapter": "Supprimer le chapitre", "MessageRemoveEpisodes": "Suppression de {0} épisode(s)", @@ -804,6 +827,9 @@ "MessageTaskOpmlImportFeedPodcastExists": "Le podcast existe déjà à cet emplacement", "MessageTaskOpmlImportFeedPodcastFailed": "Échec de la création du podcast", "MessageTaskOpmlImportFinished": "Ajout de {0} podcasts", + "MessageTaskOpmlParseFailed": "Échec de l'analyse du fichier OPML", + "MessageTaskOpmlParseFastFail": "Balise de fichier OPML non valide introuvable OU une balise n’a pas été trouvée", + "MessageTaskOpmlParseNoneFound": "Aucun flux trouvé dans le fichier OPML", "MessageTaskScanItemsAdded": "{0} ajouté", "MessageTaskScanItemsMissing": "{0} manquant", "MessageTaskScanItemsUpdated": "{0} mis à jour", @@ -828,6 +854,10 @@ "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éversez 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.", + "NotificationOnBackupCompletedDescription": "Déclenché lorsqu’une sauvegarde est terminée", + "NotificationOnBackupFailedDescription": "Déclenché lorsqu'une sauvegarde échoue", + "NotificationOnEpisodeDownloadedDescription": "Déclenché lorsqu’un épisode de podcast est téléchargé automatiquement", + "NotificationOnTestDescription": "Événement pour tester le système de notification", "PlaceholderNewCollection": "Nom de la nouvelle collection", "PlaceholderNewFolderPath": "Nouveau chemin de dossier", "PlaceholderNewPlaylist": "Nouveau nom de liste de lecture", diff --git a/client/strings/hr.json b/client/strings/hr.json index 1ae07981e..fd7abd8f9 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Isprazni predmemoriju stavki", "ButtonQueueAddItem": "Dodaj u red", "ButtonQueueRemoveItem": "Ukloni iz reda", + "ButtonQuickEmbed": "Brzo ugrađivanje", "ButtonQuickEmbedMetadata": "Brzo ugrađivanje meta-podataka", "ButtonQuickMatch": "Brzo prepoznavanje", "ButtonReScan": "Ponovno skeniraj", @@ -81,7 +82,7 @@ "ButtonRemoveSeriesFromContinueSeries": "Ukloni seriju iz Nastavi seriju", "ButtonReset": "Poništi", "ButtonResetToDefault": "Vrati na početne postavke", - "ButtonRestore": "Povrati", + "ButtonRestore": "Vraćanje", "ButtonSave": "Spremi", "ButtonSaveAndClose": "Spremi i zatvori", "ButtonSaveTracklist": "Spremi popis zvučnih zapisa", @@ -225,6 +226,9 @@ "LabelAllUsersIncludingGuests": "Svi korisnici uključujući i goste", "LabelAlreadyInYourLibrary": "Već u vašoj knjižnici", "LabelAppend": "Pridodaj", + "LabelAudioBitrate": "Kvaliteta zvučnog zapisa (npr. 128k)", + "LabelAudioChannels": "Broj zvučnih kanala (1 ili 2)", + "LabelAudioCodec": "Zvučni kodek", "LabelAuthor": "Autor", "LabelAuthorFirstLast": "Autor (Ime Prezime)", "LabelAuthorLastFirst": "Autor (Prezime, Ime)", @@ -237,8 +241,9 @@ "LabelAutoRegister": "Automatska registracija", "LabelAutoRegisterDescription": "Automatski izradi nove korisnike nakon prijave", "LabelBackToUser": "Povratak na korisnika", + "LabelBackupAudioFiles": "Sigurnosno kopiranje zvučnih datoteka", "LabelBackupLocation": "Lokacija sigurnosnih kopija", - "LabelBackupsEnableAutomaticBackups": "Uključi automatsku izradu sigurnosnih kopija", + "LabelBackupsEnableAutomaticBackups": "Omogući automatsku izradu sigurnosnih kopija", "LabelBackupsEnableAutomaticBackupsHelp": "Sigurnosne kopije spremaju se u /metadata/backups", "LabelBackupsMaxBackupSize": "Maksimalna veličina sigurnosne kopije (u GB) (0 za neograničeno)", "LabelBackupsMaxBackupSizeHelp": "U svrhu sprečavanja izrade krive konfiguracije, sigurnosne kopije neće se izraditi ako su veće od zadane veličine.", @@ -303,6 +308,15 @@ "LabelEmailSettingsTestAddress": "Probna adresa", "LabelEmbeddedCover": "Ugrađena naslovnica", "LabelEnable": "Omogući", + "LabelEncodingBackupLocation": "Sigurnosna kopija vaših izvornih zvučnih datoteka čuvat će se u mapi:", + "LabelEncodingChaptersNotEmbedded": "Poglavlja se ne ugrađuju u zvučne knjige koje se sastoje od više zvučnih zapisa.", + "LabelEncodingClearItemCache": "Svakako redovito praznite predmemoriju stavki.", + "LabelEncodingFinishedM4B": "Stvorene M4B datoteke spremit će se u vašu mapu sa zvučnim knjigama:", + "LabelEncodingInfoEmbedded": "Meta-podatci će se ugraditi u zvučne zapise u vašoj mapi sa zvučnim knjigama.", + "LabelEncodingStartedNavigation": "Nakon pokretanja zadatka možete napustiti ovu stranicu.", + "LabelEncodingTimeWarning": "Kodiranje može potrajati do 30 minuta.", + "LabelEncodingWarningAdvancedSettings": "Pažnja: Ne mijenjajte ove postavke ako niste temeljito upoznati s opcijama kodiranja u ffmpegu.", + "LabelEncodingWatcherDisabled": "Ako vam je onemogućeno praćenje mape, ovu ćete zvučnu knjigu poslije morati ponovno skenirati.", "LabelEnd": "Kraj", "LabelEndOfChapter": "Kraj poglavlja", "LabelEpisode": "Nastavak", @@ -413,7 +427,7 @@ "LabelNewPassword": "Nova zaporka", "LabelNewestAuthors": "Najnoviji autori", "LabelNewestEpisodes": "Najnovije epizode", - "LabelNextBackupDate": "Sljedeće izrada sigurnosne kopije", + "LabelNextBackupDate": "Sljedeća izrada sigurnosne kopije", "LabelNextScheduledRun": "Sljedeće zakazano izvođenje", "LabelNoCustomMetadataProviders": "Nema prilagođenih pružatelja meta-podataka", "LabelNoEpisodesSelected": "Nema odabranih nastavaka", @@ -441,7 +455,7 @@ "LabelPermanent": "Trajno", "LabelPermissionsAccessAllLibraries": "Ima pristup svim knjižnicama", "LabelPermissionsAccessAllTags": "Ima pristup svim oznakama", - "LabelPermissionsAccessExplicitContent": "Ima pristup eksplicitnom sadržzaju", + "LabelPermissionsAccessExplicitContent": "Ima pristup eksplicitnom sadržaju", "LabelPermissionsDelete": "Smije brisati", "LabelPermissionsDownload": "Smije preuzimati", "LabelPermissionsUpdate": "Smije ažurirati", @@ -501,6 +515,7 @@ "LabelSeries": "Serijal/a", "LabelSeriesName": "Ime serijala", "LabelSeriesProgress": "Napredak u serijalu", + "LabelServerLogLevel": "Razina zapisa poslužitelja", "LabelServerYearReview": "Godišnji pregled poslužitelja ({0})", "LabelSetEbookAsPrimary": "Postavi kao primarno", "LabelSetEbookAsSupplementary": "Postavi kao dopunsko", @@ -596,6 +611,7 @@ "LabelTitle": "Naslov", "LabelToolsEmbedMetadata": "Ugradi meta-podatke", "LabelToolsEmbedMetadataDescription": "Ugradi meta-podatke u zvučne datoteke zajedno s naslovnicom i poglavljima.", + "LabelToolsM4bEncoder": "M4B kodiranje", "LabelToolsMakeM4b": "Stvori M4B datoteku audioknjige", "LabelToolsMakeM4bDescription": "Izrađuje zvučnu knjigu u .M4B formatu s ugrađenim meta-podatcima, naslovnicom i poglavljima.", "LabelToolsSplitM4b": "Podijeli M4B datoteke u MP3 datoteke", @@ -621,6 +637,7 @@ "LabelUploaderDragAndDrop": "Pritisni i prevuci datoteke ili mape", "LabelUploaderDropFiles": "Ispusti datoteke", "LabelUploaderItemFetchMetadataHelp": "Automatski dohvati naslov, autora i serijal", + "LabelUseAdvancedOptions": "Koristi se naprednim opcijama", "LabelUseChapterTrack": "Koristi zvučni zapis poglavlja", "LabelUseFullTrack": "Koristi cijeli zvučni zapis", "LabelUser": "Korisnik", @@ -643,7 +660,7 @@ "LabelYourProgress": "Vaš napredak", "MessageAddToPlayerQueue": "Dodaj u redoslijed izvođenja", "MessageAppriseDescription": "Da biste se koristili ovom značajkom, treba vam instanca Apprise API-ja ili API koji može rukovati istom vrstom zahtjeva.
The Adresa Apprise API-ja treba biti puna URL putanja za slanje obavijesti, npr. ako vam se API instanca poslužuje na adresi http://192.168.1.1:8337 trebate upisati http://192.168.1.1:8337/notify.", - "MessageBackupsDescription": "Backups uključuju korisnike, korisnikov napredak, detalje stavki iz biblioteke, postavke server i slike iz /metadata/items & /metadata/authors. Backups ne uključuju nijedne datoteke koje su u folderima biblioteke.", + "MessageBackupsDescription": "Sigurnosne kopije sadrže korisnike, korisnikov napredak medija, pojedinosti knjižničke građe, postavke poslužitelja i slike koje se spremaju u /metadata/items & /metadata/authors. Sigurnosne kopije ne sadrže niti jednu datoteku iz mapa knjižnice.", "MessageBackupsLocationEditNote": "Napomena: Uređivanje lokacije za sigurnosne kopije ne premješta ili mijenja postojeće sigurnosne kopije", "MessageBackupsLocationNoEditNote": "Napomena: Lokacija za sigurnosne kopije zadana je kroz varijablu okoline i ovdje se ne može izmijeniti.", "MessageBackupsLocationPathEmpty": "Putanja do lokacije za sigurnosne kopije ne može ostati prazna", @@ -669,6 +686,7 @@ "MessageConfirmDeleteMetadataProvider": "Sigurno želite izbrisati prilagođenog pružatelja meta-podataka \"{0}\"?", "MessageConfirmDeleteNotification": "Sigurno želite izbrisati ovu obavijest?", "MessageConfirmDeleteSession": "Sigurno želite obrisati ovu sesiju?", + "MessageConfirmEmbedMetadataInAudioFiles": "Sigurno želite ugraditi meta-podatke u {0} zvučnih datoteka?", "MessageConfirmForceReScan": "Sigurno želite ponovno pokrenuti skeniranje?", "MessageConfirmMarkAllEpisodesFinished": "Sigurno želite označiti sve nastavke dovršenima?", "MessageConfirmMarkAllEpisodesNotFinished": "Sigurno želite označiti sve nastavke nedovršenima?", @@ -702,6 +720,7 @@ "MessageDragFilesIntoTrackOrder": "Ispravi redoslijed zapisa prevlačenje datoteka", "MessageEmbedFailed": "Ugrađivanje nije uspjelo!", "MessageEmbedFinished": "Ugrađivanje je dovršeno!", + "MessageEmbedQueue": "Ugrađivanje meta-podataka dodano u red obrade ({0} u redu)", "MessageEpisodesQueuedForDownload": "{0} nastavak(a) u redu za preuzimanje", "MessageEreaderDevices": "Da biste osigurali isporuku e-knjiga, možda ćete morati gornju adresu e-pošte dodati kao dopuštenog pošiljatelja za svaki od donjih uređaja.", "MessageFeedURLWillBe": "URL izvora bit će {0}", @@ -746,6 +765,7 @@ "MessageNoLogs": "Nema zapisnika", "MessageNoMediaProgress": "Nema podataka o započetim medijima", "MessageNoNotifications": "Nema obavijesti", + "MessageNoPodcastFeed": "Neispravan podcast: Nema izvora", "MessageNoPodcastsFound": "Nije pronađen niti jedan podcast", "MessageNoResults": "Nema rezultata", "MessageNoSearchResultsFor": "Nema rezultata pretrage za \"{0}\"", @@ -762,6 +782,9 @@ "MessagePlaylistCreateFromCollection": "Stvori popis za izvođenje od zbirke", "MessagePleaseWait": "Molimo pričekajte...", "MessagePodcastHasNoRSSFeedForMatching": "Podcast nema adresu RSS izvora za prepoznavanje", + "MessagePodcastSearchField": "Unesite upit za pretragu ili URL RSS izvora", + "MessageQuickEmbedInProgress": "Brzo ugrađivanje u tijeku", + "MessageQuickEmbedQueue": "Dodano u red za brzo ugrađivanje ({0} u redu izvođenja)", "MessageQuickMatchDescription": "Popuni pojedinosti i naslovnice koji nedostaju prvim pronađenim rezultatom za '{0}'. Ne prepisuje podatke osim ako ne uključite mogućnost 'Daj prednost meta-podatcima prepoznatih stavki'.", "MessageRemoveChapter": "Ukloni poglavlje", "MessageRemoveEpisodes": "Ukloni {0} nastavaka", @@ -804,6 +827,9 @@ "MessageTaskOpmlImportFeedPodcastExists": "Podcast već postoji u putanji", "MessageTaskOpmlImportFeedPodcastFailed": "Stvaranje podcasta nije uspjelo", "MessageTaskOpmlImportFinished": "Dodano {0} podcasta", + "MessageTaskOpmlParseFailed": "Raščlanjivanje OPML datoteke nije uspjelo", + "MessageTaskOpmlParseFastFail": "Neispravna OPML datoteka, oznaka nije pronađena ILI oznaka nije pronađena", + "MessageTaskOpmlParseNoneFound": "U OPML datoteci nisu pronađeni izvori", "MessageTaskScanItemsAdded": "{0} dodan(o)", "MessageTaskScanItemsMissing": "{0} nedostaje", "MessageTaskScanItemsUpdated": "{0} ažurirano", @@ -828,6 +854,10 @@ "NoteUploaderFoldersWithMediaFiles": "Mape s medijskim datotekama smatrat će se zasebnim stavkama knjižnice.", "NoteUploaderOnlyAudioFiles": "Ako učitavate samo zvučne datoteke svaka će se zvučna datoteka uvesti kao zasebna zvučna knjiga.", "NoteUploaderUnsupportedFiles": "Nepodržane vrste datoteka zanemaruju se. Kada odabirete datoteke ili ispuštate mapu, sve datoteke koje nisu u mapi stavke zanemarit će se.", + "NotificationOnBackupCompletedDescription": "Pokreće se po završetku sigurnosnog kopiranja", + "NotificationOnBackupFailedDescription": "Pokreće se kada sigurnosno kopiranje ne uspije", + "NotificationOnEpisodeDownloadedDescription": "Pokreće se kada se nastavak podcasta automatski preuzme", + "NotificationOnTestDescription": "Događaj za testiranje sustava obavijesti", "PlaceholderNewCollection": "Ime nove zbirke", "PlaceholderNewFolderPath": "Nova putanja mape", "PlaceholderNewPlaylist": "Naziv novog popisa za izvođenje", diff --git a/client/strings/it.json b/client/strings/it.json index 3078706ad..1450b972c 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Elimina la Cache selezionata", "ButtonQueueAddItem": "Aggiungi alla Coda", "ButtonQueueRemoveItem": "Rimuovi dalla Coda", + "ButtonQuickEmbed": "Quick Embed", "ButtonQuickEmbedMetadata": "Incorporamento rapido Metadati", "ButtonQuickMatch": "Controlla Metadata Auto", "ButtonReScan": "Ri-scansiona", @@ -225,6 +226,9 @@ "LabelAllUsersIncludingGuests": "Tutti gli Utenti Inclusi gli ospiti", "LabelAlreadyInYourLibrary": "Già esistente nella libreria", "LabelAppend": "Appese", + "LabelAudioBitrate": "Audio Bitrate (es. 128k)", + "LabelAudioChannels": "Canali Audio (1 o 2)", + "LabelAudioCodec": "Codec Audio", "LabelAuthor": "Autore", "LabelAuthorFirstLast": "Autore (Per Nome)", "LabelAuthorLastFirst": "Autori (Per Cognome)", @@ -237,6 +241,7 @@ "LabelAutoRegister": "Auto Registrazione", "LabelAutoRegisterDescription": "Crea automaticamente nuovi utenti dopo aver effettuato l'accesso", "LabelBackToUser": "Torna a Utenti", + "LabelBackupAudioFiles": "Backup file Audio", "LabelBackupLocation": "Percorso del Backup", "LabelBackupsEnableAutomaticBackups": "Abilita backup Automatico", "LabelBackupsEnableAutomaticBackupsHelp": "I Backup saranno salvati in /metadata/backups", @@ -303,6 +308,15 @@ "LabelEmailSettingsTestAddress": "Indirizzo di test", "LabelEmbeddedCover": "Cover Integrata", "LabelEnable": "Abilita", + "LabelEncodingBackupLocation": "il backup dei file audio verrà archiviato in:", + "LabelEncodingChaptersNotEmbedded": "Negli audiolibri multitraccia i capitoli non sono incorporati.", + "LabelEncodingClearItemCache": "Assicurati di svuotare periodicamente la cache degli oggetti.", + "LabelEncodingFinishedM4B": "L'M4B completato verrà inserito nella cartella:", + "LabelEncodingInfoEmbedded": "I metadati verranno incorporati nelle tracce audio all'interno della cartella dell'audiolibro.", + "LabelEncodingStartedNavigation": "Una volta avviata l'attività, è possibile uscire da questa pagina.", + "LabelEncodingTimeWarning": "La codifica può richiedere fino a 30 minuti.", + "LabelEncodingWarningAdvancedSettings": "Attenzione: non aggiornare queste impostazioni se non hai familiarità con le opzioni di codifica ffmpeg.", + "LabelEncodingWatcherDisabled": "Se hai disabilitato l'opzione Watcher, dovrai eseguire nuovamente la scansione dell'audiolibro in seguito.", "LabelEnd": "Fine", "LabelEndOfChapter": "Fine Capitolo", "LabelEpisode": "Episodio", @@ -501,6 +515,7 @@ "LabelSeries": "Serie", "LabelSeriesName": "Nome Serie", "LabelSeriesProgress": "Cominciato", + "LabelServerLogLevel": "Server Log Level", "LabelServerYearReview": "Anno del server in sintesi({0})", "LabelSetEbookAsPrimary": "Imposta come primario", "LabelSetEbookAsSupplementary": "Imposta come suplementare", @@ -596,6 +611,7 @@ "LabelTitle": "Titolo", "LabelToolsEmbedMetadata": "Incorpora Metadata", "LabelToolsEmbedMetadataDescription": "Incorpora i metadati nei file audio, inclusi l'immagine di copertina e i capitoli.", + "LabelToolsM4bEncoder": "M4B Encoder", "LabelToolsMakeM4b": "Crea un file M4B", "LabelToolsMakeM4bDescription": "Genera un file audiolibro M4B con metadati incorporati, immagine di copertina e capitoli.", "LabelToolsSplitM4b": "Converti M4B in MP3", @@ -621,6 +637,7 @@ "LabelUploaderDragAndDrop": "Drag & drop file o Cartelle", "LabelUploaderDropFiles": "Elimina file", "LabelUploaderItemFetchMetadataHelp": "Recupera automaticamente titolo, autore e serie", + "LabelUseAdvancedOptions": "Usa le opzioni avanzate", "LabelUseChapterTrack": "Usa il Capitolo della Traccia", "LabelUseFullTrack": "Usa la traccia totale", "LabelUser": "Utente", @@ -669,6 +686,7 @@ "MessageConfirmDeleteMetadataProvider": "Sei sicuro/sicura di voler eliminare il fornitore di metadati personalizzato {0}?", "MessageConfirmDeleteNotification": "Sei sicuro/sicura di voler eliminare questa notifica?", "MessageConfirmDeleteSession": "Sei sicuro di voler eliminare questa sessione?", + "MessageConfirmEmbedMetadataInAudioFiles": "Sei sicuro di voler incorporare i metadati nei file audio {0}?", "MessageConfirmForceReScan": "Sei sicuro di voler forzare una nuova scansione?", "MessageConfirmMarkAllEpisodesFinished": "Sei sicuro di voler contrassegnare tutti gli episodi come finiti?", "MessageConfirmMarkAllEpisodesNotFinished": "Sei sicuro di voler contrassegnare tutti gli episodi come non completati?", @@ -702,6 +720,7 @@ "MessageDragFilesIntoTrackOrder": "Trascina i file nell'ordine di traccia corretto", "MessageEmbedFailed": "Incorporamento non riuscito!", "MessageEmbedFinished": "Incorporamento finito!", + "MessageEmbedQueue": "In coda per l'incorporamento dei metadati ({0} in coda)", "MessageEpisodesQueuedForDownload": "{0} episodio(i) in coda per lo scaricamento", "MessageEreaderDevices": "Per garantire la consegna dei libri digitali, potrebbe essere necessario aggiungere l'indirizzo e-mail sopra indicato come mittente valido per ciascun dispositivo elencato di seguito.", "MessageFeedURLWillBe": "l’URL del flusso sarà {0}", @@ -746,6 +765,7 @@ "MessageNoLogs": "Nessun Logs", "MessageNoMediaProgress": "Nessun progresso multimediale", "MessageNoNotifications": "Nessuna notifica", + "MessageNoPodcastFeed": "Podcast non valido: nessun feed", "MessageNoPodcastsFound": "Nessun podcast trovato", "MessageNoResults": "Nessun Risultato", "MessageNoSearchResultsFor": "Nessun risultato per \"{0}\"", @@ -762,6 +782,9 @@ "MessagePlaylistCreateFromCollection": "Crea playlist da una Raccolta", "MessagePleaseWait": "Attendi...", "MessagePodcastHasNoRSSFeedForMatching": "Podcast non ha l'URL del feed RSS da utilizzare per il match", + "MessagePodcastSearchField": "Inserisci il termine di ricerca o l'URL del feed RSS", + "MessageQuickEmbedInProgress": "Incorporamento rapido in corso", + "MessageQuickEmbedQueue": "In coda per incorporamento rapido ({0} in coda)", "MessageQuickMatchDescription": "Compila i dettagli dell'articolo vuoto e copri con il risultato della prima corrispondenza di '{0}'. Non sovrascrive i dettagli a meno che non sia abilitata l'impostazione del server \"Preferisci metadati corrispondenti\".", "MessageRemoveChapter": "Rimuovi Capitolo", "MessageRemoveEpisodes": "rimuovi {0} episodio(i)", @@ -804,6 +827,9 @@ "MessageTaskOpmlImportFeedPodcastExists": "Il podcast esiste già nel percorso", "MessageTaskOpmlImportFeedPodcastFailed": "Errore durante la creazione del podcast", "MessageTaskOpmlImportFinished": "{0} podcast aggiunti", + "MessageTaskOpmlParseFailed": "Impossibile analizzare il file OPML", + "MessageTaskOpmlParseFastFail": "File OPML non valido. Tag non trovato OPPURE non è stato trovato un tag ", + "MessageTaskOpmlParseNoneFound": "Nessun feed trovato nel file OPML", "MessageTaskScanItemsAdded": "{0} aggiunti", "MessageTaskScanItemsMissing": "{0} mancanti", "MessageTaskScanItemsUpdated": "{0} aggiornati", @@ -828,6 +854,10 @@ "NoteUploaderFoldersWithMediaFiles": "Le cartelle con file multimediali verranno gestite come elementi della libreria separati.", "NoteUploaderOnlyAudioFiles": "Se carichi solo file audio, ogni file audio verrà gestito come un audiolibro separato.", "NoteUploaderUnsupportedFiles": "I file non supportati vengono ignorati. Quando si sceglie o si elimina una cartella, gli altri file che non si trovano in una cartella di elementi vengono ignorati.", + "NotificationOnBackupCompletedDescription": "Attivato al completamento di un backup", + "NotificationOnBackupFailedDescription": "Attivato quando un backup fallisce", + "NotificationOnEpisodeDownloadedDescription": "Attivato quando un episodio di podcast viene scaricato automaticamente", + "NotificationOnTestDescription": "test il sistema di notifica", "PlaceholderNewCollection": "Nome Nuova Raccolta", "PlaceholderNewFolderPath": "Nuovo Percorso Cartella", "PlaceholderNewPlaylist": "Nome nuova playlist", @@ -922,7 +952,7 @@ "ToastLibraryScanFailedToStart": "Errore inizio scansione", "ToastLibraryScanStarted": "Scansione Libreria iniziata", "ToastLibraryUpdateSuccess": "Libreria \"{0}\" aggiornata", - "ToastMatchAllAuthorsFailed": "Tutti gli autori non hanno potuto essere classificati", + "ToastMatchAllAuthorsFailed": "Tutti gli autori non sono potuti essere classificati", "ToastNameEmailRequired": "Nome ed email sono obbligatori", "ToastNameRequired": "Il nome è obbligatorio", "ToastNewUserCreatedFailed": "Impossibile creare l'account: \"{0}\"", diff --git a/client/strings/nl.json b/client/strings/nl.json index 06a1ffa80..aad7f3015 100644 --- a/client/strings/nl.json +++ b/client/strings/nl.json @@ -19,6 +19,7 @@ "ButtonChooseFiles": "Bestanden kiezen", "ButtonClearFilter": "Filter verwijderen", "ButtonCloseFeed": "Feed sluiten", + "ButtonCloseSession": "Sluit Sessie", "ButtonCollections": "Collecties", "ButtonConfigureScanner": "Configureer scanner", "ButtonCreate": "Creëer", @@ -28,6 +29,7 @@ "ButtonEdit": "Wijzig", "ButtonEditChapters": "Hoofdstukken wijzigen", "ButtonEditPodcast": "Podcast wijzigen", + "ButtonEnable": "Aanzetten", "ButtonForceReScan": "Forceer nieuwe scan", "ButtonFullPath": "Volledig pad", "ButtonHide": "Verberg", @@ -46,18 +48,23 @@ "ButtonNevermind": "Laat maar", "ButtonNext": "Volgende", "ButtonNextChapter": "Volgend hoofdstuk", + "ButtonNextItemInQueue": "Volgend Item in Wachtrij", + "ButtonOk": "Ok", "ButtonOpenFeed": "Feed openen", "ButtonOpenManager": "Manager openen", "ButtonPause": "Pauze", "ButtonPlay": "Afspelen", + "ButtonPlayAll": "Alles Afspelen", "ButtonPlaying": "Speelt", "ButtonPlaylists": "Afspeellijsten", "ButtonPrevious": "Vorige", "ButtonPreviousChapter": "Vorig hoofdstuk", + "ButtonProbeAudioFile": "Onderzoek Audio Bestand", "ButtonPurgeAllCache": "Volledige cache legen", "ButtonPurgeItemsCache": "Onderdelen-cache legen", "ButtonQueueAddItem": "In wachtrij zetten", "ButtonQueueRemoveItem": "Uit wachtrij verwijderen", + "ButtonQuickEmbed": "Snel Embedden", "ButtonQuickMatch": "Snelle match", "ButtonReScan": "Nieuwe scan", "ButtonRead": "Lees", @@ -70,10 +77,13 @@ "ButtonRemoveFromContinueListening": "Vewijder uit Verder luisteren", "ButtonRemoveFromContinueReading": "Verwijder van Verder luisteren", "ButtonRemoveSeriesFromContinueSeries": "Verwijder serie uit Serie vervolgen", + "ButtonReset": "Opnieuw Instellen", + "ButtonResetToDefault": "Standaardwaarden Terugzetten", "ButtonRestore": "Herstel", "ButtonSave": "Opslaan", "ButtonSaveAndClose": "Opslaan & sluiten", "ButtonSaveTracklist": "Afspeellijst opslaan", + "ButtonScan": "Scannen", "ButtonScanLibrary": "Scan bibliotheek", "ButtonSearch": "Zoeken", "ButtonSelectFolderPath": "Maplocatie selecteren", @@ -84,7 +94,9 @@ "ButtonShow": "Toon", "ButtonStartM4BEncode": "Start M4B-encoding", "ButtonStartMetadataEmbed": "Start insluiten metadata", + "ButtonStats": "Statistieken", "ButtonSubmit": "Indienen", + "ButtonTest": "Testen", "ButtonUploadBackup": "Upload back-up", "ButtonUploadCover": "Upload cover", "ButtonUploadOPMLFile": "Upload OPML-bestand", @@ -213,7 +225,7 @@ "LabelConfirmPassword": "Bevestig wachtwoord", "LabelContinueListening": "Verder Luisteren", "LabelContinueReading": "Verder lezen", - "LabelContinueSeries": "Ga verder met serie", + "LabelContinueSeries": "Doorgaan met Serie", "LabelCoverImageURL": "Coverafbeelding URL", "LabelCreatedAt": "Gecreëerd op", "LabelCronExpression": "Cron-uitdrukking", @@ -229,9 +241,12 @@ "LabelDirectory": "Map", "LabelDiscFromFilename": "Schijf uit bestandsnaam", "LabelDiscFromMetadata": "Schijf uit metadata", - "LabelDiscover": "Ontdek", + "LabelDiscover": "Ontdekken", + "LabelDownload": "Download", "LabelDuration": "Duur", "LabelDurationFound": "Gevonden duur:", + "LabelEbook": "Ebook", + "LabelEbooks": "Eboeken", "LabelEdit": "Wijzig", "LabelEmailSettingsFromAddress": "Van-adres", "LabelEmailSettingsSecure": "Veilig", @@ -240,11 +255,13 @@ "LabelEmbeddedCover": "Ingesloten cover", "LabelEnable": "Inschakelen", "LabelEnd": "Einde", + "LabelEndOfChapter": "Einde van het Hoofdstuk", "LabelEpisode": "Aflevering", "LabelEpisodeTitle": "Afleveringtitel", "LabelEpisodeType": "Afleveringtype", "LabelExample": "Voorbeeld", "LabelExplicit": "Expliciet", + "LabelFeedURL": "Feed URL", "LabelFetchingMetadata": "Metadata ophalen", "LabelFile": "Bestand", "LabelFileBirthtime": "Aanmaaktijd bestand", @@ -256,12 +273,16 @@ "LabelFolder": "Map", "LabelFolders": "Mappen", "LabelFontBold": "Vetgedrukt", + "LabelFontBoldness": "Font Boldness", "LabelFontFamily": "Lettertypefamilie", "LabelFontScale": "Lettertype schaal", "LabelFormat": "Formaat", + "LabelGenre": "Genre", + "LabelGenres": "Genres", "LabelHardDeleteFile": "Hard-delete bestand", - "LabelHasEbook": "Heeft ebook", - "LabelHasSupplementaryEbook": "Heeft supplementair ebook", + "LabelHasEbook": "Heeft Ebook", + "LabelHasSupplementaryEbook": "Heeft aanvullend Ebook", + "LabelHost": "Host", "LabelHour": "Uur", "LabelHours": "Uren", "LabelIcon": "Icoon", @@ -285,6 +306,7 @@ "LabelLastSeen": "Laatst gezien", "LabelLastTime": "Laatste keer", "LabelLastUpdate": "Laatste update", + "LabelLayout": "Layout", "LabelLayoutSinglePage": "Enkele pagina", "LabelLayoutSplitPage": "Gesplitste pagina", "LabelLess": "Minder", @@ -294,7 +316,7 @@ "LabelLibraryName": "Bibliotheeknaam", "LabelLimit": "Limiet", "LabelLineSpacing": "Regelruimte", - "LabelListenAgain": "Luister opnieuw", + "LabelListenAgain": "Opnieuw Beluisteren", "LabelLogLevelWarn": "Waarschuwing", "LabelLookForNewEpisodesAfterDate": "Zoek naar nieuwe afleveringen na deze datum", "LabelMediaPlayer": "Mediaspeler", @@ -311,8 +333,8 @@ "LabelNarrators": "Vertellers", "LabelNew": "Nieuw", "LabelNewPassword": "Nieuw wachtwoord", - "LabelNewestAuthors": "Nieuwste auteurs", - "LabelNewestEpisodes": "Nieuwste afleveringen", + "LabelNewestAuthors": "Nieuwste Auteurs", + "LabelNewestEpisodes": "Nieuwste Afleveringen", "LabelNextBackupDate": "Volgende back-up datum", "LabelNextScheduledRun": "Volgende geplande run", "LabelNoEpisodesSelected": "Geen afleveringen geselecteerd", @@ -343,6 +365,7 @@ "LabelPhotoPathURL": "Foto pad/URL", "LabelPlayMethod": "Afspeelwijze", "LabelPlaylists": "Afspeellijsten", + "LabelPodcast": "Podcast", "LabelPodcastSearchRegion": "Podcast zoekregio", "LabelPodcastType": "Podcasttype", "LabelPort": "Poort", @@ -360,11 +383,12 @@ "LabelRSSFeedPreventIndexing": "Voorkom indexering", "LabelRSSFeedSlug": "RSS-feed slug", "LabelRSSFeedURL": "RSS-feed URL", + "LabelRandomly": "Willekeurig", "LabelRead": "Lees", - "LabelReadAgain": "Lees opnieuw", + "LabelReadAgain": "Opnieuw Lezen", "LabelReadEbookWithoutProgress": "Lees ebook zonder voortgang bij te houden", - "LabelRecentSeries": "Recente series", - "LabelRecentlyAdded": "Recent toegevoegd", + "LabelRecentSeries": "Recente Serie", + "LabelRecentlyAdded": "Recent Toegevoegd", "LabelRecommended": "Aangeraden", "LabelRegion": "Regio", "LabelReleaseDate": "Verschijningsdatum", @@ -418,6 +442,7 @@ "LabelShowAll": "Toon alle", "LabelSize": "Grootte", "LabelSleepTimer": "Slaaptimer", + "LabelStart": "Start", "LabelStartTime": "Starttijd", "LabelStarted": "Gestart", "LabelStartedAt": "Gestart op", @@ -438,6 +463,8 @@ "LabelStatsWeekListening": "Week luisterend", "LabelSubtitle": "Subtitel", "LabelSupportedFileTypes": "Ondersteunde bestandstypes", + "LabelTag": "Tag", + "LabelTags": "Tags", "LabelTagsAccessibleToUser": "Tags toegankelijk voor de gebruiker", "LabelTagsNotAccessibleToUser": "Tags niet toegankelijk voor de gebruiker", "LabelTasks": "Lopende taken", @@ -460,8 +487,10 @@ "LabelTotalTimeListened": "Totale tijd geluisterd", "LabelTrackFromFilename": "Track vanuit bestandsnaam", "LabelTrackFromMetadata": "Track vanuit metadata", + "LabelTracks": "Audiosporen", "LabelTracksNone": "Geen tracks", "LabelTracksSingleTrack": "Enkele track", + "LabelType": "Type", "LabelUnabridged": "Onverkort", "LabelUndo": "Ongedaan maken", "LabelUnknown": "Onbekend", diff --git a/client/strings/pl.json b/client/strings/pl.json index 9fd6c9feb..57bb577a0 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -95,7 +95,7 @@ "ButtonStartM4BEncode": "Eksportuj jako plik M4B", "ButtonStartMetadataEmbed": "Osadź metadane", "ButtonStats": "Statystyki", - "ButtonSubmit": "Zaloguj", + "ButtonSubmit": "Pobierz", "ButtonTest": "Test", "ButtonUnlinkOpenId": "Odłącz OpenID", "ButtonUpload": "Wgraj", @@ -462,7 +462,7 @@ "LabelReadAgain": "Czytaj ponownie", "LabelReadEbookWithoutProgress": "Czytaj książkę bez zapamiętywania postępu", "LabelRecentSeries": "Ostatnie serie", - "LabelRecentlyAdded": "Niedawno dodany", + "LabelRecentlyAdded": "Niedawno dodane", "LabelRecommended": "Polecane", "LabelRedo": "Wycofaj", "LabelReleaseDate": "Data wydania", diff --git a/client/strings/sl.json b/client/strings/sl.json index 68676313f..c0512f4bd 100644 --- a/client/strings/sl.json +++ b/client/strings/sl.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Počisti predpomnilnik elementov", "ButtonQueueAddItem": "Dodaj v čakalno vrsto", "ButtonQueueRemoveItem": "Odstrani iz čakalne vrste", + "ButtonQuickEmbed": "Hitra vdelava", "ButtonQuickEmbedMetadata": "Hitra vdelava metapodatkov", "ButtonQuickMatch": "Hitro ujemanje", "ButtonReScan": "Ponovno pregledovanje", @@ -225,6 +226,9 @@ "LabelAllUsersIncludingGuests": "Vsi uporabniki vključno z gosti", "LabelAlreadyInYourLibrary": "Že v tvoji knjižnici", "LabelAppend": "Priloži", + "LabelAudioBitrate": "Avdio bitna hitrost (npr. 128k)", + "LabelAudioChannels": "Avdio kanali (1 ali 2)", + "LabelAudioCodec": "Avdio kodek", "LabelAuthor": "Avtor", "LabelAuthorFirstLast": "Avtor (ime priimek)", "LabelAuthorLastFirst": "Avtor (priimek, ime)", @@ -237,6 +241,7 @@ "LabelAutoRegister": "Samodejna registracija", "LabelAutoRegisterDescription": "Po prijavi samodejno ustvari nove uporabnike", "LabelBackToUser": "Nazaj na uporabnika", + "LabelBackupAudioFiles": "Varnostno kopiranje zvočnih datotek", "LabelBackupLocation": "Lokacija rezervne kopije", "LabelBackupsEnableAutomaticBackups": "Omogoči samodejno varnostno kopiranje", "LabelBackupsEnableAutomaticBackupsHelp": "Varnostne kopije shranjene v /metadata/backups", @@ -303,6 +308,15 @@ "LabelEmailSettingsTestAddress": "Testiraj naslov", "LabelEmbeddedCover": "Vdelana naslovnica", "LabelEnable": "Omogoči", + "LabelEncodingBackupLocation": "Varnostna kopija vaših izvirnih zvočnih datotek bo shranjena v:", + "LabelEncodingChaptersNotEmbedded": "Poglavja niso vdelana v zvočne knjige z večimi sledmi.", + "LabelEncodingClearItemCache": "Občasno počistite predpomnilnik elementov.", + "LabelEncodingFinishedM4B": "Končana M4B datoteka bo shranjena v vaši mapi z zvočnimi knjigami:", + "LabelEncodingInfoEmbedded": "Metapodatki bodo vdelani v zvočne posnetke znotraj vaše mape zvočne knjige.", + "LabelEncodingStartedNavigation": "Ko se opravilo začne, lahko zapustite to stran.", + "LabelEncodingTimeWarning": "Enkodiranje lahko traja tudi do 30 minut.", + "LabelEncodingWarningAdvancedSettings": "Opozorilo: Ne posodabljajte teh nastavitev, razen če poznate možnosti ekodiranja s programom ffmpeg.", + "LabelEncodingWatcherDisabled": "Če ste spremljanje datotečnega sistema onemogočili, boste morali pozneje ponovno pregledati to zvočno knjigo.", "LabelEnd": "Konec", "LabelEndOfChapter": "Konec poglavja", "LabelEpisode": "Epizoda", @@ -350,7 +364,7 @@ "LabelImageURLFromTheWeb": "URL slike iz spleta", "LabelInProgress": "V teku", "LabelIncludeInTracklist": "Vključi v seznam skladb", - "LabelIncomplete": "Nepopolno", + "LabelIncomplete": "Nedokončano", "LabelInterval": "Interval", "LabelIntervalCustomDailyWeekly": "Dnevno/tedensko po meri", "LabelIntervalEvery12Hours": "Vsakih 12 ur", @@ -422,7 +436,7 @@ "LabelNotes": "Opombe", "LabelNotificationAppriseURL": "Apprise URL(ji)", "LabelNotificationAvailableVariables": "Razpoložljive spremenljivke", - "LabelNotificationBodyTemplate": "Predloga telesa", + "LabelNotificationBodyTemplate": "Predloga vsebime", "LabelNotificationEvent": "Dogodek obvestila", "LabelNotificationTitleTemplate": "Predloga naslova", "LabelNotificationsMaxFailedAttempts": "Najvišje število neuspelih poskusov", @@ -501,6 +515,7 @@ "LabelSeries": "Serije", "LabelSeriesName": "Ime serije", "LabelSeriesProgress": "Napredek serije", + "LabelServerLogLevel": "Raven dnevnika strežnika", "LabelServerYearReview": "Pregled leta strežnika ({0})", "LabelSetEbookAsPrimary": "Nastavi kot primarno", "LabelSetEbookAsSupplementary": "Nastavi kot dodatno", @@ -596,6 +611,7 @@ "LabelTitle": "Naslov", "LabelToolsEmbedMetadata": "Vdelaj metapodatke", "LabelToolsEmbedMetadataDescription": "Vdelajte metapodatke v zvočne datoteke, vključno s sliko naslovnice in poglavji.", + "LabelToolsM4bEncoder": "M4B enkoder", "LabelToolsMakeM4b": "Ustvari M4B datoteko zvočne knjige", "LabelToolsMakeM4bDescription": "Ustvari zvočno knjigo v .M4B obliki z vdelanimi metapodatki, sliko naslovnice in poglavji.", "LabelToolsSplitM4b": "Razdeli M4B v MP3 datoteke", @@ -621,6 +637,7 @@ "LabelUploaderDragAndDrop": "Povleci in spusti datoteke ali mape", "LabelUploaderDropFiles": "Spusti datoteke", "LabelUploaderItemFetchMetadataHelp": "Samodejno pridobi naslov, avtorja in serijo", + "LabelUseAdvancedOptions": "Uporabi napredne možnosti", "LabelUseChapterTrack": "Uporabi posnetek poglavij", "LabelUseFullTrack": "Uporabi celoten posnetek", "LabelUser": "Uporabnik", @@ -669,6 +686,7 @@ "MessageConfirmDeleteMetadataProvider": "Ali ste prepričani, da želite izbrisati ponudnika metapodatkov po meri \"{0}\"?", "MessageConfirmDeleteNotification": "Ali ste prepričani, da želite izbrisati to obvestilo?", "MessageConfirmDeleteSession": "Ali ste prepričani, da želite izbrisati to sejo?", + "MessageConfirmEmbedMetadataInAudioFiles": "Ali ste prepričani, da želite vdelati metapodatke v {0} zvočnih datotek?", "MessageConfirmForceReScan": "Ali ste prepričani, da želite vsiliti ponovno pregledovanje?", "MessageConfirmMarkAllEpisodesFinished": "Ali ste prepričani, da želite označiti vse epizode kot dokončane?", "MessageConfirmMarkAllEpisodesNotFinished": "Ali ste prepričani, da želite vse epizode označiti kot nedokončane?", @@ -702,6 +720,7 @@ "MessageDragFilesIntoTrackOrder": "Povlecite datoteke v pravilen vrstni red posnetkov", "MessageEmbedFailed": "Vdelava ni uspela!", "MessageEmbedFinished": "Vdelava končana!", + "MessageEmbedQueue": "V čakalni vrsta za vdelavo metapodatkov ({0} v čakalni vrsti)", "MessageEpisodesQueuedForDownload": "{0} epizod v čakalni vrsti za prenos", "MessageEreaderDevices": "Da zagotovite dostavo e-knjig, boste morda morali dodati zgornji e-poštni naslov kot veljavnega pošiljatelja za vsako spodaj navedeno napravo.", "MessageFeedURLWillBe": "URL vira bo {0}", @@ -746,6 +765,7 @@ "MessageNoLogs": "Ni dnevnikov", "MessageNoMediaProgress": "Ni medijskega napredka", "MessageNoNotifications": "Ni obvestil", + "MessageNoPodcastFeed": "Neveljaven podcast: Ni vira", "MessageNoPodcastsFound": "Ni podcastov", "MessageNoResults": "Ni rezultatov", "MessageNoSearchResultsFor": "Ni rezultatov iskanja za \"{0}\"", @@ -762,6 +782,9 @@ "MessagePlaylistCreateFromCollection": "Ustvari seznam predvajanja iz zbirke", "MessagePleaseWait": "Prosim počakajte...", "MessagePodcastHasNoRSSFeedForMatching": "Podcast nima URL-ja vira RSS, ki bi ga lahko uporabil za ujemanje", + "MessagePodcastSearchField": "Vnesite iskalni izraz ali URL vira RSS", + "MessageQuickEmbedInProgress": "Hitra vdelava je v teku", + "MessageQuickEmbedQueue": "V čakalni vrsti za hitro vdelavo ({0} v čakalni vrsti)", "MessageQuickMatchDescription": "Izpolni prazne podrobnosti elementa in naslovnico s prvim rezultatom ujemanja iz '{0}'. Ne prepiše podrobnosti, razen če je omogočena nastavitev strežnika 'Prednostno ujemajoči se metapodatki'.", "MessageRemoveChapter": "Odstrani poglavje", "MessageRemoveEpisodes": "Odstrani toliko epizod: {0}", @@ -804,6 +827,9 @@ "MessageTaskOpmlImportFeedPodcastExists": "Podcast že obstaja na tej poti", "MessageTaskOpmlImportFeedPodcastFailed": "Podcasta ni bilo mogoče ustvariti", "MessageTaskOpmlImportFinished": "Dodanih {0} podcastov", + "MessageTaskOpmlParseFailed": "Datoteke OPML ni bilo mogoče razčleniti", + "MessageTaskOpmlParseFastFail": "Neveljavna OPMPL datoteka, oznake ni bilo mogoče najti ALI oznake ni bilo mogoče najti", + "MessageTaskOpmlParseNoneFound": "V datoteki OPML ni virov", "MessageTaskScanItemsAdded": "{0} dodano", "MessageTaskScanItemsMissing": "{0} manjka", "MessageTaskScanItemsUpdated": "{0} posodobljeno", @@ -828,6 +854,10 @@ "NoteUploaderFoldersWithMediaFiles": "Mape z predstavnostnimi datotekami bodo obravnavane kot ločene postavke knjižnice.", "NoteUploaderOnlyAudioFiles": "Če nalagate samo zvočne datoteke, bo vsaka zvočna datoteka obravnavana kot ločena zvočna knjiga.", "NoteUploaderUnsupportedFiles": "Nepodprte datoteke so prezrte. Ko izberete ali spustite mapo, se druge datoteke, ki niso v mapi elementov, prezrejo.", + "NotificationOnBackupCompletedDescription": "Sproži se, ko je varnostno kopiranje končano", + "NotificationOnBackupFailedDescription": "Sproži se, ko varnostno kopiranje ne uspe", + "NotificationOnEpisodeDownloadedDescription": "Sproži se, ko se epizoda podcasta samodejno prenese", + "NotificationOnTestDescription": "Dogodek za testiranje sistema obveščanja", "PlaceholderNewCollection": "Novo ime zbirke", "PlaceholderNewFolderPath": "Pot nove mape", "PlaceholderNewPlaylist": "Novo ime seznama predvajanja", diff --git a/server/Server.js b/server/Server.js index 7e541e612..d82652376 100644 --- a/server/Server.js +++ b/server/Server.js @@ -243,6 +243,15 @@ class Server { await this.auth.initPassportJs() const router = express.Router() + // if RouterBasePath is set, modify all requests to include the base path + if (global.RouterBasePath) { + app.use((req, res, next) => { + if (!req.url.startsWith(global.RouterBasePath)) { + req.url = `${global.RouterBasePath}${req.url}` + } + next() + }) + } app.use(global.RouterBasePath, router) app.disable('x-powered-by') @@ -340,7 +349,7 @@ class Server { Logger.info('Received ping') res.json({ success: true }) }) - app.get('/healthcheck', (req, res) => res.sendStatus(200)) + router.get('/healthcheck', (req, res) => res.sendStatus(200)) this.server.listen(this.Port, this.Host, () => { if (this.Host) Logger.info(`Listening on http://${this.Host}:${this.Port}`) diff --git a/server/SocketAuthority.js b/server/SocketAuthority.js index af8204c60..a71829361 100644 --- a/server/SocketAuthority.js +++ b/server/SocketAuthority.js @@ -103,7 +103,8 @@ class SocketAuthority { cors: { origin: '*', methods: ['GET', 'POST'] - } + }, + path: `${global.RouterBasePath}/socket.io` }) this.io.on('connection', (socket) => { diff --git a/server/utils/queries/libraryFilters.js b/server/utils/queries/libraryFilters.js index fc04fefc5..34c3fe544 100644 --- a/server/utils/queries/libraryFilters.js +++ b/server/utils/queries/libraryFilters.js @@ -508,9 +508,9 @@ module.exports = { } if (book.publisher) data.publishers.add(book.publisher) // Check if published year exists and is valid - if (book.publishedYear && !isNaN(book.publishedYear) && book.publishedYear > 0 && book.publishedYear < 3000 && book.publishedYear.toString().length === 4) { - const decade = Math.floor(book.publishedYear / 10) * 10 - data.publishedDecades.add(decade.toString()) + if (book.publishedYear && !isNaN(book.publishedYear) && book.publishedYear > 0 && book.publishedYear < 3000) { + const decade = (Math.floor(book.publishedYear / 10) * 10).toString() + data.publishedDecades.add(decade) } if (book.language) data.languages.add(book.language) } diff --git a/server/utils/queries/libraryItemsBookFilters.js b/server/utils/queries/libraryItemsBookFilters.js index e64e7b786..e8b424ed9 100644 --- a/server/utils/queries/libraryItemsBookFilters.js +++ b/server/utils/queries/libraryItemsBookFilters.js @@ -229,10 +229,11 @@ module.exports = { mediaWhere['$series.id$'] = null } } else if (group === 'publishedDecades') { - const year = parseInt(value, 10) - mediaWhere['publishedYear'] = { - [Sequelize.Op.between]: year >= 1000 ? [year, year + 9] : [year * 10, (year + 1) * 10 - 1] - } + const startYear = parseInt(value) + const endYear = parseInt(value, 10) + 9 + mediaWhere = Sequelize.where(Sequelize.literal('CAST(`book`.`publishedYear` AS INTEGER)'), { + [Sequelize.Op.between]: [startYear, endYear] + }) } return { mediaWhere, replacements } @@ -504,7 +505,6 @@ module.exports = { } let { mediaWhere, replacements } = this.getMediaGroupQuery(filterGroup, filterValue) - let bookWhere = Array.isArray(mediaWhere) ? mediaWhere : [mediaWhere] // User permissions