From cbe5dac026b55d3512f94c59c44bf482e362774c Mon Sep 17 00:00:00 2001
From: DitFranXX <45893338+DitFranXX@users.noreply.github.com>
Date: Fri, 19 Feb 2021 23:03:01 +0900
Subject: [PATCH] Update Newtoki Extension to v1.2.20 (#5917)

* Update Newtoki Extension to v1.2.20

* Better RateLimit
* New Search filter for ManaToki.

* Fix Page Selector and Filters

* Order was not worked on default sort due to missing value
* Page is now searchable over 10 pages. Seems site changed a bit.

* Backport Sort and Order to NewToki
---
 src/ko/newtoki/build.gradle                   |  2 +-
 .../extension/ko/newtoki/ManaToki.kt          | 74 +++++++++++++------
 .../tachiyomi/extension/ko/newtoki/NewToki.kt | 24 +-----
 .../extension/ko/newtoki/NewTokiFactory.kt    | 29 +++++++-
 4 files changed, 85 insertions(+), 44 deletions(-)

diff --git a/src/ko/newtoki/build.gradle b/src/ko/newtoki/build.gradle
index e0bbe5d22..7b160febe 100644
--- a/src/ko/newtoki/build.gradle
+++ b/src/ko/newtoki/build.gradle
@@ -5,7 +5,7 @@ ext {
     extName = 'NewToki / ManaToki'
     pkgNameSuffix = 'ko.newtoki'
     extClass = '.NewTokiFactory'
-    extVersionCode = 19
+    extVersionCode = 20
     libVersion = '1.2'
 }
 
diff --git a/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/ManaToki.kt b/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/ManaToki.kt
index 63c0d162d..0468141e7 100644
--- a/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/ManaToki.kt
+++ b/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/ManaToki.kt
@@ -16,7 +16,7 @@ import rx.Observable
 import java.util.concurrent.TimeUnit
 
 /*
- * ManaToki Is too big to support in a Factory File., So split into separate file.
+ * ManaToki is too big to support in a Factory File., So split into separate file.
  */
 
 class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domainNumber.net", "comic") {
@@ -104,10 +104,7 @@ class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domai
     override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
         val url = HttpUrl.parse("$baseUrl/comic" + (if (page > 1) "/p$page" else ""))!!.newBuilder()
 
-        if (!query.isBlank()) {
-            url.addQueryParameter("stx", query)
-            return GET(url.toString())
-        }
+        val genres = mutableListOf<String>()
 
         filters.forEach { filter ->
             when (filter) {
@@ -124,33 +121,54 @@ class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domai
                 }
 
                 is SearchGenreTypeList -> {
-                    if (filter.state > 0) {
-                        url.addQueryParameter("tag", filter.values[filter.state])
+                    filter.state.forEach {
+                        if (it.state) {
+                            genres.add(it.id)
+                        }
                     }
                 }
+
+                is SearchSortTypeList -> {
+                    url.addQueryParameter("sst", listOf("wr_datetime", "wr_hit", "wr_good", "as_update")[filter.state])
+                }
+
+                is SearchOrderTypeList -> {
+                    url.addQueryParameter("sod", listOf("desc", "asc")[filter.state])
+                }
             }
         }
 
+        if (query.isNotBlank()) {
+            url.addQueryParameter("stx", query)
+
+            // Remove some filter QueryParams that not working with query
+            url.setQueryParameter("publish", null)
+            url.setQueryParameter("jaum", null)
+
+            return GET(url.toString())
+        }
+
+        url.addQueryParameter("tag", genres.joinToString(","))
         return GET(url.toString())
     }
 
-    // [...document.querySelectorAll("form.form td")[2].querySelectorAll("a")].map((el, i) => `"${el.innerText.trim()}"`).join(',\n')
+    private class SearchCheckBox(name: String, val id: String = name) : Filter.CheckBox(name)
+
+    // [...document.querySelectorAll("form.form td")[3].querySelectorAll("span.btn")].map((el, i) => `"${el.innerText.trim()}"`).join(',\n')
     private class SearchPublishTypeList : Filter.Select<String>(
         "Publish",
         arrayOf(
             "전체",
-            "미분류",
             "주간",
             "격주",
             "월간",
-            "격월/비정기",
             "단편",
             "단행본",
             "완결"
         )
     )
 
-    // [...document.querySelectorAll("form.form td")[3].querySelectorAll("a")].map((el, i) => `"${el.innerText.trim()}"`).join(',\n')
+    // [...document.querySelectorAll("form.form td")[4].querySelectorAll("span.btn")].map((el, i) => `"${el.innerText.trim()}"`).join(',\n')
     private class SearchJaumTypeList : Filter.Select<String>(
         "Jaum",
         arrayOf(
@@ -174,9 +192,9 @@ class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domai
         )
     )
 
-    // [...document.querySelectorAll("form.form td")[4].querySelectorAll("a")].map((el, i) => `"${el.innerText.trim()}"`).join(',\n')
-    private class SearchGenreTypeList : Filter.Select<String>(
-        "Genre",
+    // [...document.querySelectorAll("form.form td")[6].querySelectorAll("span.btn")].map((el, i) => `"${el.innerText.trim()}"`).join(',\n')
+    private class SearchGenreTypeList : Filter.Group<SearchCheckBox>(
+        "Genres",
         arrayOf(
             "전체",
             "17",
@@ -185,40 +203,54 @@ class ManaToki(domainNumber: Long) : NewToki("ManaToki", "https://manatoki$domai
             "TS",
             "개그",
             "게임",
-            "공포",
             "도박",
             "드라마",
             "라노벨",
             "러브코미디",
-            "로맨스",
             "먹방",
-            "미스터리",
             "백합",
             "붕탁",
-            "성인",
             "순정",
             "스릴러",
             "스포츠",
             "시대",
             "애니화",
             "액션",
-            "역사",
             "음악",
             "이세계",
             "일상",
-            "일상+치유",
             "전생",
             "추리",
             "판타지",
             "학원",
             "호러"
+        ).map { SearchCheckBox(it) }
+    )
+
+    private class SearchSortTypeList : Filter.Select<String>(
+        "Sort",
+        arrayOf(
+            "기본",
+            "인기순",
+            "추천순",
+            "업데이트순"
+        )
+    )
+
+    private class SearchOrderTypeList : Filter.Select<String>(
+        "Order",
+        arrayOf(
+            "Descending",
+            "Ascending"
         )
     )
 
     override fun getFilterList() = FilterList(
-        Filter.Header("Filter can't use with query"),
+        Filter.Header("Some filters can't use with query"),
         SearchPublishTypeList(),
         SearchJaumTypeList(),
+        SearchSortTypeList(),
+        SearchOrderTypeList(),
         SearchGenreTypeList()
     )
 }
diff --git a/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewToki.kt b/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewToki.kt
index ade739277..2e55e7c36 100644
--- a/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewToki.kt
+++ b/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewToki.kt
@@ -42,7 +42,7 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
     override val supportsLatest = true
     override val client: OkHttpClient = network.cloudflareClient
     protected val rateLimitedClient: OkHttpClient = network.cloudflareClient.newBuilder()
-        .addNetworkInterceptor(RateLimitInterceptor(2, 5))
+        .addNetworkInterceptor(RateLimitInterceptor(1))
         .build()
 
     override fun popularMangaSelector() = "div#webtoon-list > ul > li"
@@ -57,31 +57,14 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
         return manga
     }
 
-    override fun popularMangaNextPageSelector() = "ul.pagination > li:not(.disabled)"
+    override fun popularMangaNextPageSelector() = "ul.pagination > li:last-child:not(.disabled)"
 
     // Do not add page parameter if page is 1 to prevent tracking.
     override fun popularMangaRequest(page: Int) = GET("$baseUrl/$boardName" + if (page > 1) "/p$page" else "")
 
-    override fun popularMangaParse(response: Response): MangasPage {
-        val document = response.asJsoup()
-
-        val mangas = document.select(popularMangaSelector()).map { element ->
-            popularMangaFromElement(element)
-        }
-
-        val hasNextPage = try {
-            !document.select(popularMangaNextPageSelector()).last().hasClass("active")
-        } catch (_: Exception) {
-            false
-        }
-
-        return MangasPage(mangas, hasNextPage)
-    }
-
     override fun searchMangaSelector() = popularMangaSelector()
     override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
-    override fun searchMangaNextPageSelector() = popularMangaSelector()
-    override fun searchMangaParse(response: Response) = popularMangaParse(response)
+    override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
     override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/$boardName" + (if (page > 1) "/p$page" else "") + "?stx=$query")
     override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
         return if (query.startsWith(PREFIX_ID_SEARCH)) {
@@ -253,7 +236,6 @@ open class NewToki(override val name: String, private val defaultBaseUrl: String
     override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
     override fun latestUpdatesRequest(page: Int) = popularMangaRequest(page)
     override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
-    override fun latestUpdatesParse(response: Response) = popularMangaParse(response)
 
     // We are able to get the image URL directly from the page list
     override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("This method should not be called!")
diff --git a/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewTokiFactory.kt b/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewTokiFactory.kt
index 7c8cf74a7..ea3db32f0 100644
--- a/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewTokiFactory.kt
+++ b/src/ko/newtoki/src/eu/kanade/tachiyomi/extension/ko/newtoki/NewTokiFactory.kt
@@ -42,10 +42,18 @@ class NewTokiWebtoon : NewToki("NewToki", "https://newtoki$domainNumber.com", "w
                         url.addQueryParameter("toon", filter.values[filter.state])
                     }
                 }
+
+                is SearchSortTypeList -> {
+                    url.addQueryParameter("sst", listOf("as_update", "wr_hit", "wr_good")[filter.state])
+                }
+
+                is SearchOrderTypeList -> {
+                    url.addQueryParameter("sod", listOf("desc", "asc")[filter.state])
+                }
             }
         }
 
-        // Imcompatible with Other Search Parametor
+        // Incompatible with Other Search Parameter
         if (!query.isBlank()) {
             url.addQueryParameter("stx", query)
         } else {
@@ -135,8 +143,27 @@ class NewTokiWebtoon : NewToki("NewToki", "https://newtoki$domainNumber.com", "w
         )
     )
 
+    private class SearchSortTypeList : Filter.Select<String>(
+        "Sort",
+        arrayOf(
+            "기본",
+            "인기순",
+            "추천순",
+        )
+    )
+
+    private class SearchOrderTypeList : Filter.Select<String>(
+        "Order",
+        arrayOf(
+            "Descending",
+            "Ascending"
+        )
+    )
+
     override fun getFilterList() = FilterList(
         SearchTargetTypeList(),
+        SearchSortTypeList(),
+        SearchOrderTypeList(),
         Filter.Separator(),
         Filter.Header("Under 3 Filters can't use with query"),
         SearchYoilTypeList(),