From fbe9971a8b4fa3606ef8dbd8262a40ba03d40f3c Mon Sep 17 00:00:00 2001 From: votex001 Date: Wed, 3 Sep 2025 18:19:52 +0300 Subject: [PATCH 01/29] [fix] prevent duplicates in multi-selects --- client/components/ui/MultiSelect.vue | 2 +- client/components/ui/MultiSelectQueryInput.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/components/ui/MultiSelect.vue b/client/components/ui/MultiSelect.vue index c7572ba50..3dcfb0495 100644 --- a/client/components/ui/MultiSelect.vue +++ b/client/components/ui/MultiSelect.vue @@ -278,7 +278,7 @@ export default { }) }, insertNewItem(item) { - this.selected.push(item) + if (!this.selected.includes(item)) this.selected.push(item) this.$emit('input', this.selected) this.$emit('newItem', item) this.textInput = null diff --git a/client/components/ui/MultiSelectQueryInput.vue b/client/components/ui/MultiSelectQueryInput.vue index 18abc66e7..4bc434cbd 100644 --- a/client/components/ui/MultiSelectQueryInput.vue +++ b/client/components/ui/MultiSelectQueryInput.vue @@ -287,7 +287,7 @@ export default { }) }, insertNewItem(item) { - this.selected.push(item) + if (!this.selected.find((i) => i.name === item.name)) this.selected.push(item) this.$emit('input', this.selected) this.$emit('newItem', item) this.textInput = null From 797dba244892b3455a9506a44298446844a0f814 Mon Sep 17 00:00:00 2001 From: Frank de Lange Date: Fri, 10 Oct 2025 22:30:38 +0200 Subject: [PATCH 02/29] fix #1617 (useradd: user 'audiobookshelf' already exists) This change fixes the problem of failing upgrades on dpkg-based systems by reworking the check for whether the `audiobookshelf` user/group already exists. --- build/debian/DEBIAN/preinst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/debian/DEBIAN/preinst b/build/debian/DEBIAN/preinst index e30bc490c..241a47010 100644 --- a/build/debian/DEBIAN/preinst +++ b/build/debian/DEBIAN/preinst @@ -22,7 +22,7 @@ add_user() { declare -r descr="${4:-No description}" declare -r shell="${5:-/bin/false}" - if ! getent passwd | grep -q "^$user:"; then + if ! getent passwd "$user" 2>&1 >/dev/null; then echo "Creating system user: $user in $group with $descr and shell $shell" useradd $uid_flags --gid $group --no-create-home --system --shell $shell -c "$descr" $user fi @@ -39,7 +39,7 @@ add_group() { declare -r gid_flags="--gid $gid" fi - if ! getent group | grep -q "^$group:" ; then + if ! getent group "$group" 2>&1 >/dev/null; then echo "Creating system group: $group" groupadd $gid_flags --system $group fi From a5750deaaf824e99fec54848640c21d5395dd626 Mon Sep 17 00:00:00 2001 From: "Tomasz N." Date: Wed, 22 Oct 2025 23:02:49 +0200 Subject: [PATCH 03/29] The key change: Move the Database.bookAuthorModel.create() block outside the if (!author) check, so it runs whether the author was just created OR already existed in the database. This bug was visible when using "Match Books" for a library and the outcome was books had no author(s) assigned despite the custom providers correctly providing those values. --- server/scanner/Scanner.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index 206068cc4..cf5c87b78 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -259,7 +259,7 @@ class Scanner { SocketAuthority.emitter('author_added', author.toOldJSON()) // Update filter data Database.addAuthorToFilterData(libraryItem.libraryId, author.name, author.id) - + } await Database.bookAuthorModel .create({ authorId: author.id, @@ -270,7 +270,6 @@ class Scanner { libraryItem.media.authors.push(author) hasAuthorUpdates = true }) - } } const authorsRemoved = libraryItem.media.authors.filter((a) => !matchData.author.find((ma) => ma.toLowerCase() === a.name.toLowerCase())) if (authorsRemoved.length) { From 372c9a5322bca988f66c4d714067bfa5a9922ac8 Mon Sep 17 00:00:00 2001 From: "Tomasz N." Date: Fri, 31 Oct 2025 15:36:47 +0100 Subject: [PATCH 04/29] Increasing the timeout for bookfinder - some metadata providers heavily throttle the requests, original 10s is not enough. --- server/finders/BookFinder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/finders/BookFinder.js b/server/finders/BookFinder.js index fe1a61027..c25afe075 100644 --- a/server/finders/BookFinder.js +++ b/server/finders/BookFinder.js @@ -11,7 +11,7 @@ const { levenshteinDistance, levenshteinSimilarity, escapeRegExp, isValidASIN } const htmlSanitizer = require('../utils/htmlSanitizer') class BookFinder { - #providerResponseTimeout = 10000 + #providerResponseTimeout = 120000 constructor() { this.openLibrary = new OpenLibrary() From 961d066bdd5d18efa2d8774362b2b236a8ca2d82 Mon Sep 17 00:00:00 2001 From: "Tomasz N." Date: Fri, 31 Oct 2025 15:39:12 +0100 Subject: [PATCH 05/29] Wrong branch. --- server/finders/BookFinder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/finders/BookFinder.js b/server/finders/BookFinder.js index c25afe075..fe1a61027 100644 --- a/server/finders/BookFinder.js +++ b/server/finders/BookFinder.js @@ -11,7 +11,7 @@ const { levenshteinDistance, levenshteinSimilarity, escapeRegExp, isValidASIN } const htmlSanitizer = require('../utils/htmlSanitizer') class BookFinder { - #providerResponseTimeout = 120000 + #providerResponseTimeout = 10000 constructor() { this.openLibrary = new OpenLibrary() From 648983708ed2c461a286f153917615d60788cffe Mon Sep 17 00:00:00 2001 From: sir-wilhelm Date: Fri, 12 Dec 2025 04:02:20 +0000 Subject: [PATCH 06/29] Sort the playlist sections alphabetically. --- client/components/modals/playlists/AddCreateModal.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/components/modals/playlists/AddCreateModal.vue b/client/components/modals/playlists/AddCreateModal.vue index e695ccb0c..f8543f1de 100644 --- a/client/components/modals/playlists/AddCreateModal.vue +++ b/client/components/modals/playlists/AddCreateModal.vue @@ -97,7 +97,10 @@ export default { ...playlist } }) - .sort((a, b) => (a.isItemIncluded ? -1 : 1)) + .sort((a, b) => { + if (a.isItemIncluded !== b.isItemIncluded) return a.isItemIncluded ? -1 : 1 + return a.name.localeCompare(b.name) + }) }, isBatch() { return this.selectedPlaylistItems.length > 1 From 503f4611b221a5bde19024e657021670df204478 Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 12 Dec 2025 17:24:01 -0600 Subject: [PATCH 07/29] Update tooltip with plaintext prop --- client/components/cards/LazyBookCard.vue | 6 +++--- client/components/stats/DailyListeningChart.vue | 2 +- client/components/ui/Tooltip.vue | 15 ++++++++++++--- client/pages/audiobook/_id/chapters.vue | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index d06f083ba..51f657dbc 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -78,7 +78,7 @@ - +
priority_high
@@ -121,12 +121,12 @@
- +

{{ displayTitle }}

- +

{{ displaySubtitle }}

{{ displayLineTwo || ' ' }}

diff --git a/client/components/stats/DailyListeningChart.vue b/client/components/stats/DailyListeningChart.vue index f3a50d11c..55752fc5d 100644 --- a/client/components/stats/DailyListeningChart.vue +++ b/client/components/stats/DailyListeningChart.vue @@ -14,7 +14,7 @@
- +
diff --git a/client/components/ui/Tooltip.vue b/client/components/ui/Tooltip.vue index e6ab0117b..c858cbfec 100644 --- a/client/components/ui/Tooltip.vue +++ b/client/components/ui/Tooltip.vue @@ -22,7 +22,8 @@ export default { type: Number, default: 0 }, - disabled: Boolean + disabled: Boolean, + plaintext: Boolean }, data() { return { @@ -46,7 +47,11 @@ export default { methods: { updateText() { if (this.tooltip) { - this.tooltip.innerHTML = this.text + if (this.plaintext) { + this.tooltip.textContent = this.text + } else { + this.tooltip.innerHTML = this.text + } this.setTooltipPosition(this.tooltip) } }, @@ -58,7 +63,11 @@ export default { tooltip.className = 'tooltip-wrapper absolute px-2 py-1 text-white text-xs rounded-sm shadow-lg max-w-xs text-center hidden sm:block' tooltip.style.zIndex = 100 tooltip.style.backgroundColor = 'rgba(0,0,0,0.85)' - tooltip.innerHTML = this.text + if (this.plaintext) { + tooltip.textContent = this.text + } else { + tooltip.innerHTML = this.text + } tooltip.addEventListener('mouseover', this.cancelHide) tooltip.addEventListener('mouseleave', this.hideTooltip) diff --git a/client/pages/audiobook/_id/chapters.vue b/client/pages/audiobook/_id/chapters.vue index 4d6c0e41d..e91a8846d 100644 --- a/client/pages/audiobook/_id/chapters.vue +++ b/client/pages/audiobook/_id/chapters.vue @@ -126,7 +126,7 @@
{{ elapsedTime }}s
- + From bcfe1e96478a977b74a3b4267852d707496b8995 Mon Sep 17 00:00:00 2001 From: thehijacker Date: Tue, 2 Dec 2025 12:57:43 +0100 Subject: [PATCH 08/29] Translated using Weblate (Slovenian) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sl/ --- client/strings/sl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/sl.json b/client/strings/sl.json index 962ccaa80..3b7ce53a2 100644 --- a/client/strings/sl.json +++ b/client/strings/sl.json @@ -383,7 +383,7 @@ "LabelFolders": "Mape", "LabelFontBold": "Krepko", "LabelFontBoldness": "Krepkost pisave", - "LabelFontFamily": "Družina pisave", + "LabelFontFamily": "Družina pisav", "LabelFontItalic": "Ležeče", "LabelFontScale": "Merilo pisave", "LabelFontStrikethrough": "Prečrtano", From 5de942aefbf915297e91e87f6ed44bec906126c6 Mon Sep 17 00:00:00 2001 From: Napitauki Date: Mon, 1 Dec 2025 23:09:52 +0100 Subject: [PATCH 09/29] Translated using Weblate (Finnish) Currently translated at 97.6% (1136 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fi/ --- client/strings/fi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/fi.json b/client/strings/fi.json index bf2659ba1..db152c9f3 100644 --- a/client/strings/fi.json +++ b/client/strings/fi.json @@ -930,7 +930,7 @@ "MessageTaskScanningFileChanges": "Tarkastetaan tiedoston muutoksia \"{0}\":sta", "MessageTaskScanningLibrary": "Tarkastetaan kirjastoa \"{0}\"", "MessageTaskTargetDirectoryNotWritable": "Kohdehakemisto ei ole kirjoitettava", - "MessageThinking": "Ajattellaan...", + "MessageThinking": "Ajatellaan...", "MessageUploaderItemFailed": "Lataaminen ulospäin epäonnistui", "MessageUploaderItemSuccess": "Onnistuneesti ladattu! ulospäin!", "MessageUploading": "Ladataan! ulospäin...", From a33e87db9965f2aabc370699c66de520a1488ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4m=C3=A4l=C3=A4inen?= Date: Tue, 2 Dec 2025 17:39:45 +0100 Subject: [PATCH 10/29] Translated using Weblate (Finnish) Currently translated at 97.6% (1136 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fi/ --- client/strings/fi.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/strings/fi.json b/client/strings/fi.json index db152c9f3..600db265a 100644 --- a/client/strings/fi.json +++ b/client/strings/fi.json @@ -815,6 +815,7 @@ "MessageFeedURLWillBe": "Syötteen URL tulee olemaan {0}", "MessageFetching": "Haetaan...", "MessageForceReScanDescription": "skannaa kaikki tiedostot uudelleen kuten uusi tarkistus. Äänitiedoston ID3-tunnisteet, OPF-tiedostot ja tekstitiedostot skannataan uusina.", + "MessageHeatmapListeningTimeTooltip": "{0} kuunnellaan on {1}", "MessageImportantNotice": "Tärkeä huomautus!", "MessageInsertChapterBelow": "Syötä luku alle", "MessageInvalidAsin": "Virheellinen ASIN", @@ -885,7 +886,7 @@ "MessageResetChaptersConfirm": "Oletko varma, että haluat nollata luvut ja kumota tekemäsi muutokset?", "MessageRestoreBackupConfirm": "Oletko varma, että haluat palauttaa varmuuskopion, joka on luotu", "MessageRestoreBackupWarning": "Varmuuskopion palauttaminen korvaa koko /config:ssa sijaitsevan tietokannan, ja kansikuvat /metadata/items & /metadata/authors:ssa.

Varmuuskopiot eivät muuta kirjastokansioissasi olevia tiedostoja. Jos olet ottanut käyttöön palvelinasetuksissa kansikuvien ja metatietojen tallentamisen kirjaston kansioihin, niitä ei varmuuskopioida tai korvata.

Kaikki palvelintasi käyttävät asiakkaat virkistetään automaattisesti.", - "MessageScheduleLibraryScanNote": "Suurimmalle osaa käyttäjistä on suositeltavaa jättää tämä ominaisuus pois päältä ja säilyttää kansiotarkkailu päällä. Kansiotarkkailu havaitsee automaattisesti tiedostomuutokset kirjaston kansioissa. Kansiotarkkailu ei toimi kaikille tiedostojärjestelmille (kuten NFS), jolloin voidaan käyttää ajastettuja kirjastoskannauksia.", + "MessageScheduleLibraryScanNote": "Suurimmalle osaa käyttäjistä on suositeltavaa jättää tämä ominaisuus pois päältä ja \"Tarkkaile kirjaston muutoksia automaattisesti\" -asetus pidetään käytössä - se havaitsee muutokset kirjastokansioissasi automaattisesti. Ota tämä ominaisuus käyttöön, jos \"Tarkkaile kirjaston muutoksia automaattisesti\" ei toimi tiedostojärjestelmässäsi (kuten NFS).\"", "MessageScheduleRunEveryWeekdayAtTime": "Suorita joka {0} klo {1}", "MessageSearchResultsFor": "Hakutulokset haulle", "MessageSelected": "{0} valittuna", From ed5766b4ab13f8b11cfce088c3fb7ada0c64dd0c Mon Sep 17 00:00:00 2001 From: Alessandro Burzio Date: Mon, 1 Dec 2025 23:05:14 +0100 Subject: [PATCH 11/29] Translated using Weblate (Italian) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/it/ --- client/strings/it.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/strings/it.json b/client/strings/it.json index 2354bc0ae..46ecb0f53 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -383,7 +383,7 @@ "LabelFolders": "Cartelle", "LabelFontBold": "Grassetto", "LabelFontBoldness": "Grassetto", - "LabelFontFamily": "Famiglia di caratteri", + "LabelFontFamily": "Famiglia caratteri", "LabelFontItalic": "Corsivo", "LabelFontScale": "Dimensione font", "LabelFontStrikethrough": "Barrato", @@ -588,8 +588,8 @@ "LabelSettingsBookshelfViewHelp": "Design con scaffali in legno", "LabelSettingsChromecastSupport": "Supporto a Chromecast", "LabelSettingsDateFormat": "Formato Data", - "LabelSettingsEnableWatcher": "Scansiona le librerie Automaticamente per trovare modifiche", - "LabelSettingsEnableWatcherForLibrary": "Scansiona la libreria Automaticamente per trovare modifiche", + "LabelSettingsEnableWatcher": "Controlla automaticamente le modifiche alle librerie", + "LabelSettingsEnableWatcherForLibrary": "Controlla automaticamente le modifiche alle librerie", "LabelSettingsEnableWatcherHelp": "Abilita l'aggiunta/aggiornamento automatico degli elementi quando vengono rilevate modifiche ai file. *Richiede il riavvio del Server", "LabelSettingsEpubsAllowScriptedContent": "Consenti contenuti con script negli epub", "LabelSettingsEpubsAllowScriptedContentHelp": "Consenti ai file epub di eseguire script. Si consiglia di mantenere questa impostazione disabilitata a meno che non si ritenga attendibile l'origine dei file epub.", @@ -888,7 +888,7 @@ "MessageResetChaptersConfirm": "Sei sicuro di voler reimpostare i capitoli e annullare le modifiche ?", "MessageRestoreBackupConfirm": "Sei sicuro di voler ripristinare il backup creato su", "MessageRestoreBackupWarning": "Il ripristino di un backup sovrascriverà l'intero database situato in /config e sovrascrive le immagini in /metadata/items & /metadata/authors.

I backup non modificano alcun file nelle cartelle della libreria. Se hai abilitato le impostazioni del server per archiviare copertine e metadati nelle cartelle della libreria, questi non vengono sottoposti a backup o sovrascritti.

Tutti i client che utilizzano il tuo server verranno aggiornati automaticamente.", - "MessageScheduleLibraryScanNote": "Per la maggior parte degli utenti, si consiglia di lasciare questa funzionalità disabilitata e di mantenere abilitata l'impostazione di folder watcher. Il folder watcher rileverà automaticamente le modifiche nelle cartelle della libreria. Il folder watcher non funziona per ogni file system (come NFS), quindi è possibile utilizzare le scansioni pianificate della libreria.", + "MessageScheduleLibraryScanNote": "Per la maggior parte degli utenti, si consiglia di lasciare questa funzione disabilitata e mantenere abilitata l'impostazione “Controlla automaticamente le modifiche nella libreria”: in questo modo verranno rilevate automaticamente le modifiche nelle cartelle della libreria. Abilita questa funzione se “Controlla automaticamente le modifiche nella libreria” non funziona con il tuo file system (come NFS).", "MessageScheduleRunEveryWeekdayAtTime": "Esegui ogni {0} alle {1}", "MessageSearchResultsFor": "cerca risultati per", "MessageSelected": "{0} selezionati", From 2e2d857ce0508852e3d3cf4858c23c3499a8e36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Dobra=C4=8Da?= Date: Sat, 6 Dec 2025 08:16:28 +0100 Subject: [PATCH 12/29] Translated using Weblate (Croatian) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/hr/ --- client/strings/hr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/strings/hr.json b/client/strings/hr.json index f22feb656..eccd12563 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -197,7 +197,7 @@ "HeaderSetBackupSchedule": "Zakazivanje sigurnosne pohrane", "HeaderSettings": "Postavke", "HeaderSettingsDisplay": "Prikaz", - "HeaderSettingsExperimental": "Eksperimentalne funkcije", + "HeaderSettingsExperimental": "Eksperimentalne značajke", "HeaderSettingsGeneral": "Općenito", "HeaderSettingsScanner": "Skener", "HeaderSettingsSecurity": "Sigurnost", @@ -383,7 +383,7 @@ "LabelFolders": "Mape", "LabelFontBold": "Podebljano", "LabelFontBoldness": "Debljina slova", - "LabelFontFamily": "Skupina fontova", + "LabelFontFamily": "Skup pisma", "LabelFontItalic": "Kurziv", "LabelFontScale": "Veličina slova", "LabelFontStrikethrough": "Precrtano", @@ -444,7 +444,7 @@ "LabelListenAgain": "Ponovno poslušaj", "LabelLogLevelDebug": "Debug", "LabelLogLevelInfo": "Info", - "LabelLogLevelWarn": "Warn", + "LabelLogLevelWarn": "Upozorenje", "LabelLookForNewEpisodesAfterDate": "Traži nove nastavke nakon ovog datuma", "LabelLowestPriority": "Najniži prioritet", "LabelMatchConfidence": "Pouzdanost", @@ -452,7 +452,7 @@ "LabelMatchExistingUsersByDescription": "Rabi se za povezivanje postojećih korisnika. Nakon što se spoje, korisnike se prepoznaje temeljem jedinstvene oznake vašeg pružatelja SSO usluga", "LabelMaxEpisodesToDownload": "Najveći broj nastavaka za preuzimanje. 0 za neograničeno.", "LabelMaxEpisodesToDownloadPerCheck": "Najveći broj novih nastavaka za preuzimanje po provjeri", - "LabelMaxEpisodesToKeep": "Najveći broj nastavaka za čuvanje", + "LabelMaxEpisodesToKeep": "Najveći # nastavaka za čuvanje", "LabelMaxEpisodesToKeepHelp": "Ako je vrijednost 0, nema ograničenja broja. Nakon automatskog preuzimanja novog nastavka ova funkcija briše najstariji nastavak ako ih ima više od zadanog broja. Ovo briše samo jedan nastavak po novom preuzetom nastavku.", "LabelMediaPlayer": "Reproduktor medijskih sadržaja", "LabelMediaType": "Vrsta medija", From afb4108c308f6be11fde15fd2a2203434b3c9a73 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 6 Dec 2025 22:31:14 +0100 Subject: [PATCH 13/29] Added translation using Weblate (Greek) --- client/strings/el.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 client/strings/el.json diff --git a/client/strings/el.json b/client/strings/el.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/client/strings/el.json @@ -0,0 +1 @@ +{} From ee6016999560023c1c802a8e2f5194677d25ad41 Mon Sep 17 00:00:00 2001 From: zard Kim Date: Mon, 8 Dec 2025 05:44:44 +0100 Subject: [PATCH 14/29] Translated using Weblate (Korean) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ko/ --- client/strings/ko.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/strings/ko.json b/client/strings/ko.json index a4dea5de4..a2a4dc92a 100644 --- a/client/strings/ko.json +++ b/client/strings/ko.json @@ -57,7 +57,7 @@ "ButtonNextItemInQueue": "대기열의 다음 항목", "ButtonOk": "확인", "ButtonOpenFeed": "피드 열기", - "ButtonOpenManager": "오픈 매니저", + "ButtonOpenManager": "매니저 열기", "ButtonPause": "일시정지", "ButtonPlay": "재생", "ButtonPlayAll": "모두 재생", @@ -301,7 +301,7 @@ "LabelCoverProvider": "커버 제공자", "LabelCreatedAt": "생성일", "LabelCronExpression": "Cron Expression", - "LabelCurrent": "현재재", + "LabelCurrent": "현재", "LabelCurrently": "현재:", "LabelCustomCronExpression": "사용자 정의 Cron 표현식:", "LabelDatetime": "일시", @@ -320,7 +320,7 @@ "LabelDownload": "다운로드", "LabelDownloadNEpisodes": "{0}개 에피소드 다운로드", "LabelDownloadable": "다운로드 가능", - "LabelDuration": "Duration", + "LabelDuration": "기간", "LabelDurationComparisonExactMatch": "(정확히 일치)", "LabelDurationComparisonLonger": "({0} 더 길음)", "LabelDurationComparisonShorter": "({0} 더 짧음)", @@ -436,7 +436,7 @@ "LabelLibraryFilterSublistEmpty": "{0} 없음", "LabelLibraryItem": "라이브러리 항목", "LabelLibraryName": "라이브러리 이름", - "LabelLibrarySortByProgress": "Progress: 마지막 업데이트", + "LabelLibrarySortByProgress": "진행상황: 마지막 업데이트", "LabelLibrarySortByProgressFinished": "진행 상황: 완료", "LabelLibrarySortByProgressStarted": "진행 상황: 시작됨", "LabelLimit": "한계", @@ -606,7 +606,7 @@ "LabelSettingsLibraryMarkAsFinishedWhen": "미디어 항목을 완료된 것으로 표시", "LabelSettingsOnlyShowLaterBooksInContinueSeries": "Continue Series의 이전 책 건너뛰기", "LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "시리즈 계속하기 홈페이지 선반에는 시리즈 중 아직 시작하지 않은 첫 번째 책이 표시됩니다. 시리즈 중 최소 한 권은 완료되었고 진행 중인 책은 없습니다. 이 설정을 활성화하면 시작하지 않은 첫 번째 책 대신 가장 늦게 완료된 책부터 시리즈가 이어집니다.", - "LabelSettingsParseSubtitles": "Parse subtitles", + "LabelSettingsParseSubtitles": "자막 파싱", "LabelSettingsParseSubtitlesHelp": "오디오북 폴더 이름에서 자막을 추출합니다.
자막은 \" - \"로 구분해야 합니다.
즉, \"책 제목 - 여기에 자막이 있습니다\"에는 \"여기에 자막이 있습니다\"라는 자막이 있습니다.", "LabelSettingsPreferMatchedMetadata": "일치하는 메타데이터를 선호", "LabelSettingsPreferMatchedMetadataHelp": "빠른 매칭을 사용하면 매칭된 데이터가 항목 세부 정보보다 우선합니다. 기본적으로 빠른 매칭은 누락된 세부 정보만 채웁니다.", @@ -616,7 +616,7 @@ "LabelSettingsSortingIgnorePrefixesHelp": "즉, 접두사 \"the\"의 경우 책 제목 \"The Book Title\"은 \"Book Title, The\"로 정렬됩니다.", "LabelSettingsSquareBookCovers": "정사각형 책 표지를 사용", "LabelSettingsSquareBookCoversHelp": "표준 1.6:1 책 표지보다 정사각형 표지를 사용하는 것을 선호합니다.", - "LabelSettingsStoreCoversWithItem": "품목과 함께 매장 커버", + "LabelSettingsStoreCoversWithItem": "항목에 있는 커버로 저장", "LabelSettingsStoreCoversWithItemHelp": "기본적으로 표지는 /metadata/items에 저장됩니다. 이 설정을 활성화하면 표지가 라이브러리 항목 폴더에 저장됩니다. \"cover\"라는 이름의 파일 하나만 저장됩니다.", "LabelSettingsStoreMetadataWithItem": "항목과 함께 메타데이터 저장", "LabelSettingsStoreMetadataWithItemHelp": "기본적으로 메타데이터 파일은 /metadata/items에 저장되며 이 설정을 활성화하면 라이브러리 항목 폴더에 메타데이터 파일이 저장됩니다.", @@ -965,11 +965,11 @@ "PlaceholderSearchEpisode": "에피소드 검색..", "StatsAuthorsAdded": "작가가 추가되었습니다", "StatsBooksAdded": "추가된 책", - "StatsBooksAdditional": "추가된 내용은 다음과 같습니다…", + "StatsBooksAdditional": "추가된 내용은 포함…", "StatsBooksFinished": "책 완성", "StatsBooksFinishedThisYear": "올해 읽은 책이 몇 권 있어요…", "StatsBooksListenedTo": "듣는 책", - "StatsCollectionGrewTo": "너의 책 컬렉션이 다음과 같이 늘어났습니다…", + "StatsCollectionGrewTo": "나의 책 컬렉션이 늘어난…", "StatsSessions": "세션", "StatsSpentListening": "보낸 청취시간", "StatsTopAuthor": "인기 작가", From 646c861bcc0e11adf9c0abccc69f76c490885463 Mon Sep 17 00:00:00 2001 From: kfctatertot Date: Mon, 8 Dec 2025 00:33:20 +0100 Subject: [PATCH 15/29] Translated using Weblate (Arabic) Currently translated at 95.9% (1116 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ar/ --- client/strings/ar.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/strings/ar.json b/client/strings/ar.json index e3e13a859..a176b9d8b 100644 --- a/client/strings/ar.json +++ b/client/strings/ar.json @@ -355,7 +355,7 @@ "LabelExample": "مثال", "LabelExpandSeries": "توسيع السلاسل", "LabelExpandSubSeries": "توسيع السلاسل الفرعية", - "LabelExplicit": "صريح", + "LabelExplicit": "محتوى صريح", "LabelExplicitChecked": "صريح (محدد)", "LabelExplicitUnchecked": "غير صريح (غير محدد)", "LabelExportOPML": "تصدير OPML", @@ -374,7 +374,7 @@ "LabelFolders": "مجلدات", "LabelFontBold": "عريض", "LabelFontBoldness": "تعريض الخط", - "LabelFontFamily": "عائلة الخط", + "LabelFontFamily": "عائلة الخطوط", "LabelFontItalic": "مائل", "LabelFontScale": "نطاق الخط", "LabelFontStrikethrough": "يتوسطه خط", @@ -570,7 +570,7 @@ "LabelSettingsBookshelfViewHelp": "تصميم يحاكي الواقع مع رفوف خشبية", "LabelSettingsChromecastSupport": "دعم Chromecast", "LabelSettingsDateFormat": "تنسيق التاريخ", - "LabelSettingsEnableWatcher": "فحص المكتبات تلقائيًا بحثًا عن تغييرات", + "LabelSettingsEnableWatcher": "مراقبة المكتبات تلقائياً بحثاً عن تغييرات", "LabelSettingsEnableWatcherForLibrary": "فحص المكتبة تلقائيًا بحثًا عن تغييرات", "LabelSettingsEnableWatcherHelp": "يمكّن الإضافة/التحديث التلقائي للعناصر عند اكتشاف تغييرات في الملفات. *يتطلب إعادة تشغيل الخادم", "LabelSettingsEpubsAllowScriptedContent": "السماح بالمحتوى النصي في ملفات epub", @@ -861,7 +861,7 @@ "MessageResetChaptersConfirm": "هل أنت متأكد أنك تريد إعادة تعيين الفصول والتراجع عن التغييرات التي أجريتها؟", "MessageRestoreBackupConfirm": "هل أنت متأكد أنك تريد استعادة النسخ الاحتياطي الذي تم إنشاؤه في", "MessageRestoreBackupWarning": "ستؤدي استعادة النسخ الاحتياطي إلى الكتابة فوق قاعدة البيانات بأكملها الموجودة في /config وصور الأغلفة في /metadata/items و /metadata/authors.

لا تعدل النسخ الاحتياطية أي ملفات في مجلدات مكتبتك. إذا قمت بتمكين إعدادات الخادم لتخزين صور الأغلفة والبيانات الوصفية في مجلدات مكتبتك، فلن يتم نسخها احتياطيًا أو الكتابة فوقها.

سيتم تحديث جميع العملاء الذين يستخدمون الخادم الخاص بك تلقائيًا.", - "MessageScheduleLibraryScanNote": "بالنسبة لمعظم المستخدمين، يوصى بترك هذه الميزة معطلة وإبقاء إعداد مراقب المجلدات ممكّنًا. سيكتشف مراقب المجلدات تلقائيًا التغييرات في مجلدات مكتبتك. لا يعمل مراقب المجلدات مع كل نظام ملفات (مثل NFS)، لذا يمكن استخدام عمليات فحص المكتبة المجدولة بدلاً من ذلك.", + "MessageScheduleLibraryScanNote": "لمعظم المستخدمين، موصى بترك هذه الميزة معطلة وإبقاء ممكّنة الأعداد، ”قم بمراقبة المكتبة تلقائاً للتغييرات“. سوف يقم بالكشف التلقائي عن تغييرات في مجلدات مكتبتك. لو لم يعمل الإعداد، \"قم بمراقبة المكتبة تلقائاً للتغييرات،“مع نظمة ملفاتك المستخدمة (مثل NFS على سبيل المثال)، فأمكِن هذه الميزة.", "MessageScheduleRunEveryWeekdayAtTime": "تشغيل كل {0} في الساعة {1}", "MessageSearchResultsFor": "نتائج البحث عن", "MessageSelected": "تم تحديد {0}", From 8bdcabf9731550c242c4d1f5fd1444b099b81a47 Mon Sep 17 00:00:00 2001 From: kfctatertot Date: Mon, 8 Dec 2025 01:27:29 +0100 Subject: [PATCH 16/29] Translated using Weblate (Spanish) Currently translated at 96.8% (1126 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/strings/es.json b/client/strings/es.json index 53bfad693..3f0ff806b 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -242,6 +242,10 @@ "LabelAllUsersExcludingGuests": "Todos los usuarios excepto invitados", "LabelAllUsersIncludingGuests": "Todos los usuarios e invitados", "LabelAlreadyInYourLibrary": "Ya existe en la Biblioteca", + "LabelApiKeyCreated": "La clave de API “{0}” se ha creado con éxito.", + "LabelApiKeyCreatedDescription": "Asegúrate de copiar la clave de API ahora, no la volverás a ver otra vez.", + "LabelApiKeyUser": "Actuar en nombre del usuario", + "LabelApiKeyUserDescription": "Esta clave de API tendrá los mismos permisos que el usuario al que representa. En los registros se verá como si la solicitud la hubiera hecho el usuario directamente.", "LabelApiToken": "Token de la API", "LabelAppend": "Adjuntar", "LabelAudioBitrate": "Tasa de bits del audio (por ejemplo, 128k)", @@ -291,6 +295,7 @@ "LabelContinueListening": "Seguir escuchando", "LabelContinueReading": "Continuar leyendo", "LabelContinueSeries": "Continuar series", + "LabelCorsAllowed": "Orígenes CORS Permitidos", "LabelCover": "Cubierta", "LabelCoverImageURL": "URL de imagen de cubierta", "LabelCoverProvider": "Proveedor de cubiertas", @@ -524,7 +529,7 @@ "LabelPublishers": "Editores", "LabelRSSFeedCustomOwnerEmail": "Correo electrónico de dueño personalizado", "LabelRSSFeedCustomOwnerName": "Nombre de dueño personalizado", - "LabelRSSFeedOpen": "Suministro RSS abierto", + "LabelRSSFeedOpen": "Fuente RSS Abierta", "LabelRSSFeedPreventIndexing": "Evitar indización", "LabelRSSFeedSlug": "«Slug» de suministro RSS", "LabelRSSFeedURL": "URL de suministro RSS", From f7d7c9a4f571fd69afab05db3a55f60ccb85ce26 Mon Sep 17 00:00:00 2001 From: A L Date: Mon, 8 Dec 2025 13:03:30 +0100 Subject: [PATCH 17/29] Translated using Weblate (Bulgarian) Currently translated at 88.2% (1026 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/bg/ --- client/strings/bg.json | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/client/strings/bg.json b/client/strings/bg.json index ca14035f8..dacd62087 100644 --- a/client/strings/bg.json +++ b/client/strings/bg.json @@ -378,6 +378,7 @@ "LabelFilterByUser": "Филтриране по Потребител", "LabelFindEpisodes": "Намери Епизоди", "LabelFinished": "Дата на приключване", + "LabelFinishedDate": "Приключено на {0}", "LabelFolder": "Папка", "LabelFolders": "Папки", "LabelFontBold": "Получерно", @@ -435,7 +436,9 @@ "LabelLibraryFilterSublistEmpty": "Не {0}", "LabelLibraryItem": "Елемент на Библиотека", "LabelLibraryName": "Име на Библиотека", - "LabelLibrarySortByProgress": "Прогресът е обновен", + "LabelLibrarySortByProgress": "Прогрес: Последно Обновен", + "LabelLibrarySortByProgressFinished": "Прогрес: Приключено", + "LabelLibrarySortByProgressStarted": "Прогрес: Започнато", "LabelLimit": "Лимит", "LabelLineSpacing": "Междуредие", "LabelListenAgain": "Слушай отново", @@ -585,8 +588,8 @@ "LabelSettingsBookshelfViewHelp": "Скеуморфен дизайн с дървени рафтове", "LabelSettingsChromecastSupport": "Chromecast поддръжка", "LabelSettingsDateFormat": "Формат на Дата", - "LabelSettingsEnableWatcher": "Автоматично сканиране на библиотеките за промени", - "LabelSettingsEnableWatcherForLibrary": "Автоматично сканиране на библиотеката за промени", + "LabelSettingsEnableWatcher": "Автоматично преглеждане на библиотеките за промени", + "LabelSettingsEnableWatcherForLibrary": "Автоматично преглеждане на библиотеката за промени", "LabelSettingsEnableWatcherHelp": "Включва автоматичното добавяне/обновяване на елементи, когато се открият промени във файловете. *Изисква рестарт на сървъра", "LabelSettingsEpubsAllowScriptedContent": "Позволи скриптово съдържание в epub-и", "LabelSettingsEpubsAllowScriptedContentHelp": "Позволи epub файловете да изпълняват скриптове. Препоръчително е да бъде изключено освен ако не се доверявате на източника на epub файловете.", @@ -635,6 +638,7 @@ "LabelStartTime": "Начално Време", "LabelStarted": "Стартирано", "LabelStartedAt": "Стартирано на", + "LabelStartedDate": "Започнато {0}", "LabelStatsAudioTracks": "Аудио Канали", "LabelStatsAuthors": "Автори", "LabelStatsBestDay": "Най-добър ден", @@ -780,6 +784,7 @@ "MessageConfirmPurgeCache": "Изчистването на кеша ще изтрие цялата директория в /metadata/cache.

Сигурни ли сте, че искате да премахнете директорията на кеша?", "MessageConfirmPurgeItemsCache": "Изчистването на кеша на елементите ще изтрие цялата директория в /metadata/cache/items.
Сигурни ли сте?", "MessageConfirmQuickEmbed": "Внимание! Бързото вграждане няма да архивира вашите аудио файлове. Уверете се, че имате резервно копие на вашите аудио файлове.

Искате ли да продължите?", + "MessageConfirmQuickMatchEpisodes": "Бързото сравняване на епизоди ще презапише детайлите, ако се намери съвпадение. Само не съвпаднали епизоди ще бъдат обновени. Сигурни ли сте?", "MessageConfirmReScanLibraryItems": "Сигурни ли сте, че искате да сканирате отново {0} елемента?", "MessageConfirmRemoveAllChapters": "Сигурни ли сте, че искате да премахнете всички глави?", "MessageConfirmRemoveAuthor": "Сигурни ли сте, че искате да премахнете автор \"{0}\"?", @@ -788,6 +793,7 @@ "MessageConfirmRemoveEpisodeNote": "Забележка: Това няма да доведе до изтриване на аудио файла, освен ако не активирате опцията \"Твърдо изтриване на файла\"", "MessageConfirmRemoveEpisodes": "Сигурни ли сте, че искате да премахнете {0} епизода?", "MessageConfirmRemoveListeningSessions": "Сигурни ли сте, че искате да премахнете {0} слушателски сесии?", + "MessageConfirmRemoveMetadataFiles": "Сигурни ли сте, че искате да премахнете всичките метаданни. {0} файлове във папките на Вашата библиотека?", "MessageConfirmRemoveNarrator": "Сигурни ли сте, че искате да премахнете разказвач \"{0}\"?", "MessageConfirmRemovePlaylist": "Сигурни ли сте, че искате да премахнете плейлиста \"{0}\"?", "MessageConfirmRenameGenre": "Сигурни ли сте, че искате да преименувате жанра \"{0}\" на \"{1}\" за всички елементи?", @@ -862,6 +868,7 @@ "MessageNoUserPlaylists": "Нямате създадени плейлисти", "MessageNoUserPlaylistsHelp": "Плейлистите за частни. Само създалият ги потребител ще може да ги вижда.", "MessageNotYetImplemented": "Още не е изпълнено", + "MessageOpmlPreviewNote": "Забележка: Това е преглед на анализирания OPML файл. Действителното заглавие на подкаста ще бъде взето от RSS фийда.", "MessageOr": "или", "MessagePauseChapter": "Пауза на глава", "MessagePlayChapter": "Пусни налчалото на глава", @@ -871,6 +878,7 @@ "MessagePodcastSearchField": "Въведи какво да търся или RSS емисия адрес", "MessageQuickEmbedInProgress": "Бързото вграждане е в процес на изпълнение", "MessageQuickEmbedQueue": "Поставено в опашката за бързо вграждане ({0} в опашката)", + "MessageQuickMatchAllEpisodes": "Бързо Сравняване на Всички Епизоди", "MessageQuickMatchDescription": "Попълни празните детайли и корици с първия резултат от '{0}'. Не презаписва детайлите, освен ако не е активирана настройката 'Предпочети съвпадащи метаданни' на сървъра.", "MessageRemoveChapter": "Премахни глава", "MessageRemoveEpisodes": "Премахни {0} епизод(и)", @@ -880,16 +888,23 @@ "MessageResetChaptersConfirm": "Сигурни ли сте, че искате да нулирате главите и да отмените промените, които сте направили?", "MessageRestoreBackupConfirm": "Сигурни ли сте, че искате да възстановите архива създаден на", "MessageRestoreBackupWarning": "Възстановяването на архив ще презапише цялата база данни, намираща се в /config и кориците в /metadata/items & /metadata/authors.

Архивите не променят файловете в папките на вашата библиотека. Ако сте активирали настройките на сървъра за съхранение на корици и метаданни в папките на вашата библиотека, те няма да бъдат архивирани или презаписани.

Всички клиенти, използващи вашия сървър, ще бъдат автоматично обновени.", + "MessageScheduleLibraryScanNote": "За повече потребители се препоръчва да оставят този фийчър изключен и да оставят настройката \"Автоматично преглеждане за промени в библиотеката\" включена - тя автоматично ще засече промени в папките на вашата библиотека. Включете тази настройка ако \"Автоматично преглеждане за промени в библиотеката\" не рабови на вашата файлова система (например NFS).", "MessageScheduleRunEveryWeekdayAtTime": "Изпълни всеки {0} в {1}", "MessageSearchResultsFor": "Резултати от търсенето за", "MessageSelected": "{0} избрани", + "MessageSeriesSequenceCannotContainSpaces": "Подредбата в серия не може да съдържа шпации.", "MessageServerCouldNotBeReached": "Сървърът не може да бъде достигнат", "MessageSetChaptersFromTracksDescription": "Задайте глави, като използвате всеки аудио файл като глава и заглавие на главата като име на аудио файла", + "MessageShareExpirationWillBe": "Изтичането ще бъде на {0}", "MessageShareExpiresIn": "Изтича след {0}", + "MessageShareURLWillBe": "URL за споделяне ще бъде {0}", "MessageStartPlaybackAtTime": "Започни възпроизвеждане на \"{0}\" в {1}?", + "MessageTaskAudioFileNotWritable": "На Аудио файл \"{0}\" не може да се записва", + "MessageTaskCanceledByUser": "Задачата е отказана от потребител", "MessageTaskDownloadingEpisodeDescription": "Изтегляне на епизод \"{0}\"", "MessageTaskEmbeddingMetadata": "Вграждане на метаданни", "MessageTaskEmbeddingMetadataDescription": "Вграждане на метаданни в аудиокнига \"{0}\"", + "MessageTaskEncodingM4b": "Кодиране M4B", "MessageTaskEncodingM4bDescription": "Кодиране на аудиокнига \"{0}\" в единичен m4b файл", "MessageTaskFailed": "Неуспешно", "MessageTaskFailedToBackupAudioFile": "Неуспешно създаване на разервно копие на аудио файл \"{0}\"", @@ -902,7 +917,9 @@ "MessageTaskNoFilesToScan": "Няма файлове за сканиране", "MessageTaskOpmlImport": "OPML импортиране", "MessageTaskOpmlImportDescription": "Създаване на подкасти от {0} RSS хранилки", + "MessageTaskOpmlImportFeed": "OPML импортиран фийд", "MessageTaskOpmlImportFeedDescription": "Импортиране на RSS хранилка \"{0}\"", + "MessageTaskOpmlImportFeedFailed": "Неуспешно взимане на подкаст фийд", "MessageTaskOpmlImportFeedPodcastDescription": "Създаване на подкаст \"{0}\"", "MessageTaskOpmlImportFeedPodcastExists": "На този път вече съществува подкаст", "MessageTaskOpmlImportFeedPodcastFailed": "Неуспешно създаване на подкаст", @@ -938,6 +955,7 @@ "NotificationOnBackupFailedDescription": "Изпълнява се при неуспешено създаване на резервно копие", "NotificationOnEpisodeDownloadedDescription": "Изпълнява се при автоматично изтегляне на подкаст епизод", "NotificationOnRSSFeedDisabledDescription": "Изпълнява се, когато автоматичното изтегляне на епизодите е деактивирано, поради твърде много неуспешни опити", + "NotificationOnRSSFeedFailedDescription": "Пуска се когато заявката за RSS фийд е неуспешна за автоматично сваляне на епизод", "PlaceholderNewCollection": "Ново име на колекцията", "PlaceholderNewFolderPath": "Нов път на папката", "PlaceholderNewPlaylist": "Ново име на плейлиста", From 092c504eb1db754eed758f48ad3a6c85d484fba1 Mon Sep 17 00:00:00 2001 From: Alberto Coronado Date: Thu, 11 Dec 2025 05:30:19 +0100 Subject: [PATCH 18/29] Translated using Weblate (Spanish) Currently translated at 97.5% (1134 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/strings/es.json b/client/strings/es.json index 3f0ff806b..4a611b3de 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -359,6 +359,10 @@ "LabelExample": "Ejemplo", "LabelExpandSeries": "Ampliar serie", "LabelExpandSubSeries": "Expandir la subserie", + "LabelExpired": "Expirado", + "LabelExpiresAt": "Expira El", + "LabelExpiresInSeconds": "Expira en (segundos)", + "LabelExpiresNever": "Nunca", "LabelExplicit": "Explícito", "LabelExplicitChecked": "Explícito (marcado)", "LabelExplicitUnchecked": "No Explícito (sin marcar)", @@ -773,6 +777,7 @@ "MessageConfirmRemoveAuthor": "¿Confirma que quiere quitar el autor «{0}»?", "MessageConfirmRemoveCollection": "¿Confirma que quiere quitar la colección «{0}»?", "MessageConfirmRemoveEpisode": "¿Confirma que quiere quitar el episodio «{0}»?", + "MessageConfirmRemoveEpisodeNote": "Nota: Esto no borra el archivo de audio a menos que se active la opción \"Borrado definitivo del archivo\"", "MessageConfirmRemoveEpisodes": "¿Confirma que quiere quitar {0} episodios?", "MessageConfirmRemoveListeningSessions": "¿Confirma que quiere quitar {0} sesiones de escucha?", "MessageConfirmRemoveMetadataFiles": "¿Confirma que quiere quitar todos los archivos metadata.{0} en las carpetas de elementos de su biblioteca?", @@ -934,6 +939,8 @@ "NotificationOnBackupCompletedDescription": "Se activa cuando se completa una copia de seguridad", "NotificationOnBackupFailedDescription": "Se activa cuando falla una copia de seguridad", "NotificationOnEpisodeDownloadedDescription": "Se activa cuando se descarga automáticamente un episodio de un podcast", + "NotificationOnRSSFeedDisabledDescription": "Se activa cuando las descargas automáticas de episodios se desactivan debido a varios intentos fallidos", + "NotificationOnRSSFeedFailedDescription": "Se activa cuando la solicitud a la fuente RSS falla durante una descarga automática de episodio", "NotificationOnTestDescription": "Evento para probar el sistema de notificaciones", "PlaceholderBulkChapterInput": "Ingrese título de capítulo o use numeración (ej. 'Episodio 1', 'Capítulo 10', '1.')", "PlaceholderNewCollection": "Nuevo nombre de la colección", @@ -1072,6 +1079,7 @@ "ToastPlaylistUpdateSuccess": "Lista de reproducción actualizada", "ToastPodcastCreateFailed": "No se pudo crear el pódcast", "ToastPodcastCreateSuccess": "Se creó el pódcast correctamente", + "ToastPodcastEpisodeUpdated": "Episodio actualizado", "ToastPodcastGetFeedFailed": "No se puede obtener el podcast", "ToastPodcastNoEpisodesInFeed": "No se han encontrado episodios en el feed del RSS", "ToastPodcastNoRssFeed": "El pódcast no tiene suministro RSS", From 70e6efc3d0b6babd2f6086347a0ea6b1724b4c4b Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 10 Dec 2025 12:21:51 +0100 Subject: [PATCH 19/29] Translated using Weblate (German) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/de.json b/client/strings/de.json index 8398a7211..970c94233 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -13,7 +13,7 @@ "ButtonBack": "Zurück", "ButtonBatchEditPopulateFromExisting": "Auffüllen aus vorhandenem", "ButtonBatchEditPopulateMapDetails": "Kartendetails auffüllen", - "ButtonBrowseForFolder": "Ordnersuche", + "ButtonBrowseForFolder": "Ordner auswählen", "ButtonCancel": "Abbrechen", "ButtonCancelEncode": "Konvertierung abbrechen", "ButtonChangeRootPassword": "Hauptpasswort ändern", From c1e21d31ee0c99414b4173b3d6a8fd817668247a Mon Sep 17 00:00:00 2001 From: lambolighting Date: Thu, 11 Dec 2025 14:19:06 +0100 Subject: [PATCH 20/29] Translated using Weblate (Greek) Currently translated at 1.1% (13 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/el/ --- client/strings/el.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client/strings/el.json b/client/strings/el.json index 0967ef424..2527e1988 100644 --- a/client/strings/el.json +++ b/client/strings/el.json @@ -1 +1,15 @@ -{} +{ + "ButtonAdd": "Προσθήκη", + "ButtonAuthors": "Συγγραφείς", + "ButtonBack": "Πίσω", + "ButtonCancel": "Ακύρωση", + "ButtonClearFilter": "Διαγραφή Φίλτρου", + "ButtonCloseFeed": "Κλείσιμο Τροφοδοσίας", + "ButtonCollections": "Συλλογές", + "ButtonCreate": "Δημιουργία", + "ButtonDelete": "Διαγραφή", + "ButtonHome": "Αρχική", + "ButtonIssues": "Θέματα", + "ButtonLatest": "Τελευταία", + "ButtonLibrary": "Βιβλιοθήκη" +} From dc2398a07284c3e075764ceac58eecc4c85d391b Mon Sep 17 00:00:00 2001 From: Lucas Jaksys Date: Fri, 12 Dec 2025 17:53:33 +0100 Subject: [PATCH 21/29] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/pt_BR/ --- client/strings/pt-br.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/pt-br.json b/client/strings/pt-br.json index 9c8754c44..c6c9781cf 100644 --- a/client/strings/pt-br.json +++ b/client/strings/pt-br.json @@ -383,7 +383,7 @@ "LabelFolders": "Pastas", "LabelFontBold": "Negrito", "LabelFontBoldness": "Intensidade do negrito", - "LabelFontFamily": "Família de fonte", + "LabelFontFamily": "Família de fontes", "LabelFontItalic": "Itálico", "LabelFontScale": "Escala de fonte", "LabelFontStrikethrough": "Tachado", From 0ecbb1c3f448748a5c63cd4bc917f284abfc6d25 Mon Sep 17 00:00:00 2001 From: MODI NAVON Date: Fri, 12 Dec 2025 10:09:19 +0100 Subject: [PATCH 22/29] Translated using Weblate (Hebrew) Currently translated at 73.0% (850 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/he/ --- client/strings/he.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/strings/he.json b/client/strings/he.json index 9525ca6cd..0efc1ec9c 100644 --- a/client/strings/he.json +++ b/client/strings/he.json @@ -126,6 +126,7 @@ "HeaderAudiobookTools": "כלים לניהול קבצי ספרים קוליים", "HeaderAuthentication": "אימות", "HeaderBackups": "גיבויים", + "HeaderBulkChapterModal": "הוסף מספר פרקים", "HeaderChangePassword": "שנה סיסמה", "HeaderChapters": "פרקים", "HeaderChooseAFolder": "בחר תיקייה", @@ -197,6 +198,7 @@ "HeaderSettingsExperimental": "תכונות ניסיוניות", "HeaderSettingsGeneral": "כללי", "HeaderSettingsScanner": "סורק", + "HeaderSettingsSecurity": "אבטחה", "HeaderSettingsWebClient": "מערך", "HeaderSleepTimer": "טיימר שינה", "HeaderStatsLargestItems": "הפריטים הגדולים ביותר", @@ -237,6 +239,7 @@ "LabelAllUsersExcludingGuests": "כל המשתמשים, ללא אורחים", "LabelAllUsersIncludingGuests": "כל המשתמשים כולל אורחים", "LabelAlreadyInYourLibrary": "כבר קיים בספרייה שלך", + "LabelApiKeyUser": "פעל בשם המשתמש", "LabelApiToken": "טוקן API", "LabelAppend": "הוסף לסוף", "LabelAudioBitrate": "קצב סיביות (לדוגמא 128k)", From 10a4777ddf4e51945a425a5f57a3c0cfc362512a Mon Sep 17 00:00:00 2001 From: lambolighting Date: Sat, 13 Dec 2025 11:01:47 +0100 Subject: [PATCH 23/29] Translated using Weblate (Greek) Currently translated at 9.0% (105 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/el/ --- client/strings/el.json | 94 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/client/strings/el.json b/client/strings/el.json index 2527e1988..9d12d3096 100644 --- a/client/strings/el.json +++ b/client/strings/el.json @@ -1,15 +1,107 @@ { "ButtonAdd": "Προσθήκη", + "ButtonAddApiKey": "Προσθήκη Κλειδιού API", + "ButtonAddChapters": "Προσθήκη Κεφαλαίων", + "ButtonAddDevice": "Προσθήκη Συσκευής", + "ButtonAddLibrary": "Προσθήκη Βιβλιοθήκης", + "ButtonAddPodcasts": "Προσθήκη Podcasts", + "ButtonAddUser": "Προσθήκη Χρήστη", + "ButtonAddYourFirstLibrary": "Πρόσθεσε την πρώτη σου βιβλιοθήκη", + "ButtonApply": "Εφαρμογή", + "ButtonApplyChapters": "Εφαρμογή Κεφαλαίων", "ButtonAuthors": "Συγγραφείς", "ButtonBack": "Πίσω", + "ButtonBatchEditPopulateFromExisting": "Συμπλήρωση από υπάρχοντα", + "ButtonBatchEditPopulateMapDetails": "Συμπλήρωση λεπτομερειών χάρτη", + "ButtonBrowseForFolder": "Περιήγηση για Φάκελο", "ButtonCancel": "Ακύρωση", + "ButtonCancelEncode": "Ακύρωση Κωδικοποίησης", + "ButtonChangeRootPassword": "Αλλαγή Κωδικού Πρόσβασης Root", + "ButtonCheckAndDownloadNewEpisodes": "Έλεγχος και Κατέβασμα Νέων Επεισοδίων", + "ButtonChooseAFolder": "Επιλογή φακέλου", + "ButtonChooseFiles": "Επιλογή αρχείων", "ButtonClearFilter": "Διαγραφή Φίλτρου", + "ButtonClose": "Κλείσιμο", "ButtonCloseFeed": "Κλείσιμο Τροφοδοσίας", + "ButtonCloseSession": "Κλείσιμο Ανοιχτής Συνεδρίας", "ButtonCollections": "Συλλογές", + "ButtonConfigureScanner": "Ρύθμιση Παραμέτρων Σαρωτή", "ButtonCreate": "Δημιουργία", + "ButtonCreateBackup": "Δημιουργία Αντιγράφου Ασφαλείας", "ButtonDelete": "Διαγραφή", + "ButtonDownloadQueue": "Ουρά", + "ButtonEdit": "Επεξεργασία", + "ButtonEditChapters": "Επεξεργασία Κεφαλαίων", + "ButtonEditPodcast": "Επεξεργασία Podcast", + "ButtonEnable": "Ενεργοποίηση", + "ButtonForceReScan": "Αναγκαστική Επανάληψη Σάρωσης", + "ButtonFullPath": "Πλήρης Διαδρομή", + "ButtonHide": "Απόκρυψη", "ButtonHome": "Αρχική", "ButtonIssues": "Θέματα", + "ButtonJumpBackward": "Μεταπήδηση Πίσω", + "ButtonJumpForward": "Μεταπήδηση Μπροστά", "ButtonLatest": "Τελευταία", - "ButtonLibrary": "Βιβλιοθήκη" + "ButtonLibrary": "Βιβλιοθήκη", + "ButtonLogout": "Αποσύνδεση", + "ButtonLookup": "Εύρεση", + "ButtonManageTracks": "Διαχείριση Κομματιών", + "ButtonMapChapterTitles": "Χαρτογράφηση Τίτλων Κεφαλαίων", + "ButtonMatchAllAuthors": "Αντιστοίχιση Όλων των Συγγραφέων", + "ButtonMatchBooks": "Αντιστοίχιση Βιβλίων", + "ButtonNext": "Επόμενο", + "ButtonNextChapter": "Επόμενο Κεφάλαιο", + "ButtonNextItemInQueue": "Επόμενο Αντικείμενο στην Ουρά", + "ButtonOk": "Εντάξει", + "ButtonOpenFeed": "Άνοιγμα Τροφοδοσίας", + "ButtonOpenManager": "Άνοιγμα Διαχειριστή", + "ButtonPause": "Παύση", + "ButtonPlay": "Αναπαραγωγή", + "ButtonPlayAll": "Αναπαραγωγή Όλων", + "ButtonPlaying": "Αναπαράγεται", + "ButtonPlaylists": "Λίστες Αναπαραγωγής", + "ButtonPrevious": "Προηγούμενο", + "ButtonPreviousChapter": "Προηγούμενο Κεφάλαιο", + "ButtonQueueAddItem": "Προσθήκη στην ουρά", + "ButtonQueueRemoveItem": "Αφαίρεση απ'την ουρά", + "ButtonQuickMatch": "Γρήγορη Αντιστοίχηση", + "ButtonReScan": "Επανασάρωση", + "ButtonRead": "Ανάγνωση", + "ButtonReadLess": "Ανάγνωση λιγότερων", + "ButtonReadMore": "Διάβασε περισσότερα", + "ButtonRefresh": "Ανανέωση", + "ButtonRemove": "Αφαίρεση", + "ButtonRemoveAll": "Αφαίρεση Όλων", + "ButtonRemoveAllLibraryItems": "Αφαίρεση Όλων των Αντικειμέων Βιβλιοθήκης", + "ButtonReset": "Επαναφορά", + "ButtonResetToDefault": "Επαναφορά στις προεπιλογές", + "ButtonRestore": "Επαναφορά", + "ButtonSave": "Αποθήκευση", + "ButtonSaveAndClose": "Αποθήκευση και Κλείσιμο", + "ButtonScan": "Σάρψση", + "ButtonSearch": "Αναζήτηση", + "ButtonSeries": "Σειρά", + "ButtonSubmit": "Υποβολή", + "ButtonYes": "Ναι", + "HeaderAccount": "Λογαριασμός", + "HeaderAdvanced": "Για Προχωρημένους", + "HeaderAudioTracks": "Κομμάτια Ήχου", + "HeaderChapters": "Κεφάλαια", + "HeaderCollection": "Συλλογή", + "HeaderCollectionItems": "Αντικείμενα Συλλογής", + "HeaderDetails": "Λεπτομέρειες", + "HeaderEbookFiles": "Αρχεία Ebook", + "HeaderEpisodes": "Επεισόδια", + "HeaderEreaderSettings": "Ρυθμίσεις Ereader", + "HeaderLatestEpisodes": "Τελευταία Επεισόδια", + "HeaderLibraries": "Βιβλιοθήκες", + "HeaderOpenRSSFeed": "Άνοιγμα Τροφοδοσίας RSS", + "HeaderPlaylist": "Λίστα Αναπαραγωγής", + "HeaderPlaylistItems": "Αντικείμενα Λίστας Αναπαραγωγής", + "HeaderRSSFeedGeneral": "Λεπτομέρειες RSS", + "HeaderRSSFeedIsOpen": "Η Τροφοδοσία RSS είναι Ανοιχτή", + "HeaderSettings": "Ρυθμίσεις", + "HeaderStatsMinutesListeningChart": "Λεπτά Ακρόασης (τελευταίες 7 ημέρες)", + "HeaderStatsRecentSessions": "Πρόσφατες Συνεδρίες", + "HeaderTableOfContents": "Πίνακας Περιεχομένων" } From 076ece6fe748fa4b0b44ea3c8e89cb940333781f Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 21 Dec 2025 14:45:04 -0600 Subject: [PATCH 24/29] Auto-formatting --- server/scanner/Scanner.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index cf5c87b78..af4405987 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -260,16 +260,16 @@ class Scanner { // Update filter data Database.addAuthorToFilterData(libraryItem.libraryId, author.name, author.id) } - await Database.bookAuthorModel - .create({ - authorId: author.id, - bookId: libraryItem.media.id - }) - .then(() => { - Logger.info(`[Scanner] quickMatchBookBuildUpdatePayload: Added author "${author.name}" to "${libraryItem.media.title}"`) - libraryItem.media.authors.push(author) - hasAuthorUpdates = true - }) + await Database.bookAuthorModel + .create({ + authorId: author.id, + bookId: libraryItem.media.id + }) + .then(() => { + Logger.info(`[Scanner] quickMatchBookBuildUpdatePayload: Added author "${author.name}" to "${libraryItem.media.title}"`) + libraryItem.media.authors.push(author) + hasAuthorUpdates = true + }) } const authorsRemoved = libraryItem.media.authors.filter((a) => !matchData.author.find((ma) => ma.toLowerCase() === a.name.toLowerCase())) if (authorsRemoved.length) { From 7b37c98e88309f67b467fea5fcf71e4736984a0d Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 21 Dec 2025 15:38:34 -0600 Subject: [PATCH 25/29] Book tags genres dedupe (#4927) * Update Audible provider dedupe genres/tags and return tags as array * Update custom metadata provider to dedupe tags/genres and return tags as array --- server/providers/Audible.js | 13 ++++++++---- server/providers/CustomProviderAdapter.js | 25 +++++++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/server/providers/Audible.js b/server/providers/Audible.js index 2c12ffc1a..6ba01aa83 100644 --- a/server/providers/Audible.js +++ b/server/providers/Audible.js @@ -57,8 +57,13 @@ class Audible { }) } - const genresFiltered = genres ? genres.filter((g) => g.type == 'genre').map((g) => g.name) : [] - const tagsFiltered = genres ? genres.filter((g) => g.type == 'tag').map((g) => g.name) : [] + let genresCleaned = null + let tagsCleaned = null + + if (genres && Array.isArray(genres)) { + genresCleaned = [...new Set(genres.filter((g) => g.type == 'genre').map((g) => g.name))] + tagsCleaned = [...new Set(genres.filter((g) => g.type == 'tag').map((g) => g.name))] + } return { title, @@ -71,8 +76,8 @@ class Audible { cover: image, asin, isbn, - genres: genresFiltered.length ? genresFiltered : null, - tags: tagsFiltered.length ? tagsFiltered.join(', ') : null, + genres: genresCleaned.length ? genresCleaned : null, + tags: tagsCleaned.length ? tagsCleaned : null, series: series.length ? series : null, language: language ? language.charAt(0).toUpperCase() + language.slice(1) : null, duration: runtimeLengthMin && !isNaN(runtimeLengthMin) ? Number(runtimeLengthMin) : 0, diff --git a/server/providers/CustomProviderAdapter.js b/server/providers/CustomProviderAdapter.js index c079a1280..5c8cad75a 100644 --- a/server/providers/CustomProviderAdapter.js +++ b/server/providers/CustomProviderAdapter.js @@ -89,6 +89,27 @@ class CustomProviderAdapter { }) .filter((s) => s !== undefined) } + /** + * Validates and dedupes tags/genres array + * Can be comma separated string or array of strings + * @param {string|string[]} tagsGenres + * @returns {string[]} + */ + const validateTagsGenresArray = (tagsGenres) => { + if (!tagsGenres || (typeof tagsGenres !== 'string' && !Array.isArray(tagsGenres))) return undefined + + // If string, split by comma and trim each item + if (typeof tagsGenres === 'string') tagsGenres = tagsGenres.split(',') + // If array, ensure all items are strings + else if (!tagsGenres.every((t) => typeof t === 'string')) return undefined + + // Trim and filter out empty strings + tagsGenres = tagsGenres.map((t) => t.trim()).filter(Boolean) + if (!tagsGenres.length) return undefined + + // Dedup + return [...new Set(tagsGenres)] + } // re-map keys to throw out return matches.map((match) => { @@ -105,8 +126,8 @@ class CustomProviderAdapter { cover: toStringOrUndefined(cover), isbn: toStringOrUndefined(isbn), asin: toStringOrUndefined(asin), - genres: Array.isArray(genres) && genres.every((g) => typeof g === 'string') ? genres : undefined, - tags: toStringOrUndefined(tags), + genres: validateTagsGenresArray(genres), + tags: validateTagsGenresArray(tags), series: validateSeriesArray(series), language: toStringOrUndefined(language), duration: !isNaN(duration) && duration !== null ? Number(duration) : undefined From 3c2eec8279d82185cd858bd0a856b865160e2099 Mon Sep 17 00:00:00 2001 From: FiendFEARing Date: Wed, 17 Dec 2025 01:55:49 +0100 Subject: [PATCH 26/29] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1163 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/zh_Hans/ --- client/strings/zh-cn.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index 1a95256ab..64c41619e 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -275,7 +275,7 @@ "LabelBonus": "额外", "LabelBooks": "图书", "LabelButtonText": "按钮文本", - "LabelByAuthor": "由 {0}", + "LabelByAuthor": "作者: {0}", "LabelChangePassword": "修改密码", "LabelChannels": "声道", "LabelChapterCount": "{0} 章节", From ac08e897ee93cd2457d13716d10be94e5d0b0535 Mon Sep 17 00:00:00 2001 From: Ahetek Date: Mon, 15 Dec 2025 21:54:40 +0100 Subject: [PATCH 27/29] Translated using Weblate (Polish) Currently translated at 89.2% (1038 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/pl/ --- client/strings/pl.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/strings/pl.json b/client/strings/pl.json index 316e84234..32c9766ca 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -233,8 +233,8 @@ "LabelAddToCollectionBatch": "Dodaj {0} książki do kolekcji", "LabelAddToPlaylist": "Dodaj do playlisty", "LabelAddToPlaylistBatch": "Dodaj {0} pozycji do playlisty", - "LabelAddedAt": "Dodano w", - "LabelAddedDate": "Dodano", + "LabelAddedAt": "Dodano", + "LabelAddedDate": "Dodano {0}", "LabelAdminUsersOnly": "Tylko użytkownicy administracyjni", "LabelAll": "Wszystkie", "LabelAllEpisodesDownloaded": "Wszystkie odcinki pobrane", From cc48d9f26dc3dc0c2b096b9ba892c501609bfbd9 Mon Sep 17 00:00:00 2001 From: lambolighting Date: Fri, 19 Dec 2025 11:21:03 +0100 Subject: [PATCH 28/29] Translated using Weblate (Greek) Currently translated at 26.9% (313 of 1163 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/el/ --- client/strings/el.json | 210 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 1 deletion(-) diff --git a/client/strings/el.json b/client/strings/el.json index 9d12d3096..881bd971b 100644 --- a/client/strings/el.json +++ b/client/strings/el.json @@ -49,6 +49,7 @@ "ButtonMapChapterTitles": "Χαρτογράφηση Τίτλων Κεφαλαίων", "ButtonMatchAllAuthors": "Αντιστοίχιση Όλων των Συγγραφέων", "ButtonMatchBooks": "Αντιστοίχιση Βιβλίων", + "ButtonNevermind": "Άστο", "ButtonNext": "Επόμενο", "ButtonNextChapter": "Επόμενο Κεφάλαιο", "ButtonNextItemInQueue": "Επόμενο Αντικείμενο στην Ουρά", @@ -62,8 +63,13 @@ "ButtonPlaylists": "Λίστες Αναπαραγωγής", "ButtonPrevious": "Προηγούμενο", "ButtonPreviousChapter": "Προηγούμενο Κεφάλαιο", + "ButtonProbeAudioFile": "Ανάλυση Αρχείου Ήχου", + "ButtonPurgeAllCache": "Εκκαθάριση Όλης της Προσωρινής Μνήμης", + "ButtonPurgeItemsCache": "Εκκαθάριση της Μνήμης Αντικειμένων", "ButtonQueueAddItem": "Προσθήκη στην ουρά", "ButtonQueueRemoveItem": "Αφαίρεση απ'την ουρά", + "ButtonQuickEmbed": "Γρήγορη Ενσωμάτωση", + "ButtonQuickEmbedMetadata": "Γρήγορη Ενσωμάτωση Μεταδεδομένων", "ButtonQuickMatch": "Γρήγορη Αντιστοίχηση", "ButtonReScan": "Επανασάρωση", "ButtonRead": "Ανάγνωση", @@ -73,35 +79,237 @@ "ButtonRemove": "Αφαίρεση", "ButtonRemoveAll": "Αφαίρεση Όλων", "ButtonRemoveAllLibraryItems": "Αφαίρεση Όλων των Αντικειμέων Βιβλιοθήκης", + "ButtonRemoveFromContinueListening": "Αφαίρεση από τη Συνέχεια Ακρόασης", + "ButtonRemoveFromContinueReading": "Αφαίρεση από τη Συνέχεια Ανάγνωσης", + "ButtonRemoveSeriesFromContinueSeries": "Αφαίρεση Σειράς από τη Συνέχεια Σειράς", "ButtonReset": "Επαναφορά", "ButtonResetToDefault": "Επαναφορά στις προεπιλογές", "ButtonRestore": "Επαναφορά", "ButtonSave": "Αποθήκευση", "ButtonSaveAndClose": "Αποθήκευση και Κλείσιμο", + "ButtonSaveTracklist": "Αποθήκευση Λίστας Κομματιών", "ButtonScan": "Σάρψση", + "ButtonScanLibrary": "Σάρωση Βιβλιοθήκης", + "ButtonScrollLeft": "Κύλιση Αριστερά", + "ButtonScrollRight": "Κύλιση Δεξιά", "ButtonSearch": "Αναζήτηση", + "ButtonSelectFolderPath": "Επιλογή Διαδρομής Φακέλου", "ButtonSeries": "Σειρά", + "ButtonSetChaptersFromTracks": "Ορισμός κεφαλαίων από τα κομμάτια", + "ButtonShare": "Κοινοποίηση", + "ButtonShiftTimes": "Χρόνοι Μετακίνησης", + "ButtonShow": "Εμφάνιση", + "ButtonStartM4BEncode": "Έναρξη Κωδικοποίησης M4B", + "ButtonStats": "Στατιστικά", "ButtonSubmit": "Υποβολή", + "ButtonTest": "Δοκιμή", + "ButtonUpload": "Μεταφόρτωση", + "ButtonUploadBackup": "Μεταφόρτωση Αντιγράφου Ασφαλείας", + "ButtonUploadCover": "Μεταφόρτωση Εξωφύλλου", + "ButtonUploadOPMLFile": "Μεταφόρτωση Αρχείου OPML", + "ButtonUserDelete": "Διαγραφή Χρήστη {0}", + "ButtonUserEdit": "Επεξεργασίας χρήστη {0}", + "ButtonViewAll": "Εμφάνιση Όλων", "ButtonYes": "Ναι", + "ErrorUploadLacksTitle": "Πρέπει να έχει τίτλο", "HeaderAccount": "Λογαριασμός", "HeaderAdvanced": "Για Προχωρημένους", + "HeaderApiKeys": "Κλειδιά API", "HeaderAudioTracks": "Κομμάτια Ήχου", + "HeaderBackups": "Αντίγραφα Ασφαλείας", + "HeaderBulkChapterModal": "Προσθήκη Πολλαπλών Κεφαλαίων", + "HeaderChangePassword": "Αλλαγή Κωδικού Πρόσβασης", "HeaderChapters": "Κεφάλαια", + "HeaderChooseAFolder": "Επιλογή Φακέλου", "HeaderCollection": "Συλλογή", "HeaderCollectionItems": "Αντικείμενα Συλλογής", + "HeaderCover": "Εξώφυλλο", + "HeaderCurrentDownloads": "Τρέχουσες Λήψεις", "HeaderDetails": "Λεπτομέρειες", + "HeaderDownloadQueue": "Ουρά Λήψης", "HeaderEbookFiles": "Αρχεία Ebook", + "HeaderEmail": "Ηλεκτρονικό Ταχυδρομίο", + "HeaderEmailSettings": "Ρυθμίσεις Ηλεκτρονικού Ταχυδρομίου", "HeaderEpisodes": "Επεισόδια", "HeaderEreaderSettings": "Ρυθμίσεις Ereader", + "HeaderFiles": "Αρχεία", + "HeaderFindChapters": "Εύρεση Κεφαλαίων", + "HeaderItemFiles": "Αρχεία Αντικειμένων", + "HeaderLastListeningSession": "Τελευταία Συνεδρία Ακρόασης", "HeaderLatestEpisodes": "Τελευταία Επεισόδια", "HeaderLibraries": "Βιβλιοθήκες", + "HeaderLibraryFiles": "Αρχεία Βιβλιοθήκης", + "HeaderLibraryStats": "Στατιστικά Βιβλιοθήκης", + "HeaderListeningSessions": "Συνεδρίες Ακρόασης", + "HeaderListeningStats": "Στατιστικά Ακρόασης", + "HeaderMatch": "Ταύτιση", + "HeaderNewAccount": "Νέος Λογαριασμός", + "HeaderNewApiKey": "Νέο Κλειδί API", + "HeaderNewLibrary": "Νέα Βιβλιοθήκη", + "HeaderNotificationCreate": "Δημιουργία Ειδοποίησης", + "HeaderNotificationUpdate": "Ενημέρωση Ειδοποίησης", + "HeaderNotifications": "Ειδοποιήσεις", "HeaderOpenRSSFeed": "Άνοιγμα Τροφοδοσίας RSS", + "HeaderOtherFiles": "Άλλα Αρχεία", + "HeaderPermissions": "Δικαιώματα", + "HeaderPlayerSettings": "Ρυθμίσεις Αναπαραγωγής", "HeaderPlaylist": "Λίστα Αναπαραγωγής", "HeaderPlaylistItems": "Αντικείμενα Λίστας Αναπαραγωγής", + "HeaderPresets": "Προεπιλογές", "HeaderRSSFeedGeneral": "Λεπτομέρειες RSS", "HeaderRSSFeedIsOpen": "Η Τροφοδοσία RSS είναι Ανοιχτή", + "HeaderRemoveEpisode": "Αφαίρεση Επεισοδίου", + "HeaderSession": "Συνεδρία", + "HeaderSetBackupSchedule": "Ορισμός Προγράμματος Αντιγράφων Ασφαλείας", "HeaderSettings": "Ρυθμίσεις", + "HeaderSettingsDisplay": "Προβολή", + "HeaderSettingsGeneral": "Γενικά", + "HeaderSettingsSecurity": "Ασφάλεια", + "HeaderSleepTimer": "Χρονοδιακόπτης Ύπνου", + "HeaderStatsLargestItems": "Μεγαλύτερα Αντικείμενα", + "HeaderStatsLongestItems": "Μεγαλύτερα Αντικείμενα (ώρες)", "HeaderStatsMinutesListeningChart": "Λεπτά Ακρόασης (τελευταίες 7 ημέρες)", "HeaderStatsRecentSessions": "Πρόσφατες Συνεδρίες", - "HeaderTableOfContents": "Πίνακας Περιεχομένων" + "HeaderStatsTop10Authors": "10 Κορυφαίου Συγγραφείς", + "HeaderStatsTop5Genres": "5 Κορυφαία Είδη", + "HeaderTableOfContents": "Πίνακας Περιεχομένων", + "HeaderTools": "Εργαλεία", + "HeaderUpdateAccount": "Ενημέρωση Λογαριασμού", + "HeaderUpdateApiKey": "Ενημέρωση Κλειδιού API", + "HeaderUpdateAuthor": "Ενημέρωση Συγγραφέα", + "HeaderUpdateDetails": "Ενημέρωση Λεπτομερειεών", + "HeaderUpdateLibrary": "Ενημέρωση Βιβλιοθήκης", + "HeaderUsers": "Χρήστες", + "HeaderYourStats": "Τα Στατιστικά Σας", + "LabelAbridged": "Συνοπτικό", + "LabelAccessibleBy": "Προσβάσιμο από", + "LabelAccountType": "Τύπος Λογαριασμού", + "LabelAccountTypeAdmin": "Διαχειριστής", + "LabelAccountTypeGuest": "Επισκέπτης", + "LabelAccountTypeUser": "Χρήστης", + "LabelAddToCollection": "Προσθήκη σε Συλλογή", + "LabelAddToCollectionBatch": "Προσθήκη {0} Βιβλίων στην Συλλογή", + "LabelAddToPlaylist": "Προσθήκη στην Λίστα Αναπαραγωγής", + "LabelAddedAt": "Προστέθηκε Στις", + "LabelAddedDate": "Προστέθηκε {0}", + "LabelAll": "Όλα", + "LabelAllEpisodesDownloaded": "Όλα τα επεισόδια λήφθηκαν", + "LabelAllUsers": "Όλοι οι Χρήστες", + "LabelAlreadyInYourLibrary": "Υπάρχει ήδη στην βιβλιοθήκη", + "LabelAudioChannels": "Κανάλια Ήχου (1 ή 2)", + "LabelAuthor": "Συγγραφέας", + "LabelAuthorFirstLast": "Συγγραφέας (Όνομα Επώνυμο)", + "LabelAuthorLastFirst": "Συγγραφέας (Επώνυμο, Όνομα)", + "LabelAuthors": "Συγγραφείς", + "LabelAutoDownloadEpisodes": "Αυτόματο Κατέβασμα Επεισοδίων", + "LabelAutoLaunch": "Αυτόματη Εκκίνηση", + "LabelBackupLocation": "Τοποθεσία Αντιγράφου Ασφαλείας", + "LabelBackupsEnableAutomaticBackups": "Αυτόματα αντίγραφα ασφαλείας", + "LabelBackupsNumberToKeep": "Αριθμός αντιγράφων ασφαλείας προς διατήρηση", + "LabelBooks": "Βιβλία", + "LabelButtonText": "Κείμενο Κουμπιού", + "LabelByAuthor": "κατά {0}", + "LabelChangePassword": "Αλλαγή Κωδικού Πρόσβασης", + "LabelChannels": "Κανάλια", + "LabelChapterCount": "{0} Κεφάλαια", + "LabelChapterTitle": "Τίτλος Κεφαλαίου", + "LabelChapters": "Κεφάλαια", + "LabelChaptersFound": "κεφάλαια βρέθηκαν", + "LabelClosePlayer": "Κλείσιμο αναπαραγωγής", + "LabelCollection": "Συλλογή", + "LabelCollections": "Συλλογές", + "LabelComplete": "Ολοκλήρωση", + "LabelConfirmPassword": "Επιβεβαίωση Κωδικού Πρόσβασης", + "LabelContinueListening": "Συνέχεια Ακρόασης", + "LabelContinueReading": "Συνέχεια Ανάγνωσης", + "LabelContinueSeries": "Συνέχεια Σειράς", + "LabelCover": "Εξώφυλλο", + "LabelCoverImageURL": "URL Εικόνας Εξωφύλλου", + "LabelCoverProvider": "Πάροχος Εξωφύλλου", + "LabelCreatedAt": "Δημιουρήθηκε Στις", + "LabelCurrent": "Τρέχων", + "LabelCurrently": "Τρέχων:", + "LabelDays": "Ημέρες", + "LabelDescription": "Περιγραφή", + "LabelDevice": "Συσκευή", + "LabelDeviceInfo": "Πληροφορίες Συσκευής", + "LabelDownload": "Λήψη", + "LabelDownloadNEpisodes": "Λήψη {0} επεισοδίων", + "LabelDuration": "Διάρκεια", + "LabelDurationComparisonExactMatch": "(ακριβής ταύτιση)", + "LabelEbook": "Ebook", + "LabelEbooks": "Ebooks", + "LabelEdit": "Επεξεργασία", + "LabelEmail": "Ηλεκτρονικό Ταχυδρομίο", + "LabelEmailSettingsFromAddress": "Από Διεύθυνση", + "LabelEmailSettingsSecure": "Ασφαλές", + "LabelEmailSettingsTestAddress": "Δοκιμή Διεύθυνσης", + "LabelEmbeddedCover": "Ενσωματωμένο Εξώφυλλο", + "LabelEnable": "Ενεργοποίηση", + "LabelEnd": "Τέλος", + "LabelEndOfChapter": "Τέλος Κεφαλαίου", + "LabelEpisode": "Επεισόδιο", + "LabelFile": "Αρχείο", + "LabelFilename": "Όνομα Αρχείου", + "LabelFinished": "Ολοκληρώθηκε", + "LabelFolder": "Φάκελος", + "LabelFontFamily": "Οικογένεια Γραμματοσειράς", + "LabelGenre": "Είδος", + "LabelGenres": "Είδη", + "LabelHost": "Διακομιστής", + "LabelInProgress": "Σε Εξέλιξη", + "LabelLanguage": "Γλώσσα", + "LabelLayoutSinglePage": "Μονή Σελίδα", + "LabelListenAgain": "Επανάληψη Ακρόασης", + "LabelMediaType": "Τύπος Πολυμέσων", + "LabelMore": "Περισσότερα", + "LabelMoreInfo": "Περισσότερες Πληροφορίες", + "LabelName": "Όνομα", + "LabelNarrator": "Αφηγητής", + "LabelNarrators": "Αφηγητές", + "LabelNewestAuthors": "Πρόσφατοι Συγγραφείς", + "LabelNewestEpisodes": "Πρόσφατα Επεισόδια", + "LabelNotStarted": "Δεν Έχει Ξεκινήσει", + "LabelNumberOfEpisodes": "# Επεισοδίων", + "LabelPassword": "Κωδικός Πρόσβασης", + "LabelPath": "Διαδρομή", + "LabelProgress": "Πρόοδος", + "LabelPublishYear": "Χρονολογία Έκδοσης", + "LabelPublishedDate": "Εκδόθηκε {0}", + "LabelRandomly": "Τυχαία", + "LabelRead": "Ανάγνωση", + "LabelReadAgain": "Ανάγνωση Ξανά", + "LabelRecentSeries": "Πρόσφατη Σειρά", + "LabelRecentlyAdded": "Προστέθηκαν Πρόσφατα", + "LabelSeries": "Σειρά", + "LabelSetEbookAsPrimary": "Ορισμός ως πρωτεύων", + "LabelShowAll": "Εμφάνιση Όλων", + "LabelSize": "Μέγεθος", + "LabelSleepTimer": "Χρονοδιακόπτης Ύπνου", + "LabelStart": "Έναρξη", + "LabelStatsBestDay": "Καλύτερη Ημέρα", + "LabelStatsDailyAverage": "Ημερήσιος Μέσος Όρος", + "LabelStatsDays": "Ημέρες", + "LabelStatsDaysListened": "Ημέρες Ακρόασης", + "LabelStatsInARow": "Σε σειρά", + "LabelStatsItemsFinished": "Ολοκληρωμένα Αντικείμενα", + "LabelStatsMinutes": "λεπτά", + "LabelStatsMinutesListening": "Λεπτά Ακρόασης", + "LabelStatsWeekListening": "Εβδομαδιαία Ακρόαση", + "LabelTheme": "Θέμα", + "LabelThemeDark": "Σκοτεινό", + "LabelThemeLight": "Φωτεινό", + "LabelTimeRemaining": "{0} απομένουν", + "LabelTitle": "Τίτλος", + "LabelTracks": "Κομμάτια", + "LabelType": "Τύπος", + "LabelUnknown": "Άγνωστο", + "LabelUser": "Χρήστης", + "LabelUsername": "Όνομα Χρήστη", + "LabelYourProgress": "Η Πρόοδος Σας", + "MessageDownloadingEpisode": "Λήψη επεισοδίου", + "MessageLoading": "Φόρτωση...", + "MessageMarkAsFinished": "Σήμανση ως Ολοκληρωμένο", + "MessageNoItemsFound": "Δεν βρέθηκαν αντικείμενα", + "MessageNoUserPlaylists": "Δεν έχετε λίστες αναπαραγωγής" } From 81e96df9c5f8db502e3d9740ee8cb6b718c5a074 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 21 Dec 2025 15:54:07 -0600 Subject: [PATCH 29/29] Version bump v2.32.0 --- client/package-lock.json | 4 ++-- client/package.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 2d41d39ef..568274c80 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "audiobookshelf-client", - "version": "2.31.0", + "version": "2.32.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "audiobookshelf-client", - "version": "2.31.0", + "version": "2.32.0", "license": "ISC", "dependencies": { "@nuxtjs/axios": "^5.13.6", diff --git a/client/package.json b/client/package.json index 33d66c276..df71f6256 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-client", - "version": "2.31.0", + "version": "2.32.0", "buildNumber": 1, "description": "Self-hosted audiobook and podcast client", "main": "index.js", diff --git a/package-lock.json b/package-lock.json index d703a8edc..4c9e9b9ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "audiobookshelf", - "version": "2.31.0", + "version": "2.32.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "audiobookshelf", - "version": "2.31.0", + "version": "2.32.0", "license": "GPL-3.0", "dependencies": { "axios": "^0.27.2", diff --git a/package.json b/package.json index 0aaf4f5af..2b0d0b6cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf", - "version": "2.31.0", + "version": "2.32.0", "buildNumber": 1, "description": "Self-hosted audiobook and podcast server", "main": "index.js",