Fix local manga operations

This commit is contained in:
Koitharu
2023-03-30 18:11:43 +03:00
parent 056538a341
commit bd27eb9f59
5 changed files with 32 additions and 37 deletions

View File

@@ -15,8 +15,8 @@ android {
applicationId 'org.koitharu.kotatsu'
minSdkVersion 21
targetSdkVersion 33
versionCode 530
versionName '5.0-a1'
versionCode 531
versionName '5.0-a2'
generatedDensities = []
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -87,26 +87,26 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.activity:activity-ktx:1.6.1'
implementation 'androidx.fragment:fragment-ktx:1.5.5'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.0'
implementation 'androidx.lifecycle:lifecycle-service:2.6.0'
implementation 'androidx.lifecycle:lifecycle-process:2.6.0'
implementation 'androidx.activity:activity-ktx:1.7.0'
implementation 'androidx.fragment:fragment-ktx:1.5.6'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-service:2.6.1'
implementation 'androidx.lifecycle:lifecycle-process:2.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.3.0'
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.work:work-runtime-ktx:2.8.0'
implementation 'androidx.work:work-runtime-ktx:2.8.1'
implementation 'androidx.biometric:biometric-ktx:1.2.0-alpha05'
implementation 'com.google.android.material:material:1.8.0'
//noinspection LifecycleAnnotationProcessorWithJava8
kapt 'androidx.lifecycle:lifecycle-compiler:2.6.0'
kapt 'androidx.lifecycle:lifecycle-compiler:2.6.1'
implementation 'androidx.room:room-runtime:2.5.0'
implementation 'androidx.room:room-ktx:2.5.0'
kapt 'androidx.room:room-compiler:2.5.0'
implementation 'androidx.room:room-runtime:2.5.1'
implementation 'androidx.room:room-ktx:2.5.1'
kapt 'androidx.room:room-compiler:2.5.1'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.3'
@@ -120,8 +120,8 @@ dependencies {
implementation 'androidx.hilt:hilt-work:1.0.0'
kapt 'androidx.hilt:hilt-compiler:1.0.0'
implementation 'io.coil-kt:coil-base:2.2.2'
implementation 'io.coil-kt:coil-svg:2.2.2'
implementation 'io.coil-kt:coil-base:2.3.0'
implementation 'io.coil-kt:coil-svg:2.3.0'
implementation 'com.github.KotatsuApp:subsampling-scale-image-view:1b19231b2f'
implementation 'com.github.solkin:disk-lru-cache:1.4'
implementation 'io.noties.markwon:core:4.6.2'
@@ -142,7 +142,7 @@ dependencies {
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
androidTestImplementation 'androidx.room:room-testing:2.5.0'
androidTestImplementation 'androidx.room:room-testing:2.5.1'
androidTestImplementation 'com.squareup.moshi:moshi-kotlin:1.14.0'
androidTestImplementation 'com.google.dagger:hilt-android-testing:2.45'

View File

@@ -39,8 +39,7 @@ class ExceptionResolver private constructor(
sourceAuthContract = fragment.registerForActivityResult(SourceAuthActivity.Contract(), this)
}
override fun onActivityResult(result: TaggedActivityResult?) {
result ?: return
override fun onActivityResult(result: TaggedActivityResult) {
continuations.remove(result.tag)?.resume(result.isSuccess)
}

View File

@@ -34,9 +34,10 @@ class LocalMangaDirOutput(
}
}
runInterruptible(Dispatchers.IO) {
file.copyTo(File(rootFile, name))
file.copyTo(File(rootFile, name), overwrite = true)
}
index.setCoverEntry(name)
flushIndex()
}
override suspend fun addPage(chapter: MangaChapter, file: File, pageNumber: Int, ext: String) {
@@ -59,12 +60,11 @@ class LocalMangaDirOutput(
override suspend fun flushChapter(chapter: MangaChapter) {
val output = chaptersOutput.remove(chapter) ?: return
output.flushAndFinish()
flushIndex()
}
override suspend fun finish() {
runInterruptible(Dispatchers.IO) {
File(rootFile, ENTRY_NAME_INDEX).writeText(index.toString())
}
flushIndex()
for (output in chaptersOutput.values) {
output.flushAndFinish()
}
@@ -103,6 +103,10 @@ class LocalMangaDirOutput(
return "${chapter.number}_${chapter.name.toFileNameSafe()}".take(18) + ".cbz"
}
private suspend fun flushIndex() = runInterruptible(Dispatchers.IO) {
File(rootFile, ENTRY_NAME_INDEX).writeText(index.toString())
}
companion object {
private const val FILENAME_PATTERN = "%08d_%03d%03d"

View File

@@ -12,11 +12,9 @@ import kotlinx.coroutines.runInterruptible
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.local.data.LocalManga
import org.koitharu.kotatsu.local.data.LocalStorageManager
import org.koitharu.kotatsu.local.data.MangaIndex
import org.koitharu.kotatsu.local.data.TempFileFilter
import org.koitharu.kotatsu.local.data.input.LocalMangaInput
import org.koitharu.kotatsu.local.data.output.LocalMangaDirOutput
import org.koitharu.kotatsu.local.data.output.LocalMangaOutput
import org.koitharu.kotatsu.local.data.output.LocalMangaZipOutput
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter
@@ -27,10 +25,9 @@ import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.utils.AlphanumComparator
import org.koitharu.kotatsu.utils.CompositeMutex
import org.koitharu.kotatsu.utils.ext.deleteAwait
import org.koitharu.kotatsu.utils.ext.readText
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
import java.io.File
import java.util.zip.ZipFile
import javax.inject.Inject
import javax.inject.Singleton
@@ -114,16 +111,11 @@ class LocalMangaRepository @Inject constructor(private val storageManager: Local
}
suspend fun getRemoteManga(localManga: Manga): Manga? {
val file = runCatching {
Uri.parse(localManga.url).toFile()
}.getOrNull() ?: return null
return runInterruptible(Dispatchers.IO) {
ZipFile(file).use { zip ->
val entry = zip.getEntry(LocalMangaOutput.ENTRY_NAME_INDEX)
val index = entry?.let(zip::readText)?.let(::MangaIndex)
index?.getMangaInfo()
}
}
return runCatchingCancellable {
LocalMangaInput.of(localManga).getMangaInfo()
}.onFailure {
it.printStackTraceDebug()
}.getOrNull()
}
suspend fun findSavedManga(remoteManga: Manga): LocalManga? {

View File

@@ -47,7 +47,7 @@ fun File.getStorageName(context: Context): String = runCatching {
fun Uri.toFileOrNull() = if (scheme == "file") path?.let(::File) else null
suspend fun File.deleteAwait() = withContext(Dispatchers.IO) {
delete()
delete() || deleteRecursively()
}
fun ContentResolver.resolveName(uri: Uri): String? {