Refactor repository creation
This commit is contained in:
@@ -93,7 +93,7 @@ class DownloadService : BaseService() {
|
||||
checkNotNull(destination) { getString(R.string.cannot_find_available_storage) }
|
||||
var output: MangaZip? = null
|
||||
try {
|
||||
val repo = manga.source.repository
|
||||
val repo = mangaRepositoryOf(manga.source)
|
||||
val cover = runCatching {
|
||||
imageLoader.execute(
|
||||
ImageRequest.Builder(this@DownloadService)
|
||||
|
||||
@@ -3,16 +3,20 @@ package org.koitharu.kotatsu.reader.domain
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.util.ArrayMap
|
||||
import androidx.collection.LongSparseArray
|
||||
import androidx.collection.set
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import okhttp3.OkHttpClient
|
||||
import org.koitharu.kotatsu.core.model.RequestDraft
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koitharu.kotatsu.core.model.MangaPage
|
||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.local.data.PagesCache
|
||||
import org.koitharu.kotatsu.utils.CacheUtils
|
||||
import org.koitharu.kotatsu.utils.ext.await
|
||||
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
@@ -20,45 +24,61 @@ class PageLoader(
|
||||
scope: CoroutineScope,
|
||||
private val okHttp: OkHttpClient,
|
||||
private val cache: PagesCache
|
||||
) : CoroutineScope by scope {
|
||||
) : CoroutineScope by scope, KoinComponent {
|
||||
|
||||
private val tasks = ArrayMap<String, Deferred<File>>()
|
||||
private var repository: MangaRepository? = null
|
||||
private val tasks = LongSparseArray<Deferred<File>>()
|
||||
private val convertLock = Mutex()
|
||||
|
||||
suspend fun loadFile(requestDraft: RequestDraft, force: Boolean): File {
|
||||
suspend fun loadPage(page: MangaPage, force: Boolean): File {
|
||||
if (!force) {
|
||||
cache[requestDraft.url]?.let {
|
||||
cache[page.url]?.let {
|
||||
return it
|
||||
}
|
||||
}
|
||||
val task =
|
||||
tasks[requestDraft.url]?.takeUnless { it.isCancelled || (force && it.isCompleted) }
|
||||
return (task ?: loadAsync(requestDraft).also { tasks[requestDraft.url] = it }).await()
|
||||
var task = tasks[page.id]
|
||||
if (force) {
|
||||
task?.cancel()
|
||||
} else if (task?.isCancelled == false) {
|
||||
return task.await()
|
||||
}
|
||||
task = loadAsync(page)
|
||||
tasks[page.id] = task
|
||||
return task.await()
|
||||
}
|
||||
|
||||
private fun loadAsync(requestDraft: RequestDraft) = async(Dispatchers.IO) {
|
||||
val uri = Uri.parse(requestDraft.url)
|
||||
if (uri.scheme == "cbz") {
|
||||
val zip = ZipFile(uri.schemeSpecificPart)
|
||||
val entry = zip.getEntry(uri.fragment)
|
||||
zip.getInputStream(entry).use {
|
||||
cache.put(requestDraft.url, it)
|
||||
}
|
||||
} else {
|
||||
val request = requestDraft.newBuilder()
|
||||
.header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8")
|
||||
.cacheControl(CacheUtils.CONTROL_DISABLED)
|
||||
.build()
|
||||
okHttp.newCall(request).await().use { response ->
|
||||
check(response.isSuccessful) {
|
||||
"Invalid response: ${response.code} ${response.message}"
|
||||
}
|
||||
val body = checkNotNull(response.body) {
|
||||
"Null response"
|
||||
}
|
||||
body.byteStream().use {
|
||||
private fun loadAsync(page: MangaPage): Deferred<File> {
|
||||
var repo = repository
|
||||
if (repo?.javaClass != page.source.cls) {
|
||||
repo = mangaRepositoryOf(page.source)
|
||||
repository = repo
|
||||
}
|
||||
return async(Dispatchers.IO) {
|
||||
val requestDraft = repo.getPageRequest(page)
|
||||
check(requestDraft.isValid) { "Cannot obtain full image url" }
|
||||
val uri = Uri.parse(requestDraft.url)
|
||||
if (uri.scheme == "cbz") {
|
||||
val zip = ZipFile(uri.schemeSpecificPart)
|
||||
val entry = zip.getEntry(uri.fragment)
|
||||
zip.getInputStream(entry).use {
|
||||
cache.put(requestDraft.url, it)
|
||||
}
|
||||
} else {
|
||||
val request = requestDraft.newBuilder()
|
||||
.header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8")
|
||||
.cacheControl(CacheUtils.CONTROL_DISABLED)
|
||||
.build()
|
||||
okHttp.newCall(request).await().use { response ->
|
||||
check(response.isSuccessful) {
|
||||
"Invalid response: ${response.code} ${response.message}"
|
||||
}
|
||||
val body = checkNotNull(response.body) {
|
||||
"Null response"
|
||||
}
|
||||
body.byteStream().use {
|
||||
cache.put(requestDraft.url, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,11 +88,7 @@ class PageHolderDelegate(
|
||||
error = null
|
||||
callback.onLoadingStarted()
|
||||
try {
|
||||
val file = withContext(Dispatchers.IO) {
|
||||
val pageRequest = data.source.repository.getPageRequest(data)
|
||||
check(pageRequest.isValid) { "Cannot obtain full image url" }
|
||||
loader.loadFile(pageRequest, force)
|
||||
}
|
||||
val file = loader.loadPage(data, force)
|
||||
this@PageHolderDelegate.file = file
|
||||
state = State.LOADED
|
||||
callback.onImageReady(file.toUri())
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.databinding.SheetPagesBinding
|
||||
import org.koitharu.kotatsu.list.ui.MangaListSpanResolver
|
||||
import org.koitharu.kotatsu.reader.ui.thumbnails.adapter.PageThumbnailAdapter
|
||||
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
@@ -36,7 +37,7 @@ class PagesThumbnailsSheet : BaseBottomSheet<SheetPagesBinding>(),
|
||||
return
|
||||
}
|
||||
val current = arguments?.getInt(ARG_CURRENT, -1) ?: -1
|
||||
val repository = pages.first().source.repository
|
||||
val repository = mangaRepositoryOf(pages.first().source)
|
||||
thumbnails = pages.mapIndexed { i, x ->
|
||||
PageThumbnail(
|
||||
number = i + 1,
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
||||
import org.koitharu.kotatsu.settings.utils.EditTextSummaryProvider
|
||||
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class SourceSettingsFragment : PreferenceFragmentCompat() {
|
||||
@@ -24,7 +25,7 @@ class SourceSettingsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
preferenceManager.sharedPreferencesName = source.name
|
||||
val repo = source.repository as? RemoteMangaRepository ?: return
|
||||
val repo = mangaRepositoryOf(source) as? RemoteMangaRepository ?: return
|
||||
val keys = repo.onCreatePreferences()
|
||||
addPreferencesFromResource(R.xml.pref_source)
|
||||
for (i in 0 until preferenceScreen.preferenceCount) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.koitharu.kotatsu.core.model.MangaChapter
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||
import org.koitharu.kotatsu.utils.ext.mangaRepositoryOf
|
||||
import org.koitharu.kotatsu.utils.ext.toBitmapOrNull
|
||||
import org.koitharu.kotatsu.utils.ext.toUriOrNull
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -51,7 +52,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
|
||||
var success = 0
|
||||
for (track in tracks) {
|
||||
val details = runCatching {
|
||||
track.manga.source.repository.getDetails(track.manga)
|
||||
mangaRepositoryOf(track.manga.source).getDetails(track.manga)
|
||||
}.getOrNull()
|
||||
val chapters = details?.chapters ?: continue
|
||||
when {
|
||||
|
||||
19
app/src/main/java/org/koitharu/kotatsu/utils/ext/KoinExt.kt
Normal file
19
app/src/main/java/org/koitharu/kotatsu/utils/ext/KoinExt.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import android.content.ComponentCallbacks
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun ComponentCallbacks.mangaRepositoryOf(source: MangaSource): MangaRepository {
|
||||
return get(named(source))
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun KoinComponent.mangaRepositoryOf(source: MangaSource): MangaRepository {
|
||||
return get(named(source))
|
||||
}
|
||||
Reference in New Issue
Block a user