diff --git a/.travis.yml b/.travis.yml index 714819fb7..6187fee35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: trusty android: components: - android-30 - - build-tools-30.0.2 - - platform-tools-30.0.3 + - build-tools-30.0.3 + - platform-tools-30.0.5 - tools script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt index 45072da6b..83bd5dc25 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt @@ -5,10 +5,13 @@ import android.net.Uri import android.util.Size import androidx.annotation.WorkerThread import okhttp3.OkHttpClient +import okhttp3.Request import org.koin.core.component.KoinComponent import org.koin.core.component.get import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.core.network.CommonHeaders +import org.koitharu.kotatsu.utils.CacheUtils import org.koitharu.kotatsu.utils.ext.await import org.koitharu.kotatsu.utils.ext.medianOrNull import java.io.InputStream @@ -25,8 +28,8 @@ object MangaUtils : KoinComponent { suspend fun determineMangaIsWebtoon(pages: List): Boolean? { try { val page = pages.medianOrNull() ?: return null - val pageRequest = page.source.repository.getPageRequest(page) - val uri = Uri.parse(pageRequest.url) + val url = page.source.repository.getPageUrl(page) + val uri = Uri.parse(url) val size = if (uri.scheme == "cbz") { val zip = ZipFile(uri.schemeSpecificPart) val entry = zip.getEntry(uri.fragment) @@ -35,7 +38,11 @@ object MangaUtils : KoinComponent { } } else { val client = get() - val request = pageRequest.newBuilder() + val request = Request.Builder() + .url(url) + .get() + .header(CommonHeaders.REFERER, page.referer) + .cacheControl(CacheUtils.CONTROL_DISABLED) .build() client.newCall(request).await().use { getBitmapSize(it.body?.byteStream()) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/RequestDraft.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/RequestDraft.kt deleted file mode 100644 index 9fdf46651..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/RequestDraft.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.koitharu.kotatsu.core.model - -import okhttp3.Headers -import okhttp3.Request - -data class RequestDraft( - val url: String, - val headers: Headers -) { - - val isValid: Boolean - get() = url.isNotEmpty() - - fun newBuilder(): Request.Builder = Request.Builder() - .url(url) - .get() - .headers(headers) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt index b15583535..cd17805d4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt @@ -17,7 +17,7 @@ interface MangaRepository { suspend fun getPages(chapter: MangaChapter): List - suspend fun getPageRequest(page: MangaPage): RequestDraft + suspend fun getPageUrl(page: MangaPage): String suspend fun getTags(): Set } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt index afe237d53..e3d2237c7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt @@ -1,9 +1,10 @@ package org.koitharu.kotatsu.core.parser -import okhttp3.Headers import org.koitharu.kotatsu.base.domain.MangaLoaderContext -import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.core.network.CommonHeaders +import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.core.model.MangaTag +import org.koitharu.kotatsu.core.model.SortOrder abstract class RemoteMangaRepository( protected val loaderContext: MangaLoaderContext @@ -17,12 +18,7 @@ abstract class RemoteMangaRepository( override val sortOrders: Set get() = emptySet() - override suspend fun getPageRequest(page: MangaPage): RequestDraft { - return RequestDraft( - url = page.url, - headers = Headers.headersOf(CommonHeaders.REFERER, page.referer) - ) - } + override suspend fun getPageUrl(page: MangaPage): String = page.url override suspend fun getTags(): Set = emptySet() diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt index 4245c7ba1..6360b252d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt @@ -1,12 +1,10 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf -import okhttp3.Headers import org.intellij.lang.annotations.Language import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings import org.koitharu.kotatsu.utils.ext.* @@ -142,12 +140,11 @@ class MangaTownRepository(loaderContext: MangaLoaderContext) : } } - override suspend fun getPageRequest(page: MangaPage): RequestDraft { + override suspend fun getPageUrl(page: MangaPage): String { val domain = conf.getDomain(DOMAIN) val ssl = conf.isUseSsl(false) val doc = loaderContext.httpGet(page.url).parseHtml() - val url = doc.getElementById("image").attr("src").withDomain(domain, ssl) - return RequestDraft(url, Headers.headersOf(CommonHeaders.REFERER, page.referer)) + return doc.getElementById("image").attr("src").withDomain(domain, ssl) } override suspend fun getTags(): Set { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt index c7e4df9c7..f83586a16 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt @@ -1,11 +1,9 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf -import okhttp3.Headers import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings import org.koitharu.kotatsu.utils.ext.* @@ -118,10 +116,9 @@ class NudeMoonRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposit } } - override suspend fun getPageRequest(page: MangaPage): RequestDraft { + override suspend fun getPageUrl(page: MangaPage): String { val doc = loaderContext.httpGet(page.url).parseHtml() - val url = doc.body().getElementById("gallery").attr("src").inContextOf(doc) - return RequestDraft(url, Headers.headersOf(CommonHeaders.REFERER, page.referer)) + return doc.body().getElementById("gallery").attr("src").inContextOf(doc) } override suspend fun getTags(): Set { diff --git a/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt b/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt index a434571cb..b07239c81 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt @@ -12,8 +12,8 @@ import coil.ImageLoader import coil.request.ImageRequest import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex -import okhttp3.Headers import okhttp3.OkHttpClient +import okhttp3.Request import okio.IOException import org.koin.android.ext.android.get import org.koin.android.ext.android.inject @@ -23,7 +23,6 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseService import org.koitharu.kotatsu.base.ui.dialog.CheckBoxAlertDialog import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.RequestDraft import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.local.data.MangaZip @@ -107,12 +106,7 @@ class DownloadService : BaseService() { output = MangaZip.findInDir(destination, data) output.prepare(data) val coverUrl = data.largeCoverUrl ?: data.coverUrl - downloadPage( - RequestDraft( - coverUrl, - Headers.headersOf(CommonHeaders.REFERER, data.url) - ), destination - ).let { file -> + downloadFile(coverUrl, data.url, destination).let { file -> output.addCover(file, MimeTypeMap.getFileExtensionFromUrl(coverUrl)) } val chapters = if (chaptersIds == null) { @@ -126,14 +120,14 @@ class DownloadService : BaseService() { for ((pageIndex, page) in pages.withIndex()) { failsafe@ do { try { - val request = repo.getPageRequest(page) + val url = repo.getPageUrl(page) val file = - cache[request.url] ?: downloadPage(request, destination) + cache[url] ?: downloadFile(url, page.referer, destination) output.addPage( chapter, file, pageIndex, - MimeTypeMap.getFileExtensionFromUrl(request.url) + MimeTypeMap.getFileExtensionFromUrl(url) ) } catch (e: IOException) { notification.setWaitingForNetwork() @@ -195,8 +189,10 @@ class DownloadService : BaseService() { } } - private suspend fun downloadPage(requestDraft: RequestDraft, destination: File): File { - val request = requestDraft.newBuilder() + private suspend fun downloadFile(url: String, referer: String, destination: File): File { + val request = Request.Builder() + .url(url) + .header(CommonHeaders.REFERER, referer) .cacheControl(CacheUtils.CONTROL_DISABLED) .get() .build() 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 56d458839..7f0548509 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 @@ -7,7 +7,6 @@ import android.webkit.MimeTypeMap import androidx.collection.ArraySet import androidx.core.net.toFile import androidx.core.net.toUri -import okhttp3.internal.EMPTY_HEADERS import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.local.data.CbzFilter @@ -157,9 +156,7 @@ class LocalMangaRepository(private val context: Context) : MangaRepository { override val sortOrders = emptySet() - override suspend fun getPageRequest(page: MangaPage): RequestDraft { - return RequestDraft(page.url, EMPTY_HEADERS) - } + override suspend fun getPageUrl(page: MangaPage) = page.url override suspend fun getTags() = emptySet() diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt index acdd7bca7..0b66f7087 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/domain/PageLoader.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import okhttp3.OkHttpClient +import okhttp3.Request import org.koin.core.component.KoinComponent import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.network.CommonHeaders @@ -54,17 +55,20 @@ class PageLoader( 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) + val pageUrl = repo.getPageUrl(page) + check(pageUrl.isNotBlank()) { "Cannot obtain full image url" } + val uri = Uri.parse(pageUrl) if (uri.scheme == "cbz") { val zip = ZipFile(uri.schemeSpecificPart) val entry = zip.getEntry(uri.fragment) zip.getInputStream(entry).use { - cache.put(requestDraft.url, it) + cache.put(pageUrl, it) } } else { - val request = requestDraft.newBuilder() + val request = Request.Builder() + .url(pageUrl) + .get() + .header(CommonHeaders.REFERER, page.referer) .header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8") .cacheControl(CacheUtils.CONTROL_DISABLED) .build() @@ -76,7 +80,7 @@ class PageLoader( "Null response" } body.byteStream().use { - cache.put(requestDraft.url, it) + cache.put(pageUrl, it) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt index d68eaf32c..9221d7bc5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt @@ -9,6 +9,7 @@ import androidx.lifecycle.viewModelScope import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import okhttp3.OkHttpClient +import okhttp3.Request import org.koin.core.component.KoinComponent import org.koin.core.component.get import org.koitharu.kotatsu.base.domain.MangaDataRepository @@ -19,6 +20,7 @@ import org.koitharu.kotatsu.core.exceptions.MangaNotFoundException import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.os.ShortcutsRepository import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode @@ -153,14 +155,16 @@ class ReaderViewModel( it.chapterId == state.chapterId && it.index == state.page }?.toMangaPage() ?: error("Page not found") val repo = page.source.repository - val pageRequest = repo.getPageRequest(page) - val request = pageRequest.newBuilder() + val pageUrl = repo.getPageUrl(page) + val request = Request.Builder() + .url(pageUrl) + .header(CommonHeaders.REFERER, page.referer) .get() .build() val uri = get().newCall(request).await().use { response -> val fileName = URLUtil.guessFileName( - pageRequest.url, + pageUrl, response.contentDisposition, response.mimeType ) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt index 58d23b1ca..2ae446b4f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt @@ -6,16 +6,14 @@ import coil.request.ImageRequest import coil.size.PixelSize import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import kotlinx.coroutines.* -import okhttp3.Headers import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.core.model.RequestDraft -import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.databinding.ItemPageThumbBinding import org.koitharu.kotatsu.local.data.PagesCache import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail import org.koitharu.kotatsu.utils.ext.IgnoreErrors +import org.koitharu.kotatsu.utils.ext.referer fun pageThumbnailAD( coil: ImageLoader, @@ -45,18 +43,14 @@ fun pageThumbnailAD( text = (item.number).toString() } job = scope.launch(Dispatchers.Default + IgnoreErrors) { - val pageRequest = item.page.preview?.let { - RequestDraft(it, Headers.headersOf(CommonHeaders.REFERER, item.page.referer)) - } ?: item.page.url.let { - val pageRequest = item.repository.getPageRequest(item.page) - cache[pageRequest.url]?.toUri()?.toString()?.let { - pageRequest.copy(url = it) - } ?: pageRequest + val url = item.page.preview ?: item.page.url.let { + val pageUrl = item.repository.getPageUrl(item.page) + cache[pageUrl]?.toUri()?.toString() ?: pageUrl } val drawable = coil.execute( ImageRequest.Builder(context) - .data(pageRequest.url) - .headers(pageRequest.headers) + .data(url) + .referer(item.page.referer) .size(thumbSize) .allowRgb565(true) .build() diff --git a/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt b/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt index d20766c5c..2efd9c140 100644 --- a/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt +++ b/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt @@ -82,7 +82,7 @@ class RemoteRepositoryTest(source: MangaSource) : KoinTest { val pages = runBlocking { repo.getPages(details.chapters!!.random()) } Assert.assertFalse(pages.isEmpty()) val page = pages.random() - val fullUrl = runBlocking { repo.getPageRequest(page) } + val fullUrl = runBlocking { repo.getPageUrl(page) } AssertX.assertContentType(fullUrl, "image/*") }