Fix local manga operations
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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? {
|
||||
|
||||
@@ -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? {
|
||||
|
||||
Reference in New Issue
Block a user