Fix obtaining manga output
This commit is contained in:
@@ -15,8 +15,8 @@ android {
|
|||||||
applicationId 'org.koitharu.kotatsu'
|
applicationId 'org.koitharu.kotatsu'
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 542
|
versionCode 543
|
||||||
versionName '5.1-b1'
|
versionName '5.1-b2'
|
||||||
generatedDensities = []
|
generatedDensities = []
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ class PausingReceiver(
|
|||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent?) {
|
override fun onReceive(context: Context, intent: Intent?) {
|
||||||
val uuid = intent?.getStringExtra(EXTRA_UUID)?.toUUIDOrNull()
|
val uuid = intent?.getStringExtra(EXTRA_UUID)?.toUUIDOrNull()
|
||||||
assert(uuid == id)
|
if (uuid != id) {
|
||||||
when (intent?.action) {
|
return
|
||||||
|
}
|
||||||
|
when (intent.action) {
|
||||||
ACTION_RESUME -> pausingHandle.resume()
|
ACTION_RESUME -> pausingHandle.resume()
|
||||||
ACTION_PAUSE -> pausingHandle.pause()
|
ACTION_PAUSE -> pausingHandle.pause()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
package org.koitharu.kotatsu.local.data.output
|
package org.koitharu.kotatsu.local.data.output
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import okio.Closeable
|
import okio.Closeable
|
||||||
|
import org.koitharu.kotatsu.local.data.input.LocalMangaInput
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||||
import org.koitharu.kotatsu.parsers.util.toFileNameSafe
|
import org.koitharu.kotatsu.parsers.util.toFileNameSafe
|
||||||
@@ -26,25 +31,63 @@ sealed class LocalMangaOutput(
|
|||||||
|
|
||||||
const val ENTRY_NAME_INDEX = "index.json"
|
const val ENTRY_NAME_INDEX = "index.json"
|
||||||
const val SUFFIX_TMP = ".tmp"
|
const val SUFFIX_TMP = ".tmp"
|
||||||
|
private val mutex = Mutex()
|
||||||
|
|
||||||
fun getOrCreate(root: File, manga: Manga): LocalMangaOutput {
|
suspend fun getOrCreate(root: File, manga: Manga): LocalMangaOutput = withContext(Dispatchers.IO) {
|
||||||
return checkNotNull(getImpl(root, manga, onlyIfExists = false))
|
val preferSingleCbz = manga.chapters.let {
|
||||||
}
|
it != null && it.size <= 3
|
||||||
|
|
||||||
fun get(root: File, manga: Manga): LocalMangaOutput? {
|
|
||||||
return getImpl(root, manga, onlyIfExists = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImpl(root: File, manga: Manga, onlyIfExists: Boolean): LocalMangaOutput? {
|
|
||||||
val fileName = manga.title.toFileNameSafe()
|
|
||||||
val dir = File(root, fileName)
|
|
||||||
val zip = File(root, "$fileName.cbz")
|
|
||||||
return when {
|
|
||||||
dir.isDirectory -> LocalMangaDirOutput(dir, manga)
|
|
||||||
zip.isFile -> LocalMangaZipOutput(zip, manga)
|
|
||||||
!onlyIfExists -> LocalMangaDirOutput(dir, manga)
|
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
|
checkNotNull(getImpl(root, manga, onlyIfExists = false, preferSingleCbz))
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun get(root: File, manga: Manga): LocalMangaOutput? = withContext(Dispatchers.IO) {
|
||||||
|
getImpl(root, manga, onlyIfExists = true, preferSingleCbz = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getImpl(
|
||||||
|
root: File,
|
||||||
|
manga: Manga,
|
||||||
|
onlyIfExists: Boolean,
|
||||||
|
preferSingleCbz: Boolean,
|
||||||
|
): LocalMangaOutput? {
|
||||||
|
mutex.withLock {
|
||||||
|
var i = 0
|
||||||
|
val baseName = manga.title.toFileNameSafe()
|
||||||
|
while (true) {
|
||||||
|
val fileName = if (i == 0) baseName else baseName + "_$i"
|
||||||
|
val dir = File(root, fileName)
|
||||||
|
val zip = File(root, "$fileName.cbz")
|
||||||
|
i++
|
||||||
|
return when {
|
||||||
|
dir.isDirectory -> {
|
||||||
|
if (canWriteTo(dir, manga)) {
|
||||||
|
LocalMangaDirOutput(dir, manga)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zip.isFile -> if (canWriteTo(zip, manga)) {
|
||||||
|
LocalMangaZipOutput(zip, manga)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
!onlyIfExists -> if (preferSingleCbz) {
|
||||||
|
LocalMangaZipOutput(zip, manga)
|
||||||
|
} else {
|
||||||
|
LocalMangaDirOutput(dir, manga)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun canWriteTo(file: File, manga: Manga): Boolean {
|
||||||
|
val info = LocalMangaInput.of(file).getMangaInfo() ?: return false
|
||||||
|
return info.id == manga.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ class PageLoader @Inject constructor(
|
|||||||
.build()
|
.build()
|
||||||
okHttp.newCall(request).await().use { response ->
|
okHttp.newCall(request).await().use { response ->
|
||||||
check(response.isSuccessful) {
|
check(response.isSuccessful) {
|
||||||
"Invalid response: ${response.code} ${response.message}"
|
"Invalid response: ${response.code} ${response.message} at $pageUrl"
|
||||||
}
|
}
|
||||||
val body = checkNotNull(response.body) {
|
val body = checkNotNull(response.body) {
|
||||||
"Null response"
|
"Null response"
|
||||||
|
|||||||
Reference in New Issue
Block a user