diff --git a/src/en/manhwahentai/build.gradle b/src/en/manhwahentai/build.gradle
new file mode 100644
index 000000000..d4d9b38fc
--- /dev/null
+++ b/src/en/manhwahentai/build.gradle
@@ -0,0 +1,12 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+ext {
+ appName = 'Tachiyomi: Manhwahentai'
+ pkgNameSuffix = 'en.manhwahentai'
+ extClass = '.Manhwahentai'
+ extVersionCode = 1
+ libVersion = '1.2'
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/en/manhwahentai/res/mipmap-anydpi-v26/ic_launcher.xml b/src/en/manhwahentai/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/src/en/manhwahentai/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/en/manhwahentai/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/en/manhwahentai/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/src/en/manhwahentai/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher.png b/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..2d3286cc1
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher_foreground.png b/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..a6815bfb9
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher_round.png b/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..7f10e8d14
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher.png b/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..cdb6b0880
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher_foreground.png b/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..d05e6bb1b
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher_round.png b/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..43ba53ad8
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher.png b/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..48434937c
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher_foreground.png b/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..76153d4ec
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher_round.png b/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..c4c1cfa15
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher.png b/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..51ac95df0
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher_foreground.png b/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..cf66f6e26
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher_round.png b/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..9edd38446
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..1a05ccb74
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..45e83f59e
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher_round.png b/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..64415a26b
Binary files /dev/null and b/src/en/manhwahentai/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/src/en/manhwahentai/res/values/ic_launcher_background.xml b/src/en/manhwahentai/res/values/ic_launcher_background.xml
new file mode 100644
index 000000000..b15a8af4f
--- /dev/null
+++ b/src/en/manhwahentai/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #1A1A1A
+
\ No newline at end of file
diff --git a/src/en/manhwahentai/res/web_hi_res_512.png b/src/en/manhwahentai/res/web_hi_res_512.png
new file mode 100644
index 000000000..595ab7908
Binary files /dev/null and b/src/en/manhwahentai/res/web_hi_res_512.png differ
diff --git a/src/en/manhwahentai/src/eu/kanade/tachiyomi/extension/en/manhwahentai/Manhwahentai.kt b/src/en/manhwahentai/src/eu/kanade/tachiyomi/extension/en/manhwahentai/Manhwahentai.kt
new file mode 100644
index 000000000..3ac12d56e
--- /dev/null
+++ b/src/en/manhwahentai/src/eu/kanade/tachiyomi/extension/en/manhwahentai/Manhwahentai.kt
@@ -0,0 +1,253 @@
+package eu.kanade.tachiyomi.extension.en.manhwahentai
+
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.online.ParsedHttpSource
+import okhttp3.*
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+import java.text.SimpleDateFormat
+import java.util.*
+import eu.kanade.tachiyomi.source.model.*
+import java.text.ParseException
+
+class Manhwahentai: ParsedHttpSource() {
+
+ override val name = "Manhwahentai"
+ override val baseUrl = "https://manhwahentai.com"
+ override val lang = "en"
+ override val supportsLatest = true
+ override val client: OkHttpClient = network.cloudflareClient
+
+ override fun popularMangaRequest(page: Int): Request {
+ return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers)
+ }
+ override fun latestUpdatesRequest(page: Int): Request {
+ return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers)
+ }
+ // LIST SELECTOR
+ override fun popularMangaSelector() = "div.c-tabs-item__content"
+ override fun latestUpdatesSelector() = popularMangaSelector()
+ override fun searchMangaSelector() = popularMangaSelector()
+
+ // ELEMENT
+ override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
+ override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
+
+ // NEXT SELECTOR
+ override fun popularMangaNextPageSelector() = "div.nav-previous.float-left > a"
+ override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
+ override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
+
+ override fun searchMangaFromElement(element: Element):SManga {
+ val manga = SManga.create()
+ manga.thumbnail_url = element.select("div.tab-thumb > a > img").attr("src")
+ element.select("div.tab-thumb > a").first().let {
+ manga.setUrlWithoutDomain(it.attr("href"))
+ manga.title = it.attr("title")
+ }
+ return manga
+ }
+
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+ val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder()
+ url.addQueryParameter("post_type","wp-manga")
+ val pattern = "\\s+".toRegex()
+ val q = query.replace(pattern, "+")
+ if(query.length > 0){
+ url.addQueryParameter("s", q)
+ }else{
+ url.addQueryParameter("s", "")
+ }
+
+ var orderBy = ""
+
+ (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+ when (filter) {
+// is Status -> url.addQueryParameter("manga_status", arrayOf("", "completed", "ongoing")[filter.state])
+ is GenreList -> {
+ val genreInclude = mutableListOf()
+ filter.state.forEach {
+ if (it.state == 1) {
+ genreInclude.add(it.id)
+ }
+ }
+ if(genreInclude.isNotEmpty()){
+ genreInclude.forEach{ genre ->
+ url.addQueryParameter("genre[]", genre)
+ }
+ }
+ }
+ is StatusList ->{
+ val statuses = mutableListOf()
+ filter.state.forEach {
+ if (it.state == 1) {
+ statuses.add(it.id)
+ }
+ }
+ if(statuses.isNotEmpty()){
+ statuses.forEach{ status ->
+ url.addQueryParameter("status[]", status)
+ }
+ }
+ }
+
+ is SortBy -> {
+ orderBy = filter.toUriPart();
+ url.addQueryParameter("m_orderby",orderBy)
+ }
+ is TextField -> url.addQueryParameter(filter.key, filter.state)
+ }
+ }
+
+ return GET(url.toString(), headers)
+ }
+
+
+
+ // max 200 results
+
+ override fun mangaDetailsParse(document: Document): SManga {
+ val infoElement = document.select("div.site-content").first()
+
+ val manga = SManga.create()
+ manga.author = infoElement.select("div.author-content")?.text()
+ manga.artist = infoElement.select("div.artist-content")?.text()
+
+ val genres = mutableListOf()
+ infoElement.select("div.genres-content a").forEach { element ->
+ val genre = element.text()
+ genres.add(genre)
+ }
+ manga.genre =genres.joinToString(", ")
+ manga.status = parseStatus(infoElement.select("div.post-status > div:nth-child(2) div").text())
+
+ manga.description = document.select("div.description-summary")?.text()
+ manga.thumbnail_url = document.select("div.summary_image > a > img").attr("src")
+
+ return manga
+ }
+
+ private fun parseStatus(element: String): Int = when {
+
+ element.toLowerCase().contains("ongoing") -> SManga.ONGOING
+ element.toLowerCase().contains("completed") -> SManga.COMPLETED
+ else -> SManga.UNKNOWN
+ }
+
+ override fun chapterListSelector() = "li.wp-manga-chapter"
+
+ override fun chapterFromElement(element: Element): SChapter {
+ val urlElement = element.select("a").first()
+ val chapter = SChapter.create()
+ chapter.setUrlWithoutDomain(urlElement.attr("href"))
+ chapter.name = urlElement.text()
+ chapter.date_upload = element.select("span.chapter-release-date i").last()?.text()?.let {
+ try {
+ SimpleDateFormat("MMMM dd, yyyy", Locale.US).parse(it).time
+ } catch (e: ParseException) {
+ SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(it).time
+ }
+
+ } ?: 0
+ return chapter
+ }
+
+ override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
+ val basic = Regex("""Chapter\s([0-9]+)""")
+ when {
+ basic.containsMatchIn(chapter.name) -> {
+ basic.find(chapter.name)?.let {
+ chapter.chapter_number = it.groups[1]?.value!!.toFloat()
+ }
+ }
+ }
+ }
+
+ override fun pageListParse(document: Document): List {
+ val pages = mutableListOf()
+ var i = 0
+ document.select("div.reading-content * img").forEach { element ->
+ val url = element.attr("src")
+ i++
+ if(url.length != 0){
+ pages.add(Page(i, "", url))
+ }
+ }
+ return pages
+ }
+
+ override fun imageUrlParse(document: Document) = ""
+
+ override fun imageRequest(page: Page): Request {
+ val imgHeader = Headers.Builder().apply {
+ add("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.1.1; en-gb; Build/KLP) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30")
+ add("Referer", baseUrl)
+ }.build()
+ return GET(page.imageUrl!!, imgHeader)
+ }
+ // private class Status : Filter.TriState("Completed")
+ private class TextField(name: String, val key: String) : Filter.Text(name)
+ private class SortBy : UriPartFilter("Sort by", arrayOf(
+ Pair("Relevance", ""),
+ Pair("Latest", "latest"),
+ Pair("A-Z", "alphabet"),
+ Pair("Rating", "rating"),
+ Pair("Trending", "trending"),
+ Pair("Most View", "views"),
+ Pair("New", "new-manga")
+ ))
+ private class Genre(name: String, val id: String = name) : Filter.TriState(name)
+ private class GenreList(genres: List) : Filter.Group("Genres", genres)
+ private class Status(name: String, val id: String = name) : Filter.TriState(name)
+ private class StatusList(statuses: List) : Filter.Group("Status", statuses)
+
+ override fun getFilterList() = FilterList(
+// TextField("Judul", "title"),
+ TextField("Author", "author"),
+ TextField("Year", "release"),
+ SortBy(),
+ StatusList(getStatusList()),
+ GenreList(getGenreList())
+ )
+ private fun getStatusList() = listOf(
+ Status("Completed","end"),
+ Status("Ongoing","on-going"),
+ Status("Canceled","canceled"),
+ Status("Onhold","on-hold")
+ )
+ private fun getGenreList() = listOf(
+ Genre("Action","action"),
+ Genre("Adventure","adventure"),
+ Genre("Comedy","comedy"),
+ Genre("Drama","drama"),
+ Genre("Fantasy","fantasy"),
+ Genre("Gender bender","gender-bender"),
+ Genre("Gossip","gossip"),
+ Genre("Harem","harem"),
+ Genre("Historical","historical"),
+ Genre("Horror","horror"),
+ Genre("Incest","incest"),
+ Genre("Martial arts","martial-arts"),
+ Genre("Mecha","mecha"),
+ Genre("Medical","medical"),
+ Genre("Mystery","mystery"),
+ Genre("One shot","one-shot"),
+ Genre("Psychological","psychological"),
+ Genre("Romance","romance"),
+ Genre("School LIfe","school-life"),
+ Genre("Sci Fi","sci-fi"),
+ Genre("Slice of Life","slice-of-life"),
+ Genre("Smut","smut"),
+ Genre("Sports","sports"),
+ Genre("Supernatural","supernatural"),
+ Genre("Tragedy","tragedy"),
+ Genre("Yaoi","yaoi"),
+ Genre("Yuri","yuri")
+ )
+ private open class UriPartFilter(displayName: String, val vals: Array>) :
+ Filter.Select(displayName, vals.map { it.first }.toTypedArray()) {
+ fun toUriPart() = vals[state].second
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/id/komikgo/build.gradle b/src/id/komikgo/build.gradle
new file mode 100644
index 000000000..75add5ddf
--- /dev/null
+++ b/src/id/komikgo/build.gradle
@@ -0,0 +1,12 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+ext {
+ appName = 'Tachiyomi: Komikgo'
+ pkgNameSuffix = 'id.komikgo'
+ extClass = '.Komikgo'
+ extVersionCode = 1
+ libVersion = '1.2'
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/id/komikgo/res/mipmap-anydpi-v26/ic_launcher.xml b/src/id/komikgo/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/src/id/komikgo/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/id/komikgo/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/id/komikgo/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/src/id/komikgo/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/id/komikgo/res/mipmap-hdpi/ic_launcher.png b/src/id/komikgo/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..a8e5e239b
Binary files /dev/null and b/src/id/komikgo/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/id/komikgo/res/mipmap-hdpi/ic_launcher_foreground.png b/src/id/komikgo/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..95f973b31
Binary files /dev/null and b/src/id/komikgo/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/src/id/komikgo/res/mipmap-hdpi/ic_launcher_round.png b/src/id/komikgo/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..f584b4b24
Binary files /dev/null and b/src/id/komikgo/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/src/id/komikgo/res/mipmap-mdpi/ic_launcher.png b/src/id/komikgo/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..7ed757857
Binary files /dev/null and b/src/id/komikgo/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/id/komikgo/res/mipmap-mdpi/ic_launcher_foreground.png b/src/id/komikgo/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..e6a6ce985
Binary files /dev/null and b/src/id/komikgo/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/src/id/komikgo/res/mipmap-mdpi/ic_launcher_round.png b/src/id/komikgo/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..3f4da1eaa
Binary files /dev/null and b/src/id/komikgo/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/src/id/komikgo/res/mipmap-xhdpi/ic_launcher.png b/src/id/komikgo/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..e5fe0fd2a
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/id/komikgo/res/mipmap-xhdpi/ic_launcher_foreground.png b/src/id/komikgo/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..23146648c
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/src/id/komikgo/res/mipmap-xhdpi/ic_launcher_round.png b/src/id/komikgo/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..6d892d887
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher.png b/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..32526aef5
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher_foreground.png b/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..36dbe2d3a
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher_round.png b/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..cc66cd0f2
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher.png b/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..b96960fd2
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..81cf30721
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher_round.png b/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..aca6bb631
Binary files /dev/null and b/src/id/komikgo/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/src/id/komikgo/res/values/ic_launcher_background.xml b/src/id/komikgo/res/values/ic_launcher_background.xml
new file mode 100644
index 000000000..b15a8af4f
--- /dev/null
+++ b/src/id/komikgo/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #1A1A1A
+
\ No newline at end of file
diff --git a/src/id/komikgo/res/web_hi_res_512.png b/src/id/komikgo/res/web_hi_res_512.png
new file mode 100644
index 000000000..54876ae38
Binary files /dev/null and b/src/id/komikgo/res/web_hi_res_512.png differ
diff --git a/src/id/komikgo/src/eu/kanade/tachiyomi/extension/id/komikgo/Komikgo.kt b/src/id/komikgo/src/eu/kanade/tachiyomi/extension/id/komikgo/Komikgo.kt
new file mode 100644
index 000000000..23acf46e9
--- /dev/null
+++ b/src/id/komikgo/src/eu/kanade/tachiyomi/extension/id/komikgo/Komikgo.kt
@@ -0,0 +1,288 @@
+package eu.kanade.tachiyomi.extension.id.komikgo
+
+import java.util.*
+import android.util.Log
+import eu.kanade.tachiyomi.network.GET
+import java.text.ParseException
+import eu.kanade.tachiyomi.source.online.ParsedHttpSource
+import okhttp3.*
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+import java.text.SimpleDateFormat
+import eu.kanade.tachiyomi.source.model.*
+
+
+class Komikgo : ParsedHttpSource() {
+
+ override val name = "Komikgo"
+ override val baseUrl = "https://komikgo.com"
+ override val lang = "id"
+ override val supportsLatest = true
+ override val client: OkHttpClient = network.cloudflareClient
+
+ override fun popularMangaRequest(page: Int): Request {
+ return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers)
+ }
+ override fun latestUpdatesRequest(page: Int): Request {
+ return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers)
+ }
+ // LIST SELECTOR
+ override fun popularMangaSelector() = "div.c-tabs-item__content"
+ override fun latestUpdatesSelector() = popularMangaSelector()
+ override fun searchMangaSelector() = popularMangaSelector()
+
+ // ELEMENT
+ override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
+ override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
+
+ // NEXT SELECTOR
+ override fun popularMangaNextPageSelector() = "#navigation-ajax"
+ override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
+ override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
+
+ override fun searchMangaFromElement(element: Element):SManga {
+ val manga = SManga.create()
+ manga.thumbnail_url = element.select("div.tab-thumb > a > img").attr("src")
+ element.select("div.tab-thumb > a").first().let {
+ manga.setUrlWithoutDomain(it.attr("href"))
+ manga.title = it.attr("title")
+ }
+ return manga
+ }
+
+
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+ val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder()
+ url.addQueryParameter("post_type","wp-manga")
+ val pattern = "\\s+".toRegex()
+ val q = query.replace(pattern, "+")
+ if(query.length > 0){
+ url.addQueryParameter("s", q)
+ }else{
+ url.addQueryParameter("s", "")
+ }
+
+ var orderBy = ""
+
+ (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+ when (filter) {
+// is Status -> url.addQueryParameter("manga_status", arrayOf("", "completed", "ongoing")[filter.state])
+ is GenreList -> {
+ val genreInclude = mutableListOf()
+ filter.state.forEach {
+ if (it.state == 1) {
+ genreInclude.add(it.id)
+ }
+ }
+ if(genreInclude.isNotEmpty()){
+ genreInclude.forEach{ genre ->
+ url.addQueryParameter("genre[]", genre)
+ }
+ }
+ }
+ is StatusList ->{
+ val statuses = mutableListOf()
+ filter.state.forEach {
+ if (it.state == 1) {
+ statuses.add(it.id)
+ }
+ }
+ if(statuses.isNotEmpty()){
+ statuses.forEach{ status ->
+ url.addQueryParameter("status[]", status)
+ }
+ }
+ }
+
+ is SortBy -> {
+ orderBy = filter.toUriPart();
+ url.addQueryParameter("m_orderby",orderBy)
+ }
+ is TextField -> url.addQueryParameter(filter.key, filter.state)
+ }
+ }
+ Log.d("TAG", url.toString())
+
+ return GET(url.toString(), headers)
+ }
+
+
+
+ // max 200 results
+
+ override fun mangaDetailsParse(document: Document): SManga {
+ val infoElement = document.select("div.site-content").first()
+
+ val manga = SManga.create()
+ manga.author = infoElement.select("div.author-content")?.text()
+ manga.artist = infoElement.select("div.artist-content")?.text()
+
+ val genres = mutableListOf()
+ infoElement.select("div.genres-content a").forEach { element ->
+ val genre = element.text()
+ genres.add(genre)
+ }
+ manga.genre =genres.joinToString(", ")
+ manga.status = parseStatus(infoElement.select("div.post-status > div:nth-child(2) div").text())
+
+ manga.description = document.select("div.description-summary")?.text()
+ manga.thumbnail_url = document.select("div.summary_image > a > img").attr("src")
+
+ return manga
+ }
+
+ private fun parseStatus(element: String): Int = when {
+
+ element.toLowerCase().contains("ongoing") -> SManga.ONGOING
+ element.toLowerCase().contains("completed") -> SManga.COMPLETED
+ else -> SManga.UNKNOWN
+ }
+
+ override fun chapterListSelector() = "li.wp-manga-chapter"
+
+ override fun chapterFromElement(element: Element): SChapter {
+ val urlElement = element.select("a").first()
+ val chapter = SChapter.create()
+ chapter.setUrlWithoutDomain(urlElement.attr("href"))
+ chapter.name = urlElement.text()
+ chapter.date_upload = element.select("span.chapter-release-date i").last()?.text()?.let {
+ try {
+ SimpleDateFormat("MMMM dd, yyyy", Locale.US).parse(it).time
+ } catch (e: ParseException) {
+ SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(it).time
+ }
+
+ } ?: 0
+ return chapter
+ }
+
+ override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
+ val basic = Regex("""Chapter\s([0-9]+)""")
+ when {
+ basic.containsMatchIn(chapter.name) -> {
+ basic.find(chapter.name)?.let {
+ chapter.chapter_number = it.groups[1]?.value!!.toFloat()
+ }
+ }
+ }
+ }
+
+ override fun pageListParse(document: Document): List {
+ val pages = mutableListOf()
+ var i = 0
+ document.select("div.reading-content * img").forEach { element ->
+ val url = element.attr("src")
+ i++
+ if(url.length != 0){
+ pages.add(Page(i, "", url))
+ }
+ }
+ return pages
+ }
+
+ override fun imageUrlParse(document: Document) = ""
+
+ override fun imageRequest(page: Page): Request {
+ val imgHeader = Headers.Builder().apply {
+ add("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.1.1; en-gb; Build/KLP) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30")
+ add("Referer", baseUrl)
+ }.build()
+ return GET(page.imageUrl!!, imgHeader)
+ }
+ // private class Status : Filter.TriState("Completed")
+ private class TextField(name: String, val key: String) : Filter.Text(name)
+ private class SortBy : UriPartFilter("Sort by", arrayOf(
+ Pair("Relevance", ""),
+ Pair("Latest", "latest"),
+ Pair("A-Z", "alphabet"),
+ Pair("Rating", "rating"),
+ Pair("Trending", "trending"),
+ Pair("Most View", "views"),
+ Pair("New", "new-manga")
+ ))
+ private class Genre(name: String, val id: String = name) : Filter.TriState(name)
+ private class GenreList(genres: List) : Filter.Group("Genres", genres)
+ private class Status(name: String, val id: String = name) : Filter.TriState(name)
+ private class StatusList(statuses: List) : Filter.Group("Status", statuses)
+
+ override fun getFilterList() = FilterList(
+// TextField("Judul", "title"),
+ TextField("Author", "author"),
+ TextField("Year", "release"),
+ SortBy(),
+ StatusList(getStatusList()),
+ GenreList(getGenreList())
+ )
+ private fun getStatusList() = listOf(
+ Status("Completed","end"),
+ Status("Ongoing","on-going"),
+ Status("Canceled","canceled"),
+ Status("Onhold","on-hold")
+ )
+ private fun getGenreList() = listOf(
+ Genre("Adventure", "Adventure"),
+ Genre( "Action", "action"),
+ Genre( "Adventure", "adventure"),
+ Genre( "Cars", "cars"),
+ Genre( "4-Koma", "4-koma"),
+ Genre( "Comedy", "comedy"),
+ Genre( "Completed", "completed"),
+ Genre( "Cooking", "cooking"),
+ Genre( "Dementia", "dementia"),
+ Genre( "Demons", "demons"),
+ Genre( "Doujinshi", "doujinshi"),
+ Genre( "Drama", "drama"),
+ Genre( "Ecchi", "ecchi"),
+ Genre( "Fantasy", "fantasy"),
+ Genre( "Game", "game"),
+ Genre( "Gender Bender", "gender-bender"),
+ Genre( "Harem", "harem"),
+ Genre( "Historical", "historical"),
+ Genre( "Horror", "horror"),
+ Genre( "Isekai", "isekai"),
+ Genre( "Josei", "josei"),
+ Genre( "Kids", "kids"),
+ Genre( "Magic", "magic"),
+ Genre( "Manga", "manga"),
+ Genre( "Manhua", "manhua"),
+ Genre( "Manhwa", "manhwa"),
+ Genre( "Martial Arts", "martial-arts"),
+ Genre( "Mature", "mature"),
+ Genre( "Mecha", "mecha"),
+ Genre( "Military", "military"),
+ Genre( "Music", "music"),
+ Genre( "Mystery", "mystery"),
+ Genre( "Old Comic", "old-comic"),
+ Genre( "One Shot", "one-shot"),
+ Genre( "Oneshot", "oneshot"),
+ Genre( "Parodi", "parodi"),
+ Genre( "Parody", "parody"),
+ Genre( "Police", "police"),
+ Genre( "Psychological", "psychological"),
+ Genre( "Romance", "romance"),
+ Genre( "Samurai", "samurai"),
+ Genre( "School", "school"),
+ Genre( "School Life", "school-life"),
+ Genre( "Sci-Fi", "sci-fi"),
+ Genre( "Seinen", "seinen"),
+ Genre( "Shoujo", "shoujo"),
+ Genre( "Shoujo Ai", "shoujo-ai"),
+ Genre( "Shounen", "shounen"),
+ Genre( "Shounen ai", "shounen-ai"),
+ Genre( "Slice of Life", "slice-of-life"),
+ Genre( "Sports", "sports"),
+ Genre( "Super Power", "super-power"),
+ Genre( "Supernatural", "supernatural"),
+ Genre( "Thriller", "thriller"),
+ Genre( "Tragedy", "tragedy"),
+ Genre( "Vampire", "vampire"),
+ Genre( "Webtoons", "webtoons"),
+ Genre( "Yaoi", "yaoi"),
+ Genre( "Yuri", "yuri")
+ )
+ private open class UriPartFilter(displayName: String, val vals: Array>) :
+ Filter.Select(displayName, vals.map { it.first }.toTypedArray()) {
+ fun toUriPart() = vals[state].second
+ }
+
+}
\ No newline at end of file
diff --git a/src/ko/manhwahand/build.gradle b/src/ko/manhwahand/build.gradle
new file mode 100644
index 000000000..d1136c17a
--- /dev/null
+++ b/src/ko/manhwahand/build.gradle
@@ -0,0 +1,12 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+ext {
+ appName = 'Tachiyomi: Manhwahand'
+ pkgNameSuffix = 'ko.manhwahand'
+ extClass = '.Manhwahand'
+ extVersionCode = 1
+ libVersion = '1.2'
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/ko/manhwahand/res/mipmap-anydpi-v26/ic_launcher.xml b/src/ko/manhwahand/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/src/ko/manhwahand/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ko/manhwahand/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/ko/manhwahand/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/src/ko/manhwahand/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher.png b/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..79f396016
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher_foreground.png b/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..27234a0f2
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher_round.png b/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..b4270a220
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher.png b/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..eee7884f0
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher_foreground.png b/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..8676e233e
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher_round.png b/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..0f69b26bc
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher.png b/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..9136e3f44
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher_foreground.png b/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..51d038786
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher_round.png b/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..43df3d91e
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher.png b/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..e4e36bdc4
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher_foreground.png b/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..daa8f60aa
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher_round.png b/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..7824e5824
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher.png b/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..685a637b9
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..bb7d42312
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher_round.png b/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..8b8c09553
Binary files /dev/null and b/src/ko/manhwahand/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/src/ko/manhwahand/res/values/ic_launcher_background.xml b/src/ko/manhwahand/res/values/ic_launcher_background.xml
new file mode 100644
index 000000000..b15a8af4f
--- /dev/null
+++ b/src/ko/manhwahand/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #1A1A1A
+
\ No newline at end of file
diff --git a/src/ko/manhwahand/res/web_hi_res_512.png b/src/ko/manhwahand/res/web_hi_res_512.png
new file mode 100644
index 000000000..06edd7757
Binary files /dev/null and b/src/ko/manhwahand/res/web_hi_res_512.png differ
diff --git a/src/ko/manhwahand/src/eu/kanade/tachiyomi/extension/ko/manhwahand/Manhwahand.kt b/src/ko/manhwahand/src/eu/kanade/tachiyomi/extension/ko/manhwahand/Manhwahand.kt
new file mode 100644
index 000000000..62a76afe3
--- /dev/null
+++ b/src/ko/manhwahand/src/eu/kanade/tachiyomi/extension/ko/manhwahand/Manhwahand.kt
@@ -0,0 +1,251 @@
+package eu.kanade.tachiyomi.extension.ko.manhwahand
+
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.*
+import eu.kanade.tachiyomi.source.online.ParsedHttpSource
+import java.util.*
+import okhttp3.*
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+import java.text.SimpleDateFormat
+import java.text.ParseException
+
+
+class Manhwahand : ParsedHttpSource() {
+
+ override val name = "Manhwahand"
+ override val baseUrl = "https://manhwahand.com/"
+ override val lang = "ko"
+ override val supportsLatest = true
+ override val client: OkHttpClient = network.cloudflareClient
+
+ override fun popularMangaRequest(page: Int): Request {
+ return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers)
+ }
+ override fun latestUpdatesRequest(page: Int): Request {
+ return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers)
+ }
+ // LIST SELECTOR
+ override fun popularMangaSelector() = "div.c-tabs-item__content"
+ override fun latestUpdatesSelector() = popularMangaSelector()
+ override fun searchMangaSelector() = popularMangaSelector()
+
+ // ELEMENT
+ override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
+ override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
+
+ // NEXT SELECTOR
+ override fun popularMangaNextPageSelector() = "div.nav-previous.float-left > a"
+ override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
+ override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
+
+ override fun searchMangaFromElement(element: Element):SManga {
+ val manga = SManga.create()
+ manga.thumbnail_url = element.select("div.tab-thumb > a > img").attr("src")
+ element.select("div.tab-thumb > a").first().let {
+ manga.setUrlWithoutDomain(it.attr("href"))
+ manga.title = it.attr("title")
+ }
+ return manga
+ }
+
+
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+ val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder()
+ url.addQueryParameter("post_type","wp-manga")
+ val pattern = "\\s+".toRegex()
+ val q = query.replace(pattern, "+")
+ if(query.length > 0){
+ url.addQueryParameter("s", q)
+ }else{
+ url.addQueryParameter("s", "")
+ }
+
+ var orderBy = ""
+
+ (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+ when (filter) {
+// is Status -> url.addQueryParameter("manga_status", arrayOf("", "completed", "ongoing")[filter.state])
+ is GenreList -> {
+ val genreInclude = mutableListOf()
+ filter.state.forEach {
+ if (it.state == 1) {
+ genreInclude.add(it.id)
+ }
+ }
+ if(genreInclude.isNotEmpty()){
+ genreInclude.forEach{ genre ->
+ url.addQueryParameter("genre[]", genre)
+ }
+ }
+ }
+ is StatusList ->{
+ val statuses = mutableListOf()
+ filter.state.forEach {
+ if (it.state == 1) {
+ statuses.add(it.id)
+ }
+ }
+ if(statuses.isNotEmpty()){
+ statuses.forEach{ status ->
+ url.addQueryParameter("status[]", status)
+ }
+ }
+ }
+
+ is SortBy -> {
+ orderBy = filter.toUriPart();
+ url.addQueryParameter("m_orderby",orderBy)
+ }
+ is TextField -> url.addQueryParameter(filter.key, filter.state)
+ }
+ }
+ return GET(url.toString(), headers)
+ }
+
+
+
+ // max 200 results
+
+ override fun mangaDetailsParse(document: Document): SManga {
+ val infoElement = document.select("div.site-content").first()
+
+ val manga = SManga.create()
+ manga.author = infoElement.select("div.author-content")?.text()
+ manga.artist = infoElement.select("div.artist-content")?.text()
+
+ val genres = mutableListOf()
+ infoElement.select("div.genres-content a").forEach { element ->
+ val genre = element.text()
+ genres.add(genre)
+ }
+ manga.genre =genres.joinToString(", ")
+ manga.status = parseStatus(infoElement.select("div.post-status > div:nth-child(2) div").text())
+
+ manga.description = document.select("div.description-summary")?.text()
+ manga.thumbnail_url = document.select("div.summary_image > a > img").attr("src")
+
+ return manga
+ }
+
+ private fun parseStatus(element: String): Int = when {
+
+ element.toLowerCase().contains("ongoing") -> SManga.ONGOING
+ element.toLowerCase().contains("completed") -> SManga.COMPLETED
+ else -> SManga.UNKNOWN
+ }
+
+ override fun chapterListSelector() = "li.wp-manga-chapter"
+
+ override fun chapterFromElement(element: Element): SChapter {
+ val urlElement = element.select("a").first()
+ val chapter = SChapter.create()
+ chapter.setUrlWithoutDomain(urlElement.attr("href"))
+ chapter.name = urlElement.text()
+ chapter.date_upload = element.select("span.chapter-release-date i").last()?.text()?.let {
+ try {
+ SimpleDateFormat("MMMM dd, yyyy", Locale.US).parse(it).time
+ } catch (e: ParseException) {
+ SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(it).time
+ }
+
+ } ?: 0
+ return chapter
+ }
+
+ override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
+ val basic = Regex("""Chapter\s([0-9]+)""")
+ when {
+ basic.containsMatchIn(chapter.name) -> {
+ basic.find(chapter.name)?.let {
+ chapter.chapter_number = it.groups[1]?.value!!.toFloat()
+ }
+ }
+ }
+ }
+
+ override fun pageListParse(document: Document): List {
+ val pages = mutableListOf()
+ var i = 0
+ document.select("div.reading-content * img").forEach { element ->
+ val url = element.attr("src")
+ i++
+ if(url.length != 0){
+ pages.add(Page(i, "", url))
+ }
+ }
+ return pages
+ }
+
+ override fun imageUrlParse(document: Document) = ""
+
+ override fun imageRequest(page: Page): Request {
+ val imgHeader = Headers.Builder().apply {
+ add("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.1.1; en-gb; Build/KLP) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30")
+ add("Referer", baseUrl)
+ }.build()
+ return GET(page.imageUrl!!, imgHeader)
+ }
+ // private class Status : Filter.TriState("Completed")
+ private class TextField(name: String, val key: String) : Filter.Text(name)
+ private class SortBy : UriPartFilter("Sort by", arrayOf(
+ Pair("Relevance", ""),
+ Pair("Latest", "latest"),
+ Pair("A-Z", "alphabet"),
+ Pair("Rating", "rating"),
+ Pair("Trending", "trending"),
+ Pair("Most View", "views"),
+ Pair("New", "new-manga")
+ ))
+ private class Genre(name: String, val id: String = name) : Filter.TriState(name)
+ private class GenreList(genres: List) : Filter.Group("Genres", genres)
+ private class Status(name: String, val id: String = name) : Filter.TriState(name)
+ private class StatusList(statuses: List) : Filter.Group("Status", statuses)
+
+ override fun getFilterList() = FilterList(
+// TextField("Judul", "title"),
+ TextField("Author", "author"),
+ TextField("Year", "release"),
+ SortBy(),
+ StatusList(getStatusList()),
+ GenreList(getGenreList())
+ )
+ private fun getStatusList() = listOf(
+ Status("Completed","end"),
+ Status("Ongoing","on-going"),
+ Status("Canceled","canceled"),
+ Status("Onhold","on-hold")
+ )
+ private fun getGenreList() = listOf(
+ Genre("Action","action"),
+ Genre("Adventure","adventure"),
+ Genre("Bondage","bondage"),
+ Genre("Celebrity","celebrity"),
+ Genre("Comedy","comedy"),
+ Genre("Crime","crime"),
+ Genre("Drama","drama"),
+ Genre("Fantasy","fantasy"),
+ Genre("Gossip","gossip"),
+ Genre("Harem","harem"),
+ Genre("Historical","historical"),
+ Genre("Horror","horror"),
+ Genre("Mystery","mystery"),
+ Genre("Psychological","psychological"),
+ Genre("Romance","romance"),
+ Genre("School Life","school-life"),
+ Genre("Sci-fi","sci-fi"),
+ Genre("Slice of Life","slice-of-life"),
+ Genre("Smut","smut"),
+ Genre("Sports","sports"),
+ Genre("Supernatural","supernatural"),
+ Genre("Tragedy","tragedy"),
+ Genre("Voyeur","voyeur"),
+ Genre("Webtoon","webtoon")
+ )
+ private open class UriPartFilter(displayName: String, val vals: Array>) :
+ Filter.Select(displayName, vals.map { it.first }.toTypedArray()) {
+ fun toUriPart() = vals[state].second
+ }
+
+
+}
\ No newline at end of file