Fix EPUB and TXT document downloads
Release / Extract tag name (push) Waiting to run
Release / Build (push) Blocked by required conditions
Release / Build (FOSS) (push) Blocked by required conditions
Release / Create GitHub Release (push) Blocked by required conditions
Update website / update_website (release) Waiting to run
Build & Test / Build & Test App (push) Has been cancelled
Release / Extract tag name (push) Waiting to run
Release / Build (push) Blocked by required conditions
Release / Build (FOSS) (push) Blocked by required conditions
Release / Create GitHub Release (push) Blocked by required conditions
Update website / update_website (release) Waiting to run
Build & Test / Build & Test App (push) Has been cancelled
This commit is contained in:
@@ -374,6 +374,7 @@ class DownloadCache(
|
|||||||
when {
|
when {
|
||||||
// Ignore incomplete downloads
|
// Ignore incomplete downloads
|
||||||
it.name?.endsWith(Downloader.TMP_DIR_SUFFIX) == true -> null
|
it.name?.endsWith(Downloader.TMP_DIR_SUFFIX) == true -> null
|
||||||
|
it.name?.contains(".download.", ignoreCase = true) == true -> null
|
||||||
// Folder of images
|
// Folder of images
|
||||||
it.isDirectory -> it.name
|
it.isDirectory -> it.name
|
||||||
// Archived or original document files
|
// Archived or original document files
|
||||||
|
|||||||
@@ -455,9 +455,9 @@ class Downloader(
|
|||||||
document: RemoteDocument,
|
document: RemoteDocument,
|
||||||
) {
|
) {
|
||||||
val targetName = "$chapterDirname.${document.extension}"
|
val targetName = "$chapterDirname.${document.extension}"
|
||||||
mangaDir.findFile(targetName)?.delete()
|
val tempName = "$chapterDirname.download.${document.extension}"
|
||||||
mangaDir.findFile("$targetName.tmp")?.delete()
|
mangaDir.findFile(tempName)?.delete()
|
||||||
val temp = mangaDir.createFile("$targetName.tmp")
|
val temp = mangaDir.createFile(tempName)
|
||||||
?: error("Failed to create temporary document file")
|
?: error("Failed to create temporary document file")
|
||||||
val page = Page(0).apply {
|
val page = Page(0).apply {
|
||||||
status = Page.State.DownloadImage
|
status = Page.State.DownloadImage
|
||||||
@@ -482,6 +482,7 @@ class Downloader(
|
|||||||
throw IllegalStateException("Document download returned an empty file")
|
throw IllegalStateException("Document download returned an empty file")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mangaDir.findFile(targetName)?.delete()
|
||||||
if (!temp.renameTo(targetName)) {
|
if (!temp.renameTo(targetName)) {
|
||||||
val target = mangaDir.createFile(targetName)
|
val target = mangaDir.createFile(targetName)
|
||||||
?: error("Failed to create downloaded document file")
|
?: error("Failed to create downloaded document file")
|
||||||
|
|||||||
@@ -21,13 +21,24 @@ internal data class BookOasisChapterRef(
|
|||||||
val format: String,
|
val format: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun HttpSource.bookOasisServerBase(): String {
|
||||||
|
val normalized = baseUrl.trimEnd('/')
|
||||||
|
return when {
|
||||||
|
normalized.endsWith("/app-opds-adult", ignoreCase = true) ->
|
||||||
|
normalized.dropLast("/app-opds-adult".length)
|
||||||
|
normalized.endsWith("/app-opds", ignoreCase = true) ->
|
||||||
|
normalized.dropLast("/app-opds".length)
|
||||||
|
else -> normalized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun HttpSource.bookOasisDocumentDownloadRequest(ref: BookOasisChapterRef): Request {
|
internal fun HttpSource.bookOasisDocumentDownloadRequest(ref: BookOasisChapterRef): Request {
|
||||||
val downloadUrl = buildString {
|
val downloadUrl = buildString {
|
||||||
append(baseUrl.trimEnd('/'))
|
append(bookOasisServerBase())
|
||||||
append("/api/media/books/")
|
append("/app-opds/download/")
|
||||||
append(ref.bookId)
|
|
||||||
append("/download?type=")
|
|
||||||
append(ref.dbType)
|
append(ref.dbType)
|
||||||
|
append('/')
|
||||||
|
append(ref.bookId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Request.Builder()
|
return Request.Builder()
|
||||||
@@ -43,7 +54,7 @@ internal fun Source.isBookOasisSource(): Boolean {
|
|||||||
|
|
||||||
internal fun String.toBookOasisChapterRef(): BookOasisChapterRef? {
|
internal fun String.toBookOasisChapterRef(): BookOasisChapterRef? {
|
||||||
val path = substringBefore('?')
|
val path = substringBefore('?')
|
||||||
val match = Regex("""^/api/media/books/(\d+)/info$""").matchEntire(path) ?: return null
|
val match = Regex("""^/(?:app-opds(?:-adult)?/)?api/media/books/(\d+)/info$""").matchEntire(path) ?: return null
|
||||||
val params = parseQueryParameters(this)
|
val params = parseQueryParameters(this)
|
||||||
val format = params["bo_format"]?.lowercase() ?: return null
|
val format = params["bo_format"]?.lowercase() ?: return null
|
||||||
if (format !in DOCUMENT_FORMATS) return null
|
if (format !in DOCUMENT_FORMATS) return null
|
||||||
|
|||||||
@@ -12,8 +12,13 @@ private const val KAVITA_PACKAGE_PREFIX = "eu.kanade.tachiyomi.extension.all.kav
|
|||||||
internal fun Source.isKavitaSource(): Boolean =
|
internal fun Source.isKavitaSource(): Boolean =
|
||||||
this::class.java.name.startsWith(KAVITA_PACKAGE_PREFIX)
|
this::class.java.name.startsWith(KAVITA_PACKAGE_PREFIX)
|
||||||
|
|
||||||
|
private fun HttpSource.kavitaApiBase(): String {
|
||||||
|
val normalized = baseUrl.trimEnd('/')
|
||||||
|
return if (normalized.endsWith("/api", ignoreCase = true)) normalized else "$normalized/api"
|
||||||
|
}
|
||||||
|
|
||||||
internal suspend fun HttpSource.detectKavitaDocumentFormat(chapterId: Int): String? {
|
internal suspend fun HttpSource.detectKavitaDocumentFormat(chapterId: Int): String? {
|
||||||
val apiBase = baseUrl.trimEnd('/') + "/api"
|
val apiBase = kavitaApiBase()
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("$apiBase/Chapter?chapterId=$chapterId")
|
.url("$apiBase/Chapter?chapterId=$chapterId")
|
||||||
.headers(headers)
|
.headers(headers)
|
||||||
@@ -43,7 +48,7 @@ internal suspend fun HttpSource.detectKavitaDocumentFormat(chapterId: Int): Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun HttpSource.kavitaDocumentDownloadRequest(chapterId: Int): Request {
|
internal fun HttpSource.kavitaDocumentDownloadRequest(chapterId: Int): Request {
|
||||||
val apiBase = baseUrl.trimEnd('/') + "/api"
|
val apiBase = kavitaApiBase()
|
||||||
return Request.Builder()
|
return Request.Builder()
|
||||||
.url("$apiBase/Download/chapter?chapterId=$chapterId")
|
.url("$apiBase/Download/chapter?chapterId=$chapterId")
|
||||||
.headers(headers)
|
.headers(headers)
|
||||||
|
|||||||
Reference in New Issue
Block a user