Update dependencies; drop Android 4.x support (#6742)

This commit is contained in:
arkon 2021-04-28 15:38:05 -04:00 committed by GitHub
parent 4c08f48fc7
commit 50bf2a56e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
199 changed files with 792 additions and 2116 deletions

View File

@ -1,6 +1,6 @@
buildscript { buildscript {
ext.kotlin_version = '1.4.10' ext.kotlin_version = '1.4.32'
ext.coroutines_version = '1.3.9' ext.coroutines_version = '1.4.3'
repositories { repositories {
mavenCentral() mavenCentral()
google() google()

View File

@ -1,6 +1,6 @@
object Config { object Config {
const val compileSdk = 29 const val compileSdk = 29
const val minSdk = 16 const val minSdk = 21
const val targetSdk = 29 const val targetSdk = 29
const val buildTools = "29.0.3" const val buildTools = "29.0.3"
} }

View File

@ -1,18 +1,18 @@
// used both in common.gradle and themesources library // used both in common.gradle and themesources library
dependencies { dependencies {
// Lib 1.2, but using specific commit so we don't need to bump up the version // Lib 1.2, but using specific commit so we don't need to bump up the version
compileOnly "com.github.tachiyomiorg:extensions-lib:a596412" compileOnly "com.github.tachiyomiorg:extensions-lib:cc271c3"
// These are provided by the app itself // These are provided by the app itself
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440' compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
compileOnly 'com.squareup.okhttp3:okhttp:3.10.0' compileOnly 'com.squareup.okhttp3:okhttp:4.9.1'
compileOnly 'io.reactivex:rxjava:1.3.6' compileOnly 'io.reactivex:rxjava:1.3.8'
compileOnly 'org.jsoup:jsoup:1.10.2' compileOnly 'org.jsoup:jsoup:1.13.1'
compileOnly 'com.google.code.gson:gson:2.8.2' compileOnly 'com.google.code.gson:gson:2.8.6'
compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0' compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0'
implementation project(":annotations") implementation project(":annotations")
compileOnly project(':duktape-stub') compileOnly project(':duktape-stub')
} }

View File

@ -9,7 +9,7 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m org.gradle.jvmargs=-Xmx3072m
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit

View File

@ -11,8 +11,8 @@ import java.util.concurrent.TimeUnit
* *
* Examples: * Examples:
* *
* httpUrl = Httpurl.parse("api.manga.com"), permits = 5, period = 1, unit = seconds => 5 requests per second to api.manga.com * httpUrl = "api.manga.com".toHttpUrlOrNull(), permits = 5, period = 1, unit = seconds => 5 requests per second to api.manga.com
* httpUrl = Httpurl.parse("imagecdn.manga.com"), permits = 10, period = 2, unit = minutes => 10 requests per 2 minutes to imagecdn.manga.com * httpUrl = "imagecdn.manga.com".toHttpUrlOrNull(), permits = 10, period = 2, unit = minutes => 10 requests per 2 minutes to imagecdn.manga.com
* *
* @param httpUrl {HttpUrl} The url host that this interceptor should handle. Will get url's host by using HttpUrl.host() * @param httpUrl {HttpUrl} The url host that this interceptor should handle. Will get url's host by using HttpUrl.host()
* @param permits {Int} Number of requests allowed within a period of units. * @param permits {Int} Number of requests allowed within a period of units.

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
@ -32,7 +32,7 @@ class Erofus : EroMuse("Erofus", "https://www.erofus.com") {
pageStack.addLast(StackItem("$baseUrl/?search=$query&sort=$currentSortingMode&page=1", SEARCH_RESULTS_OR_BASE)) pageStack.addLast(StackItem("$baseUrl/?search=$query&sort=$currentSortingMode&page=1", SEARCH_RESULTS_OR_BASE))
} else { } else {
val albumFilter = filterList.filterIsInstance<AlbumFilter>().first().selection() val albumFilter = filterList.filterIsInstance<AlbumFilter>().first().selection()
val url = HttpUrl.parse(baseUrl + albumFilter.pathSegments)!!.newBuilder() val url = (baseUrl + albumFilter.pathSegments).toHttpUrl().newBuilder()
.addQueryParameter("sort", currentSortingMode) .addQueryParameter("sort", currentSortingMode)
.addQueryParameter("page", "1") .addQueryParameter("page", "1")
@ -48,7 +48,7 @@ class Erofus : EroMuse("Erofus", "https://www.erofus.com") {
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
return SManga.create().apply { return SManga.create().apply {
with(response.asJsoup()) { with(response.asJsoup()) {
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
thumbnail_url = select("$albumSelector img").firstOrNull()?.imgAttr() thumbnail_url = select("$albumSelector img").firstOrNull()?.imgAttr()
author = when (getAlbumType(url)) { author = when (getAlbumType(url)) {
AUTHOR -> { AUTHOR -> {

View File

@ -8,7 +8,7 @@ class HeroScan : FMReader("HeroScan", "https://heroscan.com", "en") {
.addInterceptor { chain -> .addInterceptor { chain ->
val originalRequest = chain.request() val originalRequest = chain.request()
chain.proceed(originalRequest).let { response -> chain.proceed(originalRequest).let { response ->
if (response.code() == 403 && originalRequest.url().host().contains("b-cdn")) { if (response.code == 403 && originalRequest.url.host.contains("b-cdn")) {
response.close() response.close()
chain.proceed(originalRequest.newBuilder().removeHeader("Referer").addHeader("Referer", "https://isekaiscan.com").build()) chain.proceed(originalRequest.newBuilder().removeHeader("Referer").addHeader("Referer", "https://isekaiscan.com").build())
} else { } else {

View File

@ -24,7 +24,7 @@ class Manhwa18Net : FMReader("Manhwa18.net", "https://manhwa18.net", "en") {
GET("$baseUrl/$requestPath?listType=pagination&page=$page&sort=last_update&sort_type=DESC&ungenre=raw", headers) GET("$baseUrl/$requestPath?listType=pagination&page=$page&sort=last_update&sort_type=DESC&ungenre=raw", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val noRawsUrl = super.searchMangaRequest(page, query, filters).url().newBuilder().addQueryParameter("ungenre", "raw").toString() val noRawsUrl = super.searchMangaRequest(page, query, filters).url.newBuilder().addQueryParameter("ungenre", "raw").toString()
return GET(noRawsUrl, headers) return GET(noRawsUrl, headers)
} }
@ -35,7 +35,7 @@ class Manhwa18Net : FMReader("Manhwa18.net", "https://manhwa18.net", "en") {
class Manhwa18NetRaw : FMReader("Manhwa18.net", "https://manhwa18.net", "ko") { class Manhwa18NetRaw : FMReader("Manhwa18.net", "https://manhwa18.net", "ko") {
override val requestPath = "manga-list-genre-raw.html" override val requestPath = "manga-list-genre-raw.html"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val onlyRawsUrl = super.searchMangaRequest(page, query, filters).url().newBuilder().addQueryParameter("genre", "raw").toString() val onlyRawsUrl = super.searchMangaRequest(page, query, filters).url.newBuilder().addQueryParameter("genre", "raw").toString()
return GET(onlyRawsUrl, headers) return GET(onlyRawsUrl, headers)
} }

View File

@ -5,10 +5,8 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.EditTextPreference
import android.support.v7.preference.PreferenceScreen
import android.widget.Toast import android.widget.Toast
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -49,30 +47,6 @@ class FoolSlideCustomizable : ConfigurableSource, FoolSlide("FoolSlide Customiza
screen.addPreference(baseUrlPref) screen.addPreference(baseUrlPref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val baseUrlPref = EditTextPreference(screen.context).apply {
key = BASE_URL_PREF_TITLE
title = BASE_URL_PREF_TITLE
summary = BASE_URL_PREF_SUMMARY
this.setDefaultValue(DEFAULT_BASEURL)
dialogTitle = BASE_URL_PREF_TITLE
dialogMessage = "Default: $DEFAULT_BASEURL"
setOnPreferenceChangeListener { _, newValue ->
try {
val res = preferences.edit().putString(BASE_URL_PREF, newValue as String).commit()
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
res
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
screen.addPreference(baseUrlPref)
}
/** /**
* Tell the user to include /directory/ in the URL even though we remove it * Tell the user to include /directory/ in the URL even though we remove it
* To increase the chance they input a usable URL * To increase the chance they input a usable URL

View File

@ -43,7 +43,7 @@ class HNIScantradEN : FoolSlide("HNI-Scantrad", "https://hni-scantrad.com", "en"
} }
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
return Regex("""imageArray\[\d+]='(.*)'""").findAll(response.body()!!.string()).toList().mapIndexed { i, mr -> return Regex("""imageArray\[\d+]='(.*)'""").findAll(response.body!!.string()).toList().mapIndexed { i, mr ->
Page(i, "", "$baseUrl$urlModifier/${mr.groupValues[1]}") Page(i, "", "$baseUrl$urlModifier/${mr.groupValues[1]}")
} }
} }

View File

@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -29,7 +29,7 @@ class DoujinHentai : Madara("DoujinHentai", "https://doujinhentai.net", "es", Si
override fun popularMangaNextPageSelector() = "a[rel=next]" override fun popularMangaNextPageSelector() = "a[rel=next]"
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=last&page=$page", headers) override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=last&page=$page", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse(baseUrl)!!.newBuilder() val url = baseUrl.toHttpUrl().newBuilder()
if (query.isNotBlank()) { if (query.isNotBlank()) {
url.addPathSegment("search") url.addPathSegment("search")
url.addQueryParameter("query", query) // query returns results all on one page url.addQueryParameter("query", query) // query returns results all on one page

View File

@ -8,7 +8,7 @@ class Manhuaga : Madara("Manhuaga", "https://manhuaga.com", "en") {
.addInterceptor { chain -> .addInterceptor { chain ->
val originalRequest = chain.request() val originalRequest = chain.request()
chain.proceed(originalRequest).let { response -> chain.proceed(originalRequest).let { response ->
if (response.code() == 403) { if (response.code == 403) {
response.close() response.close()
chain.proceed(originalRequest.newBuilder().removeHeader("Referer").addHeader("Referer", "https://manhuaga.com").build()) chain.proceed(originalRequest.newBuilder().removeHeader("Referer").addHeader("Referer", "https://manhuaga.com").build())
} else { } else {

View File

@ -10,7 +10,7 @@ class Mangakakalots : MangaBox("Mangakakalots (unoriginal)", "https://mangakakal
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup() val document = response.asJsoup()
val mangas = document.select(searchMangaSelector()).map { mangaFromElement(it) } val mangas = document.select(searchMangaSelector()).map { mangaFromElement(it) }
val hasNextPage = !response.request().url().toString() val hasNextPage = !response.request.url.toString()
.contains(document.select(searchMangaNextPageSelector()).attr("href")) .contains(document.select(searchMangaNextPageSelector()).attr("href"))
return MangasPage(mangas, hasNextPage) return MangasPage(mangas, hasNextPage)

View File

@ -25,7 +25,7 @@ class LeitorNet : MangasProject("Leitor.net", "https://leitor.net", "pt-BR") {
* Temporary fix to bypass Cloudflare. * Temporary fix to bypass Cloudflare.
*/ */
override fun pageListRequest(chapter: SChapter): Request { override fun pageListRequest(chapter: SChapter): Request {
val newHeaders = super.pageListRequest(chapter).headers().newBuilder() val newHeaders = super.pageListRequest(chapter).headers.newBuilder()
.set("Referer", "https://mangalivre.net/home") .set("Referer", "https://mangalivre.net/home")
.build() .build()

View File

@ -21,7 +21,7 @@ class MangaLivre : MangasProject("Mangá Livre", "https://mangalivre.net", "pt-B
.build() .build()
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
val originalRequestUrl = super.popularMangaRequest(page).url().toString() val originalRequestUrl = super.popularMangaRequest(page).url.toString()
return GET(originalRequestUrl + DEFAULT_TYPE, sourceHeaders) return GET(originalRequestUrl + DEFAULT_TYPE, sourceHeaders)
} }
@ -30,7 +30,7 @@ class MangaLivre : MangasProject("Mangá Livre", "https://mangalivre.net", "pt-B
return super.searchMangaRequest(page, query, filters) return super.searchMangaRequest(page, query, filters)
} }
val popularRequestUrl = super.popularMangaRequest(page).url().toString() val popularRequestUrl = super.popularMangaRequest(page).url.toString()
val type = filters.filterIsInstance<TypeFilter>() val type = filters.filterIsInstance<TypeFilter>()
.firstOrNull()?.selected?.value ?: DEFAULT_TYPE .firstOrNull()?.selected?.value ?: DEFAULT_TYPE
@ -38,7 +38,7 @@ class MangaLivre : MangasProject("Mangá Livre", "https://mangalivre.net", "pt-B
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
if (response.request().url().pathSegments().contains("search")) { if (response.request.url.pathSegments.contains("search")) {
return super.searchMangaParse(response) return super.searchMangaParse(response)
} }

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -39,7 +39,7 @@ class KomikCast : WPMangaStream("Komik Cast", "https://komikcast.com", "id") {
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = if (query.isNotBlank()) { val url = if (query.isNotBlank()) {
val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() val url = "$baseUrl/page/$page".toHttpUrlOrNull()!!.newBuilder()
val pattern = "\\s+".toRegex() val pattern = "\\s+".toRegex()
val q = query.replace(pattern, "+") val q = query.replace(pattern, "+")
if (query.isNotEmpty()) { if (query.isNotEmpty()) {
@ -49,7 +49,7 @@ class KomikCast : WPMangaStream("Komik Cast", "https://komikcast.com", "id") {
} }
url.toString() url.toString()
} else { } else {
val url = HttpUrl.parse("$baseUrl/daftar-komik/page/$page")!!.newBuilder() val url = "$baseUrl/daftar-komik/page/$page".toHttpUrlOrNull()!!.newBuilder()
var orderBy: String var orderBy: String
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) { when (filter) {

View File

@ -10,7 +10,7 @@ import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -48,7 +48,7 @@ class KomikGO : WPMangaStream("Komik GO", "https://komikgo.com", "id") {
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() val url = "$baseUrl/page/$page".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("post_type", "wp-manga") url.addQueryParameter("post_type", "wp-manga")
val pattern = "\\s+".toRegex() val pattern = "\\s+".toRegex()
val q = query.replace(pattern, "+") val q = query.replace(pattern, "+")

View File

@ -21,7 +21,7 @@ class MangaSwat : WPMangaStream("MangaSwat", "https://mangaswat.com", "ar") {
private class Sucuri : Interceptor { private class Sucuri : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(chain.request()) val response = chain.proceed(chain.request())
if (response.header("x-sucuri-cache").isNullOrEmpty() && response.request().url().toString().contains("//mangaswat.com")) if (response.header("x-sucuri-cache").isNullOrEmpty() && response.request.url.toString().contains("//mangaswat.com"))
throw IOException("Site protected, open webview | موقع محمي ، عرض ويب مفتوح") throw IOException("Site protected, open webview | موقع محمي ، عرض ويب مفتوح")
return response return response
} }

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.multisrc.comicake package eu.kanade.tachiyomi.multisrc.comicake
import android.os.Build import android.os.Build
import eu.kanade.tachiyomi.extensions.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
@ -45,7 +45,7 @@ abstract class ComiCake(
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val res = response.body()!!.string() val res = response.body!!.string()
return getMangasPageFromComicsResponse(res) return getMangasPageFromComicsResponse(res)
} }
@ -97,7 +97,7 @@ abstract class ComiCake(
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val comicJson = JSONObject(response.body()!!.string()) val comicJson = JSONObject(response.body!!.string())
return parseComicJson(comicJson, true) return parseComicJson(comicJson, true)
} }
@ -130,7 +130,7 @@ abstract class ComiCake(
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val res = response.body()!!.string() val res = response.body!!.string()
return getMangasPageFromComicsResponse(res) return getMangasPageFromComicsResponse(res)
} }
@ -139,7 +139,7 @@ abstract class ComiCake(
} }
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val res = response.body()!!.string() val res = response.body!!.string()
return getMangasPageFromComicsResponse(res, true) return getMangasPageFromComicsResponse(res, true)
} }
@ -156,7 +156,7 @@ abstract class ComiCake(
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val chapterJson = JSONObject(response.body()!!.string()) val chapterJson = JSONObject(response.body!!.string())
val results = chapterJson.getJSONArray("results") val results = chapterJson.getJSONArray("results")
val ret = ArrayList<SChapter>() val ret = ArrayList<SChapter>()
for (i in 0 until results.length()) { for (i in 0 until results.length()) {
@ -166,7 +166,7 @@ abstract class ComiCake(
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val webPub = JSONObject(response.body()!!.string()) val webPub = JSONObject(response.body!!.string())
val readingOrder = webPub.getJSONArray("readingOrder") val readingOrder = webPub.getJSONArray("readingOrder")
val ret = ArrayList<Page>() val ret = ArrayList<Page>()
for (i in 0 until readingOrder.length()) { for (i in 0 until readingOrder.length()) {

View File

@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -59,9 +59,9 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
if (url.contains(pageQueryRegex)) { if (url.contains(pageQueryRegex)) {
url.replace(pageQueryRegex, "page=$int") url.replace(pageQueryRegex, "page=$int")
} else { } else {
val httpUrl = HttpUrl.parse(url)!! val httpUrl = url.toHttpUrlOrNull()!!
val builder = if (httpUrl.pathSegments().last().toIntOrNull() is Int) { val builder = if (httpUrl.pathSegments.last().toIntOrNull() is Int) {
httpUrl.newBuilder().removePathSegment(httpUrl.pathSegments().lastIndex) httpUrl.newBuilder().removePathSegment(httpUrl.pathSegments.lastIndex)
} else { } else {
httpUrl.newBuilder() httpUrl.newBuilder()
} }
@ -165,7 +165,7 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
protected fun stackRequest(): Request { protected fun stackRequest(): Request {
stackItem = pageStack.removeLast() stackItem = pageStack.removeLast()
val url = if (stackItem.pageType == AUTHOR && currentSortingMode.isNotEmpty() && !stackItem.url.contains("sort")) { val url = if (stackItem.pageType == AUTHOR && currentSortingMode.isNotEmpty() && !stackItem.url.contains("sort")) {
HttpUrl.parse(stackItem.url)!!.newBuilder().addQueryParameter("sort", currentSortingMode).toString() stackItem.url.toHttpUrlOrNull()!!.newBuilder().addQueryParameter("sort", currentSortingMode).toString()
} else { } else {
stackItem.url stackItem.url
} }
@ -208,14 +208,14 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
currentSortingMode = filterList.filterIsInstance<SortFilter>().first().toQueryValue() currentSortingMode = filterList.filterIsInstance<SortFilter>().first().toQueryValue()
if (query.isNotBlank()) { if (query.isNotBlank()) {
val url = HttpUrl.parse("$baseUrl/search?q=$query")!!.newBuilder().apply { val url = "$baseUrl/search?q=$query".toHttpUrlOrNull()!!.newBuilder().apply {
if (currentSortingMode.isNotEmpty()) addQueryParameter("sort", currentSortingMode) if (currentSortingMode.isNotEmpty()) addQueryParameter("sort", currentSortingMode)
addQueryParameter("page", "1") addQueryParameter("page", "1")
} }
pageStack.addLast(StackItem(url.toString(), SEARCH_RESULTS_OR_BASE)) pageStack.addLast(StackItem(url.toString(), SEARCH_RESULTS_OR_BASE))
} else { } else {
val albumFilter = filterList.filterIsInstance<AlbumFilter>().first().selection() val albumFilter = filterList.filterIsInstance<AlbumFilter>().first().selection()
val url = HttpUrl.parse("$baseUrl/comics/${albumFilter.pathSegments}")!!.newBuilder().apply { val url = "$baseUrl/comics/${albumFilter.pathSegments}".toHttpUrlOrNull()!!.newBuilder().apply {
if (currentSortingMode.isNotEmpty()) addQueryParameter("sort", currentSortingMode) if (currentSortingMode.isNotEmpty()) addQueryParameter("sort", currentSortingMode)
if (albumFilter.pageType != AUTHOR) addQueryParameter("page", "1") if (albumFilter.pageType != AUTHOR) addQueryParameter("page", "1")
} }
@ -236,7 +236,7 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
return SManga.create().apply { return SManga.create().apply {
with(response.asJsoup()) { with(response.asJsoup()) {
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
thumbnail_url = select("$albumSelector img").firstOrNull()?.imgAttr() thumbnail_url = select("$albumSelector img").firstOrNull()?.imgAttr()
author = when (getAlbumType(url)) { author = when (getAlbumType(url)) {
AUTHOR -> { AUTHOR -> {
@ -278,7 +278,7 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
chapters.add( chapters.add(
SChapter.create().apply { SChapter.create().apply {
name = "Chapter" name = "Chapter"
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
} }
) )
} }

View File

@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -62,7 +62,7 @@ abstract class FMReader(
GET("$baseUrl/$requestPath?listType=pagination&page=$page&$popularSort&sort_type=DESC", headers) GET("$baseUrl/$requestPath?listType=pagination&page=$page&$popularSort&sort_type=DESC", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/$requestPath?")!!.newBuilder() val url = "$baseUrl/$requestPath?".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("name", query) .addQueryParameter("name", query)
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->

View File

@ -135,7 +135,7 @@ abstract class FoolSlide(
/** /**
* Transform a GET request into a POST request that automatically authorizes all adult content * Transform a GET request into a POST request that automatically authorizes all adult content
*/ */
private fun allowAdult(request: Request) = allowAdult(request.url().toString()) private fun allowAdult(request: Request) = allowAdult(request.url.toString())
private fun allowAdult(url: String): Request { private fun allowAdult(url: String): Request {
return POST( return POST(

View File

@ -1,5 +1,10 @@
package eu.kanade.tachiyomi.multisrc.luscious package eu.kanade.tachiyomi.multisrc.luscious
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.CheckBoxPreference
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import com.github.salomonbrys.kotson.addProperty import com.github.salomonbrys.kotson.addProperty
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.get import com.github.salomonbrys.kotson.get
@ -9,6 +14,7 @@ import com.google.gson.JsonArray
import com.google.gson.JsonObject import com.google.gson.JsonObject
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
@ -16,23 +22,13 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
import android.app.Application
import android.content.SharedPreferences
import android.net.Uri
import androidx.preference.CheckBoxPreference
import androidx.preference.PreferenceScreen
import androidx.preference.ListPreference
import eu.kanade.tachiyomi.source.ConfigurableSource
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import android.support.v7.preference.CheckBoxPreference as LegacyCheckBoxPreference
import android.support.v7.preference.PreferenceScreen as LegacyPreferenceScreen
import android.support.v7.preference.ListPreference as LegacyListPreference
abstract class Luscious( abstract class Luscious(
override val name: String, override val name: String,
@ -138,7 +134,7 @@ abstract class Luscious(
private fun buildAlbumListRequest(page: Int, filters: FilterList, query: String = ""): Request { private fun buildAlbumListRequest(page: Int, filters: FilterList, query: String = ""): Request {
val input = buildAlbumListRequestInput(page, filters, query) val input = buildAlbumListRequestInput(page, filters, query)
val url = HttpUrl.parse(apiBaseUrl)!!.newBuilder() val url = apiBaseUrl.toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("operationName", "AlbumList") .addQueryParameter("operationName", "AlbumList")
.addQueryParameter("query", ALBUM_LIST_REQUEST_GQL) .addQueryParameter("query", ALBUM_LIST_REQUEST_GQL)
.addQueryParameter("variables", input.toString()) .addQueryParameter("variables", input.toString())
@ -147,7 +143,7 @@ abstract class Luscious(
} }
private fun parseAlbumListResponse(response: Response): MangasPage { private fun parseAlbumListResponse(response: Response): MangasPage {
val data = gson.fromJson<JsonObject>(response.body()!!.string()) val data = gson.fromJson<JsonObject>(response.body!!.string())
with(data["data"]["album"]["list"]) { with(data["data"]["album"]["list"]) {
return MangasPage( return MangasPage(
this["items"].asJsonArray.map { this["items"].asJsonArray.map {
@ -170,7 +166,7 @@ abstract class Luscious(
private fun buildAlbumInfoRequest(id: String): Request { private fun buildAlbumInfoRequest(id: String): Request {
val input = buildAlbumInfoRequestInput(id) val input = buildAlbumInfoRequestInput(id)
val url = HttpUrl.parse(apiBaseUrl)!!.newBuilder() val url = apiBaseUrl.toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("operationName", "AlbumGet") .addQueryParameter("operationName", "AlbumGet")
.addQueryParameter("query", albumInfoQuery) .addQueryParameter("query", albumInfoQuery)
.addQueryParameter("variables", input.toString()) .addQueryParameter("variables", input.toString())
@ -208,12 +204,12 @@ abstract class Luscious(
false -> { false -> {
var nextPage = true var nextPage = true
var page = 2 var page = 2
val id = response.request().url().queryParameter("variables").toString() val id = response.request.url.queryParameter("variables").toString()
.let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray } .let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray }
.let { it.first { f -> f["name"].asString == "album_id" } } .let { it.first { f -> f["name"].asString == "album_id" } }
.let { it["value"].asString } .let { it["value"].asString }
var data = gson.fromJson<JsonObject>(response.body()!!.string()) var data = gson.fromJson<JsonObject>(response.body!!.string())
.let { it["data"]["picture"]["list"].asJsonObject } .let { it["data"]["picture"]["list"].asJsonObject }
while (nextPage) { while (nextPage) {
@ -231,7 +227,7 @@ abstract class Luscious(
} }
if (nextPage) { if (nextPage) {
val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute() val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute()
data = gson.fromJson<JsonObject>(newPage.body()!!.string()) data = gson.fromJson<JsonObject>(newPage.body!!.string())
.let { it["data"]["picture"]["list"].asJsonObject } .let { it["data"]["picture"]["list"].asJsonObject }
} }
page++ page++
@ -272,7 +268,7 @@ abstract class Luscious(
private fun buildAlbumPicturesPageUrl(id: String, page: Int, sortPagesByOption: String): String { private fun buildAlbumPicturesPageUrl(id: String, page: Int, sortPagesByOption: String): String {
val input = buildAlbumPicturesRequestInput(id, page, sortPagesByOption) val input = buildAlbumPicturesRequestInput(id, page, sortPagesByOption)
return HttpUrl.parse(apiBaseUrl)!!.newBuilder() return apiBaseUrl.toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("operationName", "AlbumListOwnPictures") .addQueryParameter("operationName", "AlbumListOwnPictures")
.addQueryParameter("query", ALBUM_PICTURES_REQUEST_GQL) .addQueryParameter("query", ALBUM_PICTURES_REQUEST_GQL)
.addQueryParameter("variables", input.toString()) .addQueryParameter("variables", input.toString())
@ -283,12 +279,12 @@ abstract class Luscious(
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
var nextPage = true var nextPage = true
var page = 2 var page = 2
val id = response.request().url().queryParameter("variables").toString() val id = response.request.url.queryParameter("variables").toString()
.let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray } .let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray }
.let { it.first { f -> f["name"].asString == "album_id" } } .let { it.first { f -> f["name"].asString == "album_id" } }
.let { it["value"].asString } .let { it["value"].asString }
var data = gson.fromJson<JsonObject>(response.body()!!.string()) var data = gson.fromJson<JsonObject>(response.body!!.string())
.let { it["data"]["picture"]["list"].asJsonObject } .let { it["data"]["picture"]["list"].asJsonObject }
while (nextPage) { while (nextPage) {
@ -305,7 +301,7 @@ abstract class Luscious(
} }
if (nextPage) { if (nextPage) {
val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute() val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute()
data = gson.fromJson<JsonObject>(newPage.body()!!.string()) data = gson.fromJson<JsonObject>(newPage.body!!.string())
.let { it["data"]["picture"]["list"].asJsonObject } .let { it["data"]["picture"]["list"].asJsonObject }
} }
page++ page++
@ -341,7 +337,7 @@ abstract class Luscious(
return client.newCall(GET(page.url, headers)) return client.newCall(GET(page.url, headers))
.asObservableSuccess() .asObservableSuccess()
.map { .map {
val data = gson.fromJson<JsonObject>(it.body()!!.string()).let { data -> val data = gson.fromJson<JsonObject>(it.body!!.string()).let { data ->
data["data"]["picture"]["list"].asJsonObject data["data"]["picture"]["list"].asJsonObject
} }
when (getResolutionPref()){ when (getResolutionPref()){
@ -360,7 +356,7 @@ abstract class Luscious(
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val data = gson.fromJson<JsonObject>(response.body()!!.string()) val data = gson.fromJson<JsonObject>(response.body!!.string())
with(data["data"]["album"]["get"]) { with(data["data"]["album"]["get"]) {
val manga = SManga.create() val manga = SManga.create()
manga.url = this["url"].asString manga.url = this["url"].asString
@ -790,37 +786,6 @@ abstract class Luscious(
screen.addPreference(mergeChapterPref) screen.addPreference(mergeChapterPref)
} }
override fun setupPreferenceScreen(screen: LegacyPreferenceScreen) {
val resolutionPref = LegacyListPreference(screen.context).apply {
key = "${RESOLUTION_PREF_KEY}_$lang"
title = RESOLUTION_PREF_TITLE
entries = RESOLUTION_PREF_ENTRIES
entryValues = RESOLUTION_PREF_ENTRY_VALUES
setDefaultValue(RESOLUTION_PREF_DEFAULT_VALUE)
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString("${RESOLUTION_PREF_KEY}_$lang", entry).commit()
}
}
val mergeChapterPref = LegacyCheckBoxPreference(screen.context).apply {
key = "${MERGE_CHAPTER_PREF_KEY}_$lang"
title = MERGE_CHAPTER_PREF_TITLE
summary = MERGE_CHAPTER_PREF_SUMMARY
setDefaultValue(MERGE_CHAPTER_PREF_DEFAULT_VALUE)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", checkValue).commit()
}
}
screen.addPreference(resolutionPref)
screen.addPreference(mergeChapterPref)
}
private fun getMergeChapterPref(): Boolean = preferences.getBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", MERGE_CHAPTER_PREF_DEFAULT_VALUE) private fun getMergeChapterPref(): Boolean = preferences.getBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", MERGE_CHAPTER_PREF_DEFAULT_VALUE)
private fun getResolutionPref(): String? = preferences.getString("${RESOLUTION_PREF_KEY}_$lang", RESOLUTION_PREF_DEFAULT_VALUE) private fun getResolutionPref(): String? = preferences.getString("${RESOLUTION_PREF_KEY}_$lang", RESOLUTION_PREF_DEFAULT_VALUE)
} }

View File

@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
@ -123,9 +123,9 @@ abstract class Madara(
if (!response.isSuccessful) { if (!response.isSuccessful) {
response.close() response.close()
// Error message for exceeding last page // Error message for exceeding last page
if (response.code() == 404) if (response.code == 404)
error("Already on the Last Page!") error("Already on the Last Page!")
else throw Exception("HTTP error ${response.code()}") else throw Exception("HTTP error ${response.code}")
} }
} }
.map { response -> .map { response ->
@ -138,7 +138,7 @@ abstract class Madara(
protected open fun searchPage(page: Int): String = "page/$page/" protected open fun searchPage(page: Int): String = "page/$page/"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/${searchPage(page)}")!!.newBuilder() val url = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("s", query) url.addQueryParameter("s", query)
url.addQueryParameter("post_type", "wp-manga") url.addQueryParameter("post_type", "wp-manga")
filters.forEach { filter -> filters.forEach { filter ->

View File

@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -80,7 +80,7 @@ abstract class MangaBox(
return if (query.isNotBlank() && getAdvancedGenreFilters().isEmpty()) { return if (query.isNotBlank() && getAdvancedGenreFilters().isEmpty()) {
GET("$baseUrl/$simpleQueryPath${normalizeSearchQuery(query)}?page=$page", headers) GET("$baseUrl/$simpleQueryPath${normalizeSearchQuery(query)}?page=$page", headers)
} else { } else {
val url = HttpUrl.parse(baseUrl)!!.newBuilder() val url = baseUrl.toHttpUrlOrNull()!!.newBuilder()
if (getAdvancedGenreFilters().isNotEmpty()) { if (getAdvancedGenreFilters().isNotEmpty()) {
url.addPathSegment("advanced_search") url.addPathSegment("advanced_search")
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())
@ -206,7 +206,8 @@ abstract class MangaBox(
element.select("a").let { element.select("a").let {
url = it.attr("abs:href").substringAfter(baseUrl) // intentionally not using setUrlWithoutDomain url = it.attr("abs:href").substringAfter(baseUrl) // intentionally not using setUrlWithoutDomain
name = it.text() name = it.text()
scanlator = HttpUrl.parse(it.attr("abs:href"))!!.host() // show where chapters are actually from scanlator =
it.attr("abs:href").toHttpUrlOrNull()!!.host // show where chapters are actually from
} }
date_upload = parseChapterDate(element.selectDateFromElement().text(), scanlator!!) ?: 0 date_upload = parseChapterDate(element.selectDateFromElement().text(), scanlator!!) ?: 0
} }

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.multisrc.mangadventure
import android.net.Uri import android.net.Uri
import android.os.Build.VERSION import android.os.Build.VERSION
import eu.kanade.tachiyomi.extensions.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter

View File

@ -9,7 +9,7 @@ import org.json.JSONObject
import java.text.DecimalFormat import java.text.DecimalFormat
/** Returns the body of a response as a `String`. */ /** Returns the body of a response as a `String`. */
fun Response.asString(): String = body()!!.string() fun Response.asString(): String = body!!.string()
/** /**
* Formats the number according to [fmt]. * Formats the number according to [fmt].

View File

@ -16,7 +16,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -64,7 +64,7 @@ abstract class MangasProject(
val popularMangas = result["most_read"].array val popularMangas = result["most_read"].array
.map { popularMangaItemParse(it.obj) } .map { popularMangaItemParse(it.obj) }
val hasNextPage = response.request().url().queryParameter("page")!!.toInt() < 10 val hasNextPage = response.request.url.queryParameter("page")!!.toInt() < 10
return MangasPage(popularMangas, hasNextPage) return MangasPage(popularMangas, hasNextPage)
} }
@ -85,7 +85,7 @@ abstract class MangasProject(
val latestMangas = result["releases"].array val latestMangas = result["releases"].array
.map { latestMangaItemParse(it.obj) } .map { latestMangaItemParse(it.obj) }
val hasNextPage = response.request().url().queryParameter("page")!!.toInt() < 5 val hasNextPage = response.request.url.queryParameter("page")!!.toInt() < 5
return MangasPage(latestMangas, hasNextPage) return MangasPage(latestMangas, hasNextPage)
} }
@ -197,7 +197,7 @@ abstract class MangasProject(
throw Exception(MANGA_REMOVED) throw Exception(MANGA_REMOVED)
} }
val mangaUrl = response.request().url().toString().replace(baseUrl, "") val mangaUrl = response.request.url.toString().replace(baseUrl, "")
val mangaId = mangaUrl.substringAfterLast("/") val mangaId = mangaUrl.substringAfterLast("/")
var page = 1 var page = 1
@ -277,13 +277,13 @@ abstract class MangasProject(
} }
open fun getChapterUrl(response: Response): String { open fun getChapterUrl(response: Response): String {
return response.request().url().toString() return response.request.url.toString()
} }
protected open fun getReaderToken(document: Document): String? { protected open fun getReaderToken(document: Document): String? {
return document.select("script[src*=\"reader.\"]").firstOrNull() return document.select("script[src*=\"reader.\"]").firstOrNull()
?.attr("abs:src") ?.attr("abs:src")
?.let { HttpUrl.parse(it) } ?.let { it.toHttpUrlOrNull() }
?.queryParameter("token") ?.queryParameter("token")
} }
@ -301,10 +301,10 @@ abstract class MangasProject(
private fun Response.asJsonObject(): JsonObject { private fun Response.asJsonObject(): JsonObject {
if (!isSuccessful) { if (!isSuccessful) {
throw Exception("HTTP error ${code()}") throw Exception("HTTP error $code")
} }
return JSON_PARSER.parse(body()!!.string()).obj return JSON_PARSER.parse(body!!.string()).obj
} }
private fun String.toDate(): Long { private fun String.toDate(): Long {

View File

@ -259,7 +259,7 @@ abstract class NepNep(
val indexChapter = json["Chapter"].string val indexChapter = json["Chapter"].string
SChapter.create().apply { SChapter.create().apply {
name = json["ChapterName"].nullString.let { if (it.isNullOrEmpty()) "${json["Type"].string} ${chapterImage(indexChapter, true)}" else it } name = json["ChapterName"].nullString.let { if (it.isNullOrEmpty()) "${json["Type"].string} ${chapterImage(indexChapter, true)}" else it }
url = "/read-online/" + response.request().url().toString().substringAfter("/manga/") + chapterURLEncode(indexChapter) url = "/read-online/" + response.request.url.toString().substringAfter("/manga/") + chapterURLEncode(indexChapter)
date_upload = try { date_upload = try {
json["Date"].nullString?.let { dateFormat.parse("$it +0600")?.time } ?: 0 json["Date"].nullString?.let { dateFormat.parse("$it +0600")?.time } ?: 0
} catch (_: Exception) { } catch (_: Exception) {

View File

@ -112,7 +112,7 @@ abstract class NyaHentai (
listOf( listOf(
SChapter.create().apply { SChapter.create().apply {
name = "Single Chapter" name = "Single Chapter"
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
} }
) )
} }
@ -185,7 +185,7 @@ abstract class NyaHentai (
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
return if (response.request().url().toString().contains("tag?")) { return if (response.request.url.toString().contains("tag?")) {
response.asJsoup().select("table.table tbody tr a:first-of-type").attr("abs:href").let { response.asJsoup().select("table.table tbody tr a:first-of-type").attr("abs:href").let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
tagUrl = it tagUrl = it

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -67,7 +67,7 @@ abstract class Paprika(
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/search?q=$query&page=$page") GET("$baseUrl/search?q=$query&page=$page")
} else { } else {
val url = HttpUrl.parse("$baseUrl/mangas/")!!.newBuilder() val url = "$baseUrl/mangas/".toHttpUrlOrNull()!!.newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
is GenreFilter -> url.addPathSegment(filter.toUriPart()) is GenreFilter -> url.addPathSegment(filter.toUriPart())

View File

@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -36,7 +36,7 @@ abstract class PaprikaAlt(
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/search?s=$query&post_type=manga&page=$page") GET("$baseUrl/search?s=$query&post_type=manga&page=$page")
} else { } else {
val url = HttpUrl.parse("$baseUrl/genres/")!!.newBuilder() val url = "$baseUrl/genres/".toHttpUrlOrNull()!!.newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
is GenreFilter -> url.addPathSegment(filter.toUriPart()) is GenreFilter -> url.addPathSegment(filter.toUriPart())

View File

@ -5,12 +5,17 @@ import eu.kanade.tachiyomi.source.model.Filter.Header
import eu.kanade.tachiyomi.source.model.Filter.Select import eu.kanade.tachiyomi.source.model.Filter.Select
import eu.kanade.tachiyomi.source.model.Filter.Separator import eu.kanade.tachiyomi.source.model.Filter.Separator
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Cookie import okhttp3.Cookie
import okhttp3.CookieJar import okhttp3.CookieJar
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -18,12 +23,8 @@ import org.json.JSONObject
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.MangasPage
import java.util.Locale
import java.util.Calendar import java.util.Calendar
import java.util.Locale
open class Webtoons( open class Webtoons(
override val name: String, override val name: String,
@ -129,7 +130,7 @@ open class Webtoons(
override fun latestUpdatesNextPageSelector(): String? = null override fun latestUpdatesNextPageSelector(): String? = null
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/$langCode/search?keyword=$query")?.newBuilder()!! val url = "$baseUrl/$langCode/search?keyword=$query".toHttpUrlOrNull()?.newBuilder()!!
val uriPart = (filters.find { it is SearchType } as? SearchType)?.toUriPart() ?: "" val uriPart = (filters.find { it is SearchType } as? SearchType)?.toUriPart() ?: ""
url.addQueryParameter("searchType", uriPart) url.addQueryParameter("searchType", uriPart)
@ -232,7 +233,7 @@ open class Webtoons(
val docUrl = docUrlRegex.find(docString)!!.destructured.toList()[0] val docUrl = docUrlRegex.find(docString)!!.destructured.toList()[0]
val motiontoonPath = motiontoonPathRegex.find(docString)!!.destructured.toList()[0] val motiontoonPath = motiontoonPathRegex.find(docString)!!.destructured.toList()[0]
val motiontoonJson = JSONObject(client.newCall(GET(docUrl, headers)).execute().body()!!.string()).getJSONObject("assets").getJSONObject("image") val motiontoonJson = JSONObject(client.newCall(GET(docUrl, headers)).execute().body!!.string()).getJSONObject("assets").getJSONObject("image")
val keys = motiontoonJson.keys().asSequence().toList().filter { it.contains("layer") } val keys = motiontoonJson.keys().asSequence().toList().filter { it.contains("layer") }

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.json.JSONObject import org.json.JSONObject
@ -26,8 +26,8 @@ open class WebtoonsTranslate (
// popularMangaRequest already returns manga sorted by latest update // popularMangaRequest already returns manga sorted by latest update
override val supportsLatest = false override val supportsLatest = false
private val apiBaseUrl = HttpUrl.parse("https://global.apis.naver.com")!! private val apiBaseUrl = "https://global.apis.naver.com".toHttpUrlOrNull()!!
private val mobileBaseUrl = HttpUrl.parse("https://m.webtoons.com")!! private val mobileBaseUrl = "https://m.webtoons.com".toHttpUrlOrNull()!!
private val thumbnailBaseUrl = "https://mwebtoon-phinf.pstatic.net" private val thumbnailBaseUrl = "https://mwebtoon-phinf.pstatic.net"
private val pageListUrlPattern = "/lineWebtoon/ctrans/translatedEpisodeDetail_jsonp.json?titleNo=%s&episodeNo=%d&languageCode=%s&teamVersion=%d" private val pageListUrlPattern = "/lineWebtoon/ctrans/translatedEpisodeDetail_jsonp.json?titleNo=%s&episodeNo=%d&languageCode=%s&teamVersion=%d"
@ -56,11 +56,11 @@ open class WebtoonsTranslate (
override fun popularMangaRequest(page: Int): Request = mangaRequest(page, pageSize) override fun popularMangaRequest(page: Int): Request = mangaRequest(page, pageSize)
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val offset = response.request().url().queryParameter("offset")!!.toInt() val offset = response.request.url.queryParameter("offset")!!.toInt()
var totalCount: Int var totalCount: Int
val mangas = mutableListOf<SManga>() val mangas = mutableListOf<SManga>()
JSONObject(response.body()!!.string()).let { json -> JSONObject(response.body!!.string()).let { json ->
json.getString("code").let { code -> json.getString("code").let { code ->
if (code != "000") throw Exception("Error getting popular manga: error code $code") if (code != "000") throw Exception("Error getting popular manga: error code $code")
} }
@ -118,7 +118,7 @@ open class WebtoonsTranslate (
private fun searchMangaParse(response: Response, query: String): MangasPage { private fun searchMangaParse(response: Response, query: String): MangasPage {
val mangas = mutableListOf<SManga>() val mangas = mutableListOf<SManga>()
JSONObject(response.body()!!.string()).let { json -> JSONObject(response.body!!.string()).let { json ->
json.getString("code").let { code -> json.getString("code").let { code ->
if (code != "000") throw Exception("Error getting manga: error code $code") if (code != "000") throw Exception("Error getting manga: error code $code")
} }
@ -168,7 +168,7 @@ open class WebtoonsTranslate (
override fun pageListParse(document: Document): List<Page> = throw Exception("Not used") override fun pageListParse(document: Document): List<Page> = throw Exception("Not used")
override fun chapterListRequest(manga: SManga): Request { override fun chapterListRequest(manga: SManga): Request {
val titleNo = HttpUrl.parse(manga.url)!! val titleNo = manga.url.toHttpUrlOrNull()!!
.queryParameter("titleNo") .queryParameter("titleNo")
val chapterUrl = apiBaseUrl val chapterUrl = apiBaseUrl
.resolve("/lineWebtoon/ctrans/translatedEpisodes_jsonp.json")!! .resolve("/lineWebtoon/ctrans/translatedEpisodes_jsonp.json")!!
@ -182,7 +182,7 @@ open class WebtoonsTranslate (
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val chapterData = response.body()!!.string() val chapterData = response.body!!.string()
val chapterJson = JSONObject(chapterData) val chapterJson = JSONObject(chapterData)
val responseCode = chapterJson.getString("code") val responseCode = chapterJson.getString("code")
if (responseCode != "000") { if (responseCode != "000") {
@ -217,7 +217,7 @@ open class WebtoonsTranslate (
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val pageJson = JSONObject(response.body()!!.string()) val pageJson = JSONObject(response.body!!.string())
val results = pageJson.getJSONObject("result").getJSONArray("imageInfo") val results = pageJson.getJSONObject("result").getJSONArray("imageInfo")
val ret = ArrayList<Page>() val ret = ArrayList<Page>()
for (i in 0 until results.length()) { for (i in 0 until results.length()) {

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -78,7 +78,7 @@ abstract class WPComics(
return if (filterList.isEmpty()) { return if (filterList.isEmpty()) {
GET("$baseUrl/?s=$query&post_type=comics&page=$page") GET("$baseUrl/?s=$query&post_type=comics&page=$page")
} else { } else {
val url = HttpUrl.parse("$baseUrl/$searchPath")!!.newBuilder() val url = "$baseUrl/$searchPath".toHttpUrlOrNull()!!.newBuilder()
filterList.forEach { filter -> filterList.forEach { filter ->
when (filter) { when (filter) {

View File

@ -1,10 +1,8 @@
package eu.kanade.tachiyomi.multisrc.wpmangastream package eu.kanade.tachiyomi.multisrc.wpmangastream
//import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor // added to override
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
//import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor // added to override
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
@ -15,7 +13,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -67,23 +65,6 @@ abstract class WPMangaStream(
screen.addPreference(thumbsPref) screen.addPreference(thumbsPref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val thumbsPref = ListPreference(screen.context).apply {
key = SHOW_THUMBNAIL_PREF_Title
title = SHOW_THUMBNAIL_PREF_Title
entries = arrayOf("Show high quality", "Show mid quality", "Show low quality")
entryValues = arrayOf("0", "1", "2")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
preferences.edit().putInt(SHOW_THUMBNAIL_PREF, index).commit()
}
}
screen.addPreference(thumbsPref)
}
private fun getShowThumbnail(): Int = preferences.getInt(SHOW_THUMBNAIL_PREF, 0) private fun getShowThumbnail(): Int = preferences.getInt(SHOW_THUMBNAIL_PREF, 0)
//private val rateLimitInterceptor = RateLimitInterceptor(4) //private val rateLimitInterceptor = RateLimitInterceptor(4)
@ -106,7 +87,7 @@ abstract class WPMangaStream(
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/manga/")!!.newBuilder() val url = "$baseUrl/manga/".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("title", query) url.addQueryParameter("title", query)
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())
filters.forEach { filter -> filters.forEach { filter ->

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.json.JSONArray import org.json.JSONArray
@ -70,7 +70,7 @@ open class BatoTo(
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/search?word=$query&page=$page") GET("$baseUrl/search?word=$query&page=$page")
} else { } else {
val url = HttpUrl.parse("$baseUrl/browse")!!.newBuilder() val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())
url.addQueryParameter("langs", siteLang) url.addQueryParameter("langs", siteLang)
filters.forEach { filter -> filters.forEach { filter ->
@ -311,7 +311,7 @@ open class BatoTo(
"https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js", "https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js",
headers headers
) )
).execute().body()!!.string() ).execute().body!!.string()
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")

View File

@ -10,8 +10,8 @@ class BatoToFactory : SourceFactory {
} }
private val languages = listOf( private val languages = listOf(
//commented langueges do currently not exist on Bato.to but haven in the past // commented langueges do currently not exist on Bato.to but haven in the past
Pair("all",""), Pair("all", ""),
Pair("ar", "ar"), Pair("ar", "ar"),
Pair("bg", "bg"), Pair("bg", "bg"),
Pair("cs", "cs"), Pair("cs", "cs"),
@ -28,14 +28,14 @@ private val languages = listOf(
Pair("fil", "fil"), Pair("fil", "fil"),
Pair("fr", "fr"), Pair("fr", "fr"),
Pair("he", "he"), Pair("he", "he"),
//Pair("hi", "hi"), // Pair("hi", "hi"),
Pair("hr", "hr"), Pair("hr", "hr"),
Pair("hu", "hu"), Pair("hu", "hu"),
Pair("id", "id"), Pair("id", "id"),
Pair("it", "it"), Pair("it", "it"),
Pair("ja", "ja"), Pair("ja", "ja"),
Pair("ko", "ko"), Pair("ko", "ko"),
//Pair("ku", "ku"), // Pair("ku", "ku"),
Pair("ml", "ml"), Pair("ml", "ml"),
Pair("mn", "mn"), Pair("mn", "mn"),
Pair("ms", "ms"), Pair("ms", "ms"),
@ -52,7 +52,7 @@ private val languages = listOf(
Pair("tr", "tr"), Pair("tr", "tr"),
Pair("uk", "uk"), Pair("uk", "uk"),
Pair("vi", "vi"), Pair("vi", "vi"),
//Pair("xh", "xh"), // Pair("xh", "xh"),
Pair("zh", "zh"), Pair("zh", "zh"),
Pair("zh-rHK", "zh_hk"), Pair("zh-rHK", "zh_hk"),
Pair("zh-rTW", "zh_tw"), Pair("zh-rTW", "zh_tw"),

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.extension.all.cubari package eu.kanade.tachiyomi.extension.all.cubari
import android.os.Build import android.os.Build
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
@ -40,14 +40,14 @@ open class Cubari(override val lang: String) : HttpSource() {
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> { override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
return client.newBuilder() return client.newBuilder()
.addInterceptor(RemoteStorageUtils.HomeInterceptor()) .addInterceptor(RemoteStorageUtils.HomeInterceptor())
.build()!! .build()
.newCall(latestUpdatesRequest(page)) .newCall(latestUpdatesRequest(page))
.asObservableSuccess() .asObservableSuccess()
.map { response -> latestUpdatesParse(response) } .map { response -> latestUpdatesParse(response) }
} }
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
return parseMangaList(JSONArray(response.body()!!.string()), SortType.UNPINNED) return parseMangaList(JSONArray(response.body!!.string()), SortType.UNPINNED)
} }
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
@ -57,14 +57,14 @@ open class Cubari(override val lang: String) : HttpSource() {
override fun fetchPopularManga(page: Int): Observable<MangasPage> { override fun fetchPopularManga(page: Int): Observable<MangasPage> {
return client.newBuilder() return client.newBuilder()
.addInterceptor(RemoteStorageUtils.HomeInterceptor()) .addInterceptor(RemoteStorageUtils.HomeInterceptor())
.build()!! .build()
.newCall(popularMangaRequest(page)) .newCall(popularMangaRequest(page))
.asObservableSuccess() .asObservableSuccess()
.map { response -> popularMangaParse(response) } .map { response -> popularMangaParse(response) }
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
return parseMangaList(JSONArray(response.body()!!.string()), SortType.PINNED) return parseMangaList(JSONArray(response.body!!.string()), SortType.PINNED)
} }
override fun fetchMangaDetails(manga: SManga): Observable<SManga> { override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
@ -83,7 +83,7 @@ open class Cubari(override val lang: String) : HttpSource() {
} }
private fun mangaDetailsParse(response: Response, manga: SManga): SManga { private fun mangaDetailsParse(response: Response, manga: SManga): SManga {
return parseMangaFromApi(JSONObject(response.body()!!.string()), manga) return parseMangaFromApi(JSONObject(response.body!!.string()), manga)
} }
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
@ -107,7 +107,7 @@ open class Cubari(override val lang: String) : HttpSource() {
// Called after the request // Called after the request
private fun chapterListParse(response: Response, manga: SManga): List<SChapter> { private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
val res = response.body()!!.string() val res = response.body!!.string()
return parseChapterList(res, manga) return parseChapterList(res, manga)
} }
@ -146,7 +146,7 @@ open class Cubari(override val lang: String) : HttpSource() {
} }
private fun directPageListParse(response: Response): List<Page> { private fun directPageListParse(response: Response): List<Page> {
val res = response.body()!!.string() val res = response.body!!.string()
val pages = JSONArray(res) val pages = JSONArray(res)
val pageArray = ArrayList<Page>() val pageArray = ArrayList<Page>()
@ -162,7 +162,7 @@ open class Cubari(override val lang: String) : HttpSource() {
} }
private fun seriesJsonPageListParse(response: Response, chapter: SChapter): List<Page> { private fun seriesJsonPageListParse(response: Response, chapter: SChapter): List<Page> {
val res = response.body()!!.string() val res = response.body!!.string()
val json = JSONObject(res) val json = JSONObject(res)
val groups = json.getJSONObject("groups") val groups = json.getJSONObject("groups")
val groupIter = groups.keys() val groupIter = groups.keys()
@ -210,7 +210,7 @@ open class Cubari(override val lang: String) : HttpSource() {
// Only tag for recently read on search // Only tag for recently read on search
client.newBuilder() client.newBuilder()
.addInterceptor(RemoteStorageUtils.TagInterceptor()) .addInterceptor(RemoteStorageUtils.TagInterceptor())
.build()!! .build()
.newCall(searchMangaRequest(page, trimmedQuery, filters)) .newCall(searchMangaRequest(page, trimmedQuery, filters))
.asObservableSuccess() .asObservableSuccess()
.map { response -> .map { response ->
@ -238,7 +238,7 @@ open class Cubari(override val lang: String) : HttpSource() {
} }
private fun searchMangaParse(response: Response, query: String): MangasPage { private fun searchMangaParse(response: Response, query: String): MangasPage {
return parseSearchList(JSONObject(response.body()!!.string()), query) return parseSearchList(JSONObject(response.body!!.string()), query)
} }
// ------------- Helpers and whatnot --------------- // ------------- Helpers and whatnot ---------------

View File

@ -50,8 +50,8 @@ class RemoteStorageUtils {
var webView: WebView? = null var webView: WebView? = null
val origRequestUrl = request.url().toString() val origRequestUrl = request.url.toString()
val headers = request.headers().toMultimap().mapValues { val headers = request.headers.toMultimap().mapValues {
it.value.getOrNull(0) ?: "" it.value.getOrNull(0) ?: ""
}.toMutableMap() }.toMutableMap()
val jsInterface = JsInterface(latch) val jsInterface = JsInterface(latch)
@ -94,7 +94,7 @@ class RemoteStorageUtils {
return if (transparent) { return if (transparent) {
response response
} else { } else {
response.newBuilder().body(ResponseBody.create(response.body()?.contentType(), jsInterface.payload)).build() response.newBuilder().body(ResponseBody.create(response.body?.contentType(), jsInterface.payload)).build()
} }
} }
} }

View File

@ -32,8 +32,6 @@ import rx.Observable
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.net.URLEncoder import java.net.URLEncoder
import android.support.v7.preference.CheckBoxPreference as LegacyCheckBoxPreference
import android.support.v7.preference.PreferenceScreen as LegacyPreferenceScreen
open class EHentai(override val lang: String, private val ehLang: String) : ConfigurableSource, HttpSource() { open class EHentai(override val lang: String, private val ehLang: String) : ConfigurableSource, HttpSource() {
@ -196,7 +194,7 @@ open class EHentai(override val lang: String, private val ehLang: String) : Conf
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
override fun mangaDetailsParse(response: Response) = with(response.asJsoup()) { override fun mangaDetailsParse(response: Response) = with(response.asJsoup()) {
with(ExGalleryMetadata()) { with(ExGalleryMetadata()) {
url = response.request().url().encodedPath() url = response.request.url.encodedPath
title = select("#gn").text().nullIfBlank()?.trim() title = select("#gn").text().nullIfBlank()?.trim()
altTitle = select("#gj").text().nullIfBlank()?.trim() altTitle = select("#gj").text().nullIfBlank()?.trim()
@ -514,20 +512,5 @@ open class EHentai(override val lang: String, private val ehLang: String) : Conf
screen.addPreference(enforceLanguagePref) screen.addPreference(enforceLanguagePref)
} }
override fun setupPreferenceScreen(screen: LegacyPreferenceScreen) {
val enforceLanguagePref = LegacyCheckBoxPreference(screen.context).apply {
key = "${ENFORCE_LANGUAGE_PREF_KEY}_$lang"
title = ENFORCE_LANGUAGE_PREF_TITLE
summary = ENFORCE_LANGUAGE_PREF_SUMMARY
setDefaultValue(ENFORCE_LANGUAGE_PREF_DEFAULT_VALUE)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean("${ENFORCE_LANGUAGE_PREF_KEY}_$lang", checkValue).commit()
}
}
screen.addPreference(enforceLanguagePref)
}
private fun getEnforceLanguagePref(): Boolean = preferences.getBoolean("${ENFORCE_LANGUAGE_PREF_KEY}_$lang", ENFORCE_LANGUAGE_PREF_DEFAULT_VALUE) private fun getEnforceLanguagePref(): Boolean = preferences.getBoolean("${ENFORCE_LANGUAGE_PREF_KEY}_$lang", ENFORCE_LANGUAGE_PREF_DEFAULT_VALUE)
} }

View File

@ -3,8 +3,6 @@ package eu.kanade.tachiyomi.extension.all.hentaihand
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.EditTextPreference
import android.support.v7.preference.PreferenceScreen
import android.text.InputType import android.text.InputType
import android.widget.Toast import android.widget.Toast
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
@ -26,9 +24,9 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
@ -59,7 +57,7 @@ class HentaiHand(
.build() .build()
private fun parseGenericResponse(response: Response): MangasPage { private fun parseGenericResponse(response: Response): MangasPage {
val data = gson.fromJson<JsonObject>(response.body()!!.string()) val data = gson.fromJson<JsonObject>(response.body!!.string())
return MangasPage( return MangasPage(
data.getAsJsonArray("data").map { data.getAsJsonArray("data").map {
SManga.create().apply { SManga.create().apply {
@ -100,7 +98,7 @@ class HentaiHand(
.asObservableSuccess() .asObservableSuccess()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.map { .map {
val data = gson.fromJson<JsonObject>(it.body()!!.string()) val data = gson.fromJson<JsonObject>(it.body!!.string())
// only the first tag will be used // only the first tag will be used
data.getAsJsonArray("data").firstOrNull()?.let { t -> t["id"].asInt } data.getAsJsonArray("data").firstOrNull()?.let { t -> t["id"].asInt }
}.toBlocking().first() }.toBlocking().first()
@ -108,7 +106,7 @@ class HentaiHand(
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/api/comics")!!.newBuilder() val url = "$baseUrl/api/comics".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
.addQueryParameter("q", query) .addQueryParameter("q", query)
@ -158,7 +156,7 @@ class HentaiHand(
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val data = gson.fromJson<JsonObject>(response.body()!!.string()) val data = gson.fromJson<JsonObject>(response.body!!.string())
return SManga.create().apply { return SManga.create().apply {
artist = tagArrayToString(data.getAsJsonArray("artists")) artist = tagArrayToString(data.getAsJsonArray("artists"))
@ -188,7 +186,7 @@ class HentaiHand(
override fun chapterListRequest(manga: SManga): Request = mangaDetailsApiRequest(manga) override fun chapterListRequest(manga: SManga): Request = mangaDetailsApiRequest(manga)
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val data = gson.fromJson<JsonObject>(response.body()!!.string()) val data = gson.fromJson<JsonObject>(response.body!!.string())
return listOf( return listOf(
SChapter.create().apply { SChapter.create().apply {
url = "/en/comic/${data["slug"].asString}/reader/1" url = "/en/comic/${data["slug"].asString}/reader/1"
@ -207,7 +205,7 @@ class HentaiHand(
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val data = gson.fromJson<JsonObject>(response.body()!!.string()) val data = gson.fromJson<JsonObject>(response.body!!.string())
return data.getAsJsonArray("images").mapIndexed { i, it -> return data.getAsJsonArray("images").mapIndexed { i, it ->
Page(i, "/en/comic/${data["comic"]["slug"].asString}/reader/${it["page"].asInt}", it["source_url"].asString) Page(i, "/en/comic/${data["comic"]["slug"].asString}/reader/${it["page"].asInt}", it["source_url"].asString)
} }
@ -240,14 +238,14 @@ class HentaiHand(
} }
val body = RequestBody.create(MEDIA_TYPE, jsonObject.toString()) val body = RequestBody.create(MEDIA_TYPE, jsonObject.toString())
val response = chain.proceed(POST("$baseUrl/api/login", headers, body)) val response = chain.proceed(POST("$baseUrl/api/login", headers, body))
if (response.code() == 401) { if (response.code == 401) {
throw Exception("Failed to login, check if username and password are correct") throw Exception("Failed to login, check if username and password are correct")
} }
if (response.body() == null) if (response.body == null)
throw Exception("Login response body is empty") throw Exception("Login response body is empty")
try { try {
return JSONObject(response.body()!!.string()) return JSONObject(response.body!!.string())
.getJSONObject("auth") .getJSONObject("auth")
.getString("access_token") .getString("access_token")
} catch (e: JSONException) { } catch (e: JSONException) {
@ -296,32 +294,6 @@ class HentaiHand(
} }
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
screen.addPreference(screen.supportEditTextPreference(USERNAME_TITLE, USERNAME_DEFAULT, username))
screen.addPreference(screen.supportEditTextPreference(PASSWORD_TITLE, PASSWORD_DEFAULT, password))
}
private fun PreferenceScreen.supportEditTextPreference(title: String, default: String, value: String): EditTextPreference {
return EditTextPreference(context).apply {
key = title
this.title = title
summary = value
this.setDefaultValue(default)
dialogTitle = title
setOnPreferenceChangeListener { _, newValue ->
try {
val res = preferences.edit().putString(title, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
res
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
}
private fun getPrefUsername(): String = preferences.getString(USERNAME_TITLE, USERNAME_DEFAULT)!! private fun getPrefUsername(): String = preferences.getString(USERNAME_TITLE, USERNAME_DEFAULT)!!
private fun getPrefPassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!! private fun getPrefPassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!!
@ -387,7 +359,7 @@ class HentaiHand(
companion object { companion object {
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
private val DATE_FORMAT = SimpleDateFormat("yyyy-dd-MM") private val DATE_FORMAT = SimpleDateFormat("yyyy-dd-MM")
private val MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8") private val MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
private const val USERNAME_TITLE = "Username" private const val USERNAME_TITLE = "Username"
private const val USERNAME_DEFAULT = "" private const val USERNAME_DEFAULT = ""
private const val PASSWORD_TITLE = "Password" private const val PASSWORD_TITLE = "Password"

View File

@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.extension.all.hitomi
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.CheckBoxPreference
import android.support.v7.preference.PreferenceScreen
import com.github.salomonbrys.kotson.array import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.get import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.string import com.github.salomonbrys.kotson.string
@ -61,7 +59,7 @@ open class Hitomi(override val lang: String, private val nozomiLang: String) : H
val range = response.header("Content-Range")!! val range = response.header("Content-Range")!!
val total = range.substringAfter('/').toLong() val total = range.substringAfter('/').toLong()
val end = range.substringBefore('/').substringAfter('-').toLong() val end = range.substringBefore('/').substringAfter('-').toLong()
val body = response.body()!! val body = response.body!!
return parseNozomiPage(body.bytes()) return parseNozomiPage(body.bytes())
.map { .map {
MangasPage(it, end < total - 1) MangasPage(it, end < total - 1)
@ -276,7 +274,7 @@ open class Hitomi(override val lang: String, private val nozomiLang: String) : H
private val jsonParser = JsonParser() private val jsonParser = JsonParser()
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val str = response.body()!!.string() val str = response.body!!.string()
val json = jsonParser.parse(str.removePrefix("var galleryinfo = ")) val json = jsonParser.parse(str.removePrefix("var galleryinfo = "))
return json["files"].array.mapIndexed { i, jsonElement -> return json["files"].array.mapIndexed { i, jsonElement ->
val hash = jsonElement["hash"].string val hash = jsonElement["hash"].string
@ -305,7 +303,7 @@ open class Hitomi(override val lang: String, private val nozomiLang: String) : H
override fun imageRequest(page: Page): Request { override fun imageRequest(page: Page): Request {
val request = super.imageRequest(page) val request = super.imageRequest(page)
val hlId = request.url().pathSegments().let { val hlId = request.url.pathSegments.let {
it[it.lastIndex - 1] it[it.lastIndex - 1]
} }
return request.newBuilder() return request.newBuilder()
@ -343,35 +341,6 @@ open class Hitomi(override val lang: String, private val nozomiLang: String) : H
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val webpPref = CheckBoxPreference(screen.context).apply {
key = "${WEBP_PREF_KEY}_$lang"
title = WEBP_PREF_TITLE
summary = WEBP_PREF_SUMMARY
setDefaultValue(WEBP_PREF_DEFAULT_VALUE)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean("${WEBP_PREF_KEY}_$lang", checkValue).commit()
}
}
val coverPref = CheckBoxPreference(screen.context).apply {
key = "${COVER_PREF_KEY}_$lang"
title = COVER_PREF_TITLE
summary = COVER_PREF_SUMMARY
setDefaultValue(COVER_PREF_DEFAULT_VALUE)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean("${COVER_PREF_KEY}_$lang", checkValue).commit()
}
}
screen.addPreference(webpPref)
screen.addPreference(coverPref)
}
override fun setupPreferenceScreen(screen: AndroidXPreferenceScreen) { override fun setupPreferenceScreen(screen: AndroidXPreferenceScreen) {
val webpPref = AndroidXCheckBoxPreference(screen.context).apply { val webpPref = AndroidXCheckBoxPreference(screen.context).apply {
key = "${WEBP_PREF_KEY}_$lang" key = "${WEBP_PREF_KEY}_$lang"

View File

@ -83,7 +83,7 @@ class HitomiNozomi(
return client.newCall(rangedGet(url, offset, offset + length - 1)) return client.newCall(rangedGet(url, offset, offset + length - 1))
.asObservable() .asObservable()
.map { .map {
it.body()?.bytes() ?: ByteArray(0) it.body?.bytes() ?: ByteArray(0)
} }
.onErrorReturn { ByteArray(0) } .onErrorReturn { ByteArray(0) }
.map { inbuf -> .map { inbuf ->
@ -192,7 +192,7 @@ class HitomiNozomi(
return client.newCall(rangedGet(url, address, address + MAX_NODE_SIZE - 1)) return client.newCall(rangedGet(url, address, address + MAX_NODE_SIZE - 1))
.asObservableSuccess() .asObservableSuccess()
.map { .map {
it.body()?.bytes() ?: ByteArray(0) it.body?.bytes() ?: ByteArray(0)
} }
.onErrorReturn { ByteArray(0) } .onErrorReturn { ByteArray(0) }
.map { nodedata -> .map { nodedata ->
@ -215,7 +215,7 @@ class HitomiNozomi(
) )
.asObservableSuccess() .asObservableSuccess()
.map { resp -> .map { resp ->
val body = resp.body()!!.bytes() val body = resp.body!!.bytes()
val cursor = ByteCursor(body) val cursor = ByteCursor(body)
(1..body.size / 4).map { (1..body.size / 4).map {
cursor.nextInt() cursor.nextInt()
@ -251,7 +251,7 @@ class HitomiNozomi(
fun getIndexVersion(httpClient: OkHttpClient, name: String): Observable<Long> { fun getIndexVersion(httpClient: OkHttpClient, name: String): Observable<Long> {
return httpClient.newCall(GET("$LTN_BASE_URL/$name/version?_=${System.currentTimeMillis()}")) return httpClient.newCall(GET("$LTN_BASE_URL/$name/version?_=${System.currentTimeMillis()}"))
.asObservableSuccess() .asObservableSuccess()
.map { it.body()!!.string().toLong() } .map { it.body!!.string().toLong() }
} }
} }
} }

View File

@ -11,11 +11,11 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -72,7 +72,7 @@ class IMHentai(override val lang: String, private val imhLang: String) : ParsedH
private fun toBinary(boolean: Boolean) = if (boolean) "1" else "0" private fun toBinary(boolean: Boolean) = if (boolean) "1" else "0"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("key", query) .addQueryParameter("key", query)
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
.addQueryParameter(getLanguageURIByName(imhLang).uri, toBinary(true)) // main language always enabled .addQueryParameter(getLanguageURIByName(imhLang).uri, toBinary(true)) // main language always enabled
@ -168,7 +168,7 @@ class IMHentai(override val lang: String, private val imhLang: String) : ParsedH
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
return listOf( return listOf(
SChapter.create().apply { SChapter.create().apply {
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
name = "Chapter" name = "Chapter"
chapter_number = 1f chapter_number = 1f
} }
@ -185,7 +185,7 @@ class IMHentai(override val lang: String, private val imhLang: String) : ParsedH
return client.newCall(GET("$baseUrl${chapter.url}")) return client.newCall(GET("$baseUrl${chapter.url}"))
.asObservableSuccess() .asObservableSuccess()
.map { pageLoadMetaParse(it.asJsoup()) } .map { pageLoadMetaParse(it.asJsoup()) }
.map { RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=UTF-8"), it) } .map { it.toRequestBody("application/x-www-form-urlencoded; charset=UTF-8".toMediaTypeOrNull()) }
.concatMap { client.newCall(POST(PAEG_LOAD_URL, pageLoadHeaders, it)).asObservableSuccess() } .concatMap { client.newCall(POST(PAEG_LOAD_URL, pageLoadHeaders, it)).asObservableSuccess() }
.map { pageListParse(it) } .map { pageListParse(it) }
} }

View File

@ -2,14 +2,12 @@ package eu.kanade.tachiyomi.extension.all.komga
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.EditTextPreference
import android.support.v7.preference.PreferenceScreen
import android.text.InputType import android.text.InputType
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.google.gson.Gson import com.google.gson.Gson
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.extension.all.komga.dto.AuthorDto import eu.kanade.tachiyomi.extension.all.komga.dto.AuthorDto
import eu.kanade.tachiyomi.extension.all.komga.dto.BookDto import eu.kanade.tachiyomi.extension.all.komga.dto.BookDto
import eu.kanade.tachiyomi.extension.all.komga.dto.CollectionDto import eu.kanade.tachiyomi.extension.all.komga.dto.CollectionDto
@ -30,7 +28,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Dns import okhttp3.Dns
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -67,7 +65,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
else -> "series" else -> "series"
} }
val url = HttpUrl.parse("$baseUrl/api/v1/$type?search=$query&page=${page - 1}")!!.newBuilder() val url = "$baseUrl/api/v1/$type?search=$query&page=${page - 1}".toHttpUrlOrNull()!!.newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
@ -168,10 +166,10 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
override fun mangaDetailsParse(response: Response): SManga = override fun mangaDetailsParse(response: Response): SManga =
if (response.fromReadList()) { if (response.fromReadList()) {
val readList = gson.fromJson<ReadListDto>(response.body()?.charStream()!!) val readList = gson.fromJson<ReadListDto>(response.body?.charStream()!!)
readList.toSManga() readList.toSManga()
} else { } else {
val series = gson.fromJson<SeriesDto>(response.body()?.charStream()!!) val series = gson.fromJson<SeriesDto>(response.body?.charStream()!!)
series.toSManga() series.toSManga()
} }
@ -179,7 +177,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
GET("${manga.url}/books?unpaged=true&media_status=READY", headers) GET("${manga.url}/books?unpaged=true&media_status=READY", headers)
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val page = gson.fromJson<PageWrapperDto<BookDto>>(response.body()?.charStream()!!).content val page = gson.fromJson<PageWrapperDto<BookDto>>(response.body?.charStream()!!).content
val r = page.map { book -> val r = page.map { book ->
SChapter.create().apply { SChapter.create().apply {
@ -197,9 +195,9 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
GET("${chapter.url}/pages") GET("${chapter.url}/pages")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val pages = gson.fromJson<List<PageDto>>(response.body()?.charStream()!!) val pages = gson.fromJson<List<PageDto>>(response.body?.charStream()!!)
return pages.map { return pages.map {
val url = "${response.request().url()}/${it.number}" + val url = "${response.request.url}/${it.number}" +
if (!supportedImageTypes.contains(it.mediaType)) { if (!supportedImageTypes.contains(it.mediaType)) {
"?convert=png" "?convert=png"
} else { } else {
@ -214,11 +212,11 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
private fun processSeriesPage(response: Response): MangasPage { private fun processSeriesPage(response: Response): MangasPage {
if (response.fromReadList()) { if (response.fromReadList()) {
with(gson.fromJson<PageWrapperDto<ReadListDto>>(response.body()?.charStream()!!)) { with(gson.fromJson<PageWrapperDto<ReadListDto>>(response.body?.charStream()!!)) {
return MangasPage(content.map { it.toSManga() }, !last) return MangasPage(content.map { it.toSManga() }, !last)
} }
} else { } else {
with(gson.fromJson<PageWrapperDto<SeriesDto>>(response.body()?.charStream()!!)) { with(gson.fromJson<PageWrapperDto<SeriesDto>>(response.body?.charStream()!!)) {
return MangasPage(content.map { it.toSManga() }, !last) return MangasPage(content.map { it.toSManga() }, !last)
} }
} }
@ -250,7 +248,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
status = SManga.UNKNOWN status = SManga.UNKNOWN
} }
private fun Response.fromReadList() = request().url().toString().contains("/api/v1/readlists") private fun Response.fromReadList() = request.url.toString().contains("/api/v1/readlists")
private fun parseDate(date: String?): Long = private fun parseDate(date: String?): Long =
if (date == null) if (date == null)
@ -355,10 +353,10 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
override val client: OkHttpClient = override val client: OkHttpClient =
network.client.newBuilder() network.client.newBuilder()
.authenticator { _, response -> .authenticator { _, response ->
if (response.request().header("Authorization") != null) { if (response.request.header("Authorization") != null) {
null // Give up, we've already failed to authenticate. null // Give up, we've already failed to authenticate.
} else { } else {
response.request().newBuilder() response.request.newBuilder()
.addHeader("Authorization", Credentials.basic(username, password)) .addHeader("Authorization", Credentials.basic(username, password))
.build() .build()
} }
@ -399,33 +397,6 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
} }
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
screen.addPreference(screen.supportEditTextPreference(ADDRESS_TITLE, ADDRESS_DEFAULT, baseUrl))
screen.addPreference(screen.supportEditTextPreference(USERNAME_TITLE, USERNAME_DEFAULT, username))
screen.addPreference(screen.supportEditTextPreference(PASSWORD_TITLE, PASSWORD_DEFAULT, password))
}
private fun PreferenceScreen.supportEditTextPreference(title: String, default: String, value: String): EditTextPreference {
return EditTextPreference(context).apply {
key = title
this.title = title
summary = value
this.setDefaultValue(default)
dialogTitle = title
setOnPreferenceChangeListener { _, newValue ->
try {
val res = preferences.edit().putString(title, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
res
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
}
private fun getPrefBaseUrl(): String = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!! private fun getPrefBaseUrl(): String = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!!
private fun getPrefUsername(): String = preferences.getString(USERNAME_TITLE, USERNAME_DEFAULT)!! private fun getPrefUsername(): String = preferences.getString(USERNAME_TITLE, USERNAME_DEFAULT)!!
private fun getPrefPassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!! private fun getPrefPassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!!
@ -440,7 +411,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ response -> { response ->
libraries = try { libraries = try {
gson.fromJson(response.body()?.charStream()!!) gson.fromJson(response.body?.charStream()!!)
} catch (e: Exception) { } catch (e: Exception) {
emptyList() emptyList()
} }
@ -458,7 +429,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ response -> { response ->
collections = try { collections = try {
gson.fromJson<PageWrapperDto<CollectionDto>>(response.body()?.charStream()!!).content gson.fromJson<PageWrapperDto<CollectionDto>>(response.body?.charStream()!!).content
} catch (e: Exception) { } catch (e: Exception) {
emptyList() emptyList()
} }
@ -476,7 +447,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ response -> { response ->
genres = try { genres = try {
gson.fromJson(response.body()?.charStream()!!) gson.fromJson(response.body?.charStream()!!)
} catch (e: Exception) { } catch (e: Exception) {
emptySet() emptySet()
} }
@ -494,7 +465,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ response -> { response ->
tags = try { tags = try {
gson.fromJson(response.body()?.charStream()!!) gson.fromJson(response.body?.charStream()!!)
} catch (e: Exception) { } catch (e: Exception) {
emptySet() emptySet()
} }
@ -512,7 +483,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ response -> { response ->
publishers = try { publishers = try {
gson.fromJson(response.body()?.charStream()!!) gson.fromJson(response.body?.charStream()!!)
} catch (e: Exception) { } catch (e: Exception) {
emptySet() emptySet()
} }
@ -530,7 +501,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ response -> { response ->
authors = try { authors = try {
val list: List<AuthorDto> = gson.fromJson(response.body()?.charStream()!!) val list: List<AuthorDto> = gson.fromJson(response.body?.charStream()!!)
list.groupBy { it.role } list.groupBy { it.role }
} catch (e: Exception) { } catch (e: Exception) {
emptyMap() emptyMap()

View File

@ -11,7 +11,7 @@ ext {
dependencies { dependencies {
implementation 'io.reactivex:rxandroid:1.2.1' implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.3.6' implementation 'io.reactivex:rxjava:1.3.8'
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -3,9 +3,6 @@ package eu.kanade.tachiyomi.extension.all.lanraragi
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import android.support.v7.preference.CheckBoxPreference
import android.support.v7.preference.EditTextPreference
import android.support.v7.preference.PreferenceScreen
import android.util.Base64 import android.util.Base64
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.google.gson.Gson import com.google.gson.Gson
@ -65,7 +62,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
return client.newCall(GET(uri.toString(), headers)) return client.newCall(GET(uri.toString(), headers))
.asObservable().doOnNext { .asObservable().doOnNext {
if (!it.isSuccessful && it.code() == 404) error("Log in with WebView then try again.") if (!it.isSuccessful && it.code == 404) error("Log in with WebView then try again.")
} }
.map { mangaDetailsParse(it).apply { initialized = true } } .map { mangaDetailsParse(it).apply { initialized = true } }
} }
@ -78,7 +75,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val archive = gson.fromJson<Archive>(response.body()!!.string()) val archive = gson.fromJson<Archive>(response.body!!.string())
return archiveToSManga(archive) return archiveToSManga(archive)
} }
@ -91,7 +88,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val archive = gson.fromJson<Archive>(response.body()!!.string()) val archive = gson.fromJson<Archive>(response.body!!.string())
val uri = getApiUriBuilder("/api/archives/${archive.arcid}/extract") val uri = getApiUriBuilder("/api/archives/${archive.arcid}/extract")
// Replicate old behavior and unset "isnew" for the archive. // Replicate old behavior and unset "isnew" for the archive.
@ -124,7 +121,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val archivePage = gson.fromJson<ArchivePage>(response.body()!!.string()) val archivePage = gson.fromJson<ArchivePage>(response.body!!.string())
return archivePage.pages.mapIndexed { index, url -> return archivePage.pages.mapIndexed { index, url ->
val uri = Uri.parse("${baseUrl}${url.trimStart('.')}") val uri = Uri.parse("${baseUrl}${url.trimStart('.')}")
@ -197,7 +194,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val jsonResult = gson.fromJson<ArchiveSearchResult>(response.body()!!.string()) val jsonResult = gson.fromJson<ArchiveSearchResult>(response.body!!.string())
val currentStart = getStart(response) val currentStart = getStart(response)
val archives = arrayListOf<SManga>() val archives = arrayListOf<SManga>()
@ -231,7 +228,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
return ( return (
totalRecords > 0 && totalRecords > 0 &&
getStart(response) == 0 && getStart(response) == 0 &&
response.request().url().querySize() == 1 // ?start= response.request.url.querySize == 1 // ?start=
) )
} }
@ -276,84 +273,6 @@ open class LANraragi : ConfigurableSource, HttpSource() {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val hostnamePref = EditTextPreference(screen.context).apply {
key = "Hostname"
title = "Hostname"
text = baseUrl
summary = baseUrl
dialogTitle = "Hostname"
setOnPreferenceChangeListener { _, newValue ->
var hostname = newValue as String
if (!hostname.startsWith("http://") && !hostname.startsWith("https://")) {
hostname = "http://$hostname"
}
this.apply {
text = hostname
summary = hostname
}
preferences.edit().putString("hostname", hostname).commit()
}
}
val apiKeyPref = EditTextPreference(screen.context).apply {
key = "API Key"
title = "API Key"
text = apiKey
summary = "Required if No-Fun Mode is enabled."
dialogTitle = "API Key"
setOnPreferenceChangeListener { _, newValue ->
val apiKey = newValue as String
this.apply {
text = apiKey
summary = "Required if No-Fun Mode is enabled."
}
preferences.edit().putString("apiKey", newValue).commit()
}
}
val latestNewOnlyPref = CheckBoxPreference(screen.context).apply {
key = "latestNewOnly"
title = "Latest - New Only"
setDefaultValue(true)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean("latestNewOnly", checkValue).commit()
}
}
val latestNamespacePref = EditTextPreference(screen.context).apply {
key = "latestNamespacePref"
title = "Latest - Sort by Namespace"
text = latestNamespacePref
summary = "Sort by the given namespace for Latest, such as date_added."
dialogTitle = "Latest - Sort by Namespace"
setDefaultValue(DEFAULT_SORT_BY_NS)
setOnPreferenceChangeListener { _, newValue ->
val latestNamespacePref = newValue as String
this.apply {
text = latestNamespacePref
}
preferences.edit().putString("latestNamespacePref", newValue).commit()
}
}
screen.addPreference(hostnamePref)
screen.addPreference(apiKeyPref)
screen.addPreference(latestNewOnlyPref)
screen.addPreference(latestNamespacePref)
}
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) { override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
val hostnamePref = androidx.preference.EditTextPreference(screen.context).apply { val hostnamePref = androidx.preference.EditTextPreference(screen.context).apply {
key = "Hostname" key = "Hostname"
@ -457,7 +376,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ {
categories = try { categories = try {
gson.fromJson(it.body()?.charStream()!!) gson.fromJson(it.body?.charStream()!!)
} catch (e: Exception) { } catch (e: Exception) {
emptyList() emptyList()
} }
@ -505,15 +424,15 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
private fun getTopResponse(response: Response): Response { private fun getTopResponse(response: Response): Response {
return if (response.priorResponse() == null) response else getTopResponse(response.priorResponse()!!) return if (response.priorResponse == null) response else getTopResponse(response.priorResponse!!)
} }
private fun getId(response: Response): String { private fun getId(response: Response): String {
return getTopResponse(response).request().url().queryParameter("id").toString() return getTopResponse(response).request.url.queryParameter("id").toString()
} }
private fun getStart(response: Response): Int { private fun getStart(response: Response): Int {
return getTopResponse(response).request().url().queryParameter("start")!!.toInt() return getTopResponse(response).request.url.queryParameter("start")!!.toInt()
} }
private fun getReaderId(url: String): String { private fun getReaderId(url: String): String {

View File

@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.extension.all.mangadex
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import android.util.Log import android.util.Log
import com.github.salomonbrys.kotson.array import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.bool import com.github.salomonbrys.kotson.bool
@ -33,7 +31,7 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -230,7 +228,7 @@ abstract class MangaDex(
val genresToExclude = mutableListOf<String>() val genresToExclude = mutableListOf<String>()
// Do traditional search // Do traditional search
val url = HttpUrl.parse("$baseUrl/?page=search")!!.newBuilder() val url = "$baseUrl/?page=search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("p", page.toString()) .addQueryParameter("p", page.toString())
.addQueryParameter("title", query.replace(WHITESPACE_REGEX, " ")) .addQueryParameter("title", query.replace(WHITESPACE_REGEX, " "))
@ -346,7 +344,7 @@ abstract class MangaDex(
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
return if (response.request().url().toString().contains("/groups/")) { return if (response.request.url.toString().contains("/groups/")) {
response.asJsoup() response.asJsoup()
.select(".table > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(2) > a") .select(".table > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(2) > a")
.firstOrNull()?.attr("abs:href") .firstOrNull()?.attr("abs:href")
@ -428,7 +426,7 @@ abstract class MangaDex(
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val manga = SManga.create() val manga = SManga.create()
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val json = JsonParser().parse(jsonData).asJsonObject["data"] val json = JsonParser().parse(jsonData).asJsonObject["data"]
val mangaJson = json["manga"].asJsonObject val mangaJson = json["manga"].asJsonObject
val chapterJson = json["chapters"].asJsonArray val chapterJson = json["chapters"].asJsonArray
@ -519,7 +517,7 @@ abstract class MangaDex(
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val now = Date().time val now = Date().time
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val json = JsonParser().parse(jsonData).asJsonObject["data"] val json = JsonParser().parse(jsonData).asJsonObject["data"]
val mangaJson = json["manga"].asJsonObject val mangaJson = json["manga"].asJsonObject
@ -615,10 +613,10 @@ abstract class MangaDex(
.asObservable().doOnNext { response -> .asObservable().doOnNext { response ->
if (!response.isSuccessful) { if (!response.isSuccessful) {
response.close() response.close()
if (response.code() == 451) { if (response.code == 451) {
error("Error 451: Log in to view manga; contact MangaDex if error persists.") error("Error 451: Log in to view manga; contact MangaDex if error persists.")
} else { } else {
throw Exception("HTTP error ${response.code()}") throw Exception("HTTP error ${response.code}")
} }
} }
} }
@ -645,7 +643,7 @@ abstract class MangaDex(
override fun pageListParse(document: Document) = throw Exception("Not used") override fun pageListParse(document: Document) = throw Exception("Not used")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val json = JsonParser().parse(jsonData).asJsonObject["data"] val json = JsonParser().parse(jsonData).asJsonObject["data"]
val hash = json["hash"].string val hash = json["hash"].string
@ -653,7 +651,7 @@ abstract class MangaDex(
return json["pages"].asJsonArray.mapIndexed { idx, it -> return json["pages"].asJsonArray.mapIndexed { idx, it ->
val url = "$hash/${it.asString}" val url = "$hash/${it.asString}"
val mdAtHomeMetadataUrl = "$server,${response.request().url()},${Date().time}" val mdAtHomeMetadataUrl = "$server,${response.request.url},${Date().time}"
Page(idx, mdAtHomeMetadataUrl, url) Page(idx, mdAtHomeMetadataUrl, url)
} }
} }
@ -682,7 +680,7 @@ abstract class MangaDex(
} }
val jsonData = val jsonData =
client.newCall(GET(tokenRequestUrl, headers, cacheControl)).execute() client.newCall(GET(tokenRequestUrl, headers, cacheControl)).execute()
.body()!!.string() .body!!.string()
tokenedServer = tokenedServer =
JsonParser().parse(jsonData).asJsonObject["data"]["server"].string JsonParser().parse(jsonData).asJsonObject["data"]["server"].string
} }
@ -766,69 +764,6 @@ abstract class MangaDex(
screen.addPreference(dataSaverPref) screen.addPreference(dataSaverPref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val r18Pref = ListPreference(screen.context).apply {
key = SHOW_R18_PREF_Title
title = SHOW_R18_PREF_Title
title = SHOW_R18_PREF_Title
entries = arrayOf("Show No R18+", "Show All", "Show Only R18+")
entryValues = arrayOf("0", "1", "2")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
preferences.edit().putInt(SHOW_R18_PREF, index).commit()
}
}
val thumbsPref = ListPreference(screen.context).apply {
key = SHOW_THUMBNAIL_PREF_Title
title = SHOW_THUMBNAIL_PREF_Title
entries = arrayOf("Show high quality", "Show low quality")
entryValues = arrayOf("0", "1")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
preferences.edit().putInt(SHOW_THUMBNAIL_PREF, index).commit()
}
}
val serverPref = ListPreference(screen.context).apply {
key = SERVER_PREF_Title
title = SERVER_PREF_Title
entries = SERVER_PREF_ENTRIES
entryValues = SERVER_PREF_ENTRY_VALUES
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(SERVER_PREF, entry).commit()
}
}
val dataSaverPref = ListPreference(screen.context).apply {
key = DATA_SAVER_PREF_Title
title = DATA_SAVER_PREF_Title
entries = arrayOf("Disable", "Enable")
entryValues = arrayOf("0", "1")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
preferences.edit().putInt(DATA_SAVER_PREF, index).commit()
}
}
screen.addPreference(r18Pref)
screen.addPreference(thumbsPref)
screen.addPreference(serverPref)
screen.addPreference(dataSaverPref)
}
private fun getShowR18(): Int = preferences.getInt(SHOW_R18_PREF, 0) private fun getShowR18(): Int = preferences.getInt(SHOW_R18_PREF, 0)
private fun getShowThumbnail(): Int = preferences.getInt(SHOW_THUMBNAIL_PREF, 0) private fun getShowThumbnail(): Int = preferences.getInt(SHOW_THUMBNAIL_PREF, 0)
private fun getServer(): String { private fun getServer(): String {
@ -1068,11 +1003,11 @@ class CoverInterceptor : Interceptor {
val originalRequest = chain.request() val originalRequest = chain.request()
return chain.proceed(chain.request()).let { response -> return chain.proceed(chain.request()).let { response ->
if (response.code() == 404 && originalRequest.url().toString().contains(coverRegex)) { if (response.code == 404 && originalRequest.url.toString().contains(coverRegex)) {
response.close() response.close()
chain.proceed( chain.proceed(
originalRequest.newBuilder().url( originalRequest.newBuilder().url(
originalRequest.url().toString().substringBeforeLast(".") + ".thumb.jpg" originalRequest.url.toString().substringBeforeLast(".") + ".thumb.jpg"
).build() ).build()
) )
} else { } else {
@ -1087,7 +1022,7 @@ class MdRateLimitInterceptor : Interceptor {
private val baseInterceptor = RateLimitInterceptor(2) private val baseInterceptor = RateLimitInterceptor(2)
override fun intercept(chain: Interceptor.Chain): Response = override fun intercept(chain: Interceptor.Chain): Response =
if (chain.request().url().toString().contains(coverRegex)) if (chain.request().url.toString().contains(coverRegex))
chain.proceed(chain.request()) chain.proceed(chain.request())
else else
baseInterceptor.intercept(chain) baseInterceptor.intercept(chain)
@ -1105,7 +1040,7 @@ class MdAtHomeReportInterceptor(
val originalRequest = chain.request() val originalRequest = chain.request()
return chain.proceed(chain.request()).let { response -> return chain.proceed(chain.request()).let { response ->
val url = originalRequest.url().toString() val url = originalRequest.url.toString()
if (url.contains(mdAtHomeUrlRegex)) { if (url.contains(mdAtHomeUrlRegex)) {
val jsonString = gson.toJson( val jsonString = gson.toJson(
mapOf( mapOf(

View File

@ -3,9 +3,6 @@ package eu.kanade.tachiyomi.extension.all.mangaplus
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build import android.os.Build
import android.support.v7.preference.CheckBoxPreference
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import com.google.gson.Gson import com.google.gson.Gson
import com.squareup.duktape.Duktape import com.squareup.duktape.Duktape
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
@ -19,9 +16,9 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -59,7 +56,7 @@ abstract class MangaPlus(
private val protobufJs: String by lazy { private val protobufJs: String by lazy {
val request = GET(PROTOBUFJS_CDN, headers) val request = GET(PROTOBUFJS_CDN, headers)
client.newCall(request).execute().body()!!.string() client.newCall(request).execute().body!!.string()
} }
private val gson: Gson by lazy { Gson() } private val gson: Gson by lazy { Gson() }
@ -274,7 +271,7 @@ abstract class MangaPlus(
.set("Referer", "$baseUrl/viewer/$chapterId") .set("Referer", "$baseUrl/viewer/$chapterId")
.build() .build()
val url = HttpUrl.parse("$API_URL/manga_viewer")!!.newBuilder() val url = "$API_URL/manga_viewer".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("chapter_id", chapterId) .addQueryParameter("chapter_id", chapterId)
.addQueryParameter("split", splitImages) .addQueryParameter("split", splitImages)
.addQueryParameter("img_quality", imageResolution) .addQueryParameter("img_quality", imageResolution)
@ -289,7 +286,7 @@ abstract class MangaPlus(
if (result.success == null) if (result.success == null)
throw Exception(result.error!!.langPopup.body) throw Exception(result.error!!.langPopup.body)
val referer = response.request().header("Referer")!! val referer = response.request.header("Referer")!!
return result.success.mangaViewer!!.pages return result.success.mangaViewer!!.pages
.mapNotNull { it.page } .mapNotNull { it.page }
@ -344,48 +341,16 @@ abstract class MangaPlus(
screen.addPreference(splitPref) screen.addPreference(splitPref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val resolutionPref = ListPreference(screen.context).apply {
key = "${RESOLUTION_PREF_KEY}_$lang"
title = RESOLUTION_PREF_TITLE
entries = RESOLUTION_PREF_ENTRIES
entryValues = RESOLUTION_PREF_ENTRY_VALUES
setDefaultValue(RESOLUTION_PREF_DEFAULT_VALUE)
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString("${RESOLUTION_PREF_KEY}_$lang", entry).commit()
}
}
val splitPref = CheckBoxPreference(screen.context).apply {
key = "${SPLIT_PREF_KEY}_$lang"
title = SPLIT_PREF_TITLE
summary = SPLIT_PREF_SUMMARY
setDefaultValue(SPLIT_PREF_DEFAULT_VALUE)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean("${SPLIT_PREF_KEY}_$lang", checkValue).commit()
}
}
screen.addPreference(resolutionPref)
screen.addPreference(splitPref)
}
private fun imageIntercept(chain: Interceptor.Chain): Response { private fun imageIntercept(chain: Interceptor.Chain): Response {
var request = chain.request() var request = chain.request()
if (request.url().queryParameter("encryptionKey") == null) if (request.url.queryParameter("encryptionKey") == null)
return chain.proceed(request) return chain.proceed(request)
val encryptionKey = request.url().queryParameter("encryptionKey")!! val encryptionKey = request.url.queryParameter("encryptionKey")!!
// Change the url and remove the encryptionKey to avoid detection. // Change the url and remove the encryptionKey to avoid detection.
val newUrl = request.url().newBuilder() val newUrl = request.url.newBuilder()
.removeAllQueryParameters("encryptionKey") .removeAllQueryParameters("encryptionKey")
.build() .build()
request = request.newBuilder() request = request.newBuilder()
@ -395,8 +360,8 @@ abstract class MangaPlus(
val response = chain.proceed(request) val response = chain.proceed(request)
val contentType = response.header("Content-Type", "image/jpeg")!! val contentType = response.header("Content-Type", "image/jpeg")!!
val image = decodeImage(encryptionKey, response.body()!!.bytes()) val image = decodeImage(encryptionKey, response.body!!.bytes())
val body = ResponseBody.create(MediaType.parse(contentType), image) val body = ResponseBody.create(contentType.toMediaTypeOrNull(), image)
return response.newBuilder() return response.newBuilder()
.body(body) .body(body)
@ -427,17 +392,17 @@ abstract class MangaPlus(
val response = chain.proceed(request) val response = chain.proceed(request)
// Check if it is 404 to maintain compatibility when the extension used Weserv. // Check if it is 404 to maintain compatibility when the extension used Weserv.
val isBadCode = (response.code() == 401 || response.code() == 404) val isBadCode = (response.code == 401 || response.code == 404)
if (isBadCode && request.url().toString().contains(TITLE_THUMBNAIL_PATH)) { if (isBadCode && request.url.toString().contains(TITLE_THUMBNAIL_PATH)) {
val titleId = request.url().toString() val titleId = request.url.toString()
.substringBefore("/$TITLE_THUMBNAIL_PATH") .substringBefore("/$TITLE_THUMBNAIL_PATH")
.substringAfterLast("/") .substringAfterLast("/")
.toInt() .toInt()
val title = titleList?.find { it.titleId == titleId } ?: return response val title = titleList?.find { it.titleId == titleId } ?: return response
response.close() response.close()
val thumbnailRequest = GET(title.portraitImageUrl, request.headers()) val thumbnailRequest = GET(title.portraitImageUrl, request.headers)
return chain.proceed(thumbnailRequest) return chain.proceed(thumbnailRequest)
} }
@ -457,13 +422,13 @@ abstract class MangaPlus(
private fun Response.asProto(): MangaPlusResponse { private fun Response.asProto(): MangaPlusResponse {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M)
return ProtoBuf.decodeFromByteArray(MangaPlusSerializer, body()!!.bytes()) return ProtoBuf.decodeFromByteArray(MangaPlusSerializer, body!!.bytes())
// The kotlinx.serialization library eventually always have some issues with // The kotlinx.serialization library eventually always have some issues with
// devices with Android version below Nougat. So, if the device is running Marshmallow // devices with Android version below Nougat. So, if the device is running Marshmallow
// or lower, the deserialization is done using ProtobufJS + Duktape + Gson. // or lower, the deserialization is done using ProtobufJS + Duktape + Gson.
val bytes = body()!!.bytes() val bytes = body!!.bytes()
val messageBytes = "var BYTE_ARR = new Uint8Array([${bytes.joinToString()}]);" val messageBytes = "var BYTE_ARR = new Uint8Array([${bytes.joinToString()}]);"
val res = Duktape.create().use { val res = Duktape.create().use {

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -42,7 +42,7 @@ open class MangaToon(
return GET("$baseUrl/$urllang/genre/new?page=$page0", headers) return GET("$baseUrl/$urllang/genre/new?page=$page0", headers)
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/$urllang/search?word=$query")?.newBuilder() val url = "$baseUrl/$urllang/search?word=$query".toHttpUrlOrNull()?.newBuilder()
return GET(url.toString(), headers) return GET(url.toString(), headers)
} }

View File

@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.extension.all.mango
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.EditTextPreference
import android.support.v7.preference.PreferenceScreen
import android.text.InputType import android.text.InputType
import android.widget.Toast import android.widget.Toast
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
@ -11,7 +9,7 @@ import com.github.salomonbrys.kotson.get
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
@ -44,7 +42,7 @@ class Mango : ConfigurableSource, HttpSource() {
// Our popular manga are just our library of manga // Our popular manga are just our library of manga
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val result = try { val result = try {
gson.fromJson<JsonObject>(response.body()!!.string()) gson.fromJson<JsonObject>(response.body!!.string())
} catch (e: JsonSyntaxException) { } catch (e: JsonSyntaxException) {
apiCookies = "" apiCookies = ""
throw Exception("Login Likely Failed. Try Refreshing.") throw Exception("Login Likely Failed. Try Refreshing.")
@ -120,7 +118,7 @@ class Mango : ConfigurableSource, HttpSource() {
// This will just return the same thing as the main library endpoint // This will just return the same thing as the main library endpoint
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val result = try { val result = try {
gson.fromJson<JsonObject>(response.body()!!.string()) gson.fromJson<JsonObject>(response.body!!.string())
} catch (e: JsonSyntaxException) { } catch (e: JsonSyntaxException) {
apiCookies = "" apiCookies = ""
throw Exception("Login Likely Failed. Try Refreshing.") throw Exception("Login Likely Failed. Try Refreshing.")
@ -138,7 +136,7 @@ class Mango : ConfigurableSource, HttpSource() {
// The chapter url will contain how many pages the chapter contains for our page list endpoint // The chapter url will contain how many pages the chapter contains for our page list endpoint
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val result = try { val result = try {
gson.fromJson<JsonObject>(response.body()!!.string()) gson.fromJson<JsonObject>(response.body!!.string())
} catch (e: JsonSyntaxException) { } catch (e: JsonSyntaxException) {
apiCookies = "" apiCookies = ""
throw Exception("Login Likely Failed. Try Refreshing.") throw Exception("Login Likely Failed. Try Refreshing.")
@ -235,7 +233,7 @@ class Mango : ConfigurableSource, HttpSource() {
.build() .build()
val loginRequest = POST("$baseUrl/login", formHeaders, formBody) val loginRequest = POST("$baseUrl/login", formHeaders, formBody)
val response = chain.proceed(loginRequest) val response = chain.proceed(loginRequest)
if (response.code() != 200 || response.header("Set-Cookie") == null) { if (response.code != 200 || response.header("Set-Cookie") == null) {
throw Exception("Login Failed. Check Address and Credentials") throw Exception("Login Failed. Check Address and Credentials")
} }
// Save the cookies from the response // Save the cookies from the response
@ -276,33 +274,6 @@ class Mango : ConfigurableSource, HttpSource() {
} }
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
screen.addPreference(screen.supportEditTextPreference(ADDRESS_TITLE, ADDRESS_DEFAULT, baseUrl))
screen.addPreference(screen.supportEditTextPreference(USERNAME_TITLE, USERNAME_DEFAULT, username))
screen.addPreference(screen.supportEditTextPreference(PASSWORD_TITLE, PASSWORD_DEFAULT, password))
}
private fun PreferenceScreen.supportEditTextPreference(title: String, default: String, value: String): EditTextPreference {
return EditTextPreference(context).apply {
key = title
this.title = title
summary = value
this.setDefaultValue(default)
dialogTitle = title
setOnPreferenceChangeListener { _, newValue ->
try {
val res = preferences.edit().putString(title, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
apiCookies = ""
res
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
}
// We strip the last slash since we will append it above // We strip the last slash since we will append it above
private fun getPrefBaseUrl(): String { private fun getPrefBaseUrl(): String {
var path = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!! var path = preferences.getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!!

View File

@ -17,7 +17,6 @@ import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager import javax.net.ssl.X509TrustManager
import kotlin.jvm.Throws
/** /**
* This class generates the sources for MMRCMS. * This class generates the sources for MMRCMS.
@ -123,21 +122,21 @@ class Generator {
val request = Request.Builder().url(url) val request = Request.Builder().url(url)
getOkHttpClient().newCall(request.build()).execute().let { response -> getOkHttpClient().newCall(request.build()).execute().let { response ->
// Bypass Cloudflare ("Please wait 5 seconds" page) // Bypass Cloudflare ("Please wait 5 seconds" page)
if (response.code() == 503 && response.header("Server") in serverCheck) { if (response.code == 503 && response.header("Server") in serverCheck) {
var cookie = "${response.header("Set-Cookie")!!.substringBefore(";")}; " var cookie = "${response.header("Set-Cookie")!!.substringBefore(";")}; "
Jsoup.parse(response.body()!!.string()).let { document -> Jsoup.parse(response.body!!.string()).let { document ->
val path = document.select("[id=\"challenge-form\"]").attr("action") val path = document.select("[id=\"challenge-form\"]").attr("action")
val chk = document.select("[name=\"s\"]").attr("value") val chk = document.select("[name=\"s\"]").attr("value")
getOkHttpClient().newCall(Request.Builder().url("$url/$path?s=$chk").build()).execute().let { solved -> getOkHttpClient().newCall(Request.Builder().url("$url/$path?s=$chk").build()).execute().let { solved ->
cookie += solved.header("Set-Cookie")!!.substringBefore(";") cookie += solved.header("Set-Cookie")!!.substringBefore(";")
request.addHeader("Cookie", cookie).build().let { request.addHeader("Cookie", cookie).build().let {
return Jsoup.parse(getOkHttpClient().newCall(it).execute().body()?.string()) return Jsoup.parse(getOkHttpClient().newCall(it).execute().body?.string())
} }
} }
} }
} }
if (response.code() == 200) { if (response.code == 200) {
return Jsoup.parse(response.body()?.string()) return Jsoup.parse(response.body?.string())
} }
} }
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -109,9 +109,9 @@ open class MyMangaReaderCMSSource(
override fun popularMangaParse(response: Response) = internalMangaParse(response) override fun popularMangaParse(response: Response) = internalMangaParse(response)
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
return if (listOf("query", "q").any { it in response.request().url().queryParameterNames() }) { return if (listOf("query", "q").any { it in response.request.url.queryParameterNames }) {
// If a search query was specified, use search instead! // If a search query was specified, use search instead!
val jsonArray = jsonParser.parse(response.body()!!.string()).let { val jsonArray = jsonParser.parse(response.body!!.string()).let {
if (name == "Mangas.pw") it.array else it["suggestions"].array if (name == "Mangas.pw") it.array else it["suggestions"].array
} }
MangasPage( MangasPage(

View File

@ -231,7 +231,7 @@ open class MyReadingManga(override val lang: String, private val siteLang: Strin
// Grabs page containing filters and puts it into cache // Grabs page containing filters and puts it into cache
private fun filterAssist(url: String): String { private fun filterAssist(url: String): String {
val response = client.newCall(GET(url, headers)).execute() val response = client.newCall(GET(url, headers)).execute()
return response.body()!!.string() return response.body!!.string()
} }
// Returns page from cache to reduce calls to website // Returns page from cache to reduce calls to website

View File

@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.extension.all.nhentai
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getArtists import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getArtists
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getGroups import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getGroups
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getNumPages import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getNumPages
@ -22,7 +20,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -83,29 +81,6 @@ open class NHentai(
screen.addPreference(serverPref) screen.addPreference(serverPref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val serverPref = ListPreference(screen.context).apply {
key = TITLE_PREF
title = TITLE_PREF
entries = arrayOf("Full Title", "Short Title")
entryValues = arrayOf("full", "short")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
displayFullTitle = when (newValue) {
"full" -> true
else -> false
}
true
}
}
if (!preferences.contains(TITLE_PREF))
preferences.edit().putString(TITLE_PREF, "full").apply()
screen.addPreference(serverPref)
}
override fun latestUpdatesRequest(page: Int) = GET(if (nhLang.isBlank()) "$baseUrl/?page=$page" else "$baseUrl/language/$nhLang/?page=$page", headers) override fun latestUpdatesRequest(page: Int) = GET(if (nhLang.isBlank()) "$baseUrl/?page=$page" else "$baseUrl/language/$nhLang/?page=$page", headers)
override fun latestUpdatesSelector() = "#content .gallery" override fun latestUpdatesSelector() = "#content .gallery"
@ -161,13 +136,13 @@ open class NHentai(
val isOkayToSort = filterList.findInstance<UploadedFilter>()?.state?.isBlank() ?: true val isOkayToSort = filterList.findInstance<UploadedFilter>()?.state?.isBlank() ?: true
if (favoriteFilter?.state == true) { if (favoriteFilter?.state == true) {
val url = HttpUrl.parse("$baseUrl/favorites")!!.newBuilder() val url = "$baseUrl/favorites".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("q", "$query $advQuery") .addQueryParameter("q", "$query $advQuery")
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
return GET(url.toString(), headers) return GET(url.toString(), headers)
} else { } else {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("q", "$query $nhLangSearch$advQuery") .addQueryParameter("q", "$query $nhLangSearch$advQuery")
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
@ -211,7 +186,7 @@ open class NHentai(
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
if (response.request().url().toString().contains("/login/")) { if (response.request.url.toString().contains("/login/")) {
val document = response.asJsoup() val document = response.asJsoup()
if (document.select(".fa-sign-in").isNotEmpty()) { if (document.select(".fa-sign-in").isNotEmpty()) {
throw Exception("Log in via WebView to view favorites") throw Exception("Log in via WebView to view favorites")
@ -256,7 +231,7 @@ open class NHentai(
name = "Chapter" name = "Chapter"
scanlator = getGroups(document) scanlator = getGroups(document)
date_upload = getTime(document) date_upload = getTime(document)
setUrlWithoutDomain(response.request().url().encodedPath()) setUrlWithoutDomain(response.request.url.encodedPath)
} }
) )
} }

View File

@ -19,7 +19,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
@ -75,7 +75,7 @@ class NineHentai : HttpSource() {
} }
private fun getMangaList(response: Response, page: Int): MangasPage { private fun getMangaList(response: Response, page: Int): MangasPage {
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val jsonObject = JsonParser().parse(jsonData).asJsonObject val jsonObject = JsonParser().parse(jsonData).asJsonObject
val totalPages = jsonObject["total_count"].int val totalPages = jsonObject["total_count"].int
val results = jsonObject["results"].array val results = jsonObject["results"].array
@ -150,7 +150,7 @@ class NineHentai : HttpSource() {
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val jsonObject = JsonParser().parse(jsonData).asJsonObject val jsonObject = JsonParser().parse(jsonData).asJsonObject
val jsonArray = jsonObject.getAsJsonObject("results") val jsonArray = jsonObject.getAsJsonObject("results")
var imageUrl: String var imageUrl: String
@ -168,7 +168,7 @@ class NineHentai : HttpSource() {
"$imageUrl/preview/${totalPages}t.jpg", "$imageUrl/preview/${totalPages}t.jpg",
headersBuilder().build() headersBuilder().build()
) )
).execute().code().let { code -> ).execute().code.let { code ->
if (code == 404) totalPages-- if (code == 404) totalPages--
} }
@ -214,7 +214,7 @@ class NineHentai : HttpSource() {
override fun chapterListParse(response: Response): List<SChapter> = throw Exception("Not Used") override fun chapterListParse(response: Response): List<SChapter> = throw Exception("Not Used")
companion object { companion object {
private val MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8") private val MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
private const val SEARCH_URL = "/api/getBook" private const val SEARCH_URL = "/api/getBook"
private const val MANGA_URL = "/api/getBookByID" private const val MANGA_URL = "/api/getBookByID"
} }

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -113,7 +113,7 @@ open class NineManga(override val name: String, override val baseUrl: String, ov
override fun imageUrlParse(document: Document) = document.select("div.pic_box img.manga_pic").first().attr("src").orEmpty() override fun imageUrlParse(document: Document) = document.select("div.pic_box img.manga_pic").first().attr("src").orEmpty()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search/")!!.newBuilder() val url = "$baseUrl/search/".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("wd", query) url.addQueryParameter("wd", query)
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())

View File

@ -15,7 +15,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -75,7 +75,7 @@ abstract class SimplyHentai(
// Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("query", query) .addQueryParameter("query", query)
.addQueryParameter("language_ids[$searchLang]", searchLang) .addQueryParameter("language_ids[$searchLang]", searchLang)
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
@ -135,7 +135,7 @@ abstract class SimplyHentai(
return listOf( return listOf(
SChapter.create().apply { SChapter.create().apply {
name = "Chapter" name = "Chapter"
url = response.request().url().toString().removeSuffix("/").substringAfterLast("/") url = response.request.url.toString().removeSuffix("/").substringAfterLast("/")
chapter_number = 1f chapter_number = 1f
date_upload = response.asJsoup().select(".stat-container div:contains(Uploaded) div.bold")?.text().let { date_upload = response.asJsoup().select(".stat-container div:contains(Uploaded) div.bold")?.text().let {
@ -158,7 +158,7 @@ abstract class SimplyHentai(
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
gson.fromJson<JsonObject>(response.body()!!.string()).forEach { _, jsonElement -> gson.fromJson<JsonObject>(response.body!!.string()).forEach { _, jsonElement ->
pages.add(Page(pages.size, "", jsonElement["sizes"]["full"].string)) pages.add(Page(pages.size, "", jsonElement["sizes"]["full"].string))
} }

View File

@ -7,9 +7,9 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -46,7 +46,7 @@ class AndromedaScans : ParsedHttpSource() {
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val type = "application/x-www-form-urlencoded; charset=UTF-8" val type = "application/x-www-form-urlencoded; charset=UTF-8"
val body = RequestBody.create(MediaType.parse(type), "action=data_fetch&keyword=$query") val body = "action=data_fetch&keyword=$query".toRequestBody(type.toMediaTypeOrNull())
return POST("$baseUrl/wp-admin/admin-ajax.php", headers, body) return POST("$baseUrl/wp-admin/admin-ajax.php", headers, body)
} }

View File

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.extension.ar.gmanga package eu.kanade.tachiyomi.extension.ar.gmanga
import android.support.v7.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.get import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.nullString import com.github.salomonbrys.kotson.nullString
@ -21,7 +21,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers import okhttp3.Headers
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
@ -55,8 +55,6 @@ class Gmanga : ConfigurableSource, HttpSource() {
override fun setupPreferenceScreen(screen: PreferenceScreen) = preferences.setupPreferenceScreen(screen) override fun setupPreferenceScreen(screen: PreferenceScreen) = preferences.setupPreferenceScreen(screen)
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) = preferences.setupPreferenceScreen(screen)
override fun chapterListRequest(manga: SManga): Request { override fun chapterListRequest(manga: SManga): Request {
val mangaId = manga.url.substringAfterLast("/") val mangaId = manga.url.substringAfterLast("/")
return GET("$baseUrl/api/mangas/$mangaId/releases", headers) return GET("$baseUrl/api/mangas/$mangaId/releases", headers)
@ -128,7 +126,7 @@ class Gmanga : ConfigurableSource, HttpSource() {
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val url = response.request().url().toString() val url = response.request.url.toString()
val data = gson.fromJson<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html()) val data = gson.fromJson<JsonObject>(response.asJsoup().select(".js-react-on-rails-component").html())
val releaseData = data["readerDataAction"]["readerData"]["release"].asJsonObject val releaseData = data["readerDataAction"]["readerData"]["release"].asJsonObject
@ -163,7 +161,7 @@ class Gmanga : ConfigurableSource, HttpSource() {
} }
private fun decryptResponse(response: Response): JsonObject { private fun decryptResponse(response: Response): JsonObject {
val encryptedData = gson.fromJson<JsonObject>(response.body()!!.string())["data"].asString val encryptedData = gson.fromJson<JsonObject>(response.body!!.string())["data"].asString
val decryptedData = decrypt(encryptedData) val decryptedData = decrypt(encryptedData)
return gson.fromJson(decryptedData) return gson.fromJson(decryptedData)
} }
@ -179,6 +177,6 @@ class Gmanga : ConfigurableSource, HttpSource() {
companion object { companion object {
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36" private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36"
private val MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8") private val MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
} }
} }

View File

@ -2,8 +2,8 @@ package eu.kanade.tachiyomi.extension.ar.gmanga
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.ListPreference import androidx.preference.ListPreference
import android.support.v7.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -14,7 +14,6 @@ class GmangaPreferences(id: Long) {
} }
fun setupPreferenceScreen(screen: PreferenceScreen) { fun setupPreferenceScreen(screen: PreferenceScreen) {
STRING_PREFERENCES.forEach { STRING_PREFERENCES.forEach {
val preference = ListPreference(screen.context).apply { val preference = ListPreference(screen.context).apply {
key = it.key key = it.key
@ -31,24 +30,6 @@ class GmangaPreferences(id: Long) {
} }
} }
fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
STRING_PREFERENCES.forEach {
val preference = androidx.preference.ListPreference(screen.context).apply {
key = it.key
title = it.title
entries = it.entries()
entryValues = it.entryValues()
summary = "%s"
}
if (!preferences.contains(it.key))
preferences.edit().putString(it.key, it.default().key).apply()
screen.addPreference(preference)
}
}
fun getString(pref: StringPreference): String { fun getString(pref: StringPreference): String {
return preferences.getString(pref.key, pref.default().key)!! return preferences.getString(pref.key, pref.default().key)!!
} }

View File

@ -9,7 +9,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -90,7 +90,7 @@ class MangaAe : ParsedHttpSource() {
} }
} }
url += "|arrange:minus" url += "|arrange:minus"
return GET(HttpUrl.parse(url)!!.newBuilder().build().toString(), headers) return GET(url.toHttpUrlOrNull()!!.newBuilder().build().toString(), headers)
} }
override fun searchMangaSelector(): String = popularMangaSelector() override fun searchMangaSelector(): String = popularMangaSelector()

View File

@ -8,7 +8,7 @@ import com.github.salomonbrys.kotson.nullString
import com.github.salomonbrys.kotson.string import com.github.salomonbrys.kotson.string
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonObject import com.google.gson.JsonObject
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
@ -18,7 +18,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -44,7 +44,7 @@ class FansubsCat : HttpSource() {
private val apiBaseUrl = "https://api.fansubs.cat" private val apiBaseUrl = "https://api.fansubs.cat"
private fun parseMangaFromJson(response: Response): MangasPage { private fun parseMangaFromJson(response: Response): MangasPage {
val jsonObject = gson.fromJson<JsonObject>(response.body()!!.string()) val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
val mangas = jsonObject["result"].asJsonArray.map { json -> val mangas = jsonObject["result"].asJsonArray.map { json ->
SManga.create().apply { SManga.create().apply {
@ -62,7 +62,7 @@ class FansubsCat : HttpSource() {
} }
private fun parseChapterListFromJson(response: Response): List<SChapter> { private fun parseChapterListFromJson(response: Response): List<SChapter> {
val jsonObject = gson.fromJson<JsonObject>(response.body()!!.string()) val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
return jsonObject["result"].asJsonArray.map { json -> return jsonObject["result"].asJsonArray.map { json ->
SChapter.create().apply { SChapter.create().apply {
@ -76,7 +76,7 @@ class FansubsCat : HttpSource() {
} }
private fun parsePageListFromJson(response: Response): List<Page> { private fun parsePageListFromJson(response: Response): List<Page> {
val jsonObject = gson.fromJson<JsonObject>(response.body()!!.string()) val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
return jsonObject["result"].asJsonArray.mapIndexed { i, it -> return jsonObject["result"].asJsonArray.mapIndexed { i, it ->
Page(i, it["url"].asString, it["url"].asString) Page(i, it["url"].asString, it["url"].asString)
@ -102,7 +102,7 @@ class FansubsCat : HttpSource() {
// Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$apiBaseUrl/manga/search/$page")!!.newBuilder() val url = "$apiBaseUrl/manga/search/$page".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("query", query) .addQueryParameter("query", query)
return GET(url.toString(), headers) return GET(url.toString(), headers)
} }
@ -124,7 +124,7 @@ class FansubsCat : HttpSource() {
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val jsonObject = gson.fromJson<JsonObject>(response.body()!!.string()) val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
return SManga.create().apply { return SManga.create().apply {
url = jsonObject["result"]["slug"].string url = jsonObject["result"]["slug"].string

View File

@ -66,7 +66,7 @@ class MangaTube : ParsedHttpSource() {
// for future reference: if adding filters, advanced search might use a different key // for future reference: if adding filters, advanced search might use a different key
private fun parseMangaFromJson(response: Response, hasNextPage: Boolean): MangasPage { private fun parseMangaFromJson(response: Response, hasNextPage: Boolean): MangasPage {
var titleKey = "manga_title" var titleKey = "manga_title"
val mangas = gson.fromJson<JsonObject>(response.body()!!.string()) val mangas = gson.fromJson<JsonObject>(response.body!!.string())
.let { it["success"] ?: it["suggestions"].also { titleKey = "value" } } .let { it["success"] ?: it["suggestions"].also { titleKey = "value" } }
.asJsonArray .asJsonArray
.map { json -> .map { json ->

View File

@ -8,11 +8,12 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -69,7 +70,7 @@ class Comicastle : ParsedHttpSource() {
// Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/library/search")!!.newBuilder() val url = "$baseUrl/library/search".toHttpUrlOrNull()!!.newBuilder()
var rBody: RequestBody? = null var rBody: RequestBody? = null
(filters.let { if (it.isEmpty()) getFilterList() else filters }) (filters.let { if (it.isEmpty()) getFilterList() else filters })
@ -160,4 +161,5 @@ class Comicastle : ParsedHttpSource() {
private fun getPublisherList() = arrayOf("<Select>", "Action Lab", "Aftershock", "AHOY", "American Mythology", "Aspen", "Avatar Press", "AWA Studios", "Black Mask", "BOOM! Studios", "Dark Horse", "DC", "Death Rattle", "Dynamite", "IDW", "Image", "Magnetic Press", "Marvel", "MAX", "Titan", "Ubiworkshop", "Valiant", "Vault", "Vertigo", "Wildstorm", "Zenescope") private fun getPublisherList() = arrayOf("<Select>", "Action Lab", "Aftershock", "AHOY", "American Mythology", "Aspen", "Avatar Press", "AWA Studios", "Black Mask", "BOOM! Studios", "Dark Horse", "DC", "Death Rattle", "Dynamite", "IDW", "Image", "Magnetic Press", "Marvel", "MAX", "Titan", "Ubiworkshop", "Valiant", "Vault", "Vertigo", "Wildstorm", "Zenescope")
} }
private fun createRequestBody(value: String) = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), "search=" + URLEncoder.encode(value, "UTF-8")) private fun createRequestBody(value: String) =
("search=" + URLEncoder.encode(value, "UTF-8")).toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.extension.en.dilbert package eu.kanade.tachiyomi.extension.en.dilbert
import android.os.Build.VERSION import android.os.Build.VERSION
import eu.kanade.tachiyomi.extension.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
@ -89,7 +89,7 @@ class Dilbert : ParsedHttpSource() {
val res = client.newCall(chapterListRequest(manga, page)).execute() val res = client.newCall(chapterListRequest(manga, page)).execute()
if (!res.isSuccessful) { if (!res.isSuccessful) {
res.close() res.close()
throw Exception("HTTP error ${res.code()}") throw Exception("HTTP error ${res.code}")
} }
return res.asJsoup().also { return res.asJsoup().also {
chapters.addAll(it.select(".comic-item").map(::chapterFromElement)) chapters.addAll(it.select(".comic-item").map(::chapterFromElement))

View File

@ -49,7 +49,7 @@ class Doujins : HttpSource() {
return listOf( return listOf(
SChapter.create().apply { SChapter.create().apply {
name = "Chapter" name = "Chapter"
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
val dateAndPageCountString = response.asJsoup().select(".text-md-right.text-sm-left > .folder-message").text() val dateAndPageCountString = response.asJsoup().select(".text-md-right.text-sm-left > .folder-message").text()
@ -68,7 +68,7 @@ class Doujins : HttpSource() {
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
return MangasPage( return MangasPage(
gson.fromJson<JsonObject>(response.body()!!.string())["folders"].asJsonArray.map { gson.fromJson<JsonObject>(response.body!!.string())["folders"].asJsonArray.map {
SManga.create().apply { SManga.create().apply {
setUrlWithoutDomain(it["link"].asString) setUrlWithoutDomain(it["link"].asString)
title = it["name"].asString title = it["name"].asString
@ -114,7 +114,7 @@ class Doujins : HttpSource() {
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup() val document = response.asJsoup()
val pageUrl = response.request().url().toString() val pageUrl = response.request.url.toString()
return document.select(".doujin").mapIndexed { i, page -> return document.select(".doujin").mapIndexed { i, page ->
Page(i, "$pageUrl${page.attr("data-link")}", page.attr("data-file").replace("amp;", "")) Page(i, "$pageUrl${page.attr("data-link")}", page.attr("data-file").replace("amp;", ""))
} }

View File

@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -74,11 +74,11 @@ class Eggporncomics : ParsedHttpSource() {
if (!response.isSuccessful) { if (!response.isSuccessful) {
// when combining a category filter and comics filter, if there are no results the source // when combining a category filter and comics filter, if there are no results the source
// issues a 404, override that so as not to confuse users // issues a 404, override that so as not to confuse users
if (response.request().url().toString().contains("category-tag") && response.code() == 404) { if (response.request.url.toString().contains("category-tag") && response.code == 404) {
Observable.just(MangasPage(emptyList(), false)) Observable.just(MangasPage(emptyList(), false))
} else { } else {
response.close() response.close()
throw Exception("HTTP error ${response.code()}") throw Exception("HTTP error ${response.code}")
} }
} }
} }
@ -93,7 +93,7 @@ class Eggporncomics : ParsedHttpSource() {
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/search/${query.replace(queryRegex, "-")}?page=$page", headers) GET("$baseUrl/search/${query.replace(queryRegex, "-")}?page=$page", headers)
} else { } else {
val url = HttpUrl.parse(baseUrl)!!.newBuilder() val url = baseUrl.toHttpUrlOrNull()!!.newBuilder()
val filterList = if (filters.isEmpty()) getFilterList() else filters val filterList = if (filters.isEmpty()) getFilterList() else filters
val category = filterList.find { it is CategoryFilter } as UriPartFilter val category = filterList.find { it is CategoryFilter } as UriPartFilter
val comics = filterList.find { it is ComicsFilter } as UriPartFilter val comics = filterList.find { it is ComicsFilter } as UriPartFilter
@ -141,7 +141,7 @@ class Eggporncomics : ParsedHttpSource() {
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
return listOf( return listOf(
SChapter.create().apply { SChapter.create().apply {
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
name = "Chapter" name = "Chapter"
date_upload = response.asJsoup().select("div.info > div.meta li:contains(days ago)").firstOrNull() date_upload = response.asJsoup().select("div.info > div.meta li:contains(days ago)").firstOrNull()
?.let { Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, -(it.text().substringBefore(" ").toIntOrNull() ?: 0)) }.timeInMillis } ?.let { Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, -(it.text().substringBefore(" ").toIntOrNull() ?: 0)) }.timeInMillis }

View File

@ -3,9 +3,7 @@ package eu.kanade.tachiyomi.extension.en.guya
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build import android.os.Build
import android.support.v7.preference.ListPreference import eu.kanade.tachiyomi.BuildConfig
import android.support.v7.preference.PreferenceScreen
import eu.kanade.tachiyomi.extension.BuildConfig
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservable import eu.kanade.tachiyomi.network.asObservable
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
@ -61,7 +59,7 @@ open class Guya : ConfigurableSource, HttpSource() {
// Gets the response object from the request // Gets the response object from the request
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val res = response.body()!!.string() val res = response.body!!.string()
return parseManga(JSONObject(res)) return parseManga(JSONObject(res))
} }
@ -99,7 +97,7 @@ open class Guya : ConfigurableSource, HttpSource() {
} }
private fun mangaDetailsParse(response: Response, manga: SManga): SManga { private fun mangaDetailsParse(response: Response, manga: SManga): SManga {
val res = response.body()!!.string() val res = response.body!!.string()
return parseMangaFromJson(JSONObject(res), "", manga.title) return parseMangaFromJson(JSONObject(res), "", manga.title)
} }
@ -133,7 +131,7 @@ open class Guya : ConfigurableSource, HttpSource() {
// Called after the request // Called after the request
private fun chapterListParse(response: Response, manga: SManga): List<SChapter> { private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
val res = response.body()!!.string() val res = response.body!!.string()
return parseChapterList(res, manga) return parseChapterList(res, manga)
} }
@ -167,7 +165,7 @@ open class Guya : ConfigurableSource, HttpSource() {
} }
private fun pageListParse(response: Response, chapter: SChapter): List<Page> { private fun pageListParse(response: Response, chapter: SChapter): List<Page> {
val res = response.body()!!.string() val res = response.body!!.string()
val json = JSONObject(res) val json = JSONObject(res)
val chapterNum = chapter.name.split(" - ")[0] val chapterNum = chapter.name.split(" - ")[0]
@ -225,7 +223,7 @@ open class Guya : ConfigurableSource, HttpSource() {
} }
private fun searchMangaParseWithSlug(response: Response, slug: String): MangasPage { private fun searchMangaParseWithSlug(response: Response, slug: String): MangasPage {
val results = JSONObject(response.body()!!.string()) val results = JSONObject(response.body!!.string())
val mangaIter = results.keys() val mangaIter = results.keys()
val truncatedJSON = JSONObject() val truncatedJSON = JSONObject()
@ -242,7 +240,7 @@ open class Guya : ConfigurableSource, HttpSource() {
} }
private fun searchMangaParse(response: Response, query: String): MangasPage { private fun searchMangaParse(response: Response, query: String): MangasPage {
val res = response.body()!!.string() val res = response.body!!.string()
val json = JSONObject(res) val json = JSONObject(res)
val truncatedJSON = JSONObject() val truncatedJSON = JSONObject()
@ -284,32 +282,6 @@ open class Guya : ConfigurableSource, HttpSource() {
screen.addPreference(preference) screen.addPreference(preference)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val preference = ListPreference(screen.context).apply {
key = "preferred_scanlator"
title = "Preferred scanlator"
entries = arrayOf<String>()
entryValues = arrayOf<String>()
for (key in scanlators.keys()) {
entries += scanlators.getValueFromKey(key)
entryValues += key
}
summary = "Current: %s\n\n" +
"This setting sets the scanlation group to prioritize " +
"on chapter refresh/update. It will get the next available if " +
"your preferred scanlator isn't an option (yet)."
this.setDefaultValue("1")
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue.toString()
preferences.edit().putString(scanlatorPreference, selected).commit()
}
}
screen.addPreference(preference)
}
// ---------------- Proxy methods ------------------ // ---------------- Proxy methods ------------------
private fun proxySeriesRequest(query: String, api: Boolean = true): Request { private fun proxySeriesRequest(query: String, api: Boolean = true): Request {
@ -347,7 +319,7 @@ open class Guya : ConfigurableSource, HttpSource() {
} }
private fun proxyPageListParse(response: Response, chapter: SChapter): List<Page> { private fun proxyPageListParse(response: Response, chapter: SChapter): List<Page> {
val res = response.body()!!.string() val res = response.body!!.string()
val pages = if (chapter.url.removePrefix(PROXY_PREFIX).startsWith(NESTED_PROXY_API_PREFIX)) { val pages = if (chapter.url.removePrefix(PROXY_PREFIX).startsWith(NESTED_PROXY_API_PREFIX)) {
JSONArray(res) JSONArray(res)
} else { } else {
@ -378,7 +350,7 @@ open class Guya : ConfigurableSource, HttpSource() {
private fun proxySearchMangaParse(response: Response, query: String): MangasPage { private fun proxySearchMangaParse(response: Response, query: String): MangasPage {
return MangasPage( return MangasPage(
arrayListOf(parseMangaFromJson(JSONObject(response.body()!!.string()), query)), arrayListOf(parseMangaFromJson(JSONObject(response.body!!.string()), query)),
false false
) )
} }
@ -572,7 +544,7 @@ open class Guya : ConfigurableSource, HttpSource() {
if (!response.isSuccessful) { if (!response.isSuccessful) {
retryCount++ retryCount++
} else { } else {
val json = JSONObject(response.body()!!.string()) val json = JSONObject(response.body!!.string())
val iter = json.keys() val iter = json.keys()
while (iter.hasNext()) { while (iter.hasNext()) {
val scanId = iter.next() val scanId = iter.next()

View File

@ -42,7 +42,7 @@ class HBrowse : ParsedHttpSource() {
.addInterceptor { chain -> .addInterceptor { chain ->
val originalRequest = chain.request() val originalRequest = chain.request()
when { when {
originalRequest.url().toString() == searchUrl -> { originalRequest.url.toString() == searchUrl -> {
phpSessId = searchClient.newCall(originalRequest).execute() phpSessId = searchClient.newCall(originalRequest).execute()
.headers("Set-Cookie") .headers("Set-Cookie")
.firstOrNull { it.contains("PHPSESSID") } .firstOrNull { it.contains("PHPSESSID") }
@ -53,11 +53,11 @@ class HBrowse : ParsedHttpSource() {
val newHeaders = headersBuilder() val newHeaders = headersBuilder()
.add("Cookie", phpSessId) .add("Cookie", phpSessId)
val contentLength = originalRequest.body()!!.contentLength() val contentLength = originalRequest.body!!.contentLength()
searchClient.newCall(GET("$baseUrl/${if (contentLength > 8000) "result" else "search"}/1", newHeaders.build())).execute() searchClient.newCall(GET("$baseUrl/${if (contentLength > 8000) "result" else "search"}/1", newHeaders.build())).execute()
} }
originalRequest.url().toString().contains(nextSearchPageUrlRegex) -> { originalRequest.url.toString().contains(nextSearchPageUrlRegex) -> {
searchClient.newCall(originalRequest).execute() searchClient.newCall(originalRequest).execute()
} }
else -> chain.proceed(originalRequest) else -> chain.proceed(originalRequest)

View File

@ -19,7 +19,6 @@ import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
import java.lang.UnsupportedOperationException
import java.util.Calendar import java.util.Calendar
import java.util.regex.Pattern import java.util.regex.Pattern
@ -248,7 +247,7 @@ class Hentai2Read : ParsedHttpSource() {
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
val m = pagesUrlPattern.matcher(response.body()!!.string()) val m = pagesUrlPattern.matcher(response.body!!.string())
var i = 0 var i = 0
while (m.find()) { while (m.find()) {
m.group(1)?.split(",")?.forEach { m.group(1)?.split(",")?.forEach {

View File

@ -113,7 +113,7 @@ class HentaiFox : ParsedHttpSource() {
SChapter.create().apply { SChapter.create().apply {
name = "Chapter" name = "Chapter"
// page path with a marker at the end // page path with a marker at the end
url = "${response.request().url().toString().replace("/gallery/", "/g/")}#" url = "${response.request.url.toString().replace("/gallery/", "/g/")}#"
// number of pages // number of pages
url += response.asJsoup().select("[id=load_pages]").attr("value") url += response.asJsoup().select("[id=load_pages]").attr("value")
} }

View File

@ -103,7 +103,7 @@ class Hiveworks : ParsedHttpSource() {
override fun searchMangaSelector() = popularMangaSelector() + ", div.originalsblock" override fun searchMangaSelector() = popularMangaSelector() + ", div.originalsblock"
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val url = response.request().url().toString() val url = response.request.url.toString()
val document = response.asJsoup() val document = response.asJsoup()
val selectManga = document.select(searchMangaSelector()) val selectManga = document.select(searchMangaSelector())
@ -195,7 +195,7 @@ class Hiveworks : ParsedHttpSource() {
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val url = response.request().url().toString() val url = response.request.url.toString()
val document = response.asJsoup() val document = response.asJsoup()
val baseUrl = document.select("div script").html().substringAfter("href='").substringBefore("'") val baseUrl = document.select("div script").html().substringAfter("href='").substringBefore("'")
val elements = document.select(chapterListSelector()) val elements = document.select(chapterListSelector())
@ -227,7 +227,7 @@ class Hiveworks : ParsedHttpSource() {
override fun pageListRequest(chapter: SChapter) = GET(chapter.url, headers) override fun pageListRequest(chapter: SChapter) = GET(chapter.url, headers)
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val url = response.request().url().toString() val url = response.request.url.toString()
val document = response.asJsoup() val document = response.asJsoup()
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
@ -430,9 +430,9 @@ class Hiveworks : ParsedHttpSource() {
return asObservable().doOnNext { response -> return asObservable().doOnNext { response ->
if (!response.isSuccessful) { if (!response.isSuccessful) {
response.close() response.close()
when (response.code()) { when (response.code) {
404 -> throw Exception("This comic has a unsupported chapter list") 404 -> throw Exception("This comic has a unsupported chapter list")
else -> throw Exception("HiveWorks Comics HTTP Error ${response.code()}") else -> throw Exception("HiveWorks Comics HTTP Error ${response.code}")
} }
} }
} }

View File

@ -34,7 +34,7 @@ class Honkaiimpact : ParsedHttpSource() {
.readTimeout(1, TimeUnit.MINUTES) .readTimeout(1, TimeUnit.MINUTES)
.retryOnConnectionFailure(true) .retryOnConnectionFailure(true)
.followRedirects(true) .followRedirects(true)
.build()!! .build()
// Popular // Popular
override fun popularMangaSelector() = "a[href*=book]" override fun popularMangaSelector() = "a[href*=book]"
@ -80,7 +80,7 @@ class Honkaiimpact : ParsedHttpSource() {
override fun chapterFromElement(element: Element) = throw Exception("Not Used") override fun chapterFromElement(element: Element) = throw Exception("Not Used")
override fun chapterListRequest(manga: SManga) = GET(baseUrl + manga.url + "/get_chapter", headers) override fun chapterListRequest(manga: SManga) = GET(baseUrl + manga.url + "/get_chapter", headers)
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val jsondata = response.body()!!.string() val jsondata = response.body!!.string()
val json = JsonParser().parse(jsondata).asJsonArray val json = JsonParser().parse(jsondata).asJsonArray
val chapters = mutableListOf<SChapter>() val chapters = mutableListOf<SChapter>()
json.forEach { json.forEach {

View File

@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.extension.en.madokami
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.EditTextPreference
import android.support.v7.preference.PreferenceScreen
import android.text.InputType import android.text.InputType
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.google.gson.Gson import com.google.gson.Gson
@ -17,6 +15,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -52,7 +51,7 @@ class Madokami : ConfigurableSource, ParsedHttpSource() {
override val client: OkHttpClient = super.client.newBuilder().addInterceptor { chain -> override val client: OkHttpClient = super.client.newBuilder().addInterceptor { chain ->
val response = chain.proceed(chain.request()) val response = chain.proceed(chain.request())
if (response.code() == 401) throw IOException("You are currently logged out.\nGo to Extensions > Details to input your credentials.") if (response.code == 401) throw IOException("You are currently logged out.\nGo to Extensions > Details to input your credentials.")
response response
}.build() }.build()
@ -83,14 +82,14 @@ class Madokami : ConfigurableSource, ParsedHttpSource() {
override fun searchMangaNextPageSelector(): String? = null override fun searchMangaNextPageSelector(): String? = null
override fun mangaDetailsRequest(manga: SManga): Request { override fun mangaDetailsRequest(manga: SManga): Request {
val url = HttpUrl.parse(baseUrl + manga.url)!! val url = (baseUrl + manga.url).toHttpUrlOrNull()!!
if (url.pathSize() > 5 && url.pathSegments()[0] == "Manga" && url.pathSegments()[1].length == 1) { if (url.pathSize > 5 && url.pathSegments[0] == "Manga" && url.pathSegments[1].length == 1) {
return authenticate(GET(url.newBuilder().removePathSegment(5).build().url().toExternalForm(), headers)) return authenticate(GET(url.newBuilder().removePathSegment(5).build().toUrl().toExternalForm(), headers))
} }
if (url.pathSize() > 2 && url.pathSegments()[0] == "Raws") { if (url.pathSize > 2 && url.pathSegments[0] == "Raws") {
return authenticate(GET(url.newBuilder().removePathSegment(2).build().url().toExternalForm(), headers)) return authenticate(GET(url.newBuilder().removePathSegment(2).build().toUrl().toExternalForm(), headers))
} }
return authenticate(GET(url.url().toExternalForm(), headers)) return authenticate(GET(url.toUrl().toExternalForm(), headers))
} }
/** /**
@ -164,7 +163,8 @@ class Madokami : ConfigurableSource, ParsedHttpSource() {
.addPathSegments("reader/image") .addPathSegments("reader/image")
.addEncodedQueryParameter("path", URLEncoder.encode(path, "UTF-8")) .addEncodedQueryParameter("path", URLEncoder.encode(path, "UTF-8"))
.addEncodedQueryParameter("file", URLEncoder.encode(file.asString, "UTF-8")) .addEncodedQueryParameter("file", URLEncoder.encode(file.asString, "UTF-8"))
.build().url() .build()
.toUrl()
pages.add(Page(index, url.toExternalForm(), url.toExternalForm())) pages.add(Page(index, url.toExternalForm(), url.toExternalForm()))
} }
return pages return pages
@ -204,26 +204,4 @@ class Madokami : ConfigurableSource, ParsedHttpSource() {
screen.addPreference(username) screen.addPreference(username)
screen.addPreference(password) screen.addPreference(password)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val username = EditTextPreference(screen.context).apply {
key = "username"
title = "Username"
setOnPreferenceChangeListener { _, newValue ->
preferences.edit().putString(key, newValue as String).commit()
}
}
val password = EditTextPreference(screen.context).apply {
key = "password"
title = "Password"
setOnPreferenceChangeListener { _, newValue ->
preferences.edit().putString(key, newValue as String).commit()
}
}
screen.addPreference(username)
screen.addPreference(password)
}
} }

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -67,7 +67,7 @@ class manga1s : ParsedHttpSource() {
// Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("text", query) .addQueryParameter("text", query)
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {

View File

@ -37,8 +37,8 @@ class Mangadog : HttpSource() {
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
// val page = response.request().url().queryParameterValues("page").toString().toInt() // val page = response.request.url.queryParameterValues("page").toString().toInt()
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val results = JsonParser().parse(jsonData) val results = JsonParser().parse(jsonData)
val data = results["data"]["data"] val data = results["data"]["data"]
val mangas = mutableListOf<SManga>() val mangas = mutableListOf<SManga>()
@ -61,7 +61,7 @@ class Mangadog : HttpSource() {
} }
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val results = JsonParser().parse(jsonData) val results = JsonParser().parse(jsonData)
val data = results["data"] val data = results["data"]
val mangas = mutableListOf<SManga>() val mangas = mutableListOf<SManga>()
@ -74,7 +74,7 @@ class Mangadog : HttpSource() {
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val results = JsonParser().parse(jsonData) val results = JsonParser().parse(jsonData)
val data = results["suggestions"] val data = results["suggestions"]
val mangas = mutableListOf<SManga>() val mangas = mutableListOf<SManga>()
@ -100,7 +100,7 @@ class Mangadog : HttpSource() {
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val jsonData = response.body()!!.string() val jsonData = response.body!!.string()
val results = JsonParser().parse(jsonData) val results = JsonParser().parse(jsonData)
val data = results["data"]["data"] val data = results["data"]["data"]
val chapters = mutableListOf<SChapter>() val chapters = mutableListOf<SChapter>()

View File

@ -95,7 +95,7 @@ class MangaDoom : HttpSource() {
val dlElement = innerContentElement.select("div.col-md-8 > dl").first() val dlElement = innerContentElement.select("div.col-md-8 > dl").first()
return SManga.create().apply { return SManga.create().apply {
this.url = response.request().url().toString() this.url = response.request.url.toString()
this.title = innerContentElement this.title = innerContentElement
.select("h5.widget-heading:matchText").first().text() .select("h5.widget-heading:matchText").first().text()
@ -517,8 +517,8 @@ class MangaDoom : HttpSource() {
) )
).execute() ).execute()
return if (genreResponse.code() == 200 && return if (genreResponse.code == 200 &&
contentUpToDate(genreResponse.receivedResponseAtMillis()) contentUpToDate(genreResponse.receivedResponseAtMillis)
) { ) {
responseToGenreFilterContentPair(genreResponse) responseToGenreFilterContentPair(genreResponse)
} else { } else {
@ -534,7 +534,7 @@ class MangaDoom : HttpSource() {
} }
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
genreFilterContentFrom = response.receivedResponseAtMillis() genreFilterContentFrom = response.receivedResponseAtMillis
genreFiltersContent = responseToGenreFilterContentPair(response) genreFiltersContent = responseToGenreFilterContentPair(response)
} }
} }

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -49,7 +49,7 @@ class Mangaeden : ParsedHttpSource() {
override fun popularMangaNextPageSelector() = searchMangaNextPageSelector() override fun popularMangaNextPageSelector() = searchMangaNextPageSelector()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/en/en-directory/")?.newBuilder()!!.addQueryParameter("title", query) val url = "$baseUrl/en/en-directory/".toHttpUrlOrNull()?.newBuilder()!!.addQueryParameter("title", query)
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) { when (filter) {
is StatusList -> is StatusList ->

View File

@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -66,7 +66,7 @@ class Mangahasu : ParsedHttpSource() {
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/advanced-search.html")!!.newBuilder() val url = "$baseUrl/advanced-search.html".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("keyword", query) url.addQueryParameter("keyword", query)
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())

View File

@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Cookie import okhttp3.Cookie
import okhttp3.CookieJar import okhttp3.CookieJar
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -36,7 +37,7 @@ class Mangahere : ParsedHttpSource() {
override val client: OkHttpClient = super.client.newBuilder() override val client: OkHttpClient = super.client.newBuilder()
.cookieJar( .cookieJar(
object : CookieJar { object : CookieJar {
override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {} override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {}
override fun loadForRequest(url: HttpUrl): MutableList<Cookie> { override fun loadForRequest(url: HttpUrl): MutableList<Cookie> {
return ArrayList<Cookie>().apply { return ArrayList<Cookie>().apply {
add( add(
@ -86,7 +87,7 @@ class Mangahere : ParsedHttpSource() {
override fun latestUpdatesNextPageSelector() = "div.pager-list-left a:last-child" override fun latestUpdatesNextPageSelector() = "div.pager-list-left a:last-child"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
@ -267,7 +268,7 @@ class Mangahere : ParsedHttpSource() {
.build() .build()
val response = client.newCall(request).execute() val response = client.newCall(request).execute()
responseText = response.body()!!.string() responseText = response.body!!.string()
if (responseText.isNotEmpty()) if (responseText.isNotEmpty())
break break

View File

@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.Response import okhttp3.Response
@ -155,7 +155,7 @@ class Mangahub : ParsedHttpSource() {
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val cdn = "https://img.mghubcdn.com/file/imghub" val cdn = "https://img.mghubcdn.com/file/imghub"
return gson.fromJson<JsonObject>(response.body()!!.string())["data"]["chapter"]["pages"].string return gson.fromJson<JsonObject>(response.body!!.string())["data"]["chapter"]["pages"].string
.removeSurrounding("\"").replace("\\", "") .removeSurrounding("\"").replace("\\", "")
.let { cleaned -> .let { cleaned ->
val jsonObject = gson.fromJson<JsonObject>(cleaned) val jsonObject = gson.fromJson<JsonObject>(cleaned)
@ -170,7 +170,7 @@ class Mangahub : ParsedHttpSource() {
// https://mangahub.io/search/page/1?q=a&order=POPULAR&genre=all // https://mangahub.io/search/page/1?q=a&order=POPULAR&genre=all
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search/page/$page")?.newBuilder()!!.addQueryParameter("q", query) val url = "$baseUrl/search/page/$page".toHttpUrlOrNull()?.newBuilder()!!.addQueryParameter("q", query)
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) { when (filter) {
is OrderBy -> { is OrderBy -> {

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -60,7 +60,7 @@ class MangaJar : ParsedHttpSource() {
val genreFilter = filters.findInstance<GenreList>() val genreFilter = filters.findInstance<GenreList>()
val genre = genreFilter?.let { f -> f.values[f.state] } val genre = genreFilter?.let { f -> f.values[f.state] }
val url = HttpUrl.parse(if (genre!!.isEmpty()) "$baseUrl/search" else "$baseUrl/genre/$genre")!!.newBuilder() val url = (if (genre!!.isEmpty()) "$baseUrl/search" else "$baseUrl/genre/$genre").toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("q", query) url.addQueryParameter("q", query)
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())

View File

@ -8,10 +8,10 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody import okhttp3.ResponseBody.Companion.toResponseBody
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -29,9 +29,9 @@ class MangaKatana : ParsedHttpSource() {
override val client: OkHttpClient = network.cloudflareClient.newBuilder().addNetworkInterceptor { chain -> override val client: OkHttpClient = network.cloudflareClient.newBuilder().addNetworkInterceptor { chain ->
val originalResponse = chain.proceed(chain.request()) val originalResponse = chain.proceed(chain.request())
if (originalResponse.headers("Content-Type").contains("application/octet-stream")) { if (originalResponse.headers("Content-Type").contains("application/octet-stream")) {
val orgBody = originalResponse.body()!!.bytes() val orgBody = originalResponse.body!!.bytes()
val extension = chain.request().url().toString().substringAfterLast(".") val extension = chain.request().url.toString().substringAfterLast(".")
val newBody = ResponseBody.create(MediaType.parse("image/$extension"), orgBody) val newBody = orgBody.toResponseBody("image/$extension".toMediaTypeOrNull())
originalResponse.newBuilder() originalResponse.newBuilder()
.body(newBody) .body(newBody)
.build() .build()
@ -69,13 +69,13 @@ class MangaKatana : ParsedHttpSource() {
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector() override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
return if (response.request().url().toString().contains("/manga/")) { return if (response.request.url.toString().contains("/manga/")) {
val document = response.asJsoup() val document = response.asJsoup()
val manga = SManga.create().apply { val manga = SManga.create().apply {
thumbnail_url = parseThumbnail(document) thumbnail_url = parseThumbnail(document)
title = document.select("h1.heading").first().text() title = document.select("h1.heading").first().text()
} }
manga.setUrlWithoutDomain(response.request().url().toString()) manga.setUrlWithoutDomain(response.request.url.toString())
MangasPage(listOf(manga), false) MangasPage(listOf(manga), false)
} else { } else {
super.searchMangaParse(response) super.searchMangaParse(response)

View File

@ -17,11 +17,9 @@ import okhttp3.Headers
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
import java.lang.Exception
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.TimeZone import java.util.TimeZone
import kotlin.collections.ArrayList
fun JsonObject.getNullable(key: String): JsonElement? { fun JsonObject.getNullable(key: String): JsonElement? {
val value: JsonElement = this.get(key) ?: return null val value: JsonElement = this.get(key) ?: return null
@ -81,7 +79,7 @@ class MangaMutiny : HttpSource() {
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val chapterList = mutableListOf<SChapter>() val chapterList = mutableListOf<SChapter>()
val responseBody = response.body() val responseBody = response.body
if (responseBody != null) { if (responseBody != null) {
val jsonChapters = JsonParser().parse(responseBody.charStream()).asJsonObject val jsonChapters = JsonParser().parse(responseBody.charStream()).asJsonObject
@ -165,7 +163,7 @@ class MangaMutiny : HttpSource() {
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val manga = SManga.create() val manga = SManga.create()
val responseBody = response.body() val responseBody = response.body
if (responseBody != null) { if (responseBody != null) {
val rootNode = parser.parse(responseBody.charStream()).asJsonObject val rootNode = parser.parse(responseBody.charStream()).asJsonObject
@ -203,7 +201,7 @@ class MangaMutiny : HttpSource() {
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val pageList = ArrayList<Page>() val pageList = ArrayList<Page>()
val responseBody = response.body() val responseBody = response.body
if (responseBody != null) { if (responseBody != null) {
val rootNode = parser.parse(responseBody.charStream()).asJsonObject val rootNode = parser.parse(responseBody.charStream()).asJsonObject
@ -237,7 +235,7 @@ class MangaMutiny : HttpSource() {
// commonly used functions // commonly used functions
private fun mangaParse(response: Response): MangasPage { private fun mangaParse(response: Response): MangasPage {
val mangasPage = ArrayList<SManga>() val mangasPage = ArrayList<SManga>()
val responseBody = response.body() val responseBody = response.body
var totalObjects = 0 var totalObjects = 0
@ -267,7 +265,7 @@ class MangaMutiny : HttpSource() {
responseBody.close() responseBody.close()
} }
val skipped = response.request().url().queryParameter("skip")?.toInt() ?: 0 val skipped = response.request.url.queryParameter("skip")?.toInt() ?: 0
val moreElementsToSkip = skipped + fetchAmount < totalObjects val moreElementsToSkip = skipped + fetchAmount < totalObjects

View File

@ -4,8 +4,6 @@ import android.annotation.SuppressLint
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
@ -126,7 +124,6 @@ class MangaPark : ConfigurableSource, ParsedHttpSource() {
} }
} }
} }
} }
// force network to make sure chapter prefs take effect // force network to make sure chapter prefs take effect
@ -279,8 +276,8 @@ class MangaPark : ConfigurableSource, ParsedHttpSource() {
private val objRegex = Regex("""var _load_pages = (\[.*])""") private val objRegex = Regex("""var _load_pages = (\[.*])""")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val obj = objRegex.find(response.body()!!.string())?.groupValues?.get(1) val obj = objRegex.find(response.body!!.string())?.groupValues?.get(1)
?: throw Exception("_load_pages not found - ${response.request().url()}") ?: throw Exception("_load_pages not found - ${response.request.url}")
val jsonArray = JSONArray(obj) val jsonArray = JSONArray(obj)
return (0 until jsonArray.length()).map { i -> jsonArray.getJSONObject(i).getString("u") } return (0 until jsonArray.length()).map { i -> jsonArray.getJSONObject(i).getString("u") }
.mapIndexed { i, url -> Page(i, "", if (url.startsWith("//")) "https://$url" else url) } .mapIndexed { i, url -> Page(i, "", if (url.startsWith("//")) "https://$url" else url) }
@ -590,23 +587,6 @@ class MangaPark : ConfigurableSource, ParsedHttpSource() {
screen.addPreference(myPref) screen.addPreference(myPref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val myPref = ListPreference(screen.context).apply {
key = SOURCE_PREF_TITLE
title = SOURCE_PREF_TITLE
entries = sourceArray.map { it.first }.toTypedArray()
entryValues = sourceArray.map { it.second }.toTypedArray()
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(SOURCE_PREF, entry).commit()
}
}
screen.addPreference(myPref)
}
private fun getSourcePref(): String? = preferences.getString(SOURCE_PREF, "all") private fun getSourcePref(): String? = preferences.getString(SOURCE_PREF, "all")
companion object { companion object {

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -102,7 +102,7 @@ class MangaPill : ParsedHttpSource() {
override fun imageUrlParse(document: Document) = "" override fun imageUrlParse(document: Document) = ""
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
.addQueryParameter("q", query) .addQueryParameter("q", query)

View File

@ -10,12 +10,12 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody import okhttp3.ResponseBody.Companion.toResponseBody
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -37,13 +37,13 @@ class MangaRockEs : ParsedHttpSource() {
// Handles the page decoding // Handles the page decoding
override val client: OkHttpClient = network.cloudflareClient.newBuilder().addInterceptor( override val client: OkHttpClient = network.cloudflareClient.newBuilder().addInterceptor(
fun(chain): Response { fun(chain): Response {
val url = chain.request().url().toString() val url = chain.request().url.toString()
val response = chain.proceed(chain.request()) val response = chain.proceed(chain.request())
if (!url.endsWith(".mri")) return response if (!url.endsWith(".mri")) return response
val decoded: ByteArray = decodeMri(response) val decoded: ByteArray = decodeMri(response)
val mediaType = MediaType.parse("image/webp") val mediaType = "image/webp".toMediaTypeOrNull()
val rb = ResponseBody.create(mediaType, decoded) val rb = decoded.toResponseBody(mediaType)
return response.newBuilder().body(rb).build() return response.newBuilder().body(rb).build()
} }
).build() ).build()
@ -82,7 +82,7 @@ class MangaRockEs : ParsedHttpSource() {
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/search/${query.replace(" ", "+")}/$page", headers) GET("$baseUrl/search/${query.replace(" ", "+")}/$page", headers)
} else { } else {
val url = HttpUrl.parse("$baseUrl/manga" + if (page > 1) "/$page" else "")!!.newBuilder() val url = ("$baseUrl/manga" + if (page > 1) "/$page" else "").toHttpUrl().newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
is StatusFilter -> url.addQueryParameter("status", filter.toUriPart()) is StatusFilter -> url.addQueryParameter("status", filter.toUriPart())
@ -163,7 +163,7 @@ class MangaRockEs : ParsedHttpSource() {
private val gson by lazy { Gson() } private val gson by lazy { Gson() }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val responseString = response.body()!!.string() val responseString = response.body!!.string()
return Regex("""mangaData = (\[.*]);""", RegexOption.IGNORE_CASE).find(responseString)?.groupValues?.get(1)?.let { array -> return Regex("""mangaData = (\[.*]);""", RegexOption.IGNORE_CASE).find(responseString)?.groupValues?.get(1)?.let { array ->
gson.fromJson<JsonArray>(array) gson.fromJson<JsonArray>(array)
.mapIndexed { i, jsonElement -> Page(i, "", jsonElement.asJsonObject["url"].asString) } .mapIndexed { i, jsonElement -> Page(i, "", jsonElement.asJsonObject["url"].asString) }
@ -181,7 +181,7 @@ class MangaRockEs : ParsedHttpSource() {
// See drawWebpToCanvas function in the site's client.js file // See drawWebpToCanvas function in the site's client.js file
// Extracted code: https://jsfiddle.net/6h2sLcs4/30/ // Extracted code: https://jsfiddle.net/6h2sLcs4/30/
private fun decodeMri(response: Response): ByteArray { private fun decodeMri(response: Response): ByteArray {
val data = response.body()!!.bytes() val data = response.body!!.bytes()
// Decode file if it starts with "E" (space when XOR-ed later) // Decode file if it starts with "E" (space when XOR-ed later)
if (data[0] != 69.toByte()) return data if (data[0] != 69.toByte()) return data

View File

@ -97,7 +97,7 @@ class Mangasail : ParsedHttpSource() {
// Function to get data fragments from website // Function to get data fragments from website
private fun getNodeDetail(node: String, field: String): String? { private fun getNodeDetail(node: String, field: String): String? {
val requestUrl = "$baseUrl/sites/all/modules/authcache/modules/authcache_p13n/frontcontroller/authcache.php?a[field][0]=$node:full:en&r=asm/field/node/$field&o[q]=node/$node" val requestUrl = "$baseUrl/sites/all/modules/authcache/modules/authcache_p13n/frontcontroller/authcache.php?a[field][0]=$node:full:en&r=asm/field/node/$field&o[q]=node/$node"
val responseString = client.newCall(GET(requestUrl, headers)).execute().body()?.string() ?: return null val responseString = client.newCall(GET(requestUrl, headers)).execute().body?.string() ?: return null
return with(gson.fromJson<JsonObject>(responseString)) { return with(gson.fromJson<JsonObject>(responseString)) {
when (field) { when (field) {
"field_image2" -> this["field"]["$node:full:en"].asString.substringAfter("src=\"").substringBefore("\"") "field_image2" -> this["field"]["$node:full:en"].asString.substringAfter("src=\"").substringBefore("\"")

View File

@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.Response import okhttp3.Response
@ -45,7 +45,7 @@ class ManhwaManga : ParsedHttpSource() {
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/?s=$query", headers) GET("$baseUrl/?s=$query", headers)
} else { } else {
val url = HttpUrl.parse("$baseUrl/category/")!!.newBuilder() val url = "$baseUrl/category/".toHttpUrlOrNull()!!.newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {

View File

@ -19,11 +19,11 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody import okhttp3.ResponseBody.Companion.toResponseBody
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
@ -67,12 +67,12 @@ class Multporn : ParsedHttpSource() {
override fun popularMangaRequest(page: Int) = buildPopularMangaRequest(page - 1) override fun popularMangaRequest(page: Int) = buildPopularMangaRequest(page - 1)
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val html = gson.fromJson<JsonArray>(response.body()!!.string()) val html = gson.fromJson<JsonArray>(response.body!!.string())
.last { it["command"].asString == "insert" }.asJsonObject["data"].asString .last { it["command"].asString == "insert" }.asJsonObject["data"].asString
return super.popularMangaParse( return super.popularMangaParse(
response.newBuilder() response.newBuilder()
.body(ResponseBody.create(MediaType.parse("text/html; charset=UTF-8"), html)) .body(html.toResponseBody("text/html; charset=UTF-8".toMediaTypeOrNull()))
.build() .build()
) )
} }
@ -88,7 +88,7 @@ class Multporn : ParsedHttpSource() {
// Latest // Latest
private fun buildLatestMangaRequest(page: Int, filters: FilterList = FilterList()): Request { private fun buildLatestMangaRequest(page: Int, filters: FilterList = FilterList()): Request {
val url = HttpUrl.parse("$baseUrl/new")!!.newBuilder() val url = "$baseUrl/new".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
(if (filters.isEmpty()) getFilterList(LATEST_DEFAULT_SORT_BY_FILTER_STATE) else filters).forEach { (if (filters.isEmpty()) getFilterList(LATEST_DEFAULT_SORT_BY_FILTER_STATE) else filters).forEach {
@ -126,7 +126,7 @@ class Multporn : ParsedHttpSource() {
} }
private fun buildSearchMangaRequest(page: Int, query: String, filtersArg: FilterList = FilterList()): Request { private fun buildSearchMangaRequest(page: Int, query: String, filtersArg: FilterList = FilterList()): Request {
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
.addQueryParameter("views_fulltext", query) .addQueryParameter("views_fulltext", query)
@ -176,7 +176,7 @@ class Multporn : ParsedHttpSource() {
squashMangasPageObservables( squashMangasPageObservables(
requests.map { requests.map {
client.newCall(it).asObservable().map { res -> client.newCall(it).asObservable().map { res ->
if (res.code() == 200) textSearchFilterParse(res) if (res.code == 200) textSearchFilterParse(res)
else null else null
} }
} }

View File

@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -84,7 +84,7 @@ class MyHentaiGallery : ParsedHttpSource() {
return if (query.isNotBlank()) { return if (query.isNotBlank()) {
GET("$baseUrl/search/$page?query=$query", headers) GET("$baseUrl/search/$page?query=$query", headers)
} else { } else {
val url = HttpUrl.parse("$baseUrl/gallery/category")!!.newBuilder() val url = "$baseUrl/gallery/category".toHttpUrl().newBuilder()
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
@ -130,7 +130,7 @@ class MyHentaiGallery : ParsedHttpSource() {
return listOf( return listOf(
SChapter.create().apply { SChapter.create().apply {
name = "Chapter" name = "Chapter"
url = response.request().url().toString().substringAfter(baseUrl) url = response.request.url.toString().substringAfter(baseUrl)
} }
) )
} }

View File

@ -13,7 +13,6 @@ import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import rx.Observable import rx.Observable
import java.lang.UnsupportedOperationException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -29,7 +28,7 @@ class NaniScans : HttpSource() {
override fun latestUpdatesRequest(page: Int): Request = popularMangaRequest(page) override fun latestUpdatesRequest(page: Int): Request = popularMangaRequest(page)
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val titlesJson = JSONArray(response.body()!!.string()) val titlesJson = JSONArray(response.body!!.string())
val mangaMap = mutableMapOf<Long, SManga>() val mangaMap = mutableMapOf<Long, SManga>()
for (i in 0 until titlesJson.length()) { for (i in 0 until titlesJson.length()) {
@ -52,7 +51,7 @@ class NaniScans : HttpSource() {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/api/titles") override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/api/titles")
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val titlesJson = JSONArray(response.body()!!.string()) val titlesJson = JSONArray(response.body!!.string())
val mangaList = mutableListOf<SManga>() val mangaList = mutableListOf<SManga>()
for (i in 0 until titlesJson.length()) { for (i in 0 until titlesJson.length()) {
@ -78,7 +77,7 @@ class NaniScans : HttpSource() {
override fun mangaDetailsRequest(manga: SManga) = GET("$baseUrl/titles/${manga.url}") override fun mangaDetailsRequest(manga: SManga) = GET("$baseUrl/titles/${manga.url}")
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val titleJson = JSONObject(response.body()!!.string()) val titleJson = JSONObject(response.body!!.string())
if (titleJson.getString("type") != "Comic") if (titleJson.getString("type") != "Comic")
throw UnsupportedOperationException("Tachiyomi only supports Comics.") throw UnsupportedOperationException("Tachiyomi only supports Comics.")
@ -98,7 +97,7 @@ class NaniScans : HttpSource() {
override fun chapterListRequest(manga: SManga) = GET("$baseUrl/api/titles/${manga.url}") override fun chapterListRequest(manga: SManga) = GET("$baseUrl/api/titles/${manga.url}")
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val titleJson = JSONObject(response.body()!!.string()) val titleJson = JSONObject(response.body!!.string())
if (titleJson.getString("type") != "Comic") if (titleJson.getString("type") != "Comic")
throw UnsupportedOperationException("Tachiyomi only supports Comics.") throw UnsupportedOperationException("Tachiyomi only supports Comics.")
@ -125,7 +124,7 @@ class NaniScans : HttpSource() {
override fun pageListRequest(chapter: SChapter): Request = GET("$baseUrl/api/chapters/${chapter.url.substring(37, 73)}") override fun pageListRequest(chapter: SChapter): Request = GET("$baseUrl/api/chapters/${chapter.url.substring(37, 73)}")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val jsonObject = JSONObject(response.body()!!.string()) val jsonObject = JSONObject(response.body!!.string())
val pagesJson = jsonObject.getJSONArray("pages") val pagesJson = jsonObject.getJSONArray("pages")
val pagesList = mutableListOf<Page>() val pagesList = mutableListOf<Page>()

View File

@ -20,7 +20,7 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -51,7 +51,7 @@ class NHentaiCom : HttpSource() {
private val gson = Gson() private val gson = Gson()
private fun parseMangaFromJson(response: Response): MangasPage { private fun parseMangaFromJson(response: Response): MangasPage {
val jsonObject = gson.fromJson<JsonObject>(response.body()!!.string()) val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
val mangas = jsonObject["data"].asJsonArray.map { json -> val mangas = jsonObject["data"].asJsonArray.map { json ->
SManga.create().apply { SManga.create().apply {
@ -64,7 +64,7 @@ class NHentaiCom : HttpSource() {
return MangasPage(mangas, jsonObject["current_page"].int < jsonObject["last_page"].int) return MangasPage(mangas, jsonObject["current_page"].int < jsonObject["last_page"].int)
} }
private fun getMangaUrl(url: String): String { private fun getMangaUrl(url: String): String {
return HttpUrl.parse(url)!!.newBuilder() return url.toHttpUrlOrNull()!!.newBuilder()
.setQueryParameter("nsfw", "false").toString() .setQueryParameter("nsfw", "false").toString()
} }
@ -87,7 +87,7 @@ class NHentaiCom : HttpSource() {
// Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/api/comics")!!.newBuilder() val url = "$baseUrl/api/comics".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("per_page", "18") .addQueryParameter("per_page", "18")
.addQueryParameter("page", page.toString()) .addQueryParameter("page", page.toString())
.addQueryParameter("order", "desc") .addQueryParameter("order", "desc")
@ -120,7 +120,7 @@ class NHentaiCom : HttpSource() {
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val jsonObject = gson.fromJson<JsonObject>(response.body()!!.string()) val jsonObject = gson.fromJson<JsonObject>(response.body!!.string())
return SManga.create().apply { return SManga.create().apply {
description = jsonObject["description"].nullString description = jsonObject["description"].nullString
@ -163,7 +163,7 @@ class NHentaiCom : HttpSource() {
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
return gson.fromJson<JsonObject>(response.body()!!.string())["images"].asJsonArray.mapIndexed { i, json -> return gson.fromJson<JsonObject>(response.body!!.string())["images"].asJsonArray.mapIndexed { i, json ->
Page(i, "", json["source_url"].string) Page(i, "", json["source_url"].string)
} }
} }

View File

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -45,7 +45,7 @@ class Perveden : ParsedHttpSource() {
override fun popularMangaNextPageSelector() = searchMangaNextPageSelector() override fun popularMangaNextPageSelector() = searchMangaNextPageSelector()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/en/en-directory/")?.newBuilder()!!.addQueryParameter("title", query) val url = "$baseUrl/en/en-directory/".toHttpUrlOrNull()?.newBuilder()!!.addQueryParameter("title", query)
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) { when (filter) {
is StatusList -> is StatusList ->

View File

@ -127,7 +127,7 @@ class Pururin : ParsedHttpSource() {
listOf( listOf(
SChapter.create().apply { SChapter.create().apply {
name = "Chapter" name = "Chapter"
setUrlWithoutDomain(response.request().url().toString()) setUrlWithoutDomain(response.request.url.toString())
if (mangaInfoElements.containsKey("Scanlator")) if (mangaInfoElements.containsKey("Scanlator"))
scanlator = mangaInfoElements.getValue("Scanlator").select("li a")?.joinToString { s -> s.text() } scanlator = mangaInfoElements.getValue("Scanlator").select("li a")?.joinToString { s -> s.text() }
@ -195,7 +195,7 @@ class Pururin : ParsedHttpSource() {
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
return if (response.request().url().toString().contains("tag?")) { return if (response.request.url.toString().contains("tag?")) {
response.asJsoup().select("table.table tbody tr a:first-of-type").attr("abs:href").let { response.asJsoup().select("table.table tbody tr a:first-of-type").attr("abs:href").let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
tagUrl = it tagUrl = it

View File

@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
@ -49,7 +49,7 @@ open class RainOfSnow() : ParsedHttpSource() {
override fun popularMangaNextPageSelector() = ".page-numbers .next" override fun popularMangaNextPageSelector() = ".page-numbers .next"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/")!!.newBuilder() val url = "$baseUrl/".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("serchfor", "comics") url.addQueryParameter("serchfor", "comics")
url.addQueryParameter("s", query) url.addQueryParameter("s", query)
return GET(url.build().toString(), headers) return GET(url.build().toString(), headers)

View File

@ -2,8 +2,6 @@ package eu.kanade.tachiyomi.extension.en.readcomiconline
import android.app.Application import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
@ -130,7 +128,7 @@ class Readcomiconline : ConfigurableSource, ParsedHttpSource() {
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url + "&quality=${qualitypref()}", headers) override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url + "&quality=${qualitypref()}", headers)
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
return Regex("""lstImages\.push\("(http.*)"\)""").findAll(response.body()!!.string()) return Regex("""lstImages\.push\("(http.*)"\)""").findAll(response.body!!.string())
.toList() .toList()
.mapIndexed { i, mr -> Page(i, "", mr.groupValues[1]) } .mapIndexed { i, mr -> Page(i, "", mr.groupValues[1]) }
} }
@ -220,24 +218,6 @@ class Readcomiconline : ConfigurableSource, ParsedHttpSource() {
screen.addPreference(qualitypref) screen.addPreference(qualitypref)
} }
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val qualitypref = ListPreference(screen.context).apply {
key = QUALITY_PREF_Title
title = QUALITY_PREF_Title
entries = arrayOf("High Quality", "Low Quality")
entryValues = arrayOf("hq", "lq")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(QUALITY_PREF, entry).commit()
}
}
screen.addPreference(qualitypref)
}
private fun qualitypref() = preferences.getString(QUALITY_PREF, "hq") private fun qualitypref() = preferences.getString(QUALITY_PREF, "hq")
companion object { companion object {

View File

@ -77,7 +77,7 @@ class ReadM : ParsedHttpSource() {
override fun searchMangaFromElement(element: Element): SManga = throw Exception("Not used") override fun searchMangaFromElement(element: Element): SManga = throw Exception("Not used")
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val json = JSONObject(response.body()!!.string()).getJSONArray("manga") val json = JSONObject(response.body!!.string()).getJSONArray("manga")
val manga = (0 until json.length()).asSequence().toList().map { it -> val manga = (0 until json.length()).asSequence().toList().map { it ->
SManga.create().apply { SManga.create().apply {

Some files were not shown because too many files have changed in this diff Show More