New headers processing approach
This commit is contained in:
@@ -16,7 +16,7 @@ Download APK directly from GitHub:
|
|||||||
|
|
||||||
### Main Features
|
### Main Features
|
||||||
|
|
||||||
* Online manga catalogues
|
* Online [manga catalogues](https://github.com/KotatsuApp/kotatsu-parsers)
|
||||||
* Search manga by name and genres
|
* Search manga by name and genres
|
||||||
* Reading history and bookmarks
|
* Reading history and bookmarks
|
||||||
* Favourites organized by user-defined categories
|
* Favourites organized by user-defined categories
|
||||||
@@ -24,7 +24,7 @@ Download APK directly from GitHub:
|
|||||||
* Tablet-optimized Material You UI
|
* Tablet-optimized Material You UI
|
||||||
* Standard and Webtoon-optimized reader
|
* Standard and Webtoon-optimized reader
|
||||||
* Notifications about new chapters with updates feed
|
* Notifications about new chapters with updates feed
|
||||||
* Shikimori integration (manga tracking)
|
* Integration with manga tracking services: Shikimori, AniList, MAL (coming soon)
|
||||||
* Password/fingerprint protect access to the app
|
* Password/fingerprint protect access to the app
|
||||||
* History and favourites [synchronization](https://github.com/KotatsuApp/kotatsu-syncserver) across devices
|
* History and favourites [synchronization](https://github.com/KotatsuApp/kotatsu-syncserver) across devices
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ afterEvaluate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation('com.github.KotatsuApp:kotatsu-parsers:00abaea324') {
|
implementation('com.github.KotatsuApp:kotatsu-parsers:05d705ac03') {
|
||||||
exclude group: 'org.json', module: 'json'
|
exclude group: 'org.json', module: 'json'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package org.koitharu.kotatsu.core.parser
|
package org.koitharu.kotatsu.core.parser
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
import org.koitharu.kotatsu.parsers.MangaParser
|
import org.koitharu.kotatsu.parsers.MangaParser
|
||||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||||
import org.koitharu.kotatsu.parsers.model.*
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
|
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||||
|
import java.util.EnumSet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This parser is just for parser development, it should not be used in releases
|
* This parser is just for parser development, it should not be used in releases
|
||||||
*/
|
*/
|
||||||
class DummyParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.DUMMY) {
|
class DummyParser(context: MangaLoaderContext) : MangaParser(context, MangaSource.DUMMY) {
|
||||||
|
|
||||||
override val configKeyDomain: ConfigKey.Domain
|
override val configKeyDomain: ConfigKey.Domain
|
||||||
get() = ConfigKey.Domain("", null)
|
get() = ConfigKey.Domain("", null)
|
||||||
@@ -37,4 +42,4 @@ class DummyParser(override val context: MangaLoaderContext) : MangaParser(MangaS
|
|||||||
override suspend fun getTags(): Set<MangaTag> {
|
override suspend fun getTags(): Set<MangaTag> {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import org.koitharu.kotatsu.databinding.ItemBookmarkBinding
|
|||||||
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
|
|
||||||
fun bookmarkListAD(
|
fun bookmarkListAD(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
@@ -27,7 +26,6 @@ fun bookmarkListAD(
|
|||||||
|
|
||||||
bind {
|
bind {
|
||||||
binding.imageViewThumb.newImageRequest(item.imageUrl, item.manga.source)?.run {
|
binding.imageViewThumb.newImageRequest(item.imageUrl, item.manga.source)?.run {
|
||||||
referer(item.manga.publicUrl)
|
|
||||||
placeholder(R.drawable.ic_placeholder)
|
placeholder(R.drawable.ic_placeholder)
|
||||||
fallback(R.drawable.ic_placeholder)
|
fallback(R.drawable.ic_placeholder)
|
||||||
error(R.drawable.ic_error_placeholder)
|
error(R.drawable.ic_error_placeholder)
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import org.koitharu.kotatsu.utils.ext.clearItemDecorations
|
|||||||
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
|
|
||||||
fun bookmarksGroupAD(
|
fun bookmarksGroupAD(
|
||||||
coil: ImageLoader,
|
coil: ImageLoader,
|
||||||
@@ -50,7 +49,6 @@ fun bookmarksGroupAD(
|
|||||||
selectionController.attachToRecyclerView(item.manga, binding.recyclerView)
|
selectionController.attachToRecyclerView(item.manga, binding.recyclerView)
|
||||||
}
|
}
|
||||||
binding.imageViewCover.newImageRequest(item.manga.coverUrl, item.manga.source)?.run {
|
binding.imageViewCover.newImageRequest(item.manga.coverUrl, item.manga.source)?.run {
|
||||||
referer(item.manga.publicUrl)
|
|
||||||
placeholder(R.drawable.ic_placeholder)
|
placeholder(R.drawable.ic_placeholder)
|
||||||
fallback(R.drawable.ic_placeholder)
|
fallback(R.drawable.ic_placeholder)
|
||||||
error(R.drawable.ic_error_placeholder)
|
error(R.drawable.ic_error_placeholder)
|
||||||
|
|||||||
@@ -8,16 +8,14 @@ import android.net.Uri
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updateLayoutParams
|
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import com.google.android.material.R as materialR
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||||
import org.koitharu.kotatsu.core.network.UserAgentInterceptor
|
import org.koitharu.kotatsu.core.network.CommonHeadersInterceptor
|
||||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback {
|
class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback {
|
||||||
@@ -31,7 +29,7 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
|
|||||||
}
|
}
|
||||||
with(binding.webView.settings) {
|
with(binding.webView.settings) {
|
||||||
javaScriptEnabled = true
|
javaScriptEnabled = true
|
||||||
userAgentString = UserAgentInterceptor.userAgentChrome
|
userAgentString = CommonHeadersInterceptor.userAgentChrome
|
||||||
}
|
}
|
||||||
binding.webView.webViewClient = BrowserClient(this)
|
binding.webView.webViewClient = BrowserClient(this)
|
||||||
binding.webView.webChromeClient = ProgressChromeClient(binding.progressBar)
|
binding.webView.webChromeClient = ProgressChromeClient(binding.progressBar)
|
||||||
@@ -72,6 +70,7 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
|
|||||||
finishAfterTransition()
|
finishAfterTransition()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_browser -> {
|
R.id.action_browser -> {
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
intent.data = Uri.parse(binding.webView.url)
|
intent.data = Uri.parse(binding.webView.url)
|
||||||
@@ -81,6 +80,7 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> super.onOptionsItemSelected(item)
|
else -> super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import org.koitharu.kotatsu.base.ui.AlertDialogFragment
|
import org.koitharu.kotatsu.base.ui.AlertDialogFragment
|
||||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||||
import org.koitharu.kotatsu.core.network.UserAgentInterceptor
|
import org.koitharu.kotatsu.core.network.CommonHeadersInterceptor
|
||||||
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
||||||
import org.koitharu.kotatsu.databinding.FragmentCloudflareBinding
|
import org.koitharu.kotatsu.databinding.FragmentCloudflareBinding
|
||||||
import org.koitharu.kotatsu.utils.ext.stringArgument
|
import org.koitharu.kotatsu.utils.ext.stringArgument
|
||||||
@@ -44,7 +44,7 @@ class CloudFlareDialog : AlertDialogFragment<FragmentCloudflareBinding>(), Cloud
|
|||||||
cacheMode = WebSettings.LOAD_DEFAULT
|
cacheMode = WebSettings.LOAD_DEFAULT
|
||||||
domStorageEnabled = true
|
domStorageEnabled = true
|
||||||
databaseEnabled = true
|
databaseEnabled = true
|
||||||
userAgentString = arguments?.getString(ARG_UA) ?: UserAgentInterceptor.userAgentChrome
|
userAgentString = arguments?.getString(ARG_UA) ?: CommonHeadersInterceptor.userAgentChrome
|
||||||
}
|
}
|
||||||
binding.webView.webViewClient = CloudFlareClient(cookieJar, this, url.orEmpty())
|
binding.webView.webViewClient = CloudFlareClient(cookieJar, this, url.orEmpty())
|
||||||
CookieManager.getInstance().setAcceptThirdPartyCookies(binding.webView, true)
|
CookieManager.getInstance().setAcceptThirdPartyCookies(binding.webView, true)
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ interface AppModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
fun provideOkHttpClient(
|
fun provideOkHttpClient(
|
||||||
localStorageManager: LocalStorageManager,
|
localStorageManager: LocalStorageManager,
|
||||||
userAgentInterceptor: UserAgentInterceptor,
|
commonHeadersInterceptor: CommonHeadersInterceptor,
|
||||||
cookieJar: CookieJar,
|
cookieJar: CookieJar,
|
||||||
settings: AppSettings,
|
settings: AppSettings,
|
||||||
): OkHttpClient {
|
): OkHttpClient {
|
||||||
@@ -98,7 +98,7 @@ interface AppModule {
|
|||||||
dns(DoHManager(cache, settings))
|
dns(DoHManager(cache, settings))
|
||||||
cache(cache)
|
cache(cache)
|
||||||
addInterceptor(GZipInterceptor())
|
addInterceptor(GZipInterceptor())
|
||||||
addInterceptor(userAgentInterceptor)
|
addInterceptor(commonHeadersInterceptor)
|
||||||
addInterceptor(CloudFlareInterceptor())
|
addInterceptor(CloudFlareInterceptor())
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
addInterceptor(CurlLoggingInterceptor())
|
addInterceptor(CurlLoggingInterceptor())
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.koitharu.kotatsu.core.network
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import dagger.Lazy
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.util.mergeWith
|
||||||
|
import java.util.Locale
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class CommonHeadersInterceptor @Inject constructor(
|
||||||
|
private val mangaRepositoryFactoryLazy: Lazy<MangaRepository.Factory>,
|
||||||
|
) : Interceptor {
|
||||||
|
|
||||||
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
val request = chain.request()
|
||||||
|
val source = request.tag(MangaSource::class.java)
|
||||||
|
val repository = if (source != null) {
|
||||||
|
mangaRepositoryFactoryLazy.get().create(source) as? RemoteMangaRepository
|
||||||
|
} else {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Log.w("Http", "Request without source tag: ${request.url}")
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
val headersBuilder = request.headers.newBuilder()
|
||||||
|
repository?.headers?.let {
|
||||||
|
headersBuilder.mergeWith(it, replaceExisting = false)
|
||||||
|
}
|
||||||
|
if (headersBuilder[CommonHeaders.USER_AGENT] == null) {
|
||||||
|
headersBuilder[CommonHeaders.USER_AGENT] = userAgentFallback
|
||||||
|
}
|
||||||
|
if (headersBuilder[CommonHeaders.REFERER] == null && repository != null) {
|
||||||
|
headersBuilder[CommonHeaders.REFERER] = "https://${repository.domain}/"
|
||||||
|
}
|
||||||
|
val newRequest = request.newBuilder().headers(headersBuilder.build()).build()
|
||||||
|
return repository?.intercept(ProxyChain(chain, newRequest)) ?: chain.proceed(newRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProxyChain(
|
||||||
|
private val delegate: Interceptor.Chain,
|
||||||
|
private val request: Request,
|
||||||
|
) : Interceptor.Chain by delegate {
|
||||||
|
|
||||||
|
override fun request(): Request = request
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val userAgentFallback
|
||||||
|
get() = "Kotatsu/%s (Android %s; %s; %s %s; %s)".format(
|
||||||
|
BuildConfig.VERSION_NAME,
|
||||||
|
Build.VERSION.RELEASE,
|
||||||
|
Build.MODEL,
|
||||||
|
Build.BRAND,
|
||||||
|
Build.DEVICE,
|
||||||
|
Locale.getDefault().language,
|
||||||
|
)
|
||||||
|
|
||||||
|
val userAgentChrome
|
||||||
|
get() = (
|
||||||
|
"Mozilla/5.0 (Linux; Android %s; %s) AppleWebKit/537.36 (KHTML, like Gecko) " +
|
||||||
|
"Chrome/100.0.4896.127 Mobile Safari/537.36"
|
||||||
|
).format(
|
||||||
|
Build.VERSION.RELEASE,
|
||||||
|
Build.MODEL,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.core.network
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import dagger.Lazy
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
|
||||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
|
||||||
import java.util.Locale
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class UserAgentInterceptor @Inject constructor(
|
|
||||||
private val mangaRepositoryFactoryLazy: Lazy<MangaRepository.Factory>,
|
|
||||||
) : Interceptor {
|
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
|
||||||
val request = chain.request()
|
|
||||||
return chain.proceed(
|
|
||||||
if (request.header(CommonHeaders.USER_AGENT) == null) {
|
|
||||||
request.newBuilder()
|
|
||||||
.addHeader(CommonHeaders.USER_AGENT, getUserAgent(request))
|
|
||||||
.build()
|
|
||||||
} else request,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getUserAgent(request: Request): String {
|
|
||||||
val source = request.tag(MangaSource::class.java) ?: return userAgent
|
|
||||||
val repository = mangaRepositoryFactoryLazy.get().create(source) as? RemoteMangaRepository
|
|
||||||
return repository?.userAgent ?: userAgent
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
val userAgent
|
|
||||||
get() = "Kotatsu/%s (Android %s; %s; %s %s; %s)".format(
|
|
||||||
BuildConfig.VERSION_NAME,
|
|
||||||
Build.VERSION.RELEASE,
|
|
||||||
Build.MODEL,
|
|
||||||
Build.BRAND,
|
|
||||||
Build.DEVICE,
|
|
||||||
Locale.getDefault().language,
|
|
||||||
) // TODO Decide what to do with this afterwards
|
|
||||||
|
|
||||||
val userAgentChrome
|
|
||||||
get() = (
|
|
||||||
"Mozilla/5.0 (Linux; Android %s; %s) AppleWebKit/537.36 (KHTML, like Gecko) " +
|
|
||||||
"Chrome/100.0.4896.127 Mobile Safari/537.36"
|
|
||||||
).format(
|
|
||||||
Build.VERSION.RELEASE,
|
|
||||||
Build.MODEL,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,9 +6,11 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.MainCoroutineDispatcher
|
import kotlinx.coroutines.MainCoroutineDispatcher
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.currentCoroutineContext
|
import kotlinx.coroutines.currentCoroutineContext
|
||||||
|
import okhttp3.Headers
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.Response
|
||||||
import org.koitharu.kotatsu.core.cache.ContentCache
|
import org.koitharu.kotatsu.core.cache.ContentCache
|
||||||
import org.koitharu.kotatsu.core.cache.SafeDeferred
|
import org.koitharu.kotatsu.core.cache.SafeDeferred
|
||||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
|
||||||
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
||||||
import org.koitharu.kotatsu.parsers.MangaParser
|
import org.koitharu.kotatsu.parsers.MangaParser
|
||||||
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
||||||
@@ -20,13 +22,14 @@ import org.koitharu.kotatsu.parsers.model.MangaPage
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||||
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.utils.ext.processLifecycleScope
|
import org.koitharu.kotatsu.utils.ext.processLifecycleScope
|
||||||
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
||||||
|
|
||||||
class RemoteMangaRepository(
|
class RemoteMangaRepository(
|
||||||
private val parser: MangaParser,
|
private val parser: MangaParser,
|
||||||
private val cache: ContentCache,
|
private val cache: ContentCache,
|
||||||
) : MangaRepository {
|
) : MangaRepository, Interceptor {
|
||||||
|
|
||||||
override val source: MangaSource
|
override val source: MangaSource
|
||||||
get() = parser.source
|
get() = parser.source
|
||||||
@@ -40,8 +43,19 @@ class RemoteMangaRepository(
|
|||||||
getConfig().defaultSortOrder = value
|
getConfig().defaultSortOrder = value
|
||||||
}
|
}
|
||||||
|
|
||||||
val userAgent: String?
|
val domain: String
|
||||||
get() = parser.headers?.get(CommonHeaders.USER_AGENT)
|
get() = parser.domain
|
||||||
|
|
||||||
|
val headers: Headers?
|
||||||
|
get() = parser.headers
|
||||||
|
|
||||||
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
return if (parser is Interceptor) {
|
||||||
|
parser.intercept(chain)
|
||||||
|
} else {
|
||||||
|
chain.proceed(chain.request())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getList(offset: Int, query: String): List<Manga> {
|
override suspend fun getList(offset: Int, query: String): List<Manga> {
|
||||||
return parser.getList(offset, query)
|
return parser.getList(offset, query)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import okhttp3.Response
|
|||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import okhttp3.internal.closeQuietly
|
import okhttp3.internal.closeQuietly
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||||
import org.koitharu.kotatsu.local.data.CacheDir
|
import org.koitharu.kotatsu.local.data.CacheDir
|
||||||
@@ -53,7 +52,7 @@ class FaviconFetcher(
|
|||||||
options.size.height.pxOrElse { FALLBACK_SIZE },
|
options.size.height.pxOrElse { FALLBACK_SIZE },
|
||||||
)
|
)
|
||||||
val icon = checkNotNull(favicons.find(sizePx)) { "No favicons found" }
|
val icon = checkNotNull(favicons.find(sizePx)) { "No favicons found" }
|
||||||
val response = loadIcon(icon.url, repo.userAgent, favicons.referer)
|
val response = loadIcon(icon.url, mangaSource)
|
||||||
val responseBody = response.requireBody()
|
val responseBody = response.requireBody()
|
||||||
val source = writeToDiskCache(responseBody)?.toImageSource() ?: responseBody.toImageSource()
|
val source = writeToDiskCache(responseBody)?.toImageSource() ?: responseBody.toImageSource()
|
||||||
return SourceResult(
|
return SourceResult(
|
||||||
@@ -63,14 +62,11 @@ class FaviconFetcher(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun loadIcon(url: String, userAgent: String?, referer: String): Response {
|
private suspend fun loadIcon(url: String, source: MangaSource): Response {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.get()
|
.get()
|
||||||
.header(CommonHeaders.REFERER, referer)
|
.tag(MangaSource::class.java, source)
|
||||||
if (userAgent != null) {
|
|
||||||
request.header(CommonHeaders.USER_AGENT, userAgent)
|
|
||||||
}
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
options.tags.asMap().forEach { request.tag(it.key as Class<Any>, it.value) }
|
options.tags.asMap().forEach { request.tag(it.key as Class<Any>, it.value) }
|
||||||
val response = okHttpClient.newCall(request.build()).await()
|
val response = okHttpClient.newCall(request.build()).await()
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import org.koitharu.kotatsu.utils.ext.drawableTop
|
|||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.ifNullOrEmpty
|
import org.koitharu.kotatsu.utils.ext.ifNullOrEmpty
|
||||||
import org.koitharu.kotatsu.utils.ext.measureHeight
|
import org.koitharu.kotatsu.utils.ext.measureHeight
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.resolveDp
|
import org.koitharu.kotatsu.utils.ext.resolveDp
|
||||||
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
|
import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf
|
||||||
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
||||||
@@ -343,7 +342,6 @@ class DetailsFragment :
|
|||||||
.data(imageUrl)
|
.data(imageUrl)
|
||||||
.tag(manga.source)
|
.tag(manga.source)
|
||||||
.crossfade(context)
|
.crossfade(context)
|
||||||
.referer(manga.publicUrl)
|
|
||||||
.lifecycle(viewLifecycleOwner)
|
.lifecycle(viewLifecycleOwner)
|
||||||
.placeholderMemoryCacheKey(manga.coverUrl)
|
.placeholderMemoryCacheKey(manga.coverUrl)
|
||||||
val previousDrawable = lastResult?.drawable
|
val previousDrawable = lastResult?.drawable
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import org.koitharu.kotatsu.parsers.util.await
|
|||||||
import org.koitharu.kotatsu.utils.ext.copyToSuspending
|
import org.koitharu.kotatsu.utils.ext.copyToSuspending
|
||||||
import org.koitharu.kotatsu.utils.ext.deleteAwait
|
import org.koitharu.kotatsu.utils.ext.deleteAwait
|
||||||
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
||||||
import org.koitharu.kotatsu.utils.progress.PausingProgressJob
|
import org.koitharu.kotatsu.utils.progress.PausingProgressJob
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -220,7 +219,7 @@ class DownloadManager @AssistedInject constructor(
|
|||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(CommonHeaders.REFERER, referer)
|
.header(CommonHeaders.REFERER, referer)
|
||||||
.tag(source)
|
.tag(MangaSource::class.java, source)
|
||||||
.cacheControl(CommonHeaders.CACHE_CONTROL_DISABLED)
|
.cacheControl(CommonHeaders.CACHE_CONTROL_DISABLED)
|
||||||
.get()
|
.get()
|
||||||
.build()
|
.build()
|
||||||
@@ -250,7 +249,6 @@ class DownloadManager @AssistedInject constructor(
|
|||||||
imageLoader.execute(
|
imageLoader.execute(
|
||||||
ImageRequest.Builder(context)
|
ImageRequest.Builder(context)
|
||||||
.data(manga.coverUrl)
|
.data(manga.coverUrl)
|
||||||
.referer(manga.publicUrl)
|
|
||||||
.tag(manga.source)
|
.tag(manga.source)
|
||||||
.size(coverWidth, coverHeight)
|
.size(coverWidth, coverHeight)
|
||||||
.scale(Scale.FILL)
|
.scale(Scale.FILL)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.koitharu.kotatsu.utils.ext.enqueueWith
|
|||||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.onFirst
|
import org.koitharu.kotatsu.utils.ext.onFirst
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
|
|
||||||
fun downloadItemAD(
|
fun downloadItemAD(
|
||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
@@ -45,7 +44,6 @@ fun downloadItemAD(
|
|||||||
job?.cancel()
|
job?.cancel()
|
||||||
job = item.progressAsFlow().onFirst { state ->
|
job = item.progressAsFlow().onFirst { state ->
|
||||||
binding.imageViewCover.newImageRequest(state.manga.coverUrl, state.manga.source)?.run {
|
binding.imageViewCover.newImageRequest(state.manga.coverUrl, state.manga.source)?.run {
|
||||||
referer(state.manga.publicUrl)
|
|
||||||
placeholder(state.cover)
|
placeholder(state.cover)
|
||||||
fallback(R.drawable.ic_placeholder)
|
fallback(R.drawable.ic_placeholder)
|
||||||
error(R.drawable.ic_error_placeholder)
|
error(R.drawable.ic_error_placeholder)
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import org.koitharu.kotatsu.parsers.model.Manga
|
|||||||
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.image.CoverSizeResolver
|
import org.koitharu.kotatsu.utils.image.CoverSizeResolver
|
||||||
|
|
||||||
fun mangaGridItemAD(
|
fun mangaGridItemAD(
|
||||||
@@ -40,7 +39,6 @@ fun mangaGridItemAD(
|
|||||||
binding.textViewTitle.text = item.title
|
binding.textViewTitle.text = item.title
|
||||||
binding.progressView.setPercent(item.progress, MangaListAdapter.PAYLOAD_PROGRESS in payloads)
|
binding.progressView.setPercent(item.progress, MangaListAdapter.PAYLOAD_PROGRESS in payloads)
|
||||||
binding.imageViewCover.newImageRequest(item.coverUrl, item.source)?.run {
|
binding.imageViewCover.newImageRequest(item.coverUrl, item.source)?.run {
|
||||||
referer(item.manga.publicUrl)
|
|
||||||
size(CoverSizeResolver(binding.imageViewCover))
|
size(CoverSizeResolver(binding.imageViewCover))
|
||||||
placeholder(R.drawable.ic_placeholder)
|
placeholder(R.drawable.ic_placeholder)
|
||||||
fallback(R.drawable.ic_placeholder)
|
fallback(R.drawable.ic_placeholder)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.koitharu.kotatsu.parsers.model.MangaTag
|
|||||||
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
||||||
import org.koitharu.kotatsu.utils.image.CoverSizeResolver
|
import org.koitharu.kotatsu.utils.image.CoverSizeResolver
|
||||||
|
|
||||||
@@ -53,7 +52,6 @@ fun mangaListDetailedItemAD(
|
|||||||
binding.textViewSubtitle.textAndVisible = item.subtitle
|
binding.textViewSubtitle.textAndVisible = item.subtitle
|
||||||
binding.progressView.setPercent(item.progress, MangaListAdapter.PAYLOAD_PROGRESS in payloads)
|
binding.progressView.setPercent(item.progress, MangaListAdapter.PAYLOAD_PROGRESS in payloads)
|
||||||
binding.imageViewCover.newImageRequest(item.coverUrl, item.source)?.run {
|
binding.imageViewCover.newImageRequest(item.coverUrl, item.source)?.run {
|
||||||
referer(item.manga.publicUrl)
|
|
||||||
size(CoverSizeResolver(binding.imageViewCover))
|
size(CoverSizeResolver(binding.imageViewCover))
|
||||||
placeholder(R.drawable.ic_placeholder)
|
placeholder(R.drawable.ic_placeholder)
|
||||||
fallback(R.drawable.ic_placeholder)
|
fallback(R.drawable.ic_placeholder)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.koitharu.kotatsu.parsers.model.Manga
|
|||||||
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
import org.koitharu.kotatsu.utils.ext.disposeImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
import org.koitharu.kotatsu.utils.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
||||||
|
|
||||||
fun mangaListItemAD(
|
fun mangaListItemAD(
|
||||||
@@ -36,7 +35,6 @@ fun mangaListItemAD(
|
|||||||
binding.textViewTitle.text = item.title
|
binding.textViewTitle.text = item.title
|
||||||
binding.textViewSubtitle.textAndVisible = item.subtitle
|
binding.textViewSubtitle.textAndVisible = item.subtitle
|
||||||
binding.imageViewCover.newImageRequest(item.coverUrl, item.source)?.run {
|
binding.imageViewCover.newImageRequest(item.coverUrl, item.source)?.run {
|
||||||
referer(item.manga.publicUrl)
|
|
||||||
placeholder(R.drawable.ic_placeholder)
|
placeholder(R.drawable.ic_placeholder)
|
||||||
fallback(R.drawable.ic_placeholder)
|
fallback(R.drawable.ic_placeholder)
|
||||||
error(R.drawable.ic_error_placeholder)
|
error(R.drawable.ic_error_placeholder)
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import org.koitharu.kotatsu.utils.PendingIntentCompat
|
|||||||
import org.koitharu.kotatsu.utils.ext.asArrayList
|
import org.koitharu.kotatsu.utils.ext.asArrayList
|
||||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||||
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.report
|
import org.koitharu.kotatsu.utils.ext.report
|
||||||
import org.koitharu.kotatsu.utils.ext.toBitmapOrNull
|
import org.koitharu.kotatsu.utils.ext.toBitmapOrNull
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -102,7 +101,6 @@ class ImportService : CoroutineIntentService() {
|
|||||||
ImageRequest.Builder(applicationContext)
|
ImageRequest.Builder(applicationContext)
|
||||||
.data(manga.coverUrl)
|
.data(manga.coverUrl)
|
||||||
.tag(manga.source)
|
.tag(manga.source)
|
||||||
.referer(manga.publicUrl)
|
|
||||||
.build(),
|
.build(),
|
||||||
).toBitmapOrNull(),
|
).toBitmapOrNull(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ class PageLoader @Inject constructor(
|
|||||||
.header(CommonHeaders.REFERER, page.referer)
|
.header(CommonHeaders.REFERER, page.referer)
|
||||||
.header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8")
|
.header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8")
|
||||||
.cacheControl(CommonHeaders.CACHE_CONTROL_DISABLED)
|
.cacheControl(CommonHeaders.CACHE_CONTROL_DISABLED)
|
||||||
.tag(page.source)
|
.tag(MangaSource::class.java, page.source)
|
||||||
.build()
|
.build()
|
||||||
okHttp.newCall(request).await().use { response ->
|
okHttp.newCall(request).await().use { response ->
|
||||||
check(response.isSuccessful) {
|
check(response.isSuccessful) {
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.koitharu.kotatsu.utils.ext.assistedViewModels
|
|||||||
import org.koitharu.kotatsu.utils.ext.decodeRegion
|
import org.koitharu.kotatsu.utils.ext.decodeRegion
|
||||||
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
import org.koitharu.kotatsu.utils.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat
|
import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.setValueRounded
|
import org.koitharu.kotatsu.utils.ext.setValueRounded
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.google.android.material.R as materialR
|
import com.google.android.material.R as materialR
|
||||||
@@ -117,7 +116,6 @@ class ColorFilterConfigActivity :
|
|||||||
if (preview == null) return
|
if (preview == null) return
|
||||||
ImageRequest.Builder(this@ColorFilterConfigActivity)
|
ImageRequest.Builder(this@ColorFilterConfigActivity)
|
||||||
.data(preview.url)
|
.data(preview.url)
|
||||||
.referer(preview.referer)
|
|
||||||
.scale(Scale.FILL)
|
.scale(Scale.FILL)
|
||||||
.decodeRegion()
|
.decodeRegion()
|
||||||
.tag(preview.source)
|
.tag(preview.source)
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import org.koitharu.kotatsu.reader.domain.PageLoader
|
|||||||
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
|
import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail
|
||||||
import org.koitharu.kotatsu.utils.ext.decodeRegion
|
import org.koitharu.kotatsu.utils.ext.decodeRegion
|
||||||
import org.koitharu.kotatsu.utils.ext.isLowRamDevice
|
import org.koitharu.kotatsu.utils.ext.isLowRamDevice
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
||||||
import org.koitharu.kotatsu.utils.ext.setTextColorAttr
|
import org.koitharu.kotatsu.utils.ext.setTextColorAttr
|
||||||
import com.google.android.material.R as materialR
|
import com.google.android.material.R as materialR
|
||||||
@@ -44,7 +43,6 @@ fun pageThumbnailAD(
|
|||||||
coil.execute(
|
coil.execute(
|
||||||
ImageRequest.Builder(context)
|
ImageRequest.Builder(context)
|
||||||
.data(url)
|
.data(url)
|
||||||
.referer(item.page.referer)
|
|
||||||
.tag(item.page.source)
|
.tag(item.page.source)
|
||||||
.size(thumbSize)
|
.size(thumbSize)
|
||||||
.scale(Scale.FILL)
|
.scale(Scale.FILL)
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import org.koitharu.kotatsu.base.ui.BaseActivity
|
|||||||
import org.koitharu.kotatsu.browser.BrowserCallback
|
import org.koitharu.kotatsu.browser.BrowserCallback
|
||||||
import org.koitharu.kotatsu.browser.BrowserClient
|
import org.koitharu.kotatsu.browser.BrowserClient
|
||||||
import org.koitharu.kotatsu.browser.ProgressChromeClient
|
import org.koitharu.kotatsu.browser.ProgressChromeClient
|
||||||
import org.koitharu.kotatsu.core.network.UserAgentInterceptor
|
import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||||
|
import org.koitharu.kotatsu.core.network.CommonHeadersInterceptor
|
||||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||||
@@ -60,7 +61,8 @@ class SourceAuthActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallba
|
|||||||
}
|
}
|
||||||
with(binding.webView.settings) {
|
with(binding.webView.settings) {
|
||||||
javaScriptEnabled = true
|
javaScriptEnabled = true
|
||||||
userAgentString = repository.userAgent ?: UserAgentInterceptor.userAgent
|
userAgentString = repository.headers?.get(CommonHeaders.USER_AGENT)
|
||||||
|
?: CommonHeadersInterceptor.userAgentFallback
|
||||||
}
|
}
|
||||||
binding.webView.webViewClient = BrowserClient(this)
|
binding.webView.webViewClient = BrowserClient(this)
|
||||||
binding.webView.webChromeClient = ProgressChromeClient(binding.progressBar)
|
binding.webView.webChromeClient = ProgressChromeClient(binding.progressBar)
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter
|
|||||||
import org.koitharu.kotatsu.tracker.domain.Tracker
|
import org.koitharu.kotatsu.tracker.domain.Tracker
|
||||||
import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates
|
import org.koitharu.kotatsu.tracker.domain.model.MangaUpdates
|
||||||
import org.koitharu.kotatsu.utils.PendingIntentCompat
|
import org.koitharu.kotatsu.utils.PendingIntentCompat
|
||||||
import org.koitharu.kotatsu.utils.ext.referer
|
|
||||||
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
|
||||||
import org.koitharu.kotatsu.utils.ext.toBitmapOrNull
|
import org.koitharu.kotatsu.utils.ext.toBitmapOrNull
|
||||||
import org.koitharu.kotatsu.utils.ext.trySetForeground
|
import org.koitharu.kotatsu.utils.ext.trySetForeground
|
||||||
@@ -157,7 +156,6 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
coil.execute(
|
coil.execute(
|
||||||
ImageRequest.Builder(applicationContext)
|
ImageRequest.Builder(applicationContext)
|
||||||
.data(manga.coverUrl)
|
.data(manga.coverUrl)
|
||||||
.referer(manga.publicUrl)
|
|
||||||
.tag(manga.source)
|
.tag(manga.source)
|
||||||
.build(),
|
.build(),
|
||||||
).toBitmapOrNull(),
|
).toBitmapOrNull(),
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import coil.request.ImageResult
|
|||||||
import coil.request.SuccessResult
|
import coil.request.SuccessResult
|
||||||
import coil.util.CoilUtils
|
import coil.util.CoilUtils
|
||||||
import com.google.android.material.progressindicator.BaseProgressIndicator
|
import com.google.android.material.progressindicator.BaseProgressIndicator
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.utils.image.RegionBitmapDecoder
|
import org.koitharu.kotatsu.utils.image.RegionBitmapDecoder
|
||||||
import org.koitharu.kotatsu.utils.progress.ImageRequestIndicatorListener
|
import org.koitharu.kotatsu.utils.progress.ImageRequestIndicatorListener
|
||||||
@@ -51,21 +49,6 @@ fun ImageResult.toBitmapOrNull() = when (this) {
|
|||||||
is ErrorResult -> null
|
is ErrorResult -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ImageRequest.Builder.referer(referer: String): ImageRequest.Builder {
|
|
||||||
if (referer.isEmpty()) {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
setHeader(CommonHeaders.REFERER, referer)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
val baseUrl = referer.baseUrl()
|
|
||||||
if (baseUrl != null) {
|
|
||||||
setHeader(CommonHeaders.REFERER, baseUrl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ImageRequest.Builder.indicator(indicator: BaseProgressIndicator<*>): ImageRequest.Builder {
|
fun ImageRequest.Builder.indicator(indicator: BaseProgressIndicator<*>): ImageRequest.Builder {
|
||||||
return listener(ImageRequestIndicatorListener(indicator))
|
return listener(ImageRequestIndicatorListener(indicator))
|
||||||
}
|
}
|
||||||
@@ -83,11 +66,3 @@ fun ImageRequest.Builder.crossfade(context: Context?): ImageRequest.Builder {
|
|||||||
val duration = context.resources.getInteger(R.integer.config_defaultAnimTime) * context.animatorDurationScale
|
val duration = context.resources.getInteger(R.integer.config_defaultAnimTime) * context.animatorDurationScale
|
||||||
return crossfade(duration.toInt())
|
return crossfade(duration.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.baseUrl(): String? {
|
|
||||||
return (this.toHttpUrlOrNull()?.newBuilder("/") ?: return null)
|
|
||||||
.username("")
|
|
||||||
.password("")
|
|
||||||
.build()
|
|
||||||
.toString()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import org.koitharu.kotatsu.parsers.model.MangaTag
|
|||||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||||
import java.util.EnumSet
|
import java.util.EnumSet
|
||||||
|
|
||||||
class DummyParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.DUMMY) {
|
class DummyParser(context: MangaLoaderContext) : MangaParser(context, MangaSource.DUMMY) {
|
||||||
|
|
||||||
override val configKeyDomain: ConfigKey.Domain
|
override val configKeyDomain: ConfigKey.Domain
|
||||||
get() = ConfigKey.Domain("localhost", null)
|
get() = ConfigKey.Domain("localhost", null)
|
||||||
|
|||||||
Reference in New Issue
Block a user