Update dependencies; drop Android 4.x support (#6742)
This commit is contained in:
parent
4c08f48fc7
commit
50bf2a56e5
|
@ -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()
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 -> {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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, "+")
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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].
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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") }
|
||||||
|
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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 ---------------
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)!!
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)!!
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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;", ""))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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>()
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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())
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 -> {
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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("\"")
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>()
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue