Search and parallelism in LocalMangaRepository.getList
This commit is contained in:
@@ -3,12 +3,17 @@ package org.koitharu.kotatsu.local.domain
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.collection.ArraySet
|
import androidx.collection.ArraySet
|
||||||
import androidx.core.net.toFile
|
import androidx.core.net.toFile
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import kotlinx.coroutines.Dispatchers
|
import java.io.File
|
||||||
import kotlinx.coroutines.runInterruptible
|
import java.io.IOException
|
||||||
import kotlinx.coroutines.withContext
|
import java.util.*
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipFile
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException
|
import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
import org.koitharu.kotatsu.local.data.CbzFilter
|
import org.koitharu.kotatsu.local.data.CbzFilter
|
||||||
@@ -21,11 +26,8 @@ import org.koitharu.kotatsu.utils.AlphanumComparator
|
|||||||
import org.koitharu.kotatsu.utils.ext.deleteAwait
|
import org.koitharu.kotatsu.utils.ext.deleteAwait
|
||||||
import org.koitharu.kotatsu.utils.ext.readText
|
import org.koitharu.kotatsu.utils.ext.readText
|
||||||
import org.koitharu.kotatsu.utils.ext.resolveName
|
import org.koitharu.kotatsu.utils.ext.resolveName
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
private const val MAX_PARALLELISM = 4
|
||||||
import java.util.*
|
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipFile
|
|
||||||
|
|
||||||
class LocalMangaRepository(private val storageManager: LocalStorageManager) : MangaRepository {
|
class LocalMangaRepository(private val storageManager: LocalStorageManager) : MangaRepository {
|
||||||
|
|
||||||
@@ -38,11 +40,28 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
|
|||||||
tags: Set<MangaTag>?,
|
tags: Set<MangaTag>?,
|
||||||
sortOrder: SortOrder?
|
sortOrder: SortOrder?
|
||||||
): List<Manga> {
|
): List<Manga> {
|
||||||
require(offset == 0) {
|
if (offset > 0) {
|
||||||
"LocalMangaRepository does not support pagination"
|
return emptyList()
|
||||||
}
|
}
|
||||||
val files = getAllFiles()
|
val files = getAllFiles()
|
||||||
return files.mapNotNull { x -> runCatching { getFromFile(x) }.getOrNull() }
|
val list = coroutineScope {
|
||||||
|
val dispatcher = Dispatchers.IO.limitedParallelism(MAX_PARALLELISM)
|
||||||
|
files.map { file ->
|
||||||
|
getFromFileAsync(file, dispatcher)
|
||||||
|
}.awaitAll()
|
||||||
|
}.filterNotNullTo(ArrayList(files.size))
|
||||||
|
if (!query.isNullOrEmpty()) {
|
||||||
|
list.retainAll { x ->
|
||||||
|
x.title.contains(query, ignoreCase = true) ||
|
||||||
|
x.altTitle?.contains(query, ignoreCase = true) == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tags.isNullOrEmpty()) {
|
||||||
|
list.retainAll { x ->
|
||||||
|
x.tags.containsAll(tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDetails(manga: Manga) = when {
|
override suspend fun getDetails(manga: Manga) = when {
|
||||||
@@ -99,6 +118,7 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
|
|||||||
CbzMangaOutput.filterChapters(cbz, ids)
|
CbzMangaOutput.filterChapters(cbz, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
fun getFromFile(file: File): Manga = ZipFile(file).use { zip ->
|
fun getFromFile(file: File): Manga = ZipFile(file).use { zip ->
|
||||||
val fileUri = file.toUri().toString()
|
val fileUri = file.toUri().toString()
|
||||||
@@ -192,6 +212,15 @@ class LocalMangaRepository(private val storageManager: LocalStorageManager) : Ma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun CoroutineScope.getFromFileAsync(
|
||||||
|
file: File,
|
||||||
|
context: CoroutineContext,
|
||||||
|
): Deferred<Manga?> = async(context) {
|
||||||
|
runInterruptible {
|
||||||
|
runCatching { getFromFile(file) }.getOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun zipUri(file: File, entryName: String) = "cbz://${file.path}#$entryName"
|
private fun zipUri(file: File, entryName: String) = "cbz://${file.path}#$entryName"
|
||||||
|
|
||||||
private fun findFirstImageEntry(entries: Enumeration<out ZipEntry>): ZipEntry? {
|
private fun findFirstImageEntry(entries: Enumeration<out ZipEntry>): ZipEntry? {
|
||||||
|
|||||||
Reference in New Issue
Block a user