From bd27eb9f59c1ae616ffe001b6442ed0a3dc50a47 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 30 Mar 2023 18:11:43 +0300 Subject: [PATCH] Fix local manga operations --- app/build.gradle | 32 +++++++++---------- .../exceptions/resolve/ExceptionResolver.kt | 3 +- .../local/data/output/LocalMangaDirOutput.kt | 12 ++++--- .../local/domain/LocalMangaRepository.kt | 20 ++++-------- .../org/koitharu/kotatsu/utils/ext/FileExt.kt | 2 +- 5 files changed, 32 insertions(+), 37 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f5bd2ff5b..33e975a8b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/main/java/org/koitharu/kotatsu/core/exceptions/resolve/ExceptionResolver.kt b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/resolve/ExceptionResolver.kt index 60df80fbf..75d466bbb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/exceptions/resolve/ExceptionResolver.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/resolve/ExceptionResolver.kt @@ -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) } diff --git a/app/src/main/java/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt index 02ee3f412..29343fe3b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt @@ -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" diff --git a/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt index 77a720357..3c19e9d86 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt @@ -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? { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FileExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FileExt.kt index 9dec944b4..f2800f68c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/FileExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/FileExt.kt @@ -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? {