mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-06-02 00:40:39 +02:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a992400d6a | |||
| 108b2a60f5 | |||
| af684e6a69 | |||
| 5336d0525e | |||
| bb4eec9355 | |||
| 28404f37b8 | |||
| 7b92c15a46 | |||
| c150ed4e98 | |||
| cb7632b216 | |||
| b8849677de | |||
| 9bf8d7de11 | |||
| 6634ce8fd4 | |||
| 9d4303ef7b | |||
| 1f7be58124 | |||
| 6b8b27b04f | |||
| ba4061e5a4 | |||
| 693dc00fa3 | |||
| f3f5f3b9bd | |||
| b515c6c746 | |||
| 35e196238a | |||
| 2dc93258f1 | |||
| 5123f7d240 | |||
| 06d3bd76a8 | |||
| 52196afd99 | |||
| 3e44ee6f50 | |||
| 9841826e10 | |||
| def93d18ec | |||
| 387a3d05b4 | |||
| 398d04fc08 | |||
| c5e5e516af | |||
| 1c6f99b876 | |||
| d0af82e71a | |||
| 76e7616439 | |||
| fe99a269bc | |||
| 5315f65023 | |||
| c2809808c3 | |||
| 204ac4f204 | |||
| accd5d1096 | |||
| 5025c6a3ea | |||
| 6d0d1415e4 | |||
| 514f5c2409 | |||
| 2cc58b2c8a | |||
| a617994207 | |||
| eda7036f70 |
+1
-1
@@ -57,7 +57,7 @@ WORKDIR /app
|
|||||||
# Copy compiled frontend and server from build stages
|
# Copy compiled frontend and server from build stages
|
||||||
COPY --from=build-client /client/dist /app/client/dist
|
COPY --from=build-client /client/dist /app/client/dist
|
||||||
COPY --from=build-server /server /app
|
COPY --from=build-server /server /app
|
||||||
COPY --from=build-server /usr/local/lib/nusqlite3 /usr/local/lib/nusqlite3
|
COPY --from=build-server ${NUSQLITE3_PATH} ${NUSQLITE3_PATH}
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ export default {
|
|||||||
userIsAdminOrUp() {
|
userIsAdminOrUp() {
|
||||||
return this.$store.getters['user/getIsAdminOrUp']
|
return this.$store.getters['user/getIsAdminOrUp']
|
||||||
},
|
},
|
||||||
|
userCanAccessExplicitContent() {
|
||||||
|
return this.$store.getters['user/getUserCanAccessExplicitContent']
|
||||||
|
},
|
||||||
libraryMediaType() {
|
libraryMediaType() {
|
||||||
return this.$store.getters['libraries/getCurrentLibraryMediaType']
|
return this.$store.getters['libraries/getCurrentLibraryMediaType']
|
||||||
},
|
},
|
||||||
@@ -239,6 +242,15 @@ export default {
|
|||||||
sublist: false
|
sublist: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (this.userCanAccessExplicitContent) {
|
||||||
|
items.push({
|
||||||
|
text: this.$strings.LabelExplicit,
|
||||||
|
value: 'explicit',
|
||||||
|
sublist: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (this.userIsAdminOrUp) {
|
if (this.userIsAdminOrUp) {
|
||||||
items.push({
|
items.push({
|
||||||
text: this.$strings.LabelShareOpen,
|
text: this.$strings.LabelShareOpen,
|
||||||
@@ -249,7 +261,7 @@ export default {
|
|||||||
return items
|
return items
|
||||||
},
|
},
|
||||||
podcastItems() {
|
podcastItems() {
|
||||||
return [
|
const items = [
|
||||||
{
|
{
|
||||||
text: this.$strings.LabelAll,
|
text: this.$strings.LabelAll,
|
||||||
value: 'all'
|
value: 'all'
|
||||||
@@ -283,6 +295,16 @@ export default {
|
|||||||
sublist: false
|
sublist: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (this.userCanAccessExplicitContent) {
|
||||||
|
items.push({
|
||||||
|
text: this.$strings.LabelExplicit,
|
||||||
|
value: 'explicit',
|
||||||
|
sublist: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return items
|
||||||
},
|
},
|
||||||
selectItems() {
|
selectItems() {
|
||||||
if (this.isSeries) return this.seriesItems
|
if (this.isSeries) return this.seriesItems
|
||||||
|
|||||||
@@ -35,7 +35,14 @@
|
|||||||
<widgets-podcast-type-indicator :type="episode.episodeType" />
|
<widgets-podcast-type-indicator :type="episode.episodeType" />
|
||||||
</div>
|
</div>
|
||||||
<p v-if="episode.subtitle" class="mb-1 text-sm text-gray-300 line-clamp-2">{{ episode.subtitle }}</p>
|
<p v-if="episode.subtitle" class="mb-1 text-sm text-gray-300 line-clamp-2">{{ episode.subtitle }}</p>
|
||||||
<p class="text-xs text-gray-300">Published {{ episode.publishedAt ? $dateDistanceFromNow(episode.publishedAt) : 'Unknown' }}</p>
|
<div class="flex items-center space-x-2">
|
||||||
|
<!-- published -->
|
||||||
|
<p class="text-xs text-gray-300 w-40">Published {{ episode.publishedAt ? $dateDistanceFromNow(episode.publishedAt) : 'Unknown' }}</p>
|
||||||
|
<!-- duration -->
|
||||||
|
<p v-if="episode.durationSeconds && !isNaN(episode.durationSeconds)" class="text-xs text-gray-300 min-w-28">{{ $strings.LabelDuration }}: {{ $elapsedPretty(episode.durationSeconds) }}</p>
|
||||||
|
<!-- size -->
|
||||||
|
<p v-if="episode.enclosure?.length && !isNaN(episode.enclosure.length) && Number(episode.enclosure.length) > 0" class="text-xs text-gray-300">{{ $strings.LabelSize }}: {{ $bytesPretty(Number(episode.enclosure.length)) }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p dir="auto" class="text-lg font-semibold mb-6">{{ title }}</p>
|
<p dir="auto" class="text-lg font-semibold mb-6">{{ title }}</p>
|
||||||
<div v-if="description" dir="auto" class="default-style less-spacing" v-html="description" />
|
<div v-if="description" dir="auto" class="default-style less-spacing" @click="handleDescriptionClick" v-html="description" />
|
||||||
<p v-else class="mb-2">{{ $strings.MessageNoDescription }}</p>
|
<p v-else class="mb-2">{{ $strings.MessageNoDescription }}</p>
|
||||||
|
|
||||||
<div class="w-full h-px bg-white/5 my-4" />
|
<div class="w-full h-px bg-white/5 my-4" />
|
||||||
@@ -34,6 +34,12 @@
|
|||||||
{{ audioFileSize }}
|
{{ audioFileSize }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="grow">
|
||||||
|
<p class="font-semibold text-xs mb-1">{{ $strings.LabelDuration }}</p>
|
||||||
|
<p class="mb-2 text-xs">
|
||||||
|
{{ audioFileDuration }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</modals-modal>
|
</modals-modal>
|
||||||
@@ -68,7 +74,7 @@ export default {
|
|||||||
return this.episode.title || 'No Episode Title'
|
return this.episode.title || 'No Episode Title'
|
||||||
},
|
},
|
||||||
description() {
|
description() {
|
||||||
return this.episode.description || ''
|
return this.parseDescription(this.episode.description || '')
|
||||||
},
|
},
|
||||||
media() {
|
media() {
|
||||||
return this.libraryItem?.media || {}
|
return this.libraryItem?.media || {}
|
||||||
@@ -90,11 +96,49 @@ export default {
|
|||||||
|
|
||||||
return this.$bytesPretty(size)
|
return this.$bytesPretty(size)
|
||||||
},
|
},
|
||||||
|
audioFileDuration() {
|
||||||
|
const duration = this.episode.duration || 0
|
||||||
|
return this.$elapsedPretty(duration)
|
||||||
|
},
|
||||||
bookCoverAspectRatio() {
|
bookCoverAspectRatio() {
|
||||||
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {
|
||||||
|
handleDescriptionClick(e) {
|
||||||
|
if (e.target.matches('span.time-marker')) {
|
||||||
|
const time = parseInt(e.target.dataset.time)
|
||||||
|
if (!isNaN(time)) {
|
||||||
|
this.$eventBus.$emit('play-item', {
|
||||||
|
episodeId: this.episodeId,
|
||||||
|
libraryItemId: this.libraryItem.id,
|
||||||
|
startTime: time
|
||||||
|
})
|
||||||
|
}
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseDescription(description) {
|
||||||
|
const timeMarkerLinkRegex = /<a href="#([^"]*?\b\d{1,2}:\d{1,2}(?::\d{1,2})?)">(.*?)<\/a>/g
|
||||||
|
const timeMarkerRegex = /\b\d{1,2}:\d{1,2}(?::\d{1,2})?\b/g
|
||||||
|
|
||||||
|
function convertToSeconds(time) {
|
||||||
|
const timeParts = time.split(':').map(Number)
|
||||||
|
return timeParts.reduce((acc, part, index) => acc * 60 + part, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return description
|
||||||
|
.replace(timeMarkerLinkRegex, (match, href, displayTime) => {
|
||||||
|
const time = displayTime.match(timeMarkerRegex)[0]
|
||||||
|
const seekTimeInSeconds = convertToSeconds(time)
|
||||||
|
return `<span class="time-marker cursor-pointer text-blue-400 hover:text-blue-300" data-time="${seekTimeInSeconds}">${displayTime}</span>`
|
||||||
|
})
|
||||||
|
.replace(timeMarkerRegex, (match) => {
|
||||||
|
const seekTimeInSeconds = convertToSeconds(match)
|
||||||
|
return `<span class="time-marker cursor-pointer text-blue-400 hover:text-blue-300" data-time="${seekTimeInSeconds}">${match}</span>`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {}
|
mounted() {}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.24.0",
|
"version": "2.25.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.24.0",
|
"version": "2.25.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.13.6",
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.24.0",
|
"version": "2.25.1",
|
||||||
"buildNumber": 1,
|
"buildNumber": 1,
|
||||||
"description": "Self-hosted audiobook and podcast client",
|
"description": "Self-hosted audiobook and podcast client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ export const getters = {
|
|||||||
getUserCanAccessAllLibraries: (state) => {
|
getUserCanAccessAllLibraries: (state) => {
|
||||||
return !!state.user?.permissions?.accessAllLibraries
|
return !!state.user?.permissions?.accessAllLibraries
|
||||||
},
|
},
|
||||||
|
getUserCanAccessExplicitContent: (state) => {
|
||||||
|
return !!state.user?.permissions?.accessExplicitContent
|
||||||
|
},
|
||||||
getLibrariesAccessible: (state, getters) => {
|
getLibrariesAccessible: (state, getters) => {
|
||||||
if (!state.user) return []
|
if (!state.user) return []
|
||||||
if (getters.getUserCanAccessAllLibraries) return []
|
if (getters.getUserCanAccessAllLibraries) return []
|
||||||
|
|||||||
@@ -514,7 +514,7 @@
|
|||||||
"LabelPublishers": "الناشرون",
|
"LabelPublishers": "الناشرون",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "البريد الالكتروني المخصص للمالك",
|
"LabelRSSFeedCustomOwnerEmail": "البريد الالكتروني المخصص للمالك",
|
||||||
"LabelRSSFeedCustomOwnerName": "الاسم المخصص للمالك",
|
"LabelRSSFeedCustomOwnerName": "الاسم المخصص للمالك",
|
||||||
"LabelRSSFeedOpen": "فتح تغذية RSS",
|
"LabelRSSFeedOpen": "موجز RSS مفتوح",
|
||||||
"LabelRSSFeedPreventIndexing": "منع الفهرسة",
|
"LabelRSSFeedPreventIndexing": "منع الفهرسة",
|
||||||
"LabelRSSFeedSlug": "اسم تعريف تغذية RSS",
|
"LabelRSSFeedSlug": "اسم تعريف تغذية RSS",
|
||||||
"LabelRSSFeedURL": "رابط تغذية RSS",
|
"LabelRSSFeedURL": "رابط تغذية RSS",
|
||||||
@@ -918,6 +918,8 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "يتم تشغيله عند اكتمال النسخ الاحتياطي",
|
"NotificationOnBackupCompletedDescription": "يتم تشغيله عند اكتمال النسخ الاحتياطي",
|
||||||
"NotificationOnBackupFailedDescription": "يتم تشغيله عند فشل النسخ الاحتياطي",
|
"NotificationOnBackupFailedDescription": "يتم تشغيله عند فشل النسخ الاحتياطي",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "يتم تشغيله عند تنزيل حلقة بودكاست تلقائيًا",
|
"NotificationOnEpisodeDownloadedDescription": "يتم تشغيله عند تنزيل حلقة بودكاست تلقائيًا",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "يتم تشغيله عندما يتم تعطيل تنزيلات الحلقة التلقائية بسبب الكثير من المحاولات الفاشلة",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "يتم تشغيله عند فشل طلب تغذية RSS في تنزيل حلقة تلقائية",
|
||||||
"NotificationOnTestDescription": "حدث لاختبار نظام الإشعارات",
|
"NotificationOnTestDescription": "حدث لاختبار نظام الإشعارات",
|
||||||
"PlaceholderNewCollection": "اسم المجموعة الجديدة",
|
"PlaceholderNewCollection": "اسم المجموعة الجديدة",
|
||||||
"PlaceholderNewFolderPath": "مسار المجلد الجديد",
|
"PlaceholderNewFolderPath": "مسار المجلد الجديد",
|
||||||
|
|||||||
+14
-8
@@ -154,7 +154,7 @@
|
|||||||
"HeaderListeningSessions": "Poslechové relace",
|
"HeaderListeningSessions": "Poslechové relace",
|
||||||
"HeaderListeningStats": "Statistiky poslechu",
|
"HeaderListeningStats": "Statistiky poslechu",
|
||||||
"HeaderLogin": "Přihlásit",
|
"HeaderLogin": "Přihlásit",
|
||||||
"HeaderLogs": "Záznamy",
|
"HeaderLogs": "Logy",
|
||||||
"HeaderManageGenres": "Spravovat žánry",
|
"HeaderManageGenres": "Spravovat žánry",
|
||||||
"HeaderManageTags": "Spravovat štítky",
|
"HeaderManageTags": "Spravovat štítky",
|
||||||
"HeaderMapDetails": "Podrobnosti mapování",
|
"HeaderMapDetails": "Podrobnosti mapování",
|
||||||
@@ -177,6 +177,7 @@
|
|||||||
"HeaderPlaylist": "Seznam skladeb",
|
"HeaderPlaylist": "Seznam skladeb",
|
||||||
"HeaderPlaylistItems": "Položky seznamu přehrávání",
|
"HeaderPlaylistItems": "Položky seznamu přehrávání",
|
||||||
"HeaderPodcastsToAdd": "Podcasty k přidání",
|
"HeaderPodcastsToAdd": "Podcasty k přidání",
|
||||||
|
"HeaderPresets": "Předvolba",
|
||||||
"HeaderPreviewCover": "Náhled obálky",
|
"HeaderPreviewCover": "Náhled obálky",
|
||||||
"HeaderRSSFeedGeneral": "Podrobnosti o RSS",
|
"HeaderRSSFeedGeneral": "Podrobnosti o RSS",
|
||||||
"HeaderRSSFeedIsOpen": "Informační kanál RSS je otevřený",
|
"HeaderRSSFeedIsOpen": "Informační kanál RSS je otevřený",
|
||||||
@@ -513,9 +514,9 @@
|
|||||||
"LabelPublishers": "Vydavatelé",
|
"LabelPublishers": "Vydavatelé",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Vlastní e-mail vlastníka",
|
"LabelRSSFeedCustomOwnerEmail": "Vlastní e-mail vlastníka",
|
||||||
"LabelRSSFeedCustomOwnerName": "Vlastní jméno vlastníka",
|
"LabelRSSFeedCustomOwnerName": "Vlastní jméno vlastníka",
|
||||||
"LabelRSSFeedOpen": "Otevření RSS kanálu",
|
"LabelRSSFeedOpen": "RSS kanál otevřen",
|
||||||
"LabelRSSFeedPreventIndexing": "Zabránit indexování",
|
"LabelRSSFeedPreventIndexing": "Zabránit indexování",
|
||||||
"LabelRSSFeedSlug": "RSS kanál Slug",
|
"LabelRSSFeedSlug": "Klíčové slovo kanálu RSS",
|
||||||
"LabelRSSFeedURL": "URL RSS kanálu",
|
"LabelRSSFeedURL": "URL RSS kanálu",
|
||||||
"LabelRandomly": "Náhodně",
|
"LabelRandomly": "Náhodně",
|
||||||
"LabelReAddSeriesToContinueListening": "Znovu přidat sérii k pokračování poslechu",
|
"LabelReAddSeriesToContinueListening": "Znovu přidat sérii k pokračování poslechu",
|
||||||
@@ -530,6 +531,7 @@
|
|||||||
"LabelReleaseDate": "Datum vydání",
|
"LabelReleaseDate": "Datum vydání",
|
||||||
"LabelRemoveAllMetadataAbs": "Odebrat všechny soubory metadata.abs",
|
"LabelRemoveAllMetadataAbs": "Odebrat všechny soubory metadata.abs",
|
||||||
"LabelRemoveAllMetadataJson": "Smazat všechny soubory metadata.json",
|
"LabelRemoveAllMetadataJson": "Smazat všechny soubory metadata.json",
|
||||||
|
"LabelRemoveAudibleBranding": "Odebrat úvod a závěr Audible z kapitol",
|
||||||
"LabelRemoveCover": "Odstranit obálku",
|
"LabelRemoveCover": "Odstranit obálku",
|
||||||
"LabelRemoveMetadataFile": "Odstranit soubory metadat ve složkách položek knihovny",
|
"LabelRemoveMetadataFile": "Odstranit soubory metadat ve složkách položek knihovny",
|
||||||
"LabelRemoveMetadataFileHelp": "Odstraníte všechny soubory metadata.json a metadata.abs ve svých složkách {0}.",
|
"LabelRemoveMetadataFileHelp": "Odstraníte všechny soubory metadata.json a metadata.abs ve svých složkách {0}.",
|
||||||
@@ -549,7 +551,7 @@
|
|||||||
"LabelSeries": "Série",
|
"LabelSeries": "Série",
|
||||||
"LabelSeriesName": "Název série",
|
"LabelSeriesName": "Název série",
|
||||||
"LabelSeriesProgress": "Průběh série",
|
"LabelSeriesProgress": "Průběh série",
|
||||||
"LabelServerLogLevel": "Úroveň protokolu serveru",
|
"LabelServerLogLevel": "Úroveň Logování serveru",
|
||||||
"LabelServerYearReview": "Přehled roku na serveru ({0})",
|
"LabelServerYearReview": "Přehled roku na serveru ({0})",
|
||||||
"LabelSetEbookAsPrimary": "Nastavit jako primární",
|
"LabelSetEbookAsPrimary": "Nastavit jako primární",
|
||||||
"LabelSetEbookAsSupplementary": "Nastavit jako doplňkové",
|
"LabelSetEbookAsSupplementary": "Nastavit jako doplňkové",
|
||||||
@@ -706,6 +708,7 @@
|
|||||||
"MessageAddToPlayerQueue": "Přidat do fronty přehrávače",
|
"MessageAddToPlayerQueue": "Přidat do fronty přehrávače",
|
||||||
"MessageAppriseDescription": "Abyste mohli používat tuto funkci, musíte mít spuštěnou instanci <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> nebo API, které bude zpracovávat stejné požadavky. <br />Adresa URL API Apprise by měla být úplná URL cesta pro odeslání oznámení, např. pokud je vaše instance API obsluhována na adrese <code>http://192.168.1.1:8337</code> pak byste měli zadat <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "Abyste mohli používat tuto funkci, musíte mít spuštěnou instanci <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> nebo API, které bude zpracovávat stejné požadavky. <br />Adresa URL API Apprise by měla být úplná URL cesta pro odeslání oznámení, např. pokud je vaše instance API obsluhována na adrese <code>http://192.168.1.1:8337</code> pak byste měli zadat <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
"MessageAsinCheck": "Ujistěte se, že používáte ASIN ze správného regionu Audible a ne z Amazonu.",
|
"MessageAsinCheck": "Ujistěte se, že používáte ASIN ze správného regionu Audible a ne z Amazonu.",
|
||||||
|
"MessageAuthenticationOIDCChangesRestart": "Po uložení restartujte server, aby se změny OIDC použily.",
|
||||||
"MessageBackupsDescription": "Zálohy zahrnují uživatele, průběh uživatele, podrobnosti o položkách knihovny, nastavení serveru a obrázky uložené v <code>/metadata/items</code> a <code>/metadata/authors</code>. Zálohy <strong>ne</strong> zahrnují všechny soubory uložené ve složkách knihovny.",
|
"MessageBackupsDescription": "Zálohy zahrnují uživatele, průběh uživatele, podrobnosti o položkách knihovny, nastavení serveru a obrázky uložené v <code>/metadata/items</code> a <code>/metadata/authors</code>. Zálohy <strong>ne</strong> zahrnují všechny soubory uložené ve složkách knihovny.",
|
||||||
"MessageBackupsLocationEditNote": "Poznámka: Změna umístění záloh nepřesune ani nezmění existující zálohy",
|
"MessageBackupsLocationEditNote": "Poznámka: Změna umístění záloh nepřesune ani nezmění existující zálohy",
|
||||||
"MessageBackupsLocationNoEditNote": "Poznámka: Umístění záloh je nastavené z proměnných prostředí a nelze zde změnit.",
|
"MessageBackupsLocationNoEditNote": "Poznámka: Umístění záloh je nastavené z proměnných prostředí a nelze zde změnit.",
|
||||||
@@ -787,7 +790,7 @@
|
|||||||
"MessageJoinUsOn": "Přidejte se k nám",
|
"MessageJoinUsOn": "Přidejte se k nám",
|
||||||
"MessageLoading": "Načítá se...",
|
"MessageLoading": "Načítá se...",
|
||||||
"MessageLoadingFolders": "Načítám složky...",
|
"MessageLoadingFolders": "Načítám složky...",
|
||||||
"MessageLogsDescription": "Protokoly se ukládají do souborů JSON v <code>/metadata/logs</code>. Protokoly o pádech jsou uloženy v <code>/metadata/logs/crash_logs.txt</code>.",
|
"MessageLogsDescription": "Logy se ukládají do souborů JSON v <code>/metadata/logs</code>. Logy o pádech jsou uloženy v <code>/metadata/logs/crash_logs.txt</code>.",
|
||||||
"MessageM4BFailed": "M4B se nezdařil!",
|
"MessageM4BFailed": "M4B se nezdařil!",
|
||||||
"MessageM4BFinished": "M4B dokončen!",
|
"MessageM4BFinished": "M4B dokončen!",
|
||||||
"MessageMapChapterTitles": "Mapování názvů kapitol ke stávajícím kapitolám audioknihy bez úpravy časových razítek",
|
"MessageMapChapterTitles": "Mapování názvů kapitol ke stávajícím kapitolám audioknihy bez úpravy časových razítek",
|
||||||
@@ -811,11 +814,11 @@
|
|||||||
"MessageNoEpisodes": "Žádné epizody",
|
"MessageNoEpisodes": "Žádné epizody",
|
||||||
"MessageNoFoldersAvailable": "Nejsou k dispozici žádné složky",
|
"MessageNoFoldersAvailable": "Nejsou k dispozici žádné složky",
|
||||||
"MessageNoGenres": "Žádné žánry",
|
"MessageNoGenres": "Žádné žánry",
|
||||||
"MessageNoIssues": "Žádné výtisk",
|
"MessageNoIssues": "Žádné problémy",
|
||||||
"MessageNoItems": "Žádné položky",
|
"MessageNoItems": "Žádné položky",
|
||||||
"MessageNoItemsFound": "Nebyly nalezeny žádné položky",
|
"MessageNoItemsFound": "Nebyly nalezeny žádné položky",
|
||||||
"MessageNoListeningSessions": "Žádné poslechové relace",
|
"MessageNoListeningSessions": "Žádné poslechové relace",
|
||||||
"MessageNoLogs": "Žádné protokoly",
|
"MessageNoLogs": "Žádné logy",
|
||||||
"MessageNoMediaProgress": "Žádný průběh médií",
|
"MessageNoMediaProgress": "Žádný průběh médií",
|
||||||
"MessageNoNotifications": "Žádná oznámení",
|
"MessageNoNotifications": "Žádná oznámení",
|
||||||
"MessageNoPodcastFeed": "Neplatný podcast: Žádný kanál",
|
"MessageNoPodcastFeed": "Neplatný podcast: Žádný kanál",
|
||||||
@@ -853,6 +856,7 @@
|
|||||||
"MessageScheduleRunEveryWeekdayAtTime": "Spusť každý {0} v {1}",
|
"MessageScheduleRunEveryWeekdayAtTime": "Spusť každý {0} v {1}",
|
||||||
"MessageSearchResultsFor": "Výsledky hledání pro",
|
"MessageSearchResultsFor": "Výsledky hledání pro",
|
||||||
"MessageSelected": "{0} vybráno",
|
"MessageSelected": "{0} vybráno",
|
||||||
|
"MessageSeriesSequenceCannotContainSpaces": "Sekvence série nesmí obsahovat mezery",
|
||||||
"MessageServerCouldNotBeReached": "Server je nedostupný",
|
"MessageServerCouldNotBeReached": "Server je nedostupný",
|
||||||
"MessageSetChaptersFromTracksDescription": "Nastavit kapitoly jako kapitolu a název kapitoly jako název zvukového souboru",
|
"MessageSetChaptersFromTracksDescription": "Nastavit kapitoly jako kapitolu a název kapitoly jako název zvukového souboru",
|
||||||
"MessageShareExpirationWillBe": "Expiruje <strong>{0}</strong>",
|
"MessageShareExpirationWillBe": "Expiruje <strong>{0}</strong>",
|
||||||
@@ -971,6 +975,8 @@
|
|||||||
"ToastCachePurgeFailed": "Nepodařilo se vyčistit mezipaměť",
|
"ToastCachePurgeFailed": "Nepodařilo se vyčistit mezipaměť",
|
||||||
"ToastCachePurgeSuccess": "Vyrovnávací paměť úspěšně vyčištěna",
|
"ToastCachePurgeSuccess": "Vyrovnávací paměť úspěšně vyčištěna",
|
||||||
"ToastChaptersHaveErrors": "Kapitoly obsahují chyby",
|
"ToastChaptersHaveErrors": "Kapitoly obsahují chyby",
|
||||||
|
"ToastChaptersInvalidShiftAmountLast": "Nesprávná délka posunu. Čas začátku poslední kapitoly by přesáhl dobu trvání této audioknihy.",
|
||||||
|
"ToastChaptersInvalidShiftAmountStart": "Nesprávná délka posunu. První kapitola by měla nulovou nebo zápornou délku a byla by přepsána druhou kapitolou. Zvětšete počáteční délku druhé kapitoly.",
|
||||||
"ToastChaptersMustHaveTitles": "Kapitoly musí mít názvy",
|
"ToastChaptersMustHaveTitles": "Kapitoly musí mít názvy",
|
||||||
"ToastChaptersRemoved": "Kapitoly odstraněny",
|
"ToastChaptersRemoved": "Kapitoly odstraněny",
|
||||||
"ToastChaptersUpdated": "Kapitola aktualizována",
|
"ToastChaptersUpdated": "Kapitola aktualizována",
|
||||||
@@ -1091,7 +1097,7 @@
|
|||||||
"ToastUnlinkOpenIdFailed": "Chyba při odpárování uživatele z OpenID",
|
"ToastUnlinkOpenIdFailed": "Chyba při odpárování uživatele z OpenID",
|
||||||
"ToastUnlinkOpenIdSuccess": "Uživatel odpárován z uživatele z OpenID",
|
"ToastUnlinkOpenIdSuccess": "Uživatel odpárován z uživatele z OpenID",
|
||||||
"ToastUploaderFilepathExistsError": "Soubor \"{0}\" na serveru již existuje",
|
"ToastUploaderFilepathExistsError": "Soubor \"{0}\" na serveru již existuje",
|
||||||
"ToastUploaderItemExistsInSubdirectoryError": "Položka \"{0}\" používá podsložku nahrávané cesty.",
|
"ToastUploaderItemExistsInSubdirectoryError": "Položka \"{0}\" používá podadresář cesty pro nahrání.",
|
||||||
"ToastUserDeleteFailed": "Nepodařilo se smazat uživatele",
|
"ToastUserDeleteFailed": "Nepodařilo se smazat uživatele",
|
||||||
"ToastUserDeleteSuccess": "Uživatel smazán",
|
"ToastUserDeleteSuccess": "Uživatel smazán",
|
||||||
"ToastUserPasswordChangeSuccess": "Heslo bylo změněno úspěšně",
|
"ToastUserPasswordChangeSuccess": "Heslo bylo změněno úspěšně",
|
||||||
|
|||||||
@@ -513,7 +513,7 @@
|
|||||||
"LabelPublishers": "Forlag",
|
"LabelPublishers": "Forlag",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Brugerdefineret ejerens e-mail",
|
"LabelRSSFeedCustomOwnerEmail": "Brugerdefineret ejerens e-mail",
|
||||||
"LabelRSSFeedCustomOwnerName": "Brugerdefineret ejerens navn",
|
"LabelRSSFeedCustomOwnerName": "Brugerdefineret ejerens navn",
|
||||||
"LabelRSSFeedOpen": "Åben RSS-feed",
|
"LabelRSSFeedOpen": "RSS-feed åbent",
|
||||||
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
|
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
|
||||||
"LabelRSSFeedSlug": "RSS-feed-slug",
|
"LabelRSSFeedSlug": "RSS-feed-slug",
|
||||||
"LabelRSSFeedURL": "RSS-feed-URL",
|
"LabelRSSFeedURL": "RSS-feed-URL",
|
||||||
|
|||||||
@@ -514,7 +514,7 @@
|
|||||||
"LabelPublishers": "Herausgeber",
|
"LabelPublishers": "Herausgeber",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
|
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
|
||||||
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
||||||
"LabelRSSFeedOpen": "RSS Feed offen",
|
"LabelRSSFeedOpen": "RSS Feed öffnen",
|
||||||
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
||||||
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
|
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
|
||||||
"LabelRSSFeedURL": "RSS-Feed-URL",
|
"LabelRSSFeedURL": "RSS-Feed-URL",
|
||||||
@@ -858,7 +858,7 @@
|
|||||||
"MessageSelected": "{0} ausgewählt",
|
"MessageSelected": "{0} ausgewählt",
|
||||||
"MessageSeriesSequenceCannotContainSpaces": "Serie Abfolge kann keine Leerzeichen enthalten",
|
"MessageSeriesSequenceCannotContainSpaces": "Serie Abfolge kann keine Leerzeichen enthalten",
|
||||||
"MessageServerCouldNotBeReached": "Server kann nicht erreicht werden",
|
"MessageServerCouldNotBeReached": "Server kann nicht erreicht werden",
|
||||||
"MessageSetChaptersFromTracksDescription": "Kaitelerstellung basiert auf den existierenden einzelnen Audiodateien. Pro existierende Audiodatei wird 1 Kapitel erstellt, wobei deren Kapitelname aus dem Audiodateinamen extrahiert wird",
|
"MessageSetChaptersFromTracksDescription": "Kapitelerstellung basiert auf den existierenden einzelnen Audiodateien. Pro existierende Audiodatei wird 1 Kapitel erstellt, wobei deren Kapitelname aus dem Audiodateinamen extrahiert wird",
|
||||||
"MessageShareExpirationWillBe": "Läuft am <strong>{0}</strong> ab",
|
"MessageShareExpirationWillBe": "Läuft am <strong>{0}</strong> ab",
|
||||||
"MessageShareExpiresIn": "Läuft in {0} ab",
|
"MessageShareExpiresIn": "Läuft in {0} ab",
|
||||||
"MessageShareURLWillBe": "Der Freigabe Link wird <strong>{0}</strong> sein",
|
"MessageShareURLWillBe": "Der Freigabe Link wird <strong>{0}</strong> sein",
|
||||||
|
|||||||
+55
-4
@@ -11,7 +11,7 @@
|
|||||||
"ButtonAuthors": "Szerzők",
|
"ButtonAuthors": "Szerzők",
|
||||||
"ButtonBack": "Vissza",
|
"ButtonBack": "Vissza",
|
||||||
"ButtonBatchEditPopulateFromExisting": "Létezőből feltöltés",
|
"ButtonBatchEditPopulateFromExisting": "Létezőből feltöltés",
|
||||||
"ButtonBatchEditPopulateMapDetails": "",
|
"ButtonBatchEditPopulateMapDetails": "A térkép részleteinek feltöltése",
|
||||||
"ButtonBrowseForFolder": "Mappa keresése",
|
"ButtonBrowseForFolder": "Mappa keresése",
|
||||||
"ButtonCancel": "Mégse",
|
"ButtonCancel": "Mégse",
|
||||||
"ButtonCancelEncode": "Kódolás megszakítása",
|
"ButtonCancelEncode": "Kódolás megszakítása",
|
||||||
@@ -177,6 +177,7 @@
|
|||||||
"HeaderPlaylist": "Lejátszási lista",
|
"HeaderPlaylist": "Lejátszási lista",
|
||||||
"HeaderPlaylistItems": "Lejátszási lista elemek",
|
"HeaderPlaylistItems": "Lejátszási lista elemek",
|
||||||
"HeaderPodcastsToAdd": "Hozzáadandó podcastok",
|
"HeaderPodcastsToAdd": "Hozzáadandó podcastok",
|
||||||
|
"HeaderPresets": "Alapbeállítások",
|
||||||
"HeaderPreviewCover": "Borító előnézete",
|
"HeaderPreviewCover": "Borító előnézete",
|
||||||
"HeaderRSSFeedGeneral": "RSS részletek",
|
"HeaderRSSFeedGeneral": "RSS részletek",
|
||||||
"HeaderRSSFeedIsOpen": "RSS hírcsatorna nyitva van",
|
"HeaderRSSFeedIsOpen": "RSS hírcsatorna nyitva van",
|
||||||
@@ -219,6 +220,7 @@
|
|||||||
"LabelAccountTypeAdmin": "Adminisztrátor",
|
"LabelAccountTypeAdmin": "Adminisztrátor",
|
||||||
"LabelAccountTypeGuest": "Vendég",
|
"LabelAccountTypeGuest": "Vendég",
|
||||||
"LabelAccountTypeUser": "Felhasználó",
|
"LabelAccountTypeUser": "Felhasználó",
|
||||||
|
"LabelActivities": "Tevékenységek",
|
||||||
"LabelActivity": "Tevékenység",
|
"LabelActivity": "Tevékenység",
|
||||||
"LabelAddToCollection": "Hozzáadás a gyűjteményhez",
|
"LabelAddToCollection": "Hozzáadás a gyűjteményhez",
|
||||||
"LabelAddToCollectionBatch": "{0} könyv hozzáadása a gyűjteményhez",
|
"LabelAddToCollectionBatch": "{0} könyv hozzáadása a gyűjteményhez",
|
||||||
@@ -228,6 +230,7 @@
|
|||||||
"LabelAddedDate": "{0} Hozzáadva",
|
"LabelAddedDate": "{0} Hozzáadva",
|
||||||
"LabelAdminUsersOnly": "Csak admin felhasználók",
|
"LabelAdminUsersOnly": "Csak admin felhasználók",
|
||||||
"LabelAll": "Összes",
|
"LabelAll": "Összes",
|
||||||
|
"LabelAllEpisodesDownloaded": "Minden epizód letöltve",
|
||||||
"LabelAllUsers": "Minden felhasználó",
|
"LabelAllUsers": "Minden felhasználó",
|
||||||
"LabelAllUsersExcludingGuests": "Minden felhasználó, vendégek kivételével",
|
"LabelAllUsersExcludingGuests": "Minden felhasználó, vendégek kivételével",
|
||||||
"LabelAllUsersIncludingGuests": "Minden felhasználó, beleértve a vendégeket is",
|
"LabelAllUsersIncludingGuests": "Minden felhasználó, beleértve a vendégeket is",
|
||||||
@@ -251,7 +254,7 @@
|
|||||||
"LabelBackToUser": "Vissza a felhasználóhoz",
|
"LabelBackToUser": "Vissza a felhasználóhoz",
|
||||||
"LabelBackupAudioFiles": "Audiófájlok biztonsági mentése",
|
"LabelBackupAudioFiles": "Audiófájlok biztonsági mentése",
|
||||||
"LabelBackupLocation": "Biztonsági másolat helye",
|
"LabelBackupLocation": "Biztonsági másolat helye",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Automatikus biztonsági másolatok engedélyezése",
|
"LabelBackupsEnableAutomaticBackups": "Automatikus biztonsági másolatok",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Biztonsági másolatok mentése a /metadata/backups mappába",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Biztonsági másolatok mentése a /metadata/backups mappába",
|
||||||
"LabelBackupsMaxBackupSize": "Maximális biztonsági másolat méret (GB-ban) (0-tól végtelenig)",
|
"LabelBackupsMaxBackupSize": "Maximális biztonsági másolat méret (GB-ban) (0-tól végtelenig)",
|
||||||
"LabelBackupsMaxBackupSizeHelp": "A rossz konfiguráció elleni védelem érdekében a biztonsági másolatok meghiúsulnak, ha meghaladják a beállított méretet.",
|
"LabelBackupsMaxBackupSizeHelp": "A rossz konfiguráció elleni védelem érdekében a biztonsági másolatok meghiúsulnak, ha meghaladják a beállított méretet.",
|
||||||
@@ -283,6 +286,7 @@
|
|||||||
"LabelContinueSeries": "Sorozat folytatása",
|
"LabelContinueSeries": "Sorozat folytatása",
|
||||||
"LabelCover": "Borító",
|
"LabelCover": "Borító",
|
||||||
"LabelCoverImageURL": "Borítókép URL",
|
"LabelCoverImageURL": "Borítókép URL",
|
||||||
|
"LabelCoverProvider": "Borító Szolgáltató",
|
||||||
"LabelCreatedAt": "Létrehozás ideje",
|
"LabelCreatedAt": "Létrehozás ideje",
|
||||||
"LabelCronExpression": "Cron kifejezés",
|
"LabelCronExpression": "Cron kifejezés",
|
||||||
"LabelCurrent": "Jelenlegi",
|
"LabelCurrent": "Jelenlegi",
|
||||||
@@ -391,7 +395,8 @@
|
|||||||
"LabelIntervalEvery6Hours": "Minden 6 órában",
|
"LabelIntervalEvery6Hours": "Minden 6 órában",
|
||||||
"LabelIntervalEveryDay": "Minden nap",
|
"LabelIntervalEveryDay": "Minden nap",
|
||||||
"LabelIntervalEveryHour": "Minden órában",
|
"LabelIntervalEveryHour": "Minden órában",
|
||||||
"LabelInvert": "Megfordítás",
|
"LabelIntervalEveryMinute": "Minden percben",
|
||||||
|
"LabelInvert": "Inverz",
|
||||||
"LabelItem": "Elem",
|
"LabelItem": "Elem",
|
||||||
"LabelJumpBackwardAmount": "Visszafelé ugrás mennyisége",
|
"LabelJumpBackwardAmount": "Visszafelé ugrás mennyisége",
|
||||||
"LabelJumpForwardAmount": "Előre ugrás mennyisége",
|
"LabelJumpForwardAmount": "Előre ugrás mennyisége",
|
||||||
@@ -486,6 +491,7 @@
|
|||||||
"LabelPersonalYearReview": "Az éved összefoglalása ({0})",
|
"LabelPersonalYearReview": "Az éved összefoglalása ({0})",
|
||||||
"LabelPhotoPathURL": "Fénykép útvonal/URL",
|
"LabelPhotoPathURL": "Fénykép útvonal/URL",
|
||||||
"LabelPlayMethod": "Lejátszási módszer",
|
"LabelPlayMethod": "Lejátszási módszer",
|
||||||
|
"LabelPlaybackRateIncrementDecrement": "Lejátszási sebesség növelés/csökkentés értéke",
|
||||||
"LabelPlayerChapterNumberMarker": "{0} a {1} -ből",
|
"LabelPlayerChapterNumberMarker": "{0} a {1} -ből",
|
||||||
"LabelPlaylists": "Lejátszási listák",
|
"LabelPlaylists": "Lejátszási listák",
|
||||||
"LabelPodcast": "Podcast",
|
"LabelPodcast": "Podcast",
|
||||||
@@ -508,7 +514,7 @@
|
|||||||
"LabelPublishers": "Kiadók",
|
"LabelPublishers": "Kiadók",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Egyéni tulajdonos e-mail",
|
"LabelRSSFeedCustomOwnerEmail": "Egyéni tulajdonos e-mail",
|
||||||
"LabelRSSFeedCustomOwnerName": "Egyéni tulajdonos neve",
|
"LabelRSSFeedCustomOwnerName": "Egyéni tulajdonos neve",
|
||||||
"LabelRSSFeedOpen": "RSS hírcsatorna nyitva",
|
"LabelRSSFeedOpen": "RSS-hírcsatorna nyitva",
|
||||||
"LabelRSSFeedPreventIndexing": "Indexelés megakadályozása",
|
"LabelRSSFeedPreventIndexing": "Indexelés megakadályozása",
|
||||||
"LabelRSSFeedSlug": "RSS hírcsatorna slug",
|
"LabelRSSFeedSlug": "RSS hírcsatorna slug",
|
||||||
"LabelRSSFeedURL": "RSS hírcsatorna URL",
|
"LabelRSSFeedURL": "RSS hírcsatorna URL",
|
||||||
@@ -525,6 +531,7 @@
|
|||||||
"LabelReleaseDate": "Megjelenés dátuma",
|
"LabelReleaseDate": "Megjelenés dátuma",
|
||||||
"LabelRemoveAllMetadataAbs": "Az összes metadata.abs fájl eltávolítása",
|
"LabelRemoveAllMetadataAbs": "Az összes metadata.abs fájl eltávolítása",
|
||||||
"LabelRemoveAllMetadataJson": "Az összes metadata.json fájl eltávolítása",
|
"LabelRemoveAllMetadataJson": "Az összes metadata.json fájl eltávolítása",
|
||||||
|
"LabelRemoveAudibleBranding": "Audible intro és outro eltávolítása a fejezetekből",
|
||||||
"LabelRemoveCover": "Borító eltávolítása",
|
"LabelRemoveCover": "Borító eltávolítása",
|
||||||
"LabelRemoveMetadataFile": "Metaadatfájlok eltávolítása a könyvtár elemek mappáiból",
|
"LabelRemoveMetadataFile": "Metaadatfájlok eltávolítása a könyvtár elemek mappáiból",
|
||||||
"LabelRemoveMetadataFileHelp": "A metadata.json és metadata.abs fájlokat eltávolítása a {0} mappáidból.",
|
"LabelRemoveMetadataFileHelp": "A metadata.json és metadata.abs fájlokat eltávolítása a {0} mappáidból.",
|
||||||
@@ -554,6 +561,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Skeuomorfikus dizájn fa polcokkal",
|
"LabelSettingsBookshelfViewHelp": "Skeuomorfikus dizájn fa polcokkal",
|
||||||
"LabelSettingsChromecastSupport": "Chromecast támogatás",
|
"LabelSettingsChromecastSupport": "Chromecast támogatás",
|
||||||
"LabelSettingsDateFormat": "Dátumformátum",
|
"LabelSettingsDateFormat": "Dátumformátum",
|
||||||
|
"LabelSettingsEnableWatcher": "Változások automatikus vizsgálata a könyvtárakban",
|
||||||
|
"LabelSettingsEnableWatcherForLibrary": "Változások automatikus vizsgálata a könyvtárban",
|
||||||
"LabelSettingsEnableWatcherHelp": "Engedélyezi az automatikus elem hozzáadás/frissítés funkciót, amikor fájlváltozásokat észlel. *Szerver újraindítása szükséges",
|
"LabelSettingsEnableWatcherHelp": "Engedélyezi az automatikus elem hozzáadás/frissítés funkciót, amikor fájlváltozásokat észlel. *Szerver újraindítása szükséges",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Szkriptelt tartalmak engedélyezése epub-okban",
|
"LabelSettingsEpubsAllowScriptedContent": "Szkriptelt tartalmak engedélyezése epub-okban",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Megengedi, hogy az epub fájlok szkripteket hajtsanak végre. Ezt a beállítást kikapcsolva ajánlott tartani, kivéve, ha megbízik az epub fájlok forrásában.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Megengedi, hogy az epub fájlok szkripteket hajtsanak végre. Ezt a beállítást kikapcsolva ajánlott tartani, kivéve, ha megbízik az epub fájlok forrásában.",
|
||||||
@@ -597,6 +606,7 @@
|
|||||||
"LabelSlug": "Rövid cím",
|
"LabelSlug": "Rövid cím",
|
||||||
"LabelSortAscending": "Emelkedő",
|
"LabelSortAscending": "Emelkedő",
|
||||||
"LabelSortDescending": "Csökkenő",
|
"LabelSortDescending": "Csökkenő",
|
||||||
|
"LabelSortPubDate": "Rendezés megjelenés dátuma szerint",
|
||||||
"LabelStart": "Kezdés",
|
"LabelStart": "Kezdés",
|
||||||
"LabelStartTime": "Kezdési idő",
|
"LabelStartTime": "Kezdési idő",
|
||||||
"LabelStarted": "Elkezdődött",
|
"LabelStarted": "Elkezdődött",
|
||||||
@@ -697,12 +707,17 @@
|
|||||||
"LabelYourProgress": "Haladásod",
|
"LabelYourProgress": "Haladásod",
|
||||||
"MessageAddToPlayerQueue": "Hozzáadás a lejátszó sorhoz",
|
"MessageAddToPlayerQueue": "Hozzáadás a lejátszó sorhoz",
|
||||||
"MessageAppriseDescription": "Ennek a funkció használatához futtatnia kell egy <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> példányt vagy egy olyan API-t, amely kezeli ezeket a kéréseket. <br />Az Apprise API URL-nek a teljes URL útvonalat kell tartalmaznia az értesítés elküldéséhez, például, ha az API példánya a <code>http://192.168.1.1:8337</code> címen szolgáltatva, akkor <code>http://192.168.1.1:8337/notify</code> értéket kell megadnia.",
|
"MessageAppriseDescription": "Ennek a funkció használatához futtatnia kell egy <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> példányt vagy egy olyan API-t, amely kezeli ezeket a kéréseket. <br />Az Apprise API URL-nek a teljes URL útvonalat kell tartalmaznia az értesítés elküldéséhez, például, ha az API példánya a <code>http://192.168.1.1:8337</code> címen szolgáltatva, akkor <code>http://192.168.1.1:8337/notify</code> értéket kell megadnia.",
|
||||||
|
"MessageAsinCheck": "Győződjön meg róla, hogy az ASIN-t a megfelelő Audible régióból használja, nem az Amazonból.",
|
||||||
|
"MessageAuthenticationOIDCChangesRestart": "A mentés után indítsa újra a szervert az OIDC módosítások alkalmazásához.",
|
||||||
"MessageBackupsDescription": "A biztonsági másolatok tartalmazzák a felhasználókat, a felhasználói haladást, a könyvtári elem részleteit, a szerver beállításait és a képeket, amelyek a <code>/metadata/items</code> és <code>/metadata/authors</code> mappákban vannak tárolva. A biztonsági másolatok <strong>nem</strong> tartalmazzák a könyvtári mappákban tárolt fájlokat.",
|
"MessageBackupsDescription": "A biztonsági másolatok tartalmazzák a felhasználókat, a felhasználói haladást, a könyvtári elem részleteit, a szerver beállításait és a képeket, amelyek a <code>/metadata/items</code> és <code>/metadata/authors</code> mappákban vannak tárolva. A biztonsági másolatok <strong>nem</strong> tartalmazzák a könyvtári mappákban tárolt fájlokat.",
|
||||||
"MessageBackupsLocationEditNote": "Megjegyzés: A biztonsági mentés helyének frissítése nem mozgatja vagy módosítja a meglévő biztonsági mentéseket",
|
"MessageBackupsLocationEditNote": "Megjegyzés: A biztonsági mentés helyének frissítése nem mozgatja vagy módosítja a meglévő biztonsági mentéseket",
|
||||||
"MessageBackupsLocationNoEditNote": "Megjegyzés: A biztonsági mentés helye egy környezeti változóval van beállítva, és itt nem módosítható.",
|
"MessageBackupsLocationNoEditNote": "Megjegyzés: A biztonsági mentés helye egy környezeti változóval van beállítva, és itt nem módosítható.",
|
||||||
"MessageBackupsLocationPathEmpty": "A biztonsági mentés helyének elérési útvonala nem lehet üres",
|
"MessageBackupsLocationPathEmpty": "A biztonsági mentés helyének elérési útvonala nem lehet üres",
|
||||||
|
"MessageBatchEditPopulateMapDetailsAllHelp": "Az engedélyezett mezők feltöltése az összes elem adatával. A több értéket tartalmazó mezők összevonásra kerülnek",
|
||||||
|
"MessageBatchEditPopulateMapDetailsItemHelp": "A térkép engedélyezett adatmezőinek feltöltése ezen elem adataival",
|
||||||
"MessageBatchQuickMatchDescription": "A Gyors egyeztetés megpróbálja hozzáadni a hiányzó borítókat és metaadatokat a kiválasztott elemekhez. Engedélyezze az alábbi opciókat, hogy a Gyors egyeztetés felülírhassa a meglévő borítókat és/vagy metaadatokat.",
|
"MessageBatchQuickMatchDescription": "A Gyors egyeztetés megpróbálja hozzáadni a hiányzó borítókat és metaadatokat a kiválasztott elemekhez. Engedélyezze az alábbi opciókat, hogy a Gyors egyeztetés felülírhassa a meglévő borítókat és/vagy metaadatokat.",
|
||||||
"MessageBookshelfNoCollections": "Még nem készített gyűjteményeket",
|
"MessageBookshelfNoCollections": "Még nem készített gyűjteményeket",
|
||||||
|
"MessageBookshelfNoCollectionsHelp": "A gyűjtemények nyilvánosak. Minden, a könyvtárhoz hozzáféréssel rendelkező felhasználó láthatja őket.",
|
||||||
"MessageBookshelfNoRSSFeeds": "Nincsenek nyitott RSS hírcsatornák",
|
"MessageBookshelfNoRSSFeeds": "Nincsenek nyitott RSS hírcsatornák",
|
||||||
"MessageBookshelfNoResultsForFilter": "Nincs eredmény a \"{0}: {1}\" szűrőre",
|
"MessageBookshelfNoResultsForFilter": "Nincs eredmény a \"{0}: {1}\" szűrőre",
|
||||||
"MessageBookshelfNoResultsForQuery": "Nincs eredmény a lekérdezéshez",
|
"MessageBookshelfNoResultsForQuery": "Nincs eredmény a lekérdezéshez",
|
||||||
@@ -712,6 +727,7 @@
|
|||||||
"MessageChapterErrorStartGteDuration": "Érvénytelen kezdési idő, kevesebbnek kell lennie, mint a hangoskönyv időtartama",
|
"MessageChapterErrorStartGteDuration": "Érvénytelen kezdési idő, kevesebbnek kell lennie, mint a hangoskönyv időtartama",
|
||||||
"MessageChapterErrorStartLtPrev": "Érvénytelen kezdési idő, nagyobbnak kell lennie, mint az előző fejezet kezdési ideje",
|
"MessageChapterErrorStartLtPrev": "Érvénytelen kezdési idő, nagyobbnak kell lennie, mint az előző fejezet kezdési ideje",
|
||||||
"MessageChapterStartIsAfter": "A fejezet kezdete a hangoskönyv végét követi",
|
"MessageChapterStartIsAfter": "A fejezet kezdete a hangoskönyv végét követi",
|
||||||
|
"MessageChaptersNotFound": "Fejezetek nem találhatók",
|
||||||
"MessageCheckingCron": "Cron ellenőrzése...",
|
"MessageCheckingCron": "Cron ellenőrzése...",
|
||||||
"MessageConfirmCloseFeed": "Biztosan be szeretné zárni ezt a hírcsatornát?",
|
"MessageConfirmCloseFeed": "Biztosan be szeretné zárni ezt a hírcsatornát?",
|
||||||
"MessageConfirmDeleteBackup": "Biztosan törölni szeretné a(z) {0} biztonsági másolatot?",
|
"MessageConfirmDeleteBackup": "Biztosan törölni szeretné a(z) {0} biztonsági másolatot?",
|
||||||
@@ -768,6 +784,7 @@
|
|||||||
"MessageForceReScanDescription": "minden fájlt újra szkennel, mint egy friss szkennelés. Az audiofájlok ID3 címkéi, OPF fájlok és szövegfájlok újként lesznek szkennelve.",
|
"MessageForceReScanDescription": "minden fájlt újra szkennel, mint egy friss szkennelés. Az audiofájlok ID3 címkéi, OPF fájlok és szövegfájlok újként lesznek szkennelve.",
|
||||||
"MessageImportantNotice": "Fontos közlemény!",
|
"MessageImportantNotice": "Fontos közlemény!",
|
||||||
"MessageInsertChapterBelow": "Fejezet beszúrása alulra",
|
"MessageInsertChapterBelow": "Fejezet beszúrása alulra",
|
||||||
|
"MessageInvalidAsin": "Érvénytelen ASIN",
|
||||||
"MessageItemsSelected": "{0} kiválasztott elem",
|
"MessageItemsSelected": "{0} kiválasztott elem",
|
||||||
"MessageItemsUpdated": "{0} frissített elem",
|
"MessageItemsUpdated": "{0} frissített elem",
|
||||||
"MessageJoinUsOn": "Csatlakozzon hozzánk a",
|
"MessageJoinUsOn": "Csatlakozzon hozzánk a",
|
||||||
@@ -813,6 +830,7 @@
|
|||||||
"MessageNoTasksRunning": "Nincsenek futó feladatok",
|
"MessageNoTasksRunning": "Nincsenek futó feladatok",
|
||||||
"MessageNoUpdatesWereNecessary": "Nem volt szükség frissítésekre",
|
"MessageNoUpdatesWereNecessary": "Nem volt szükség frissítésekre",
|
||||||
"MessageNoUserPlaylists": "Nincsenek felhasználói lejátszási listák",
|
"MessageNoUserPlaylists": "Nincsenek felhasználói lejátszási listák",
|
||||||
|
"MessageNoUserPlaylistsHelp": "A lejátszási listák személyesek. Csak az a felhasználó láthatja őket, aki létrehozta őket.",
|
||||||
"MessageNotYetImplemented": "Még nem implementált",
|
"MessageNotYetImplemented": "Még nem implementált",
|
||||||
"MessageOpmlPreviewNote": "Megjegyzés: Ez egy előnézeti kép az elemzett OPML fájlról. A podcast tényleges címe az RSS hírcsatornából származik.",
|
"MessageOpmlPreviewNote": "Megjegyzés: Ez egy előnézeti kép az elemzett OPML fájlról. A podcast tényleges címe az RSS hírcsatornából származik.",
|
||||||
"MessageOr": "vagy",
|
"MessageOr": "vagy",
|
||||||
@@ -835,8 +853,10 @@
|
|||||||
"MessageRestoreBackupConfirm": "Biztosan vissza szeretné állítani a biztonsági másolatot, amely ekkor készült:",
|
"MessageRestoreBackupConfirm": "Biztosan vissza szeretné állítani a biztonsági másolatot, amely ekkor készült:",
|
||||||
"MessageRestoreBackupWarning": "A biztonsági mentés visszaállítása felülírja az egész adatbázist, amely a /config mappában található, valamint a borítóképeket a /metadata/items és /metadata/authors mappákban.<br /><br />A biztonsági mentések nem módosítják a könyvtár mappáiban található fájlokat. Ha engedélyezte a szerverbeállításokat a borítóképek és a metaadatok könyvtármappákban való tárolására, akkor ezek nem kerülnek biztonsági mentésre vagy felülírásra.<br /><br />A szerver használó összes kliens automatikusan frissül.",
|
"MessageRestoreBackupWarning": "A biztonsági mentés visszaállítása felülírja az egész adatbázist, amely a /config mappában található, valamint a borítóképeket a /metadata/items és /metadata/authors mappákban.<br /><br />A biztonsági mentések nem módosítják a könyvtár mappáiban található fájlokat. Ha engedélyezte a szerverbeállításokat a borítóképek és a metaadatok könyvtármappákban való tárolására, akkor ezek nem kerülnek biztonsági mentésre vagy felülírásra.<br /><br />A szerver használó összes kliens automatikusan frissül.",
|
||||||
"MessageScheduleLibraryScanNote": "A legtöbb felhasználó számára ajánlott ezt a funkciót kikapcsolva hagyni, és engedélyezni a mappafigyelő beállítást. A mappafigyelő automatikusan észleli a könyvtári mappák változásait. A mappafigyelő nem működik minden fájlrendszernél (mint például az NFS), ezért helyette ütemezett könyvtárellenőrzéseket lehet használni.",
|
"MessageScheduleLibraryScanNote": "A legtöbb felhasználó számára ajánlott ezt a funkciót kikapcsolva hagyni, és engedélyezni a mappafigyelő beállítást. A mappafigyelő automatikusan észleli a könyvtári mappák változásait. A mappafigyelő nem működik minden fájlrendszernél (mint például az NFS), ezért helyette ütemezett könyvtárellenőrzéseket lehet használni.",
|
||||||
|
"MessageScheduleRunEveryWeekdayAtTime": "Futás minden {1} óra {0}-kor",
|
||||||
"MessageSearchResultsFor": "Keresési eredmények",
|
"MessageSearchResultsFor": "Keresési eredmények",
|
||||||
"MessageSelected": "{0} kiválasztva",
|
"MessageSelected": "{0} kiválasztva",
|
||||||
|
"MessageSeriesSequenceCannotContainSpaces": "Sorozat sorrend nem tartalmazhat szóközt",
|
||||||
"MessageServerCouldNotBeReached": "A szervert nem lehet elérni",
|
"MessageServerCouldNotBeReached": "A szervert nem lehet elérni",
|
||||||
"MessageSetChaptersFromTracksDescription": "Fejezetek beállítása minden egyes hangfájlt egy fejezetként használva, és a fejezet címét a hangfájl neveként",
|
"MessageSetChaptersFromTracksDescription": "Fejezetek beállítása minden egyes hangfájlt egy fejezetként használva, és a fejezet címét a hangfájl neveként",
|
||||||
"MessageShareExpirationWillBe": "A lejárat: <strong>{0}</strong>",
|
"MessageShareExpirationWillBe": "A lejárat: <strong>{0}</strong>",
|
||||||
@@ -861,6 +881,7 @@
|
|||||||
"MessageTaskNoFilesToScan": "Nincs beolvasandó fájl",
|
"MessageTaskNoFilesToScan": "Nincs beolvasandó fájl",
|
||||||
"MessageTaskOpmlImport": "OPML import",
|
"MessageTaskOpmlImport": "OPML import",
|
||||||
"MessageTaskOpmlImportDescription": "Podcastok létrehozása {0} RSS hírcsatornából",
|
"MessageTaskOpmlImportDescription": "Podcastok létrehozása {0} RSS hírcsatornából",
|
||||||
|
"MessageTaskOpmlImportFeed": "OPML import hírcsatorna",
|
||||||
"MessageTaskOpmlImportFeedDescription": "RSS feed „{0}” importálása",
|
"MessageTaskOpmlImportFeedDescription": "RSS feed „{0}” importálása",
|
||||||
"MessageTaskOpmlImportFeedFailed": "Nem sikerült letölteni a podcast feedet",
|
"MessageTaskOpmlImportFeedFailed": "Nem sikerült letölteni a podcast feedet",
|
||||||
"MessageTaskOpmlImportFeedPodcastDescription": "„{0}” podcast létrehozása",
|
"MessageTaskOpmlImportFeedPodcastDescription": "„{0}” podcast létrehozása",
|
||||||
@@ -869,6 +890,7 @@
|
|||||||
"MessageTaskOpmlImportFinished": "{0} podcast hozzáadva",
|
"MessageTaskOpmlImportFinished": "{0} podcast hozzáadva",
|
||||||
"MessageTaskOpmlParseFailed": "Az OPML fájl elemzése nem sikerült",
|
"MessageTaskOpmlParseFailed": "Az OPML fájl elemzése nem sikerült",
|
||||||
"MessageTaskOpmlParseFastFail": "Érvénytelen OPML fájl: <opml> tag nem található VAGY nem találtak <outline> taget",
|
"MessageTaskOpmlParseFastFail": "Érvénytelen OPML fájl: <opml> tag nem található VAGY nem találtak <outline> taget",
|
||||||
|
"MessageTaskOpmlParseNoneFound": "Nem található feed az OPML fájlban",
|
||||||
"MessageTaskScanItemsAdded": "{0} hozzáadva",
|
"MessageTaskScanItemsAdded": "{0} hozzáadva",
|
||||||
"MessageTaskScanItemsMissing": "{0} hiányzik",
|
"MessageTaskScanItemsMissing": "{0} hiányzik",
|
||||||
"MessageTaskScanItemsUpdated": "{0} frissítve",
|
"MessageTaskScanItemsUpdated": "{0} frissítve",
|
||||||
@@ -896,6 +918,8 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "A biztonsági mentés befejezésekor aktiválódik",
|
"NotificationOnBackupCompletedDescription": "A biztonsági mentés befejezésekor aktiválódik",
|
||||||
"NotificationOnBackupFailedDescription": "A biztonsági mentés sikertelensége esetén aktiválódik",
|
"NotificationOnBackupFailedDescription": "A biztonsági mentés sikertelensége esetén aktiválódik",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "Egy podcast epizód automatikus letöltésekor aktiválódik",
|
"NotificationOnEpisodeDownloadedDescription": "Egy podcast epizód automatikus letöltésekor aktiválódik",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Akkor lép működésbe, ha az automatikus epizódletöltés a túl sok sikertelen próbálkozás miatt letiltásra kerül",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Akkor aktiválódik, ha az RSS feed kérés sikertelen az automatikus epizódletöltésnél",
|
||||||
"NotificationOnTestDescription": "Esemény az értesítési rendszer teszteléséhez",
|
"NotificationOnTestDescription": "Esemény az értesítési rendszer teszteléséhez",
|
||||||
"PlaceholderNewCollection": "Új gyűjtemény neve",
|
"PlaceholderNewCollection": "Új gyűjtemény neve",
|
||||||
"PlaceholderNewFolderPath": "Új mappa útvonala",
|
"PlaceholderNewFolderPath": "Új mappa útvonala",
|
||||||
@@ -940,8 +964,11 @@
|
|||||||
"ToastBackupRestoreFailed": "A biztonsági mentés visszaállítása sikertelen",
|
"ToastBackupRestoreFailed": "A biztonsági mentés visszaállítása sikertelen",
|
||||||
"ToastBackupUploadFailed": "A biztonsági mentés feltöltése sikertelen",
|
"ToastBackupUploadFailed": "A biztonsági mentés feltöltése sikertelen",
|
||||||
"ToastBackupUploadSuccess": "Biztonsági mentés feltöltve",
|
"ToastBackupUploadSuccess": "Biztonsági mentés feltöltve",
|
||||||
|
"ToastBatchApplyDetailsToItemsSuccess": "Tételekre alkalmazott részletek",
|
||||||
"ToastBatchDeleteFailed": "A tömeges törlés nem sikerült",
|
"ToastBatchDeleteFailed": "A tömeges törlés nem sikerült",
|
||||||
"ToastBatchDeleteSuccess": "Sikeres tömeges törlés",
|
"ToastBatchDeleteSuccess": "Sikeres tömeges törlés",
|
||||||
|
"ToastBatchQuickMatchFailed": "Tömeges Gyors Egyeztetés sikertelen!",
|
||||||
|
"ToastBatchQuickMatchStarted": "{0} könyv Tömeges Gyors Egyeztetése elkezdődött!",
|
||||||
"ToastBatchUpdateFailed": "Kötegelt frissítés sikertelen",
|
"ToastBatchUpdateFailed": "Kötegelt frissítés sikertelen",
|
||||||
"ToastBatchUpdateSuccess": "Kötegelt frissítés sikeres",
|
"ToastBatchUpdateSuccess": "Kötegelt frissítés sikeres",
|
||||||
"ToastBookmarkCreateFailed": "Könyvjelző létrehozása sikertelen",
|
"ToastBookmarkCreateFailed": "Könyvjelző létrehozása sikertelen",
|
||||||
@@ -950,9 +977,12 @@
|
|||||||
"ToastCachePurgeFailed": "A gyorsítótár törlése sikertelen",
|
"ToastCachePurgeFailed": "A gyorsítótár törlése sikertelen",
|
||||||
"ToastCachePurgeSuccess": "A gyorsítótár sikeresen törölve",
|
"ToastCachePurgeSuccess": "A gyorsítótár sikeresen törölve",
|
||||||
"ToastChaptersHaveErrors": "A fejezetek hibákat tartalmaznak",
|
"ToastChaptersHaveErrors": "A fejezetek hibákat tartalmaznak",
|
||||||
|
"ToastChaptersInvalidShiftAmountLast": "Érvénytelen eltolási érték. Az utolsó fejezet kezdési időpontja túlnyúlna a hangoskönyv időtartamán.",
|
||||||
|
"ToastChaptersInvalidShiftAmountStart": "Érvénytelen eltolási érték. Az első fejezet hossza nulla vagy negatív lenne, és a második fejezet felülírná. Növelje a második fejezet kezdő időtartamát.",
|
||||||
"ToastChaptersMustHaveTitles": "A fejezeteknek címekkel kell rendelkezniük",
|
"ToastChaptersMustHaveTitles": "A fejezeteknek címekkel kell rendelkezniük",
|
||||||
"ToastChaptersRemoved": "Fejezetek eltávolítva",
|
"ToastChaptersRemoved": "Fejezetek eltávolítva",
|
||||||
"ToastChaptersUpdated": "Fejezetek frissítve",
|
"ToastChaptersUpdated": "Fejezetek frissítve",
|
||||||
|
"ToastCollectionItemsAddFailed": "A tétel(ek) hozzáadása gyűjteményhez sikertelen",
|
||||||
"ToastCollectionRemoveSuccess": "Gyűjtemény eltávolítva",
|
"ToastCollectionRemoveSuccess": "Gyűjtemény eltávolítva",
|
||||||
"ToastCollectionUpdateSuccess": "Gyűjtemény frissítve",
|
"ToastCollectionUpdateSuccess": "Gyűjtemény frissítve",
|
||||||
"ToastCoverUpdateFailed": "A borító frissítése nem sikerült",
|
"ToastCoverUpdateFailed": "A borító frissítése nem sikerült",
|
||||||
@@ -967,6 +997,7 @@
|
|||||||
"ToastEncodeCancelFailed": "A kódolás törlése sikertelen volt",
|
"ToastEncodeCancelFailed": "A kódolás törlése sikertelen volt",
|
||||||
"ToastEncodeCancelSucces": "Kódolás törölve",
|
"ToastEncodeCancelSucces": "Kódolás törölve",
|
||||||
"ToastEpisodeDownloadQueueClearFailed": "Nem sikerült törölni a várólistát",
|
"ToastEpisodeDownloadQueueClearFailed": "Nem sikerült törölni a várólistát",
|
||||||
|
"ToastEpisodeDownloadQueueClearSuccess": "Epizód letöltési várólista törölve",
|
||||||
"ToastEpisodeUpdateSuccess": "{0} epizód frissítve",
|
"ToastEpisodeUpdateSuccess": "{0} epizód frissítve",
|
||||||
"ToastErrorCannotShare": "Ezen az eszközön nem lehet natívan megosztani",
|
"ToastErrorCannotShare": "Ezen az eszközön nem lehet natívan megosztani",
|
||||||
"ToastFailedToLoadData": "Sikertelen adatbetöltés",
|
"ToastFailedToLoadData": "Sikertelen adatbetöltés",
|
||||||
@@ -974,6 +1005,7 @@
|
|||||||
"ToastFailedToShare": "Nem sikerült megosztani",
|
"ToastFailedToShare": "Nem sikerült megosztani",
|
||||||
"ToastFailedToUpdate": "Nem sikerült frissíteni",
|
"ToastFailedToUpdate": "Nem sikerült frissíteni",
|
||||||
"ToastInvalidImageUrl": "Érvénytelen a kép URL címe",
|
"ToastInvalidImageUrl": "Érvénytelen a kép URL címe",
|
||||||
|
"ToastInvalidMaxEpisodesToDownload": "A letölthető epizódok száma érvénytelen",
|
||||||
"ToastInvalidUrl": "Érvénytelen URL",
|
"ToastInvalidUrl": "Érvénytelen URL",
|
||||||
"ToastItemCoverUpdateSuccess": "Elem borítója frissítve",
|
"ToastItemCoverUpdateSuccess": "Elem borítója frissítve",
|
||||||
"ToastItemDeletedFailed": "Nem sikerült törölni az elemet",
|
"ToastItemDeletedFailed": "Nem sikerült törölni az elemet",
|
||||||
@@ -1011,8 +1043,11 @@
|
|||||||
"ToastNoUpdatesNecessary": "Nincs szükség frissítésre",
|
"ToastNoUpdatesNecessary": "Nincs szükség frissítésre",
|
||||||
"ToastNotificationCreateFailed": "Értesítés létrehozása sikertelen",
|
"ToastNotificationCreateFailed": "Értesítés létrehozása sikertelen",
|
||||||
"ToastNotificationDeleteFailed": "Értesítés törlése sikertelen",
|
"ToastNotificationDeleteFailed": "Értesítés törlése sikertelen",
|
||||||
|
"ToastNotificationFailedMaximum": "A sikertelen kísérletek maximális száma >= 0 kell, hogy legyen",
|
||||||
|
"ToastNotificationQueueMaximum": "Az értesítési sor maximális száma >= 0 kell, hogy legyen",
|
||||||
"ToastNotificationSettingsUpdateSuccess": "Értesítési beállítások frissítve",
|
"ToastNotificationSettingsUpdateSuccess": "Értesítési beállítások frissítve",
|
||||||
"ToastNotificationTestTriggerFailed": "Nem sikerült a tesztértesítést elindítani",
|
"ToastNotificationTestTriggerFailed": "Nem sikerült a tesztértesítést elindítani",
|
||||||
|
"ToastNotificationTestTriggerSuccess": "Kiváltott tesztértesítés",
|
||||||
"ToastNotificationUpdateSuccess": "Értesítés frissítve",
|
"ToastNotificationUpdateSuccess": "Értesítés frissítve",
|
||||||
"ToastPlaylistCreateFailed": "Lejátszási lista létrehozása sikertelen",
|
"ToastPlaylistCreateFailed": "Lejátszási lista létrehozása sikertelen",
|
||||||
"ToastPlaylistCreateSuccess": "Lejátszási lista létrehozva",
|
"ToastPlaylistCreateSuccess": "Lejátszási lista létrehozva",
|
||||||
@@ -1020,6 +1055,7 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "Lejátszási lista frissítve",
|
"ToastPlaylistUpdateSuccess": "Lejátszási lista frissítve",
|
||||||
"ToastPodcastCreateFailed": "Podcast létrehozása sikertelen",
|
"ToastPodcastCreateFailed": "Podcast létrehozása sikertelen",
|
||||||
"ToastPodcastCreateSuccess": "A podcast sikeresen létrehozva",
|
"ToastPodcastCreateSuccess": "A podcast sikeresen létrehozva",
|
||||||
|
"ToastPodcastGetFeedFailed": "Nem sikerült podcast feedet kapni",
|
||||||
"ToastPodcastNoEpisodesInFeed": "Nincsenek epizódok az RSS hírcsatornában",
|
"ToastPodcastNoEpisodesInFeed": "Nincsenek epizódok az RSS hírcsatornában",
|
||||||
"ToastPodcastNoRssFeed": "A podcastnak nincs RSS-hírcsatornája",
|
"ToastPodcastNoRssFeed": "A podcastnak nincs RSS-hírcsatornája",
|
||||||
"ToastProgressIsNotBeingSynced": "Az előrehaladás nem szinkronizálódik, a lejátszás újraindul",
|
"ToastProgressIsNotBeingSynced": "Az előrehaladás nem szinkronizálódik, a lejátszás újraindul",
|
||||||
@@ -1032,10 +1068,18 @@
|
|||||||
"ToastRemoveFailed": "Sikertelen eltávolítás",
|
"ToastRemoveFailed": "Sikertelen eltávolítás",
|
||||||
"ToastRemoveItemFromCollectionFailed": "Tétel eltávolítása a gyűjteményből sikertelen",
|
"ToastRemoveItemFromCollectionFailed": "Tétel eltávolítása a gyűjteményből sikertelen",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "Tétel eltávolítva a gyűjteményből",
|
"ToastRemoveItemFromCollectionSuccess": "Tétel eltávolítva a gyűjteményből",
|
||||||
|
"ToastRemoveItemsWithIssuesFailed": "Nem sikerült eltávolítani a hibás könyvtárelemeket",
|
||||||
|
"ToastRemoveItemsWithIssuesSuccess": "Hibás könyvtárelemek eltávolítva",
|
||||||
"ToastRenameFailed": "Sikertelen átnevezés",
|
"ToastRenameFailed": "Sikertelen átnevezés",
|
||||||
|
"ToastRescanFailed": "Sikertelen újrakeresés a következőnél: {0}",
|
||||||
|
"ToastRescanRemoved": "A teljes újrabeolvasás befejezve, elem eltávolítva",
|
||||||
|
"ToastRescanUpToDate": "A teljes újrabeolvasás befejezve, elem naprakész volt",
|
||||||
|
"ToastRescanUpdated": "A teljes újrabeolvasás befejezve, elem frissítve",
|
||||||
|
"ToastScanFailed": "Nem sikerült beolvasni a könyvtárelemet",
|
||||||
"ToastSelectAtLeastOneUser": "Válasszon legalább egy felhasználót",
|
"ToastSelectAtLeastOneUser": "Válasszon legalább egy felhasználót",
|
||||||
"ToastSendEbookToDeviceFailed": "E-könyv küldése az eszközre sikertelen",
|
"ToastSendEbookToDeviceFailed": "E-könyv küldése az eszközre sikertelen",
|
||||||
"ToastSendEbookToDeviceSuccess": "E-könyv elküldve az eszközre \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "E-könyv elküldve az eszközre \"{0}\"",
|
||||||
|
"ToastSeriesSubmitFailedSameName": "Nem lehet két azonos nevű sorozatot hozzáadni",
|
||||||
"ToastSeriesUpdateFailed": "Sorozat frissítése sikertelen",
|
"ToastSeriesUpdateFailed": "Sorozat frissítése sikertelen",
|
||||||
"ToastSeriesUpdateSuccess": "Sorozat frissítése sikeres",
|
"ToastSeriesUpdateSuccess": "Sorozat frissítése sikeres",
|
||||||
"ToastServerSettingsUpdateSuccess": "Szerver beállítások frissítve",
|
"ToastServerSettingsUpdateSuccess": "Szerver beállítások frissítve",
|
||||||
@@ -1043,6 +1087,8 @@
|
|||||||
"ToastSessionDeleteFailed": "Munkamenet törlése sikertelen",
|
"ToastSessionDeleteFailed": "Munkamenet törlése sikertelen",
|
||||||
"ToastSessionDeleteSuccess": "Munkamenet törölve",
|
"ToastSessionDeleteSuccess": "Munkamenet törölve",
|
||||||
"ToastSleepTimerDone": "Alvásidőzítő kész... zZzzZZz",
|
"ToastSleepTimerDone": "Alvásidőzítő kész... zZzzZZz",
|
||||||
|
"ToastSlugMustChange": "A Slug érvénytelen karaktereket tartalmaz",
|
||||||
|
"ToastSlugRequired": "Slug szükséges",
|
||||||
"ToastSocketConnected": "Socket csatlakoztatva",
|
"ToastSocketConnected": "Socket csatlakoztatva",
|
||||||
"ToastSocketDisconnected": "Socket lecsatlakoztatva",
|
"ToastSocketDisconnected": "Socket lecsatlakoztatva",
|
||||||
"ToastSocketFailedToConnect": "A Socket csatlakoztatása sikertelen",
|
"ToastSocketFailedToConnect": "A Socket csatlakoztatása sikertelen",
|
||||||
@@ -1050,9 +1096,14 @@
|
|||||||
"ToastSortingPrefixesUpdateSuccess": "Rendezési előtagok frissítése ({0} elem)",
|
"ToastSortingPrefixesUpdateSuccess": "Rendezési előtagok frissítése ({0} elem)",
|
||||||
"ToastTitleRequired": "A cím kötelező",
|
"ToastTitleRequired": "A cím kötelező",
|
||||||
"ToastUnknownError": "Ismeretlen hiba",
|
"ToastUnknownError": "Ismeretlen hiba",
|
||||||
|
"ToastUnlinkOpenIdFailed": "Nem sikerült leválasztani a felhasználót az OpenID-ről",
|
||||||
|
"ToastUnlinkOpenIdSuccess": "Felhasználó leválasztva az OpenID-ről",
|
||||||
|
"ToastUploaderFilepathExistsError": "A \"{0}\" fájl elérési útja már létezik a szerveren",
|
||||||
|
"ToastUploaderItemExistsInSubdirectoryError": "A „{0}” elem a feltöltési útvonal egy alkönyvtárát használja.",
|
||||||
"ToastUserDeleteFailed": "Felhasználó törlése sikertelen",
|
"ToastUserDeleteFailed": "Felhasználó törlése sikertelen",
|
||||||
"ToastUserDeleteSuccess": "Felhasználó törölve",
|
"ToastUserDeleteSuccess": "Felhasználó törölve",
|
||||||
"ToastUserPasswordChangeSuccess": "Jelszó sikeresen megváltoztatva",
|
"ToastUserPasswordChangeSuccess": "Jelszó sikeresen megváltoztatva",
|
||||||
|
"ToastUserPasswordMismatch": "A jelszavak nem egyeznek",
|
||||||
"ToastUserPasswordMustChange": "Az új jelszó nem egyezik a régi jelszóval",
|
"ToastUserPasswordMustChange": "Az új jelszó nem egyezik a régi jelszóval",
|
||||||
"ToastUserRootRequireName": "Egy root felhasználónevet kell megadnia"
|
"ToastUserRootRequireName": "Egy root felhasználónevet kell megadnia"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -394,6 +394,7 @@
|
|||||||
"LabelIntervalEvery6Hours": "Iedere 6 uur",
|
"LabelIntervalEvery6Hours": "Iedere 6 uur",
|
||||||
"LabelIntervalEveryDay": "Iedere dag",
|
"LabelIntervalEveryDay": "Iedere dag",
|
||||||
"LabelIntervalEveryHour": "Ieder uur",
|
"LabelIntervalEveryHour": "Ieder uur",
|
||||||
|
"LabelIntervalEveryMinute": "Elke minuut",
|
||||||
"LabelInvert": "Omdraaien",
|
"LabelInvert": "Omdraaien",
|
||||||
"LabelItem": "Onderdeel",
|
"LabelItem": "Onderdeel",
|
||||||
"LabelJumpBackwardAmount": "Terugspoelen hoeveelheid",
|
"LabelJumpBackwardAmount": "Terugspoelen hoeveelheid",
|
||||||
@@ -424,7 +425,7 @@
|
|||||||
"LabelLookForNewEpisodesAfterDate": "Zoek naar nieuwe afleveringen na deze datum",
|
"LabelLookForNewEpisodesAfterDate": "Zoek naar nieuwe afleveringen na deze datum",
|
||||||
"LabelLowestPriority": "Laagste Prioriteit",
|
"LabelLowestPriority": "Laagste Prioriteit",
|
||||||
"LabelMatchExistingUsersBy": "Bestaande gebruikers matchen op",
|
"LabelMatchExistingUsersBy": "Bestaande gebruikers matchen op",
|
||||||
"LabelMatchExistingUsersByDescription": "Wordt gebruikt om bestaande gebruikers te verbinden. Zodra ze verbonden zijn, worden gebruikers gekoppeld aan een unieke id van uw SSO-provider.",
|
"LabelMatchExistingUsersByDescription": "Wordt gebruikt om bestaande gebruikers te verbinden. Zodra ze verbonden zijn, worden gebruikers gekoppeld aan een unieke id van uw SSO-provider",
|
||||||
"LabelMaxEpisodesToDownload": "Maximale # afleveringen om te downloaden. Gebruik 0 voor ongelimiteerd.",
|
"LabelMaxEpisodesToDownload": "Maximale # afleveringen om te downloaden. Gebruik 0 voor ongelimiteerd.",
|
||||||
"LabelMaxEpisodesToDownloadPerCheck": "Maximale # nieuwe afleveringen om te downloaden per check",
|
"LabelMaxEpisodesToDownloadPerCheck": "Maximale # nieuwe afleveringen om te downloaden per check",
|
||||||
"LabelMaxEpisodesToKeep": "Maximale # afleveringen om te houden",
|
"LabelMaxEpisodesToKeep": "Maximale # afleveringen om te houden",
|
||||||
@@ -529,6 +530,7 @@
|
|||||||
"LabelReleaseDate": "Verschijningsdatum",
|
"LabelReleaseDate": "Verschijningsdatum",
|
||||||
"LabelRemoveAllMetadataAbs": "Verwijder alle metadata.abs bestanden",
|
"LabelRemoveAllMetadataAbs": "Verwijder alle metadata.abs bestanden",
|
||||||
"LabelRemoveAllMetadataJson": "Verwijder alle metadata.json bestanden",
|
"LabelRemoveAllMetadataJson": "Verwijder alle metadata.json bestanden",
|
||||||
|
"LabelRemoveAudibleBranding": "Verwijder Audible intro en outro uit hoofdstukken",
|
||||||
"LabelRemoveCover": "Verwijder cover",
|
"LabelRemoveCover": "Verwijder cover",
|
||||||
"LabelRemoveMetadataFile": "Verwijder metadata bestanden in bibliotheek item folders",
|
"LabelRemoveMetadataFile": "Verwijder metadata bestanden in bibliotheek item folders",
|
||||||
"LabelRemoveMetadataFileHelp": "Verwijder alle metadata.json en metadata.abs bestanden in uw {0} folders.",
|
"LabelRemoveMetadataFileHelp": "Verwijder alle metadata.json en metadata.abs bestanden in uw {0} folders.",
|
||||||
@@ -558,6 +560,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Skeumorphisch design met houten planken",
|
"LabelSettingsBookshelfViewHelp": "Skeumorphisch design met houten planken",
|
||||||
"LabelSettingsChromecastSupport": "Chromecast ondersteuning",
|
"LabelSettingsChromecastSupport": "Chromecast ondersteuning",
|
||||||
"LabelSettingsDateFormat": "Datum format",
|
"LabelSettingsDateFormat": "Datum format",
|
||||||
|
"LabelSettingsEnableWatcher": "Bibliotheken automatisch scannen op wijzigingen",
|
||||||
|
"LabelSettingsEnableWatcherForLibrary": "Bibliotheek automatisch scannen op wijzigingen",
|
||||||
"LabelSettingsEnableWatcherHelp": "Zorgt voor het automatisch toevoegen/bijwerken van onderdelen als bestandswijzigingen worden gedetecteerd. *Vereist herstarten van server",
|
"LabelSettingsEnableWatcherHelp": "Zorgt voor het automatisch toevoegen/bijwerken van onderdelen als bestandswijzigingen worden gedetecteerd. *Vereist herstarten van server",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Sta scripted content toe in epubs",
|
"LabelSettingsEpubsAllowScriptedContent": "Sta scripted content toe in epubs",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Sta toe dat epub-bestanden scripts uitvoeren. Het wordt aanbevolen om deze instelling uitgeschakeld te houden, tenzij u de bron van de epub-bestanden vertrouwt.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Sta toe dat epub-bestanden scripts uitvoeren. Het wordt aanbevolen om deze instelling uitgeschakeld te houden, tenzij u de bron van de epub-bestanden vertrouwt.",
|
||||||
@@ -719,6 +723,7 @@
|
|||||||
"MessageChapterErrorStartGteDuration": "Ongeldig: starttijd moet kleiner zijn dan duur van audioboek",
|
"MessageChapterErrorStartGteDuration": "Ongeldig: starttijd moet kleiner zijn dan duur van audioboek",
|
||||||
"MessageChapterErrorStartLtPrev": "Ongeldig: starttijd moet be groter zijn dan of equal aan starttijd van vorig hoofdstuk",
|
"MessageChapterErrorStartLtPrev": "Ongeldig: starttijd moet be groter zijn dan of equal aan starttijd van vorig hoofdstuk",
|
||||||
"MessageChapterStartIsAfter": "Start van hoofdstuk is na het einde van je audioboek",
|
"MessageChapterStartIsAfter": "Start van hoofdstuk is na het einde van je audioboek",
|
||||||
|
"MessageChaptersNotFound": "Hoofdstukken niet gevonden",
|
||||||
"MessageCheckingCron": "Cron aan het checken...",
|
"MessageCheckingCron": "Cron aan het checken...",
|
||||||
"MessageConfirmCloseFeed": "Ben je zeker dat je deze feed wil sluiten?",
|
"MessageConfirmCloseFeed": "Ben je zeker dat je deze feed wil sluiten?",
|
||||||
"MessageConfirmDeleteBackup": "Weet je zeker dat je de backup voor {0} wil verwijderen?",
|
"MessageConfirmDeleteBackup": "Weet je zeker dat je de backup voor {0} wil verwijderen?",
|
||||||
@@ -775,6 +780,7 @@
|
|||||||
"MessageForceReScanDescription": "zal alle bestanden opnieuw scannen als een verse scan. Audiobestanden ID3-tags, OPF-bestanden en textbestanden zullen als nieuw worden gescand.",
|
"MessageForceReScanDescription": "zal alle bestanden opnieuw scannen als een verse scan. Audiobestanden ID3-tags, OPF-bestanden en textbestanden zullen als nieuw worden gescand.",
|
||||||
"MessageImportantNotice": "Belangrijke opmerking!",
|
"MessageImportantNotice": "Belangrijke opmerking!",
|
||||||
"MessageInsertChapterBelow": "Hoofdstuk hieronder invoegen",
|
"MessageInsertChapterBelow": "Hoofdstuk hieronder invoegen",
|
||||||
|
"MessageInvalidAsin": "Ongeldige ASIN",
|
||||||
"MessageItemsSelected": "{0} onderdelen geselecteerd",
|
"MessageItemsSelected": "{0} onderdelen geselecteerd",
|
||||||
"MessageItemsUpdated": "{0} onderdelen bijgewerkt",
|
"MessageItemsUpdated": "{0} onderdelen bijgewerkt",
|
||||||
"MessageJoinUsOn": "Doe mee op",
|
"MessageJoinUsOn": "Doe mee op",
|
||||||
@@ -808,7 +814,7 @@
|
|||||||
"MessageNoItems": "Geen onderdelen",
|
"MessageNoItems": "Geen onderdelen",
|
||||||
"MessageNoItemsFound": "Geen onderdelen gevonden",
|
"MessageNoItemsFound": "Geen onderdelen gevonden",
|
||||||
"MessageNoListeningSessions": "Geen luistersessies",
|
"MessageNoListeningSessions": "Geen luistersessies",
|
||||||
"MessageNoLogs": "Geen logs",
|
"MessageNoLogs": "Geen logbestanden",
|
||||||
"MessageNoMediaProgress": "Geen mediavoortgang",
|
"MessageNoMediaProgress": "Geen mediavoortgang",
|
||||||
"MessageNoNotifications": "Geen notificaties",
|
"MessageNoNotifications": "Geen notificaties",
|
||||||
"MessageNoPodcastFeed": "Ongeldige podcast: Geen Feed",
|
"MessageNoPodcastFeed": "Ongeldige podcast: Geen Feed",
|
||||||
|
|||||||
+13
-1
@@ -8,7 +8,7 @@
|
|||||||
"ButtonAddYourFirstLibrary": "Legg til ditt første bibliotek",
|
"ButtonAddYourFirstLibrary": "Legg til ditt første bibliotek",
|
||||||
"ButtonApply": "Bruk",
|
"ButtonApply": "Bruk",
|
||||||
"ButtonApplyChapters": "Bruk kapittel",
|
"ButtonApplyChapters": "Bruk kapittel",
|
||||||
"ButtonAuthors": "Forfatter",
|
"ButtonAuthors": "Forfattere",
|
||||||
"ButtonBack": "Tilbake",
|
"ButtonBack": "Tilbake",
|
||||||
"ButtonBrowseForFolder": "Bla gjennom mappe",
|
"ButtonBrowseForFolder": "Bla gjennom mappe",
|
||||||
"ButtonCancel": "Avbryt",
|
"ButtonCancel": "Avbryt",
|
||||||
@@ -175,6 +175,7 @@
|
|||||||
"HeaderPlaylist": "Spilleliste",
|
"HeaderPlaylist": "Spilleliste",
|
||||||
"HeaderPlaylistItems": "Spillelisteelement",
|
"HeaderPlaylistItems": "Spillelisteelement",
|
||||||
"HeaderPodcastsToAdd": "Podcaster å legge til",
|
"HeaderPodcastsToAdd": "Podcaster å legge til",
|
||||||
|
"HeaderPresets": "Forhåndsinnstillinger",
|
||||||
"HeaderPreviewCover": "Forhåndsvis omslag",
|
"HeaderPreviewCover": "Forhåndsvis omslag",
|
||||||
"HeaderRSSFeedGeneral": "RSS Detailer",
|
"HeaderRSSFeedGeneral": "RSS Detailer",
|
||||||
"HeaderRSSFeedIsOpen": "RSS Feed er åpen",
|
"HeaderRSSFeedIsOpen": "RSS Feed er åpen",
|
||||||
@@ -217,6 +218,7 @@
|
|||||||
"LabelAccountTypeAdmin": "Administrator",
|
"LabelAccountTypeAdmin": "Administrator",
|
||||||
"LabelAccountTypeGuest": "Gjest",
|
"LabelAccountTypeGuest": "Gjest",
|
||||||
"LabelAccountTypeUser": "Bruker",
|
"LabelAccountTypeUser": "Bruker",
|
||||||
|
"LabelActivities": "Aktiviteter",
|
||||||
"LabelActivity": "Aktivitet",
|
"LabelActivity": "Aktivitet",
|
||||||
"LabelAddToCollection": "Legg til i samling",
|
"LabelAddToCollection": "Legg til i samling",
|
||||||
"LabelAddToCollectionBatch": "Legg {0} bøker til samling",
|
"LabelAddToCollectionBatch": "Legg {0} bøker til samling",
|
||||||
@@ -226,6 +228,7 @@
|
|||||||
"LabelAddedDate": "La til {0}",
|
"LabelAddedDate": "La til {0}",
|
||||||
"LabelAdminUsersOnly": "Kun administratorer",
|
"LabelAdminUsersOnly": "Kun administratorer",
|
||||||
"LabelAll": "Alle",
|
"LabelAll": "Alle",
|
||||||
|
"LabelAllEpisodesDownloaded": "Alle nedlastede episoder",
|
||||||
"LabelAllUsers": "Alle brukere",
|
"LabelAllUsers": "Alle brukere",
|
||||||
"LabelAllUsersExcludingGuests": "Alle brukere bortsett fra gjester",
|
"LabelAllUsersExcludingGuests": "Alle brukere bortsett fra gjester",
|
||||||
"LabelAllUsersIncludingGuests": "Alle brukere inkludert gjester",
|
"LabelAllUsersIncludingGuests": "Alle brukere inkludert gjester",
|
||||||
@@ -281,6 +284,7 @@
|
|||||||
"LabelContinueSeries": "Fortsett serier",
|
"LabelContinueSeries": "Fortsett serier",
|
||||||
"LabelCover": "Omslag",
|
"LabelCover": "Omslag",
|
||||||
"LabelCoverImageURL": "Omslagsbilde URL",
|
"LabelCoverImageURL": "Omslagsbilde URL",
|
||||||
|
"LabelCoverProvider": "Tilbyder av omslagsbilde",
|
||||||
"LabelCreatedAt": "Dato opprettet",
|
"LabelCreatedAt": "Dato opprettet",
|
||||||
"LabelCronExpression": "Cron uttrykk",
|
"LabelCronExpression": "Cron uttrykk",
|
||||||
"LabelCurrent": "Nåværende",
|
"LabelCurrent": "Nåværende",
|
||||||
@@ -389,6 +393,7 @@
|
|||||||
"LabelIntervalEvery6Hours": "Hver 6. timer",
|
"LabelIntervalEvery6Hours": "Hver 6. timer",
|
||||||
"LabelIntervalEveryDay": "Hver dag",
|
"LabelIntervalEveryDay": "Hver dag",
|
||||||
"LabelIntervalEveryHour": "Hver time",
|
"LabelIntervalEveryHour": "Hver time",
|
||||||
|
"LabelIntervalEveryMinute": "Hvert minutt",
|
||||||
"LabelInvert": "Inverter",
|
"LabelInvert": "Inverter",
|
||||||
"LabelItem": "Enhet",
|
"LabelItem": "Enhet",
|
||||||
"LabelJumpBackwardAmount": "Hopp bakover med",
|
"LabelJumpBackwardAmount": "Hopp bakover med",
|
||||||
@@ -464,6 +469,7 @@
|
|||||||
"LabelNotificationsMaxQueueSizeHelp": "Hendelser er begrenset til avfyre én gang per sekund. Hendelser blir ignorert om køen er full. Dette forhindrer overflod av varslinger.",
|
"LabelNotificationsMaxQueueSizeHelp": "Hendelser er begrenset til avfyre én gang per sekund. Hendelser blir ignorert om køen er full. Dette forhindrer overflod av varslinger.",
|
||||||
"LabelNumberOfBooks": "Antall bøker",
|
"LabelNumberOfBooks": "Antall bøker",
|
||||||
"LabelNumberOfEpisodes": "Antall episoder",
|
"LabelNumberOfEpisodes": "Antall episoder",
|
||||||
|
"LabelOpenIDAdvancedPermsClaimDescription": "Navnet på OpenID claim'et som inneholder avanserte tilganger for brukerhandlinger i applikasjonen som vil brukes for ikke-administratorroller (<b>hvis konfigurert</b>). Hvis claim'et mangler fra responsen, nektes tilgang til ABS. Hvis en enkelt opsjon mangler, blir behandlet som <code>false</code>. Påse at identitetstilbyderens claim stemmer overens med den forventede strukturen:",
|
||||||
"LabelOpenIDClaims": "La følge valg være tomme for å slå av avanserte gruppe og tillatelser. Gruppen \"Bruker\" vil da også automatisk legges til.",
|
"LabelOpenIDClaims": "La følge valg være tomme for å slå av avanserte gruppe og tillatelser. Gruppen \"Bruker\" vil da også automatisk legges til.",
|
||||||
"LabelOpenRSSFeed": "Åpne RSS Feed",
|
"LabelOpenRSSFeed": "Åpne RSS Feed",
|
||||||
"LabelOverwrite": "Overskriv",
|
"LabelOverwrite": "Overskriv",
|
||||||
@@ -521,6 +527,7 @@
|
|||||||
"LabelReleaseDate": "Utgivelsesdato",
|
"LabelReleaseDate": "Utgivelsesdato",
|
||||||
"LabelRemoveAllMetadataAbs": "Fjern alle metadata.abs filer",
|
"LabelRemoveAllMetadataAbs": "Fjern alle metadata.abs filer",
|
||||||
"LabelRemoveAllMetadataJson": "Fjern alle metadata.json filer",
|
"LabelRemoveAllMetadataJson": "Fjern alle metadata.json filer",
|
||||||
|
"LabelRemoveAudibleBranding": "Fjern Audible inn- og utledning fra kapitler",
|
||||||
"LabelRemoveCover": "Fjern omslag",
|
"LabelRemoveCover": "Fjern omslag",
|
||||||
"LabelRemoveMetadataFile": "Fjern metadata-filer fra biblioteks-mapper",
|
"LabelRemoveMetadataFile": "Fjern metadata-filer fra biblioteks-mapper",
|
||||||
"LabelRemoveMetadataFileHelp": "Fjern alle metadata.json og metadata.abs i alle {0} mappene.",
|
"LabelRemoveMetadataFileHelp": "Fjern alle metadata.json og metadata.abs i alle {0} mappene.",
|
||||||
@@ -550,6 +557,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Skeuomorf design med hyller av ved",
|
"LabelSettingsBookshelfViewHelp": "Skeuomorf design med hyller av ved",
|
||||||
"LabelSettingsChromecastSupport": "Chromecast støtte",
|
"LabelSettingsChromecastSupport": "Chromecast støtte",
|
||||||
"LabelSettingsDateFormat": "Dato Format",
|
"LabelSettingsDateFormat": "Dato Format",
|
||||||
|
"LabelSettingsEnableWatcher": "Skann biblioteker automatisk for endringer",
|
||||||
|
"LabelSettingsEnableWatcherForLibrary": "Skann bibliotek automatisk for endringer",
|
||||||
"LabelSettingsEnableWatcherHelp": "Aktiverer automatisk opprettelse/oppdatering av enheter når filendringer er oppdaget. *Krever restart av server*",
|
"LabelSettingsEnableWatcherHelp": "Aktiverer automatisk opprettelse/oppdatering av enheter når filendringer er oppdaget. *Krever restart av server*",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Tillat scripting i innholdet i ebub-bøker",
|
"LabelSettingsEpubsAllowScriptedContent": "Tillat scripting i innholdet i ebub-bøker",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Tillat epub-filer å kjøre script. Det er anbefalt å slå av denne innstillingen med mindre du stoler på kilden til epub-filene.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Tillat epub-filer å kjøre script. Det er anbefalt å slå av denne innstillingen med mindre du stoler på kilden til epub-filene.",
|
||||||
@@ -593,6 +602,7 @@
|
|||||||
"LabelSlug": "Slug",
|
"LabelSlug": "Slug",
|
||||||
"LabelSortAscending": "Stigende",
|
"LabelSortAscending": "Stigende",
|
||||||
"LabelSortDescending": "Synkende",
|
"LabelSortDescending": "Synkende",
|
||||||
|
"LabelSortPubDate": "Sorter etter publiseringsdato",
|
||||||
"LabelStart": "Start",
|
"LabelStart": "Start",
|
||||||
"LabelStartTime": "Start Tid",
|
"LabelStartTime": "Start Tid",
|
||||||
"LabelStarted": "Startet",
|
"LabelStarted": "Startet",
|
||||||
@@ -693,6 +703,8 @@
|
|||||||
"LabelYourProgress": "Din fremgang",
|
"LabelYourProgress": "Din fremgang",
|
||||||
"MessageAddToPlayerQueue": "Legg til i kø",
|
"MessageAddToPlayerQueue": "Legg til i kø",
|
||||||
"MessageAppriseDescription": "For å bruke denne funksjonen trenger du en instans av <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> kjørende eller et API som håndterer disse forespørslene. <br />Apprise API URL skal være hele URL-en til varslingen, f.eks., hvis din API-instans er på <code>http://192.168.1.1:8337</code> så skal du bruke <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "For å bruke denne funksjonen trenger du en instans av <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> kjørende eller et API som håndterer disse forespørslene. <br />Apprise API URL skal være hele URL-en til varslingen, f.eks., hvis din API-instans er på <code>http://192.168.1.1:8337</code> så skal du bruke <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
|
"MessageAsinCheck": "Påse at du bruker ASIN fra den riktige Audible-regionen, ikke Amazon.",
|
||||||
|
"MessageAuthenticationOIDCChangesRestart": "Etter å ha lagret, start serveren din på nytt for at OIDC-endringene skal tre i kraft.",
|
||||||
"MessageBackupsDescription": "Sikkerhetskopier inkluderer, brukerfremgang, detaljer om bibliotekgjenstander, tjener instillinger og bilder lagret under <code>/metadata/items</code> og <code>/metadata/authors</code>. Sikkerhetskopier <strong>vil ikke</strong> inkludere filer som er lagret i bibliotek mappene.",
|
"MessageBackupsDescription": "Sikkerhetskopier inkluderer, brukerfremgang, detaljer om bibliotekgjenstander, tjener instillinger og bilder lagret under <code>/metadata/items</code> og <code>/metadata/authors</code>. Sikkerhetskopier <strong>vil ikke</strong> inkludere filer som er lagret i bibliotek mappene.",
|
||||||
"MessageBackupsLocationEditNote": "Viktig: Endring av mappen for sikkerhetskopi hverken endrer eller flytter eksisterende sikkerhetskopier!",
|
"MessageBackupsLocationEditNote": "Viktig: Endring av mappen for sikkerhetskopi hverken endrer eller flytter eksisterende sikkerhetskopier!",
|
||||||
"MessageBackupsLocationNoEditNote": "NB: Mappen for sikkerhetskopi settes i en miljøvariabel og kan ikke endres her.",
|
"MessageBackupsLocationNoEditNote": "NB: Mappen for sikkerhetskopi settes i en miljøvariabel og kan ikke endres her.",
|
||||||
|
|||||||
+41
-1
@@ -329,7 +329,9 @@
|
|||||||
"LabelEpisode": "Odcinek",
|
"LabelEpisode": "Odcinek",
|
||||||
"LabelEpisodeTitle": "Tytuł odcinka",
|
"LabelEpisodeTitle": "Tytuł odcinka",
|
||||||
"LabelEpisodeType": "Typ odcinka",
|
"LabelEpisodeType": "Typ odcinka",
|
||||||
|
"LabelEpisodeUrlFromRssFeed": "Adres URL odcinka z kanału RSS",
|
||||||
"LabelEpisodes": "Epizody",
|
"LabelEpisodes": "Epizody",
|
||||||
|
"LabelEpisodic": "Epizodyczny",
|
||||||
"LabelExample": "Przykład",
|
"LabelExample": "Przykład",
|
||||||
"LabelExpandSeries": "Rozwiń serie",
|
"LabelExpandSeries": "Rozwiń serie",
|
||||||
"LabelExpandSubSeries": "Rozwiń podserie",
|
"LabelExpandSubSeries": "Rozwiń podserie",
|
||||||
@@ -357,6 +359,7 @@
|
|||||||
"LabelFontScale": "Rozmiar czcionki",
|
"LabelFontScale": "Rozmiar czcionki",
|
||||||
"LabelFontStrikethrough": "Przekreślony",
|
"LabelFontStrikethrough": "Przekreślony",
|
||||||
"LabelFormat": "Format",
|
"LabelFormat": "Format",
|
||||||
|
"LabelFull": "Pełny",
|
||||||
"LabelGenre": "Gatunek",
|
"LabelGenre": "Gatunek",
|
||||||
"LabelGenres": "Gatunki",
|
"LabelGenres": "Gatunki",
|
||||||
"LabelHardDeleteFile": "Usuń trwale plik",
|
"LabelHardDeleteFile": "Usuń trwale plik",
|
||||||
@@ -381,6 +384,7 @@
|
|||||||
"LabelIntervalEvery6Hours": "Co 6 godzin",
|
"LabelIntervalEvery6Hours": "Co 6 godzin",
|
||||||
"LabelIntervalEveryDay": "Każdego dnia",
|
"LabelIntervalEveryDay": "Każdego dnia",
|
||||||
"LabelIntervalEveryHour": "Każdej godziny",
|
"LabelIntervalEveryHour": "Każdej godziny",
|
||||||
|
"LabelIntervalEveryMinute": "Co minutę",
|
||||||
"LabelInvert": "Inversja",
|
"LabelInvert": "Inversja",
|
||||||
"LabelItem": "Pozycja",
|
"LabelItem": "Pozycja",
|
||||||
"LabelJumpBackwardAmount": "Przeskocz do tyłu o:",
|
"LabelJumpBackwardAmount": "Przeskocz do tyłu o:",
|
||||||
@@ -412,6 +416,9 @@
|
|||||||
"LabelLowestPriority": "Najniższy priorytet",
|
"LabelLowestPriority": "Najniższy priorytet",
|
||||||
"LabelMatchExistingUsersBy": "Dopasuje istniejących użytkowników poprzez",
|
"LabelMatchExistingUsersBy": "Dopasuje istniejących użytkowników poprzez",
|
||||||
"LabelMatchExistingUsersByDescription": "Służy do łączenia istniejących użytkowników. Po połączeniu użytkownicy zostaną dopasowani za pomocą unikalnego identyfikatora od dostawcy SSO",
|
"LabelMatchExistingUsersByDescription": "Służy do łączenia istniejących użytkowników. Po połączeniu użytkownicy zostaną dopasowani za pomocą unikalnego identyfikatora od dostawcy SSO",
|
||||||
|
"LabelMaxEpisodesToDownload": "Maksymalna liczba odcinków do pobrania. Użyj 0, aby wyłączyć ograniczenie.",
|
||||||
|
"LabelMaxEpisodesToKeep": "Maksymalna liczba odcinków do zachowania",
|
||||||
|
"LabelMaxEpisodesToKeepHelp": "Wartość 0 wyłącza maksymalny limit. Po automatycznym pobraniu nowego odcinka, najstarszy odcinek zostanie usunięty, jeśli masz ich więcej niż X. Spowoduje to usunięcie tylko 1 odcinka na nowe pobieranie.",
|
||||||
"LabelMediaPlayer": "Odtwarzacz",
|
"LabelMediaPlayer": "Odtwarzacz",
|
||||||
"LabelMediaType": "Typ mediów",
|
"LabelMediaType": "Typ mediów",
|
||||||
"LabelMetaTag": "Tag",
|
"LabelMetaTag": "Tag",
|
||||||
@@ -424,6 +431,7 @@
|
|||||||
"LabelMissingEbook": "Nie posiada ebooka",
|
"LabelMissingEbook": "Nie posiada ebooka",
|
||||||
"LabelMissingSupplementaryEbook": "Nie posiada dodatkowego ebooka",
|
"LabelMissingSupplementaryEbook": "Nie posiada dodatkowego ebooka",
|
||||||
"LabelMobileRedirectURIs": "Dozwolone URI przekierowań mobilnych",
|
"LabelMobileRedirectURIs": "Dozwolone URI przekierowań mobilnych",
|
||||||
|
"LabelMobileRedirectURIsDescription": "To jest biała lista prawidłowych adresów URI przekierowań dla aplikacji mobilnych. Domyślny adres to <code>audiobookshelf://oauth</code>, który można usunąć lub dodać inne adresy URI w celu integracji z aplikacjami innych firm. Użycie gwiazdki (<code>*</code>) jako jedynego wpisu zezwala na dowolny URI.",
|
||||||
"LabelMore": "Więcej",
|
"LabelMore": "Więcej",
|
||||||
"LabelMoreInfo": "Więcej informacji",
|
"LabelMoreInfo": "Więcej informacji",
|
||||||
"LabelName": "Nazwa",
|
"LabelName": "Nazwa",
|
||||||
@@ -453,12 +461,14 @@
|
|||||||
"LabelNumberOfEpisodes": "# Odcinków",
|
"LabelNumberOfEpisodes": "# Odcinków",
|
||||||
"LabelOpenRSSFeed": "Otwórz kanał RSS",
|
"LabelOpenRSSFeed": "Otwórz kanał RSS",
|
||||||
"LabelOverwrite": "Nadpisz",
|
"LabelOverwrite": "Nadpisz",
|
||||||
|
"LabelPaginationPageXOfY": "Strona {0} z {1}",
|
||||||
"LabelPassword": "Hasło",
|
"LabelPassword": "Hasło",
|
||||||
"LabelPath": "Ścieżka",
|
"LabelPath": "Ścieżka",
|
||||||
"LabelPermanent": "Stałe",
|
"LabelPermanent": "Stałe",
|
||||||
"LabelPermissionsAccessAllLibraries": "Ma dostęp do wszystkich bibliotek",
|
"LabelPermissionsAccessAllLibraries": "Ma dostęp do wszystkich bibliotek",
|
||||||
"LabelPermissionsAccessAllTags": "Ma dostęp do wszystkich tagów",
|
"LabelPermissionsAccessAllTags": "Ma dostęp do wszystkich tagów",
|
||||||
"LabelPermissionsAccessExplicitContent": "Ma dostęp do treści oznacznych jako nieprzyzwoite",
|
"LabelPermissionsAccessExplicitContent": "Ma dostęp do treści oznacznych jako nieprzyzwoite",
|
||||||
|
"LabelPermissionsCreateEreader": "Możliwość stworzenia czytnika e-booków",
|
||||||
"LabelPermissionsDelete": "Ma możliwość usuwania",
|
"LabelPermissionsDelete": "Ma możliwość usuwania",
|
||||||
"LabelPermissionsDownload": "Ma możliwość pobierania",
|
"LabelPermissionsDownload": "Ma możliwość pobierania",
|
||||||
"LabelPermissionsUpdate": "Ma możliwość aktualizowania",
|
"LabelPermissionsUpdate": "Ma możliwość aktualizowania",
|
||||||
@@ -466,19 +476,25 @@
|
|||||||
"LabelPersonalYearReview": "Podsumowanie twojego roku ({0})",
|
"LabelPersonalYearReview": "Podsumowanie twojego roku ({0})",
|
||||||
"LabelPhotoPathURL": "Scieżka/URL do zdjęcia",
|
"LabelPhotoPathURL": "Scieżka/URL do zdjęcia",
|
||||||
"LabelPlayMethod": "Metoda odtwarzania",
|
"LabelPlayMethod": "Metoda odtwarzania",
|
||||||
|
"LabelPlayerChapterNumberMarker": "{0} z {1}",
|
||||||
"LabelPlaylists": "Listy odtwarzania",
|
"LabelPlaylists": "Listy odtwarzania",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcastSearchRegion": "Obszar wyszukiwania podcastów",
|
"LabelPodcastSearchRegion": "Obszar wyszukiwania podcastów",
|
||||||
|
"LabelPodcastType": "Typ podcastu",
|
||||||
"LabelPodcasts": "Podcasty",
|
"LabelPodcasts": "Podcasty",
|
||||||
|
"LabelPort": "Port",
|
||||||
"LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)",
|
"LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)",
|
||||||
"LabelPreventIndexing": "Zapobiega indeksowaniu przez iTunes i Google",
|
"LabelPreventIndexing": "Zapobiega indeksowaniu przez iTunes i Google",
|
||||||
"LabelPrimaryEbook": "Główny ebook",
|
"LabelPrimaryEbook": "Główny ebook",
|
||||||
"LabelProgress": "Postęp",
|
"LabelProgress": "Postęp",
|
||||||
"LabelProvider": "Dostawca",
|
"LabelProvider": "Dostawca",
|
||||||
|
"LabelProviderAuthorizationValue": "Wartość nagłówka autoryzacji",
|
||||||
"LabelPubDate": "Data publikacji",
|
"LabelPubDate": "Data publikacji",
|
||||||
"LabelPublishYear": "Rok publikacji",
|
"LabelPublishYear": "Rok publikacji",
|
||||||
|
"LabelPublishedDate": "Opublikowano {0}",
|
||||||
"LabelPublisher": "Wydawca",
|
"LabelPublisher": "Wydawca",
|
||||||
"LabelPublishers": "Wydawcy",
|
"LabelPublishers": "Wydawcy",
|
||||||
"LabelRSSFeedOpen": "RSS Feed otwarty",
|
"LabelRSSFeedOpen": "Otwarty Kanał RSS",
|
||||||
"LabelRSSFeedPreventIndexing": "Zapobiegaj indeksowaniu",
|
"LabelRSSFeedPreventIndexing": "Zapobiegaj indeksowaniu",
|
||||||
"LabelRSSFeedURL": "URL kanały RSS",
|
"LabelRSSFeedURL": "URL kanały RSS",
|
||||||
"LabelRandomly": "Losowo",
|
"LabelRandomly": "Losowo",
|
||||||
@@ -490,15 +506,22 @@
|
|||||||
"LabelRecentlyAdded": "Niedawno dodane",
|
"LabelRecentlyAdded": "Niedawno dodane",
|
||||||
"LabelRecommended": "Polecane",
|
"LabelRecommended": "Polecane",
|
||||||
"LabelRedo": "Wycofaj",
|
"LabelRedo": "Wycofaj",
|
||||||
|
"LabelRegion": "Region",
|
||||||
"LabelReleaseDate": "Data wydania",
|
"LabelReleaseDate": "Data wydania",
|
||||||
|
"LabelRemoveAllMetadataAbs": "Usuń wszystkie pliki metadata.abs",
|
||||||
|
"LabelRemoveAllMetadataJson": "Usuń wszystkie pliki metadata.json",
|
||||||
"LabelRemoveCover": "Usuń okładkę",
|
"LabelRemoveCover": "Usuń okładkę",
|
||||||
|
"LabelRemoveMetadataFile": "Usuń pliki metadanych z folderów biblioteki",
|
||||||
|
"LabelRemoveMetadataFileHelp": "Usuń wszystkie pliki metadata.json i metadata.abs z {0} folderów.",
|
||||||
"LabelRowsPerPage": "Wierszy na stronę",
|
"LabelRowsPerPage": "Wierszy na stronę",
|
||||||
"LabelSearchTerm": "Wyszukiwanie frazy",
|
"LabelSearchTerm": "Wyszukiwanie frazy",
|
||||||
"LabelSearchTitle": "Wyszukaj tytuł",
|
"LabelSearchTitle": "Wyszukaj tytuł",
|
||||||
"LabelSearchTitleOrASIN": "Szukaj tytuł lub ASIN",
|
"LabelSearchTitleOrASIN": "Szukaj tytuł lub ASIN",
|
||||||
"LabelSeason": "Sezon",
|
"LabelSeason": "Sezon",
|
||||||
|
"LabelSeasonNumber": "Sezon #{0}",
|
||||||
"LabelSelectAll": "Wybierz wszystko",
|
"LabelSelectAll": "Wybierz wszystko",
|
||||||
"LabelSelectAllEpisodes": "Wybierz wszystkie odcinki",
|
"LabelSelectAllEpisodes": "Wybierz wszystkie odcinki",
|
||||||
|
"LabelSelectEpisodesShowing": "Wybierz {0} wyświetlanych odcinków",
|
||||||
"LabelSelectUsers": "Wybór użytkowników",
|
"LabelSelectUsers": "Wybór użytkowników",
|
||||||
"LabelSendEbookToDevice": "Wyślij ebook do...",
|
"LabelSendEbookToDevice": "Wyślij ebook do...",
|
||||||
"LabelSequence": "Kolejność",
|
"LabelSequence": "Kolejność",
|
||||||
@@ -513,6 +536,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Widok półki z książkami",
|
"LabelSettingsBookshelfViewHelp": "Widok półki z książkami",
|
||||||
"LabelSettingsChromecastSupport": "Wsparcie Chromecast",
|
"LabelSettingsChromecastSupport": "Wsparcie Chromecast",
|
||||||
"LabelSettingsDateFormat": "Format daty",
|
"LabelSettingsDateFormat": "Format daty",
|
||||||
|
"LabelSettingsEnableWatcher": "Automatyczne skanowanie bibliotek w poszukiwaniu zmian",
|
||||||
|
"LabelSettingsEnableWatcherForLibrary": "Automatyczne skanowanie biblioteki w poszukiwaniu zmian",
|
||||||
"LabelSettingsEnableWatcherHelp": "Włącza automatyczne dodawanie/aktualizację pozycji gdy wykryte zostaną zmiany w plikach. Wymaga restartu serwera",
|
"LabelSettingsEnableWatcherHelp": "Włącza automatyczne dodawanie/aktualizację pozycji gdy wykryte zostaną zmiany w plikach. Wymaga restartu serwera",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Zezwalanie na skrypty w plikach epub",
|
"LabelSettingsEpubsAllowScriptedContent": "Zezwalanie na skrypty w plikach epub",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Zezwala plikom epub na wykonywanie skryptów. Zaleca się mieć to ustawienie wyłączone, chyba że ma się zaufanie do źródła plików epub.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Zezwala plikom epub na wykonywanie skryptów. Zaleca się mieć to ustawienie wyłączone, chyba że ma się zaufanie do źródła plików epub.",
|
||||||
@@ -524,6 +549,8 @@
|
|||||||
"LabelSettingsHideSingleBookSeriesHelp": "Serie, które posiadają tylko jedną książkę, nie będą pokazywane na stronie z seriami i na stronie domowej z półkami.",
|
"LabelSettingsHideSingleBookSeriesHelp": "Serie, które posiadają tylko jedną książkę, nie będą pokazywane na stronie z seriami i na stronie domowej z półkami.",
|
||||||
"LabelSettingsHomePageBookshelfView": "Widok półki z książkami na stronie głównej",
|
"LabelSettingsHomePageBookshelfView": "Widok półki z książkami na stronie głównej",
|
||||||
"LabelSettingsLibraryBookshelfView": "Widok półki z książkami na stronie biblioteki",
|
"LabelSettingsLibraryBookshelfView": "Widok półki z książkami na stronie biblioteki",
|
||||||
|
"LabelSettingsLibraryMarkAsFinishedWhen": "Oznacz element multimedialny jako ukończony, gdy",
|
||||||
|
"LabelSettingsOnlyShowLaterBooksInContinueSeries": "Pomiń poprzednie książki przy kontynuacji serii",
|
||||||
"LabelSettingsParseSubtitles": "Przetwarzaj podtytuły",
|
"LabelSettingsParseSubtitles": "Przetwarzaj podtytuły",
|
||||||
"LabelSettingsParseSubtitlesHelp": "Opcja pozwala na pobranie podtytułu z nazwy folderu z audiobookiem. <br>Podtytuł musi być rozdzielony za pomocą separatora \" - \"<br>Przykład: \"Book Title - A Subtitle Here\" podtytuł \"A Subtitle Here\"",
|
"LabelSettingsParseSubtitlesHelp": "Opcja pozwala na pobranie podtytułu z nazwy folderu z audiobookiem. <br>Podtytuł musi być rozdzielony za pomocą separatora \" - \"<br>Przykład: \"Book Title - A Subtitle Here\" podtytuł \"A Subtitle Here\"",
|
||||||
"LabelSettingsPreferMatchedMetadata": "Preferowanie dopasowanych metadanych",
|
"LabelSettingsPreferMatchedMetadata": "Preferowanie dopasowanych metadanych",
|
||||||
@@ -547,6 +574,9 @@
|
|||||||
"LabelShowSubtitles": "Pokaż Napisy",
|
"LabelShowSubtitles": "Pokaż Napisy",
|
||||||
"LabelSize": "Rozmiar",
|
"LabelSize": "Rozmiar",
|
||||||
"LabelSleepTimer": "Wyłącznik czasowy",
|
"LabelSleepTimer": "Wyłącznik czasowy",
|
||||||
|
"LabelSortAscending": "Rosnąco",
|
||||||
|
"LabelSortDescending": "Malejąco",
|
||||||
|
"LabelSortPubDate": "Sortuj według daty publikacji",
|
||||||
"LabelStart": "Rozpocznij",
|
"LabelStart": "Rozpocznij",
|
||||||
"LabelStartTime": "Czas rozpoczęcia",
|
"LabelStartTime": "Czas rozpoczęcia",
|
||||||
"LabelStarted": "Rozpoczęty",
|
"LabelStarted": "Rozpoczęty",
|
||||||
@@ -568,14 +598,21 @@
|
|||||||
"LabelStatsWeekListening": "Tydzień słuchania",
|
"LabelStatsWeekListening": "Tydzień słuchania",
|
||||||
"LabelSubtitle": "Podtytuł",
|
"LabelSubtitle": "Podtytuł",
|
||||||
"LabelSupportedFileTypes": "Obsługiwane typy plików",
|
"LabelSupportedFileTypes": "Obsługiwane typy plików",
|
||||||
|
"LabelTag": "Znacznik",
|
||||||
"LabelTags": "Tagi",
|
"LabelTags": "Tagi",
|
||||||
"LabelTagsAccessibleToUser": "Tagi dostępne dla użytkownika",
|
"LabelTagsAccessibleToUser": "Tagi dostępne dla użytkownika",
|
||||||
|
"LabelTagsNotAccessibleToUser": "Znaczniki niedostępne dla użytkownika",
|
||||||
|
"LabelTasks": "Uruchomione zadania",
|
||||||
|
"LabelTextEditorLink": "Link",
|
||||||
|
"LabelTextEditorNumberedList": "Lista numerowana",
|
||||||
|
"LabelTextEditorUnlink": "Usuń link",
|
||||||
"LabelThemeDark": "Ciemny",
|
"LabelThemeDark": "Ciemny",
|
||||||
"LabelThemeLight": "Jasny",
|
"LabelThemeLight": "Jasny",
|
||||||
"LabelTimeDurationXHours": "{0} godzin",
|
"LabelTimeDurationXHours": "{0} godzin",
|
||||||
"LabelTimeDurationXMinutes": "{0} minuty",
|
"LabelTimeDurationXMinutes": "{0} minuty",
|
||||||
"LabelTimeDurationXSeconds": "{0} sekundy",
|
"LabelTimeDurationXSeconds": "{0} sekundy",
|
||||||
"LabelTimeInMinutes": "Czas w minutach",
|
"LabelTimeInMinutes": "Czas w minutach",
|
||||||
|
"LabelTimeLeft": "pozostało {0}",
|
||||||
"LabelTimeListened": "Czas odtwarzania",
|
"LabelTimeListened": "Czas odtwarzania",
|
||||||
"LabelTimeListenedToday": "Czas odtwarzania dzisiaj",
|
"LabelTimeListenedToday": "Czas odtwarzania dzisiaj",
|
||||||
"LabelTimeRemaining": "Pozostało {0}",
|
"LabelTimeRemaining": "Pozostało {0}",
|
||||||
@@ -583,6 +620,7 @@
|
|||||||
"LabelTitle": "Tytuł",
|
"LabelTitle": "Tytuł",
|
||||||
"LabelToolsEmbedMetadata": "Załącz metadane",
|
"LabelToolsEmbedMetadata": "Załącz metadane",
|
||||||
"LabelToolsEmbedMetadataDescription": "Załącz metadane do plików audio (okładkę oraz znaczniki rozdziałów).",
|
"LabelToolsEmbedMetadataDescription": "Załącz metadane do plików audio (okładkę oraz znaczniki rozdziałów).",
|
||||||
|
"LabelToolsM4bEncoder": "Enkoder M4B",
|
||||||
"LabelToolsMakeM4b": "Generuj plik M4B",
|
"LabelToolsMakeM4b": "Generuj plik M4B",
|
||||||
"LabelToolsMakeM4bDescription": "Tworzy plik w formacie .M4B, który zawiera metadane, okładkę oraz rozdziały.",
|
"LabelToolsMakeM4bDescription": "Tworzy plik w formacie .M4B, który zawiera metadane, okładkę oraz rozdziały.",
|
||||||
"LabelToolsSplitM4b": "Podziel plik .M4B na pliki .MP3",
|
"LabelToolsSplitM4b": "Podziel plik .M4B na pliki .MP3",
|
||||||
@@ -595,12 +633,14 @@
|
|||||||
"LabelType": "Typ",
|
"LabelType": "Typ",
|
||||||
"LabelUndo": "Wycofaj",
|
"LabelUndo": "Wycofaj",
|
||||||
"LabelUnknown": "Nieznany",
|
"LabelUnknown": "Nieznany",
|
||||||
|
"LabelUnknownPublishDate": "Nieznana data publikacji",
|
||||||
"LabelUpdateCover": "Zaktalizuj odkładkę",
|
"LabelUpdateCover": "Zaktalizuj odkładkę",
|
||||||
"LabelUpdateCoverHelp": "Umożliwienie nadpisania istniejących okładek dla wybranych książek w przypadku znalezienia dopasowania",
|
"LabelUpdateCoverHelp": "Umożliwienie nadpisania istniejących okładek dla wybranych książek w przypadku znalezienia dopasowania",
|
||||||
"LabelUpdateDetails": "Zaktualizuj szczegóły",
|
"LabelUpdateDetails": "Zaktualizuj szczegóły",
|
||||||
"LabelUpdateDetailsHelp": "Umożliwienie nadpisania istniejących szczegółów dla wybranych książek w przypadku znalezienia dopasowania",
|
"LabelUpdateDetailsHelp": "Umożliwienie nadpisania istniejących szczegółów dla wybranych książek w przypadku znalezienia dopasowania",
|
||||||
"LabelUpdatedAt": "Zaktualizowano",
|
"LabelUpdatedAt": "Zaktualizowano",
|
||||||
"LabelUploaderDragAndDrop": "Przeciągnij i puść foldery lub pliki",
|
"LabelUploaderDragAndDrop": "Przeciągnij i puść foldery lub pliki",
|
||||||
|
"LabelUploaderDragAndDropFilesOnly": "Przeciągnij i upuść pliki",
|
||||||
"LabelUploaderDropFiles": "Puść pliki",
|
"LabelUploaderDropFiles": "Puść pliki",
|
||||||
"LabelUploaderItemFetchMetadataHelp": "Automatycznie pobierz tytuł, autora i serie",
|
"LabelUploaderItemFetchMetadataHelp": "Automatycznie pobierz tytuł, autora i serie",
|
||||||
"LabelUseChapterTrack": "Użyj ścieżki rozdziału",
|
"LabelUseChapterTrack": "Użyj ścieżki rozdziału",
|
||||||
|
|||||||
@@ -348,7 +348,7 @@
|
|||||||
"LabelExpandSubSeries": "Развернуть подсерию",
|
"LabelExpandSubSeries": "Развернуть подсерию",
|
||||||
"LabelExplicit": "18+",
|
"LabelExplicit": "18+",
|
||||||
"LabelExplicitChecked": "18+ (отмечено)",
|
"LabelExplicitChecked": "18+ (отмечено)",
|
||||||
"LabelExplicitUnchecked": "Не явно (не отмечено)",
|
"LabelExplicitUnchecked": "+18 (не отмечено)",
|
||||||
"LabelExportOPML": "Экспорт OPML",
|
"LabelExportOPML": "Экспорт OPML",
|
||||||
"LabelFeedURL": "URL канала",
|
"LabelFeedURL": "URL канала",
|
||||||
"LabelFetchingMetadata": "Извлечение метаданных",
|
"LabelFetchingMetadata": "Извлечение метаданных",
|
||||||
@@ -514,7 +514,7 @@
|
|||||||
"LabelPublishers": "Издатели",
|
"LabelPublishers": "Издатели",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Пользовательский Email владельца",
|
"LabelRSSFeedCustomOwnerEmail": "Пользовательский Email владельца",
|
||||||
"LabelRSSFeedCustomOwnerName": "Пользовательское Имя владельца",
|
"LabelRSSFeedCustomOwnerName": "Пользовательское Имя владельца",
|
||||||
"LabelRSSFeedOpen": "Открыть RSS-канал",
|
"LabelRSSFeedOpen": "Открыть RSS-ленту",
|
||||||
"LabelRSSFeedPreventIndexing": "Запретить индексирование",
|
"LabelRSSFeedPreventIndexing": "Запретить индексирование",
|
||||||
"LabelRSSFeedSlug": "Встроить RSS-канал",
|
"LabelRSSFeedSlug": "Встроить RSS-канал",
|
||||||
"LabelRSSFeedURL": "URL RSS-канала",
|
"LabelRSSFeedURL": "URL RSS-канала",
|
||||||
@@ -918,6 +918,8 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "Запускается при завершении резервного копирования",
|
"NotificationOnBackupCompletedDescription": "Запускается при завершении резервного копирования",
|
||||||
"NotificationOnBackupFailedDescription": "Срабатывает при сбое резервного копирования",
|
"NotificationOnBackupFailedDescription": "Срабатывает при сбое резервного копирования",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "Запускается при автоматической загрузке эпизода подкаста",
|
"NotificationOnEpisodeDownloadedDescription": "Запускается при автоматической загрузке эпизода подкаста",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Срабатывает, когда автоматическая загрузка эпизодов отключена из-за слишком большого количества неудачных попыток",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Срабатывает при сбое запроса RSS-канала на автоматическую загрузку эпизода",
|
||||||
"NotificationOnTestDescription": "Событие для тестирования системы оповещения",
|
"NotificationOnTestDescription": "Событие для тестирования системы оповещения",
|
||||||
"PlaceholderNewCollection": "Новое имя коллекции",
|
"PlaceholderNewCollection": "Новое имя коллекции",
|
||||||
"PlaceholderNewFolderPath": "Путь к новой папке",
|
"PlaceholderNewFolderPath": "Путь к новой папке",
|
||||||
|
|||||||
@@ -514,7 +514,7 @@
|
|||||||
"LabelPublishers": "Izdajatelji",
|
"LabelPublishers": "Izdajatelji",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "E-pošta lastnika po meri",
|
"LabelRSSFeedCustomOwnerEmail": "E-pošta lastnika po meri",
|
||||||
"LabelRSSFeedCustomOwnerName": "Ime lastnika po meri",
|
"LabelRSSFeedCustomOwnerName": "Ime lastnika po meri",
|
||||||
"LabelRSSFeedOpen": "Odprt vir RSS",
|
"LabelRSSFeedOpen": "RSS vir je odprt",
|
||||||
"LabelRSSFeedPreventIndexing": "Prepreči indeksiranje",
|
"LabelRSSFeedPreventIndexing": "Prepreči indeksiranje",
|
||||||
"LabelRSSFeedSlug": "Slug RSS vira",
|
"LabelRSSFeedSlug": "Slug RSS vira",
|
||||||
"LabelRSSFeedURL": "URL vira RSS",
|
"LabelRSSFeedURL": "URL vira RSS",
|
||||||
@@ -918,6 +918,8 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "Sproži se, ko je varnostno kopiranje končano",
|
"NotificationOnBackupCompletedDescription": "Sproži se, ko je varnostno kopiranje končano",
|
||||||
"NotificationOnBackupFailedDescription": "Sproži se, ko varnostno kopiranje ne uspe",
|
"NotificationOnBackupFailedDescription": "Sproži se, ko varnostno kopiranje ne uspe",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "Sproži se, ko se epizoda podcasta samodejno prenese",
|
"NotificationOnEpisodeDownloadedDescription": "Sproži se, ko se epizoda podcasta samodejno prenese",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Sproži se, ko so samodejni prenosi epizod onemogočeni zaradi preveč neuspelih poskusov",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Sproži se, ko zahteva za vir RSS za samodejni prenos epizode ne uspe",
|
||||||
"NotificationOnTestDescription": "Dogodek za testiranje sistema obveščanja",
|
"NotificationOnTestDescription": "Dogodek za testiranje sistema obveščanja",
|
||||||
"PlaceholderNewCollection": "Novo ime zbirke",
|
"PlaceholderNewCollection": "Novo ime zbirke",
|
||||||
"PlaceholderNewFolderPath": "Pot nove mape",
|
"PlaceholderNewFolderPath": "Pot nove mape",
|
||||||
|
|||||||
@@ -514,7 +514,7 @@
|
|||||||
"LabelPublishers": "Видавці",
|
"LabelPublishers": "Видавці",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Користувацька електронна адреса власника",
|
"LabelRSSFeedCustomOwnerEmail": "Користувацька електронна адреса власника",
|
||||||
"LabelRSSFeedCustomOwnerName": "Користувацьке ім'я власника",
|
"LabelRSSFeedCustomOwnerName": "Користувацьке ім'я власника",
|
||||||
"LabelRSSFeedOpen": "RSS-канал відкрито",
|
"LabelRSSFeedOpen": "RSS-канал відкритий",
|
||||||
"LabelRSSFeedPreventIndexing": "Запобігати індексації",
|
"LabelRSSFeedPreventIndexing": "Запобігати індексації",
|
||||||
"LabelRSSFeedSlug": "Назва RSS-каналу",
|
"LabelRSSFeedSlug": "Назва RSS-каналу",
|
||||||
"LabelRSSFeedURL": "Адреса RSS-каналу",
|
"LabelRSSFeedURL": "Адреса RSS-каналу",
|
||||||
@@ -918,6 +918,8 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "Запускається після завершення резервного копіювання",
|
"NotificationOnBackupCompletedDescription": "Запускається після завершення резервного копіювання",
|
||||||
"NotificationOnBackupFailedDescription": "Срабатывает при збої резервного копіювання",
|
"NotificationOnBackupFailedDescription": "Срабатывает при збої резервного копіювання",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "Запускається при автоматичному завантаженні епізоду подкасту",
|
"NotificationOnEpisodeDownloadedDescription": "Запускається при автоматичному завантаженні епізоду подкасту",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Активується, коли автоматичне завантаження епізодів вимкнено через занадто багато невдалих спроб",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Активується, коли запит RSS-каналу не вдається виконати для автоматичного завантаження епізоду",
|
||||||
"NotificationOnTestDescription": "Подія для тестування системи сповіщень",
|
"NotificationOnTestDescription": "Подія для тестування системи сповіщень",
|
||||||
"PlaceholderNewCollection": "Нова назва добірки",
|
"PlaceholderNewCollection": "Нова назва добірки",
|
||||||
"PlaceholderNewFolderPath": "Новий шлях до теки",
|
"PlaceholderNewFolderPath": "Новий шлях до теки",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ if (isDev) {
|
|||||||
if (devEnv.SkipBinariesCheck) process.env.SKIP_BINARIES_CHECK = '1'
|
if (devEnv.SkipBinariesCheck) process.env.SKIP_BINARIES_CHECK = '1'
|
||||||
if (devEnv.AllowIframe) process.env.ALLOW_IFRAME = '1'
|
if (devEnv.AllowIframe) process.env.ALLOW_IFRAME = '1'
|
||||||
if (devEnv.BackupPath) process.env.BACKUP_PATH = devEnv.BackupPath
|
if (devEnv.BackupPath) process.env.BACKUP_PATH = devEnv.BackupPath
|
||||||
|
if (devEnv.ReactClientPath) process.env.REACT_CLIENT_PATH = devEnv.ReactClientPath
|
||||||
process.env.SOURCE = 'local'
|
process.env.SOURCE = 'local'
|
||||||
process.env.ROUTER_BASE_PATH = devEnv.RouterBasePath ?? '/audiobookshelf'
|
process.env.ROUTER_BASE_PATH = devEnv.RouterBasePath ?? '/audiobookshelf'
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.24.0",
|
"version": "2.25.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.24.0",
|
"version": "2.25.1",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.24.0",
|
"version": "2.25.1",
|
||||||
"buildNumber": 1,
|
"buildNumber": 1,
|
||||||
"description": "Self-hosted audiobook and podcast server",
|
"description": "Self-hosted audiobook and podcast server",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
+12
-1
@@ -442,7 +442,17 @@ class Auth {
|
|||||||
// Local strategy login route (takes username and password)
|
// Local strategy login route (takes username and password)
|
||||||
router.post('/login', passport.authenticate('local'), async (req, res) => {
|
router.post('/login', passport.authenticate('local'), async (req, res) => {
|
||||||
// return the user login response json if the login was successfull
|
// return the user login response json if the login was successfull
|
||||||
res.json(await this.getUserLoginResponsePayload(req.user))
|
const userResponse = await this.getUserLoginResponsePayload(req.user)
|
||||||
|
|
||||||
|
// Experimental Next.js client uses bearer token in cookies
|
||||||
|
res.cookie('auth_token', userResponse.user.token, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: req.secure || req.get('x-forwarded-proto') === 'https',
|
||||||
|
sameSite: 'strict',
|
||||||
|
maxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
|
||||||
|
})
|
||||||
|
|
||||||
|
res.json(userResponse)
|
||||||
})
|
})
|
||||||
|
|
||||||
// openid strategy login route (this redirects to the configured openid login provider)
|
// openid strategy login route (this redirects to the configured openid login provider)
|
||||||
@@ -718,6 +728,7 @@ class Auth {
|
|||||||
const authMethod = req.cookies.auth_method
|
const authMethod = req.cookies.auth_method
|
||||||
|
|
||||||
res.clearCookie('auth_method')
|
res.clearCookie('auth_method')
|
||||||
|
res.clearCookie('auth_token')
|
||||||
|
|
||||||
let logoutUrl = null
|
let logoutUrl = null
|
||||||
|
|
||||||
|
|||||||
+13
-2
@@ -766,8 +766,19 @@ class Database {
|
|||||||
Logger.warn(`Removed ${badSessionsRemoved} sessions that were 3 seconds or less`)
|
Logger.warn(`Removed ${badSessionsRemoved} sessions that were 3 seconds or less`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove mediaProgresses with duplicate mediaItemId (remove the oldest updatedAt)
|
// Remove mediaProgresses with duplicate mediaItemId (remove the oldest updatedAt or if updatedAt is the same, remove arbitrary one)
|
||||||
const [duplicateMediaProgresses] = await this.sequelize.query(`SELECT id, mediaItemId FROM mediaProgresses WHERE (mediaItemId, updatedAt) IN (SELECT mediaItemId, MIN(updatedAt) FROM mediaProgresses GROUP BY mediaItemId HAVING COUNT(*) > 1)`)
|
const [duplicateMediaProgresses] = await this.sequelize.query(`SELECT mp1.id, mp1.mediaItemId
|
||||||
|
FROM mediaProgresses mp1
|
||||||
|
WHERE EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM mediaProgresses mp2
|
||||||
|
WHERE mp2.mediaItemId = mp1.mediaItemId
|
||||||
|
AND mp2.userId = mp1.userId
|
||||||
|
AND (
|
||||||
|
mp2.updatedAt > mp1.updatedAt
|
||||||
|
OR (mp2.updatedAt = mp1.updatedAt AND mp2.id < mp1.id)
|
||||||
|
)
|
||||||
|
)`)
|
||||||
for (const duplicateMediaProgress of duplicateMediaProgresses) {
|
for (const duplicateMediaProgress of duplicateMediaProgresses) {
|
||||||
Logger.warn(`Found duplicate mediaProgress for mediaItem "${duplicateMediaProgress.mediaItemId}" - removing it`)
|
Logger.warn(`Found duplicate mediaProgress for mediaItem "${duplicateMediaProgress.mediaItemId}" - removing it`)
|
||||||
await this.mediaProgressModel.destroy({
|
await this.mediaProgressModel.destroy({
|
||||||
|
|||||||
+44
-30
@@ -220,6 +220,7 @@ class Server {
|
|||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
Logger.info('=== Starting Server ===')
|
Logger.info('=== Starting Server ===')
|
||||||
|
|
||||||
this.initProcessEventListeners()
|
this.initProcessEventListeners()
|
||||||
await this.init()
|
await this.init()
|
||||||
|
|
||||||
@@ -281,6 +282,7 @@ class Server {
|
|||||||
await this.auth.initPassportJs()
|
await this.auth.initPassportJs()
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
// if RouterBasePath is set, modify all requests to include the base path
|
// if RouterBasePath is set, modify all requests to include the base path
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const urlStartsWithRouterBasePath = req.url.startsWith(global.RouterBasePath)
|
const urlStartsWithRouterBasePath = req.url.startsWith(global.RouterBasePath)
|
||||||
@@ -313,10 +315,6 @@ class Server {
|
|||||||
router.use('/hls', this.hlsRouter.router)
|
router.use('/hls', this.hlsRouter.router)
|
||||||
router.use('/public', this.publicRouter.router)
|
router.use('/public', this.publicRouter.router)
|
||||||
|
|
||||||
// Static path to generated nuxt
|
|
||||||
const distPath = Path.join(global.appRoot, '/client/dist')
|
|
||||||
router.use(express.static(distPath))
|
|
||||||
|
|
||||||
// Static folder
|
// Static folder
|
||||||
router.use(express.static(Path.join(global.appRoot, 'static')))
|
router.use(express.static(Path.join(global.appRoot, 'static')))
|
||||||
|
|
||||||
@@ -336,32 +334,6 @@ class Server {
|
|||||||
// Auth routes
|
// Auth routes
|
||||||
await this.auth.initAuthRoutes(router)
|
await this.auth.initAuthRoutes(router)
|
||||||
|
|
||||||
// Client dynamic routes
|
|
||||||
const dynamicRoutes = [
|
|
||||||
'/item/:id',
|
|
||||||
'/author/:id',
|
|
||||||
'/audiobook/:id/chapters',
|
|
||||||
'/audiobook/:id/edit',
|
|
||||||
'/audiobook/:id/manage',
|
|
||||||
'/library/:library',
|
|
||||||
'/library/:library/search',
|
|
||||||
'/library/:library/bookshelf/:id?',
|
|
||||||
'/library/:library/authors',
|
|
||||||
'/library/:library/narrators',
|
|
||||||
'/library/:library/stats',
|
|
||||||
'/library/:library/series/:id?',
|
|
||||||
'/library/:library/podcast/search',
|
|
||||||
'/library/:library/podcast/latest',
|
|
||||||
'/library/:library/podcast/download-queue',
|
|
||||||
'/config/users/:id',
|
|
||||||
'/config/users/:id/sessions',
|
|
||||||
'/config/item-metadata-utils/:id',
|
|
||||||
'/collection/:id',
|
|
||||||
'/playlist/:id',
|
|
||||||
'/share/:slug'
|
|
||||||
]
|
|
||||||
dynamicRoutes.forEach((route) => router.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
|
|
||||||
|
|
||||||
router.post('/init', (req, res) => {
|
router.post('/init', (req, res) => {
|
||||||
if (Database.hasRootUser) {
|
if (Database.hasRootUser) {
|
||||||
Logger.error(`[Server] attempt to init server when server already has a root user`)
|
Logger.error(`[Server] attempt to init server when server already has a root user`)
|
||||||
@@ -392,6 +364,48 @@ class Server {
|
|||||||
})
|
})
|
||||||
router.get('/healthcheck', (req, res) => res.sendStatus(200))
|
router.get('/healthcheck', (req, res) => res.sendStatus(200))
|
||||||
|
|
||||||
|
const ReactClientPath = process.env.REACT_CLIENT_PATH
|
||||||
|
if (!ReactClientPath) {
|
||||||
|
// Static path to generated nuxt
|
||||||
|
const distPath = Path.join(global.appRoot, '/client/dist')
|
||||||
|
router.use(express.static(distPath))
|
||||||
|
|
||||||
|
// Client dynamic routes
|
||||||
|
const dynamicRoutes = [
|
||||||
|
'/item/:id',
|
||||||
|
'/author/:id',
|
||||||
|
'/audiobook/:id/chapters',
|
||||||
|
'/audiobook/:id/edit',
|
||||||
|
'/audiobook/:id/manage',
|
||||||
|
'/library/:library',
|
||||||
|
'/library/:library/search',
|
||||||
|
'/library/:library/bookshelf/:id?',
|
||||||
|
'/library/:library/authors',
|
||||||
|
'/library/:library/narrators',
|
||||||
|
'/library/:library/stats',
|
||||||
|
'/library/:library/series/:id?',
|
||||||
|
'/library/:library/podcast/search',
|
||||||
|
'/library/:library/podcast/latest',
|
||||||
|
'/library/:library/podcast/download-queue',
|
||||||
|
'/config/users/:id',
|
||||||
|
'/config/users/:id/sessions',
|
||||||
|
'/config/item-metadata-utils/:id',
|
||||||
|
'/collection/:id',
|
||||||
|
'/playlist/:id',
|
||||||
|
'/share/:slug'
|
||||||
|
]
|
||||||
|
dynamicRoutes.forEach((route) => router.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
|
||||||
|
} else {
|
||||||
|
// This is for using the experimental Next.js client
|
||||||
|
Logger.info(`Using React client at ${ReactClientPath}`)
|
||||||
|
const nextPath = Path.join(ReactClientPath, 'node_modules/next')
|
||||||
|
const next = require(nextPath)
|
||||||
|
const nextApp = next({ dev: Logger.isDev, dir: ReactClientPath })
|
||||||
|
const handle = nextApp.getRequestHandler()
|
||||||
|
await nextApp.prepare()
|
||||||
|
router.get('*', (req, res) => handle(req, res))
|
||||||
|
}
|
||||||
|
|
||||||
const unixSocketPrefix = 'unix/'
|
const unixSocketPrefix = 'unix/'
|
||||||
if (this.Host?.startsWith(unixSocketPrefix)) {
|
if (this.Host?.startsWith(unixSocketPrefix)) {
|
||||||
const sockPath = this.Host.slice(unixSocketPrefix.length)
|
const sockPath = this.Host.slice(unixSocketPrefix.length)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -107,7 +107,7 @@ class PlaybackSessionManager {
|
|||||||
|
|
||||||
const syncResults = []
|
const syncResults = []
|
||||||
for (const sessionJson of sessions) {
|
for (const sessionJson of sessions) {
|
||||||
Logger.info(`[PlaybackSessionManager] Syncing local session "${sessionJson.displayTitle}" (${sessionJson.id})`)
|
Logger.info(`[PlaybackSessionManager] Syncing local session "${sessionJson.displayTitle}" (${sessionJson.id}) (updatedAt: ${sessionJson.updatedAt})`)
|
||||||
const result = await this.syncLocalSession(user, sessionJson, deviceInfo)
|
const result = await this.syncLocalSession(user, sessionJson, deviceInfo)
|
||||||
syncResults.push(result)
|
syncResults.push(result)
|
||||||
}
|
}
|
||||||
@@ -230,9 +230,9 @@ class PlaybackSessionManager {
|
|||||||
let userProgressForItem = user.getMediaProgress(mediaItemId)
|
let userProgressForItem = user.getMediaProgress(mediaItemId)
|
||||||
if (userProgressForItem) {
|
if (userProgressForItem) {
|
||||||
if (userProgressForItem.updatedAt.valueOf() > session.updatedAt) {
|
if (userProgressForItem.updatedAt.valueOf() > session.updatedAt) {
|
||||||
Logger.debug(`[PlaybackSessionManager] Not updating progress for "${session.displayTitle}" because it has been updated more recently`)
|
Logger.info(`[PlaybackSessionManager] Not updating progress for "${session.displayTitle}" because it has been updated more recently (${userProgressForItem.updatedAt.valueOf()} > ${session.updatedAt}) (incoming currentTime: ${session.currentTime}) (current currentTime: ${userProgressForItem.currentTime})`)
|
||||||
} else {
|
} else {
|
||||||
Logger.debug(`[PlaybackSessionManager] Updating progress for "${session.displayTitle}" with current time ${session.currentTime} (previously ${userProgressForItem.currentTime})`)
|
Logger.info(`[PlaybackSessionManager] Updating progress for "${session.displayTitle}" with current time ${session.currentTime} (previously ${userProgressForItem.currentTime})`)
|
||||||
const updateResponse = await user.createUpdateMediaProgressFromPayload({
|
const updateResponse = await user.createUpdateMediaProgressFromPayload({
|
||||||
libraryItemId: libraryItem.id,
|
libraryItemId: libraryItem.id,
|
||||||
episodeId: session.episodeId,
|
episodeId: session.episodeId,
|
||||||
@@ -246,7 +246,7 @@ class PlaybackSessionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.debug(`[PlaybackSessionManager] Creating new media progress for media item "${session.displayTitle}"`)
|
Logger.info(`[PlaybackSessionManager] Creating new media progress for media item "${session.displayTitle}"`)
|
||||||
const updateResponse = await user.createUpdateMediaProgressFromPayload({
|
const updateResponse = await user.createUpdateMediaProgressFromPayload({
|
||||||
libraryItemId: libraryItem.id,
|
libraryItemId: libraryItem.id,
|
||||||
episodeId: session.episodeId,
|
episodeId: session.episodeId,
|
||||||
|
|||||||
@@ -222,13 +222,13 @@ class MediaProgress extends Model {
|
|||||||
const markAsFinishedPercentComplete = Number(progressPayload.markAsFinishedPercentComplete) / 100
|
const markAsFinishedPercentComplete = Number(progressPayload.markAsFinishedPercentComplete) / 100
|
||||||
shouldMarkAsFinished = markAsFinishedPercentComplete < this.progress
|
shouldMarkAsFinished = markAsFinishedPercentComplete < this.progress
|
||||||
if (shouldMarkAsFinished) {
|
if (shouldMarkAsFinished) {
|
||||||
Logger.debug(`[MediaProgress] Marking media progress as finished because progress (${this.progress}) is greater than ${markAsFinishedPercentComplete}`)
|
Logger.info(`[MediaProgress] Marking media progress as finished because progress (${this.progress}) is greater than ${markAsFinishedPercentComplete} (media item ${this.mediaItemId})`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const markAsFinishedTimeRemaining = isNullOrNaN(progressPayload.markAsFinishedTimeRemaining) ? 10 : Number(progressPayload.markAsFinishedTimeRemaining)
|
const markAsFinishedTimeRemaining = isNullOrNaN(progressPayload.markAsFinishedTimeRemaining) ? 10 : Number(progressPayload.markAsFinishedTimeRemaining)
|
||||||
shouldMarkAsFinished = timeRemaining < markAsFinishedTimeRemaining
|
shouldMarkAsFinished = timeRemaining < markAsFinishedTimeRemaining
|
||||||
if (shouldMarkAsFinished) {
|
if (shouldMarkAsFinished) {
|
||||||
Logger.debug(`[MediaProgress] Marking media progress as finished because time remaining (${timeRemaining}) is less than ${markAsFinishedTimeRemaining} seconds`)
|
Logger.info(`[MediaProgress] Marking media progress as finished because time remaining (${timeRemaining}) is less than ${markAsFinishedTimeRemaining} seconds (media item ${this.mediaItemId})`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,6 +246,7 @@ class MediaProgress extends Model {
|
|||||||
// For local sync
|
// For local sync
|
||||||
if (progressPayload.lastUpdate) {
|
if (progressPayload.lastUpdate) {
|
||||||
this.updatedAt = progressPayload.lastUpdate
|
this.updatedAt = progressPayload.lastUpdate
|
||||||
|
Logger.info(`[MediaProgress] Manually setting updatedAt to ${this.updatedAt} (media item ${this.mediaItemId})`)
|
||||||
this.changed('updatedAt', true)
|
this.changed('updatedAt', true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class Audible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanResult(item) {
|
cleanResult(item) {
|
||||||
const { title, subtitle, asin, authors, narrators, publisherName, summary, releaseDate, image, genres, seriesPrimary, seriesSecondary, language, runtimeLengthMin, formatType } = item
|
const { title, subtitle, asin, authors, narrators, publisherName, summary, releaseDate, image, genres, seriesPrimary, seriesSecondary, language, runtimeLengthMin, formatType, isbn } = item
|
||||||
|
|
||||||
const series = []
|
const series = []
|
||||||
if (seriesPrimary) {
|
if (seriesPrimary) {
|
||||||
@@ -70,6 +70,7 @@ class Audible {
|
|||||||
description: summary || null,
|
description: summary || null,
|
||||||
cover: image,
|
cover: image,
|
||||||
asin,
|
asin,
|
||||||
|
isbn,
|
||||||
genres: genresFiltered.length ? genresFiltered : null,
|
genres: genresFiltered.length ? genresFiltered : null,
|
||||||
tags: tagsFiltered.length ? tagsFiltered.join(', ') : null,
|
tags: tagsFiltered.length ? tagsFiltered.join(', ') : null,
|
||||||
series: series.length ? series : null,
|
series: series.length ? series : null,
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ class FantLab {
|
|||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
||||||
return Promise.all(items.map(async (item) => await this.getWork(item, timeout))).then((resArray) => {
|
return Promise.all(items.map(async (item) => await this.getWork(item, timeout))).then((resArray) => resArray.filter(Boolean))
|
||||||
return resArray.filter((res) => res)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +81,10 @@ class FantLab {
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (!bookData) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return this.cleanBookData(bookData, timeout)
|
return this.cleanBookData(bookData, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ class Scanner {
|
|||||||
|
|
||||||
let numEpisodesUpdated = 0
|
let numEpisodesUpdated = 0
|
||||||
for (const episode of episodesToQuickMatch) {
|
for (const episode of episodesToQuickMatch) {
|
||||||
const episodeMatches = findMatchingEpisodesInFeed(feed, episode.title)
|
const episodeMatches = findMatchingEpisodesInFeed(feed, episode.title, 0.1)
|
||||||
if (episodeMatches?.length) {
|
if (episodeMatches?.length) {
|
||||||
const wasUpdated = await this.updateEpisodeWithMatch(episode, episodeMatches[0].episode, options)
|
const wasUpdated = await this.updateEpisodeWithMatch(episode, episodeMatches[0].episode, options)
|
||||||
if (wasUpdated) numEpisodesUpdated++
|
if (wasUpdated) numEpisodesUpdated++
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
const ssrfFilter = require('ssrf-req-filter')
|
const ssrfFilter = require('ssrf-req-filter')
|
||||||
const Logger = require('../Logger')
|
const Logger = require('../Logger')
|
||||||
const { xmlToJSON, levenshteinDistance, timestampToSeconds } = require('./index')
|
const { xmlToJSON, timestampToSeconds } = require('./index')
|
||||||
const htmlSanitizer = require('../utils/htmlSanitizer')
|
const htmlSanitizer = require('../utils/htmlSanitizer')
|
||||||
|
const Fuse = require('../libs/fusejs')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef RssPodcastChapter
|
* @typedef RssPodcastChapter
|
||||||
@@ -24,6 +25,7 @@ const htmlSanitizer = require('../utils/htmlSanitizer')
|
|||||||
* @property {string} episode
|
* @property {string} episode
|
||||||
* @property {string} author
|
* @property {string} author
|
||||||
* @property {string} duration
|
* @property {string} duration
|
||||||
|
* @property {number|null} durationSeconds - Parsed from duration string if duration is valid
|
||||||
* @property {string} explicit
|
* @property {string} explicit
|
||||||
* @property {number} publishedAt - Unix timestamp
|
* @property {number} publishedAt - Unix timestamp
|
||||||
* @property {{ url: string, type?: string, length?: string }} enclosure
|
* @property {{ url: string, type?: string, length?: string }} enclosure
|
||||||
@@ -216,8 +218,9 @@ function extractEpisodeData(item) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Extract psc:chapters if duration is set
|
// Extract psc:chapters if duration is set
|
||||||
let episodeDuration = !isNaN(episode.duration) ? timestampToSeconds(episode.duration) : null
|
episode.durationSeconds = episode.duration ? timestampToSeconds(episode.duration) : null
|
||||||
if (item['psc:chapters']?.[0]?.['psc:chapter']?.length && episodeDuration) {
|
|
||||||
|
if (item['psc:chapters']?.[0]?.['psc:chapter']?.length && episode.durationSeconds) {
|
||||||
// Example chapter:
|
// Example chapter:
|
||||||
// {"id":0,"start":0,"end":43.004286,"title":"chapter 1"}
|
// {"id":0,"start":0,"end":43.004286,"title":"chapter 1"}
|
||||||
|
|
||||||
@@ -243,7 +246,7 @@ function extractEpisodeData(item) {
|
|||||||
} else {
|
} else {
|
||||||
episode.chapters = cleanedChapters.map((chapter, index) => {
|
episode.chapters = cleanedChapters.map((chapter, index) => {
|
||||||
const nextChapter = cleanedChapters[index + 1]
|
const nextChapter = cleanedChapters[index + 1]
|
||||||
const end = nextChapter ? nextChapter.start : episodeDuration
|
const end = nextChapter ? nextChapter.start : episode.durationSeconds
|
||||||
return {
|
return {
|
||||||
id: chapter.id,
|
id: chapter.id,
|
||||||
title: chapter.title,
|
title: chapter.title,
|
||||||
@@ -272,6 +275,7 @@ function cleanEpisodeData(data) {
|
|||||||
episode: data.episode || '',
|
episode: data.episode || '',
|
||||||
author: data.author || '',
|
author: data.author || '',
|
||||||
duration: data.duration || '',
|
duration: data.duration || '',
|
||||||
|
durationSeconds: data.durationSeconds || null,
|
||||||
explicit: data.explicit || '',
|
explicit: data.explicit || '',
|
||||||
publishedAt,
|
publishedAt,
|
||||||
enclosure: data.enclosure,
|
enclosure: data.enclosure,
|
||||||
@@ -407,7 +411,7 @@ module.exports.getPodcastFeed = (feedUrl, excludeEpisodeMetadata = false) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return array of episodes ordered by closest match (Levenshtein distance of 6 or less)
|
// Return array of episodes ordered by closest match using fuse.js
|
||||||
module.exports.findMatchingEpisodes = async (feedUrl, searchTitle) => {
|
module.exports.findMatchingEpisodes = async (feedUrl, searchTitle) => {
|
||||||
const feed = await this.getPodcastFeed(feedUrl).catch(() => {
|
const feed = await this.getPodcastFeed(feedUrl).catch(() => {
|
||||||
return null
|
return null
|
||||||
@@ -420,32 +424,29 @@ module.exports.findMatchingEpisodes = async (feedUrl, searchTitle) => {
|
|||||||
*
|
*
|
||||||
* @param {RssPodcast} feed
|
* @param {RssPodcast} feed
|
||||||
* @param {string} searchTitle
|
* @param {string} searchTitle
|
||||||
* @returns {Array<{ episode: RssPodcastEpisode, levenshtein: number }>}
|
* @param {number} [threshold=0.4] - 0.0 for perfect match, 1.0 for match anything
|
||||||
|
* @returns {Array<{ episode: RssPodcastEpisode }>}
|
||||||
*/
|
*/
|
||||||
module.exports.findMatchingEpisodesInFeed = (feed, searchTitle) => {
|
module.exports.findMatchingEpisodesInFeed = (feed, searchTitle, threshold = 0.4) => {
|
||||||
searchTitle = searchTitle.toLowerCase().trim()
|
|
||||||
if (!feed?.episodes) {
|
if (!feed?.episodes) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fuseOptions = {
|
||||||
|
ignoreDiacritics: true,
|
||||||
|
threshold,
|
||||||
|
keys: [
|
||||||
|
{ name: 'title', weight: 0.7 }, // prefer match in title
|
||||||
|
{ name: 'subtitle', weight: 0.3 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const fuse = new Fuse(feed.episodes, fuseOptions)
|
||||||
|
|
||||||
const matches = []
|
const matches = []
|
||||||
feed.episodes.forEach((ep) => {
|
fuse.search(searchTitle).forEach((match) => {
|
||||||
if (!ep.title) return
|
matches.push({
|
||||||
const epTitle = ep.title.toLowerCase().trim()
|
episode: match.item
|
||||||
if (epTitle === searchTitle) {
|
})
|
||||||
matches.push({
|
|
||||||
episode: ep,
|
|
||||||
levenshtein: 0
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const levenshtein = levenshteinDistance(searchTitle, epTitle, true)
|
|
||||||
if (levenshtein <= 6 && epTitle.length > levenshtein) {
|
|
||||||
matches.push({
|
|
||||||
episode: ep,
|
|
||||||
levenshtein
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return matches.sort((a, b) => a.levenshtein - b.levenshtein)
|
return matches
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,6 +186,8 @@ module.exports = {
|
|||||||
mediaWhere['$series.id$'] = null
|
mediaWhere['$series.id$'] = null
|
||||||
} else if (group === 'abridged') {
|
} else if (group === 'abridged') {
|
||||||
mediaWhere['abridged'] = true
|
mediaWhere['abridged'] = true
|
||||||
|
} else if (group === 'explicit') {
|
||||||
|
mediaWhere['explicit'] = true
|
||||||
} else if (['genres', 'tags', 'narrators'].includes(group)) {
|
} else if (['genres', 'tags', 'narrators'].includes(group)) {
|
||||||
mediaWhere[group] = Sequelize.where(Sequelize.literal(`(SELECT count(*) FROM json_each(${group}) WHERE json_valid(${group}) AND json_each.value = :filterValue)`), {
|
mediaWhere[group] = Sequelize.where(Sequelize.literal(`(SELECT count(*) FROM json_each(${group}) WHERE json_valid(${group}) AND json_each.value = :filterValue)`), {
|
||||||
[Sequelize.Op.gte]: 1
|
[Sequelize.Op.gte]: 1
|
||||||
@@ -251,6 +253,15 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
getOrder(sortBy, sortDesc, collapseseries) {
|
getOrder(sortBy, sortDesc, collapseseries) {
|
||||||
const dir = sortDesc ? 'DESC' : 'ASC'
|
const dir = sortDesc ? 'DESC' : 'ASC'
|
||||||
|
|
||||||
|
const getTitleOrder = () => {
|
||||||
|
if (global.ServerSettings.sortingIgnorePrefix) {
|
||||||
|
return [Sequelize.literal('`libraryItem`.`titleIgnorePrefix` COLLATE NOCASE'), dir]
|
||||||
|
} else {
|
||||||
|
return [Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sortBy === 'addedAt') {
|
if (sortBy === 'addedAt') {
|
||||||
return [[Sequelize.literal('libraryItem.createdAt'), dir]]
|
return [[Sequelize.literal('libraryItem.createdAt'), dir]]
|
||||||
} else if (sortBy === 'size') {
|
} else if (sortBy === 'size') {
|
||||||
@@ -264,25 +275,16 @@ module.exports = {
|
|||||||
} else if (sortBy === 'media.metadata.publishedYear') {
|
} else if (sortBy === 'media.metadata.publishedYear') {
|
||||||
return [[Sequelize.literal(`CAST(\`book\`.\`publishedYear\` AS INTEGER)`), dir]]
|
return [[Sequelize.literal(`CAST(\`book\`.\`publishedYear\` AS INTEGER)`), dir]]
|
||||||
} else if (sortBy === 'media.metadata.authorNameLF') {
|
} else if (sortBy === 'media.metadata.authorNameLF') {
|
||||||
return [
|
// Sort by author name last first, secondary sort by title
|
||||||
[Sequelize.literal('`libraryItem`.`authorNamesLastFirst` COLLATE NOCASE'), dir],
|
return [[Sequelize.literal('`libraryItem`.`authorNamesLastFirst` COLLATE NOCASE'), dir], getTitleOrder()]
|
||||||
[Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]
|
|
||||||
]
|
|
||||||
} else if (sortBy === 'media.metadata.authorName') {
|
} else if (sortBy === 'media.metadata.authorName') {
|
||||||
return [
|
// Sort by author name first last, secondary sort by title
|
||||||
[Sequelize.literal('`libraryItem`.`authorNamesFirstLast` COLLATE NOCASE'), dir],
|
return [[Sequelize.literal('`libraryItem`.`authorNamesFirstLast` COLLATE NOCASE'), dir], getTitleOrder()]
|
||||||
[Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]
|
|
||||||
]
|
|
||||||
} else if (sortBy === 'media.metadata.title') {
|
} else if (sortBy === 'media.metadata.title') {
|
||||||
if (collapseseries) {
|
if (collapseseries) {
|
||||||
return [[Sequelize.literal('display_title COLLATE NOCASE'), dir]]
|
return [[Sequelize.literal('display_title COLLATE NOCASE'), dir]]
|
||||||
}
|
}
|
||||||
|
return [getTitleOrder()]
|
||||||
if (global.ServerSettings.sortingIgnorePrefix) {
|
|
||||||
return [[Sequelize.literal('`libraryItem`.`titleIgnorePrefix` COLLATE NOCASE'), dir]]
|
|
||||||
} else {
|
|
||||||
return [[Sequelize.literal('`libraryItem`.`title` COLLATE NOCASE'), dir]]
|
|
||||||
}
|
|
||||||
} else if (sortBy === 'sequence') {
|
} else if (sortBy === 'sequence') {
|
||||||
const nullDir = sortDesc ? 'DESC NULLS FIRST' : 'ASC NULLS LAST'
|
const nullDir = sortDesc ? 'DESC NULLS FIRST' : 'ASC NULLS LAST'
|
||||||
return [[Sequelize.literal(`CAST(\`series.bookSeries.sequence\` AS FLOAT) ${nullDir}`)]]
|
return [[Sequelize.literal(`CAST(\`series.bookSeries.sequence\` AS FLOAT) ${nullDir}`)]]
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ module.exports = {
|
|||||||
replacements.filterValue = value
|
replacements.filterValue = value
|
||||||
} else if (group === 'languages') {
|
} else if (group === 'languages') {
|
||||||
mediaWhere['language'] = value
|
mediaWhere['language'] = value
|
||||||
|
} else if (group === 'explicit') {
|
||||||
|
mediaWhere['explicit'] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user