Compare commits
22 Commits
504342706e
...
c353c9a780
Author | SHA1 | Date |
---|---|---|
Vetle Ledaal | c353c9a780 | |
Vetle Ledaal | 76a7c8c54a | |
beerpsi | d88fb5f595 | |
beerpsi | c6276c8a7d | |
beerpsi | 9d74ec6b34 | |
beerpsi | 85f8bd3917 | |
Eshlender | 555896d9a4 | |
Wackery | 43a2a09e4b | |
beerpsi | ddb46a88ce | |
az4521 | e0d5742b09 | |
Fermín Cirella | 6651c0421b | |
bapeey | e2dc0795c3 | |
Vetle Ledaal | 8f55b1e8d4 | |
Fermín Cirella | c2555b3e44 | |
stevenyomi | f612bc1c3f | |
Eshlender | 2b9b92ceaa | |
Fermín Cirella | a9faf70d33 | |
CodeSpoof | 84418c477f | |
AwkwardPeak7 | df0e9cb736 | |
AwkwardPeak7 | 0c197ded02 | |
Fermín Cirella | cafe12c736 | |
bapeey | 6cc9041f10 |
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
|
||||||
import eu.kanade.tachiyomi.network.GET
|
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 okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -46,15 +45,13 @@ class AllHentai : GroupLe("AllHentai", "https://z.allhen.online", "ru") {
|
||||||
is OrderBy -> {
|
is OrderBy -> {
|
||||||
if (filter.state > 0) {
|
if (filter.state > 0) {
|
||||||
val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
|
val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
|
||||||
val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
|
return GET("$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}", headers)
|
||||||
return GET(ordUrl.toString(), headers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Tags -> {
|
is Tags -> {
|
||||||
if (filter.state > 0) {
|
if (filter.state > 0) {
|
||||||
val tagName = getTagsList()[filter.state].url
|
val tagName = getTagsList()[filter.state].url
|
||||||
val tagUrl = "$baseUrl/list/tag/$tagName?offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
|
return GET("$baseUrl/list/tag/$tagName?offset=${70 * (page - 1)}", headers)
|
||||||
return GET(tagUrl.toString(), headers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
|
||||||
import eu.kanade.tachiyomi.network.GET
|
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 okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -57,8 +56,7 @@ class MintManga : GroupLe("MintManga", "https://mintmanga.com", "ru") {
|
||||||
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
||||||
} else {
|
} else {
|
||||||
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
||||||
val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
|
return GET("$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}", headers)
|
||||||
return GET(ordUrl.toString(), headers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
|
||||||
import eu.kanade.tachiyomi.network.GET
|
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 okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -57,8 +56,7 @@ class ReadManga : GroupLe("ReadManga", "https://readmanga.live", "ru") {
|
||||||
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
||||||
} else {
|
} else {
|
||||||
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
||||||
val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
|
return GET("$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}", headers)
|
||||||
return GET(ordUrl.toString(), headers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
|
||||||
import eu.kanade.tachiyomi.network.GET
|
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 okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -31,8 +30,7 @@ class RuMIX : GroupLe("RuMIX", "https://rumix.me", "ru") {
|
||||||
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
||||||
} else {
|
} else {
|
||||||
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
||||||
val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
|
return GET("$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}", headers)
|
||||||
return GET(ordUrl.toString(), headers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> return@forEach
|
else -> return@forEach
|
||||||
|
|
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
|
||||||
import eu.kanade.tachiyomi.network.GET
|
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 okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
@ -43,8 +42,7 @@ class SelfManga : GroupLe("SelfManga", "https://selfmanga.live", "ru") {
|
||||||
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
url.addQueryParameter("sortType", arrayOf("RATING", "POPULARITY", "YEAR", "NAME", "DATE_CREATE", "DATE_UPDATE")[filter.state])
|
||||||
} else {
|
} else {
|
||||||
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
val ord = arrayOf("rate", "popularity", "year", "name", "created", "updated", "votes")[filter.state]
|
||||||
val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
|
return GET("$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}", headers)
|
||||||
return GET(ordUrl.toString(), headers)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> return@forEach
|
else -> return@forEach
|
||||||
|
|
|
@ -52,7 +52,7 @@ class DoujinHentai : Madara(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.build().toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = "div.c-tabs-item__content > div.c-tabs-item__content, ${popularMangaSelector()}"
|
override fun searchMangaSelector() = "div.c-tabs-item__content > div.c-tabs-item__content, ${popularMangaSelector()}"
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class ImperioScans : Madara(
|
class ImperioScans : Madara(
|
||||||
"Império Scans",
|
"Império Scans",
|
||||||
"https://imperioscans.com.br",
|
"https://neroxus.com.br",
|
||||||
"pt-BR",
|
"pt-BR",
|
||||||
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR")),
|
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR")),
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
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 okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -23,7 +23,7 @@ class PojokManga : Madara("Pojok Manga", "https://pojokmanga.net", "id", SimpleD
|
||||||
override val mangaSubString = "komik"
|
override val mangaSubString = "komik"
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
var url = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
|
var url = "$baseUrl/${searchPage(page)}".toHttpUrl().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 ->
|
||||||
|
@ -70,13 +70,13 @@ class PojokManga : Madara("Pojok Manga", "https://pojokmanga.net", "id", SimpleD
|
||||||
}
|
}
|
||||||
is ProjectFilter -> {
|
is ProjectFilter -> {
|
||||||
if (filter.toUriPart() == "project-filter-on") {
|
if (filter.toUriPart() == "project-filter-on") {
|
||||||
url = "$baseUrl/project/page/$page".toHttpUrlOrNull()!!.newBuilder()
|
url = "$baseUrl/project/page/$page".toHttpUrl().newBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = "div.c-tabs-item__content, div.page-item-detail"
|
override fun searchMangaSelector() = "div.c-tabs-item__content, div.page-item-detail"
|
||||||
|
|
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 210 KiB |
|
@ -0,0 +1,7 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.resetscans
|
||||||
|
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
|
||||||
|
class ResetScans : Madara("Reset Scans", "https://reset-scans.us", "en") {
|
||||||
|
override val useNewChapterEndpoint = true
|
||||||
|
override val chapterUrlSelector = ".li__text > a"
|
||||||
|
}
|
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 226 KiB |
|
@ -0,0 +1,62 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.setsuscans
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
import okhttp3.Response
|
||||||
|
|
||||||
|
class SetsuScans : Madara(
|
||||||
|
"Setsu Scans",
|
||||||
|
"https://setsuscans.com",
|
||||||
|
"en",
|
||||||
|
) {
|
||||||
|
override val client = super.client.newBuilder()
|
||||||
|
.addNetworkInterceptor { chain ->
|
||||||
|
val request = chain.request()
|
||||||
|
val url = request.url
|
||||||
|
if (url.host == "i0.wp.com") {
|
||||||
|
val newUrl = url.newBuilder()
|
||||||
|
.removeAllQueryParameters("fit")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
return@addNetworkInterceptor chain.proceed(
|
||||||
|
request.newBuilder()
|
||||||
|
.url(newUrl)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return@addNetworkInterceptor chain.proceed(request)
|
||||||
|
}
|
||||||
|
.rateLimit(2)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
override val useNewChapterEndpoint = true
|
||||||
|
|
||||||
|
override fun searchPage(page: Int): String {
|
||||||
|
return if (page > 1) {
|
||||||
|
"page/$page/"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun popularMangaParse(response: Response) =
|
||||||
|
super.popularMangaParse(response).fixNextPage()
|
||||||
|
|
||||||
|
override fun latestUpdatesParse(response: Response) =
|
||||||
|
super.latestUpdatesParse(response).fixNextPage()
|
||||||
|
|
||||||
|
override fun searchMangaParse(response: Response) =
|
||||||
|
super.searchMangaParse(response).fixNextPage()
|
||||||
|
|
||||||
|
private fun MangasPage.fixNextPage(): MangasPage {
|
||||||
|
return if (mangas.size < 12) {
|
||||||
|
MangasPage(mangas, false)
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val mangaDetailsSelectorStatus = "div.summary-heading:contains(status) + div.summary-content"
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.extension.en.toonily
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||||
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
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -51,7 +51,7 @@ class Toonily : Madara(
|
||||||
val queries = request.url.queryParameterNames
|
val queries = request.url.queryParameterNames
|
||||||
.filterNot { it == "s" }
|
.filterNot { it == "s" }
|
||||||
|
|
||||||
val newUrl = "$baseUrl/${searchPage(page, query)}".toHttpUrlOrNull()!!.newBuilder().apply {
|
val newUrl = "$baseUrl/${searchPage(page, query)}".toHttpUrl().newBuilder().apply {
|
||||||
queries.map { q ->
|
queries.map { q ->
|
||||||
request.url.queryParameterValues(q).map {
|
request.url.queryParameterValues(q).map {
|
||||||
this.addQueryParameter(q, it)
|
this.addQueryParameter(q, it)
|
||||||
|
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 237 KiB |
|
@ -0,0 +1,95 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.en.constellarscans
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import eu.kanade.tachiyomi.lib.randomua.getPrefCustomUA
|
||||||
|
import eu.kanade.tachiyomi.lib.randomua.getPrefUAType
|
||||||
|
import eu.kanade.tachiyomi.lib.randomua.setRandomUserAgent
|
||||||
|
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||||
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
import okhttp3.CacheControl
|
||||||
|
import okhttp3.Headers
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class ConstellarScans : MangaThemesia("Constellar Scans", "https://constellarcomic.com", "en") {
|
||||||
|
|
||||||
|
private val preferences: SharedPreferences by lazy {
|
||||||
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val client: OkHttpClient by lazy {
|
||||||
|
network.cloudflareClient.newBuilder()
|
||||||
|
.setRandomUserAgent(
|
||||||
|
preferences.getPrefUAType(),
|
||||||
|
preferences.getPrefCustomUA(),
|
||||||
|
)
|
||||||
|
.connectTimeout(10, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.rateLimit(1, 1)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
|
.add("Referer", "$baseUrl/")
|
||||||
|
.add("Accept-Language", "en-US,en;q=0.9")
|
||||||
|
.add("DNT", "1")
|
||||||
|
.add("Upgrade-Insecure-Requests", "1")
|
||||||
|
|
||||||
|
override val seriesStatusSelector = ".status"
|
||||||
|
|
||||||
|
override fun pageListRequest(chapter: SChapter): Request =
|
||||||
|
super.pageListRequest(chapter).newBuilder()
|
||||||
|
.header(
|
||||||
|
"Accept",
|
||||||
|
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||||
|
)
|
||||||
|
.header("Sec-Fetch-Site", "same-origin")
|
||||||
|
.header("Sec-Fetch-Mode", "navigate")
|
||||||
|
.header("Sec-Fetch-Dest", "document")
|
||||||
|
.header("Sec-Fetch-User", "?1")
|
||||||
|
.cacheControl(CacheControl.FORCE_NETWORK)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
|
val html = document.toString()
|
||||||
|
if (!html.contains("ts_rea_der_._run(\"")) {
|
||||||
|
return super.pageListParse(document)
|
||||||
|
}
|
||||||
|
|
||||||
|
val tsReaderRawData = html
|
||||||
|
.substringAfter("ts_rea_der_._run(\"")
|
||||||
|
.substringBefore("\")")
|
||||||
|
.replace(Regex("""\D"""), "")
|
||||||
|
.chunked(4)
|
||||||
|
.map {
|
||||||
|
val tenthsAndOnes = it.chunked(2).map {
|
||||||
|
val num = it.toInt()
|
||||||
|
num / 10 + num % 10
|
||||||
|
}
|
||||||
|
(tenthsAndOnes[0] * 10 + tenthsAndOnes[1] + 32).toChar()
|
||||||
|
}
|
||||||
|
.joinToString("")
|
||||||
|
|
||||||
|
countViews(document)
|
||||||
|
return json.parseToJsonElement(tsReaderRawData).jsonObject["sources"]!!.jsonArray[0].jsonObject["images"]!!.jsonArray.mapIndexed { idx, it ->
|
||||||
|
Page(idx, imageUrl = it.jsonPrimitive.content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun imageRequest(page: Page): Request = super.imageRequest(page).newBuilder()
|
||||||
|
.header("Accept", "image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8")
|
||||||
|
.header("Sec-Fetch-Dest", "image")
|
||||||
|
.header("Sec-Fetch-Mode", "no-cors")
|
||||||
|
.header("Sec-Fetch-Site", "same-origin")
|
||||||
|
.build()
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ class CosmicScansID : MangaThemesia("CosmicScans.id", "https://cosmicscans.id",
|
||||||
else -> { /* Do Nothing */ }
|
else -> { /* Do Nothing */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = ".bixbox:not(.hothome):has(.hpage) .utao .uta .imgu, .bixbox:not(.hothome) .listupd .bs .bsx"
|
override fun searchMangaSelector() = ".bixbox:not(.hothome):has(.hpage) .utao .uta .imgu, .bixbox:not(.hothome) .listupd .bs .bsx"
|
||||||
|
|
|
@ -201,7 +201,7 @@ class KomikCast : MangaThemesia("Komik Cast", "https://komikcast.lol", "id", "/d
|
||||||
else -> { /* Do Nothing */ }
|
else -> { /* Do Nothing */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StatusFilter : SelectFilter(
|
private class StatusFilter : SelectFilter(
|
||||||
|
|
|
@ -55,7 +55,7 @@ class Ngomik : MangaThemesia("Ngomik", "https://ngomik.net", "id", "/manga") {
|
||||||
else -> { /* Do Nothing */ }
|
else -> { /* Do Nothing */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":lib-synchrony"))
|
||||||
|
implementation(project(":lib-cryptoaes"))
|
||||||
|
}
|
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 122 KiB |
|
@ -0,0 +1,154 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.es.mangasin
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.util.Base64
|
||||||
|
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
|
||||||
|
import eu.kanade.tachiyomi.lib.synchrony.Deobfuscator
|
||||||
|
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class MangasIn : MMRCMS("Mangas.in", "https://mangas.in", "es") {
|
||||||
|
|
||||||
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
|
override val client = super.client.newBuilder()
|
||||||
|
.rateLimitHost(baseUrl.toHttpUrl(), 1, 1)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
override fun headersBuilder() = super.headersBuilder()
|
||||||
|
.add("Referer", "$baseUrl/")
|
||||||
|
|
||||||
|
private var key = ""
|
||||||
|
|
||||||
|
private fun getKey(): String {
|
||||||
|
val script = client.newCall(GET("$baseUrl/js/datachs.js")).execute().body.string()
|
||||||
|
val deobfuscatedScript = Deobfuscator.deobfuscateScript(script)
|
||||||
|
?: throw Exception("No se pudo desofuscar el script")
|
||||||
|
|
||||||
|
return KEY_REGEX.find(deobfuscatedScript)?.groupValues?.get(1)
|
||||||
|
?: throw Exception("No se pudo encontrar la clave")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
val url: Uri.Builder
|
||||||
|
when {
|
||||||
|
query.isNotBlank() -> {
|
||||||
|
url = Uri.parse("$baseUrl/search")!!.buildUpon()
|
||||||
|
url.appendQueryParameter("q", query)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
url = Uri.parse("$baseUrl/filterList?page=$page")!!.buildUpon()
|
||||||
|
filters.filterIsInstance<UriFilter>()
|
||||||
|
.forEach { it.addToUri(url) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GET(url.toString(), headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
|
return if (listOf("query", "q").any { it in response.request.url.queryParameterNames }) {
|
||||||
|
val searchResult = json.decodeFromString<List<SearchResult>>(response.body.string())
|
||||||
|
MangasPage(
|
||||||
|
searchResult
|
||||||
|
.map {
|
||||||
|
SManga.create().apply {
|
||||||
|
url = getUrlWithoutBaseUrl(itemUrl + it.slug)
|
||||||
|
title = it.name
|
||||||
|
thumbnail_url = "$baseUrl/uploads/manga/${it.slug}/cover/cover_250x350.jpg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
internalMangaParse(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
val document = response.asJsoup()
|
||||||
|
val mangaUrl = document.location().removeSuffix("/")
|
||||||
|
val receivedData = RECEIVED_DATA_REGEX.find(document.html())?.groupValues?.get(1) ?: throw Exception("No se pudo encontrar la lista de capítulos")
|
||||||
|
val unescapedReceivedData = receivedData.unescape()
|
||||||
|
val chapterData = json.decodeFromString<CDT>(unescapedReceivedData)
|
||||||
|
val salt = chapterData.s.decodeHex()
|
||||||
|
|
||||||
|
val unsaltedCipherText = Base64.decode(chapterData.ct, Base64.DEFAULT)
|
||||||
|
val cipherText = SALTED + salt + unsaltedCipherText
|
||||||
|
|
||||||
|
val decrypted = CryptoAES.decrypt(Base64.encodeToString(cipherText, Base64.DEFAULT), key).ifEmpty {
|
||||||
|
key = getKey()
|
||||||
|
CryptoAES.decrypt(Base64.encodeToString(cipherText, Base64.DEFAULT), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
val unescaped = decrypted.unescapeJava().removeSurrounding("\"").unescape()
|
||||||
|
|
||||||
|
val chapters = json.decodeFromString<List<Chapter>>(unescaped)
|
||||||
|
|
||||||
|
return chapters.map {
|
||||||
|
SChapter.create().apply {
|
||||||
|
name = "Capítulo ${it.number}: ${it.name}"
|
||||||
|
date_upload = it.createdAt.parseDate()
|
||||||
|
setUrlWithoutDomain("$mangaUrl/${it.slug}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.unescape(): String {
|
||||||
|
return UNESCAPE_REGEX.replace(this, "$1")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.unescapeJava(): String {
|
||||||
|
var escaped = this
|
||||||
|
if (!escaped.contains("\\u")) return escaped
|
||||||
|
val builder = StringBuilder()
|
||||||
|
var position = escaped.indexOf("\\u")
|
||||||
|
while (position != -1) {
|
||||||
|
if (position != 0) {
|
||||||
|
builder.append(escaped, 0, position)
|
||||||
|
}
|
||||||
|
val token = escaped.substring(position + 2, position + 6)
|
||||||
|
escaped = escaped.substring(position + 6)
|
||||||
|
builder.append(Integer.parseInt(token, 16).toChar())
|
||||||
|
position = escaped.indexOf("\\u")
|
||||||
|
}
|
||||||
|
builder.append(escaped)
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.parseDate(): Long {
|
||||||
|
return dateFormat.parse(this)?.time ?: 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.decodeHex(): ByteArray {
|
||||||
|
check(length % 2 == 0) { "Must have an even length" }
|
||||||
|
|
||||||
|
return chunked(2)
|
||||||
|
.map { it.toInt(16).toByte() }
|
||||||
|
.toByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val UNESCAPE_REGEX = """\\(.)""".toRegex()
|
||||||
|
val RECEIVED_DATA_REGEX = """receivedData\s*=\s*["'](.*)["']\s*;""".toRegex()
|
||||||
|
val KEY_REGEX = """decrypt\(.*'(.*)'.*\)""".toRegex()
|
||||||
|
val SALTED = "Salted__".toByteArray(Charsets.UTF_8)
|
||||||
|
|
||||||
|
val dateFormat by lazy {
|
||||||
|
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.es.mangasin
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CDT(val ct: String, val s: String)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Chapter(
|
||||||
|
val slug: String,
|
||||||
|
val name: String,
|
||||||
|
val number: String,
|
||||||
|
@SerialName("created_at") val createdAt: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SearchResult(
|
||||||
|
@SerialName("value") val name: String,
|
||||||
|
@SerialName("data") val slug: String,
|
||||||
|
)
|
|
@ -9,7 +9,7 @@ import okhttp3.Request
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class NhatTruyen : WPComics("NhatTruyen", "https://nhattruyenmax.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
class NhatTruyen : WPComics("NhatTruyen", "https://nhattruyento.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/the-loai?keyword=$query&page=$page", headers)
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/the-loai?keyword=$query&page=$page", headers)
|
||||||
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
|
||||||
|
|
|
@ -5,7 +5,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.Companion.toHttpUrlOrNull
|
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
|
||||||
|
@ -38,7 +38,7 @@ class Komikita : ZManga(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrlOrNull()!!.newBuilder()
|
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrl().newBuilder()
|
||||||
url.addQueryParameter("s", query)
|
url.addQueryParameter("s", query)
|
||||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
|
@ -51,13 +51,13 @@ class Komikita : ZManga(
|
||||||
is ProjectFilter -> {
|
is ProjectFilter -> {
|
||||||
if (filter.toUriPart() == "project-filter-on") {
|
if (filter.toUriPart() == "project-filter-on") {
|
||||||
url =
|
url =
|
||||||
"$baseUrl$projectPageString/page/$page".toHttpUrlOrNull()!!.newBuilder()
|
"$baseUrl$projectPageString/page/$page".toHttpUrl().newBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList(): FilterList {
|
override fun getFilterList(): FilterList {
|
||||||
|
|
|
@ -5,7 +5,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.Companion.toHttpUrlOrNull
|
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
|
||||||
|
@ -32,20 +32,20 @@ class KomikPlay : ZManga("KomikPlay", "https://komikplay.com", "id", SimpleDateF
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrlOrNull()!!.newBuilder()
|
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrl().newBuilder()
|
||||||
url.addQueryParameter("s", query)
|
url.addQueryParameter("s", query)
|
||||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
// if site has project page, default value "hasProjectPage" = false
|
// if site has project page, default value "hasProjectPage" = false
|
||||||
is ProjectFilter -> {
|
is ProjectFilter -> {
|
||||||
if (filter.toUriPart() == "project-filter-on") {
|
if (filter.toUriPart() == "project-filter-on") {
|
||||||
url = "$baseUrl$projectPageString/page/$page".toHttpUrlOrNull()!!.newBuilder()
|
url = "$baseUrl$projectPageString/page/$page".toHttpUrl().newBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList() = FilterList(
|
||||||
|
|
|
@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
@ -58,20 +58,20 @@ class SekteKomik : ZManga("Sekte Komik", "https://sektekomik.com", "id") {
|
||||||
|
|
||||||
// search
|
// search
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrlOrNull()!!.newBuilder()
|
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrl().newBuilder()
|
||||||
url.addQueryParameter("s", query)
|
url.addQueryParameter("s", query)
|
||||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
// if site has project page, default value "hasProjectPage" = false
|
// if site has project page, default value "hasProjectPage" = false
|
||||||
is ProjectFilter -> {
|
is ProjectFilter -> {
|
||||||
if (filter.toUriPart() == "project-filter-on") {
|
if (filter.toUriPart() == "project-filter-on") {
|
||||||
url = "$baseUrl$projectPageString/${pagePathSegment(page)}".toHttpUrlOrNull()!!.newBuilder()
|
url = "$baseUrl$projectPageString/${pagePathSegment(page)}".toHttpUrl().newBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = "div.flexbox2-item"
|
override fun searchMangaSelector() = "div.flexbox2-item"
|
||||||
|
|
|
@ -42,7 +42,7 @@ abstract class BakaManga(
|
||||||
return if (query.isNotEmpty()) {
|
return if (query.isNotEmpty()) {
|
||||||
val url = "$baseUrl/page/$page".toHttpUrl().newBuilder()
|
val url = "$baseUrl/page/$page".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("s", query)
|
.addQueryParameter("s", query)
|
||||||
GET(url.toString(), headers)
|
GET(url.build(), headers)
|
||||||
} else {
|
} else {
|
||||||
val filterList = if (filters.isEmpty()) getFilterList() else filters
|
val filterList = if (filters.isEmpty()) getFilterList() else filters
|
||||||
val genreFilter = filterList.find { it is GenreFilter } as GenreFilter
|
val genreFilter = filterList.find { it is GenreFilter } as GenreFilter
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -59,7 +59,7 @@ 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 = url.toHttpUrlOrNull()!!
|
val httpUrl = url.toHttpUrl()
|
||||||
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 {
|
||||||
|
@ -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")) {
|
||||||
stackItem.url.toHttpUrlOrNull()!!.newBuilder().addQueryParameter("sort", currentSortingMode).toString()
|
stackItem.url.toHttpUrl().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 = "$baseUrl/search?q=$query".toHttpUrlOrNull()!!.newBuilder().apply {
|
val url = "$baseUrl/search?q=$query".toHttpUrl().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 = "$baseUrl/comics/${albumFilter.pathSegments}".toHttpUrlOrNull()!!.newBuilder().apply {
|
val url = "$baseUrl/comics/${albumFilter.pathSegments}".toHttpUrl().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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ abstract class FansubsCat(
|
||||||
if (query.isNotBlank()) {
|
if (query.isNotBlank()) {
|
||||||
builder.addQueryParameter("query", query)
|
builder.addQueryParameter("query", query)
|
||||||
}
|
}
|
||||||
return GET(builder.toString(), headers)
|
return GET(builder.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage = parseMangaFromJson(response)
|
override fun searchMangaParse(response: Response): MangasPage = parseMangaFromJson(response)
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -65,7 +65,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 = "$baseUrl/$requestPath?".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/$requestPath?".toHttpUrl().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 ->
|
||||||
|
@ -101,7 +101,7 @@ abstract class FMReader(
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request =
|
override fun latestUpdatesRequest(page: Int): Request =
|
||||||
|
|
|
@ -8,7 +8,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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -58,7 +58,7 @@ abstract class Gattsu(
|
||||||
override fun latestUpdatesNextPageSelector(): String = "ul.paginacao li.next > a"
|
override fun latestUpdatesNextPageSelector(): String = "ul.paginacao li.next > a"
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val searchUrl = "$baseUrl/page/$page/".toHttpUrlOrNull()!!.newBuilder()
|
val searchUrl = "$baseUrl/page/$page/".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("s", query)
|
.addQueryParameter("s", query)
|
||||||
.addQueryParameter("post_type", "post")
|
.addQueryParameter("post_type", "post")
|
||||||
.toString()
|
.toString()
|
||||||
|
|
|
@ -21,6 +21,7 @@ import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Call
|
import okhttp3.Call
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
@ -92,10 +93,10 @@ abstract class GigaViewer(
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
if (query.isNotEmpty()) {
|
if (query.isNotEmpty()) {
|
||||||
val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/search".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("q", query)
|
.addQueryParameter("q", query)
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
val collectionSelected = (filters[0] as CollectionFilter).selected
|
val collectionSelected = (filters[0] as CollectionFilter).selected
|
||||||
|
@ -138,7 +139,7 @@ abstract class GigaViewer(
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val readableProductList = document.selectFirst("div.js-readable-product-list")!!
|
val readableProductList = document.selectFirst("div.js-readable-product-list")!!
|
||||||
val firstListEndpoint = readableProductList.attr("data-first-list-endpoint")
|
val firstListEndpoint = readableProductList.attr("data-first-list-endpoint")
|
||||||
.toHttpUrlOrNull()!!
|
.toHttpUrl()
|
||||||
val latestListEndpoint = readableProductList.attr("data-latest-list-endpoint")
|
val latestListEndpoint = readableProductList.attr("data-latest-list-endpoint")
|
||||||
.toHttpUrlOrNull() ?: firstListEndpoint
|
.toHttpUrlOrNull() ?: firstListEndpoint
|
||||||
val numberSince = latestListEndpoint.queryParameter("number_since")!!.toFloat()
|
val numberSince = latestListEndpoint.queryParameter("number_since")!!.toFloat()
|
||||||
|
@ -214,7 +215,7 @@ abstract class GigaViewer(
|
||||||
return episode.readableProduct.pageStructure.pages
|
return episode.readableProduct.pageStructure.pages
|
||||||
.filter { it.type == "main" }
|
.filter { it.type == "main" }
|
||||||
.mapIndexed { i, page ->
|
.mapIndexed { i, page ->
|
||||||
val imageUrl = page.src.toHttpUrlOrNull()!!.newBuilder()
|
val imageUrl = page.src.toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("width", page.width.toString())
|
.addQueryParameter("width", page.width.toString())
|
||||||
.addQueryParameter("height", page.height.toString())
|
.addQueryParameter("height", page.height.toString())
|
||||||
.toString()
|
.toString()
|
||||||
|
|
|
@ -15,7 +15,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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -101,7 +101,7 @@ abstract class GroupLe(
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url =
|
val url =
|
||||||
"$baseUrl/search/advancedResults?offset=${50 * (page - 1)}".toHttpUrlOrNull()!!
|
"$baseUrl/search/advancedResults?offset=${50 * (page - 1)}".toHttpUrl()
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
if (query.isNotEmpty()) {
|
if (query.isNotEmpty()) {
|
||||||
url.addQueryParameter("q", query)
|
url.addQueryParameter("q", query)
|
||||||
|
@ -286,11 +286,7 @@ abstract class GroupLe(
|
||||||
|
|
||||||
val html = document.html()
|
val html = document.html()
|
||||||
|
|
||||||
var readerMark = "rm_h.initReader( ["
|
var readerMark = "rm_h.readerDoInit(["
|
||||||
|
|
||||||
if (!html.contains(readerMark)) {
|
|
||||||
readerMark = "rm_h.readerInit( 0,["
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!html.contains(readerMark)) {
|
if (!html.contains(readerMark)) {
|
||||||
if (document.select(".input-lg").isNotEmpty() || (document.select(".user-avatar").isNullOrEmpty() && document.select("img.logo").first()?.attr("title")?.contains("Allhentai") == true)) {
|
if (document.select(".input-lg").isNotEmpty() || (document.select(".user-avatar").isNullOrEmpty() && document.select("img.logo").first()?.attr("title")?.contains("Allhentai") == true)) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ class GroupLeGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
override val themeClass = "GroupLe"
|
override val themeClass = "GroupLe"
|
||||||
|
|
||||||
override val baseVersionCode = 20
|
override val baseVersionCode = 21
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang("ReadManga", "https://readmanga.live", "ru", overrideVersionCode = 46),
|
SingleLang("ReadManga", "https://readmanga.live", "ru", overrideVersionCode = 46),
|
||||||
|
|
|
@ -24,7 +24,7 @@ import kotlinx.serialization.json.jsonArray
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import kotlinx.serialization.json.put
|
import kotlinx.serialization.json.put
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
@ -79,7 +79,7 @@ abstract class HentaiHand(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
val url = "$baseUrl/api/comics".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/api/comics".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("page", page.toString())
|
.addQueryParameter("page", page.toString())
|
||||||
.addQueryParameter("sort", "popularity")
|
.addQueryParameter("sort", "popularity")
|
||||||
.addQueryParameter("order", "desc")
|
.addQueryParameter("order", "desc")
|
||||||
|
@ -88,7 +88,7 @@ abstract class HentaiHand(
|
||||||
url.addQueryParameter("languages[${-index - 1}]", it.toString())
|
url.addQueryParameter("languages[${-index - 1}]", it.toString())
|
||||||
}
|
}
|
||||||
// if (altLangId != null) url.addQueryParameter("languages", altLangId.toString())
|
// if (altLangId != null) url.addQueryParameter("languages", altLangId.toString())
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Latest
|
// Latest
|
||||||
|
@ -96,7 +96,7 @@ abstract class HentaiHand(
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
|
override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
val url = "$baseUrl/api/comics".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/api/comics".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("page", page.toString())
|
.addQueryParameter("page", page.toString())
|
||||||
.addQueryParameter("sort", "uploaded_at")
|
.addQueryParameter("sort", "uploaded_at")
|
||||||
.addQueryParameter("order", "desc")
|
.addQueryParameter("order", "desc")
|
||||||
|
@ -104,7 +104,7 @@ abstract class HentaiHand(
|
||||||
hhLangId.forEachIndexed { index, it ->
|
hhLangId.forEachIndexed { index, it ->
|
||||||
url.addQueryParameter("languages[${-index - 1}]", it.toString())
|
url.addQueryParameter("languages[${-index - 1}]", it.toString())
|
||||||
}
|
}
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
|
@ -130,7 +130,7 @@ abstract class HentaiHand(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url = "$baseUrl/api/comics".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/api/comics".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("page", page.toString())
|
.addQueryParameter("page", page.toString())
|
||||||
.addQueryParameter("q", query)
|
.addQueryParameter("q", query)
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ abstract class HentaiHand(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Details
|
// Details
|
||||||
|
|
|
@ -31,7 +31,7 @@ import kotlinx.serialization.json.jsonArray
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -544,7 +544,7 @@ abstract class LibGroup(
|
||||||
val resBody = tokenResponse.body.string()
|
val resBody = tokenResponse.body.string()
|
||||||
csrfToken = "_token\" content=\"(.*)\"".toRegex().find(resBody)!!.groups[1]!!.value
|
csrfToken = "_token\" content=\"(.*)\"".toRegex().find(resBody)!!.groups[1]!!.value
|
||||||
}
|
}
|
||||||
val url = "$baseUrl/filterlist?page=$page&chapters[min]=1".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/filterlist?page=$page&chapters[min]=1".toHttpUrl().newBuilder()
|
||||||
if (query.isNotEmpty()) {
|
if (query.isNotEmpty()) {
|
||||||
url.addQueryParameter("name", query)
|
url.addQueryParameter("name", query)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.CacheControl
|
import okhttp3.CacheControl
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -209,7 +209,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 = "$baseUrl/${searchPage(page)}".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/${searchPage(page)}".toHttpUrl().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 ->
|
||||||
|
@ -257,7 +257,7 @@ abstract class Madara(
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open val authorFilterTitle: String = when (lang) {
|
protected open val authorFilterTitle: String = when (lang) {
|
||||||
|
|
|
@ -152,7 +152,7 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("I Love Manhwa", "https://ilovemanhwa.com", "en", isNsfw = true),
|
SingleLang("I Love Manhwa", "https://ilovemanhwa.com", "en", isNsfw = true),
|
||||||
SingleLang("Illusion Scan", "https://illusionscan.com", "pt-BR", isNsfw = true),
|
SingleLang("Illusion Scan", "https://illusionscan.com", "pt-BR", isNsfw = true),
|
||||||
SingleLang("Immortal Updates", "https://immortalupdates.com", "en", overrideVersionCode = 6),
|
SingleLang("Immortal Updates", "https://immortalupdates.com", "en", overrideVersionCode = 6),
|
||||||
SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans", overrideVersionCode = 1),
|
SingleLang("Império Scans", "https://neroxus.com.br", "pt-BR", className = "ImperioScans", overrideVersionCode = 2),
|
||||||
SingleLang("InfraFandub", "https://infrafandub.com", "es", overrideVersionCode = 1),
|
SingleLang("InfraFandub", "https://infrafandub.com", "es", overrideVersionCode = 1),
|
||||||
SingleLang("Inmortal Scan", "https://manga.mundodrama.site", "es"),
|
SingleLang("Inmortal Scan", "https://manga.mundodrama.site", "es"),
|
||||||
SingleLang("InstaManhwa", "https://www.instamanhwa.com", "en", isNsfw = true, overrideVersionCode = 1),
|
SingleLang("InstaManhwa", "https://www.instamanhwa.com", "en", isNsfw = true, overrideVersionCode = 1),
|
||||||
|
@ -414,6 +414,7 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("ReadFreeComics", "https://readfreecomics.com", "en"),
|
SingleLang("ReadFreeComics", "https://readfreecomics.com", "en"),
|
||||||
SingleLang("ReadMangaFree", "https://readmangafree.net", "en", isNsfw = true),
|
SingleLang("ReadMangaFree", "https://readmangafree.net", "en", isNsfw = true),
|
||||||
SingleLang("ReadManhua", "https://readmanhua.net", "en", overrideVersionCode = 2),
|
SingleLang("ReadManhua", "https://readmanhua.net", "en", overrideVersionCode = 2),
|
||||||
|
SingleLang("Reset Scans", "https://reset-scans.us", "en"),
|
||||||
SingleLang("Rh2PlusManga", "https://www.rh2plusmanga.com", "th", isNsfw = true, overrideVersionCode = 5),
|
SingleLang("Rh2PlusManga", "https://www.rh2plusmanga.com", "th", isNsfw = true, overrideVersionCode = 5),
|
||||||
SingleLang("RichtoScan", "https://richtoscan.com", "es"),
|
SingleLang("RichtoScan", "https://richtoscan.com", "es"),
|
||||||
SingleLang("Rightdark Scan", "https://rightdark-scan.com", "es"),
|
SingleLang("Rightdark Scan", "https://rightdark-scan.com", "es"),
|
||||||
|
@ -429,6 +430,7 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("Scan Hentai Menu", "https://scan.hentai.menu", "fr", isNsfw = true, overrideVersionCode = 1),
|
SingleLang("Scan Hentai Menu", "https://scan.hentai.menu", "fr", isNsfw = true, overrideVersionCode = 1),
|
||||||
SingleLang("Scantrad-VF", "https://scantrad-vf.co", "fr", className = "ScantradVF"),
|
SingleLang("Scantrad-VF", "https://scantrad-vf.co", "fr", className = "ScantradVF"),
|
||||||
SingleLang("Sdl scans", "https://sdlscans.com", "es", className = "SdlScans"),
|
SingleLang("Sdl scans", "https://sdlscans.com", "es", className = "SdlScans"),
|
||||||
|
SingleLang("Setsu Scans", "https://setsuscans.com", "en"),
|
||||||
SingleLang("Shadowtrad", "https://shadowtrad.net", "fr"),
|
SingleLang("Shadowtrad", "https://shadowtrad.net", "fr"),
|
||||||
SingleLang("ShavelProiection", "https://www.shavelproiection.com", "it", true),
|
SingleLang("ShavelProiection", "https://www.shavelproiection.com", "it", true),
|
||||||
SingleLang("Shayami", "https://shayami.com", "es"),
|
SingleLang("Shayami", "https://shayami.com", "es"),
|
||||||
|
@ -459,7 +461,6 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("TonizuToon", "https://tonizu.com", "tr", isNsfw = true, overrideVersionCode = 1),
|
SingleLang("TonizuToon", "https://tonizu.com", "tr", isNsfw = true, overrideVersionCode = 1),
|
||||||
SingleLang("ToonChill", "https://toonchill.com", "en", overrideVersionCode = 1),
|
SingleLang("ToonChill", "https://toonchill.com", "en", overrideVersionCode = 1),
|
||||||
SingleLang("ToonGod", "https://www.toongod.org", "en", isNsfw = true, overrideVersionCode = 5),
|
SingleLang("ToonGod", "https://www.toongod.org", "en", isNsfw = true, overrideVersionCode = 5),
|
||||||
SingleLang("Toonily.net", "https://toonily.net", "en", isNsfw = true, className = "Toonilynet", overrideVersionCode = 2),
|
|
||||||
SingleLang("Toonily", "https://toonily.com", "en", isNsfw = true, overrideVersionCode = 11),
|
SingleLang("Toonily", "https://toonily.com", "en", isNsfw = true, overrideVersionCode = 11),
|
||||||
SingleLang("Toonizy", "https://toonizy.com", "en", isNsfw = true),
|
SingleLang("Toonizy", "https://toonizy.com", "en", isNsfw = true),
|
||||||
SingleLang("ToonMany", "https://toonmany.com", "en", isNsfw = true),
|
SingleLang("ToonMany", "https://toonmany.com", "en", isNsfw = true),
|
||||||
|
|
|
@ -114,7 +114,7 @@ abstract class MadTheme(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector(): String = ".book-detailed-item"
|
override fun searchMangaSelector(): String = ".book-detailed-item"
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
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 = baseUrl.toHttpUrlOrNull()!!.newBuilder()
|
val url = baseUrl.toHttpUrl().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())
|
||||||
|
@ -113,7 +113,7 @@ abstract class MangaBox(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GET(url.toString(), headers)
|
GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ abstract class MangaBox(
|
||||||
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 =
|
scanlator =
|
||||||
it.attr("abs:href").toHttpUrlOrNull()!!.host // show where chapters are actually from
|
it.attr("abs:href").toHttpUrl().host // show where chapters are actually from
|
||||||
}
|
}
|
||||||
date_upload = parseChapterDate(element.selectDateFromElement().text(), scanlator!!) ?: 0
|
date_upload = parseChapterDate(element.selectDateFromElement().text(), scanlator!!) ?: 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ abstract class MangaHub(
|
||||||
|
|
||||||
// search
|
// search
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url = "$baseUrl/search/page/$page".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/search/page/$page".toHttpUrl().newBuilder()
|
||||||
url.addQueryParameter("q", query)
|
url.addQueryParameter("q", query)
|
||||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
|
@ -178,7 +178,7 @@ abstract class MangaHub(
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = popularMangaSelector()
|
override fun searchMangaSelector() = popularMangaSelector()
|
||||||
|
|
|
@ -31,6 +31,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("BirdManga", "https://birdmanga.com", "en"),
|
SingleLang("BirdManga", "https://birdmanga.com", "en"),
|
||||||
SingleLang("Boosei", "https://boosei.net", "id", overrideVersionCode = 2),
|
SingleLang("Boosei", "https://boosei.net", "id", overrideVersionCode = 2),
|
||||||
SingleLang("Cartel de Manhwas", "https://carteldemanhwas.com", "es", overrideVersionCode = 5),
|
SingleLang("Cartel de Manhwas", "https://carteldemanhwas.com", "es", overrideVersionCode = 5),
|
||||||
|
SingleLang("Constellar Scans", "https://constellarcomic.com", "en", isNsfw = true, overrideVersionCode = 16),
|
||||||
SingleLang("Cosmic Scans", "https://cosmic-scans.com", "en", overrideVersionCode = 2),
|
SingleLang("Cosmic Scans", "https://cosmic-scans.com", "en", overrideVersionCode = 2),
|
||||||
SingleLang("CosmicScans.id", "https://cosmicscans.id", "id", overrideVersionCode = 3, className = "CosmicScansID"),
|
SingleLang("CosmicScans.id", "https://cosmicscans.id", "id", overrideVersionCode = 3, className = "CosmicScansID"),
|
||||||
SingleLang("Cypher Scans", "https://cypherscans.xyz", "en"),
|
SingleLang("Cypher Scans", "https://cypherscans.xyz", "en"),
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -78,7 +78,7 @@ abstract class MangaWorld(
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage = searchMangaParse(response)
|
override fun latestUpdatesParse(response: Response): MangasPage = searchMangaParse(response)
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url = "$baseUrl/archive?page=$page".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/archive?page=$page".toHttpUrl().newBuilder()
|
||||||
url.addQueryParameter("keyword", query)
|
url.addQueryParameter("keyword", query)
|
||||||
|
|
||||||
filters.forEach { filter ->
|
filters.forEach { filter ->
|
||||||
|
@ -100,7 +100,7 @@ abstract class MangaWorld(
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
|
|
@ -186,14 +186,14 @@ abstract class MMRCMS(
|
||||||
.let { elements ->
|
.let { elements ->
|
||||||
when {
|
when {
|
||||||
// List layout (most sources)
|
// List layout (most sources)
|
||||||
elements.select("a").firstOrNull()?.hasText() == true -> elements.map { latestUpdatesFromElement(it, "a") }
|
elements.select("a[href]").firstOrNull()?.hasText() == true -> elements.map { latestUpdatesFromElement(it, "a[href]") }
|
||||||
// Grid layout (e.g. MangaID)
|
// Grid layout (e.g. MangaID)
|
||||||
else -> document.select(gridLatestUpdatesSelector()).map { gridLatestUpdatesFromElement(it) }
|
else -> document.select(gridLatestUpdatesSelector()).map { gridLatestUpdatesFromElement(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
|
|
||||||
return MangasPage(mangas, document.select(latestUpdatesNextPageSelector()) != null)
|
return MangasPage(mangas, document.selectFirst(latestUpdatesNextPageSelector()) != null)
|
||||||
}
|
}
|
||||||
private fun latestUpdatesSelector() = "div.mangalist div.manga-item"
|
private fun latestUpdatesSelector() = "div.mangalist div.manga-item"
|
||||||
private fun latestUpdatesNextPageSelector() = "a[rel=next]"
|
private fun latestUpdatesNextPageSelector() = "a[rel=next]"
|
||||||
|
|
|
@ -9,7 +9,7 @@ class MMRCMSGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
override val themeClass = "MMRCMS"
|
override val themeClass = "MMRCMS"
|
||||||
|
|
||||||
override val baseVersionCode = 6
|
override val baseVersionCode = 7
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang("مانجا اون لاين", "https://onma.top", "ar", className = "onma"),
|
SingleLang("مانجا اون لاين", "https://onma.top", "ar", className = "onma"),
|
||||||
|
@ -19,6 +19,7 @@ class MMRCMSGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("Scan VF", "https://www.scan-vf.net", "fr", overrideVersionCode = 1),
|
SingleLang("Scan VF", "https://www.scan-vf.net", "fr", overrideVersionCode = 1),
|
||||||
SingleLang("Komikid", "https://www.komikid.com", "id"),
|
SingleLang("Komikid", "https://www.komikid.com", "id"),
|
||||||
SingleLang("Mangadoor", "https://mangadoor.com", "es", overrideVersionCode = 1),
|
SingleLang("Mangadoor", "https://mangadoor.com", "es", overrideVersionCode = 1),
|
||||||
|
SingleLang("Mangas.in", "https://mangas.in", "es", isNsfw = true, className = "MangasIn", overrideVersionCode = 1),
|
||||||
SingleLang("Utsukushii", "https://manga.utsukushii-bg.com", "bg", overrideVersionCode = 1),
|
SingleLang("Utsukushii", "https://manga.utsukushii-bg.com", "bg", overrideVersionCode = 1),
|
||||||
SingleLang("Phoenix-Scans", "https://phoenix-scans.pl", "pl", className = "PhoenixScans", overrideVersionCode = 1),
|
SingleLang("Phoenix-Scans", "https://phoenix-scans.pl", "pl", className = "PhoenixScans", overrideVersionCode = 1),
|
||||||
SingleLang("Lelscan-VF", "https://lelscanvf.cc", "fr", className = "LelscanVF", overrideVersionCode = 2),
|
SingleLang("Lelscan-VF", "https://lelscanvf.cc", "fr", className = "LelscanVF", overrideVersionCode = 2),
|
||||||
|
|
|
@ -14,7 +14,7 @@ object SourceData {
|
||||||
"https://www.komikid.com" -> """{"name":"Komikid","base_url":"https://www.komikid.com","supports_latest":true,"item_url":"https://www.komikid.com/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Fantasy"},{"id":"7","name":"Gender Bender"},{"id":"8","name":"Historical"},{"id":"9","name":"Horror"},{"id":"10","name":"Josei"},{"id":"11","name":"Martial Arts"},{"id":"12","name":"Mature"},{"id":"13","name":"Mecha"},{"id":"14","name":"Mystery"},{"id":"15","name":"One Shot"},{"id":"16","name":"Psychological"},{"id":"17","name":"Romance"},{"id":"18","name":"School Life"},{"id":"19","name":"Sci-fi"},{"id":"20","name":"Seinen"},{"id":"21","name":"Shoujo"},{"id":"22","name":"Shoujo Ai"},{"id":"23","name":"Shounen"},{"id":"24","name":"Shounen Ai"},{"id":"25","name":"Slice of Life"},{"id":"26","name":"Sports"},{"id":"27","name":"Supernatural"},{"id":"28","name":"Tragedy"},{"id":"29","name":"Yaoi"},{"id":"30","name":"Yuri"}]}"""
|
"https://www.komikid.com" -> """{"name":"Komikid","base_url":"https://www.komikid.com","supports_latest":true,"item_url":"https://www.komikid.com/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Fantasy"},{"id":"7","name":"Gender Bender"},{"id":"8","name":"Historical"},{"id":"9","name":"Horror"},{"id":"10","name":"Josei"},{"id":"11","name":"Martial Arts"},{"id":"12","name":"Mature"},{"id":"13","name":"Mecha"},{"id":"14","name":"Mystery"},{"id":"15","name":"One Shot"},{"id":"16","name":"Psychological"},{"id":"17","name":"Romance"},{"id":"18","name":"School Life"},{"id":"19","name":"Sci-fi"},{"id":"20","name":"Seinen"},{"id":"21","name":"Shoujo"},{"id":"22","name":"Shoujo Ai"},{"id":"23","name":"Shounen"},{"id":"24","name":"Shounen Ai"},{"id":"25","name":"Slice of Life"},{"id":"26","name":"Sports"},{"id":"27","name":"Supernatural"},{"id":"28","name":"Tragedy"},{"id":"29","name":"Yaoi"},{"id":"30","name":"Yuri"}]}"""
|
||||||
"http://azbivo.webd.pro" -> """{"name":"Nikushima","base_url":"http://azbivo.webd.pro","supports_latest":false,"item_url":"\u003chtml\u003e \n \u003chead\u003e \n \u003cmeta http-equiv\u003d\"Content-Language\" content\u003d\"pl\"\u003e \n \u003cmeta http-equiv name\u003d\"pragma\" content\u003d\"no-cache\"\u003e \n \u003clink href\u003d\"style/style.css\" rel\u003d\"stylesheet\" type\u003d\"text/css\"\u003e \n \u003cmeta http-equiv\u003d\"Refresh\" content\u003d\"0; url\u003dhttps://www.webd.pl/_errnda.php?utm_source\u003dwn07\u0026amp;utm_medium\u003dwww\u0026amp;utm_campaign\u003dblock\"\u003e \n \u003cmeta name\u003d\"Robots\" content\u003d\"index, follow\"\u003e \n \u003cmeta name\u003d\"revisit-after\" content\u003d\"2 days\"\u003e \n \u003cmeta name\u003d\"rating\" content\u003d\"general\"\u003e \n \u003cmeta name\u003d\"keywords\" content\u003d\"STRONA ZAWIESZONA, WEBD, DOMENY, DOMENA, HOSTING, SERWER, INTERNET, PHP, MySQL, FTP, WEBMASTER, SERWERY WIRTUALNE, WWW, KONTO, MAIL, POCZTA, E-MAIL, NET, .COM, .ORG, TANIE, PHP+MySQL, DOMENY, DOMENA, HOSTING, SERWER, INTERNET, PHP, MySQL, FTP, WEBMASTER, SERWERY WIRTUALNE, WWW, KONTO, MAIL, POCZTA, E-MAIL, DOMENY, DOMENA, NET, .COM, .ORG, TANIE, PHP+MySQL, HOSTING, SERWER, INTERNET, PHP, MySQL, FTP, WEBMASTER, SERWERY WIRTUALNE, WWW, KONTO, MAIL, POCZTA, E-MAIL, NET, .COM, .ORG, TANIE, PHP+MySQL\"\u003e \n \u003cmeta name\u003d\"description\" content\u003d\"STRONA ZAWIESZONA - Oferujemy profesjonalny hosting z PHP + MySQL, rejestrujemy domeny. Sprawdz nasz hosting i przetestuj nasze serwery. Kupuj tanio domeny i serwery!\"\u003e \n \u003ctitle\u003eSTRONA ZAWIESZONA - WEBD.PL - Tw<54>j profesjonalny hosting za jedyne 4.99PLN! Serwery z PHP+MySQL, tanie domeny, serwer + domena .pl - taniej sie nie da!\u003c/title\u003e \n \u003cscript type\u003d\"text/javascript\"\u003e\nfunction init() {\n if (!document.getElementById) return\n var imgOriginSrc;\n var imgTemp \u003d new Array();\n var imgarr \u003d document.getElementsByTagName(\u0027img\u0027);\n for (var i \u003d 0; i \u003c imgarr.length; i++) {\n if (imgarr[i].getAttribute(\u0027hsrc\u0027)) {\n imgTemp[i] \u003d new Image();\n imgTemp[i].src \u003d imgarr[i].getAttribute(\u0027hsrc\u0027);\n imgarr[i].onmouseover \u003d function() {\n imgOriginSrc \u003d this.getAttribute(\u0027src\u0027);\n this.setAttribute(\u0027src\u0027,this.getAttribute(\u0027hsrc\u0027))\n }\n imgarr[i].onmouseout \u003d function() {\n this.setAttribute(\u0027src\u0027,imgOriginSrc)\n }\n }\n }\n}\nonload\u003dinit;\n\u003c/script\u003e \n \u003c/head\u003e \n \u003cbody\u003e\n Trwa przekierowanie .... \u0026gt;\u0026gt;\u0026gt;\u0026gt; \u003c!--\n--\u003e \n \u003c/body\u003e\n\u003c/html\u003e/","categories":[]}"""
|
"http://azbivo.webd.pro" -> """{"name":"Nikushima","base_url":"http://azbivo.webd.pro","supports_latest":false,"item_url":"\u003chtml\u003e \n \u003chead\u003e \n \u003cmeta http-equiv\u003d\"Content-Language\" content\u003d\"pl\"\u003e \n \u003cmeta http-equiv name\u003d\"pragma\" content\u003d\"no-cache\"\u003e \n \u003clink href\u003d\"style/style.css\" rel\u003d\"stylesheet\" type\u003d\"text/css\"\u003e \n \u003cmeta http-equiv\u003d\"Refresh\" content\u003d\"0; url\u003dhttps://www.webd.pl/_errnda.php?utm_source\u003dwn07\u0026amp;utm_medium\u003dwww\u0026amp;utm_campaign\u003dblock\"\u003e \n \u003cmeta name\u003d\"Robots\" content\u003d\"index, follow\"\u003e \n \u003cmeta name\u003d\"revisit-after\" content\u003d\"2 days\"\u003e \n \u003cmeta name\u003d\"rating\" content\u003d\"general\"\u003e \n \u003cmeta name\u003d\"keywords\" content\u003d\"STRONA ZAWIESZONA, WEBD, DOMENY, DOMENA, HOSTING, SERWER, INTERNET, PHP, MySQL, FTP, WEBMASTER, SERWERY WIRTUALNE, WWW, KONTO, MAIL, POCZTA, E-MAIL, NET, .COM, .ORG, TANIE, PHP+MySQL, DOMENY, DOMENA, HOSTING, SERWER, INTERNET, PHP, MySQL, FTP, WEBMASTER, SERWERY WIRTUALNE, WWW, KONTO, MAIL, POCZTA, E-MAIL, DOMENY, DOMENA, NET, .COM, .ORG, TANIE, PHP+MySQL, HOSTING, SERWER, INTERNET, PHP, MySQL, FTP, WEBMASTER, SERWERY WIRTUALNE, WWW, KONTO, MAIL, POCZTA, E-MAIL, NET, .COM, .ORG, TANIE, PHP+MySQL\"\u003e \n \u003cmeta name\u003d\"description\" content\u003d\"STRONA ZAWIESZONA - Oferujemy profesjonalny hosting z PHP + MySQL, rejestrujemy domeny. Sprawdz nasz hosting i przetestuj nasze serwery. Kupuj tanio domeny i serwery!\"\u003e \n \u003ctitle\u003eSTRONA ZAWIESZONA - WEBD.PL - Tw<54>j profesjonalny hosting za jedyne 4.99PLN! Serwery z PHP+MySQL, tanie domeny, serwer + domena .pl - taniej sie nie da!\u003c/title\u003e \n \u003cscript type\u003d\"text/javascript\"\u003e\nfunction init() {\n if (!document.getElementById) return\n var imgOriginSrc;\n var imgTemp \u003d new Array();\n var imgarr \u003d document.getElementsByTagName(\u0027img\u0027);\n for (var i \u003d 0; i \u003c imgarr.length; i++) {\n if (imgarr[i].getAttribute(\u0027hsrc\u0027)) {\n imgTemp[i] \u003d new Image();\n imgTemp[i].src \u003d imgarr[i].getAttribute(\u0027hsrc\u0027);\n imgarr[i].onmouseover \u003d function() {\n imgOriginSrc \u003d this.getAttribute(\u0027src\u0027);\n this.setAttribute(\u0027src\u0027,this.getAttribute(\u0027hsrc\u0027))\n }\n imgarr[i].onmouseout \u003d function() {\n this.setAttribute(\u0027src\u0027,imgOriginSrc)\n }\n }\n }\n}\nonload\u003dinit;\n\u003c/script\u003e \n \u003c/head\u003e \n \u003cbody\u003e\n Trwa przekierowanie .... \u0026gt;\u0026gt;\u0026gt;\u0026gt; \u003c!--\n--\u003e \n \u003c/body\u003e\n\u003c/html\u003e/","categories":[]}"""
|
||||||
"https://mangadoor.com" -> """{"name":"Mangadoor","base_url":"https://mangadoor.com","supports_latest":true,"item_url":"https://mangadoor.com/manga/","categories":[{"id":"1","name":"Acción"},{"id":"2","name":"Aventura"},{"id":"3","name":"Comedia"},{"id":"4","name":"Drama"},{"id":"5","name":"Ecchi"},{"id":"6","name":"Fantasía"},{"id":"7","name":"Gender Bender"},{"id":"8","name":"Harem"},{"id":"9","name":"Histórico"},{"id":"10","name":"Horror"},{"id":"11","name":"Josei"},{"id":"12","name":"Artes Marciales"},{"id":"13","name":"Maduro"},{"id":"14","name":"Mecha"},{"id":"15","name":"Misterio"},{"id":"16","name":"One Shot"},{"id":"17","name":"Psicológico"},{"id":"18","name":"Romance"},{"id":"19","name":"Escolar"},{"id":"20","name":"Ciencia Ficción"},{"id":"21","name":"Seinen"},{"id":"22","name":"Shoujo"},{"id":"23","name":"Shoujo Ai"},{"id":"24","name":"Shounen"},{"id":"25","name":"Shounen Ai"},{"id":"26","name":"Recuentos de la vida"},{"id":"27","name":"Deportes"},{"id":"28","name":"Supernatural"},{"id":"29","name":"Tragedia"},{"id":"30","name":"Yaoi"},{"id":"31","name":"Yuri"},{"id":"32","name":"Demonios"},{"id":"33","name":"Juegos"},{"id":"34","name":"Policial"},{"id":"35","name":"Militar"},{"id":"36","name":"Thriller"},{"id":"37","name":"Autos"},{"id":"38","name":"Música"},{"id":"39","name":"Vampiros"},{"id":"40","name":"Magia"},{"id":"41","name":"Samurai"},{"id":"42","name":"Boys love"},{"id":"43","name":"Hentai"}]}"""
|
"https://mangadoor.com" -> """{"name":"Mangadoor","base_url":"https://mangadoor.com","supports_latest":true,"item_url":"https://mangadoor.com/manga/","categories":[{"id":"1","name":"Acción"},{"id":"2","name":"Aventura"},{"id":"3","name":"Comedia"},{"id":"4","name":"Drama"},{"id":"5","name":"Ecchi"},{"id":"6","name":"Fantasía"},{"id":"7","name":"Gender Bender"},{"id":"8","name":"Harem"},{"id":"9","name":"Histórico"},{"id":"10","name":"Horror"},{"id":"11","name":"Josei"},{"id":"12","name":"Artes Marciales"},{"id":"13","name":"Maduro"},{"id":"14","name":"Mecha"},{"id":"15","name":"Misterio"},{"id":"16","name":"One Shot"},{"id":"17","name":"Psicológico"},{"id":"18","name":"Romance"},{"id":"19","name":"Escolar"},{"id":"20","name":"Ciencia Ficción"},{"id":"21","name":"Seinen"},{"id":"22","name":"Shoujo"},{"id":"23","name":"Shoujo Ai"},{"id":"24","name":"Shounen"},{"id":"25","name":"Shounen Ai"},{"id":"26","name":"Recuentos de la vida"},{"id":"27","name":"Deportes"},{"id":"28","name":"Supernatural"},{"id":"29","name":"Tragedia"},{"id":"30","name":"Yaoi"},{"id":"31","name":"Yuri"},{"id":"32","name":"Demonios"},{"id":"33","name":"Juegos"},{"id":"34","name":"Policial"},{"id":"35","name":"Militar"},{"id":"36","name":"Thriller"},{"id":"37","name":"Autos"},{"id":"38","name":"Música"},{"id":"39","name":"Vampiros"},{"id":"40","name":"Magia"},{"id":"41","name":"Samurai"},{"id":"42","name":"Boys love"},{"id":"43","name":"Hentai"}]}"""
|
||||||
"https://mangas.in" -> """{"name":"Mangas.pw","base_url":"https://mangas.in","supports_latest":true,"item_url":"https://mangas.in/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"School Life"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Slice of Life"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedy"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"},{"id":"33","name":"Hentai"},{"id":"34","name":"Smut"}]}"""
|
"https://mangas.in" -> """{"name":"Mangas.in","base_url":"https://mangas.in","supports_latest":true,"item_url":"https://mangas.in/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"School Life"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Slice of Life"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedy"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"},{"id":"33","name":"Hentai"},{"id":"34","name":"Smut"}]}"""
|
||||||
"https://manga.utsukushii-bg.com" -> """{"name":"Utsukushii","base_url":"https://manga.utsukushii-bg.com","supports_latest":true,"item_url":"https://manga.utsukushii-bg.com/manga/","categories":[{"id":"1","name":"Екшън"},{"id":"2","name":"Приключенски"},{"id":"3","name":"Комедия"},{"id":"4","name":"Драма"},{"id":"5","name":"Фентъзи"},{"id":"6","name":"Исторически"},{"id":"7","name":"Ужаси"},{"id":"8","name":"Джосей"},{"id":"9","name":"Бойни изкуства"},{"id":"10","name":"Меха"},{"id":"11","name":"Мистерия"},{"id":"12","name":"Самостоятелна/Пилотна глава"},{"id":"13","name":"Психологически"},{"id":"14","name":"Романтика"},{"id":"15","name":"Училищни"},{"id":"16","name":"Научна фантастика"},{"id":"17","name":"Сейнен"},{"id":"18","name":"Шоджо"},{"id":"19","name":"Реализъм"},{"id":"20","name":"Спорт"},{"id":"21","name":"Свръхестествено"},{"id":"22","name":"Трагедия"},{"id":"23","name":"Йокаи"},{"id":"24","name":"Паралелна вселена"},{"id":"25","name":"Супер сили"},{"id":"26","name":"Пародия"},{"id":"27","name":"Шонен"}]}"""
|
"https://manga.utsukushii-bg.com" -> """{"name":"Utsukushii","base_url":"https://manga.utsukushii-bg.com","supports_latest":true,"item_url":"https://manga.utsukushii-bg.com/manga/","categories":[{"id":"1","name":"Екшън"},{"id":"2","name":"Приключенски"},{"id":"3","name":"Комедия"},{"id":"4","name":"Драма"},{"id":"5","name":"Фентъзи"},{"id":"6","name":"Исторически"},{"id":"7","name":"Ужаси"},{"id":"8","name":"Джосей"},{"id":"9","name":"Бойни изкуства"},{"id":"10","name":"Меха"},{"id":"11","name":"Мистерия"},{"id":"12","name":"Самостоятелна/Пилотна глава"},{"id":"13","name":"Психологически"},{"id":"14","name":"Романтика"},{"id":"15","name":"Училищни"},{"id":"16","name":"Научна фантастика"},{"id":"17","name":"Сейнен"},{"id":"18","name":"Шоджо"},{"id":"19","name":"Реализъм"},{"id":"20","name":"Спорт"},{"id":"21","name":"Свръхестествено"},{"id":"22","name":"Трагедия"},{"id":"23","name":"Йокаи"},{"id":"24","name":"Паралелна вселена"},{"id":"25","name":"Супер сили"},{"id":"26","name":"Пародия"},{"id":"27","name":"Шонен"}]}"""
|
||||||
"https://phoenix-scans.pl" -> """{"name":"Phoenix-Scans","base_url":"https://phoenix-scans.pl","supports_latest":true,"item_url":"https://phoenix-scans.pl/manga/","categories":[{"id":"1","name":"Shounen"},{"id":"2","name":"Tragedia"},{"id":"3","name":"Szkolne życie"},{"id":"4","name":"Romans"},{"id":"5","name":"Zagadka"},{"id":"6","name":"Horror"},{"id":"7","name":"Dojrzałe"},{"id":"8","name":"Psychologiczne"},{"id":"9","name":"Przygodowe"},{"id":"10","name":"Akcja"},{"id":"11","name":"Komedia"},{"id":"12","name":"Zboczone"},{"id":"13","name":"Fantasy"},{"id":"14","name":"Harem"},{"id":"15","name":"Historyczne"},{"id":"16","name":"Manhua"},{"id":"17","name":"Manhwa"},{"id":"18","name":"Sztuki walki"},{"id":"19","name":"One shot"},{"id":"20","name":"Sci fi"},{"id":"21","name":"Seinen"},{"id":"22","name":"Shounen ai"},{"id":"23","name":"Spokojne życie"},{"id":"24","name":"Sport"},{"id":"25","name":"Nadprzyrodzone"},{"id":"26","name":"Webtoons"},{"id":"27","name":"Dramat"},{"id":"28","name":"Hentai"},{"id":"29","name":"Mecha"},{"id":"30","name":"Gender Bender"},{"id":"31","name":"Gry"},{"id":"32","name":"Yaoi"}],"tags":[{"id":"aktywne","name":"aktywne"},{"id":"zakonczone","name":"zakończone"},{"id":"porzucone","name":"porzucone"},{"id":"zawieszone","name":"zawieszone"},{"id":"zlicencjonowane","name":"zlicencjonowane"},{"id":"hentai","name":"Hentai"}]}"""
|
"https://phoenix-scans.pl" -> """{"name":"Phoenix-Scans","base_url":"https://phoenix-scans.pl","supports_latest":true,"item_url":"https://phoenix-scans.pl/manga/","categories":[{"id":"1","name":"Shounen"},{"id":"2","name":"Tragedia"},{"id":"3","name":"Szkolne życie"},{"id":"4","name":"Romans"},{"id":"5","name":"Zagadka"},{"id":"6","name":"Horror"},{"id":"7","name":"Dojrzałe"},{"id":"8","name":"Psychologiczne"},{"id":"9","name":"Przygodowe"},{"id":"10","name":"Akcja"},{"id":"11","name":"Komedia"},{"id":"12","name":"Zboczone"},{"id":"13","name":"Fantasy"},{"id":"14","name":"Harem"},{"id":"15","name":"Historyczne"},{"id":"16","name":"Manhua"},{"id":"17","name":"Manhwa"},{"id":"18","name":"Sztuki walki"},{"id":"19","name":"One shot"},{"id":"20","name":"Sci fi"},{"id":"21","name":"Seinen"},{"id":"22","name":"Shounen ai"},{"id":"23","name":"Spokojne życie"},{"id":"24","name":"Sport"},{"id":"25","name":"Nadprzyrodzone"},{"id":"26","name":"Webtoons"},{"id":"27","name":"Dramat"},{"id":"28","name":"Hentai"},{"id":"29","name":"Mecha"},{"id":"30","name":"Gender Bender"},{"id":"31","name":"Gry"},{"id":"32","name":"Yaoi"}],"tags":[{"id":"aktywne","name":"aktywne"},{"id":"zakonczone","name":"zakończone"},{"id":"porzucone","name":"porzucone"},{"id":"zawieszone","name":"zawieszone"},{"id":"zlicencjonowane","name":"zlicencjonowane"},{"id":"hentai","name":"Hentai"}]}"""
|
||||||
"https://lelscanvf.cc" -> """{"name":"Lelscan-VF","base_url":"https://lelscanvf.cc","supports_latest":true,"item_url":"https://lelscanvf.cc/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"School Life"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Slice of Life"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedy"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"}]}"""
|
"https://lelscanvf.cc" -> """{"name":"Lelscan-VF","base_url":"https://lelscanvf.cc","supports_latest":true,"item_url":"https://lelscanvf.cc/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"School Life"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Slice of Life"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedy"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"}]}"""
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
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 = "$baseUrl/mangas/".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/mangas/".toHttpUrl().newBuilder()
|
||||||
filters.forEach { filter ->
|
filters.forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
is GenreFilter -> url.addPathSegment(filter.toUriPart())
|
is GenreFilter -> url.addPathSegment(filter.toUriPart())
|
||||||
|
@ -76,7 +76,7 @@ abstract class Paprika(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
url.addQueryParameter("page", page.toString())
|
url.addQueryParameter("page", page.toString())
|
||||||
GET(url.toString(), headers)
|
GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
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 = "$baseUrl/genres/".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/genres/".toHttpUrl().newBuilder()
|
||||||
filters.forEach { filter ->
|
filters.forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
is GenreFilter -> url.addPathSegment(filter.toUriPart())
|
is GenreFilter -> url.addPathSegment(filter.toUriPart())
|
||||||
|
@ -45,7 +45,7 @@ abstract class PaprikaAlt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
url.addQueryParameter("page", page.toString())
|
url.addQueryParameter("page", page.toString())
|
||||||
GET(url.toString(), headers)
|
GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ 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.toHttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -178,13 +179,13 @@ open class Webtoons(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url = "$baseUrl/$langCode/search?keyword=$query".toHttpUrlOrNull()?.newBuilder()!!
|
val url = "$baseUrl/$langCode/search?keyword=$query".toHttpUrl().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)
|
||||||
if (uriPart != "WEBTOON" && page > 1) url.addQueryParameter("page", page.toString())
|
if (uriPart != "WEBTOON" && page > 1) url.addQueryParameter("page", page.toString())
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = "#content > div.card_wrap.search ul:not(#filterLayer) li a"
|
override fun searchMangaSelector() = "#content > div.card_wrap.search ul:not(#filterLayer) li a"
|
||||||
|
|
|
@ -17,7 +17,7 @@ import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import kotlinx.serialization.json.long
|
import kotlinx.serialization.json.long
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
@ -34,8 +34,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 = "https://global.apis.naver.com".toHttpUrlOrNull()!!
|
private val apiBaseUrl = "https://global.apis.naver.com".toHttpUrl()
|
||||||
private val mobileBaseUrl = "https://m.webtoons.com".toHttpUrlOrNull()!!
|
private val mobileBaseUrl = "https://m.webtoons.com".toHttpUrl()
|
||||||
private val thumbnailBaseUrl = "https://mwebtoon-phinf.pstatic.net"
|
private val thumbnailBaseUrl = "https://mwebtoon-phinf.pstatic.net"
|
||||||
|
|
||||||
private val pageSize = 24
|
private val pageSize = 24
|
||||||
|
@ -53,7 +53,7 @@ open class WebtoonsTranslate(
|
||||||
.addQueryParameter("size", "$requeztSize")
|
.addQueryParameter("size", "$requeztSize")
|
||||||
.addQueryParameter("languageCode", translateLangCode)
|
.addQueryParameter("languageCode", translateLangCode)
|
||||||
.build()
|
.build()
|
||||||
return GET(url.toString(), headers)
|
return GET(url, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Webtoons translations doesn't really have a "popular" sort; just "UPDATE", "TITLE_ASC",
|
// Webtoons translations doesn't really have a "popular" sort; just "UPDATE", "TITLE_ASC",
|
||||||
|
@ -161,7 +161,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 mangaUrl = manga.url.toHttpUrlOrNull()!!
|
val mangaUrl = manga.url.toHttpUrl()
|
||||||
val titleNo = mangaUrl.queryParameter("titleNo")
|
val titleNo = mangaUrl.queryParameter("titleNo")
|
||||||
val teamVersion = mangaUrl.queryParameter("teamVersion")
|
val teamVersion = mangaUrl.queryParameter("teamVersion")
|
||||||
val chapterListUrl = apiBaseUrl
|
val chapterListUrl = apiBaseUrl
|
||||||
|
@ -210,7 +210,7 @@ open class WebtoonsTranslate(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
override fun pageListRequest(chapter: SChapter): Request {
|
||||||
return GET(apiBaseUrl.resolve(chapter.url).toString(), headers)
|
return GET(apiBaseUrl.resolve(chapter.url)!!, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
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 = "$baseUrl/$searchPath".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/$searchPath".toHttpUrl().newBuilder()
|
||||||
|
|
||||||
filterList.forEach { filter ->
|
filterList.forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ class WPComicsGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang("NetTruyen", "https://www.nettruyenclub.com", "vi", overrideVersionCode = 21),
|
SingleLang("NetTruyen", "https://www.nettruyenclub.com", "vi", overrideVersionCode = 21),
|
||||||
SingleLang("NhatTruyen", "https://nhattruyenmax.com", "vi", overrideVersionCode = 13),
|
SingleLang("NhatTruyen", "https://nhattruyento.com", "vi", overrideVersionCode = 14),
|
||||||
SingleLang("TruyenChon", "http://truyenchon.com", "vi", overrideVersionCode = 3),
|
SingleLang("TruyenChon", "http://truyenchon.com", "vi", overrideVersionCode = 3),
|
||||||
SingleLang("XOXO Comics", "https://xoxocomic.com", "en", className = "XoxoComics", overrideVersionCode = 3),
|
SingleLang("XOXO Comics", "https://xoxocomic.com", "en", className = "XoxoComics", overrideVersionCode = 3),
|
||||||
)
|
)
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
@ -58,7 +58,7 @@ abstract class ZManga(
|
||||||
|
|
||||||
// search
|
// search
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
var url = "$baseUrl/advanced-search/${pagePathSegment(page)}".toHttpUrlOrNull()!!.newBuilder()
|
var url = "$baseUrl/advanced-search/${pagePathSegment(page)}".toHttpUrl().newBuilder()
|
||||||
url.addQueryParameter("title", query)
|
url.addQueryParameter("title", query)
|
||||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||||
when (filter) {
|
when (filter) {
|
||||||
|
@ -90,13 +90,13 @@ abstract class ZManga(
|
||||||
// if site has project page, default value "hasProjectPage" = false
|
// if site has project page, default value "hasProjectPage" = false
|
||||||
is ProjectFilter -> {
|
is ProjectFilter -> {
|
||||||
if (filter.toUriPart() == "project-filter-on") {
|
if (filter.toUriPart() == "project-filter-on") {
|
||||||
url = "$baseUrl$projectPageString/page/$page".toHttpUrlOrNull()!!.newBuilder()
|
url = "$baseUrl$projectPageString/page/$page".toHttpUrl().newBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
open val projectPageString = "/project-list"
|
open val projectPageString = "/project-list"
|
||||||
|
|
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'Bato.to'
|
extName = 'Bato.to'
|
||||||
pkgNameSuffix = 'all.batoto'
|
pkgNameSuffix = 'all.batoto'
|
||||||
extClass = '.BatoToFactory'
|
extClass = '.BatoToFactory'
|
||||||
extVersionCode = 32
|
extVersionCode = 34
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -110,7 +109,7 @@ open class BatoTo(
|
||||||
override fun latestUpdatesSelector(): String {
|
override fun latestUpdatesSelector(): String {
|
||||||
return when (siteLang) {
|
return when (siteLang) {
|
||||||
"" -> "div#series-list div.col"
|
"" -> "div#series-list div.col"
|
||||||
"en" -> "div#series-list div.col.no-flag"
|
"en,en_us" -> "div#series-list div.col.no-flag"
|
||||||
else -> "div#series-list div.col:has([data-lang=\"$siteLang\"])"
|
else -> "div#series-list div.col:has([data-lang=\"$siteLang\"])"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,13 +159,13 @@ open class BatoTo(
|
||||||
else -> { /* Do Nothing */ }
|
else -> { /* Do Nothing */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.newCall(GET(url.build().toString(), headers)).asObservableSuccess()
|
client.newCall(GET(url.build(), headers)).asObservableSuccess()
|
||||||
.map { response ->
|
.map { response ->
|
||||||
queryParse(response)
|
queryParse(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/browse".toHttpUrl().newBuilder()
|
||||||
var min = ""
|
var min = ""
|
||||||
var max = ""
|
var max = ""
|
||||||
filters.forEach { filter ->
|
filters.forEach { filter ->
|
||||||
|
@ -232,7 +231,7 @@ open class BatoTo(
|
||||||
url.addQueryParameter("chapters", "$min-$max")
|
url.addQueryParameter("chapters", "$min-$max")
|
||||||
}
|
}
|
||||||
|
|
||||||
client.newCall(GET(url.build().toString(), headers)).asObservableSuccess()
|
client.newCall(GET(url.build(), headers)).asObservableSuccess()
|
||||||
.map { response ->
|
.map { response ->
|
||||||
queryParse(response)
|
queryParse(response)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ class LanguageOption(val lang: String, val siteLang: String = lang)
|
||||||
private val languages = listOf(
|
private val languages = listOf(
|
||||||
LanguageOption("all", ""),
|
LanguageOption("all", ""),
|
||||||
// Lang options from publish.bato.to
|
// Lang options from publish.bato.to
|
||||||
LanguageOption("en"),
|
LanguageOption("en", "en,en_us"),
|
||||||
LanguageOption("ar"),
|
LanguageOption("ar"),
|
||||||
LanguageOption("bg"),
|
LanguageOption("bg"),
|
||||||
LanguageOption("zh"),
|
LanguageOption("zh"),
|
||||||
|
@ -58,7 +58,6 @@ private val languages = listOf(
|
||||||
LanguageOption("zh-Hans", "zh_hk"),
|
LanguageOption("zh-Hans", "zh_hk"),
|
||||||
LanguageOption("zh-Hant", "zh_tw"),
|
LanguageOption("zh-Hant", "zh_tw"),
|
||||||
LanguageOption("hr"),
|
LanguageOption("hr"),
|
||||||
LanguageOption("en-US", "en_us"),
|
|
||||||
LanguageOption("eo"),
|
LanguageOption("eo"),
|
||||||
LanguageOption("et"),
|
LanguageOption("et"),
|
||||||
LanguageOption("fo"),
|
LanguageOption("fo"),
|
||||||
|
|
|
@ -109,7 +109,7 @@ class Hennojin(override val lang: String, suffix: String) : ParsedHttpSource() {
|
||||||
|
|
||||||
private inline fun HttpUrl.request(
|
private inline fun HttpUrl.request(
|
||||||
block: HttpUrl.Builder.() -> HttpUrl.Builder,
|
block: HttpUrl.Builder.() -> HttpUrl.Builder,
|
||||||
) = GET(newBuilder().block().toString(), headers)
|
) = GET(newBuilder().block().build(), headers)
|
||||||
|
|
||||||
private inline val Response.date: Long
|
private inline val Response.date: Long
|
||||||
get() = headers["Last-Modified"]?.run(httpDate::parse)?.time ?: 0L
|
get() = headers["Last-Modified"]?.run(httpDate::parse)?.time ?: 0L
|
||||||
|
|
|
@ -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 kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -111,14 +111,14 @@ class IMHentai(override val lang: String, private val imhLang: String) : ParsedH
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
if (filters.any { it is LanguageFilters && it.state.any { it.name == LANGUAGE_SPEECHLESS && it.state } }) { // edge case for language = speechless
|
if (filters.any { it is LanguageFilters && it.state.any { it.name == LANGUAGE_SPEECHLESS && it.state } }) { // edge case for language = speechless
|
||||||
val url = "$baseUrl/language/speechless/".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/language/speechless/".toHttpUrl().newBuilder()
|
||||||
|
|
||||||
if ((if (filters.isEmpty()) getFilterList() else filters).filterIsInstance<SortOrderFilter>()[0].state == 0) {
|
if ((if (filters.isEmpty()) getFilterList() else filters).filterIsInstance<SortOrderFilter>()[0].state == 0) {
|
||||||
url.addPathSegment("popular")
|
url.addPathSegment("popular")
|
||||||
}
|
}
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
} else {
|
} else {
|
||||||
val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/search".toHttpUrl().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
|
||||||
|
@ -143,7 +143,7 @@ class IMHentai(override val lang: String, private val imhLang: String) : ParsedH
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString())
|
return GET(url.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import kotlinx.serialization.json.long
|
||||||
import kotlinx.serialization.json.put
|
import kotlinx.serialization.json.put
|
||||||
import kotlinx.serialization.json.putJsonArray
|
import kotlinx.serialization.json.putJsonArray
|
||||||
import kotlinx.serialization.json.putJsonObject
|
import kotlinx.serialization.json.putJsonObject
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -206,7 +206,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 = apiBaseUrl.toHttpUrlOrNull()!!.newBuilder()
|
val url = apiBaseUrl.toHttpUrl().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())
|
||||||
|
@ -238,7 +238,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 = apiBaseUrl.toHttpUrlOrNull()!!.newBuilder()
|
val url = apiBaseUrl.toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("operationName", "AlbumGet")
|
.addQueryParameter("operationName", "AlbumGet")
|
||||||
.addQueryParameter("query", albumInfoQuery)
|
.addQueryParameter("query", albumInfoQuery)
|
||||||
.addQueryParameter("variables", input.toString())
|
.addQueryParameter("variables", input.toString())
|
||||||
|
@ -337,7 +337,7 @@ abstract class Luscious(
|
||||||
|
|
||||||
private fun buildAlbumPicturesPageUrl(id: String, page: Int): String {
|
private fun buildAlbumPicturesPageUrl(id: String, page: Int): String {
|
||||||
val input = buildAlbumPicturesRequestInput(id, page)
|
val input = buildAlbumPicturesRequestInput(id, page)
|
||||||
return apiBaseUrl.toHttpUrlOrNull()!!.newBuilder()
|
return apiBaseUrl.toHttpUrl().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())
|
||||||
|
|
|
@ -27,7 +27,7 @@ import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
||||||
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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -146,13 +146,13 @@ open class NHentai(
|
||||||
filterList.findInstance<OffsetPageFilter>()?.state?.toIntOrNull()?.plus(page) ?: page
|
filterList.findInstance<OffsetPageFilter>()?.state?.toIntOrNull()?.plus(page) ?: page
|
||||||
|
|
||||||
if (favoriteFilter?.state == true) {
|
if (favoriteFilter?.state == true) {
|
||||||
val url = "$baseUrl/favorites".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/favorites".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("q", "$fixedQuery $advQuery")
|
.addQueryParameter("q", "$fixedQuery $advQuery")
|
||||||
.addQueryParameter("page", offsetPage.toString())
|
.addQueryParameter("page", offsetPage.toString())
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
} else {
|
} else {
|
||||||
val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/search".toHttpUrl().newBuilder()
|
||||||
.addQueryParameter("q", "$fixedQuery $nhLangSearch$advQuery")
|
.addQueryParameter("q", "$fixedQuery $nhLangSearch$advQuery")
|
||||||
.addQueryParameter("page", offsetPage.toString())
|
.addQueryParameter("page", offsetPage.toString())
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ open class NHentai(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
@ -137,7 +137,7 @@ open class NineManga(
|
||||||
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 = "$baseUrl/search/".toHttpUrlOrNull()!!.newBuilder()
|
val url = "$baseUrl/search/".toHttpUrl().newBuilder()
|
||||||
|
|
||||||
url.addQueryParameter("wd", query)
|
url.addQueryParameter("wd", query)
|
||||||
url.addQueryParameter("page", page.toString())
|
url.addQueryParameter("page", page.toString())
|
||||||
|
@ -166,7 +166,7 @@ open class NineManga(
|
||||||
|
|
||||||
url.addQueryParameter("type", "high")
|
url.addQueryParameter("type", "high")
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = popularMangaSelector()
|
override fun searchMangaSelector() = popularMangaSelector()
|
||||||
|
|
|
@ -76,7 +76,7 @@ class Photos18 : HttpSource(), ConfigurableSource {
|
||||||
if (filter is QueryFilter) filter.addQueryTo(url)
|
if (filter is QueryFilter) filter.addQueryTo(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response) = popularMangaParse(response)
|
override fun searchMangaParse(response: Response) = popularMangaParse(response)
|
||||||
|
|
|
@ -6,6 +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.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
|
@ -13,7 +14,6 @@ import okhttp3.HttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ class Pixiv(override val lang: String) : HttpSource() {
|
||||||
for (p in countUp(start = 1)) {
|
for (p in countUp(start = 1)) {
|
||||||
searchUsers.url.setEncodedQueryParameter("p", p.toString())
|
searchUsers.url.setEncodedQueryParameter("p", p.toString())
|
||||||
|
|
||||||
val userIds = Jsoup.parse(searchUsers.execute().body.string())
|
val userIds = searchUsers.execute().asJsoup()
|
||||||
.select(".user-recommendation-item > a").eachAttr("href")
|
.select(".user-recommendation-item > a").eachAttr("href")
|
||||||
.map { it.substringAfterLast('/') }
|
.map { it.substringAfterLast('/') }
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ ext {
|
||||||
extName = 'Yaoi Manga Online'
|
extName = 'Yaoi Manga Online'
|
||||||
pkgNameSuffix = 'all.yaoimangaonline'
|
pkgNameSuffix = 'all.yaoimangaonline'
|
||||||
extClass = '.YaoiMangaOnline'
|
extClass = '.YaoiMangaOnline'
|
||||||
extVersionCode = 2
|
extVersionCode = 3
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,26 +67,25 @@ class YaoiMangaOnline : ParsedHttpSource() {
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = element.attr("title")
|
title = element.attr("title")
|
||||||
setUrlWithoutDomain(element.attr("href"))
|
setUrlWithoutDomain(element.attr("href"))
|
||||||
thumbnail_url = element.selectFirst("img")!!.attr("src")
|
thumbnail_url = element.selectFirst("img")?.attr("src")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document) =
|
override fun mangaDetailsParse(document: Document) =
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = document.selectFirst(".entry-title")!!.text()
|
title = document.select("h1.entry-title").text()
|
||||||
thumbnail_url = document.head()
|
thumbnail_url = document
|
||||||
.selectFirst("meta[property=og:image]")!!.attr("content")
|
.selectFirst(".herald-post-thumbnail img")?.attr("src")
|
||||||
description = document.selectFirst(".entry-content > p")!!
|
description = document.select(".entry-content > p").text()
|
||||||
.html().replace("<br> ", "\n")
|
|
||||||
genre = document.select(".meta-tags > a").joinToString { it.text() }
|
genre = document.select(".meta-tags > a").joinToString { it.text() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListSelector() = "#acp_paging_menu > li"
|
override fun chapterListSelector() = ".mpp-toc a"
|
||||||
|
|
||||||
override fun chapterFromElement(element: Element) =
|
override fun chapterFromElement(element: Element) =
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
name = element.selectFirst(".acp_title")!!.text()
|
name = element.ownText()
|
||||||
setUrlWithoutDomain(
|
setUrlWithoutDomain(
|
||||||
element.selectFirst("a")?.attr("href") ?: element.baseUri(),
|
element.attr("href") ?: element.baseUri(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,10 +95,10 @@ class YaoiMangaOnline : ParsedHttpSource() {
|
||||||
name = "Chapter"
|
name = "Chapter"
|
||||||
url = response.request.url.encodedPath
|
url = response.request.url.encodedPath
|
||||||
}.let(::listOf)
|
}.let(::listOf)
|
||||||
}
|
}.reversed()
|
||||||
|
|
||||||
override fun pageListParse(document: Document) =
|
override fun pageListParse(document: Document) =
|
||||||
document.select(".size-full").mapIndexed { idx, img ->
|
document.select(".entry-content img").mapIndexed { idx, img ->
|
||||||
Page(idx, "", img.attr("src"))
|
Page(idx, "", img.attr("src"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ class REManga : ParsedHttpSource() {
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector() = popularMangaSelector()
|
override fun searchMangaSelector() = popularMangaSelector()
|
||||||
|
|
|
@ -45,7 +45,7 @@ class MangaRok : ParsedHttpSource() {
|
||||||
.addQueryParameter("q", query)
|
.addQueryParameter("q", query)
|
||||||
.addQueryParameter("page", page.toString())
|
.addQueryParameter("page", page.toString())
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.build(), headers)
|
||||||
}
|
}
|
||||||
override fun searchMangaSelector(): String =
|
override fun searchMangaSelector(): String =
|
||||||
".is-half > a.box"
|
".is-half > a.box"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest />
|
|
@ -0,0 +1,13 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlinx-serialization'
|
||||||
|
|
||||||
|
ext {
|
||||||
|
extName = 'Anchira'
|
||||||
|
pkgNameSuffix = 'en.anchira'
|
||||||
|
extClass = '.Anchira'
|
||||||
|
extVersionCode = 4
|
||||||
|
isNsfw = true
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$rootDir/common.gradle"
|
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 52 KiB |