mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-04 03:14:40 -05:00
fix(opds): handle dead sources and prevent kosync binary hash crashes (#2116)
This commit is contained in:
@@ -50,6 +50,7 @@
|
|||||||
<!-- OPDS errors -->
|
<!-- OPDS errors -->
|
||||||
<string name="opds_error_manga_not_found">Series with ID %1$d not found.</string>
|
<string name="opds_error_manga_not_found">Series with ID %1$d not found.</string>
|
||||||
<string name="opds_error_chapter_not_found">Chapter with index %1$d not found.</string>
|
<string name="opds_error_chapter_not_found">Chapter with index %1$d not found.</string>
|
||||||
|
<string name="opds_error_chapters_not_found">No chapters found or the source is unreachable on page %1$d.</string>
|
||||||
|
|
||||||
<!-- OPDS facets (Filters and Sorting) -->
|
<!-- OPDS facets (Filters and Sorting) -->
|
||||||
<string name="opds_facetgroup_sort_order">Sort Order</string>
|
<string name="opds_facetgroup_sort_order">Sort Order</string>
|
||||||
|
|||||||
@@ -127,11 +127,14 @@ object KoreaderSyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val mangaId = chapterRow[ChapterTable.manga].value
|
val mangaId = chapterRow[ChapterTable.manga].value
|
||||||
|
val isDownloaded = chapterRow[ChapterTable.isDownloaded]
|
||||||
val checksumMethod = serverConfig.koreaderSyncChecksumMethod.value
|
val checksumMethod = serverConfig.koreaderSyncChecksumMethod.value
|
||||||
|
|
||||||
val newHash =
|
val newHash =
|
||||||
when (checksumMethod) {
|
when (checksumMethod) {
|
||||||
KoreaderSyncChecksumMethod.BINARY -> {
|
KoreaderSyncChecksumMethod.BINARY -> {
|
||||||
|
// Only generate binary hash if the chapter is downloaded to avoid fetching missing files
|
||||||
|
if (isDownloaded) {
|
||||||
logger.debug { "[KOSYNC HASH] No hash for chapterId=$chapterId. Generating from downloaded content." }
|
logger.debug { "[KOSYNC HASH] No hash for chapterId=$chapterId. Generating from downloaded content." }
|
||||||
try {
|
try {
|
||||||
// Always create a CBZ in memory if it doesn't exist
|
// Always create a CBZ in memory if it doesn't exist
|
||||||
@@ -152,6 +155,10 @@ object KoreaderSyncService {
|
|||||||
logger.warn(e) { "[KOSYNC HASH] Failed to generate archive stream for chapterId=$chapterId." }
|
logger.warn(e) { "[KOSYNC HASH] Failed to generate archive stream for chapterId=$chapterId." }
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logger.debug { "[KOSYNC HASH] Skipping binary hash for chapterId=$chapterId because it is not downloaded." }
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KoreaderSyncChecksumMethod.FILENAME -> {
|
KoreaderSyncChecksumMethod.FILENAME -> {
|
||||||
@@ -175,7 +182,7 @@ object KoreaderSyncService {
|
|||||||
}
|
}
|
||||||
logger.info { "[KOSYNC HASH] Generated and saved new hash for chapterId=$chapterId" }
|
logger.info { "[KOSYNC HASH] Generated and saved new hash for chapterId=$chapterId" }
|
||||||
} else {
|
} else {
|
||||||
logger.warn { "[KOSYNC HASH] Hashing failed for chapterId=$chapterId." }
|
logger.warn { "[KOSYNC HASH] Hashing failed or skipped for chapterId=$chapterId." }
|
||||||
}
|
}
|
||||||
newHash
|
newHash
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -644,6 +644,16 @@ object OpdsFeedBuilder {
|
|||||||
skipMetadata,
|
skipMetadata,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Return a not-found feed if all available chapters are filtered out as unreachable
|
||||||
|
if (skipMetadata && chapterEntries.isEmpty() && totalChapters > 0L) {
|
||||||
|
return buildNotFoundFeed(
|
||||||
|
baseUrl = baseUrl,
|
||||||
|
locale = locale,
|
||||||
|
idPath = "series/$mangaId/chapters",
|
||||||
|
title = MR.strings.opds_error_chapters_not_found.localized(locale, pageNum),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// If no chapters are found in the database, attempt to fetch them from the source.
|
// If no chapters are found in the database, attempt to fetch them from the source.
|
||||||
if (chapterEntries.isEmpty() && totalChapters == 0L) {
|
if (chapterEntries.isEmpty() && totalChapters == 0L) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -169,6 +169,8 @@ object ChapterRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.awaitAll()
|
}.awaitAll()
|
||||||
|
// Exclude unreachable chapters that are not downloaded and have no page count
|
||||||
|
.filter { it.downloaded || it.pageCount > 0 }
|
||||||
|
|
||||||
return Pair(enrichedChapters, totalCount)
|
return Pair(enrichedChapters, totalCount)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user