mirror of
https://github.com/keiyoushi/extensions-source.git
synced 2024-11-25 03:33:24 +01:00
Mangathemesia refactor (#1637)
* remove randomua * i18n * add other language based selectors * countviews in background * small cleanup * lint * fix * bump * fix genre resetting * use enqueue instead of coroutinescope * fix build * fix build x2 * add back genre missing warning * Add ES translations * lint * Add available language * lint I hate lint * review - lowercase match for status - callback on site * review x2, also fix smol mistake * lint :) * lowercase some translations Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com> * lowercase some translations Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com> * remove "人気" * inline the labels * lint thank you lint, very cool --------- Co-authored-by: bapeey <90949336+bapeey@users.noreply.github.com> Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
This commit is contained in:
parent
10e5b90ec3
commit
6850fb0663
@ -0,0 +1,30 @@
|
||||
alt_names_heading=Alternative Names:
|
||||
author_filter_title=Author
|
||||
year_filter_title=Year
|
||||
status_filter_title=Status
|
||||
status_filter_option_all=All
|
||||
status_filter_option_ongoing=Ongoing
|
||||
status_filter_option_completed=Completed
|
||||
status_filter_option_hiatus=Hiatus
|
||||
status_filter_option_dropped=Dropped
|
||||
type_filter_title=Type
|
||||
type_filter_option_all=All
|
||||
type_filter_option_manga=Manga
|
||||
type_filter_option_manhwa=Manhwa
|
||||
type_filter_option_manhua=Manhua
|
||||
type_filter_option_comic=Comic
|
||||
order_by_filter_title=Sort By
|
||||
order_by_filter_default=Default
|
||||
order_by_filter_az=A-Z
|
||||
order_by_filter_za=Z-A
|
||||
order_by_filter_latest_update=Latest Update
|
||||
order_by_filter_latest_added=Latest Added
|
||||
order_by_filter_popular=Popular
|
||||
project_filter_title=Filter Project
|
||||
project_filter_all_manga=Show all manga
|
||||
project_filter_only_project=Show only project manga
|
||||
genre_filter_title=Genre
|
||||
genre_missing_warning=Press 'Reset' to attempt to show the genres
|
||||
genre_exclusion_warning=Genre exclusion is not available for all sources
|
||||
project_filter_warning=NOTE: Can't be used with other filter!
|
||||
project_filter_name=%s Project List page
|
@ -0,0 +1,23 @@
|
||||
alt_names_heading=Nombres alternativos:
|
||||
author_filter_title=Autor
|
||||
year_filter_title=Año
|
||||
status_filter_title=Estado
|
||||
status_filter_option_all=Todos
|
||||
status_filter_option_ongoing=En curso
|
||||
status_filter_option_completed=Completado
|
||||
status_filter_option_hiatus=En pausa
|
||||
status_filter_option_dropped=Abandonado
|
||||
type_filter_title=Tipo
|
||||
type_filter_option_all=Todos
|
||||
order_by_filter_title=Ordenar por
|
||||
order_by_filter_default=Por defecto
|
||||
order_by_filter_latest_update=Última actualización
|
||||
order_by_filter_latest_added=Último añadido
|
||||
project_filter_title=Filtrar proyectos
|
||||
project_filter_all_manga=Mostrar todos los mangas
|
||||
project_filter_only_project=Mostrar solo los proyectos
|
||||
genre_filter_title=Género
|
||||
genre_missing_warning=Presione 'Restablecer' para intentar cargar los géneros
|
||||
genre_exclusion_warning=La exclusión de géneros puede no funcionar correctamente
|
||||
project_filter_warning=NOTA: ¡No se puede usar con otros filtros!
|
||||
project_filter_name=%s Página de proyectos
|
@ -2,8 +2,8 @@ plugins {
|
||||
id("lib-multisrc")
|
||||
}
|
||||
|
||||
baseVersionCode = 28
|
||||
baseVersionCode = 29
|
||||
|
||||
dependencies {
|
||||
api(project(":lib:randomua"))
|
||||
api(project(":lib:i18n"))
|
||||
}
|
||||
|
@ -1,15 +1,8 @@
|
||||
package eu.kanade.tachiyomi.multisrc.mangathemesia
|
||||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.lib.randomua.addRandomUAPreferenceToScreen
|
||||
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.lib.i18n.Intl
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
@ -21,64 +14,56 @@ import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.jsoup.select.Elements
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.io.IOException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
// Formerly WPMangaStream & WPMangaReader -> MangaThemesia
|
||||
abstract class MangaThemesia(
|
||||
override val name: String,
|
||||
override val baseUrl: String,
|
||||
override val lang: String,
|
||||
final override val lang: String,
|
||||
val mangaUrlDirectory: String = "/manga",
|
||||
val dateFormat: SimpleDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US),
|
||||
) : ParsedHttpSource(), ConfigurableSource {
|
||||
|
||||
private val preferences: SharedPreferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
}
|
||||
) : ParsedHttpSource() {
|
||||
|
||||
protected open val json: Json by injectLazy()
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient by lazy {
|
||||
network.cloudflareClient.newBuilder()
|
||||
.setRandomUserAgent(
|
||||
preferences.getPrefUAType(),
|
||||
preferences.getPrefCustomUA(),
|
||||
)
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.build()
|
||||
}
|
||||
override val client = network.cloudflareClient
|
||||
|
||||
override fun headersBuilder() = super.headersBuilder()
|
||||
.set("Referer", "$baseUrl/")
|
||||
|
||||
protected val intl = Intl(
|
||||
language = lang,
|
||||
baseLanguage = "en",
|
||||
availableLanguages = setOf("en", "es"),
|
||||
classLoader = javaClass.classLoader!!,
|
||||
)
|
||||
|
||||
open val projectPageString = "/project"
|
||||
|
||||
// Popular (Search with popular order and nothing else)
|
||||
override fun popularMangaRequest(page: Int) = searchMangaRequest(page, "", FilterList(OrderByFilter("popular")))
|
||||
override fun popularMangaRequest(page: Int) = searchMangaRequest(page, "", popularFilter)
|
||||
override fun popularMangaParse(response: Response) = searchMangaParse(response)
|
||||
|
||||
// Latest (Search with update order and nothing else)
|
||||
override fun latestUpdatesRequest(page: Int) = searchMangaRequest(page, "", FilterList(OrderByFilter("update")))
|
||||
override fun latestUpdatesRequest(page: Int) = searchMangaRequest(page, "", latestFilter)
|
||||
override fun latestUpdatesParse(response: Response) = searchMangaParse(response)
|
||||
|
||||
// Search
|
||||
@ -166,22 +151,96 @@ abstract class MangaThemesia(
|
||||
override fun searchMangaNextPageSelector() = "div.pagination .next, div.hpage .r"
|
||||
|
||||
// Manga details
|
||||
private fun selector(selector: String, contains: List<String>): String {
|
||||
return contains.joinToString(", ") { selector.replace("%s", it) }
|
||||
}
|
||||
|
||||
open val seriesDetailsSelector = "div.bigcontent, div.animefull, div.main-info, div.postbody"
|
||||
open val seriesTitleSelector = "h1.entry-title"
|
||||
open val seriesArtistSelector = ".infotable tr:contains(artist) td:last-child, .tsinfo .imptdt:contains(artist) i, .fmed b:contains(artist)+span, span:contains(artist)"
|
||||
open val seriesAuthorSelector = ".infotable tr:contains(author) td:last-child, .tsinfo .imptdt:contains(author) i, .fmed b:contains(author)+span, span:contains(author)"
|
||||
|
||||
open val seriesTitleSelector = "h1.entry-title, .ts-breadcrumb li:last-child span"
|
||||
|
||||
open val seriesArtistSelector = selector(
|
||||
".infotable tr:contains(%s) td:last-child, .tsinfo .imptdt:contains(%s) i, .fmed b:contains(%s)+span, span:contains(%s)",
|
||||
listOf(
|
||||
"artist",
|
||||
"Artiste",
|
||||
"Artista",
|
||||
"الرسام",
|
||||
"الناشر",
|
||||
"İllüstratör",
|
||||
"Çizer",
|
||||
),
|
||||
)
|
||||
|
||||
open val seriesAuthorSelector = selector(
|
||||
".infotable tr:contains(%s) td:last-child, .tsinfo .imptdt:contains(%s) i, .fmed b:contains(%s)+span, span:contains(%s)",
|
||||
listOf(
|
||||
"Author",
|
||||
"Auteur",
|
||||
"autor",
|
||||
"المؤلف",
|
||||
"Mangaka",
|
||||
"seniman",
|
||||
"Pengarang",
|
||||
"Yazar",
|
||||
),
|
||||
)
|
||||
|
||||
open val seriesDescriptionSelector = ".desc, .entry-content[itemprop=description]"
|
||||
open val seriesAltNameSelector = ".alternative, .wd-full:contains(alt) span, .alter, .seriestualt"
|
||||
open val seriesGenreSelector = "div.gnr a, .mgen a, .seriestugenre a, span:contains(genre)"
|
||||
open val seriesTypeSelector = ".infotable tr:contains(type) td:last-child, .tsinfo .imptdt:contains(type) i, .tsinfo .imptdt:contains(type) a, .fmed b:contains(type)+span, span:contains(type) a, a[href*=type\\=]"
|
||||
open val seriesStatusSelector = ".infotable tr:contains(status) td:last-child, .tsinfo .imptdt:contains(status) i, .fmed b:contains(status)+span span:contains(status)"
|
||||
|
||||
open val seriesAltNameSelector = ".alternative, .wd-full:contains(alt) span, .alter, .seriestualt, " +
|
||||
selector(
|
||||
".infotable tr:contains(%s) td:last-child",
|
||||
listOf(
|
||||
"Alternative",
|
||||
"Alternatif",
|
||||
"الأسماء الثانوية",
|
||||
),
|
||||
)
|
||||
|
||||
open val seriesGenreSelector = "div.gnr a, .mgen a, .seriestugenre a, " +
|
||||
selector(
|
||||
"span:contains(%s)",
|
||||
listOf(
|
||||
"genre",
|
||||
"التصنيف",
|
||||
),
|
||||
)
|
||||
|
||||
open val seriesTypeSelector = selector(
|
||||
".infotable tr:contains(%s) td:last-child, .tsinfo .imptdt:contains(%s) i, .tsinfo .imptdt:contains(%s) a, .fmed b:contains(%s)+span, span:contains(%s) a",
|
||||
listOf(
|
||||
"type",
|
||||
"ประเภท",
|
||||
"النوع",
|
||||
"tipe",
|
||||
"Türü",
|
||||
),
|
||||
) + ", a[href*=type\\=]"
|
||||
|
||||
open val seriesStatusSelector = selector(
|
||||
".infotable tr:contains(%s) td:last-child, .tsinfo .imptdt:contains(%s) i, .fmed b:contains(%s)+span span:contains(%s)",
|
||||
listOf(
|
||||
"status",
|
||||
"Statut",
|
||||
"Durum",
|
||||
"連載状況",
|
||||
"Estado",
|
||||
"الحالة",
|
||||
"حالة العمل",
|
||||
"สถานะ",
|
||||
"stato",
|
||||
"Statüsü",
|
||||
),
|
||||
)
|
||||
|
||||
open val seriesThumbnailSelector = ".infomanga > div[itemprop=image] img, .thumb img"
|
||||
|
||||
open val altNamePrefix = "Alternative Name: "
|
||||
open val altNamePrefix = "${intl["alt_names_heading"]} "
|
||||
|
||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||
document.selectFirst(seriesDetailsSelector)?.let { seriesDetails ->
|
||||
title = seriesDetails.selectFirst(seriesTitleSelector)?.text().orEmpty()
|
||||
title = seriesDetails.selectFirst(seriesTitleSelector)!!.text()
|
||||
artist = seriesDetails.selectFirst(seriesArtistSelector)?.ownText().removeEmptyPlaceholder()
|
||||
author = seriesDetails.selectFirst(seriesAuthorSelector)?.ownText().removeEmptyPlaceholder()
|
||||
description = seriesDetails.select(seriesDescriptionSelector).joinToString("\n") { it.text() }.trim()
|
||||
@ -210,16 +269,32 @@ abstract class MangaThemesia(
|
||||
}
|
||||
|
||||
protected fun String?.removeEmptyPlaceholder(): String? {
|
||||
return if (this.isNullOrBlank() || this == "-" || this == "N/A") null else this
|
||||
return if (this.isNullOrBlank() || this == "-" || this == "N/A" || this == "n/a") null else this
|
||||
}
|
||||
|
||||
open fun String?.parseStatus(): Int = when {
|
||||
this == null -> SManga.UNKNOWN
|
||||
listOf("ongoing", "publishing").any { this.contains(it, ignoreCase = true) } -> SManga.ONGOING
|
||||
this.contains("hiatus", ignoreCase = true) -> SManga.ON_HIATUS
|
||||
this.contains("completed", ignoreCase = true) -> SManga.COMPLETED
|
||||
listOf("dropped", "cancelled").any { this.contains(it, ignoreCase = true) } -> SManga.CANCELLED
|
||||
else -> SManga.UNKNOWN
|
||||
open fun String?.parseStatus(): Int {
|
||||
if (this == null) return SManga.UNKNOWN
|
||||
|
||||
return when (this.lowercase().trim()) {
|
||||
"مستمرة", "en curso", "ongoing", "on going", "ativo", "en cours",
|
||||
"en cours de publication", "đang tiến hành", "em lançamento", "онгоінг", "publishing",
|
||||
"devam ediyor", "em andamento", "in corso", "güncel", "berjalan", "продолжается", "updating", "lançando", "in arrivo", "emision",
|
||||
"en emision", "مستمر", "curso", "en marcha", "publicandose", "publicando", "连载中", "devam etmekte", "連載中",
|
||||
-> SManga.ONGOING
|
||||
|
||||
"completed", "completo", "complété", "fini", "achevé", "terminé", "tamamlandı", "đã hoàn thành", "hoàn thành",
|
||||
"مكتملة", "завершено", "finished", "finalizado", "completata", "one-shot", "bitti", "tamat", "completado", "concluído", "完結",
|
||||
"concluido", "已完结", "bitmiş",
|
||||
-> SManga.COMPLETED
|
||||
|
||||
"canceled", "cancelled", "cancelado", "cancellato", "cancelados", "dropped", "discontinued", "abandonné",
|
||||
-> SManga.CANCELLED
|
||||
|
||||
"hiatus", "on hold", "pausado", "en espera", "en pause", "en attente",
|
||||
-> SManga.ON_HIATUS
|
||||
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
// Chapter list
|
||||
@ -227,6 +302,9 @@ abstract class MangaThemesia(
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
val document = response.asJsoup()
|
||||
|
||||
countViews(document)
|
||||
|
||||
val chapters = document.select(chapterListSelector()).map { chapterFromElement(it) }
|
||||
|
||||
// Add timestamp to latest chapter, taken from "Updated On".
|
||||
@ -238,8 +316,6 @@ abstract class MangaThemesia(
|
||||
if (date.isNotEmpty()) chapters.first().date_upload = parseUpdatedOnDate(date)
|
||||
}
|
||||
|
||||
countViews(document)
|
||||
|
||||
return chapters
|
||||
}
|
||||
|
||||
@ -267,13 +343,13 @@ abstract class MangaThemesia(
|
||||
open val pageSelector = "div#readerarea img"
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
countViews(document)
|
||||
|
||||
val chapterUrl = document.location()
|
||||
val htmlPages = document.select(pageSelector)
|
||||
.filterNot { it.imgAttr().isEmpty() }
|
||||
.mapIndexed { i, img -> Page(i, chapterUrl, img.imgAttr()) }
|
||||
|
||||
countViews(document)
|
||||
|
||||
// Some sites also loads pages via javascript
|
||||
if (htmlPages.isNotEmpty()) { return htmlPages }
|
||||
|
||||
@ -320,8 +396,6 @@ abstract class MangaThemesia(
|
||||
.build()
|
||||
|
||||
val newHeaders = headersBuilder()
|
||||
.set("Content-Length", formBody.contentLength().toString())
|
||||
.set("Content-Type", formBody.contentType().toString())
|
||||
.set("Referer", document.location())
|
||||
.build()
|
||||
|
||||
@ -339,17 +413,22 @@ abstract class MangaThemesia(
|
||||
}
|
||||
|
||||
val request = countViewsRequest(document) ?: return
|
||||
runCatching { client.newCall(request).execute().close() }
|
||||
val callback = object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) = response.close()
|
||||
override fun onFailure(call: Call, e: IOException) = Unit
|
||||
}
|
||||
|
||||
client.newCall(request).enqueue(callback)
|
||||
}
|
||||
|
||||
// Filters
|
||||
protected class AuthorFilter : Filter.Text("Author")
|
||||
protected class AuthorFilter(name: String) : Filter.Text(name)
|
||||
|
||||
protected class YearFilter : Filter.Text("Year")
|
||||
protected class YearFilter(name: String) : Filter.Text(name)
|
||||
|
||||
open class SelectFilter(
|
||||
displayName: String,
|
||||
val vals: Array<Pair<String, String>>,
|
||||
private val vals: Array<Pair<String, String>>,
|
||||
defaultValue: String? = null,
|
||||
) : Filter.Select<String>(
|
||||
displayName,
|
||||
@ -359,63 +438,91 @@ abstract class MangaThemesia(
|
||||
fun selectedValue() = vals[state].second
|
||||
}
|
||||
|
||||
protected class StatusFilter : SelectFilter(
|
||||
"Status",
|
||||
arrayOf(
|
||||
Pair("All", ""),
|
||||
Pair("Ongoing", "ongoing"),
|
||||
Pair("Completed", "completed"),
|
||||
Pair("Hiatus", "hiatus"),
|
||||
Pair("Dropped", "dropped"),
|
||||
),
|
||||
protected class StatusFilter(
|
||||
name: String,
|
||||
options: Array<Pair<String, String>>,
|
||||
) : SelectFilter(
|
||||
name,
|
||||
options,
|
||||
)
|
||||
|
||||
protected class TypeFilter : SelectFilter(
|
||||
"Type",
|
||||
arrayOf(
|
||||
Pair("All", ""),
|
||||
Pair("Manga", "Manga"),
|
||||
Pair("Manhwa", "Manhwa"),
|
||||
Pair("Manhua", "Manhua"),
|
||||
Pair("Comic", "Comic"),
|
||||
),
|
||||
protected open val statusOptions = arrayOf(
|
||||
Pair(intl["status_filter_option_all"], ""),
|
||||
Pair(intl["status_filter_option_ongoing"], "ongoing"),
|
||||
Pair(intl["status_filter_option_completed"], "completed"),
|
||||
Pair(intl["status_filter_option_hiatus"], "hiatus"),
|
||||
Pair(intl["status_filter_option_dropped"], "dropped"),
|
||||
)
|
||||
|
||||
protected class OrderByFilter(defaultOrder: String? = null) : SelectFilter(
|
||||
"Sort By",
|
||||
arrayOf(
|
||||
Pair("Default", ""),
|
||||
Pair("A-Z", "title"),
|
||||
Pair("Z-A", "titlereverse"),
|
||||
Pair("Latest Update", "update"),
|
||||
Pair("Latest Added", "latest"),
|
||||
Pair("Popular", "popular"),
|
||||
),
|
||||
protected class TypeFilter(
|
||||
name: String,
|
||||
options: Array<Pair<String, String>>,
|
||||
) : SelectFilter(
|
||||
name,
|
||||
options,
|
||||
)
|
||||
|
||||
protected open val typeFilterOptions = arrayOf(
|
||||
Pair(intl["type_filter_option_all"], ""),
|
||||
Pair(intl["type_filter_option_manga"], "Manga"),
|
||||
Pair(intl["type_filter_option_manhwa"], "Manhwa"),
|
||||
Pair(intl["type_filter_option_manhua"], "Manhua"),
|
||||
Pair(intl["type_filter_option_comic"], "Comic"),
|
||||
)
|
||||
|
||||
protected class OrderByFilter(
|
||||
name: String,
|
||||
options: Array<Pair<String, String>>,
|
||||
defaultOrder: String? = null,
|
||||
) : SelectFilter(
|
||||
name,
|
||||
options,
|
||||
defaultOrder,
|
||||
)
|
||||
|
||||
protected class ProjectFilter : SelectFilter(
|
||||
"Filter Project",
|
||||
arrayOf(
|
||||
Pair("Show all manga", ""),
|
||||
Pair("Show only project manga", "project-filter-on"),
|
||||
),
|
||||
protected open val orderByFilterOptions = arrayOf(
|
||||
Pair(intl["order_by_filter_default"], ""),
|
||||
Pair(intl["order_by_filter_az"], "title"),
|
||||
Pair(intl["order_by_filter_za"], "titlereverse"),
|
||||
Pair(intl["order_by_filter_latest_update"], "update"),
|
||||
Pair(intl["order_by_filter_latest_added"], "latest"),
|
||||
Pair(intl["order_by_filter_popular"], "popular"),
|
||||
)
|
||||
|
||||
protected val popularFilter by lazy { FilterList(OrderByFilter("", orderByFilterOptions, "popular")) }
|
||||
protected val latestFilter by lazy { FilterList(OrderByFilter("", orderByFilterOptions, "update")) }
|
||||
|
||||
protected class ProjectFilter(
|
||||
name: String,
|
||||
options: Array<Pair<String, String>>,
|
||||
) : SelectFilter(
|
||||
name,
|
||||
options,
|
||||
)
|
||||
|
||||
protected open val projectFilterOptions = arrayOf(
|
||||
Pair(intl["project_filter_all_manga"], ""),
|
||||
Pair(intl["project_filter_only_project"], "project-filter-on"),
|
||||
)
|
||||
|
||||
protected class GenreData(
|
||||
val name: String,
|
||||
val value: String,
|
||||
val state: Int = Filter.TriState.STATE_IGNORE,
|
||||
)
|
||||
|
||||
protected class Genre(
|
||||
name: String,
|
||||
val value: String,
|
||||
state: Int = STATE_IGNORE,
|
||||
state: Int,
|
||||
) : Filter.TriState(name, state)
|
||||
|
||||
protected class GenreListFilter(genres: List<Genre>) : Filter.Group<Genre>("Genre", genres)
|
||||
protected class GenreListFilter(name: String, genres: List<Genre>) : Filter.Group<Genre>(name, genres)
|
||||
|
||||
protected var genrelist: List<GenreData>? = null
|
||||
|
||||
private var genrelist: List<Genre>? = null
|
||||
protected open fun getGenreList(): List<Genre> {
|
||||
// Filters are fetched immediately once an extension loads
|
||||
// We're only able to get filters after a loading the manga directory,
|
||||
// and resetting the filters is the only thing that seems to reinflate the view
|
||||
return genrelist ?: listOf(Genre("Press reset to attempt to fetch genres", ""))
|
||||
return genrelist?.map { Genre(it.name, it.value, it.state) }.orEmpty()
|
||||
}
|
||||
|
||||
open val hasProjectPage = false
|
||||
@ -423,21 +530,31 @@ abstract class MangaThemesia(
|
||||
override fun getFilterList(): FilterList {
|
||||
val filters = mutableListOf<Filter<*>>(
|
||||
Filter.Separator(),
|
||||
AuthorFilter(),
|
||||
YearFilter(),
|
||||
StatusFilter(),
|
||||
TypeFilter(),
|
||||
OrderByFilter(),
|
||||
Filter.Header("Genre exclusion is not available for all sources"),
|
||||
GenreListFilter(getGenreList()),
|
||||
AuthorFilter(intl["author_filter_title"]),
|
||||
YearFilter(intl["year_filter_title"]),
|
||||
StatusFilter(intl["status_filter_title"], statusOptions),
|
||||
TypeFilter(intl["type_filter_title"], typeFilterOptions),
|
||||
OrderByFilter(intl["order_by_filter_title"], orderByFilterOptions),
|
||||
)
|
||||
if (!genrelist.isNullOrEmpty()) {
|
||||
filters.addAll(
|
||||
listOf(
|
||||
Filter.Header(intl["genre_exclusion_warning"]),
|
||||
GenreListFilter(intl["genre_filter_title"], getGenreList()),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
filters.add(
|
||||
Filter.Header(intl["genre_missing_warning"]),
|
||||
)
|
||||
}
|
||||
if (hasProjectPage) {
|
||||
filters.addAll(
|
||||
mutableListOf<Filter<*>>(
|
||||
Filter.Separator(),
|
||||
Filter.Header("NOTE: Can't be used with other filter!"),
|
||||
Filter.Header("$name Project List page"),
|
||||
ProjectFilter(),
|
||||
Filter.Header(intl["project_filter_warning"]),
|
||||
Filter.Header(intl.format("project_filter_name", name)),
|
||||
ProjectFilter(intl["project_filter_title"], projectFilterOptions),
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -485,9 +602,9 @@ abstract class MangaThemesia(
|
||||
(!strict && url.pathSegments.size == n + 1 && url.pathSegments[n].isEmpty())
|
||||
}
|
||||
|
||||
private fun parseGenres(document: Document): List<Genre>? {
|
||||
private fun parseGenres(document: Document): List<GenreData>? {
|
||||
return document.selectFirst("ul.genrez")?.select("li")?.map { li ->
|
||||
Genre(
|
||||
GenreData(
|
||||
li.selectFirst("label")!!.text(),
|
||||
li.selectFirst("input[type=checkbox]")!!.attr("value"),
|
||||
)
|
||||
@ -514,15 +631,10 @@ abstract class MangaThemesia(
|
||||
|
||||
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
addRandomUAPreferenceToScreen(screen)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val URL_SEARCH_PREFIX = "url:"
|
||||
|
||||
// More info: https://issuetracker.google.com/issues/36970498
|
||||
@Suppress("RegExpRedundantEscape")
|
||||
private val MANGA_PAGE_ID_REGEX = "post_id\\s*:\\s*(\\d+)\\}".toRegex()
|
||||
private val CHAPTER_PAGE_ID_REGEX = "chapter_id\\s*=\\s*(\\d+);".toRegex()
|
||||
|
||||
|
@ -33,10 +33,11 @@ open class MiauScan(lang: String) : MangaThemesia(
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val genreFilterIndex = filters.indexOfFirst { it is GenreListFilter }
|
||||
val genreFilter = filters.getOrNull(genreFilterIndex) as? GenreListFilter
|
||||
?: GenreListFilter(emptyList())
|
||||
?: GenreListFilter("", emptyList())
|
||||
|
||||
val overloadedGenreFilter = GenreListFilter(
|
||||
genres = genreFilter.state + listOf(
|
||||
genreFilter.name,
|
||||
genreFilter.state + listOf(
|
||||
Genre("", PORTUGUESE_GENRE_ID, portugueseMode),
|
||||
),
|
||||
)
|
||||
|
@ -31,8 +31,8 @@ class Mihentai : MangaThemesia("Mihentai", "https://mihentai.com", "all") {
|
||||
listOf(
|
||||
StatusFilter(),
|
||||
TypeFilter(),
|
||||
OrderByFilter(),
|
||||
GenreListFilter(getGenreList()),
|
||||
OrderByFilter(intl["order_by_filter_title"], orderByFilterOptions),
|
||||
GenreListFilter(intl["genre_filter_title"], getGenreList()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package eu.kanade.tachiyomi.extension.ar.areamanga
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@ -10,21 +9,4 @@ class AreaManga : MangaThemesia(
|
||||
"https://www.areascans.net",
|
||||
"ar",
|
||||
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("ar")),
|
||||
) {
|
||||
override val seriesArtistSelector =
|
||||
".tsinfo .imptdt:contains(الرسام) i, ${super.seriesArtistSelector}"
|
||||
override val seriesAuthorSelector =
|
||||
".tsinfo .imptdt:contains(المؤلف) i, ${super.seriesAuthorSelector}"
|
||||
override val seriesStatusSelector =
|
||||
".tsinfo .imptdt:contains(الحالة) i, ${super.seriesStatusSelector}"
|
||||
override val seriesTypeSelector =
|
||||
".tsinfo .imptdt:contains(النوع) i, ${super.seriesTypeSelector}"
|
||||
|
||||
override fun String?.parseStatus() = when {
|
||||
this == null -> SManga.UNKNOWN
|
||||
this.contains("مستمر", ignoreCase = true) -> SManga.ONGOING
|
||||
this.contains("مكتمل", ignoreCase = true) -> SManga.COMPLETED
|
||||
this.contains("متوقف", ignoreCase = true) -> SManga.ON_HIATUS
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.extension.BuildConfig
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
@ -23,12 +24,14 @@ import java.util.Locale
|
||||
|
||||
private const val swatUrl = "https://swatmanhua.com"
|
||||
|
||||
class MangaSwat : MangaThemesia(
|
||||
"MangaSwat",
|
||||
swatUrl,
|
||||
"ar",
|
||||
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("ar")),
|
||||
) {
|
||||
class MangaSwat :
|
||||
MangaThemesia(
|
||||
"MangaSwat",
|
||||
swatUrl,
|
||||
"ar",
|
||||
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("ar")),
|
||||
),
|
||||
ConfigurableSource {
|
||||
private val defaultBaseUrl = swatUrl
|
||||
|
||||
override val baseUrl by lazy { getPrefBaseUrl() }
|
||||
@ -113,8 +116,6 @@ class MangaSwat : MangaThemesia(
|
||||
}
|
||||
}
|
||||
screen.addPreference(baseUrlPref)
|
||||
|
||||
super.setupPreferenceScreen(screen)
|
||||
}
|
||||
|
||||
private fun getPrefBaseUrl(): String = preferences.getString(BASE_URL_PREF, defaultBaseUrl)!!
|
||||
|
@ -6,6 +6,7 @@ import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
@ -26,12 +27,14 @@ import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class AsuraScans : MangaThemesia(
|
||||
"Asura Scans",
|
||||
"https://asuratoon.com",
|
||||
"en",
|
||||
dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.US),
|
||||
) {
|
||||
class AsuraScans :
|
||||
MangaThemesia(
|
||||
"Asura Scans",
|
||||
"https://asuratoon.com",
|
||||
"en",
|
||||
dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.US),
|
||||
),
|
||||
ConfigurableSource {
|
||||
|
||||
private val preferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
@ -281,8 +284,6 @@ class AsuraScans : MangaThemesia(
|
||||
summary = PREF_PERM_MANGA_URL_SUMMARY
|
||||
setDefaultValue(true)
|
||||
}.also(screen::addPreference)
|
||||
|
||||
super.setupPreferenceScreen(screen)
|
||||
}
|
||||
|
||||
private val SharedPreferences.permaUrlPref
|
||||
|
@ -8,3 +8,7 @@ ext {
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
||||
|
||||
dependencies {
|
||||
implementation(project(":lib:randomua"))
|
||||
}
|
||||
|
@ -2,11 +2,14 @@ package eu.kanade.tachiyomi.extension.en.constellarscans
|
||||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.lib.randomua.addRandomUAPreferenceToScreen
|
||||
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.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
@ -19,22 +22,29 @@ 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") {
|
||||
class ConstellarScans :
|
||||
MangaThemesia(
|
||||
"Constellar Scans",
|
||||
"https://constellarcomic.com",
|
||||
"en",
|
||||
),
|
||||
ConfigurableSource {
|
||||
|
||||
private val preferences: SharedPreferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
}
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
addRandomUAPreferenceToScreen(screen)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
@ -61,6 +71,8 @@ class ConstellarScans : MangaThemesia("Constellar Scans", "https://constellarcom
|
||||
.build()
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
countViews(document)
|
||||
|
||||
val html = document.toString()
|
||||
if (!html.contains("ts_rea_der_._run(\"")) {
|
||||
return super.pageListParse(document)
|
||||
@ -80,7 +92,6 @@ class ConstellarScans : MangaThemesia("Constellar Scans", "https://constellarcom
|
||||
}
|
||||
.joinToString("")
|
||||
|
||||
countViews(document)
|
||||
return json.parseToJsonElement(tsReaderRawData).jsonObject["sources"]!!.jsonArray[0].jsonObject["images"]!!.jsonArray.mapIndexed { idx, it ->
|
||||
Page(idx, imageUrl = it.jsonPrimitive.content)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
@ -25,12 +26,14 @@ import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
class FlameComics : MangaThemesia(
|
||||
"Flame Comics",
|
||||
"https://flamecomics.com",
|
||||
"en",
|
||||
mangaUrlDirectory = "/series",
|
||||
) {
|
||||
class FlameComics :
|
||||
MangaThemesia(
|
||||
"Flame Comics",
|
||||
"https://flamecomics.com",
|
||||
"en",
|
||||
mangaUrlDirectory = "/series",
|
||||
),
|
||||
ConfigurableSource {
|
||||
|
||||
// Flame Scans -> Flame Comics
|
||||
override val id = 6350607071566689772
|
||||
|
@ -6,6 +6,7 @@ import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
@ -20,7 +21,15 @@ import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.IOException
|
||||
|
||||
class LuminousScans : MangaThemesia("Luminous Scans", "https://lumitoon.com", "en", mangaUrlDirectory = "/series") {
|
||||
class LuminousScans :
|
||||
MangaThemesia(
|
||||
"Luminous Scans",
|
||||
"https://lumitoon.com",
|
||||
"en",
|
||||
mangaUrlDirectory = "/series",
|
||||
),
|
||||
ConfigurableSource {
|
||||
|
||||
override val client = super.client.newBuilder()
|
||||
.addInterceptor(::urlChangeInterceptor)
|
||||
.rateLimit(2)
|
||||
@ -201,8 +210,6 @@ class LuminousScans : MangaThemesia("Luminous Scans", "https://lumitoon.com", "e
|
||||
summary = PREF_PERM_MANGA_URL_SUMMARY
|
||||
setDefaultValue(true)
|
||||
}.also(screen::addPreference)
|
||||
|
||||
super.setupPreferenceScreen(screen)
|
||||
}
|
||||
|
||||
private val SharedPreferences.permaUrlPref
|
||||
|
@ -33,19 +33,29 @@ class LunarScans : MangaThemesia(
|
||||
val filters = mutableListOf<Filter<*>>(
|
||||
Filter.Header("Note: Can't be used with text search!"),
|
||||
Filter.Separator(),
|
||||
StatusFilter(),
|
||||
TypeFilter(),
|
||||
OrderByFilter(),
|
||||
Filter.Header("Genre exclusion is not available for all sources"),
|
||||
GenreListFilter(getGenreList()),
|
||||
StatusFilter(intl["status_filter_title"], statusOptions),
|
||||
TypeFilter(intl["type_filter_title"], typeFilterOptions),
|
||||
OrderByFilter(intl["order_by_filter_title"], orderByFilterOptions),
|
||||
)
|
||||
if (!genrelist.isNullOrEmpty()) {
|
||||
filters.addAll(
|
||||
listOf(
|
||||
Filter.Header(intl["genre_exclusion_warning"]),
|
||||
GenreListFilter(intl["genre_filter_title"], getGenreList()),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
filters.add(
|
||||
Filter.Header(intl["genre_missing_warning"]),
|
||||
)
|
||||
}
|
||||
if (hasProjectPage) {
|
||||
filters.addAll(
|
||||
mutableListOf<Filter<*>>(
|
||||
Filter.Separator(),
|
||||
Filter.Header("NOTE: Can't be used with other filter!"),
|
||||
Filter.Header("$name Project List page"),
|
||||
ProjectFilter(),
|
||||
Filter.Header(intl["project_filter_warning"]),
|
||||
Filter.Header(intl.format("project_filter_name", name)),
|
||||
ProjectFilter(intl["project_filter_title"], projectFilterOptions),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -17,14 +17,4 @@ class CarteldeManhwas : MangaThemesia(
|
||||
override fun searchMangaSelector() = ".utao .uta .imgu:not(:has(span.novelabel)), " +
|
||||
".listupd .bs .bsx:not(:has(span.novelabel)), " +
|
||||
".listo .bs .bsx:not(:has(span.novelabel))"
|
||||
|
||||
private class StatusFilter : SelectFilter(
|
||||
"Status",
|
||||
arrayOf(
|
||||
Pair("All", ""),
|
||||
Pair("Ongoing", "ongoing"),
|
||||
Pair("Completed", "completed"),
|
||||
Pair("Hiatus", "hiatus"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
package eu.kanade.tachiyomi.extension.es.gremorymangas
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class GremoryMangas : MangaThemesia("Gremory Mangas", "https://gremorymangas.com", "es")
|
||||
class GremoryMangas : MangaThemesia(
|
||||
"Gremory Mangas",
|
||||
"https://gremorymangas.com",
|
||||
"es",
|
||||
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("es")),
|
||||
)
|
||||
|
@ -25,13 +25,13 @@ class NekoScans : MangaThemesia(
|
||||
override val seriesStatusSelector = ".tsinfo .imptdt:contains(estado) i"
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
countViews(document)
|
||||
|
||||
val chapterUrl = document.location()
|
||||
val htmlPages = document.select(pageSelector)
|
||||
.filterNot { it.imgAttr().isEmpty() }
|
||||
.mapIndexed { i, img -> Page(i, chapterUrl, img.imgAttr()) }
|
||||
|
||||
countViews(document)
|
||||
|
||||
// Some sites also loads pages via javascript
|
||||
if (htmlPages.isNotEmpty()) { return htmlPages }
|
||||
|
||||
|
@ -1,26 +1,14 @@
|
||||
package eu.kanade.tachiyomi.extension.es.senpaiediciones
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class SenpaiEdiciones : MangaThemesia(
|
||||
"Senpai Ediciones",
|
||||
"http://senpaiediciones.com",
|
||||
"https://senpaiediciones.com",
|
||||
"es",
|
||||
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("es")),
|
||||
) {
|
||||
override val seriesAuthorSelector = ".imptdt:contains(Autor) i"
|
||||
override val seriesStatusSelector = ".imptdt:contains(Estado) i"
|
||||
|
||||
override val pageSelector = "div#readerarea img:not(noscript img)"
|
||||
|
||||
override fun String?.parseStatus(): Int = when {
|
||||
this == null -> SManga.UNKNOWN
|
||||
listOf("curso").any { this.contains(it, ignoreCase = true) } -> SManga.ONGOING
|
||||
this.contains("hiatus", ignoreCase = true) -> SManga.ON_HIATUS
|
||||
this.contains("finalizado", ignoreCase = true) -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class CosmicScansID : MangaThemesia("CosmicScans.id", "https://cosmicscans.id",
|
||||
override val hasProjectPage = true
|
||||
override val projectPageString = "/semua-komik"
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl" + if (page > 1) "/page/$page" else "", headers)
|
||||
override fun latestUpdatesRequest(page: Int) = GET(baseUrl + if (page > 1) "/page/$page" else "", headers)
|
||||
|
||||
// search
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
@ -47,8 +47,8 @@ class CosmicScansID : MangaThemesia("CosmicScans.id", "https://cosmicscans.id",
|
||||
val filters = mutableListOf<Filter<*>>(
|
||||
Filter.Separator(),
|
||||
Filter.Header("$name Project List page"),
|
||||
ProjectFilter(),
|
||||
OrderByFilter(),
|
||||
ProjectFilter(intl["project_filter_title"], projectFilterOptions),
|
||||
OrderByFilter(intl["order_by_filter_title"], orderByFilterOptions),
|
||||
)
|
||||
return FilterList(filters)
|
||||
}
|
||||
|
@ -241,12 +241,12 @@ class KomikCast : MangaThemesia("Komik Cast", "https://komikcast.lol", "id", "/d
|
||||
StatusFilter(),
|
||||
TypeFilter(),
|
||||
OrderByFilter(),
|
||||
Filter.Header("Genre exclusion is not available for all sources"),
|
||||
GenreListFilter(getGenreList()),
|
||||
Filter.Header(intl["genre_exclusion_warning"]),
|
||||
GenreListFilter(intl["genre_filter_title"], getGenreList()),
|
||||
Filter.Separator(),
|
||||
Filter.Header("NOTE: Can't be used with other filter!"),
|
||||
Filter.Header("$name Project List page"),
|
||||
ProjectFilter(),
|
||||
Filter.Header(intl["project_filter_warning"]),
|
||||
Filter.Header(intl.format("project_filter_name", name)),
|
||||
ProjectFilter(intl["project_filter_title"], projectFilterOptions),
|
||||
)
|
||||
return FilterList(filters)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package eu.kanade.tachiyomi.extension.ja.mangamate
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@ -12,12 +11,4 @@ class MangaMate : MangaThemesia(
|
||||
dateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("ja")),
|
||||
) {
|
||||
override val seriesAuthorSelector = ".fmed b:contains(作者) + span"
|
||||
override val seriesStatusSelector = ".tsinfo .imptdt:contains(連載状況) i"
|
||||
|
||||
override fun String?.parseStatus(): Int = when (this) {
|
||||
"連載中" -> SManga.ONGOING
|
||||
"完結" -> SManga.COMPLETED
|
||||
"人気" -> SManga.ON_HIATUS
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user