diff --git a/Dockerfile b/Dockerfile
index 1ba107fd..f9c46117 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,9 @@
+ARG NUSQLITE3_DIR="/usr/local/lib/nusqlite3"
+ARG NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so"
+
### STAGE 0: Build client ###
FROM node:20-alpine AS build-client
+
WORKDIR /client
COPY /client /client
RUN npm ci && npm cache clean --force
@@ -8,6 +12,9 @@ RUN npm run generate
### STAGE 1: Build server ###
FROM node:20-alpine AS build-server
+ARG NUSQLITE3_DIR
+ARG TARGETPLATFORM
+
ENV NODE_ENV=production
RUN apk add --no-cache --update \
@@ -21,11 +28,6 @@ WORKDIR /server
COPY index.js package* /server
COPY /server /server/server
-ARG TARGETPLATFORM
-
-ENV NUSQLITE3_DIR="/usr/local/lib/nusqlite3"
-ENV NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so"
-
RUN case "$TARGETPLATFORM" in \
"linux/amd64") \
curl -L -o /tmp/library.zip "https://github.com/mikiher/nunicode-sqlite/releases/download/v1.2/libnusqlite3-linux-musl-x64.zip" ;; \
@@ -41,6 +43,9 @@ RUN npm ci --only=production
### STAGE 2: Create minimal runtime image ###
FROM node:20-alpine
+ARG NUSQLITE3_DIR
+ARG NUSQLITE3_PATH
+
# Install only runtime dependencies
RUN apk add --no-cache --update \
tzdata \
@@ -52,13 +57,17 @@ WORKDIR /app
# Copy compiled frontend and server from build stages
COPY --from=build-client /client/dist /app/client/dist
COPY --from=build-server /server /app
+COPY --from=build-server /usr/local/lib/nusqlite3 /usr/local/lib/nusqlite3
EXPOSE 80
ENV PORT=80
+ENV NODE_ENV=production
ENV CONFIG_PATH="/config"
ENV METADATA_PATH="/metadata"
ENV SOURCE="docker"
+ENV NUSQLITE3_DIR=${NUSQLITE3_DIR}
+ENV NUSQLITE3_PATH=${NUSQLITE3_PATH}
ENTRYPOINT ["tini", "--"]
CMD ["node", "index.js"]
diff --git a/client/components/app/BookShelfCategorized.vue b/client/components/app/BookShelfCategorized.vue
index 8c680462..4bf8cfbb 100644
--- a/client/components/app/BookShelfCategorized.vue
+++ b/client/components/app/BookShelfCategorized.vue
@@ -217,6 +217,16 @@ export default {
})
}
+ if (this.results.episodes?.length) {
+ shelves.push({
+ id: 'episodes',
+ label: 'Episodes',
+ labelStringKey: 'LabelEpisodes',
+ type: 'episode',
+ entities: this.results.episodes.map((res) => res.libraryItem)
+ })
+ }
+
if (this.results.series?.length) {
shelves.push({
id: 'series',
diff --git a/client/components/cards/EpisodeSearchCard.vue b/client/components/cards/EpisodeSearchCard.vue
index e69de29b..8be6a3a3 100644
--- a/client/components/cards/EpisodeSearchCard.vue
+++ b/client/components/cards/EpisodeSearchCard.vue
@@ -0,0 +1,60 @@
+
+ {{ episodeTitle }} {{ podcastTitle }}
{{ $strings.LabelEpisodes }}
+ +{{ $strings.LabelAuthors }}
/login?autoLaunch=0
)",
+ "LabelAutoRegister": "تسجيل تلقائي",
+ "LabelAutoRegisterDescription": "إنشاء مستخدمين جدد تلقائيًا بعد تسجيل الدخول",
+ "LabelBackToUser": "العودة إلى المستخدم",
+ "LabelBackupAudioFiles": "نسخ ملفات الصوت احتياطيًا",
+ "LabelBackupLocation": "موقع النسخ الاحتياطي",
+ "LabelBackupsEnableAutomaticBackups": "نسخ احتياطية تلقائية",
+ "LabelBackupsEnableAutomaticBackupsHelp": "النسخ الاحتياطية المحفوظة في / البيانات الوصفية / النسخ الاحتياطية",
+ "LabelBackupsMaxBackupSize": "الحد الأقصى لحجم النسخ الاحتياطي (بالجيجابايت) (0 لغير محدود)",
+ "LabelBackupsMaxBackupSizeHelp": "كإجراء وقائي ضد سوء التكوين، ستفشل عمليات النسخ الاحتياطي إذا تجاوزت الحجم المحدد.",
+ "LabelBackupsNumberToKeep": "عدد النسخ الاحتياطية التي يجب الاحتفاظ بها",
+ "LabelBackupsNumberToKeepHelp": "ستتم إزالة نسخة احتياطية واحدة فقط في كل مرة، لذا إذا كان لديك بالفعل عدد نسخ احتياطية أكبر من هذا، فيجب عليك إزالتها يدويًا.",
+ "LabelBitrate": "معدل البت",
+ "LabelBonus": "مكافأة",
"LabelBooks": "الكتب",
+ "LabelButtonText": "نص الزر",
+ "LabelByAuthor": "بواسطة {0}",
+ "LabelChangePassword": "تغيير كلمة المرور",
+ "LabelChannels": "قنوات",
+ "LabelChapterCount": "{0} فصول",
+ "LabelChapterTitle": "عنوان الفصل",
"LabelChapters": "الفصول",
+ "LabelChaptersFound": "تم العثور على فصول",
+ "LabelClickForMoreInfo": "انقر لمزيد من المعلومات",
+ "LabelClickToUseCurrentValue": "انقر لاستخدام القيمة الحالية",
"LabelClosePlayer": "إغلاق المشغل",
+ "LabelCodec": "برنامج الترميز",
"LabelCollapseSeries": "إخفاء المسلسلات",
+ "LabelCollapseSubSeries": "إخفاء المسلسلات الفرعية",
+ "LabelCollection": "مجموعة",
+ "LabelCollections": "مجموعات",
"LabelComplete": "مكتمل",
+ "LabelConfirmPassword": "تأكيد كلمة المرور",
"LabelContinueListening": "استمرار الاستماع",
"LabelContinueReading": "استمرار القراءة",
"LabelContinueSeries": "استمرار المسلسلات",
+ "LabelCover": "الغلاف",
+ "LabelCoverImageURL": "رابط صورة الغلاف",
+ "LabelCoverProvider": "مزود الغلاف",
+ "LabelCreatedAt": "تاريخ الإنشاء",
+ "LabelCronExpression": "تعبير Cron",
+ "LabelCurrent": "الحالي",
+ "LabelCurrently": "حاليًا:",
+ "LabelCustomCronExpression": "تعبير Cron مخصص:",
+ "LabelDatetime": "التاريخ والوقت",
+ "LabelDays": "أيام",
+ "LabelDeleteFromFileSystemCheckbox": "حذف من نظام الملفات (إلغاء التحديد للإزالة من قاعدة البيانات فقط)",
"LabelDescription": "الوصف",
+ "LabelDeselectAll": "إلغاء تحديد الكل",
+ "LabelDevice": "الجهاز",
+ "LabelDeviceInfo": "معلومات الجهاز",
+ "LabelDeviceIsAvailableTo": "الجهاز متاح لـ...",
+ "LabelDirectory": "مجلد / دليل",
+ "LabelDiscFromFilename": "القرص من اسم الملف",
+ "LabelDiscFromMetadata": "القرص من البيانات الوصفية",
"LabelDiscover": "استكشف",
"LabelDownload": "تنزيل",
+ "LabelDownloadNEpisodes": "تنزيل {0} حلقات",
+ "LabelDownloadable": "قابل للتنزيل",
"LabelDuration": "المدة",
+ "LabelDurationComparisonExactMatch": "(تطابق تام)",
+ "LabelDurationComparisonLonger": "(أطول بـ {0})",
+ "LabelDurationComparisonShorter": "({0} أقصر)",
+ "LabelDurationFound": "المدة الموجودة:",
"LabelEbook": "الكتاب الإلكتروني",
"LabelEbooks": "الكتب الإلكترونية",
+ "LabelEdit": "تعديل",
+ "LabelEmail": "البريد الإلكتروني",
+ "LabelEmailSettingsFromAddress": "عنوان المرسل",
+ "LabelEmailSettingsRejectUnauthorized": "رفض الشهادات غير المصرح بها",
+ "LabelEmailSettingsRejectUnauthorizedHelp": "قد يؤدي تعطيل التحقق من شهادة SSL إلى تعريض اتصالك لمخاطر أمنية، مثل هجمات الوسيط. لا تقم بتعطيل هذا الخيار إلا إذا كنت تفهم الآثار المترتبة عليه وتثق في خادم البريد الذي تتصل به.",
+ "LabelEmailSettingsSecure": "آمن",
+ "LabelEmailSettingsSecureHelp": "إذا كانت القيمة true، فسيستخدم الاتصال TLS عند الاتصال بالخادم. وإذا كانت false، فسيتم استخدام TLS إذا كان الخادم يدعم امتداد STARTTLS. في معظم الحالات، اضبط هذه القيمة على true إذا كنت تتصل بالمنفذ 465. أما بالنسبة للمنفذ 587 أو 25، فاحتفظ بها على false. (من nodemailer.com/smtp/#authentication)",
+ "LabelEmailSettingsTestAddress": "عنوان الاختبار",
+ "LabelEmbeddedCover": "غلاف مضمن",
"LabelEnable": "تمكين",
+ "LabelEncodingBackupLocation": "سيتم تخزين نسخة احتياطية من ملفاتك الصوتية الأصلية في:",
+ "LabelEncodingChaptersNotEmbedded": "الفصول غير مضمنة في الكتب الصوتية متعددة المسارات.",
+ "LabelEncodingClearItemCache": "تأكد من مسح ذاكرة التخزين المؤقت للعناصر بشكل دوري.",
+ "LabelEncodingFinishedM4B": "سيتم وضع ملف M4B النهائي في مجلد الكتب الصوتية الخاص بك في:",
+ "LabelEncodingInfoEmbedded": "سيتم تضمين البيانات الوصفية في المسارات الصوتية داخل مجلد الكتب الصوتية الخاص بك.",
+ "LabelEncodingStartedNavigation": "بمجرد بدء المهمة، يمكنك الانتقال من هذه الصفحة.",
+ "LabelEncodingTimeWarning": "قد تستغرق عملية الترميز ما يصل إلى 30 دقيقة.",
+ "LabelEncodingWarningAdvancedSettings": "تحذير: لا تقم بتحديث هذه الإعدادات إلا إذا كنت على دراية بخيارات ترميز ffmpeg.",
+ "LabelEncodingWatcherDisabled": "إذا قمت بتعطيل المراقب، فستحتاج إلى إعادة فحص هذا الكتاب الصوتي بعد ذلك.",
"LabelEnd": "انهاء",
"LabelEndOfChapter": "نهاية الفصل",
"LabelEpisode": "الحلقة",
+ "LabelEpisodeNotLinkedToRssFeed": "الحلقة غير مرتبطة بخلاصة RSS",
+ "LabelEpisodeNumber": "الحلقة #{0}",
+ "LabelEpisodeTitle": "عنوان الحلقة",
+ "LabelEpisodeType": "نوع الحلقة",
+ "LabelEpisodeUrlFromRssFeed": "رابط الحلقة من خلاصة RSS",
+ "LabelEpisodes": "حلقات",
+ "LabelEpisodic": "عرضي / حلقي",
+ "LabelExample": "مثال",
+ "LabelExpandSeries": "توسيع السلاسل",
+ "LabelExpandSubSeries": "توسيع السلاسل الفرعية",
+ "LabelExplicit": "صريح",
+ "LabelExplicitChecked": "صريح (محدد)",
+ "LabelExplicitUnchecked": "غير صريح (غير محدد)",
+ "LabelExportOPML": "تصدير OPML",
"LabelFeedURL": "عنوان التغذية",
+ "LabelFetchingMetadata": "جلب البيانات الوصفية",
"LabelFile": "الملف",
"LabelFileBirthtime": "وقت انشاء الملف",
+ "LabelFileBornDate": "تاريخ الإنشاء {0}",
"LabelFileModified": "تم تعديل الملف",
+ "LabelFileModifiedDate": "تم التعديل في {0}",
"LabelFilename": "اسم الملف",
+ "LabelFilterByUser": "تصفية حسب المستخدم",
+ "LabelFindEpisodes": "البحث عن حلقات",
"LabelFinished": "المنجزة",
"LabelFolder": "المجلد",
+ "LabelFolders": "مجلدات",
+ "LabelFontBold": "عريض",
"LabelFontBoldness": "تعريض الخط",
+ "LabelFontFamily": "عائلة الخط",
+ "LabelFontItalic": "مائل",
"LabelFontScale": "نطاق الخط",
+ "LabelFontStrikethrough": "يتوسطه خط",
+ "LabelFormat": "تنسيق",
+ "LabelFull": "كامل",
"LabelGenre": "التصنيف",
"LabelGenres": "التصانيف",
+ "LabelHardDeleteFile": "حذف الملف نهائيًا",
"LabelHasEbook": "يحتوي كتاب إلكتروني",
"LabelHasSupplementaryEbook": "يحتوي كتاب إلكتروني تكميلي",
+ "LabelHideSubtitles": "إخفاء الترجمة",
+ "LabelHighestPriority": "الأولوية القصوى",
"LabelHost": "المضيف",
+ "LabelHour": "ساعة",
+ "LabelHours": "ساعات",
+ "LabelIcon": "أيقونة",
+ "LabelImageURLFromTheWeb": "رابط الصورة من الويب",
"LabelInProgress": "تحت التنفيذ",
+ "LabelIncludeInTracklist": "تضمين في قائمة المسارات",
"LabelIncomplete": "غير مكتمل",
+ "LabelInterval": "فاصل زمني",
+ "LabelIntervalCustomDailyWeekly": "يومي/أسبوعي مخصص",
+ "LabelIntervalEvery12Hours": "كل 12 ساعة",
+ "LabelIntervalEvery15Minutes": "كل 15 دقيقة",
+ "LabelIntervalEvery2Hours": "كل ساعتين",
+ "LabelIntervalEvery30Minutes": "كل 30 دقيقة",
+ "LabelIntervalEvery6Hours": "كل 6 ساعات",
+ "LabelIntervalEveryDay": "كل يوم",
+ "LabelIntervalEveryHour": "كل ساعة",
+ "LabelIntervalEveryMinute": "كل دقيقة",
+ "LabelInvert": "عكس",
+ "LabelItem": "عنصر",
+ "LabelJumpBackwardAmount": "مقدار الرجوع للخلف",
+ "LabelJumpForwardAmount": "مقدار التقدم للأمام",
"LabelLanguage": "اللغة",
+ "LabelLanguageDefaultServer": "لغة الخادم الافتراضية",
+ "LabelLanguages": "اللغات",
+ "LabelLastBookAdded": "آخر كتاب تمت إضافته",
+ "LabelLastBookUpdated": "آخر كتاب تم تحديثه",
+ "LabelLastSeen": "آخر ظهور",
+ "LabelLastTime": "آخر مرة",
+ "LabelLastUpdate": "آخر تحديث",
"LabelLayout": "التنسيق",
"LabelLayoutSinglePage": "صفحة واحدة",
+ "LabelLayoutSplitPage": "صفحتان متقابلتان",
+ "LabelLess": "أقل",
+ "LabelLibrariesAccessibleToUser": "المكتبات المتاحة للمستخدم",
+ "LabelLibrary": "مكتبة",
+ "LabelLibraryFilterSublistEmpty": "لا يوجد {0}",
+ "LabelLibraryItem": "عنصر المكتبة",
+ "LabelLibraryName": "اسم المكتبة",
+ "LabelLimit": "حد",
"LabelLineSpacing": "تباعد الأسطر",
"LabelListenAgain": "الاستماع مجدداً",
+ "LabelLogLevelDebug": "تصحيح الأخطاء",
+ "LabelLogLevelInfo": "معلومات",
+ "LabelLogLevelWarn": "تحذير",
+ "LabelLookForNewEpisodesAfterDate": "البحث عن حلقات جديدة بعد هذا التاريخ",
+ "LabelLowestPriority": "الأولوية الأدنى",
+ "LabelMatchExistingUsersBy": "مطابقة المستخدمين الحاليين بواسطة",
+ "LabelMatchExistingUsersByDescription": "يستخدم لربط المستخدمين الحاليين. بمجرد الاتصال، سيتم مطابقة المستخدمين بواسطة معرف فريد من مزود SSO الخاص بك",
+ "LabelMaxEpisodesToDownload": "الحد الأقصى لعدد الحلقات التي سيتم تنزيلها. استخدم 0 لغير محدود.",
+ "LabelMaxEpisodesToDownloadPerCheck": "الحد الأقصى لعدد الحلقات الجديدة التي سيتم تنزيلها في كل فحص",
+ "LabelMaxEpisodesToKeep": "الحد الأقصى لعدد الحلقات التي سيتم الاحتفاظ بها",
+ "LabelMaxEpisodesToKeepHelp": "القيمة 0 لا تضع حدًا أقصى. بعد تنزيل حلقة جديدة تلقائيًا، سيؤدي هذا إلى حذف أقدم حلقة إذا كان لديك أكثر من X حلقة. سيؤدي هذا إلى حذف حلقة واحدة فقط لكل تنزيل جديد.",
+ "LabelMediaPlayer": "مشغل الوسائط",
"LabelMediaType": "نوع الوسائط",
+ "LabelMetaTag": "علامة بيانات وصفية",
+ "LabelMetaTags": "علامات البيانات الوصفية",
+ "LabelMetadataOrderOfPrecedenceDescription": "ستتجاوز مصادر البيانات الوصفية ذات الأولوية الأعلى مصادر البيانات الوصفية ذات الأولوية الأقل",
+ "LabelMetadataProvider": "مزود البيانات الوصفية",
+ "LabelMinute": "دقيقة",
+ "LabelMinutes": "دقائق",
"LabelMissing": "مفقود",
+ "LabelMissingEbook": "لا يوجد كتاب إلكتروني",
+ "LabelMissingSupplementaryEbook": "لا يوجد كتاب إلكتروني تكميلي",
+ "LabelMobileRedirectURIs": "معرفات URI لإعادة التوجيه المسموح بها لتطبيقات الجوال",
+ "LabelMobileRedirectURIsDescription": "هذه قائمة بيضاء لمعرفات URI لإعادة التوجيه الصالحة لتطبيقات الجوال. المعرف الافتراضي هو audiobookshelf://oauth
، والذي يمكنك إزالته أو استكماله بمعرفات URI إضافية لتكامل تطبيقات الطرف الثالث. استخدام علامة النجمة (*
) كإدخال وحيد يسمح بأي معرف URI.",
"LabelMore": "أكثر",
"LabelMoreInfo": "معلومات أكثر",
"LabelName": "الاسم",
"LabelNarrator": "الراوي",
"LabelNarrators": "الرواة",
+ "LabelNew": "جديد",
+ "LabelNewPassword": "كلمة سر جديدة",
"LabelNewestAuthors": "أجدد المؤلفين",
"LabelNewestEpisodes": "أجدد الحلقات",
+ "LabelNextBackupDate": "تاريخ النسخ الاحتياطي التالي",
+ "LabelNextScheduledRun": "التشغيل المجدول التالي",
+ "LabelNoCustomMetadataProviders": "لا يوجد مزودو بيانات وصفية مخصصون",
+ "LabelNoEpisodesSelected": "لم يتم تحديد أي حلقات",
"LabelNotFinished": "لم يتم الانتهاء",
"LabelNotStarted": "لم يتم البدء",
+ "LabelNotes": "ملاحظات",
+ "LabelNotificationAppriseURL": "رابط (روابط) Apprise",
+ "LabelNotificationAvailableVariables": "المتغيرات المتاحة",
+ "LabelNotificationBodyTemplate": "قالب النص",
+ "LabelNotificationEvent": "حدث الإشعار",
+ "LabelNotificationTitleTemplate": "قالب العنوان",
+ "LabelNotificationsMaxFailedAttempts": "الحد الأقصى لعدد المحاولات الفاشلة",
+ "LabelNotificationsMaxFailedAttemptsHelp": "يتم تعطيل الإشعارات بمجرد فشل إرسالها لهذا العدد من المرات",
+ "LabelNotificationsMaxQueueSize": "الحد الأقصى لحجم قائمة انتظار أحداث الإشعارات",
+ "LabelNotificationsMaxQueueSizeHelp": "تقتصر الأحداث على التشغيل مرة واحدة في الثانية. سيتم تجاهل الأحداث إذا كانت قائمة الانتظار في الحد الأقصى لحجمها. هذا يمنع إرسال الإشعارات بشكل متكرر.",
+ "LabelNumberOfBooks": "عدد الكتب",
"LabelNumberOfEpisodes": "# من الحلقات",
+ "LabelOpenIDAdvancedPermsClaimDescription": "اسم مطالبة OpenID التي تحتوي على أذونات متقدمة لإجراءات المستخدم داخل التطبيق والتي ستطبق على الأدوار غير الإدارية (إذا تم تكوينها). إذا كانت المطالبة مفقودة من الاستجابة، فسيتم رفض الوصول إلى ABS. إذا كان هناك خيار واحد مفقودًا، فسيتم التعامل معه على أنه false
. تأكد من أن مطالبة موفر الهوية تطابق البنية المتوقعة:",
+ "LabelOpenIDClaims": "اترك الخيارات التالية فارغة لتعطيل تعيين المجموعة والأذونات المتقدمة، وسيتم تعيين مجموعة \"مستخدم\" تلقائيًا بعد ذلك.",
+ "LabelOpenIDGroupClaimDescription": "اسم مطالبة OpenID التي تحتوي على قائمة بمجموعات المستخدم. يشار إليها عادةً باسم groups
.إذا تم تكوينها، فسيقوم التطبيق تلقائيًا بتعيين الأدوار بناءً على عضويات مجموعة المستخدم، بشرط أن تسمى هذه المجموعات بشكل غير حساس لحالة الأحرف \"admin\" أو \"user\" أو \"guest\" في المطالبة. يجب أن تحتوي المطالبة على قائمة، وإذا كان المستخدم ينتمي إلى مجموعات متعددة، فسيقوم التطبيق بتعيين الدور المقابل لأعلى مستوى من الوصول. إذا لم تتطابق أي مجموعة، فسيتم رفض الوصول.",
+ "LabelOpenRSSFeed": "تغذية RSS مفتوحة",
+ "LabelOverwrite": "استبدال",
+ "LabelPaginationPageXOfY": "صفحة {0} من {1}",
"LabelPassword": "كلمة المرور",
"LabelPath": "مسار",
+ "LabelPermanent": "دائم",
+ "LabelPermissionsAccessAllLibraries": "يمكنه الوصول إلى جميع المكتبات",
+ "LabelPermissionsAccessAllTags": "يمكنه الوصول إلى جميع العلامات",
+ "LabelPermissionsAccessExplicitContent": "يمكنه الوصول إلى المحتوى الصريح",
+ "LabelPermissionsCreateEreader": "يمكنه إنشاء قارئ إلكتروني",
+ "LabelPermissionsDelete": "يمكنه الحذف",
+ "LabelPermissionsDownload": "يمكنه التنزيل",
+ "LabelPermissionsUpdate": "يمكنه التحديث",
+ "LabelPermissionsUpload": "يمكنه الرفع",
+ "LabelPersonalYearReview": "ملخص عامك ({0})",
+ "LabelPhotoPathURL": "مسار/رابط الصورة",
+ "LabelPlayMethod": "طريقة التشغيل",
+ "LabelPlaybackRateIncrementDecrement": "مقدار زيادة/نقصان سرعة التشغيل",
+ "LabelPlayerChapterNumberMarker": "{0} من {1}",
+ "LabelPlaylists": "قوائم التشغيل",
"LabelPodcast": "مدونة صوتية",
- "LabelPodcasts": "مدونات صوتية",
+ "LabelPodcastSearchRegion": "منطقة البحث عن البودكاست",
+ "LabelPodcastType": "نوع البودكاست",
+ "LabelPodcasts": "بودكاست",
+ "LabelPort": "منفذ",
+ "LabelPrefixesToIgnore": "البادئات التي يجب تجاهلها (غير حساسة لحالة الأحرف)",
"LabelPreventIndexing": "منع فهرسة تغذيتك بواسطة دليل آيتونز وقوقل بودكاست",
+ "LabelPrimaryEbook": "الكتاب الإلكتروني الأساسي",
"LabelProgress": "تقدم",
+ "LabelProvider": "مزود",
+ "LabelProviderAuthorizationValue": "قيمة رأس التفويض",
"LabelPubDate": "تاريخ النشر",
"LabelPublishYear": "سنة النشر",
"LabelPublishedDate": "منشور {0}",
+ "LabelPublishedDecade": "عقد النشر",
+ "LabelPublishedDecades": "عقود النشر",
+ "LabelPublisher": "الناشر",
+ "LabelPublishers": "الناشرون",
"LabelRSSFeedCustomOwnerEmail": "البريد الالكتروني المخصص للمالك",
"LabelRSSFeedCustomOwnerName": "الاسم المخصص للمالك",
+ "LabelRSSFeedOpen": "فتح تغذية RSS",
"LabelRSSFeedPreventIndexing": "منع الفهرسة",
- "LabelRSSFeedSlug": "رابط تغذية RSS",
+ "LabelRSSFeedSlug": "اسم تعريف تغذية RSS",
+ "LabelRSSFeedURL": "رابط تغذية RSS",
"LabelRandomly": "عشوائياً",
+ "LabelReAddSeriesToContinueListening": "إعادة إضافة السلسلة إلى \"متابعة الاستماع\"",
"LabelRead": "اقرأ",
"LabelReadAgain": "اقرأ مرة أخرى",
+ "LabelReadEbookWithoutProgress": "قراءة الكتاب الإلكتروني دون حفظ التقدم",
"LabelRecentSeries": "المسلسلات الحديثة",
"LabelRecentlyAdded": "المضافة حديثاً",
+ "LabelRecommended": "موصى به",
+ "LabelRedo": "إعادة",
+ "LabelRegion": "المنطقة",
+ "LabelReleaseDate": "تاريخ الإصدار",
+ "LabelRemoveAllMetadataAbs": "إزالة جميع ملفات metadata.abs",
+ "LabelRemoveAllMetadataJson": "إزالة جميع ملفات metadata.json",
+ "LabelRemoveAudibleBranding": "إزالة مقدمة وخاتمة Audible من الفصول",
+ "LabelRemoveCover": "إزالة الغلاف",
+ "LabelRemoveMetadataFile": "إزالة ملفات البيانات الوصفية في مجلدات عناصر المكتبة",
+ "LabelRemoveMetadataFileHelp": "إزالة جميع ملفات metadata.json و metadata.abs في مجلدات {0} الخاصة بك.",
+ "LabelRowsPerPage": "عدد الصفوف في الصفحة",
+ "LabelSearchTerm": "مصطلح البحث",
+ "LabelSearchTitle": "بحث بالعنوان",
+ "LabelSearchTitleOrASIN": "بحث بالعنوان أو ASIN",
"LabelSeason": "الموسم",
+ "LabelSeasonNumber": "الموسم #{0}",
+ "LabelSelectAll": "تحديد الكل",
+ "LabelSelectAllEpisodes": "تحديد جميع الحلقات",
+ "LabelSelectEpisodesShowing": "تحديد {0} حلقة معروضة",
+ "LabelSelectUsers": "تحديد المستخدمين",
+ "LabelSendEbookToDevice": "إرسال الكتاب الإلكتروني إلى...",
+ "LabelSequence": "تسلسل",
+ "LabelSerial": "مسلسل",
"LabelSeries": "المسلسلات",
+ "LabelSeriesName": "اسم السلسلة",
+ "LabelSeriesProgress": "تقدم السلسلة",
+ "LabelServerLogLevel": "مستوى سجل الخادم",
+ "LabelServerYearReview": "ملخص عام الخادم ({0})",
"LabelSetEbookAsPrimary": "تعيين كرئيسي",
"LabelSetEbookAsSupplementary": "تعيين كتكميلي",
- "LabelShowAll": "اظهار الكل",
+ "LabelSettingsAllowIframe": "السماح بالتضمين في إطار iframe",
+ "LabelSettingsAudiobooksOnly": "كتب صوتية فقط",
+ "LabelSettingsAudiobooksOnlyHelp": "سيؤدي تمكين هذا الإعداد إلى تجاهل ملفات الكتب الإلكترونية ما لم تكن داخل مجلد كتاب صوتي، وفي هذه الحالة سيتم تعيينها ككتب إلكترونية تكميلية",
+ "LabelSettingsBookshelfViewHelp": "تصميم يحاكي الواقع مع رفوف خشبية",
+ "LabelSettingsChromecastSupport": "دعم Chromecast",
+ "LabelSettingsDateFormat": "تنسيق التاريخ",
+ "LabelSettingsEnableWatcher": "فحص المكتبات تلقائيًا بحثًا عن تغييرات",
+ "LabelSettingsEnableWatcherForLibrary": "فحص المكتبة تلقائيًا بحثًا عن تغييرات",
+ "LabelSettingsEnableWatcherHelp": "يمكّن الإضافة/التحديث التلقائي للعناصر عند اكتشاف تغييرات في الملفات. *يتطلب إعادة تشغيل الخادم",
+ "LabelSettingsEpubsAllowScriptedContent": "السماح بالمحتوى النصي في ملفات epub",
+ "LabelSettingsEpubsAllowScriptedContentHelp": "السماح لملفات epub بتنفيذ النصوص البرمجية. يوصى بإبقاء هذا الإعداد معطلاً ما لم تثق في مصدر ملفات epub.",
+ "LabelSettingsExperimentalFeatures": "ميزات تجريبية",
+ "LabelSettingsExperimentalFeaturesHelp": "ميزات قيد التطوير يمكنها استخدام ملاحظاتك والمساعدة في اختبارها. انقر لفتح مناقشة على GitHub.",
+ "LabelSettingsFindCovers": "البحث عن الأغلفة",
+ "LabelSettingsFindCoversHelp": "إذا لم يكن لدى كتابك الصوتي غلاف مضمن أو صورة غلاف داخل المجلد، فسيحاول الماسح الضوئي العثور على غلاف.<br> ملاحظة: سيؤدي هذا إلى إطالة وقت الفحص",
+ "LabelSettingsHideSingleBookSeries": "إخفاء السلاسل ذات الكتاب الواحد",
+ "LabelSettingsHideSingleBookSeriesHelp": "سيتم إخفاء السلاسل التي تحتوي على كتاب واحد من صفحة السلاسل وأرفف الصفحة الرئيسية.",
+ "LabelSettingsHomePageBookshelfView": "استخدام عرض الرفوف في الصفحة الرئيسية",
+ "LabelSettingsLibraryBookshelfView": "استخدام عرض الرفوف في المكتبة",
+ "LabelSettingsLibraryMarkAsFinishedPercentComplete": "النسبة المئوية المكتملة أكبر من",
+ "LabelSettingsLibraryMarkAsFinishedTimeRemaining": "الوقت المتبقي أقل من (ثواني)",
+ "LabelSettingsLibraryMarkAsFinishedWhen": "تعليم عنصر الوسائط على أنه منتهٍ عند",
+ "LabelSettingsOnlyShowLaterBooksInContinueSeries": "تخطي الكتب السابقة في \"متابعة السلسلة\"",
+ "LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "يعرض رف \"متابعة السلسلة\" في الصفحة الرئيسية أول كتاب لم يبدأ في السلاسل التي تحتوي على كتاب واحد على الأقل منتهي ولا يوجد كتب قيد التقدم. سيؤدي تمكين هذا الإعداد إلى متابعة السلاسل من أبعد كتاب مكتمل بدلاً من أول كتاب لم يبدأ.",
+ "LabelSettingsParseSubtitles": "تحليل الترجمة",
+ "LabelSettingsParseSubtitlesHelp": "استخراج الترجمة من أسماء مجلدات الكتب الصوتية.<br>يجب فصل الترجمة بـ \" - \"<br>مثال: \"عنوان الكتاب - ترجمة هنا\" تحتوي على الترجمة \"ترجمة هنا\"",
+ "LabelSettingsPreferMatchedMetadata": "تفضيل البيانات الوصفية المطابقة",
+ "LabelSettingsPreferMatchedMetadataHelp": "ستتجاوز البيانات المطابقة تفاصيل العنصر عند استخدام المطابقة السريعة. بشكل افتراضي، ستملأ المطابقة السريعة التفاصيل المفقودة فقط.",
+ "LabelSettingsSkipMatchingBooksWithASIN": "تخطي مطابقة الكتب التي لديها ASIN بالفعل",
+ "LabelSettingsSkipMatchingBooksWithISBN": "تخطي مطابقة الكتب التي لديها ISBN بالفعل",
+ "LabelSettingsSortingIgnorePrefixes": "تجاهل البادئات عند الفرز",
+ "LabelSettingsSortingIgnorePrefixesHelp": "مثال: بالنسبة للبادئة \"the\"، سيتم فرز عنوان الكتاب \"The Book Title\" كـ \"Book Title, The\"",
+ "LabelSettingsSquareBookCovers": "استخدام أغلفة كتب مربعة",
+ "LabelSettingsSquareBookCoversHelp": "تفضيل استخدام الأغلفة المربعة على أغلفة الكتب القياسية بنسبة 1.6:1",
+ "LabelSettingsStoreCoversWithItem": "تخزين الأغلفة مع العنصر",
+ "LabelSettingsStoreCoversWithItemHelp": "بشكل افتراضي، يتم تخزين الأغلفة في /metadata/items، وسيؤدي تمكين هذا الإعداد إلى تخزين الأغلفة في مجلد عنصر المكتبة الخاص بك. سيتم الاحتفاظ بملف واحد فقط باسم \"cover\"",
+ "LabelSettingsStoreMetadataWithItem": "تخزين البيانات الوصفية مع العنصر",
+ "LabelSettingsStoreMetadataWithItemHelp": "بشكل افتراضي، يتم تخزين ملفات البيانات الوصفية في /metadata/items، وسيؤدي تمكين هذا الإعداد إلى تخزين ملفات البيانات الوصفية في مجلدات عناصر المكتبة الخاصة بك",
+ "LabelSettingsTimeFormat": "تنسيق الوقت",
+ "LabelShare": "مشاركة",
+ "LabelShareDownloadableHelp": "يسمح للمستخدمين الذين لديهم رابط المشاركة بتنزيل ملف مضغوط لعنصر المكتبة.",
+ "LabelShareOpen": "فتح المشاركة",
+ "LabelShareURL": "رابط المشاركة",
+ "LabelShowAll": "إظهار الكل",
+ "LabelShowSeconds": "إظهار الثواني",
+ "LabelShowSubtitles": "إظهار الترجمة",
"LabelSize": "الحجم",
"LabelSleepTimer": "مؤقت النوم",
+ "LabelSlug": "اسم تعريفي سهل القراءة",
+ "LabelSortAscending": "تصاعدي",
+ "LabelSortDescending": "تنازلي",
+ "LabelSortPubDate": "فرز حسب تاريخ النشر",
"LabelStart": "ابدأ",
+ "LabelStartTime": "وقت البدء",
+ "LabelStarted": "بدأ",
+ "LabelStartedAt": "بدأ في",
+ "LabelStatsAudioTracks": "مسارات الصوت",
+ "LabelStatsAuthors": "المؤلفون",
"LabelStatsBestDay": "أفضل يوم",
"LabelStatsDailyAverage": "المتوسط اليومي",
- "LabelStatsDays": "أيام"
+ "LabelStatsDays": "أيام",
+ "LabelStatsDaysListened": "أيام الاستماع",
+ "LabelStatsHours": "ساعات",
+ "LabelStatsInARow": "على التوالي",
+ "LabelStatsItemsFinished": "العناصر المنتهية",
+ "LabelStatsItemsInLibrary": "العناصر في المكتبة",
+ "LabelStatsMinutes": "دقائق",
+ "LabelStatsMinutesListening": "دقائق الاستماع",
+ "LabelStatsOverallDays": "إجمالي الأيام",
+ "LabelStatsOverallHours": "إجمالي الساعات",
+ "LabelStatsWeekListening": "استماع هذا الأسبوع",
+ "LabelSubtitle": "عنوان فرعي / ترجمة",
+ "LabelSupportedFileTypes": "أنواع الملفات المدعومة",
+ "LabelTag": "علامة",
+ "LabelTags": "علامات",
+ "LabelTagsAccessibleToUser": "العلامات المتاحة للمستخدم",
+ "LabelTagsNotAccessibleToUser": "العلامات غير المتاحة للمستخدم",
+ "LabelTasks": "المهام قيد التشغيل",
+ "LabelTextEditorBulletedList": "قائمة نقطية",
+ "LabelTextEditorLink": "رابط",
+ "LabelTextEditorNumberedList": "قائمة مرقمة",
+ "LabelTextEditorUnlink": "إزالة الرابط",
+ "LabelTheme": "النمط",
+ "LabelThemeDark": "غامق",
+ "LabelThemeLight": "فاتح",
+ "LabelTimeBase": "قاعدة الوقت",
+ "LabelTimeDurationXHours": "{0} ساعات",
+ "LabelTimeDurationXMinutes": "{0} دقائق",
+ "LabelTimeDurationXSeconds": "{0} ثواني",
+ "LabelTimeInMinutes": "الوقت بالدقائق",
+ "LabelTimeLeft": "باقي {0}",
+ "LabelTimeListened": "الوقت المستمع إليه",
+ "LabelTimeListenedToday": "الوقت المستمع إليه اليوم",
+ "LabelTimeRemaining": "{0} متبقية",
+ "LabelTimeToShift": "الوقت المراد إزاحته بالثواني",
+ "LabelTitle": "عنوان",
+ "LabelToolsEmbedMetadata": "تضمين البيانات الوصفية",
+ "LabelToolsEmbedMetadataDescription": "تضمين البيانات الوصفية في ملفات الصوت بما في ذلك صورة الغلاف والفصول.",
+ "LabelToolsM4bEncoder": "ترميز M4B",
+ "LabelToolsMakeM4b": "إنشاء ملف كتاب صوتي M4B",
+ "LabelToolsMakeM4bDescription": "إنشاء ملف كتاب صوتي .M4B مع بيانات وصفية مضمنة وصورة غلاف وفصول.",
+ "LabelToolsSplitM4b": "تقسيم M4B إلى ملفات MP3",
+ "LabelToolsSplitM4bDescription": "إنشاء ملفات MP3 من ملف M4B مقسم حسب الفصول مع بيانات وصفية مضمنة وصورة غلاف وفصول.",
+ "LabelTotalDuration": "المدة الكلية",
+ "LabelTotalTimeListened": "إجمالي وقت الاستماع",
+ "LabelTrackFromFilename": "المسار من اسم الملف",
+ "LabelTrackFromMetadata": "المسار من البيانات الوصفية",
+ "LabelTracks": "المسارات",
+ "LabelTracksMultiTrack": "متعدد المسارات",
+ "LabelTracksNone": "لا توجد مسارات",
+ "LabelTracksSingleTrack": "مسار واحد",
+ "LabelTrailer": "مقطع دعائي",
+ "LabelType": "نوع",
+ "LabelUnabridged": "غير مختصر",
+ "LabelUndo": "تراجع",
+ "LabelUnknown": "مجهول",
+ "LabelUnknownPublishDate": "تاريخ النشر مجهول",
+ "LabelUpdateCover": "تحديث الغلاف",
+ "LabelUpdateCoverHelp": "السماح باستبدال الأغلفة الموجودة للكتب المحددة عند العثور على تطابق",
+ "LabelUpdateDetails": "تحديث التفاصيل",
+ "LabelUpdateDetailsHelp": "السماح باستبدال التفاصيل الموجودة للكتب المحددة عند العثور على تطابق",
+ "LabelUpdatedAt": "تاريخ التحديث",
+ "LabelUploaderDragAndDrop": "اسحب وأفلت الملفات أو المجلدات",
+ "LabelUploaderDragAndDropFilesOnly": "اسحب وأفلت الملفات",
+ "LabelUploaderDropFiles": "إفلات الملفات",
+ "LabelUploaderItemFetchMetadataHelp": "جلب العنوان والمؤلف والسلسلة تلقائيًا",
+ "LabelUseAdvancedOptions": "استخدام الخيارات المتقدمة",
+ "LabelUseChapterTrack": "استخدام مسار الفصل",
+ "LabelUseFullTrack": "استخدام المسار الكامل",
+ "LabelUseZeroForUnlimited": "استخدم 0 لغير محدود",
+ "LabelUser": "مستخدم",
+ "LabelUsername": "اسم المستخدم",
+ "LabelValue": "القيمة",
+ "LabelVersion": "الإصدار",
+ "LabelViewBookmarks": "عرض الإشارات المرجعية",
+ "LabelViewChapters": "عرض الفصول",
+ "LabelViewPlayerSettings": "عرض إعدادات المشغل",
+ "LabelViewQueue": "عرض قائمة انتظار المشغل",
+ "LabelVolume": "مستوى الصوت",
+ "LabelWebRedirectURLsDescription": "قم بتخويل عناوين URL هذه في موفر OAuth الخاص بك للسماح بإعادة التوجيه إلى تطبيق الويب بعد تسجيل الدخول:",
+ "LabelWebRedirectURLsSubfolder": "مجلد فرعي لعناوين URL لإعادة التوجيه",
+ "LabelWeekdaysToRun": "أيام الأسبوع المراد التشغيل فيها",
+ "LabelXBooks": "{0} كتب",
+ "LabelXItems": "{0} عناصر",
+ "LabelYearReviewHide": "إخفاء ملخص العام",
+ "LabelYearReviewShow": "عرض ملخص العام",
+ "LabelYourAudiobookDuration": "مدة كتابك الصوتي",
+ "LabelYourBookmarks": "علاماتك المرجعية",
+ "LabelYourPlaylists": "قوائم التشغيل الخاصة بك",
+ "LabelYourProgress": "تقدمك",
+ "MessageAddToPlayerQueue": "إضافة إلى قائمة انتظار المشغل",
+ "MessageAppriseDescription": "لاستخدام هذه الميزة، ستحتاج إلى تشغيل مثيل Apprise API أو واجهة برمجة تطبيقات تتعامل مع نفس الطلبات. http://192.168.1.1:8337
، فستضع http://192.168.1.1:8337/notify
.",
+ "MessageAsinCheck": "تأكد من أنك تستخدم ASIN من منطقة Audible الصحيحة، وليس Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "أعد تشغيل الخادم بعد الحفظ لتطبيق تغييرات OIDC.",
+ "MessageBackupsDescription": "تتضمن النسخ الاحتياطية المستخدمين وتقدم المستخدم وتفاصيل عنصر المكتبة وإعدادات الخادم والصور المخزنة في /metadata/items
و /metadata/authors
. لا تتضمن النسخ الاحتياطية أي ملفات مخزنة في مجلدات مكتبتك.",
+ "MessageBackupsLocationEditNote": "ملاحظة: لن يؤدي تحديث موقع النسخ الاحتياطي إلى نقل أو تعديل النسخ الاحتياطية الموجودة",
+ "MessageBackupsLocationNoEditNote": "ملاحظة: يتم تعيين موقع النسخ الاحتياطي من خلال متغير بيئة ولا يمكن تغييره هنا.",
+ "MessageBackupsLocationPathEmpty": "لا يمكن أن يكون مسار موقع النسخ الاحتياطي فارغًا",
+ "MessageBatchEditPopulateMapDetailsAllHelp": "املأ الحقول الممكّنة ببيانات من جميع العناصر. سيتم دمج الحقول ذات القيم المتعددة",
+ "MessageBatchEditPopulateMapDetailsItemHelp": "املأ حقول تفاصيل الخريطة الممكّنة ببيانات من هذا العنصر",
+ "MessageBatchQuickMatchDescription": "ستحاول المطابقة السريعة إضافة الأغلفة والبيانات الوصفية المفقودة للعناصر المحددة. قم بتمكين الخيارات أدناه للسماح للمطابقة السريعة بالكتابة فوق الأغلفة و/أو البيانات الوصفية الموجودة.",
+ "MessageBookshelfNoCollections": "لم تنشئ أي مجموعات حتى الآن",
+ "MessageBookshelfNoCollectionsHelp": "المجموعات عامة. يمكن لجميع المستخدمين الذين لديهم حق الوصول إلى المكتبة رؤيتها.",
+ "MessageBookshelfNoRSSFeeds": "لا توجد خلاصات RSS مفتوحة",
+ "MessageBookshelfNoResultsForFilter": "لا توجد نتائج للفلتر \"{0}: {1}\"",
+ "MessageBookshelfNoResultsForQuery": "لا توجد نتائج للاستعلام",
+ "MessageBookshelfNoSeries": "ليس لديك أي مسلسلات",
+ "MessageChapterEndIsAfter": "نهاية الفصل بعد نهاية كتابك الصوتي",
+ "MessageChapterErrorFirstNotZero": "يجب أن يبدأ الفصل الأول عند 0",
+ "MessageChapterErrorStartGteDuration": "يجب أن يكون وقت البدء غير الصالح أقل من مدة الكتاب الصوتي",
+ "MessageChapterErrorStartLtPrev": "يجب أن يكون وقت البدء غير الصالح أكبر من أو يساوي وقت بدء الفصل السابق",
+ "MessageChapterStartIsAfter": "بداية الفصل بعد نهاية كتابك الصوتي",
+ "MessageChaptersNotFound": "لم يتم العثور على فصول",
+ "MessageCheckingCron": "جارٍ فحص cron...",
+ "MessageConfirmCloseFeed": "هل أنت متأكد أنك تريد إغلاق هذه التغذية؟",
+ "MessageConfirmDeleteBackup": "هل أنت متأكد أنك تريد حذف النسخ الاحتياطي لـ {0}؟",
+ "MessageConfirmDeleteDevice": "هل أنت متأكد أنك تريد حذف جهاز القارئ الإلكتروني \"{0}\"؟",
+ "MessageConfirmDeleteFile": "سيؤدي هذا إلى حذف الملف من نظام الملفات الخاص بك. هل أنت متأكد؟",
+ "MessageConfirmDeleteLibrary": "هل أنت متأكد أنك تريد حذف المكتبة \"{0}\" نهائيًا؟",
+ "MessageConfirmDeleteLibraryItem": "سيؤدي هذا إلى حذف عنصر المكتبة من قاعدة البيانات ونظام الملفات الخاص بك. هل أنت متأكد؟",
+ "MessageConfirmDeleteLibraryItems": "سيؤدي هذا إلى حذف {0} عنصرًا من عناصر المكتبة من قاعدة البيانات ونظام الملفات الخاص بك. هل أنت متأكد؟",
+ "MessageConfirmDeleteMetadataProvider": "هل أنت متأكد أنك تريد حذف مزود البيانات الوصفية المخصص \"{0}\"؟",
+ "MessageConfirmDeleteNotification": "هل أنت متأكد أنك تريد حذف هذا الإشعار؟",
+ "MessageConfirmDeleteSession": "هل أنت متأكد أنك تريد حذف هذه الجلسة؟",
+ "MessageConfirmEmbedMetadataInAudioFiles": "هل أنت متأكد أنك تريد تضمين البيانات الوصفية في {0} ملفًا صوتيًا؟",
+ "MessageConfirmForceReScan": "هل أنت متأكد أنك تريد فرض إعادة الفحص؟",
+ "MessageConfirmMarkAllEpisodesFinished": "هل أنت متأكد أنك تريد تعليم جميع الحلقات على أنها منتهية؟",
+ "MessageConfirmMarkAllEpisodesNotFinished": "هل أنت متأكد أنك تريد تعليم جميع الحلقات على أنها غير منتهية؟",
+ "MessageConfirmMarkItemFinished": "هل أنت متأكد أنك تريد تعليم \"{0}\" على أنه منتهٍ؟",
+ "MessageConfirmMarkItemNotFinished": "هل أنت متأكد أنك تريد تعليم \"{0}\" على أنه غير منتهٍ؟",
+ "MessageConfirmMarkSeriesFinished": "هل أنت متأكد أنك تريد تعليم جميع الكتب في هذه السلسلة على أنها منتهية؟",
+ "MessageConfirmMarkSeriesNotFinished": "هل أنت متأكد أنك تريد تعليم جميع الكتب في هذه السلسلة على أنها غير منتهية؟",
+ "MessageConfirmNotificationTestTrigger": "هل تريد تشغيل هذا الإشعار ببيانات اختبار؟",
+ "MessageConfirmPurgeCache": "سيؤدي مسح ذاكرة التخزين المؤقت إلى حذف الدليل بأكمله في /metadata/cache
. /metadata/cache/items
/metadata/logs
كملفات JSON. يتم تخزين سجلات الأعطال في /metadata/logs/crash_logs.txt
.",
+ "MessageM4BFailed": "فشل M4B!",
+ "MessageM4BFinished": "تم الانتهاء من M4B!",
+ "MessageMapChapterTitles": "ربط عناوين الفصول بفصول كتابك الصوتي الحالي دون تعديل الطوابع الزمنية",
+ "MessageMarkAllEpisodesFinished": "تعليم جميع الحلقات على أنها منتهية",
+ "MessageMarkAllEpisodesNotFinished": "تعليم جميع الحلقات على أنها غير منتهية",
+ "MessageMarkAsFinished": "وضع علامة \"تم الإنتهاء\"",
+ "MessageMarkAsNotFinished": "وضع علامة \"غير منته\"",
+ "MessageMatchBooksDescription": "سيحاول مطابقة الكتب في المكتبة مع كتاب من مزود البحث المحدد وملء التفاصيل الفارغة وصورة الغلاف. لا يستبدل التفاصيل الموجودة.",
+ "MessageNoAudioTracks": "لا توجد مسارات صوتية",
+ "MessageNoAuthors": "لا يوجد مؤلفون",
+ "MessageNoBackups": "لا توجد نسخ احتياطية",
+ "MessageNoBookmarks": "لا توجد علامات مرجعية",
+ "MessageNoChapters": "لا توجد فصول",
+ "MessageNoCollections": "لا توجد مجموعات",
+ "MessageNoCoversFound": "لم يتم العثور على أغلفة",
+ "MessageNoDescription": "لا يوجد وصف",
+ "MessageNoDevices": "لا توجد أجهزة",
+ "MessageNoDownloadsInProgress": "لا توجد تنزيلات قيد التقدم حاليًا",
+ "MessageNoDownloadsQueued": "لا توجد تنزيلات في قائمة الانتظار",
+ "MessageNoEpisodeMatchesFound": "لم يتم العثور على أي تطابقات للحلقات",
+ "MessageNoEpisodes": "لا توجد حلقات",
+ "MessageNoFoldersAvailable": "لا توجد مجلدات متاحة",
+ "MessageNoGenres": "لا توجد تصانيف",
+ "MessageNoIssues": "لا توجد مشاكل",
+ "MessageNoItems": "لا توجد عناصر",
+ "MessageNoItemsFound": "لم يتم العثور على عناصر",
+ "MessageNoListeningSessions": "لا توجد جلسات استماع",
+ "MessageNoLogs": "لا توجد سجلات",
+ "MessageNoMediaProgress": "لا يوجد تقدم للوسائط",
+ "MessageNoNotifications": "لا توجد إشعارات",
+ "MessageNoPodcastFeed": "بودكاست غير صالح: لا يوجد تغذية",
+ "MessageNoPodcastsFound": "لم يتم العثور على أي بودكاست",
+ "MessageNoResults": "لا توجد نتائج",
+ "MessageNoSearchResultsFor": "لا توجد نتائج بحث عن \"{0}\"",
+ "MessageNoSeries": "لا توجد مسلسلات",
+ "MessageNoTags": "لا توجد علامات",
+ "MessageNoTasksRunning": "لا توجد مهام قيد التشغيل",
+ "MessageNoUpdatesWereNecessary": "لا حاجة لأي تحديثات",
+ "MessageNoUserPlaylists": "ليس لديك أي قوائم تشغيل",
+ "MessageNoUserPlaylistsHelp": "قوائم التشغيل خاصة. لا يمكن إلا للمستخدم الذي ينشئها رؤيتها.",
+ "MessageNotYetImplemented": "لم يتم تنفيذه بعد",
+ "MessageOpmlPreviewNote": "ملاحظة: هذه معاينة لملف OPML الذي تم تحليله. سيتم أخذ عنوان البودكاست الفعلي من خلاصة RSS.",
+ "MessageOr": "أو",
+ "MessagePauseChapter": "إيقاف تشغيل الفصل مؤقتًا",
+ "MessagePlayChapter": "الاستماع إلى بداية الفصل",
+ "MessagePlaylistCreateFromCollection": "إنشاء قائمة تشغيل من المجموعة",
+ "MessagePleaseWait": "الرجاء الانتظار...",
+ "MessagePodcastHasNoRSSFeedForMatching": "لا يحتوي البودكاست على عنوان URL لخلاصة RSS لاستخدامه في المطابقة",
+ "MessagePodcastSearchField": "أدخل مصطلح البحث أو عنوان URL الخاص بتغذية RSS",
+ "MessageQuickEmbedInProgress": "التضمين السريع قيد التقدم",
+ "MessageQuickEmbedQueue": "تمت إضافته إلى قائمة انتظار التضمين السريع ({0} في قائمة الانتظار)",
+ "MessageQuickMatchAllEpisodes": "مطابقة سريعة لجميع الحلقات",
+ "MessageQuickMatchDescription": "املأ تفاصيل العنصر الفارغة والغلاف بأول نتيجة مطابقة من '{0}'. لا يستبدل التفاصيل إلا إذا تم تمكين إعداد الخادم 'تفضيل البيانات الوصفية المطابقة'.",
+ "MessageRemoveChapter": "إزالة الفصل",
+ "MessageRemoveEpisodes": "إزالة {0} حلقة (حلقات)",
+ "MessageRemoveFromPlayerQueue": "إزالة من قائمة انتظار المشغل",
+ "MessageRemoveUserWarning": "هل أنت متأكد أنك تريد حذف المستخدم \"{0}\" نهائيًا؟",
+ "MessageReportBugsAndContribute": "أبلغ عن الأخطاء، واطلب الميزات، وساهم في",
+ "MessageResetChaptersConfirm": "هل أنت متأكد أنك تريد إعادة تعيين الفصول والتراجع عن التغييرات التي أجريتها؟",
+ "MessageRestoreBackupConfirm": "هل أنت متأكد أنك تريد استعادة النسخ الاحتياطي الذي تم إنشاؤه في",
+ "MessageRestoreBackupWarning": "ستؤدي استعادة النسخ الاحتياطي إلى الكتابة فوق قاعدة البيانات بأكملها الموجودة في /config وصور الأغلفة في /metadata/items و /metadata/authors.groups
. Ако е конфигурирано, приложението автоматично ще присвоява роли въз основа на членството на потребителя в групи, при условие че тези групи са наименувани без чувствителност към регистъра като 'admin', 'user' или 'guest' в твърдението. Твърдението трябва да съдържа списък и ако потребителят принадлежи към множество групи, приложението ще присвои ролята, съответстваща на най-високото ниво на достъп. Ако няма съвпадение с група, достъпът ще бъде отказан.",
"LabelOpenRSSFeed": "Отвори RSS Feed",
"LabelOverwrite": "Презапиши",
+ "LabelPaginationPageXOfY": "Страница {0} от {1}",
"LabelPassword": "Парола",
"LabelPath": "Път",
+ "LabelPermanent": "Постоянен",
"LabelPermissionsAccessAllLibraries": "Може да достъпи до всички библиотеки",
"LabelPermissionsAccessAllTags": "Може да достъпи всички тагове",
"LabelPermissionsAccessExplicitContent": "Може да достъпи експлицитно съдържание",
+ "LabelPermissionsCreateEreader": "Може да създава електронен четец",
"LabelPermissionsDelete": "Може да трие",
"LabelPermissionsDownload": "Може да сваля",
"LabelPermissionsUpdate": "Може да обновява",
@@ -461,6 +490,8 @@
"LabelPersonalYearReview": "Преглед на годината Ви ({0})",
"LabelPhotoPathURL": "Път/URL на Снимка",
"LabelPlayMethod": "Метод на Пускане",
+ "LabelPlaybackRateIncrementDecrement": "Размер на увеличаване/намаляне при скоростта на възпроизвеждане",
+ "LabelPlayerChapterNumberMarker": "{0} от {1}",
"LabelPlaylists": "Плейлисти",
"LabelPodcast": "Подкаст",
"LabelPodcastSearchRegion": "Регион за Търсене на Подкасти",
@@ -472,9 +503,12 @@
"LabelPrimaryEbook": "Основна Електронна Книга",
"LabelProgress": "Прогрес",
"LabelProvider": "Доставчик",
+ "LabelProviderAuthorizationValue": "Стойност на Authorization Header",
"LabelPubDate": "Дата на публикуване",
"LabelPublishYear": "Година на публикуване",
"LabelPublishedDate": "Публикувани {0}",
+ "LabelPublishedDecade": "Десетилетие на публикуване",
+ "LabelPublishedDecades": "Десетилетия на публикуване",
"LabelPublisher": "Издател",
"LabelPublishers": "Издателство",
"LabelRSSFeedCustomOwnerEmail": "Персонализиран имейл на собственика",
@@ -484,6 +518,7 @@
"LabelRSSFeedSlug": "идентификатор на RSS емисия",
"LabelRSSFeedURL": "URL на RSS емисия",
"LabelRandomly": "Случайно",
+ "LabelReAddSeriesToContinueListening": "Добави отново в \"Продължете да слушате\"",
"LabelRead": "Прочети",
"LabelReadAgain": "Прочети отново",
"LabelReadEbookWithoutProgress": "Прочети електронната книга без записване прогрес",
@@ -493,29 +528,40 @@
"LabelRedo": "Повтори",
"LabelRegion": "Регион",
"LabelReleaseDate": "Дата на Издаване",
+ "LabelRemoveAllMetadataAbs": "Премахни всички metadata.abs файлове",
+ "LabelRemoveAllMetadataJson": "Премахни всички metadata.json файлове",
+ "LabelRemoveAudibleBranding": "Премахни въведението и заключението на Audible от главите",
"LabelRemoveCover": "Премахни Корица",
+ "LabelRemoveMetadataFile": "Премахни файловете с метаданни от папката на библиотеката",
+ "LabelRemoveMetadataFileHelp": "Премахни всички metadata.json и metadata.abs файлове от вашата {0} папка.",
"LabelRowsPerPage": "Редове на Страница",
"LabelSearchTerm": "Търси Термин",
"LabelSearchTitle": "Търси Заглавие",
"LabelSearchTitleOrASIN": "Търси Заглавие или ASIN",
"LabelSeason": "Сезон",
+ "LabelSeasonNumber": "Сезон #{0}",
"LabelSelectAll": "Избери всичко",
"LabelSelectAllEpisodes": "Избери всички епизоди",
"LabelSelectEpisodesShowing": "Избери {0} епизоди показани",
"LabelSelectUsers": "Избери Потребители",
"LabelSendEbookToDevice": "Изпрати електронна книга до ...",
"LabelSequence": "Последователност",
+ "LabelSerial": "Сериал",
"LabelSeries": "От сериите",
"LabelSeriesName": "Име на Серия",
"LabelSeriesProgress": "Прогрес на Серия",
+ "LabelServerLogLevel": "Ниво на сървърен журнал",
"LabelServerYearReview": "Преглед на годината на сървъра ({0})",
"LabelSetEbookAsPrimary": "Направи главен",
"LabelSetEbookAsSupplementary": "Направи второстепенен",
+ "LabelSettingsAllowIframe": "Разреши вграждане в iframe",
"LabelSettingsAudiobooksOnly": "Само аудиокниги",
"LabelSettingsAudiobooksOnlyHelp": "Активирането на тази настройка ще игнорира файловете на електронни книги, освен ако не са в папка с аудиокниги, в което случай ще бъдат зададени като допълнителни електронни книги",
"LabelSettingsBookshelfViewHelp": "Скеуморфен дизайн с дървени рафтове",
"LabelSettingsChromecastSupport": "Chromecast поддръжка",
"LabelSettingsDateFormat": "Формат на Дата",
+ "LabelSettingsEnableWatcher": "Автоматично сканиране на библиотеките за промени",
+ "LabelSettingsEnableWatcherForLibrary": "Автоматично сканиране на библиотеката за промени",
"LabelSettingsEnableWatcherHelp": "Включва автоматичното добавяне/обновяване на елементи, когато се открият промени във файловете. *Изисква рестарт на сървъра",
"LabelSettingsEpubsAllowScriptedContent": "Позволи скриптово съдържание в epub-и",
"LabelSettingsEpubsAllowScriptedContentHelp": "Позволи epub файловете да изпълняват скриптове. Препоръчително е да бъде изключено освен ако не се доверявате на източника на epub файловете.",
@@ -527,10 +573,13 @@
"LabelSettingsHideSingleBookSeriesHelp": "Сериите с една книга ще бъдат скрити от страницата на серията и рафтовете на началната страница.",
"LabelSettingsHomePageBookshelfView": "Начална страница изглед на рафт",
"LabelSettingsLibraryBookshelfView": "Библиотека изглед на рафт",
+ "LabelSettingsLibraryMarkAsFinishedPercentComplete": "Процент завършеност е по-голям от",
+ "LabelSettingsLibraryMarkAsFinishedTimeRemaining": "Оставащо време е по-малко от (секунди)",
+ "LabelSettingsLibraryMarkAsFinishedWhen": "Отбелязване на мултимедиен елемент като завършен когато",
"LabelSettingsOnlyShowLaterBooksInContinueSeries": "Пропусни предишни книги в Продължи Поредица",
"LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "Рафтът на началната страница 'Продължи поредицата' показва първата книга, която не е започната в поредици, в които има поне една завършена книга и няма книги в процес на четене. Активирането на тази настройка ще продължи поредицата от най-далечната завършена книга вместо от първата незапочната книга.",
"LabelSettingsParseSubtitles": "Извлечи подзаглавия",
- "LabelSettingsParseSubtitlesHelp": "Извлича подзаглавия от имената на папките на аудиокнигите. audiobookshelf
, que pots eliminar o complementar amb URI addicionals per a la integració d'aplicacions de tercers. Usant un asterisc ( *
) com a única entrada que permet qualsevol URI.",
@@ -497,25 +498,25 @@
"LabelPodcastType": "Tipus de pòdcast",
"LabelPodcasts": "Pòdcasts",
"LabelPort": "Port",
- "LabelPrefixesToIgnore": "Prefixos per Ignorar (no distingeix entre majúscules i minúscules.)",
+ "LabelPrefixesToIgnore": "Prefixos a ignorar (no distingeix entre majúscules i minúscules)",
"LabelPreventIndexing": "Evita que el vostre canal l'indexin els directoris de pòdcasts de l'iTunes i Google",
- "LabelPrimaryEbook": "Ebook Principal",
+ "LabelPrimaryEbook": "Llibre electrònic principal",
"LabelProgress": "Progrés",
"LabelProvider": "Proveïdor",
"LabelProviderAuthorizationValue": "Valor de l'encapçalament d'autorització",
- "LabelPubDate": "Data de Publicació",
- "LabelPublishYear": "Any de Publicació",
+ "LabelPubDate": "Data de publicació",
+ "LabelPublishYear": "Any de publicació",
"LabelPublishedDate": "Publicat {0}",
- "LabelPublishedDecade": "Dècada de Publicació",
+ "LabelPublishedDecade": "Dècada de publicació",
"LabelPublishedDecades": "Dècades Publicades",
"LabelPublisher": "Editor",
"LabelPublishers": "Editors",
"LabelRSSFeedCustomOwnerEmail": "Correu Electrònic Personalitzat del Propietari",
"LabelRSSFeedCustomOwnerName": "Nom Personalitzat del Propietari",
"LabelRSSFeedOpen": "Font RSS Oberta",
- "LabelRSSFeedPreventIndexing": "Evitar l'indexació",
- "LabelRSSFeedSlug": "Font RSS Slug",
- "LabelRSSFeedURL": "URL de la Font RSS",
+ "LabelRSSFeedPreventIndexing": "Evita la indexació",
+ "LabelRSSFeedSlug": "URL semàntic del canal RSS",
+ "LabelRSSFeedURL": "URL del canal RSS",
"LabelRandomly": "A l'atzar",
"LabelReAddSeriesToContinueListening": "Reafegir la sèrie per continuar escoltant-la",
"LabelRead": "Llegit",
@@ -524,45 +525,47 @@
"LabelRecentSeries": "Sèries recents",
"LabelRecentlyAdded": "Addicions recents",
"LabelRecommended": "Recomanats",
- "LabelRedo": "Refer",
+ "LabelRedo": "Refés",
"LabelRegion": "Regió",
- "LabelReleaseDate": "Data d'Estrena",
- "LabelRemoveAllMetadataAbs": "Eliminar tots els fitxers metadata.abs",
- "LabelRemoveAllMetadataJson": "Eliminar tots els fitxers metadata.json",
- "LabelRemoveCover": "Eliminar Coberta",
+ "LabelReleaseDate": "Data d'estrena",
+ "LabelRemoveAllMetadataAbs": "Elimina tots els fitxers metadata.abs",
+ "LabelRemoveAllMetadataJson": "Elimina tots els fitxers metadata.json",
+ "LabelRemoveAudibleBranding": "Elimina la introducció i el tancament de l'Audible dels capítols",
+ "LabelRemoveCover": "Elimina la coberta",
"LabelRemoveMetadataFile": "Eliminar fitxers de metadades en carpetes d'elements de biblioteca",
- "LabelRemoveMetadataFileHelp": "Elimina tots els fitxers metadata.json i metadata.abs de les teves carpetes {0}.",
- "LabelRowsPerPage": "Files per Pàgina",
- "LabelSearchTerm": "Cercar Terme",
- "LabelSearchTitle": "Cercar Títol",
- "LabelSearchTitleOrASIN": "Cercar Títol o ASIN",
+ "LabelRemoveMetadataFileHelp": "Elimina tots els fitxers metadata.json i metadata.abs de les vostres carpetes {0}.",
+ "LabelRowsPerPage": "Files per pàgina",
+ "LabelSearchTerm": "Cerca terme",
+ "LabelSearchTitle": "Cerca títol",
+ "LabelSearchTitleOrASIN": "Cerca títol o ASIN",
"LabelSeason": "Temporada",
- "LabelSeasonNumber": "Temporada #{0}",
- "LabelSelectAll": "Seleccionar tot",
- "LabelSelectAllEpisodes": "Seleccionar tots els episodis",
+ "LabelSeasonNumber": "{0}a temporada",
+ "LabelSelectAll": "Selecciona-ho tot",
+ "LabelSelectAllEpisodes": "Selecciona tots els episodis",
"LabelSelectEpisodesShowing": "Seleccionar els {0} episodis visibles",
"LabelSelectUsers": "Seleccionar usuaris",
"LabelSendEbookToDevice": "Enviar Ebook a...",
"LabelSequence": "Seqüència",
"LabelSerial": "En sèrie",
- "LabelSeries": "Sèries",
- "LabelSeriesName": "Nom de la Sèrie",
- "LabelSeriesProgress": "Progrés de la Sèrie",
+ "LabelSeries": "Sèrie",
+ "LabelSeriesName": "Nom de la sèrie",
+ "LabelSeriesProgress": "Progrés de la sèrie",
"LabelServerLogLevel": "Nivell de registre del servidor",
"LabelServerYearReview": "Resum de l'any del servidor ({0})",
"LabelSetEbookAsPrimary": "Establir com a principal",
"LabelSetEbookAsSupplementary": "Establir com a suplementari",
- "LabelSettingsAudiobooksOnly": "Només Audiollibres",
- "LabelSettingsAudiobooksOnlyHelp": "Activant aquesta opció s'ignoraran els fitxers d'ebook, excepte si estan dins d'una carpeta d'audiollibre, en aquest cas es marcaran com ebooks suplementaris",
+ "LabelSettingsAudiobooksOnly": "Només audiollibres",
+ "LabelSettingsAudiobooksOnlyHelp": "En activar aquesta opció s'ignoraran els fitxers de llibre electrònic, excepte si estan dins d'una carpeta d'audiollibre; en aquest cas es marcaran com a llibres suplementaris",
"LabelSettingsBookshelfViewHelp": "Disseny esqueomorf amb prestatgeries de fusta",
"LabelSettingsChromecastSupport": "Compatibilitat amb Chromecast",
- "LabelSettingsDateFormat": "Format de Data",
+ "LabelSettingsDateFormat": "Format de data",
"LabelSettingsEnableWatcherHelp": "Permet afegir/actualitzar elements automàticament quan es detectin canvis en els fitxers. *Requereix reiniciar el servidor",
"LabelSettingsEpubsAllowScriptedContent": "Permetre scripts en epubs",
"LabelSettingsEpubsAllowScriptedContentHelp": "Permetre que els fitxers epub executin scripts. Es recomana mantenir aquesta opció desactivada tret que confiïs en l'origen dels fitxers epub.",
"LabelSettingsExperimentalFeatures": "Funcions Experimentals",
"LabelSettingsExperimentalFeaturesHelp": "Funcions en desenvolupament que es beneficiarien dels teus comentaris i experiències de prova. Feu clic aquí per obrir una conversa a Github.",
"LabelSettingsFindCovers": "Troba cobertes",
+ "LabelSettingsHideSingleBookSeries": "Amaga les sèries amb un sol llibre",
"LabelSettingsParseSubtitles": "Analitza els subtítols",
"LabelSettingsSortingIgnorePrefixes": "Ignora els prefixos en ordenar",
"LabelSettingsTimeFormat": "Format d'hora",
@@ -575,6 +578,8 @@
"LabelSize": "Mida",
"LabelSleepTimer": "Temporitzador de repòs",
"LabelSlug": "Slug",
+ "LabelSortAscending": "Ascendent",
+ "LabelSortDescending": "Descendent",
"LabelStart": "Inicia",
"LabelStartTime": "Hora d'inici",
"LabelStarted": "Iniciat",
@@ -662,19 +667,20 @@
"LabelViewPlayerSettings": "Mostra els ajustaments del reproductor",
"LabelViewQueue": "Mostra cua del reproductor",
"LabelVolume": "Volum",
- "LabelWebRedirectURLsDescription": "Autoritza aquestes URL al teu proveïdor OAuth per permetre redirecció a l'aplicació web després d'iniciar sessió:",
+ "LabelWebRedirectURLsDescription": "Autoritzeu aquests URL al vostre proveïdor OAuth per a permetre redirigir a l’aplicació web després d'iniciar sessió:",
"LabelWebRedirectURLsSubfolder": "Subcarpeta per a URL de redirecció",
"LabelWeekdaysToRun": "Executar en dies de la setmana",
"LabelXBooks": "{0} llibres",
"LabelXItems": "{0} elements",
"LabelYearReviewHide": "Oculta resum de l'any",
"LabelYearReviewShow": "Mostra resum de l'any",
- "LabelYourAudiobookDuration": "Duració del teu audiollibre",
+ "LabelYourAudiobookDuration": "Duració del vostre audiollibre",
"LabelYourBookmarks": "Els vostres marcadors",
- "LabelYourPlaylists": "Les teves llistes",
+ "LabelYourPlaylists": "Les vostres llistes",
"LabelYourProgress": "El vostre progrés",
"MessageAddToPlayerQueue": "Afegeix a la cua del reproductor",
"MessageAppriseDescription": "Per utilitzar aquesta funció, hauràs de tenir l'API d'Apprise en funcionament o una API que gestioni resultats similars. http://192.168.1.1:8337
, llavors posaries http://192.168.1.1:8337/notify
.",
+ "MessageAuthenticationOIDCChangesRestart": "Reengegueu el servidor després de desar perquè s'hi apliquin els canvis d'OIDC.",
"MessageBackupsDescription": "Les còpies de seguretat inclouen: usuaris, progrés dels usuaris, detalls dels elements de la biblioteca, configuració del servidor i imatges a /metadata/items
i /metadata/authors
. Les còpies de seguretat NO inclouen cap fitxer guardat a la carpeta de la teva biblioteca.",
"MessageBackupsLocationEditNote": "Nota: Actualitzar la ubicació de la còpia de seguretat no mourà ni modificarà les còpies existents",
"MessageBackupsLocationNoEditNote": "Nota: La ubicació de la còpia de seguretat es defineix mitjançant una variable d'entorn i no es pot modificar aquí.",
@@ -685,7 +691,7 @@
"MessageBookshelfNoRSSFeeds": "Cap font RSS està oberta",
"MessageBookshelfNoResultsForFilter": "Cap resultat per al filtre «{0}: {1}»",
"MessageBookshelfNoResultsForQuery": "Cap resultat per a la consulta",
- "MessageBookshelfNoSeries": "No tens cap sèrie",
+ "MessageBookshelfNoSeries": "No teniu cap sèrie",
"MessageChapterEndIsAfter": "El final del capítol és després del final del teu audiollibre",
"MessageChapterErrorFirstNotZero": "El primer capítol ha de començar a 0",
"MessageChapterErrorStartGteDuration": "El temps d'inici no és vàlid: ha de ser inferior a la durada de l'audiollibre",
@@ -712,7 +718,7 @@
"MessageConfirmMarkSeriesFinished": "Segur que voleu marcar tots els llibres d'aquesta sèrie com a acabats?",
"MessageConfirmMarkSeriesNotFinished": "Segur que voleu marcar tots els llibres d'aquesta sèrie com a no acabats?",
"MessageConfirmNotificationTestTrigger": "Voleu activar aquesta notificació amb dades de prova?",
- "MessageConfirmPurgeCache": "Esborrar la memòria cau eliminarà tot el directori localitzat a /metadata/cache
. /metadata/cache
. /metadata/cache/items
.http://192.168.1.1:8337
pak byste měli zadat http://192.168.1.1:8337/notify
.",
+ "MessageAsinCheck": "Ujistěte se, že používáte ASIN ze správného regionu Audible a ne z Amazonu.",
"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 /metadata/items
a /metadata/authors
. Zálohy ne 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",
"MessageBackupsLocationNoEditNote": "Poznámka: Umístění záloh je nastavené z proměnných prostředí a nelze zde změnit.",
@@ -723,6 +724,7 @@
"MessageChapterErrorStartGteDuration": "Neplatný čas začátku, musí být kratší než doba trvání audioknihy",
"MessageChapterErrorStartLtPrev": "Neplatný čas začátku, musí být větší nebo roven času začátku předchozí kapitoly",
"MessageChapterStartIsAfter": "Začátek kapitoly přesahuje konec audioknihy",
+ "MessageChaptersNotFound": "Kapitoly nenalezeny",
"MessageCheckingCron": "Kontrola cronu...",
"MessageConfirmCloseFeed": "Opravdu chcete zavřít tento kanál?",
"MessageConfirmDeleteBackup": "Opravdu chcete smazat zálohu pro {0}?",
@@ -779,6 +781,7 @@
"MessageForceReScanDescription": "znovu prohledá všechny soubory jako při novém skenování. ID3 tagy zvukových souborů OPF soubory a textové soubory budou skenovány jako nové.",
"MessageImportantNotice": "Důležité upozornění!",
"MessageInsertChapterBelow": "Vložit kapitolu níže",
+ "MessageInvalidAsin": "Neplatný ASIN",
"MessageItemsSelected": "{0} vybraných položek",
"MessageItemsUpdated": "{0} položky byly aktualizovány",
"MessageJoinUsOn": "Přidejte se k nám",
diff --git a/client/strings/de.json b/client/strings/de.json
index 6bddfc1f..55b33d8a 100644
--- a/client/strings/de.json
+++ b/client/strings/de.json
@@ -88,7 +88,7 @@
"ButtonSave": "Speichern",
"ButtonSaveAndClose": "Speichern & Schließen",
"ButtonSaveTracklist": "Speichere die Titelliste",
- "ButtonScan": "Partial-Scan (nur geänderte/neue Medien)",
+ "ButtonScan": "Scannen",
"ButtonScanLibrary": "Bibliothek scannen",
"ButtonScrollLeft": "Nach Links scrollen",
"ButtonScrollRight": "Nach Rechts scrollen",
@@ -177,6 +177,7 @@
"HeaderPlaylist": "Wiedergabeliste",
"HeaderPlaylistItems": "Einträge in der Wiedergabeliste",
"HeaderPodcastsToAdd": "Podcasts zum Hinzufügen",
+ "HeaderPresets": "Voreinstellungen",
"HeaderPreviewCover": "Vorschau Titelbild",
"HeaderRSSFeedGeneral": "RSS Details",
"HeaderRSSFeedIsOpen": "RSS-Feed ist geöffnet",
@@ -530,6 +531,7 @@
"LabelReleaseDate": "Veröffentlichungsdatum",
"LabelRemoveAllMetadataAbs": "Alle metadata.abs Dateien löschen",
"LabelRemoveAllMetadataJson": "Alle metadata.json Dateien löschen",
+ "LabelRemoveAudibleBranding": "Audible Intro sowie Outro aus Kapiteln entfernen",
"LabelRemoveCover": "Entferne Titelbild",
"LabelRemoveMetadataFile": "Metadaten-Dateien in Bibliotheksordnern löschen",
"LabelRemoveMetadataFileHelp": "Alle metadata.json und metadata.abs Dateien aus den Ordnern {0} löschen.",
@@ -706,6 +708,7 @@
"MessageAddToPlayerQueue": "Zur Abspielwarteliste hinzufügen",
"MessageAppriseDescription": "Um diese Funktion nutzen zu können, musst du eine Instanz von Apprise API laufen haben oder eine API verwenden welche dieselbe Anfragen bearbeiten kann. http://192.168.1.1:8337
läuft, würdest du http://192.168.1.1:8337/notify
eingeben.",
"MessageAsinCheck": "Stellen Sie sicher, dass Sie die ASIN aus der richtigen Audible Region verwenden, nicht Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "Nach dem Speichern muß der Server neugestartet werden um die OIDC Änderungen zu übernehmen.",
"MessageBackupsDescription": "In einer Sicherung werden Benutzer, Benutzerfortschritte, Details zu den Bibliotheksobjekten, Servereinstellungen und Bilder welche in /metadata/items
& /metadata/authors
gespeichert sind gespeichert. Sicherungen enthalten keine Dateien welche in den einzelnen Bibliotheksordnern (Medien-Ordnern) gespeichert sind.",
"MessageBackupsLocationEditNote": "Hinweis: Durch das Aktualisieren des Backup-Speicherorts werden vorhandene Sicherungen nicht verschoben oder geändert",
"MessageBackupsLocationNoEditNote": "Hinweis: Der Sicherungsspeicherort wird über eine Umgebungsvariable festgelegt und kann hier nicht geändert werden.",
@@ -853,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Immer {0} um {1} ausführen",
"MessageSearchResultsFor": "Suchergebnisse für",
"MessageSelected": "{0} ausgewählt",
+ "MessageSeriesSequenceCannotContainSpaces": "Serie Abfolge kann keine Leerzeichen enthalten",
"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",
"MessageShareExpirationWillBe": "Läuft am {0} ab",
@@ -971,6 +975,8 @@
"ToastCachePurgeFailed": "Cache leeren fehlgeschlagen",
"ToastCachePurgeSuccess": "Cache geleert",
"ToastChaptersHaveErrors": "Kapitel sind fehlerhaft",
+ "ToastChaptersInvalidShiftAmountLast": "Die Verschiebung ist nicht möglich, da die Startzeit des letzten Kapitels über die Gesamtdauer dieses Hörbuchs hinausgehen würde.",
+ "ToastChaptersInvalidShiftAmountStart": "Ungültige Höhe der Verschiebung. Das erste Kapitel hätte eine Länge von Null oder eine negative Länge und würde vom zweiten Kapitel überschrieben werden. Erhöhen Sie die Startdauer des zweiten Kapitels.",
"ToastChaptersMustHaveTitles": "Kapitel benötigen eindeutige Namen",
"ToastChaptersRemoved": "Kapitel entfernt",
"ToastChaptersUpdated": "Kapitel aktualisiert",
diff --git a/client/strings/en-us.json b/client/strings/en-us.json
index 47b64c1a..939eb9f4 100644
--- a/client/strings/en-us.json
+++ b/client/strings/en-us.json
@@ -856,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Run every {0} at {1}",
"MessageSearchResultsFor": "Search results for",
"MessageSelected": "{0} selected",
+ "MessageSeriesSequenceCannotContainSpaces": "Series sequence cannot contain spaces",
"MessageServerCouldNotBeReached": "Server could not be reached",
"MessageSetChaptersFromTracksDescription": "Set chapters using each audio file as a chapter and chapter title as the audio file name",
"MessageShareExpirationWillBe": "Expiration will be {0}",
diff --git a/client/strings/es.json b/client/strings/es.json
index 5f358c6a..4dac8272 100644
--- a/client/strings/es.json
+++ b/client/strings/es.json
@@ -462,17 +462,17 @@
"LabelNotes": "Notas",
"LabelNotificationAppriseURL": "URL(s) de Apprise",
"LabelNotificationAvailableVariables": "Variables disponibles",
- "LabelNotificationBodyTemplate": "Plantilla de Cuerpo",
- "LabelNotificationEvent": "Evento de Notificación",
- "LabelNotificationTitleTemplate": "Plantilla de Titulo",
- "LabelNotificationsMaxFailedAttempts": "Máximo de Intentos Fallidos",
+ "LabelNotificationBodyTemplate": "Plantilla de cuerpo",
+ "LabelNotificationEvent": "Evento de notificación",
+ "LabelNotificationTitleTemplate": "Plantilla de título",
+ "LabelNotificationsMaxFailedAttempts": "Máximo de intentos fallidos",
"LabelNotificationsMaxFailedAttemptsHelp": "Las notificaciones se desactivan después de fallar este número de veces",
"LabelNotificationsMaxQueueSize": "Tamaño máximo de la cola de notificaciones",
"LabelNotificationsMaxQueueSizeHelp": "Las notificaciones están limitadas a 1 por segundo. Las notificaciones serán ignoradas si llegan al numero máximo de cola para prevenir spam de eventos.",
"LabelNumberOfBooks": "Número de libros",
"LabelNumberOfEpisodes": "N.º de episodios",
"LabelOpenIDAdvancedPermsClaimDescription": "Nombre de la notificación de OpenID que contiene permisos avanzados para acciones de usuario dentro de la aplicación que se aplicarán a roles que no sean de administrador (si están configurados). Si el reclamo no aparece en la respuesta, se denegará el acceso a ABS. Si falta una sola opción, se tratará como falsa
. Asegúrese de que la notificación del proveedor de identidades coincida con la estructura esperada:",
- "LabelOpenIDClaims": "Deje las siguientes opciones vacías para deshabilitar la asignación avanzada de grupos y permisos, lo que asignaría de manera automática al grupo 'Usuario'.",
+ "LabelOpenIDClaims": "Deje las siguientes opciones vacías para desactivar la asignación avanzada de grupos y permisos, lo que asignaría de manera automática al grupo «Usuario».",
"LabelOpenIDGroupClaimDescription": "Nombre de la declaración OpenID que contiene una lista de grupos del usuario. Comúnmente conocidos como grupos
. Si se configura, la aplicación asignará automáticamente roles en función de la pertenencia a grupos del usuario, siempre que estos grupos se denominen \"admin\", \"user\" o \"guest\" en la notificación. La solicitud debe contener una lista, y si un usuario pertenece a varios grupos, la aplicación asignará el rol correspondiente al mayor nivel de acceso. Si ningún grupo coincide, se denegará el acceso.",
"LabelOpenRSSFeed": "Abrir suministro RSS",
"LabelOverwrite": "Sobrescribir",
@@ -499,7 +499,7 @@
"LabelPodcastType": "Tipo de pódcast",
"LabelPodcasts": "Pódcast",
"LabelPort": "Puerto",
- "LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)",
+ "LabelPrefixesToIgnore": "Prefijos para ignorar (no distingue entre mayúsculas y minúsculas)",
"LabelPreventIndexing": "Evite que los directorios de pódcast de iTunes y Google indicen su suministro",
"LabelPrimaryEbook": "Libro electrónico principal",
"LabelProgress": "Progreso",
@@ -515,7 +515,7 @@
"LabelRSSFeedCustomOwnerEmail": "Correo electrónico de dueño personalizado",
"LabelRSSFeedCustomOwnerName": "Nombre de dueño personalizado",
"LabelRSSFeedOpen": "Suministro RSS abierto",
- "LabelRSSFeedPreventIndexing": "Prevenir indexado",
+ "LabelRSSFeedPreventIndexing": "Evitar indización",
"LabelRSSFeedSlug": "«Slug» de suministro RSS",
"LabelRSSFeedURL": "URL de suministro RSS",
"LabelRandomly": "Aleatorio",
@@ -531,6 +531,7 @@
"LabelReleaseDate": "Fecha de estreno",
"LabelRemoveAllMetadataAbs": "Eliminar todos los archivos metadata.abs",
"LabelRemoveAllMetadataJson": "Eliminar todos los archivos metadata.json",
+ "LabelRemoveAudibleBranding": "Quitar introducción y cierre de Audible de los capítulos",
"LabelRemoveCover": "Quitar cubierta",
"LabelRemoveMetadataFile": "Eliminar archivos de metadatos en carpetas de elementos de biblioteca",
"LabelRemoveMetadataFileHelp": "Elimine todos los archivos metadata.json y metadata.abs de sus carpetas {0}.",
@@ -539,7 +540,7 @@
"LabelSearchTitle": "Buscar título",
"LabelSearchTitleOrASIN": "Buscar título o ASIN",
"LabelSeason": "Temporada",
- "LabelSeasonNumber": "Sesión #{0}",
+ "LabelSeasonNumber": "{0}.ª temporada",
"LabelSelectAll": "Seleccionar todo",
"LabelSelectAllEpisodes": "Seleccionar todos los episodios",
"LabelSelectEpisodesShowing": "Seleccionar los {0} episodios visibles",
@@ -707,6 +708,7 @@
"MessageAddToPlayerQueue": "Agregar a fila del Reproductor",
"MessageAppriseDescription": "Para usar esta función deberás tener la API de Apprise corriendo o una API que maneje los mismos resultados. http://192.168.1.1:8337
entonces pondría http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Cerciórese de usar el ASIN de la región correcta de Audible, no de Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "Reinicie el servidor tras el guardado para aplicar los cambios de OIDC.",
"MessageBackupsDescription": "Los respaldos incluyen: usuarios, el progreso del los usuarios, los detalles de los elementos de la biblioteca, la configuración del servidor y las imágenes en /metadata/items
y /metadata/authors
. Los Respaldos NO incluyen ningún archivo guardado en la carpeta de tu biblioteca.",
"MessageBackupsLocationEditNote": "Nota: actualizar la ubicación de la copia de respaldo no moverá ni modificará los respaldos existentes",
"MessageBackupsLocationNoEditNote": "Nota: la ubicación de la copia de respaldo se establece a través de una variable de entorno y no se puede cambiar aquí.",
@@ -748,7 +750,7 @@
"MessageConfirmNotificationTestTrigger": "¿Activar esta notificación con datos de prueba?",
"MessageConfirmPurgeCache": "Purgar la antememoria eliminará el directorio completo ubicado en /metadata/cache
. /metadata/cache/items
.http://192.168.1.1:8337
alors vous devez mettre http://192.168.1.1:8337/notify
.",
+ "MessageAsinCheck": "Assurez-vous d’utiliser l’ASIN de la bonne région Audible, et non d’Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "Redémarrez votre serveur après avoir enregistré pour appliquer les modifications OIDC.",
"MessageBackupsDescription": "Les sauvegardes incluent les utilisateurs, la progression des utilisateurs, les détails des éléments de la bibliothèque, les paramètres du serveur et les images stockées dans /metadata/items
& /metadata/authors
. Les sauvegardes n’incluent pas les fichiers stockés dans les dossiers de votre bibliothèque.",
"MessageBackupsLocationEditNote": "Remarque : Mettre à jour l'emplacement de sauvegarde ne déplacera pas ou ne modifiera pas les sauvegardes existantes",
"MessageBackupsLocationNoEditNote": "Remarque : l’emplacement de sauvegarde est défini via une variable d’environnement et ne peut pas être modifié ici.",
@@ -723,6 +726,7 @@
"MessageChapterErrorStartGteDuration": "Horodatage invalide car il doit débuter avant la fin du livre",
"MessageChapterErrorStartLtPrev": "Horodatage invalide car il doit débuter au moins après le précédent chapitre",
"MessageChapterStartIsAfter": "Le premier chapitre est situé au début de votre livre audio",
+ "MessageChaptersNotFound": "Chapitres non trouvés",
"MessageCheckingCron": "Vérification du cron…",
"MessageConfirmCloseFeed": "Êtes-vous sûr·e de vouloir fermer ce flux ?",
"MessageConfirmDeleteBackup": "Êtes-vous sûr·e de vouloir supprimer la sauvegarde de « {0} » ?",
@@ -779,6 +783,7 @@
"MessageForceReScanDescription": "analysera de nouveau tous les fichiers. Les étiquettes ID3 des fichiers audio, les fichiers OPF et les fichiers texte seront analysés comme s’ils étaient nouveaux.",
"MessageImportantNotice": "Information importante !",
"MessageInsertChapterBelow": "Insérer le chapitre ci-dessous",
+ "MessageInvalidAsin": "ASIN invalide",
"MessageItemsSelected": "{0} éléments sélectionnés",
"MessageItemsUpdated": "{0} éléments mis à jour",
"MessageJoinUsOn": "Rejoignez-nous sur",
@@ -850,6 +855,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Exécuté tous les {0} à {1}",
"MessageSearchResultsFor": "Résultats de recherche pour",
"MessageSelected": "{0} sélectionnés",
+ "MessageSeriesSequenceCannotContainSpaces": "La séquence de séries ne peut pas contenir d’espaces",
"MessageServerCouldNotBeReached": "Serveur inaccessible",
"MessageSetChaptersFromTracksDescription": "Positionne un chapitre par fichier audio, avec le titre du fichier comme titre de chapitre",
"MessageShareExpirationWillBe": "Expire le {0}",
@@ -968,6 +974,8 @@
"ToastCachePurgeFailed": "Échec de la purge du cache",
"ToastCachePurgeSuccess": "Cache purgé avec succès",
"ToastChaptersHaveErrors": "Les chapitres contiennent des erreurs",
+ "ToastChaptersInvalidShiftAmountLast": "Durée de décalage non valide. L’heure de début du dernier chapitre pourrait dépasser la durée de ce livre audio.",
+ "ToastChaptersInvalidShiftAmountStart": "Durée de décalage non valide. Le premier chapitre aurait une longueur nulle ou négative et serait écrasé par le second. Augmentez la durée de début du second chapitre.",
"ToastChaptersMustHaveTitles": "Les chapitre doivent avoir un titre",
"ToastChaptersRemoved": "Chapitres supprimés",
"ToastChaptersUpdated": "Chapitres mis à jour",
diff --git a/client/strings/he.json b/client/strings/he.json
index 19da58e7..8b5bcdd0 100644
--- a/client/strings/he.json
+++ b/client/strings/he.json
@@ -10,6 +10,8 @@
"ButtonApplyChapters": "החל פרקים",
"ButtonAuthors": "סופרים",
"ButtonBack": "חזור",
+ "ButtonBatchEditPopulateFromExisting": "מלא משדות קיימים",
+ "ButtonBatchEditPopulateMapDetails": "מלא פרטי מפה",
"ButtonBrowseForFolder": "עיין בתיקייה",
"ButtonCancel": "ביטול",
"ButtonCancelEncode": "בטל קידוד",
@@ -29,7 +31,9 @@
"ButtonEdit": "ערוך",
"ButtonEditChapters": "ערוך פרקים",
"ButtonEditPodcast": "ערוך פודקאסט",
- "ButtonEnable": "הפעל",
+ "ButtonEnable": "אפשר",
+ "ButtonFireAndFail": "שלח בכישלון",
+ "ButtonFireOnTest": "שלח באירוע בדיקה",
"ButtonForceReScan": "סרוק מחדש בכוח",
"ButtonFullPath": "נתיב מלא",
"ButtonHide": "הסתר",
@@ -37,7 +41,7 @@
"ButtonIssues": "תקלות",
"ButtonJumpBackward": "דלג אחורה",
"ButtonJumpForward": "דלג קדימה",
- "ButtonLatest": "חדש ביותר",
+ "ButtonLatest": "אחרון",
"ButtonLibrary": "ספרייה",
"ButtonLogout": "התנתק",
"ButtonLookup": "חפש",
@@ -70,7 +74,7 @@
"ButtonReScan": "סרוק מחדש",
"ButtonRead": "קרא",
"ButtonReadLess": "קרא פחות",
- "ButtonReadMore": "קרא יותר",
+ "ButtonReadMore": "קרא עוד",
"ButtonRefresh": "רענן",
"ButtonRemove": "הסר",
"ButtonRemoveAll": "הסר הכל",
@@ -86,7 +90,9 @@
"ButtonSaveTracklist": "שמור רשימת רצועות",
"ButtonScan": "סרוק",
"ButtonScanLibrary": "סרוק ספרייה",
- "ButtonSearch": "חפש",
+ "ButtonScrollLeft": "גלול שמאלה",
+ "ButtonScrollRight": "גלול ימינה",
+ "ButtonSearch": "חיפוש",
"ButtonSelectFolderPath": "בחר נתיב לתיקייה",
"ButtonSeries": "סדרה",
"ButtonSetChaptersFromTracks": "קבע פרקים לפי הרצועות",
@@ -96,7 +102,7 @@
"ButtonStartM4BEncode": "התחל קידוד M4B",
"ButtonStartMetadataEmbed": "התחל הטמעת מטא-נתונים",
"ButtonStats": "סטטיסטיקות",
- "ButtonSubmit": "שלח",
+ "ButtonSubmit": "שליחה",
"ButtonTest": "בדיקה",
"ButtonUnlinkOpenId": "נתק OpenID",
"ButtonUpload": "העלה",
@@ -122,26 +128,26 @@
"HeaderChapters": "פרקים",
"HeaderChooseAFolder": "בחר תיקייה",
"HeaderCollection": "אוסף",
- "HeaderCollectionItems": "פריטי אוסף",
+ "HeaderCollectionItems": "פרטי אוסף",
"HeaderCover": "כריכה",
"HeaderCurrentDownloads": "הורדות נוכחיות",
"HeaderCustomMessageOnLogin": "הודעה מותאמת אישית בהתחברות",
"HeaderCustomMetadataProviders": "ספקי מטא-נתונים מותאמים אישית",
"HeaderDetails": "פרטים",
"HeaderDownloadQueue": "תור הורדה",
- "HeaderEbookFiles": "קבצי ספר אלקטרוני",
+ "HeaderEbookFiles": "קבצי Ebook",
"HeaderEmail": "אימייל",
"HeaderEmailSettings": "הגדרות אימייל",
"HeaderEpisodes": "פרקים",
"HeaderEreaderDevices": "התקני קריאה דיגיטליים",
- "HeaderEreaderSettings": "הגדרות התקני קריאה דיגיטליים",
+ "HeaderEreaderSettings": "הגדרות קורא אלקטרוני",
"HeaderFiles": "קבצים",
"HeaderFindChapters": "מצא פרקים",
"HeaderIgnoredFiles": "קבצים שנתעלמו",
"HeaderItemFiles": "קבצי פריט",
"HeaderItemMetadataUtils": "כלי מטא-נתונים",
"HeaderLastListeningSession": "הפעלת האזנה אחרונה",
- "HeaderLatestEpisodes": "הפרקים העדכניים ביותר",
+ "HeaderLatestEpisodes": "פרקים אחרונים",
"HeaderLibraries": "ספריות",
"HeaderLibraryFiles": "קבצי ספרייה",
"HeaderLibraryStats": "סטטיסטיקות ספרייה",
@@ -171,8 +177,9 @@
"HeaderPlaylist": "רשימת השמעה",
"HeaderPlaylistItems": "פריטי רשימת השמעה",
"HeaderPodcastsToAdd": "פודקאסטים להוספה",
+ "HeaderPresets": "קביעות מוגדרות מראש",
"HeaderPreviewCover": "תצוגה מקדימה של כריכה",
- "HeaderRSSFeedGeneral": "פרטי ערוץ RSS",
+ "HeaderRSSFeedGeneral": "פרטי RSS",
"HeaderRSSFeedIsOpen": "ערוץ RSS פתוח",
"HeaderRSSFeeds": "ערוצי RSS",
"HeaderRemoveEpisode": "הסר פרק",
@@ -188,14 +195,15 @@
"HeaderSettingsExperimental": "תכונות ניסיוניות",
"HeaderSettingsGeneral": "כללי",
"HeaderSettingsScanner": "סורק",
+ "HeaderSettingsWebClient": "מערך",
"HeaderSleepTimer": "טיימר שינה",
"HeaderStatsLargestItems": "הפריטים הגדולים ביותר",
"HeaderStatsLongestItems": "הפריטים הארוכים ביותר (בשעות)",
- "HeaderStatsMinutesListeningChart": "דקות האזנה (בימים האחרונים)",
- "HeaderStatsRecentSessions": "הפעלות אחרונות",
+ "HeaderStatsMinutesListeningChart": "דקות האזנה (7 ימים אחרונים)",
+ "HeaderStatsRecentSessions": "האזנות אחרונות",
"HeaderStatsTop10Authors": "10 היוצרים המובילים",
"HeaderStatsTop5Genres": "הז'אנרים המובילים 5",
- "HeaderTableOfContents": "תוכן העניינים",
+ "HeaderTableOfContents": "תוכן עניינים",
"HeaderTools": "כלים",
"HeaderUpdateAccount": "עדכן חשבון",
"HeaderUpdateAuthor": "עדכן יוצר",
@@ -212,15 +220,17 @@
"LabelAccountTypeAdmin": "מנהל",
"LabelAccountTypeGuest": "אורח",
"LabelAccountTypeUser": "משתמש",
+ "LabelActivities": "פעילויות",
"LabelActivity": "פעילות",
"LabelAddToCollection": "הוסף לאוסף",
"LabelAddToCollectionBatch": "הוסף {0} ספרים לאוסף",
"LabelAddToPlaylist": "הוסף לרשימת השמעה",
"LabelAddToPlaylistBatch": "הוסף {0} פריטים לרשימת השמעה",
- "LabelAddedAt": "נוסף בתאריך",
+ "LabelAddedAt": "נוסף ב-",
"LabelAddedDate": "נוסף ב-{0}",
"LabelAdminUsersOnly": "רק מנהלים",
"LabelAll": "הכל",
+ "LabelAllEpisodesDownloaded": "כל הפרקים הורדו",
"LabelAllUsers": "כל המשתמשים",
"LabelAllUsersExcludingGuests": "כל המשתמשים, ללא אורחים",
"LabelAllUsersIncludingGuests": "כל המשתמשים כולל אורחים",
@@ -230,10 +240,10 @@
"LabelAudioBitrate": "קצב סיביות (לדוגמא 128k)",
"LabelAudioChannels": "ערוצי קול (1 או 2)",
"LabelAudioCodec": "קידוד קול",
- "LabelAuthor": "יוצר",
- "LabelAuthorFirstLast": "יוצר (שם פרטי שם משפחה)",
- "LabelAuthorLastFirst": "יוצר (שם משפחה, שם פרטי)",
- "LabelAuthors": "יוצרים",
+ "LabelAuthor": "סופר",
+ "LabelAuthorFirstLast": "סופר (שם, משפחה)",
+ "LabelAuthorLastFirst": "סופר (משפחה, שם)",
+ "LabelAuthors": "סופרים",
"LabelAutoDownloadEpisodes": "הורד פרקים באופן אוטומטי",
"LabelAutoFetchMetadata": "חפש והורד מטא-נתונים באופן אוטומטי",
"LabelAutoFetchMetadataHelp": "מחפש ומוריד מטא-נתונים לשדות כותרת, יוצר וסדרה כדי לשפר את תהליך ההעלאה. ייתכן שיהיה צורך להתאים מטא-נתונים נוסף לאחר ההעלאה.",
@@ -242,36 +252,48 @@
"LabelAutoRegister": "הרשמה אוטומטית",
"LabelAutoRegisterDescription": "יצירת משתמשים חדשים אוטומטית לאחר התחברות",
"LabelBackToUser": "חזרה למשתמש",
+ "LabelBackupAudioFiles": "גיבוי קבצי שמע",
"LabelBackupLocation": "מיקום גיבוי",
- "LabelBackupsEnableAutomaticBackups": "הפעל גיבויים אוטומטיים",
+ "LabelBackupsEnableAutomaticBackups": "גיבויים אוטומטיים",
"LabelBackupsEnableAutomaticBackupsHelp": "גיבויים שמורים ב /metadata/backups",
- "LabelBackupsMaxBackupSize": "גודל הגיבוי המרבי (בג'יגה-בייט)",
+ "LabelBackupsMaxBackupSize": "גודל הגיבוי המרבי (בג'יגה-בייט) (0 - ללא הגבלה)",
"LabelBackupsMaxBackupSizeHelp": "כהגנה על עצמך מפני תצורה שגויה, הגיבויים ייכשלו אם הם יעברו את הגודל שהוגדר.",
"LabelBackupsNumberToKeep": "מספר הגיבויים לשמירה",
"LabelBackupsNumberToKeepHelp": "רק גיבוי אחד יוסר בכל פעם, לכן אם יש לך כבר יותר מגיבוי אחד יש להסיר אותם באופן ידני.",
"LabelBitrate": "קצב סיביות",
+ "LabelBonus": "בונוס",
"LabelBooks": "ספרים",
"LabelButtonText": "טקסט לחצן",
+ "LabelByAuthor": "על ידי {0}",
"LabelChangePassword": "שינוי סיסמה",
"LabelChannels": "ערוצים",
+ "LabelChapterCount": "{0} פרקים",
"LabelChapterTitle": "כותרת הפרק",
"LabelChapters": "פרקים",
"LabelChaptersFound": "פרקים שנמצאו",
"LabelClickForMoreInfo": "לחץ למידע נוסף",
+ "LabelClickToUseCurrentValue": "לחץ לשימוש בערך הנוכחי",
"LabelClosePlayer": "סגור נגן",
- "LabelCollapseSeries": "צמצום סדרה",
+ "LabelCodec": "Coded",
+ "LabelCollapseSeries": "הסתר סדרה",
+ "LabelCollapseSubSeries": "הסתר תת סדרה",
"LabelCollection": "אוסף",
"LabelCollections": "אוספים",
- "LabelComplete": "מלא",
+ "LabelComplete": "הושלם",
"LabelConfirmPassword": "אישור סיסמה",
"LabelContinueListening": "המשך האזנה",
"LabelContinueReading": "המשך קריאה",
"LabelContinueSeries": "המשך סדרה",
"LabelCover": "כריכה",
"LabelCoverImageURL": "כתובת התמונה ברשת",
+ "LabelCoverProvider": "ספק כריכה",
"LabelCreatedAt": "נוצר בתאריך",
+ "LabelCronExpression": "ביטוי cron",
"LabelCurrent": "נוכחי",
"LabelCurrently": "כעת:",
+ "LabelCustomCronExpression": "ביטוי cron מותאם אישית:",
+ "LabelDatetime": "Datetime",
+ "LabelDays": "ימים",
"LabelDeleteFromFileSystemCheckbox": "מחיקה מהמערכת הקבצים (הסר סימון למחיקה רק ממסד הנתונים)",
"LabelDescription": "תיאור",
"LabelDeselectAll": "הסר בחירת כל הפריטים",
@@ -282,51 +304,83 @@
"LabelDiscFromFilename": "דיסק משם הקובץ",
"LabelDiscFromMetadata": "דיסק מהמטא-נתונים",
"LabelDiscover": "גלה",
- "LabelDownload": "הורד",
+ "LabelDownload": "הורדה",
"LabelDownloadNEpisodes": "הורד {0} פרקים",
+ "LabelDownloadable": "ניתן להורדה",
"LabelDuration": "משך",
+ "LabelDurationComparisonExactMatch": "(התאמה מדוייקת)",
+ "LabelDurationComparisonLonger": "({0} ארוך יותר)",
+ "LabelDurationComparisonShorter": "({0} קצר יותר)",
"LabelDurationFound": "משך נמצא:",
"LabelEbook": "ספר אלקטרוני",
"LabelEbooks": "ספרים אלקטרוניים",
"LabelEdit": "עריכה",
"LabelEmail": "דואר אלקטרוני",
"LabelEmailSettingsFromAddress": "מאת",
+ "LabelEmailSettingsRejectUnauthorized": "דחה תעודות לא מאושרות",
+ "LabelEmailSettingsRejectUnauthorizedHelp": "השבתת אימות תעודת SSL עלולה לחשוף את החיבור שלך לסיכוני אבטחה, כגון התקפות \"אדם באמצע\". השבת אפשרות זו רק אם אתה מבין את ההשלכות ובוטח בשרת הדואר שאליו אתה מתחבר.",
"LabelEmailSettingsSecure": "מאובטח",
"LabelEmailSettingsSecureHelp": "אם מופעל, החיבור ישתמש ב-TLS בעת ההתחברות לשרת. אם לא, אז TLS יהיה בשימוש אם השרת תומך בהרחבת STARTTLS. ברוב המקרים מומלץ להפעיל את הגדרה זו אם אתה מתחבר לפורט 465. לפורט 587 או 25, השאר כבוי. (from nodemailer.com/smtp/#authentication)",
"LabelEmailSettingsTestAddress": "כתובת לבדיקה",
"LabelEmbeddedCover": "כריכה מוטמעת",
- "LabelEnable": "הפעל",
- "LabelEnd": "סיום",
+ "LabelEnable": "אפשר",
+ "LabelEncodingBackupLocation": "גיבוי של קבצי אודיו מקוריים יישמר ב:",
+ "LabelEncodingChaptersNotEmbedded": "פרקים אינם מוטבעים בספרי אודיו מרובי רצועות.",
+ "LabelEncodingClearItemCache": "הקפד לנקות מטמון פריטים מעת לעת.",
+ "LabelEncodingFinishedM4B": "קובץ M4B סופי יישמר בתיקייה ה-audiobook ב:",
+ "LabelEncodingInfoEmbedded": "מטה דאטה יוטמע ברצועות השמע בתוך תיקיית ה-audiobook.",
+ "LabelEncodingStartedNavigation": "לאחר שהמשימה תתחיל אפשר לנווט לדף אחר.",
+ "LabelEncodingTimeWarning": "קידוד יכול להימשך עד 30 דקות.",
+ "LabelEncodingWarningAdvancedSettings": "אזהרה: אל תעדכן את ההגדרות האלה אלא אם כן אתה מכיר את אפשרויות קידוד ffmpeg.",
+ "LabelEncodingWatcherDisabled": "אם ה-watcher כבוי, יש לסרוק את הספר מחדש לאחר מכן.",
+ "LabelEnd": "סוף",
+ "LabelEndOfChapter": "סוף הפרק",
"LabelEpisode": "פרק",
+ "LabelEpisodeNotLinkedToRssFeed": "פרק לא מקושר לערוץ RSS",
+ "LabelEpisodeNumber": "פרק #{0}",
"LabelEpisodeTitle": "כותרת הפרק",
"LabelEpisodeType": "סוג הפרק",
+ "LabelEpisodeUrlFromRssFeed": "קישור פרק מערוץ RSS",
+ "LabelEpisodes": "פרקים",
+ "LabelEpisodic": "ארעי",
"LabelExample": "דוגמה",
+ "LabelExpandSeries": "הרחב סדרה",
+ "LabelExpandSubSeries": "הרחב תת סדרה",
"LabelExplicit": "בוטה",
+ "LabelExplicitChecked": "בוטה (מסומן)",
+ "LabelExplicitUnchecked": "לא בוטה (לא מסומן)",
+ "LabelExportOPML": "ייצוא OPML",
"LabelFeedURL": "כתובת ערוץ",
"LabelFetchingMetadata": "מושך מטא-נתונים",
"LabelFile": "קובץ",
"LabelFileBirthtime": "זמן יצירת הקובץ",
- "LabelFileModified": "הקובץ שונה",
- "LabelFilename": "שם הקובץ",
+ "LabelFileBornDate": "נוצר {0}",
+ "LabelFileModified": "קובץ נערך",
+ "LabelFileModifiedDate": "שונה {0}",
+ "LabelFilename": "שם קובץ",
"LabelFilterByUser": "סינון לפי משתמש",
"LabelFindEpisodes": "מצא פרקים",
"LabelFinished": "הושלם",
"LabelFolder": "תיקייה",
"LabelFolders": "תיקיות",
"LabelFontBold": "מודגש",
+ "LabelFontBoldness": "עובי פונט",
"LabelFontFamily": "משפחת הפונטים",
"LabelFontItalic": "נטוי",
- "LabelFontScale": "קנה מידה של הפונט",
+ "LabelFontScale": "גודל פונט",
"LabelFontStrikethrough": "קו חוצה",
"LabelFormat": "תבנית",
- "LabelGenre": "ז'אנר",
- "LabelGenres": "ז'אנרים",
+ "LabelFull": "מלא",
+ "LabelGenre": "סגנון",
+ "LabelGenres": "סגנונות",
"LabelHardDeleteFile": "מחיקה חזקה של הקובץ",
- "LabelHasEbook": "ספר אלקטרוני קיים",
- "LabelHasSupplementaryEbook": "קיים ספר אלקטרוני נלווה",
+ "LabelHasEbook": "קיים ספר אלקטרוני",
+ "LabelHasSupplementaryEbook": "קיים ספר אלקטרוני משלים",
+ "LabelHideSubtitles": "הסתר תת כותרות",
"LabelHighestPriority": "העדיפות הגבוהה ביותר",
"LabelHost": "מארח",
"LabelHour": "שעה",
+ "LabelHours": "שעות",
"LabelIcon": "סמל",
"LabelImageURLFromTheWeb": "כתובת התמונה מהרשת",
"LabelInProgress": "בתהליך",
@@ -341,25 +395,30 @@
"LabelIntervalEvery6Hours": "כל 6 שעות",
"LabelIntervalEveryDay": "כל יום",
"LabelIntervalEveryHour": "כל שעה",
+ "LabelIntervalEveryMinute": "כל דקה",
"LabelInvert": "הפוך",
"LabelItem": "פריט",
+ "LabelJumpBackwardAmount": "כמות הרצה לאחור",
+ "LabelJumpForwardAmount": "כמות הרצה קדימה",
"LabelLanguage": "שפה",
"LabelLanguageDefaultServer": "שפת ברירת המחדל של השרת",
+ "LabelLanguages": "שפות",
"LabelLastBookAdded": "הספר האחרון שנוסף",
"LabelLastBookUpdated": "הספר האחרון שעודכן",
"LabelLastSeen": "נראה לאחרונה",
"LabelLastTime": "הזמן האחרון",
"LabelLastUpdate": "עדכון אחרון",
- "LabelLayout": "פריסה",
- "LabelLayoutSinglePage": "דף בודד",
+ "LabelLayout": "Layout",
+ "LabelLayoutSinglePage": "עמוד יחיד",
"LabelLayoutSplitPage": "פיצול הדף",
"LabelLess": "פחות",
"LabelLibrariesAccessibleToUser": "ספריות נגישות למשתמש",
"LabelLibrary": "ספרייה",
+ "LabelLibraryFilterSublistEmpty": "לא {0}",
"LabelLibraryItem": "פריט ספרייה",
"LabelLibraryName": "שם הספרייה",
"LabelLimit": "מגבלה",
- "LabelLineSpacing": "ריווח שורות",
+ "LabelLineSpacing": "מרווח שורה",
"LabelListenAgain": "האזן שוב",
"LabelLogLevelDebug": "דיבוג",
"LabelLogLevelInfo": "מידע",
@@ -368,6 +427,10 @@
"LabelLowestPriority": "העדיפות הנמוכה ביותר",
"LabelMatchExistingUsersBy": "התאם משתמשים קיימים לפי",
"LabelMatchExistingUsersByDescription": "משמש לחיבור משתמשים קיימים. לאחר החיבור, המשתמשים יותאמו לפי זיהוי ייחודי מספק ה-SSO שלך",
+ "LabelMaxEpisodesToDownload": "מספר פרקים מקסימלי להורדה. 0 - ללא הגבלה.",
+ "LabelMaxEpisodesToDownloadPerCheck": "מספר פרקים חדשים מקסימלי להורדה בכל בדיקה",
+ "LabelMaxEpisodesToKeep": "מספר פרקים מקסימלי לשמור",
+ "LabelMaxEpisodesToKeepHelp": "ערך של 0 קובע ללא מגבלה. לאחר הורדה אוטומטית של פרק חדש יימחק את הפרק הישן ביותר אם יש לך יותר מ-X פרקים. פעולה זו תמחק רק פרק אחד לכל הורדה חדשה.",
"LabelMediaPlayer": "נגן מדיה",
"LabelMediaType": "סוג מדיה",
"LabelMetaTag": "תג מטא",
@@ -375,6 +438,7 @@
"LabelMetadataOrderOfPrecedenceDescription": "מקורות המטא-נתונים עם עדיפות גבוהה יחליפו מקורות עם עדיפות נמוכה יותר",
"LabelMetadataProvider": "ספק מטא-נתונים",
"LabelMinute": "דקה",
+ "LabelMinutes": "דקות",
"LabelMissing": "חסר",
"LabelMissingEbook": "אין ספר אלקטרוני",
"LabelMissingSupplementaryEbook": "אין ספר אלקטרוני נלווה",
@@ -387,10 +451,11 @@
"LabelNarrators": "מספרים",
"LabelNew": "חדש",
"LabelNewPassword": "סיסמה חדשה",
- "LabelNewestAuthors": "הסופרים החדשים ביותר",
+ "LabelNewestAuthors": "הסופרים האחרונים",
"LabelNewestEpisodes": "הפרקים החדשים ביותר",
"LabelNextBackupDate": "תאריך הגיבוי הבא",
"LabelNextScheduledRun": "הרצה מתוזמנת הבאה",
+ "LabelNoCustomMetadataProviders": "אין ספקי מטא-נתונים מותאמים אישית",
"LabelNoEpisodesSelected": "לא נבחרו פרקים",
"LabelNotFinished": "לא הושלם",
"LabelNotStarted": "לא התחיל",
@@ -405,7 +470,9 @@
"LabelNotificationsMaxQueueSize": "גודל התור המרבי לאירועי התראה",
"LabelNotificationsMaxQueueSizeHelp": "האירועים מוגבלים לשליחה אחת לשנייה. האירועים יתעלמו אם התור מלא. הגדרה זו נועדה למנוע ספאם התראות.",
"LabelNumberOfBooks": "מספר הספרים",
- "LabelNumberOfEpisodes": "מספר הפרקים",
+ "LabelNumberOfEpisodes": "# פרקים",
+ "LabelOpenIDAdvancedPermsClaimDescription": "שם OpenID claim המכילה הרשאות מתקדמות לפעולות משתמש בתוך האפליקציה, אשר יחולו על תפקידים שאינם מנהלי מערכת (אם הוגדרה). אם התביעה חסרה בתגובה, הגישה ל-ABS תידחה. אם אפשרות אחת חסרה, היא תטופל כ-false
יש לוודא שטענת ספק הזהויות תואמת את המבנה הצפוי:",
+ "LabelOpenIDClaims": "השאר את האפשרויות הבאות ריקות כדי להשבית הקצאת קבוצות והרשאות מתקדמת, ולאחר מכן להקצות אוטומטית את קבוצת 'משתמש'.",
"LabelOpenRSSFeed": "פתח ערוץ RSS",
"LabelOverwrite": "לשכפל",
"LabelPassword": "סיסמה",
@@ -433,13 +500,15 @@
"LabelProvider": "ספק",
"LabelPubDate": "תאריך פרסום",
"LabelPublishYear": "שנת הפרסום",
+ "LabelPublishedDate": "פורסם {0}",
"LabelPublisher": "מוציא לאור",
"LabelRSSFeedCustomOwnerEmail": "אימייל בעלים מותאם אישית",
"LabelRSSFeedCustomOwnerName": "שם בעלים מותאם אישית",
- "LabelRSSFeedOpen": "פתח ערוץ RSS",
+ "LabelRSSFeedOpen": "ערוץ RSS פתוח",
"LabelRSSFeedPreventIndexing": "מנע רישום",
"LabelRSSFeedSlug": "Slug של ערוץ ה-RSS",
"LabelRSSFeedURL": "כתובת ערוץ ה-RSS",
+ "LabelRandomly": "באופן אקראי",
"LabelRead": "קריאה",
"LabelReadAgain": "קרא שוב",
"LabelReadEbookWithoutProgress": "קרא/י ספר אלקטרוני ללא שמירת התקדמות",
@@ -465,7 +534,7 @@
"LabelSeriesProgress": "התקדמות בסדרה",
"LabelServerYearReview": "השנה בסקירה של השרת ({0})",
"LabelSetEbookAsPrimary": "קבע כראשי",
- "LabelSetEbookAsSupplementary": "קבע כספר אלקטרוני נלווה",
+ "LabelSetEbookAsSupplementary": "קבע כמשלים",
"LabelSettingsAudiobooksOnly": "רק ספרי קול",
"LabelSettingsAudiobooksOnlyHelp": "הפעלת ההגדרה הזו תתעלם מקבצי ספרים אלקטרוניים אלא אם כן הם נמצאים בתיקיית ספרי קול, שבמקרה זה יקבעו כספרים אלקטרוניים נלווים",
"LabelSettingsBookshelfViewHelp": "עיצוב סקאומורפי עם מדפי עץ",
@@ -500,7 +569,7 @@
"LabelShowAll": "הצג הכל",
"LabelSize": "גודל",
"LabelSleepTimer": "טיימר שינה",
- "LabelStart": "התחלה",
+ "LabelStart": "התחל",
"LabelStartTime": "זמן התחלה",
"LabelStarted": "התחיל",
"LabelStartedAt": "התחיל ב",
@@ -576,8 +645,8 @@
"LabelViewQueue": "הצג תור נגן",
"LabelVolume": "עוצמת קול",
"LabelWeekdaysToRun": "ימי השבוע להרצה",
- "LabelYearReviewHide": "הסתר שנת סקירה",
- "LabelYearReviewShow": "הצג שנת סקירה",
+ "LabelYearReviewHide": "הסתר סקירת שנה",
+ "LabelYearReviewShow": "הצג סקירת שנה",
"LabelYourAudiobookDuration": "משך הספר הקולי שלך",
"LabelYourBookmarks": "הסימניות שלך",
"LabelYourPlaylists": "הפלייליסטים שלך",
@@ -628,8 +697,8 @@
"MessageDownloadingEpisode": "מוריד פרק",
"MessageDragFilesIntoTrackOrder": "גרור קבצים לסדר ההשמעה נכון",
"MessageEmbedFinished": "ההטמעה הושלמה!",
- "MessageEpisodesQueuedForDownload": "{0} פרקים בתור להורדה",
- "MessageFeedURLWillBe": "כתובת URL של העדכון תהיה {0}",
+ "MessageEpisodesQueuedForDownload": "{0} פרק/ים בתור להורדה",
+ "MessageFeedURLWillBe": "כתובת ה- URL של הערוץ תהיה {0}",
"MessageFetching": "מושך...",
"MessageForceReScanDescription": "תבוצע סריקה מחדש כמו סריקה חדש מאפס, תגי ID3 של קבצי קול, קבצי OPF, וקבצי טקסט ייסרקו כחדשים.",
"MessageImportantNotice": "הודעה חשובה!",
@@ -644,7 +713,7 @@
"MessageMapChapterTitles": "מפה שמות פרקים לפרקי הספר השמורים שלך ללא שינוי תגי זמן",
"MessageMarkAllEpisodesFinished": "סמן את כל הפרקים כהסתיימו",
"MessageMarkAllEpisodesNotFinished": "סמן את כל הפרקים כלא הסתיימו",
- "MessageMarkAsFinished": "סמן כהסתיים",
+ "MessageMarkAsFinished": "סמן כהושלם",
"MessageMarkAsNotFinished": "סמן כלא הסתיים",
"MessageMatchBooksDescription": "ינסה להתאים ספרים בספריית הספרים שלך עם ספר מספק החיפוש הנבחר וימלא פרטים ריקים ותמונות כריכה. לא יחליף פרטים קיימים.",
"MessageNoAudioTracks": "אין רצועות שמע",
@@ -674,7 +743,7 @@
"MessageNoSeries": "אין סדרות",
"MessageNoTags": "אין תגיות",
"MessageNoTasksRunning": "אין משימות פעילות",
- "MessageNoUpdatesWereNecessary": "לא היה צורך בעדכונים",
+ "MessageNoUpdatesWereNecessary": "לא נדרש עדכון",
"MessageNoUserPlaylists": "אין לך רשימות השמעה",
"MessageNotYetImplemented": "עדיין לא מיושם",
"MessageOr": "או",
@@ -682,6 +751,7 @@
"MessagePlayChapter": "הקשב לתחילת הפרק",
"MessagePlaylistCreateFromCollection": "צור רשימת השמעה מאוסף",
"MessagePodcastHasNoRSSFeedForMatching": "לפודקאסט אין כתובת URL של ערוץ RSS להתאמה",
+ "MessagePodcastSearchField": "הזן מונח חיפוש או כתובת URL של ערוץ RSS",
"MessageQuickMatchDescription": "ממלא פרטים ריקים וכריכות עם התוצאה הראשונה מ '{0}'. לא ימחק פרטים אלא אם הגדרת השרת 'העדף מטה-נתונים מותאמים' מופעלת.",
"MessageRemoveChapter": "הסר פרק",
"MessageRemoveEpisodes": "הסר {0} פרקים",
@@ -708,7 +778,7 @@
"NoteChangeRootPassword": "המשתמש root הוא המשתמש היחיד שיכולה להיות לו סיסמה ריקה",
"NoteChapterEditorTimes": "הערה: זמן ההתחלה של הפרק הראשון חייב להישאר 0:00 וזמן ההתחלה של הפרק האחרון לא יכול לחרוג מהזמן של ספר השמע.",
"NoteFolderPicker": "הערה: תיקיות שכבר מופו לא יוצגו",
- "NoteRSSFeedPodcastAppsHttps": "אזהרה: רוב יישומי הפודקאסט דורשים שכתובת ה-URL ערוץ ה-RSS תשתמש ב-HTTPS",
+ "NoteRSSFeedPodcastAppsHttps": "אזהרה: רוב אפליקציות הפודקאסטים ידרשו שכתובת האתר של ערוץ ה-RSS תשתמש ב-HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "אזהרה: פרק אחד או יותר לא מכילים תאריך פרסום. חלק מיישומי הפודקאסט דורשים זאת.",
"NoteUploaderFoldersWithMediaFiles": "תיקיות עם קבצי מדיה יעובדו כפריטי ספריה נפרדים.",
"NoteUploaderOnlyAudioFiles": "אם מועלים רק קבצי שמע, כל קובץ שמע יעובד כספר שמע נפרד.",
@@ -741,7 +811,7 @@
"ToastCollectionUpdateSuccess": "האוסף עודכן בהצלחה",
"ToastItemCoverUpdateSuccess": "כריכת הפריט עודכנה בהצלחה",
"ToastItemDetailsUpdateSuccess": "פרטי הפריט עודכנו בהצלחה",
- "ToastItemMarkedAsFinishedFailed": "סימון כפריט כהושלם נכשל",
+ "ToastItemMarkedAsFinishedFailed": "סימון כפריט שהושלם נכשל",
"ToastItemMarkedAsFinishedSuccess": "הפריט סומן כהושלם בהצלחה",
"ToastItemMarkedAsNotFinishedFailed": "סימון כפריט שלא הושלם נכשל",
"ToastItemMarkedAsNotFinishedSuccess": "הפריט סומן כלא הושלם בהצלחה",
diff --git a/client/strings/hr.json b/client/strings/hr.json
index 6b867312..c4715ff3 100644
--- a/client/strings/hr.json
+++ b/client/strings/hr.json
@@ -177,6 +177,7 @@
"HeaderPlaylist": "Popis za izvođenje",
"HeaderPlaylistItems": "Stavke popisa za izvođenje",
"HeaderPodcastsToAdd": "Podcasti za dodavanje",
+ "HeaderPresets": "Predlošci postavki",
"HeaderPreviewCover": "Pretpregled naslovnice",
"HeaderRSSFeedGeneral": "RSS pojedinosti",
"HeaderRSSFeedIsOpen": "RSS izvor je otvoren",
@@ -530,6 +531,7 @@
"LabelReleaseDate": "Datum izlaska",
"LabelRemoveAllMetadataAbs": "Ukloni sve datoteke metadata.abs",
"LabelRemoveAllMetadataJson": "Ukloni sve datoteke metadata.json",
+ "LabelRemoveAudibleBranding": "Ukloni Audibleove najave i odjave iz poglavlja",
"LabelRemoveCover": "Ukloni naslovnicu",
"LabelRemoveMetadataFile": "Ukloni datoteke s meta-podatcima iz mapa knjižničkih stavki",
"LabelRemoveMetadataFileHelp": "Uklanjanje svih datoteka metadata.json i metadata.abs u vaših {0} mapa.",
@@ -706,6 +708,7 @@
"MessageAddToPlayerQueue": "Dodaj u redoslijed izvođenja",
"MessageAppriseDescription": "Da biste se koristili ovom značajkom, treba vam instanca Apprise API-ja ili API koji može rukovati istom vrstom zahtjeva.http://192.168.1.1:8337
trebate upisati http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Upišite ASIN iz odgovarajuće Audibleove regije, ne s Amazonov.",
+ "MessageAuthenticationOIDCChangesRestart": "Ponovno pokrenite poslužitelj da biste primijenili OIDC promjene.",
"MessageBackupsDescription": "Sigurnosne kopije sadrže korisnike, korisnikov napredak medija, pojedinosti knjižničke građe, postavke poslužitelja i slike koje se spremaju u /metadata/items
& /metadata/authors
. Sigurnosne kopije ne sadrže niti jednu datoteku iz mapa knjižnice.",
"MessageBackupsLocationEditNote": "Napomena: Uređivanje lokacije za sigurnosne kopije ne premješta ili mijenja postojeće sigurnosne kopije",
"MessageBackupsLocationNoEditNote": "Napomena: Lokacija za sigurnosne kopije zadana je kroz varijablu okoline i ovdje se ne može izmijeniti.",
@@ -853,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Pokreni svaki {0} u {1}",
"MessageSearchResultsFor": "Rezultati pretrage za",
"MessageSelected": "{0} odabrano",
+ "MessageSeriesSequenceCannotContainSpaces": "Slijed serijala ne može sadržavati praznine",
"MessageServerCouldNotBeReached": "Nije moguće pristupiti poslužitelju",
"MessageSetChaptersFromTracksDescription": "Postavi poglavlja koristeći se zvučnom datotekom kao poglavljem i nazivom datoteke kao naslovom poglavlja",
"MessageShareExpirationWillBe": "Vrijeme isteka će biti {0}",
@@ -971,6 +975,8 @@
"ToastCachePurgeFailed": "Čišćenje predmemorije nije uspjelo",
"ToastCachePurgeSuccess": "Predmemorija uspješno očišćena",
"ToastChaptersHaveErrors": "Poglavlja imaju pogreške",
+ "ToastChaptersInvalidShiftAmountLast": "Neispravna vrijednost pomaka. Početak zadnjeg poglavlja bio bi nakon duljine trajanja ove zvučne knjige.",
+ "ToastChaptersInvalidShiftAmountStart": "Neispravna vrijednost pomaka. Trajanje prvog poglavlja bilo bi nula ili negativno i drugo poglavlje bi ga prepisalo. Povećajte vrijeme početka drugog poglavlja.",
"ToastChaptersMustHaveTitles": "Poglavlja moraju imati naslove",
"ToastChaptersRemoved": "Poglavlja uklonjena",
"ToastChaptersUpdated": "Poglavlja su ažurirana",
diff --git a/client/strings/it.json b/client/strings/it.json
index da73d66f..41c06175 100644
--- a/client/strings/it.json
+++ b/client/strings/it.json
@@ -13,7 +13,7 @@
"ButtonBatchEditPopulateFromExisting": "Popola da esistente",
"ButtonBatchEditPopulateMapDetails": "Inserisci i dettagli della mappa",
"ButtonBrowseForFolder": "Per Cartella",
- "ButtonCancel": "Cancella",
+ "ButtonCancel": "Annulla",
"ButtonCancelEncode": "Ferma la codifica",
"ButtonChangeRootPassword": "Cambia la Password di root",
"ButtonCheckAndDownloadNewEpisodes": "Controlla & scarica i nuovi episodi",
@@ -281,8 +281,8 @@
"LabelCollections": "Raccolte",
"LabelComplete": "Completo",
"LabelConfirmPassword": "Conferma Password",
- "LabelContinueListening": "Continua ad Ascoltare",
- "LabelContinueReading": "Continua la Lettura",
+ "LabelContinueListening": "Continua l'ascolto",
+ "LabelContinueReading": "Continua la lettura",
"LabelContinueSeries": "Continua serie",
"LabelCover": "Copertina",
"LabelCoverImageURL": "Indirizzo della cover URL",
@@ -708,6 +708,7 @@
"MessageAddToPlayerQueue": "Aggiungi alla coda di riproduzione",
"MessageAppriseDescription": "Per utilizzare questa funzione è necessario disporre di un'istanza di Apprise API in esecuzione o un'API che gestirà quelle stesse richieste. http://192.168.1.1:8337
Allora dovrai mettere http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Assicurati di utilizzare l'ASIN della regione Audible corretta, non di Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "Riavvia il tuo server dopo aver salvato per applicare le modifiche OIDC.",
"MessageBackupsDescription": "I backup includono utenti, progressi degli utenti, dettagli sugli elementi della libreria, impostazioni del server e immagini archiviate in /metadata/items
& /metadata/authors
. I backup non includono i file archiviati nelle cartelle della libreria.",
"MessageBackupsLocationEditNote": "Nota: l'aggiornamento della posizione di backup non sposterà o modificherà i backup esistenti",
"MessageBackupsLocationNoEditNote": "Nota: la posizione del backup viene impostata tramite una variabile di ambiente e non può essere modificata qui.",
@@ -855,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Esegui ogni {0} alle {1}",
"MessageSearchResultsFor": "cerca risultati per",
"MessageSelected": "{0} selezionati",
+ "MessageSeriesSequenceCannotContainSpaces": "La sequenza della serie non può contenere spazi",
"MessageServerCouldNotBeReached": "Impossibile raggiungere il server",
"MessageSetChaptersFromTracksDescription": "Impostare i capitoli utilizzando ciascun file audio come capitolo e il titolo del capitolo come nome del file audio",
"MessageShareExpirationWillBe": "Scadrà tra {0}",
diff --git a/client/strings/pl.json b/client/strings/pl.json
index 026d7c49..e1822755 100644
--- a/client/strings/pl.json
+++ b/client/strings/pl.json
@@ -177,6 +177,7 @@
"HeaderPlaylist": "Playlista",
"HeaderPlaylistItems": "Pozycje listy odtwarzania",
"HeaderPodcastsToAdd": "Podcasty do dodania",
+ "HeaderPresets": "Ustawienia wstępne",
"HeaderPreviewCover": "Podgląd okładki",
"HeaderRSSFeedGeneral": "Szczegóły RSS",
"HeaderRSSFeedIsOpen": "Kanał RSS jest otwarty",
@@ -219,6 +220,7 @@
"LabelAccountTypeAdmin": "Administrator",
"LabelAccountTypeGuest": "Gość",
"LabelAccountTypeUser": "Użytkownik",
+ "LabelActivities": "Aktywności",
"LabelActivity": "Aktywność",
"LabelAddToCollection": "Dodaj do kolekcji",
"LabelAddToCollectionBatch": "Dodaj {0} książki do kolekcji",
@@ -228,6 +230,7 @@
"LabelAddedDate": "Dodano {0}",
"LabelAdminUsersOnly": "Tylko użytkownicy administracyjni",
"LabelAll": "Wszystkie",
+ "LabelAllEpisodesDownloaded": "Wszystkie odcinki pobrane",
"LabelAllUsers": "Wszyscy użytkownicy",
"LabelAllUsersExcludingGuests": "Wszyscy użytkownicy z wyłączeniem gości",
"LabelAllUsersIncludingGuests": "Wszyscy użytkownicy, łącznie z gośćmi",
@@ -245,6 +248,7 @@
"LabelAutoFetchMetadata": "Automatycznie pobierz metadane",
"LabelAutoFetchMetadataHelp": "Pobiera metadane dotyczące tytułu, autora i serii, aby usprawnić przesyłanie. Po przesłaniu może być konieczne dopasowanie dodatkowych metadanych.",
"LabelAutoLaunch": "Uruchom automatycznie",
+ "LabelAutoLaunchDescription": "Automatyczne przekierowanie do dostawcy uwierzytelniania podczas przechodzenia na stronę logowania (ręczna zamiana ścieżki /login?autoLaunch=0
)",
"LabelAutoRegister": "Automatyczna rejestracja",
"LabelAutoRegisterDescription": "Automatycznie utwórz nowych użytkowników po zalogowaniu",
"LabelBackToUser": "Powrót",
@@ -282,6 +286,7 @@
"LabelContinueSeries": "Kontynuuj serię",
"LabelCover": "Okładka",
"LabelCoverImageURL": "URL okładki",
+ "LabelCoverProvider": "Dostawca okładki",
"LabelCreatedAt": "Utworzone",
"LabelCronExpression": "Wyrażenie CRON",
"LabelCurrent": "Aktualny",
diff --git a/client/strings/ru.json b/client/strings/ru.json
index ccfc15f0..07a786a1 100644
--- a/client/strings/ru.json
+++ b/client/strings/ru.json
@@ -177,6 +177,7 @@
"HeaderPlaylist": "Плейлист",
"HeaderPlaylistItems": "Элементы списка воспроизведения",
"HeaderPodcastsToAdd": "Подкасты для добавления",
+ "HeaderPresets": "Пресеты",
"HeaderPreviewCover": "Предпросмотр обложки",
"HeaderRSSFeedGeneral": "Сведения о RSS",
"HeaderRSSFeedIsOpen": "RSS-канал открыт",
@@ -211,15 +212,15 @@
"HeaderUsers": "Пользователи",
"HeaderYearReview": "Итоги {0} года",
"HeaderYourStats": "Ваша статистика",
- "LabelAbridged": "Сокращенное издание",
+ "LabelAbridged": "Сокращенная форма",
"LabelAbridgedChecked": "Сокращено (отмечено)",
- "LabelAbridgedUnchecked": "Без сокращений (не отмечено)",
+ "LabelAbridgedUnchecked": "Полное издание (не отмечено)",
"LabelAccessibleBy": "Доступ",
"LabelAccountType": "Тип учетной записи",
"LabelAccountTypeAdmin": "Администратор",
"LabelAccountTypeGuest": "Гость",
"LabelAccountTypeUser": "Пользователь",
- "LabelActivities": "Мероприятия",
+ "LabelActivities": "События",
"LabelActivity": "Активность",
"LabelAddToCollection": "Добавить в коллекцию",
"LabelAddToCollectionBatch": "Добавить {0} книг в коллекцию",
@@ -345,8 +346,8 @@
"LabelExample": "Пример",
"LabelExpandSeries": "Развернуть серию",
"LabelExpandSubSeries": "Развернуть подсерию",
- "LabelExplicit": "Явный",
- "LabelExplicitChecked": "Явный (отмечено)",
+ "LabelExplicit": "18+",
+ "LabelExplicitChecked": "18+ (отмечено)",
"LabelExplicitUnchecked": "Не явно (не отмечено)",
"LabelExportOPML": "Экспорт OPML",
"LabelFeedURL": "URL канала",
@@ -530,6 +531,7 @@
"LabelReleaseDate": "Дата выхода",
"LabelRemoveAllMetadataAbs": "Удалите все файлы metadata.abs",
"LabelRemoveAllMetadataJson": "Удалите все файлы metadata.json",
+ "LabelRemoveAudibleBranding": "Удалить вступление и концовку Audible из глав",
"LabelRemoveCover": "Удалить обложку",
"LabelRemoveMetadataFile": "Удаление файлов метаданных в папках элементов библиотеки",
"LabelRemoveMetadataFileHelp": "Удалите все файлы metadata.json и metadata.abs из ваших папок {0}.",
@@ -706,6 +708,7 @@
"MessageAddToPlayerQueue": "Добавить в очередь проигрывателя",
"MessageAppriseDescription": "Для использования этой функции необходимо иметь запущенный экземпляр Apprise API или api которое обрабатывает те же самые запросы. http://192.168.1.1:8337
тогда нужно указать http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Убедитесь, что вы используете ASIN из правильной региональной зоны Audible, а не из Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "Перезапустите ваш сервер после сохранения для применения изменений в OIDC.",
"MessageBackupsDescription": "Бэкап включает пользователей, прогресс пользователей, данные элементов библиотеки, настройки сервера и изображения хранящиеся в /metadata/items
и /metadata/authors
. Бэкапы НЕ сохраняют файлы из папок библиотек.",
"MessageBackupsLocationEditNote": "Примечание: Обновление местоположения резервной копии не приведет к перемещению или изменению существующих резервных копий",
"MessageBackupsLocationNoEditNote": "Примечание: Местоположение резервного копирования задается с помощью переменной среды и не может быть изменено здесь.",
@@ -853,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Запуск каждые {0} по {1}",
"MessageSearchResultsFor": "Результаты поиска для",
"MessageSelected": "{0} выбрано",
+ "MessageSeriesSequenceCannotContainSpaces": "Последовательность серии должна быть без пропусков",
"MessageServerCouldNotBeReached": "Не удалось связаться с сервером",
"MessageSetChaptersFromTracksDescription": "Установка глав с использованием каждого аудиофайла в качестве главы и заголовка главы в качестве имени аудиофайла",
"MessageShareExpirationWillBe": "Срок действия истекает {0}",
@@ -971,6 +975,8 @@
"ToastCachePurgeFailed": "Не удалось очистить кэш",
"ToastCachePurgeSuccess": "Кэш успешно очищен",
"ToastChaptersHaveErrors": "Главы имеют ошибки",
+ "ToastChaptersInvalidShiftAmountLast": "Некорректное значение сдвига. Начало последней главы будет превышать продолжительность этой аудиокниги.",
+ "ToastChaptersInvalidShiftAmountStart": "Некорректное значение сдвига. Первая глава будет иметь нулевую или отрицательную длину и будет перезаписана второй главой. Увеличьте начальную продолжительность второй главы.",
"ToastChaptersMustHaveTitles": "Главы должны содержать названия",
"ToastChaptersRemoved": "Удалены главы",
"ToastChaptersUpdated": "Обновленные главы",
diff --git a/client/strings/sk.json b/client/strings/sk.json
index 0cca3973..39b3c0ae 100644
--- a/client/strings/sk.json
+++ b/client/strings/sk.json
@@ -470,7 +470,7 @@
"LabelNotificationsMaxQueueSize": "Maximálna dĺžka fronty oznámení",
"LabelNotificationsMaxQueueSizeHelp": "Odosielanie udalostí je ohraničené na jedno oznámenie za sekundu. Novovzniknuté udalosti budú ignorované, ak bude fronta oznámení naplnená. Toto nastavenie zabraňuje nevyžiadanému zahlteniu oznámeniami.",
"LabelNumberOfBooks": "Počet kníh",
- "LabelNumberOfEpisodes": "# epizód",
+ "LabelNumberOfEpisodes": "# z epizód",
"LabelOpenIDAdvancedPermsClaimDescription": "Názov OpenID predpokladá prítomnosť pokročilých povolení pre užívateľské akcie v rámci aplikácie, ktoré sú aplikovateľné na ne-administrátorské role (ak sú nakonfigurované). Ak potvrdenie takýchto pokročilých povolení nie je v odozve prítomné, prístup do ABS bude automaticky zamietnutý. Ak v odozve chýba len niektoré z očakávaných nastavení, tak bude jeho hodnota automaticky nastavená na false
. Uistite sa prosím, že forma odozvy poskytovateľa identity má nasledovnú štruktúru:",
"LabelOpenIDClaims": "Ak ponecháte nasledujúce nastavenia prázdne, pokročilé nastavenia skupín a povolení nebudú aktivované a automaticky bude nastavená skupina 'Užívateľ'.",
"LabelOpenIDGroupClaimDescription": "Pri názve požiadavky OpenID sa predpokladá, že obsahuje zoznam užívateľských skupín. Bežne označovaný ako groups
. Ak je správne nakonfigurovaný, aplikácia automaticky pridelí role podľa príslušnosti k užívateľským skupinám pod podmienkou, že sú tieto skupiny v požiadavke nazvané (bez ohľadu na veľkosť písmen) ako 'admin', 'user' alebo 'guest'. Požiadavka musí obsahovať zoznam skupín a ak užívateľ patrí do viacerých skupín, aplikácia mu priradí rolu, ktorá zodpovedá skupine s najvyššími prístupovými právami. Ak sa žiadna z poskytnutých skupín nezhoduje, prístup bude zamietnutý.",
@@ -500,12 +500,12 @@
"LabelPodcasts": "Podcasty",
"LabelPort": "Prístav",
"LabelPrefixesToIgnore": "Ignorované predpony (bez ohľadu na veľkosť písmen)",
- "LabelPreventIndexing": "Zabráňte indexovaniu Vášho zdroja službami iTunes a Google podcasts directories",
+ "LabelPreventIndexing": "Zabráni indexácii vašich zdrojov službami iTunes a Google podcast directories",
"LabelPrimaryEbook": "Primárny e-book",
- "LabelProgress": "Pokrok",
+ "LabelProgress": "Stav",
"LabelProvider": "Poskytovateľ",
"LabelProviderAuthorizationValue": "Obsah hlavičky autorizácie",
- "LabelPubDate": "Dátum vydania",
+ "LabelPubDate": "Dátum publikovania",
"LabelPublishYear": "Rok vydania",
"LabelPublishedDate": "Vydané {0}",
"LabelPublishedDecade": "Dekáda vydania",
@@ -520,7 +520,7 @@
"LabelRSSFeedURL": "URL RSS zdroja",
"LabelRandomly": "Náhodne",
"LabelReAddSeriesToContinueListening": "Znova pridať série do pokračujúceho počúvania",
- "LabelRead": "Čítať",
+ "LabelRead": "Načítať",
"LabelReadAgain": "Čítať znova",
"LabelReadEbookWithoutProgress": "Čítať e-knihu bez sledovania pokroku",
"LabelRecentSeries": "Posledné série",
@@ -531,6 +531,7 @@
"LabelReleaseDate": "Dátum vydania",
"LabelRemoveAllMetadataAbs": "Odstrániť všetky súbory metadata.abs",
"LabelRemoveAllMetadataJson": "Odstrániť všetky súbory metadata.json",
+ "LabelRemoveAudibleBranding": "Odstrániť z kapitol Audible intro a outro",
"LabelRemoveCover": "Odstrániť prebal",
"LabelRemoveMetadataFile": "Odstrániť súbory metadát z priečinkov položiek v knižnici",
"LabelRemoveMetadataFileHelp": "Odstrániť všetky súbory metadata.json a metadata.abs vo Vašich {0} priečinkoch.",
@@ -547,7 +548,7 @@
"LabelSendEbookToDevice": "Poslať e-knihu do...",
"LabelSequence": "Postupnosť",
"LabelSerial": "Na pokračovanie",
- "LabelSeries": "Séria",
+ "LabelSeries": "Série",
"LabelSeriesName": "Názov série",
"LabelSeriesProgress": "Pokrok série",
"LabelServerLogLevel": "Úroveň logovania servera",
@@ -606,7 +607,7 @@
"LabelSortAscending": "Vzostupne",
"LabelSortDescending": "Zostupne",
"LabelSortPubDate": "Zoradiť podľa dátumu vydania",
- "LabelStart": "Začiatok",
+ "LabelStart": "Spustiť",
"LabelStartTime": "Čas spustenia",
"LabelStarted": "Začaté",
"LabelStartedAt": "Začaté v",
@@ -614,7 +615,7 @@
"LabelStatsAuthors": "Autori",
"LabelStatsBestDay": "Najlepší deň",
"LabelStatsDailyAverage": "Denný priemer",
- "LabelStatsDays": "Dni",
+ "LabelStatsDays": "Dní",
"LabelStatsDaysListened": "Dní počúvania",
"LabelStatsHours": "Hodiny",
"LabelStatsInARow": "v rade",
@@ -647,7 +648,7 @@
"LabelTimeLeft": "{0} ponechaných",
"LabelTimeListened": "Čas počúvania",
"LabelTimeListenedToday": "Dnešný čas počúvania",
- "LabelTimeRemaining": "{0} zostávajúcich",
+ "LabelTimeRemaining": "Zostáva {0}",
"LabelTimeToShift": "Čas posunutia v sekundách",
"LabelTitle": "Názov",
"LabelToolsEmbedMetadata": "Vlož metadáta",
@@ -684,7 +685,7 @@
"LabelUseChapterTrack": "Použiť stopu kapitoly",
"LabelUseFullTrack": "Použiť celú stopu",
"LabelUseZeroForUnlimited": "Použito 0 pre neobmedzené",
- "LabelUser": "Užívateľ",
+ "LabelUser": "Používateľ",
"LabelUsername": "Prihlasovacie meno",
"LabelValue": "Hodnota",
"LabelVersion": "Verzia",
@@ -703,10 +704,11 @@
"LabelYourAudiobookDuration": "Dĺžka Vašej audioknihy",
"LabelYourBookmarks": "Vaše záložky",
"LabelYourPlaylists": "Vaše playlisty",
- "LabelYourProgress": "Váš pokrok",
+ "LabelYourProgress": "Váš aktuálny stav",
"MessageAddToPlayerQueue": "Pridať do zoznamu prehrávania",
"MessageAppriseDescription": "Aby ste mohli používať túto funkciumusíte mať k dispozícii inštanciu Apprise API alebo inú, ktorá dokáže spracovávať rovnaké požiadavky/requesty.http://192.168.1.1:8337
, vložte do daného poľa http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Uistite sa, že používate ASIN zo správneho regiónu Audible, nie Amazonu.",
+ "MessageAuthenticationOIDCChangesRestart": "Reštartujte svoj server po uložení, aby mohli byť použité zmeny OIDC.",
"MessageBackupsDescription": "Zálohy pokrývajú používateľov, ich aktuálne stavy počúvania, detaily položiek knižnice, nastavenia servera a obrázky uložené v /metadata/items
a /metadata/authors
. Zálohy neobsahujú súbory v priečinkoch vašich knižníc.",
"MessageBackupsLocationEditNote": "Poznámka: Zmena umiestnenia záloh nepresunie ani nezmení existujúce zálohy",
"MessageBackupsLocationNoEditNote": "Poznámka: Umietnenie záloh je nastavené prostredníctvom premennej prostredia a nie je ho možné zmeniť z tohto miesta.",
@@ -775,10 +777,10 @@
"MessageEmbedFailed": "Vloženie zlyhalo!",
"MessageEmbedFinished": "Vloženie skončené!",
"MessageEmbedQueue": "Zaradené do fronty na vloženie metadát ({0} v zozname)",
- "MessageEpisodesQueuedForDownload": "{0} epizód(-a) v zozname na sťahovanie",
+ "MessageEpisodesQueuedForDownload": "{0} epizód(a) v zozname na sťahovanie",
"MessageEreaderDevices": "Na zaistenie dodania e-kníh môže byť nutné zadanie vyššie uvedenej e-mailovej adresy ako overeného odosielateľa v každom z nižšie vypísaných zariadení.",
"MessageFeedURLWillBe": "URL zdroja bude {0}",
- "MessageFetching": "Prebieha načítanie...",
+ "MessageFetching": "Získavam...",
"MessageForceReScanDescription": "preskenuje všetky súbory ako pri prvom skenovaní. ID3 štítky zvukových súborov, OPF súbory a textové súbory budú nanovo naskenované.",
"MessageImportantNotice": "Dôležité upozornenie!",
"MessageInsertChapterBelow": "Vložte kapitolu nižšie",
@@ -786,7 +788,7 @@
"MessageItemsSelected": "{0} vybraných položiek",
"MessageItemsUpdated": "{0} aktualizovaných položiek",
"MessageJoinUsOn": "Pridajte sa k nám",
- "MessageLoading": "Načítanie...",
+ "MessageLoading": "Načítavam...",
"MessageLoadingFolders": "Načítanie priečinkov...",
"MessageLogsDescription": "Záznamy logovania sú uložené v /metadata/logs
vo forme JSON súborov. Záznamy kritických chýb sú uložené v /metadata/logs/crash_logs.txt
.",
"MessageM4BFailed": "M4B zlyhalo!",
@@ -826,7 +828,7 @@
"MessageNoSeries": "Žiadne série",
"MessageNoTags": "Žiadne štítky",
"MessageNoTasksRunning": "Žiadne prebiehajúce úlohy",
- "MessageNoUpdatesWereNecessary": "Žiadne nutné aktualizácie",
+ "MessageNoUpdatesWereNecessary": "Neboli potrebné žiadne aktualizácie",
"MessageNoUserPlaylists": "Nemáte žiadny playlist",
"MessageNoUserPlaylistsHelp": "Playlisty sú súkromné. Každý playlist môže vidieť iba používateľ, ktorý ho vytvoril.",
"MessageNotYetImplemented": "Ešte neimplementované",
@@ -854,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Spustiť každú {0} o {1}",
"MessageSearchResultsFor": "Výsledky vyhľadávania pre",
"MessageSelected": "{0} vybrané",
+ "MessageSeriesSequenceCannotContainSpaces": "Poradie série nemôže obsahovať medzery",
"MessageServerCouldNotBeReached": "Nepodarilo sa pripojiť na server",
"MessageSetChaptersFromTracksDescription": "Nastaviť jednotlivé zvukové súbory ako kapitoly a názvy zvukových súborov ako názvy týchto kapitol",
"MessageShareExpirationWillBe": "Expiruje {0}",
@@ -907,8 +910,8 @@
"NoteChangeRootPassword": "Root používateľ je jediný používateľ, ktorý môže mať prázdne heslo",
"NoteChapterEditorTimes": "Poznámka: Prvá kapitola musí vždy začínať v 0:00 a začiatok poslednej kapitoly nemôže prekročiť trvanie tejto audioknihy.",
"NoteFolderPicker": "Poznámka: Priečinky, ktoré už boli priradené, sa ďalej nezobrazujú",
- "NoteRSSFeedPodcastAppsHttps": "Varovanie: Väčšina podcastových aplikácií vyžaduje, aby URL RSS zdroja vyžívala HTTPS",
- "NoteRSSFeedPodcastAppsPubDate": "Varovanie: 1 alebo viacero vašich epizód neobsahuje infomáciu o dátume vydania. Niektoré podcastové aplikácie ju vyžadujú.",
+ "NoteRSSFeedPodcastAppsHttps": "Varovanie: Väčšina podcastových aplikácií požaduje URL RSS zdroja s HTTPS",
+ "NoteRSSFeedPodcastAppsPubDate": "Varovanie: 1 alebo viac vašich epizód neobsahuje infomáciu o dátum vydania. Niektoré podcastové ju vyžadujú.",
"NoteUploaderFoldersWithMediaFiles": "Priečinky obsahujúce súbory médií budú považované za samostatné položky knižnice.",
"NoteUploaderOnlyAudioFiles": "Ak budú nahraté iba zvukové súbory, každý zvukový súbor bude považovaný za samostatnú audioknihu.",
"NoteUploaderUnsupportedFiles": "Nepodporované súbory budú ignorované. Pri výbere alebo prenesení priečinka, budú všetky súbory, ktoré nie sú v priečinku niektorej z položiek, ignorované.",
@@ -972,6 +975,8 @@
"ToastCachePurgeFailed": "Vyčistenie vyrovnávacej pamäte zlyhalo",
"ToastCachePurgeSuccess": "Vyrovnávacia pamäť vyčistená",
"ToastChaptersHaveErrors": "Kapitoly obsahujú chyby",
+ "ToastChaptersInvalidShiftAmountLast": "Neplatná hodnota veľkosti posunutia. Začiatok poslednej kapitoly by ležal za koncom audioknihy.",
+ "ToastChaptersInvalidShiftAmountStart": "Nesprávna hodnota posunutia. Prvá kapitola by mala nulovú alebo zápornú dĺžku a bola by nahradená nasledujúcou kapitolou. Navýšte čas začiatku druhej kapitoly.",
"ToastChaptersMustHaveTitles": "Kapitoly musia mať názvy",
"ToastChaptersRemoved": "Kapitoly boli odstránené",
"ToastChaptersUpdated": "Kapitoly boli aktualizované",
diff --git a/client/strings/sl.json b/client/strings/sl.json
index 8e0d23ac..2f028403 100644
--- a/client/strings/sl.json
+++ b/client/strings/sl.json
@@ -531,6 +531,7 @@
"LabelReleaseDate": "Datum izdaje",
"LabelRemoveAllMetadataAbs": "Odstrani vse datoteke metadata.abs",
"LabelRemoveAllMetadataJson": "Odstrani vse datoteke metadata.json",
+ "LabelRemoveAudibleBranding": "Odstrani Audible uvod in zaključek iz poglavij",
"LabelRemoveCover": "Odstrani naslovnico",
"LabelRemoveMetadataFile": "Odstrani datoteke z metapodatki v mapah elementov knjižnice",
"LabelRemoveMetadataFileHelp": "Odstrani vse datoteke metadata.json in metadata.abs v svojih mapah {0}.",
@@ -707,6 +708,7 @@
"MessageAddToPlayerQueue": "Dodaj v čakalno vrsto predvajalnika",
"MessageAppriseDescription": "Če želite uporabljati to funkcijo, morate imeti zagnano namestitev API Apprise ali API, ki bo obravnavala te iste zahteve. http://192.168.1.1:8337
, bi morali vnesti http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Prepričajte se, da uporabljate ASIN iz pravilne zvočne regije, ne iz Amazona.",
+ "MessageAuthenticationOIDCChangesRestart": "Za uveljavitev OIDC sprememb, po shranjevanju znova zaženite strežnik.",
"MessageBackupsDescription": "Varnostne kopije vključujejo uporabnike, napredek uporabnikov, podrobnosti elementov knjižnice, nastavitve strežnika in slike, shranjene v /metadata/items
& /metadata/authors
. Varnostne kopije ne vključujejo datotek, shranjenih v mapah vaše knjižnice.",
"MessageBackupsLocationEditNote": "Opomba: Posodabljanje lokacije varnostne kopije ne bo premaknilo ali spremenilo obstoječih varnostnih kopij",
"MessageBackupsLocationNoEditNote": "Opomba: Lokacija varnostne kopije je nastavljena s spremenljivko okolja in je tu ni mogoče spremeniti.",
@@ -854,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Zaženi vsakih {0} ob {1}",
"MessageSearchResultsFor": "Rezultati iskanja za",
"MessageSelected": "{0} izbrano",
+ "MessageSeriesSequenceCannotContainSpaces": "Zaporedje serij ne sme vsebovati presledkov",
"MessageServerCouldNotBeReached": "Strežnika ni bilo mogoče doseči",
"MessageSetChaptersFromTracksDescription": "Nastavi poglavja z uporabo vsake zvočne datoteke kot poglavja in naslova poglavja kot imena zvočne datoteke",
"MessageShareExpirationWillBe": "Potečeno bo {0}",
@@ -972,6 +975,8 @@
"ToastCachePurgeFailed": "Čiščenje predpomnilnika ni uspelo",
"ToastCachePurgeSuccess": "Predpomnilnik je bil uspešno očiščen",
"ToastChaptersHaveErrors": "Poglavja imajo napake",
+ "ToastChaptersInvalidShiftAmountLast": "Neveljavna vrednost zamika. Začetni čas zadnjega poglavja bi presegel trajanje te zvočne knjige.",
+ "ToastChaptersInvalidShiftAmountStart": "Neveljavna vrednost zamika. Prvo poglavje bi imelo ničelno ali negativno dolžino in bi ga prepisalo drugo poglavje. Povečajte začetno trajanje drugega poglavja.",
"ToastChaptersMustHaveTitles": "Poglavja morajo imeti naslove",
"ToastChaptersRemoved": "Poglavja so odstranjena",
"ToastChaptersUpdated": "Poglavja so posodobljena",
diff --git a/client/strings/uk.json b/client/strings/uk.json
index 4a906b78..51e5f69e 100644
--- a/client/strings/uk.json
+++ b/client/strings/uk.json
@@ -708,6 +708,7 @@
"MessageAddToPlayerQueue": "Додати до черги відтворення",
"MessageAppriseDescription": "Щоб скористатися цією функцією, вам потрібно мати запущену Apprise API або API, що оброблятиме ті ж запити. http://192.168.1.1:8337
, то необхідно вказати адресу http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "Переконайтесь, що ви використовуєте ASIN з правильної регіональної Audible зони, а не з Amazon.",
+ "MessageAuthenticationOIDCChangesRestart": "Перезавантажте сервер після збереження, щоб застосувати зміни OIDC.",
"MessageBackupsDescription": "Резервні копії містять користувачів, прогрес, подробиці елементів бібліотеки, налаштування сервера та зображення з /metadata/items
та /metadata/authors
. Резервні копії не містять жодних файлів з тек бібліотеки.",
"MessageBackupsLocationEditNote": "Примітка: оновлення розташування резервної копії не переносить та не змінює існуючих копій",
"MessageBackupsLocationNoEditNote": "Примітка: розташування резервної копії встановлюється за допомогою змінної середовища та не може бути змінене тут.",
@@ -817,7 +818,7 @@
"MessageNoItems": "Елементи відсутні",
"MessageNoItemsFound": "Елементів не знайдено",
"MessageNoListeningSessions": "Сеанси прослуховування відсутні",
- "MessageNoLogs": "Немає журнал",
+ "MessageNoLogs": "Немає журнали",
"MessageNoMediaProgress": "Прогрес відсутній",
"MessageNoNotifications": "Сповіщення відсутні",
"MessageNoPodcastFeed": "Невірний подкаст: Немає каналу",
@@ -855,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "Запуск кожні {0} о {1}",
"MessageSearchResultsFor": "Результати пошуку для",
"MessageSelected": "Вибрано: {0}",
+ "MessageSeriesSequenceCannotContainSpaces": "Послідовність серій не може містити пробілів",
"MessageServerCouldNotBeReached": "Не вдалося підключитися до сервера",
"MessageSetChaptersFromTracksDescription": "Створити глави з аудіодоріжок, встановивши назви файлів за заголовки",
"MessageShareExpirationWillBe": "Термін сплине за {0}",
diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json
index b6365b6e..0f9f4a99 100644
--- a/client/strings/zh-cn.json
+++ b/client/strings/zh-cn.json
@@ -21,7 +21,7 @@
"ButtonChooseFiles": "选择文件",
"ButtonClearFilter": "清除过滤器",
"ButtonCloseFeed": "关闭源",
- "ButtonCloseSession": "关闭开放会话",
+ "ButtonCloseSession": "关闭活动会话",
"ButtonCollections": "收藏",
"ButtonConfigureScanner": "配置扫描",
"ButtonCreate": "创建",
@@ -177,6 +177,7 @@
"HeaderPlaylist": "播放列表",
"HeaderPlaylistItems": "播放列表项目",
"HeaderPodcastsToAdd": "要添加的播客",
+ "HeaderPresets": "预设",
"HeaderPreviewCover": "预览封面",
"HeaderRSSFeedGeneral": "RSS 详细信息",
"HeaderRSSFeedIsOpen": "RSS 源已打开",
@@ -530,6 +531,7 @@
"LabelReleaseDate": "发布日期",
"LabelRemoveAllMetadataAbs": "删除所有 metadata.abs 文件",
"LabelRemoveAllMetadataJson": "删除所有 metadata.json 文件",
+ "LabelRemoveAudibleBranding": "删除章节中的 Audible 简介和结尾",
"LabelRemoveCover": "移除封面",
"LabelRemoveMetadataFile": "删除库项目文件夹中的元数据文件",
"LabelRemoveMetadataFileHelp": "删除 {0} 文件夹中的所有 metadata.json 和 metadata.abs 文件.",
@@ -706,6 +708,7 @@
"MessageAddToPlayerQueue": "添加到播放队列",
"MessageAppriseDescription": "要使用此功能,你需要运行一个 Apprise API 实例或一个可以处理这些相同请求的 API. http://192.168.1.1:8337
, 那么你可以输入 http://192.168.1.1:8337/notify
.",
"MessageAsinCheck": "确保你使用的 ASIN 来自正确的 Audible 地区, 而不是亚马逊.",
+ "MessageAuthenticationOIDCChangesRestart": "保存后重新启动服务器以应用 OIDC 更改.",
"MessageBackupsDescription": "备份包括用户, 用户进度, 媒体库项目详细信息, 服务器设置和图像, 存储在 /metadata/items
& /metadata/authors
. 备份不包括存储在你的媒体库文件夹中的任何文件.",
"MessageBackupsLocationEditNote": "注意: 更新备份位置不会移动或修改现有备份",
"MessageBackupsLocationNoEditNote": "注意: 备份位置是通过环境变量设置的, 不能在此处更改.",
@@ -853,6 +856,7 @@
"MessageScheduleRunEveryWeekdayAtTime": "每隔 {0} 在 {1} 运行一次",
"MessageSearchResultsFor": "搜索结果",
"MessageSelected": "{0} 已选择",
+ "MessageSeriesSequenceCannotContainSpaces": "系列序列不能包含空格",
"MessageServerCouldNotBeReached": "无法访问服务器",
"MessageSetChaptersFromTracksDescription": "把每个音频文件设置为章节并将章节标题设置为音频文件名",
"MessageShareExpirationWillBe": "到期日期为 {0}",
@@ -971,6 +975,8 @@
"ToastCachePurgeFailed": "清除缓存失败",
"ToastCachePurgeSuccess": "缓存清除成功",
"ToastChaptersHaveErrors": "章节有错误",
+ "ToastChaptersInvalidShiftAmountLast": "偏移量无效. 最后一章的开始时间将超过这本有声读物的持续时间.",
+ "ToastChaptersInvalidShiftAmountStart": "偏移量无效. 第一章的长度将为零或负数, 并会被第二章覆盖. 请增加第二章的起始时长.",
"ToastChaptersMustHaveTitles": "章节必须有标题",
"ToastChaptersRemoved": "已删除章节",
"ToastChaptersUpdated": "章节已更新",
diff --git a/package-lock.json b/package-lock.json
index 63c8fbc7..a8074794 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "audiobookshelf",
- "version": "2.22.0",
+ "version": "2.24.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "audiobookshelf",
- "version": "2.22.0",
+ "version": "2.24.0",
"license": "GPL-3.0",
"dependencies": {
"axios": "^0.27.2",
diff --git a/package.json b/package.json
index c68aa981..d4831736 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "audiobookshelf",
- "version": "2.22.0",
+ "version": "2.24.0",
"buildNumber": 1,
"description": "Self-hosted audiobook and podcast server",
"main": "index.js",
diff --git a/server/Server.js b/server/Server.js
index 0e53d3e9..17c959c0 100644
--- a/server/Server.js
+++ b/server/Server.js
@@ -310,7 +310,7 @@ class Server {
})
)
router.use(express.urlencoded({ extended: true, limit: '5mb' }))
- router.use(express.json({ limit: '5mb' }))
+ router.use(express.json({ limit: '10mb' }))
router.use('/api', this.auth.ifAuthNeeded(this.authMiddleware.bind(this)), this.apiRouter.router)
router.use('/hls', this.hlsRouter.router)
@@ -395,10 +395,19 @@ class Server {
})
router.get('/healthcheck', (req, res) => res.sendStatus(200))
- this.server.listen(this.Port, this.Host, () => {
- if (this.Host) Logger.info(`Listening on http://${this.Host}:${this.Port}`)
- else Logger.info(`Listening on port :${this.Port}`)
- })
+ const unixSocketPrefix = 'unix/'
+ if (this.Host?.startsWith(unixSocketPrefix)) {
+ const sockPath = this.Host.slice(unixSocketPrefix.length)
+ this.server.listen(sockPath, async () => {
+ await fs.chmod(sockPath, 0o666)
+ Logger.info(`Listening on unix socket ${sockPath}`)
+ })
+ } else {
+ this.server.listen(this.Port, this.Host, () => {
+ if (this.Host) Logger.info(`Listening on http://${this.Host}:${this.Port}`)
+ else Logger.info(`Listening on port :${this.Port}`)
+ })
+ }
// Start listening for socket connections
SocketAuthority.initialize(this)
diff --git a/server/controllers/FileSystemController.js b/server/controllers/FileSystemController.js
index d0b190a4..7629f9ee 100644
--- a/server/controllers/FileSystemController.js
+++ b/server/controllers/FileSystemController.js
@@ -84,49 +84,67 @@ class FileSystemController {
*/
async checkPathExists(req, res) {
if (!req.user.canUpload) {
- Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to check path exists`)
+ Logger.error(`[FileSystemController] User "${req.user.username}" without upload permissions attempting to check path exists`)
return res.sendStatus(403)
}
- const { filepath, directory, folderPath } = req.body
+ const { directory, folderPath } = req.body
- if (!filepath?.length || typeof filepath !== 'string') {
+ if (!directory?.length || typeof directory !== 'string' || !folderPath?.length || typeof folderPath !== 'string') {
+ Logger.error(`[FileSystemController] Invalid request body: ${JSON.stringify(req.body)}`)
+ return res.status(400).json({
+ error: 'Invalid request body'
+ })
+ }
+
+ // Check that library folder exists
+ const libraryFolder = await Database.libraryFolderModel.findOne({
+ where: {
+ path: folderPath
+ }
+ })
+
+ if (!libraryFolder) {
+ Logger.error(`[FileSystemController] Library folder not found: ${folderPath}`)
+ return res.sendStatus(404)
+ }
+
+ const filepath = Path.posix.join(libraryFolder.path, directory)
+ // Ensure filepath is inside library folder (prevents directory traversal)
+ if (!filepath.startsWith(libraryFolder.path)) {
+ Logger.error(`[FileSystemController] Filepath is not inside library folder: ${filepath}`)
return res.sendStatus(400)
}
- const exists = await fs.pathExists(filepath)
-
- if (exists) {
+ if (await fs.pathExists(filepath)) {
return res.json({
exists: true
})
}
- // If directory and folderPath are passed in, check if a library item exists in a subdirectory
+ // Check if a library item exists in a subdirectory
// See: https://github.com/advplyr/audiobookshelf/issues/4146
- if (typeof directory === 'string' && typeof folderPath === 'string' && directory.length > 0 && folderPath.length > 0) {
- const cleanedDirectory = directory.split('/').filter(Boolean).join('/')
- if (cleanedDirectory.includes('/')) {
- // Can only be 2 levels deep
- const possiblePaths = []
- const subdir = Path.dirname(directory)
- possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, subdir)))
- if (subdir.includes('/')) {
- possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, Path.dirname(subdir))))
- }
+ const cleanedDirectory = directory.split('/').filter(Boolean).join('/')
+ if (cleanedDirectory.includes('/')) {
+ // Can only be 2 levels deep
+ const possiblePaths = []
+ const subdir = Path.dirname(directory)
+ possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, subdir)))
+ if (subdir.includes('/')) {
+ possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, Path.dirname(subdir))))
+ }
- const libraryItem = await Database.libraryItemModel.findOne({
- where: {
- path: possiblePaths
- }
+ const libraryItem = await Database.libraryItemModel.findOne({
+ where: {
+ path: possiblePaths
+ }
+ })
+
+ if (libraryItem) {
+ return res.json({
+ exists: true,
+ libraryItemTitle: libraryItem.title
})
-
- if (libraryItem) {
- return res.json({
- exists: true,
- libraryItemTitle: libraryItem.title
- })
- }
}
}
diff --git a/server/controllers/PodcastController.js b/server/controllers/PodcastController.js
index 6395e05b..1ebe1d11 100644
--- a/server/controllers/PodcastController.js
+++ b/server/controllers/PodcastController.js
@@ -9,6 +9,7 @@ const fs = require('../libs/fsExtra')
const { getPodcastFeed, findMatchingEpisodes } = require('../utils/podcastUtils')
const { getFileTimestampsWithIno, filePathToPOSIX } = require('../utils/fileUtils')
const { validateUrl } = require('../utils/index')
+const htmlSanitizer = require('../utils/htmlSanitizer')
const Scanner = require('../scanner/Scanner')
const CoverManager = require('../managers/CoverManager')
@@ -404,6 +405,15 @@ class PodcastController {
const supportedStringKeys = ['title', 'subtitle', 'description', 'pubDate', 'episode', 'season', 'episodeType']
for (const key in req.body) {
if (supportedStringKeys.includes(key) && typeof req.body[key] === 'string') {
+ // Sanitize description HTML
+ if (key === 'description' && req.body[key]) {
+ const sanitizedDescription = htmlSanitizer.sanitize(req.body[key])
+ if (sanitizedDescription !== req.body[key]) {
+ Logger.debug(`[PodcastController] Sanitized description from "${req.body[key]}" to "${sanitizedDescription}"`)
+ req.body[key] = sanitizedDescription
+ }
+ }
+
updatePayload[key] = req.body[key]
} else if (key === 'chapters' && Array.isArray(req.body[key]) && req.body[key].every((ch) => typeof ch === 'object' && ch.title && ch.start)) {
updatePayload[key] = req.body[key]
diff --git a/server/managers/AbMergeManager.js b/server/managers/AbMergeManager.js
index f6a56160..3611d294 100644
--- a/server/managers/AbMergeManager.js
+++ b/server/managers/AbMergeManager.js
@@ -203,7 +203,15 @@ class AbMergeManager {
// Move library item tracks to cache
for (const [index, trackPath] of task.data.originalTrackPaths.entries()) {
const trackFilename = Path.basename(trackPath)
- const moveToPath = Path.join(task.data.itemCachePath, trackFilename)
+ let moveToPath = Path.join(task.data.itemCachePath, trackFilename)
+
+ // If the track is the same as the temp file, we need to rename it to avoid overwriting it
+ if (task.data.tempFilepath === moveToPath) {
+ const trackExtname = Path.extname(task.data.tempFilepath)
+ const newTrackFilename = Path.basename(task.data.tempFilepath, trackExtname) + '.backup' + trackExtname
+ moveToPath = Path.join(task.data.itemCachePath, newTrackFilename)
+ }
+
Logger.debug(`[AbMergeManager] Backing up original track "${trackPath}" to ${moveToPath}`)
if (index === 0) {
// copy the first track to the cache directory
diff --git a/server/models/Book.js b/server/models/Book.js
index 0dd0b785..96371f3a 100644
--- a/server/models/Book.js
+++ b/server/models/Book.js
@@ -377,8 +377,17 @@ class Book extends Model {
if (typeof payload.metadata[key] == 'number') {
payload.metadata[key] = String(payload.metadata[key])
}
-
+
if ((typeof payload.metadata[key] === 'string' || payload.metadata[key] === null) && this[key] !== payload.metadata[key]) {
+ // Sanitize description HTML
+ if (key === 'description' && payload.metadata[key]) {
+ const sanitizedDescription = htmlSanitizer.sanitize(payload.metadata[key])
+ if (sanitizedDescription !== payload.metadata[key]) {
+ Logger.debug(`[Book] "${this.title}" Sanitized description from "${payload.metadata[key]}" to "${sanitizedDescription}"`)
+ payload.metadata[key] = sanitizedDescription
+ }
+ }
+
this[key] = payload.metadata[key] || null
if (key === 'title') {
diff --git a/server/models/MediaProgress.js b/server/models/MediaProgress.js
index a4a4185c..af3cbc5f 100644
--- a/server/models/MediaProgress.js
+++ b/server/models/MediaProgress.js
@@ -246,9 +246,10 @@ class MediaProgress extends Model {
// For local sync
if (progressPayload.lastUpdate) {
this.updatedAt = progressPayload.lastUpdate
+ this.changed('updatedAt', true)
}
- return this.save()
+ return this.save({ silent: !!progressPayload.lastUpdate })
}
}
diff --git a/server/models/Podcast.js b/server/models/Podcast.js
index fa27821d..d99a66df 100644
--- a/server/models/Podcast.js
+++ b/server/models/Podcast.js
@@ -2,6 +2,7 @@ const { DataTypes, Model } = require('sequelize')
const { getTitlePrefixAtEnd, getTitleIgnorePrefix } = require('../utils')
const Logger = require('../Logger')
const libraryItemsPodcastFilters = require('../utils/queries/libraryItemsPodcastFilters')
+const htmlSanitizer = require('../utils/htmlSanitizer')
/**
* @typedef PodcastExpandedProperties
@@ -215,6 +216,15 @@ class Podcast extends Model {
newKey = 'itunesPageURL'
}
if ((typeof payload.metadata[key] === 'string' || payload.metadata[key] === null) && payload.metadata[key] !== this[newKey]) {
+ // Sanitize description HTML
+ if (key === 'description' && payload.metadata[key]) {
+ const sanitizedDescription = htmlSanitizer.sanitize(payload.metadata[key])
+ if (sanitizedDescription !== payload.metadata[key]) {
+ Logger.debug(`[Podcast] "${this.title}" Sanitized description from "${payload.metadata[key]}" to "${sanitizedDescription}"`)
+ payload.metadata[key] = sanitizedDescription
+ }
+ }
+
this[newKey] = payload.metadata[key] || null
if (key === 'title') {
diff --git a/server/utils/podcastUtils.js b/server/utils/podcastUtils.js
index a7ecce8a..3a1df198 100644
--- a/server/utils/podcastUtils.js
+++ b/server/utils/podcastUtils.js
@@ -205,7 +205,7 @@ function extractEpisodeData(item) {
} else if (typeof guidItem?._ === 'string') {
episode.guid = guidItem._
} else {
- Logger.error(`[podcastUtils] Invalid guid ${item['guid']} for ${episode.enclosure.url}`)
+ Logger.error(`[podcastUtils] Invalid guid for ${episode.enclosure.url}`, item['guid'])
}
}
diff --git a/server/utils/queries/libraryItemsPodcastFilters.js b/server/utils/queries/libraryItemsPodcastFilters.js
index c71e0dc8..33bac28f 100644
--- a/server/utils/queries/libraryItemsPodcastFilters.js
+++ b/server/utils/queries/libraryItemsPodcastFilters.js
@@ -149,11 +149,12 @@ module.exports = {
libraryId
}
const libraryItemIncludes = []
- if (includeRSSFeed) {
+ if (filterGroup === 'feed-open' || includeRSSFeed) {
+ const rssFeedRequired = filterGroup === 'feed-open'
libraryItemIncludes.push({
model: Database.feedModel,
- required: filterGroup === 'feed-open',
- separate: true
+ required: rssFeedRequired,
+ separate: !rssFeedRequired
})
}
if (filterGroup === 'issues') {
@@ -411,6 +412,43 @@ module.exports = {
})
}
+ // Search podcast episode title
+ const podcastEpisodes = await Database.podcastEpisodeModel.findAll({
+ where: [
+ Sequelize.literal(textSearchQuery.matchExpression('podcastEpisode.title')),
+ {
+ '$podcast.libraryItem.libraryId$': library.id
+ }
+ ],
+ replacements: userPermissionPodcastWhere.replacements,
+ include: [
+ {
+ model: Database.podcastModel,
+ where: [...userPermissionPodcastWhere.podcastWhere],
+ include: [
+ {
+ model: Database.libraryItemModel
+ }
+ ]
+ }
+ ],
+ distinct: true,
+ offset,
+ limit
+ })
+ const episodeMatches = []
+ for (const episode of podcastEpisodes) {
+ const libraryItem = episode.podcast.libraryItem
+ libraryItem.media = episode.podcast
+ libraryItem.media.podcastEpisodes = []
+ const oldPodcastEpisodeJson = episode.toOldJSONExpanded(libraryItem.id)
+ const libraryItemJson = libraryItem.toOldJSONExpanded()
+ libraryItemJson.recentEpisode = oldPodcastEpisodeJson
+ episodeMatches.push({
+ libraryItem: libraryItemJson
+ })
+ }
+
const matchJsonValue = textSearchQuery.matchExpression('json_each.value')
// Search tags
@@ -450,7 +488,8 @@ module.exports = {
return {
podcast: itemMatches,
tags: tagMatches,
- genres: genreMatches
+ genres: genreMatches,
+ episodes: episodeMatches
}
},