remove some websites (#4622)
* remove Hentai3z redirects to hentai20 * remove ReadMangaToday * remove Readmanhua * remove mangakik * remove mangapure * remove mangashiro * remove moonwithcinlove * remove readkomik * remove rio2manga
|
@ -1,10 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'Hentai3z'
|
|
||||||
extClass = '.Hentai3z'
|
|
||||||
themePkg = 'madara'
|
|
||||||
baseUrl = 'https://hentai3z.xyz'
|
|
||||||
overrideVersionCode = 0
|
|
||||||
isNsfw = true
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 53 KiB |
|
@ -1,7 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.hentai3z
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
|
|
||||||
class Hentai3z : Madara("Hentai3z", "https://hentai3z.xyz", "en") {
|
|
||||||
override val useNewChapterEndpoint = false
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'Mangakik'
|
|
||||||
extClass = '.Mangakik'
|
|
||||||
themePkg = 'madara'
|
|
||||||
baseUrl = 'https://mangakik.org'
|
|
||||||
overrideVersionCode = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -1,5 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.mangakik
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
|
|
||||||
class Mangakik : Madara("Mangakik", "https://mangakik.org", "en")
|
|
|
@ -1,10 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'MangaPure'
|
|
||||||
extClass = '.MangaPure'
|
|
||||||
themePkg = 'madara'
|
|
||||||
baseUrl = 'https://mangapure.net'
|
|
||||||
overrideVersionCode = 0
|
|
||||||
isNsfw = true
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 13 KiB |
|
@ -1,82 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.mangapure
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class MangaPure : Madara(
|
|
||||||
"MangaPure",
|
|
||||||
"https://mangapure.net",
|
|
||||||
"en",
|
|
||||||
dateFormat = SimpleDateFormat("MMM dd, HH:mm", Locale.ENGLISH),
|
|
||||||
) {
|
|
||||||
override val useNewChapterEndpoint = false
|
|
||||||
override val mangaDetailsSelectorStatus = "div.summary-heading:contains(Status) + div.summary-content"
|
|
||||||
|
|
||||||
override fun searchMangaNextPageSelector(): String? = ".pagination a[rel=next]"
|
|
||||||
|
|
||||||
override fun searchPage(page: Int): String = "search?page=$page"
|
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request =
|
|
||||||
GET("$baseUrl/popular-manga?page=$page", headers)
|
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request =
|
|
||||||
GET("$baseUrl/latest-manga?page=$page", headers)
|
|
||||||
|
|
||||||
// Copied from IsekaiScan.top (unoriginal)
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
|
||||||
val document = response.asJsoup()
|
|
||||||
val chaptersWrapper = document.select("div[id^=manga-chapters-holder]")
|
|
||||||
|
|
||||||
var chapterElements = document.select(chapterListSelector())
|
|
||||||
|
|
||||||
if (chapterElements.isEmpty() && !chaptersWrapper.isNullOrEmpty()) {
|
|
||||||
val mangaId = chaptersWrapper.attr("data-id")
|
|
||||||
val xhrHeaders = headersBuilder()
|
|
||||||
.add("Referer", "$baseUrl/")
|
|
||||||
.add("X-Requested-With", "XMLHttpRequest")
|
|
||||||
.build()
|
|
||||||
val xhrRequest = GET("$baseUrl/ajax-list-chapter?mangaID=$mangaId", xhrHeaders)
|
|
||||||
val xhrResponse = client.newCall(xhrRequest).execute()
|
|
||||||
|
|
||||||
chapterElements = xhrResponse.asJsoup().select(chapterListSelector())
|
|
||||||
xhrResponse.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
launchIO { countViews(document) }
|
|
||||||
return chapterElements.map(::chapterFromElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied from IsekaiScan.top (unoriginal)
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
|
||||||
val stringArray = document.select("p#arraydata").text().split(",").toTypedArray()
|
|
||||||
return stringArray.mapIndexed { index, url ->
|
|
||||||
Page(
|
|
||||||
index,
|
|
||||||
document.location(),
|
|
||||||
url,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some thumbnails expect harimanga.com, which has hotlink protection
|
|
||||||
override fun headersBuilder() = super.headersBuilder()
|
|
||||||
.removeAll("Referer")
|
|
||||||
|
|
||||||
// OnGoing => Ongoing
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
|
||||||
return super.mangaDetailsParse(document).apply {
|
|
||||||
document.select(mangaDetailsSelectorStatus).lastOrNull()?.text()
|
|
||||||
.takeIf { it == "Ongoing" }
|
|
||||||
?.let { status = SManga.ONGOING }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'Readkomik'
|
|
||||||
extClass = '.ReadKomik'
|
|
||||||
themePkg = 'mangathemesia'
|
|
||||||
baseUrl = 'https://rkreader.org'
|
|
||||||
overrideVersionCode = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 21 KiB |
|
@ -1,146 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.readkomik
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
|
|
||||||
class ReadKomik : MangaThemesia(
|
|
||||||
"Readkomik",
|
|
||||||
"https://rkreader.org",
|
|
||||||
"en",
|
|
||||||
"/archives/manga",
|
|
||||||
) {
|
|
||||||
override val client: OkHttpClient = super.client.newBuilder()
|
|
||||||
.rateLimit(4)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
// mangaDetailsRequest: Keeps compatibility with before version
|
|
||||||
override fun mangaDetailsRequest(manga: SManga) =
|
|
||||||
super.mangaDetailsRequest(replaceBaseUrlDirectoryByCustomUrlDirectory(manga))
|
|
||||||
|
|
||||||
// chapterListRequest: Keeps compatibility with before version
|
|
||||||
override fun chapterListRequest(manga: SManga) =
|
|
||||||
super.chapterListRequest(replaceBaseUrlDirectoryByCustomUrlDirectory(manga))
|
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int) =
|
|
||||||
searchMangaRequest(page, "", FilterList(OrderByFilter("", orderByFilterOptions, "az-list")))
|
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers)
|
|
||||||
|
|
||||||
override fun latestUpdatesSelector() = ".listupd .utao .uta .imgu"
|
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element) = searchMangaFromElement(element)
|
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response) =
|
|
||||||
super.latestUpdatesParse(response).copy(hasNextPage = false)
|
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
||||||
val url = baseUrl.toHttpUrl().newBuilder()
|
|
||||||
|
|
||||||
if (query.isNotBlank()) {
|
|
||||||
url.apply {
|
|
||||||
addPathSegment("page")
|
|
||||||
addPathSegment("$page")
|
|
||||||
addQueryParameter("s", query)
|
|
||||||
}
|
|
||||||
return GET(url.build(), headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
val filter = filters.filterIsInstance<SelectFilter>()
|
|
||||||
.first { it.selectedValue().isNotBlank() }
|
|
||||||
|
|
||||||
when (filter) {
|
|
||||||
is GenreFilter -> {
|
|
||||||
url.apply {
|
|
||||||
addPathSegment(mangaUrlDirectory.substringBeforeLast("/").substring(1))
|
|
||||||
addPathSegment("genres")
|
|
||||||
addPathSegment(filter.selectedValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is OrderByFilter -> {
|
|
||||||
url.addPathSegment("az-list")
|
|
||||||
if (filter.selectedValue() != "az-list") {
|
|
||||||
url.addQueryParameter("show", filter.selectedValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is ProjectFilter -> {
|
|
||||||
url.setPathSegment(0, projectPageString.substring(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> { /* Do Nothing */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
url.apply {
|
|
||||||
addPathSegment("page")
|
|
||||||
addPathSegment("$page")
|
|
||||||
}
|
|
||||||
|
|
||||||
return GET(url.build(), headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFilterList(): FilterList {
|
|
||||||
val filters = mutableListOf<Filter<*>>(
|
|
||||||
Filter.Header("Multiple filter selection not supported"),
|
|
||||||
OrderByFilter("Title", orderByFilterOptions),
|
|
||||||
Filter.Header("Or"),
|
|
||||||
GenreFilter("Genre", genreFilterOptions),
|
|
||||||
)
|
|
||||||
|
|
||||||
filters.addAll(
|
|
||||||
mutableListOf<Filter<*>>(
|
|
||||||
Filter.Separator(),
|
|
||||||
Filter.Header(intl["project_filter_warning"]),
|
|
||||||
Filter.Header(intl.format("project_filter_name", name)),
|
|
||||||
ProjectFilter(intl["project_filter_title"], projectFilterOptions),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return FilterList(filters)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val orderByFilterOptions = arrayOf("None" to "", "A-Z" to "az-list").let {
|
|
||||||
val A = 65; val Z = A + 25
|
|
||||||
it.plus((A..Z).map { "${it.toChar()}" }.map { it to it }.toTypedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
private val genres = listOf(
|
|
||||||
"Action", "Adult", "Adventure", "Comedy",
|
|
||||||
"Drama", "Ecchi", "Fantasy", "Harem", "Historical",
|
|
||||||
"Horror", "Josei", "Martial Arts", "Mature", "Romance",
|
|
||||||
"School Life", "Sci-fi", "Seinen", "Shounen", "Slice of Life",
|
|
||||||
"Smut", "Supernatural", "Tragedy", "Yaoi",
|
|
||||||
)
|
|
||||||
|
|
||||||
private var genreFilterOptions: Array<Pair<String, String>> = arrayOf(("None" to "")).let {
|
|
||||||
it.plus(genres.map { Pair(it, it.lowercase().replace(" ", "-")) }.toTypedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun replaceBaseUrlDirectoryByCustomUrlDirectory(manga: SManga): SManga {
|
|
||||||
return when {
|
|
||||||
isOldUrl(manga) -> manga.apply {
|
|
||||||
url = url.replace("/manga", mangaUrlDirectory)
|
|
||||||
}
|
|
||||||
else -> manga
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isOldUrl(manga: SManga) = !manga.url.contains(this.mangaUrlDirectory)
|
|
||||||
|
|
||||||
protected class GenreFilter(
|
|
||||||
name: String,
|
|
||||||
options: Array<Pair<String, String>>,
|
|
||||||
) : SelectFilter(
|
|
||||||
name,
|
|
||||||
options,
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'ReadMangaToday'
|
|
||||||
extClass = '.Readmangatoday'
|
|
||||||
extVersionCode = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 20 KiB |
|
@ -1,251 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.readmangatoday
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.network.POST
|
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
|
||||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import kotlinx.serialization.json.jsonArray
|
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
|
||||||
import okhttp3.Headers
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import java.util.Calendar
|
|
||||||
|
|
||||||
class Readmangatoday : ParsedHttpSource() {
|
|
||||||
|
|
||||||
override val id: Long = 8
|
|
||||||
|
|
||||||
override val name = "ReadMangaToday"
|
|
||||||
|
|
||||||
override val baseUrl = "https://www.readmng.com"
|
|
||||||
|
|
||||||
override val lang = "en"
|
|
||||||
|
|
||||||
override val supportsLatest = true
|
|
||||||
|
|
||||||
override val client: OkHttpClient get() = network.cloudflareClient
|
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search only returns data with user-agent and x-requeted-with set
|
|
||||||
* Referer needed due to some chapters linking images from other domains
|
|
||||||
*/
|
|
||||||
override fun headersBuilder() = Headers.Builder().apply {
|
|
||||||
add("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64)")
|
|
||||||
add("X-Requested-With", "XMLHttpRequest")
|
|
||||||
add("Referer", baseUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
|
||||||
return GET("$baseUrl/hot-manga/$page", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
|
||||||
return GET("$baseUrl/latest-releases/$page", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun popularMangaSelector() = "div.categoryContent > div.galeriContent > div.mangaSliderCard"
|
|
||||||
|
|
||||||
override fun latestUpdatesSelector() = "div.listUpdates > div.miniListCard"
|
|
||||||
|
|
||||||
override fun popularMangaFromElement(element: Element): SManga {
|
|
||||||
val manga = SManga.create()
|
|
||||||
element.selectFirst("h2")?.let {
|
|
||||||
manga.title = it.text()
|
|
||||||
}
|
|
||||||
element.select("a").first()!!.let {
|
|
||||||
manga.setUrlWithoutDomain(it.attr("href"))
|
|
||||||
}
|
|
||||||
manga.thumbnail_url = element.select("img").attr("src")
|
|
||||||
return manga
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element): SManga {
|
|
||||||
return popularMangaFromElement(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun popularMangaNextPageSelector() = "div.categoryContent a.page-link:contains(»)"
|
|
||||||
|
|
||||||
override fun latestUpdatesNextPageSelector() = "div.popularToday a.page-link:contains(»)"
|
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
||||||
val builder = okhttp3.FormBody.Builder()
|
|
||||||
builder.add("manga-name", query)
|
|
||||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
|
||||||
when (filter) {
|
|
||||||
is TextField -> builder.add(filter.key, filter.state)
|
|
||||||
is Type -> builder.add("type", arrayOf("all", "japanese", "korean", "chinese")[filter.state])
|
|
||||||
is Status -> builder.add("status", arrayOf("both", "completed", "ongoing")[filter.state])
|
|
||||||
is GenreList -> filter.state.forEach { genre ->
|
|
||||||
when (genre.state) {
|
|
||||||
Filter.TriState.STATE_INCLUDE -> builder.add("include[]", genre.id.toString())
|
|
||||||
Filter.TriState.STATE_EXCLUDE -> builder.add("exclude[]", genre.id.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return POST("$baseUrl/advanced-search", headers, builder.build())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun searchMangaSelector() = "div.mangaSliderCard"
|
|
||||||
|
|
||||||
override fun searchMangaFromElement(element: Element): SManga {
|
|
||||||
return popularMangaFromElement(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun searchMangaNextPageSelector() = "div.next-page > a.next"
|
|
||||||
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
|
||||||
val detailElement = document.select("div.productDetail").first()!!
|
|
||||||
val genreElement = detailElement.select("b:contains(Genres)+span.mgen>a")
|
|
||||||
|
|
||||||
val manga = SManga.create()
|
|
||||||
manga.author = detailElement.select("div.productRight div.infox div.flex-wrap b:contains(Author)+span>a").first()?.text()
|
|
||||||
manga.artist = detailElement.select("div.productRight div.infox div.flex-wrap b:contains(Artist)+span>a").first()?.text()
|
|
||||||
manga.description = detailElement.select("div.productRight div.infox h2:contains(Description)~p:eq(2)").first()?.text()
|
|
||||||
manga.status = detailElement.select("div.imptdt:contains(Status)>i").first()?.text().orEmpty().let { parseStatus(it) }
|
|
||||||
manga.thumbnail_url = detailElement.select("div.thumb img").first()?.attr("src")
|
|
||||||
manga.genre = genreElement.joinToString(", ") { it.text() }
|
|
||||||
|
|
||||||
return manga
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseStatus(status: String) = when {
|
|
||||||
status.contains("Ongoing") -> SManga.ONGOING
|
|
||||||
status.contains("Completed") -> SManga.COMPLETED
|
|
||||||
else -> SManga.UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun chapterListSelector() = "div#chapters-tabContent div.cardFlex div.checkBoxCard"
|
|
||||||
|
|
||||||
override fun chapterFromElement(element: Element): SChapter {
|
|
||||||
val urlElement = element.select("a").first()!!
|
|
||||||
|
|
||||||
val chapter = SChapter.create()
|
|
||||||
chapter.setUrlWithoutDomain(urlElement.attr("href"))
|
|
||||||
chapter.name = urlElement.ownText()
|
|
||||||
chapter.date_upload = element.select("i.upload-date").first()?.text()?.let { parseChapterDate(it) } ?: 0
|
|
||||||
return chapter
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseChapterDate(date: String): Long {
|
|
||||||
val dateWords: List<String> = date.split(" ")
|
|
||||||
|
|
||||||
if (dateWords.size == 3) {
|
|
||||||
val timeAgo = Integer.parseInt(dateWords[0])
|
|
||||||
val calendar = Calendar.getInstance()
|
|
||||||
|
|
||||||
when {
|
|
||||||
dateWords[1].contains("Minute", true) -> {
|
|
||||||
calendar.add(Calendar.MINUTE, -timeAgo)
|
|
||||||
}
|
|
||||||
dateWords[1].contains("Hour", true) -> {
|
|
||||||
calendar.add(Calendar.HOUR_OF_DAY, -timeAgo)
|
|
||||||
}
|
|
||||||
dateWords[1].contains("Day", true) -> {
|
|
||||||
calendar.add(Calendar.DAY_OF_YEAR, -timeAgo)
|
|
||||||
}
|
|
||||||
dateWords[1].contains("Week", true) -> {
|
|
||||||
calendar.add(Calendar.WEEK_OF_YEAR, -timeAgo)
|
|
||||||
}
|
|
||||||
dateWords[1].contains("Month", true) -> {
|
|
||||||
calendar.add(Calendar.MONTH, -timeAgo)
|
|
||||||
}
|
|
||||||
dateWords[1].contains("year", true) -> {
|
|
||||||
calendar.add(Calendar.YEAR, -timeAgo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return calendar.timeInMillis
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0L
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
|
||||||
return GET("$baseUrl/${chapter.url}/all-pages", headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
|
||||||
val docString = document.toString()
|
|
||||||
val imageListRegex = Regex("\\\"images.*?:.*?(\\[.*?\\])")
|
|
||||||
val imageListJson = imageListRegex.find(docString)!!.destructured.toList()[0]
|
|
||||||
|
|
||||||
val imageList = json.parseToJsonElement(imageListJson).jsonArray
|
|
||||||
val baseResolver = baseUrl.toHttpUrl()
|
|
||||||
|
|
||||||
val scriptPages = imageList.mapIndexed { i, jsonEl ->
|
|
||||||
val imageUrl = jsonEl.jsonPrimitive.content
|
|
||||||
Page(i, "", baseResolver.resolve(imageUrl).toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
return scriptPages.distinctBy { it.imageUrl }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
|
|
||||||
|
|
||||||
private class Status : Filter.TriState("Completed")
|
|
||||||
private class Genre(name: String, val id: Int) : Filter.TriState(name)
|
|
||||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
|
||||||
private class Type : Filter.Select<String>("Type", arrayOf("All", "Japanese Manga", "Korean Manhwa", "Chinese Manhua"))
|
|
||||||
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres)
|
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
|
||||||
TextField("Author", "author-name"),
|
|
||||||
TextField("Artist", "artist-name"),
|
|
||||||
Type(),
|
|
||||||
Status(),
|
|
||||||
GenreList(getGenreList()),
|
|
||||||
)
|
|
||||||
|
|
||||||
// [...document.querySelectorAll("ul.manga-cat span")].map(el => `Genre("${el.nextSibling.textContent.trim()}", ${el.getAttribute('data-id')})`).join(',\n')
|
|
||||||
// https://www.readmng.com/advanced-search
|
|
||||||
private fun getGenreList() = listOf(
|
|
||||||
Genre("Action", 2),
|
|
||||||
Genre("Adventure", 4),
|
|
||||||
Genre("Comedy", 5),
|
|
||||||
Genre("Doujinshi", 6),
|
|
||||||
Genre("Drama", 7),
|
|
||||||
Genre("Ecchi", 8),
|
|
||||||
Genre("Fantasy", 9),
|
|
||||||
Genre("Gender Bender", 10),
|
|
||||||
Genre("Harem", 11),
|
|
||||||
Genre("Historical", 12),
|
|
||||||
Genre("Horror", 13),
|
|
||||||
Genre("Josei", 14),
|
|
||||||
Genre("Lolicon", 15),
|
|
||||||
Genre("Martial Arts", 16),
|
|
||||||
Genre("Mature", 17),
|
|
||||||
Genre("Mecha", 18),
|
|
||||||
Genre("Mystery", 19),
|
|
||||||
Genre("One shot", 20),
|
|
||||||
Genre("Psychological", 21),
|
|
||||||
Genre("Romance", 22),
|
|
||||||
Genre("School Life", 23),
|
|
||||||
Genre("Sci-fi", 24),
|
|
||||||
Genre("Seinen", 25),
|
|
||||||
Genre("Shotacon", 26),
|
|
||||||
Genre("Shoujo", 27),
|
|
||||||
Genre("Shoujo Ai", 28),
|
|
||||||
Genre("Shounen", 29),
|
|
||||||
Genre("Shounen Ai", 30),
|
|
||||||
Genre("Slice of Life", 31),
|
|
||||||
Genre("Smut", 32),
|
|
||||||
Genre("Sports", 33),
|
|
||||||
Genre("Supernatural", 34),
|
|
||||||
Genre("Tragedy", 35),
|
|
||||||
Genre("Yaoi", 36),
|
|
||||||
Genre("Yuri", 37),
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'ReadManhua'
|
|
||||||
extClass = '.ReadManhua'
|
|
||||||
themePkg = 'madara'
|
|
||||||
baseUrl = 'https://readmanhua.net'
|
|
||||||
overrideVersionCode = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 27 KiB |
|
@ -1,36 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.readmanhua
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class ReadManhua : Madara(
|
|
||||||
"ReadManhua",
|
|
||||||
"https://readmanhua.net",
|
|
||||||
"en",
|
|
||||||
dateFormat = SimpleDateFormat("dd MMM yyyy", Locale.US),
|
|
||||||
) {
|
|
||||||
|
|
||||||
override fun chapterFromElement(element: Element): SChapter {
|
|
||||||
val chapter = SChapter.create()
|
|
||||||
val year = Calendar.getInstance().get(Calendar.YEAR).toLong()
|
|
||||||
|
|
||||||
with(element) {
|
|
||||||
selectFirst(chapterUrlSelector)?.let { urlElement ->
|
|
||||||
chapter.url = urlElement.attr("abs:href").let {
|
|
||||||
it.substringBefore("?style=paged") + if (!it.endsWith(chapterUrlSuffix)) chapterUrlSuffix else ""
|
|
||||||
}
|
|
||||||
chapter.name = urlElement.text()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dates can be part of a "new" graphic or plain text
|
|
||||||
chapter.date_upload = selectFirst("img")?.attr("alt")?.let { parseRelativeDate(it) }
|
|
||||||
?: parseChapterDate(selectFirst("span.chapter-release-date i")?.text() + " " + year)
|
|
||||||
}
|
|
||||||
|
|
||||||
return chapter
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'Rio2 Manga'
|
|
||||||
extClass = '.Rio2Manga'
|
|
||||||
themePkg = 'madara'
|
|
||||||
baseUrl = 'https://rio2manga.net'
|
|
||||||
overrideVersionCode = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 17 KiB |
|
@ -1,7 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.rio2manga
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
|
|
||||||
class Rio2Manga : Madara("Rio2 Manga", "https://rio2manga.net", "en") {
|
|
||||||
override val useNewChapterEndpoint = true
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'MangaShiro'
|
|
||||||
extClass = '.MangaShiro'
|
|
||||||
themePkg = 'mangathemesia'
|
|
||||||
baseUrl = 'https://mangashiro.me'
|
|
||||||
overrideVersionCode = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 19 KiB |
|
@ -1,19 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.id.mangashiro
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class MangaShiro : MangaThemesia("MangaShiro", "https://mangashiro.me", "id") {
|
|
||||||
|
|
||||||
override val client: OkHttpClient = super.client.newBuilder()
|
|
||||||
.rateLimit(20, 5, TimeUnit.SECONDS)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
override val hasProjectPage = true
|
|
||||||
|
|
||||||
override val projectPageString = "/project-manga"
|
|
||||||
|
|
||||||
override val seriesTitleSelector = ".ts-breadcrumb li:last-child span"
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
ext {
|
|
||||||
extName = 'Moon Witch In Love'
|
|
||||||
extClass = '.MoonWitchInLove'
|
|
||||||
themePkg = 'madara'
|
|
||||||
baseUrl = 'https://moonwitchinlovescan.com'
|
|
||||||
overrideVersionCode = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
|
@ -1,22 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.pt.moonwitchinlove
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Locale
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class MoonWitchInLove : Madara(
|
|
||||||
"Moon Witch In Love",
|
|
||||||
"https://moonwitchinlovescan.com",
|
|
||||||
"pt-BR",
|
|
||||||
SimpleDateFormat("dd 'de' MMMMM 'de' yyyy", Locale("pt", "BR")),
|
|
||||||
) {
|
|
||||||
|
|
||||||
override val client: OkHttpClient = super.client.newBuilder()
|
|
||||||
.rateLimit(1, 2, TimeUnit.SECONDS)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
override val useNewChapterEndpoint = true
|
|
||||||
}
|
|