Update Korean extensions (#1024)
JMana: Temporary pagination fix. MSM: Improve image decoder(which don't modifying url anymore), Use `s3` and `img_list1` as fallback, Fix description issue, and Update filter and domain NewToki: Move to Factory, Add Webtoon Source(Not tested), and Update domain.
This commit is contained in:
		
							parent
							
								
									cec1a82ce4
								
							
						
					
					
						commit
						d8c84d3813
					
				@ -5,7 +5,7 @@ ext {
 | 
			
		||||
    appName = 'Tachiyomi: JMana'
 | 
			
		||||
    pkgNameSuffix = 'ko.jmana'
 | 
			
		||||
    extClass = '.JMana'
 | 
			
		||||
    extVersionCode = 6
 | 
			
		||||
    extVersionCode = 7
 | 
			
		||||
    libVersion = '1.2'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -49,12 +49,8 @@ class JMana : ParsedHttpSource() {
 | 
			
		||||
            popularMangaFromElement(element)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val hasNextPage = try {
 | 
			
		||||
            val page = document.select(popularMangaNextPageSelector())
 | 
			
		||||
            !page[page.size - 2].getElementsByTag("a").attr("href").isNullOrEmpty()
 | 
			
		||||
        } catch (_: Exception) {
 | 
			
		||||
            false
 | 
			
		||||
        }
 | 
			
		||||
        // Can not detect what page is last page but max mangas are 40.
 | 
			
		||||
        val hasNextPage = mangas.size == 40
 | 
			
		||||
 | 
			
		||||
        return MangasPage(mangas, hasNextPage)
 | 
			
		||||
    }
 | 
			
		||||
@ -130,10 +126,20 @@ class JMana : ParsedHttpSource() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun latestUpdatesSelector() = popularMangaSelector()
 | 
			
		||||
    override fun latestUpdatesParse(response: Response) = popularMangaParse(response)
 | 
			
		||||
    override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
 | 
			
		||||
    override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/frame")
 | 
			
		||||
    override fun latestUpdatesNextPageSelector() = ""
 | 
			
		||||
    override fun latestUpdatesParse(response: Response): MangasPage {
 | 
			
		||||
        val document = response.asJsoup()
 | 
			
		||||
 | 
			
		||||
        val mangas = document.select(popularMangaSelector()).map { element ->
 | 
			
		||||
            popularMangaFromElement(element)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val hasNextPage = false
 | 
			
		||||
 | 
			
		||||
        return MangasPage(mangas, hasNextPage)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //We are able to get the image URL directly from the page list
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ ext {
 | 
			
		||||
    appName = 'Tachiyomi: MangaShow.Me (ManaMoa)'
 | 
			
		||||
    pkgNameSuffix = 'ko.mangashowme'
 | 
			
		||||
    extClass = '.MangaShowMe'
 | 
			
		||||
    extVersionCode = 9
 | 
			
		||||
    extVersionCode = 10
 | 
			
		||||
    libVersion = '1.2'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,6 @@ private fun searchNaming() = arrayOf(
 | 
			
		||||
 | 
			
		||||
private fun searchStatus() = arrayOf(
 | 
			
		||||
        "Not Set",
 | 
			
		||||
        "미분류",
 | 
			
		||||
        "주간",
 | 
			
		||||
        "격주",
 | 
			
		||||
        "월간",
 | 
			
		||||
@ -65,7 +64,6 @@ private fun searchGenres() = listOf(
 | 
			
		||||
        SearchCheckBox(0, "드라마"),
 | 
			
		||||
        SearchCheckBox(0, "라노벨"),
 | 
			
		||||
        SearchCheckBox(0, "러브코미디"),
 | 
			
		||||
        SearchCheckBox(0, "로맨스"),
 | 
			
		||||
        SearchCheckBox(0, "먹방"),
 | 
			
		||||
        SearchCheckBox(0, "백합"),
 | 
			
		||||
        SearchCheckBox(0, "붕탁"),
 | 
			
		||||
@ -76,7 +74,6 @@ private fun searchGenres() = listOf(
 | 
			
		||||
        SearchCheckBox(0, "애니화"),
 | 
			
		||||
        SearchCheckBox(0, "액션"),
 | 
			
		||||
        SearchCheckBox(0, "역사"),
 | 
			
		||||
        SearchCheckBox(0, "요리"),
 | 
			
		||||
        SearchCheckBox(0, "음악"),
 | 
			
		||||
        SearchCheckBox(0, "이세계"),
 | 
			
		||||
        SearchCheckBox(0, "일상"),
 | 
			
		||||
@ -94,7 +91,7 @@ fun getFilters() = FilterList(
 | 
			
		||||
        Filter.Separator(),
 | 
			
		||||
        SearchMatch(),
 | 
			
		||||
        Filter.Separator(),
 | 
			
		||||
        TextField("Author/Artist (Exact Search)", "author")
 | 
			
		||||
        TextField("Author/Artist (Exact search)", "author")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
fun searchComplexFilterMangaRequestBuilder(baseUrl: String, page: Int, query: String, filters: FilterList): Request {
 | 
			
		||||
@ -107,7 +104,7 @@ fun searchComplexFilterMangaRequestBuilder(baseUrl: String, page: Int, query: St
 | 
			
		||||
    filters.forEach { filter ->
 | 
			
		||||
        when (filter) {
 | 
			
		||||
            is SearchMatch -> {
 | 
			
		||||
                matchFilter = filter.state
 | 
			
		||||
                matchFilter = filter.state + 1
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            is TextField -> {
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,10 @@ import android.graphics.Bitmap
 | 
			
		||||
import android.graphics.BitmapFactory
 | 
			
		||||
import android.graphics.Canvas
 | 
			
		||||
import android.graphics.Rect
 | 
			
		||||
import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import okhttp3.*
 | 
			
		||||
import okhttp3.Interceptor
 | 
			
		||||
import okhttp3.MediaType
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import okhttp3.ResponseBody
 | 
			
		||||
import java.io.ByteArrayOutputStream
 | 
			
		||||
import java.io.IOException
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
@ -15,26 +17,15 @@ import java.io.InputStream
 | 
			
		||||
 *  It's not need now, but it remains in this code for sometime.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
internal class ImageDecoder(private val version: String, scripts: String) {
 | 
			
		||||
    private  val cnt = substringBetween(scripts, "var view_cnt = ", ";")
 | 
			
		||||
internal class ImageDecoder(scripts: String) {
 | 
			
		||||
    private val cnt = substringBetween(scripts, "var view_cnt = ", ";")
 | 
			
		||||
            .toIntOrNull() ?: 0
 | 
			
		||||
    private val chapter = substringBetween(scripts, "var chapter = ", ";")
 | 
			
		||||
            .toIntOrNull() ?: 0
 | 
			
		||||
 | 
			
		||||
    fun request(url: String): String {
 | 
			
		||||
        return when (version) {
 | 
			
		||||
            "v1" -> decodeVersion1ImageUrl(cnt, chapter, url)
 | 
			
		||||
            else -> url
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun decodeVersion1ImageUrl(cnt: Int, chapter: Int, url: String): String {
 | 
			
		||||
        return HttpUrl.parse(url)!!.newBuilder()
 | 
			
		||||
                .addQueryParameter("cnt", cnt.toString())
 | 
			
		||||
                .addQueryParameter("ch", chapter.toString())
 | 
			
		||||
                .addQueryParameter("ver", "v1")
 | 
			
		||||
                .addQueryParameter("type", "ImageDecodeRequest")
 | 
			
		||||
                .build()!!.toString()
 | 
			
		||||
        if (cnt < 10) return url
 | 
			
		||||
        return "$url??$chapter;$cnt"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -42,21 +33,18 @@ internal class ImageDecoder(private val version: String, scripts: String) {
 | 
			
		||||
internal class ImageDecoderInterceptor : Interceptor {
 | 
			
		||||
    override fun intercept(chain: Interceptor.Chain): Response {
 | 
			
		||||
        val req = chain.request()
 | 
			
		||||
        val url = req.url().toString()
 | 
			
		||||
        return if (url.contains("ImageDecodeRequest")) {
 | 
			
		||||
        val response = chain.proceed(req)
 | 
			
		||||
 | 
			
		||||
        val decodeHeader = req.header("ImageDecodeRequest")
 | 
			
		||||
 | 
			
		||||
        return if (decodeHeader != null) {
 | 
			
		||||
            try {
 | 
			
		||||
                val reqUrl = HttpUrl.parse(url)!!
 | 
			
		||||
                val s = decodeHeader.split(";").map { it.toInt() }
 | 
			
		||||
 | 
			
		||||
                val viewCnt = reqUrl.queryParameter("cnt")!!
 | 
			
		||||
                val version = reqUrl.queryParameter("ver")!!
 | 
			
		||||
                val chapter = reqUrl.queryParameter("ch")!!
 | 
			
		||||
                val imageUrl = url.split("?").first()
 | 
			
		||||
 | 
			
		||||
                val response = chain.proceed(GET("$imageUrl?quick"))
 | 
			
		||||
                if (viewCnt.toInt() < 10) return response // Pass decoder if it's not scrambled.
 | 
			
		||||
                if (s[1] < 10) return response
 | 
			
		||||
 | 
			
		||||
                val res = response.body()!!.byteStream().use {
 | 
			
		||||
                    decodeImageRequest(version, chapter, viewCnt, it)
 | 
			
		||||
                    decodeImageRequest(it, s[0], s[1])
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val rb = ResponseBody.create(MediaType.parse("image/png"), res)
 | 
			
		||||
@ -66,19 +54,28 @@ internal class ImageDecoderInterceptor : Interceptor {
 | 
			
		||||
                throw IOException("Image decoder failure.", e)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            chain.proceed(req)
 | 
			
		||||
            response
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun decodeImageRequest(img: InputStream, chapter: Int, view_cnt: Int): ByteArray {
 | 
			
		||||
        val decoded = BitmapFactory.decodeStream(img)
 | 
			
		||||
        val result = imageDecoder(decoded, chapter, view_cnt)
 | 
			
		||||
 | 
			
		||||
        val output = ByteArrayOutputStream()
 | 
			
		||||
        result.compress(Bitmap.CompressFormat.PNG, 100, output)
 | 
			
		||||
        return output.toByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * `decodeV1ImageNative` is modified version of
 | 
			
		||||
     * `imageDecoder` is modified version of
 | 
			
		||||
     *  https://github.com/junheah/MangaViewAndroid/blob/b69a4427258fe7fc5fb5363108572bbee0d65e94/app/src/main/java/ml/melun/mangaview/mangaview/Decoder.java#L6-L60
 | 
			
		||||
     *
 | 
			
		||||
     * MIT License
 | 
			
		||||
     *
 | 
			
		||||
     * Copyright (c) 2019 junheah
 | 
			
		||||
     */
 | 
			
		||||
    private fun decodeV1ImageNative(input: Bitmap, chapter: Int, view_cnt: Int, half: Int = 0, _CX: Int = MangaShowMe.V1_CX, _CY: Int = MangaShowMe.V1_CY): Bitmap {
 | 
			
		||||
    private fun imageDecoder(input: Bitmap, chapter: Int, view_cnt: Int, half: Int = 0, _CX: Int = MangaShowMe.V1_CX, _CY: Int = MangaShowMe.V1_CY): Bitmap {
 | 
			
		||||
        if (view_cnt == 0) return input
 | 
			
		||||
        val viewCnt = view_cnt / 10
 | 
			
		||||
        var CX = _CX
 | 
			
		||||
@ -159,22 +156,6 @@ internal class ImageDecoderInterceptor : Interceptor {
 | 
			
		||||
                Math.floor(1000 * (n - Math.floor(n))) +
 | 
			
		||||
                Math.floor(10000 * (a - Math.floor(a)))).toInt()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun decodeImageRequest(version: String, chapter: String, view_cnt: String, img: InputStream): ByteArray {
 | 
			
		||||
        return when (version) {
 | 
			
		||||
            "v1" -> decodeV1Image(chapter, view_cnt, img)
 | 
			
		||||
            else -> img.readBytes()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun decodeV1Image(chapter: String, view_cnt: String, img: InputStream): ByteArray {
 | 
			
		||||
        val decoded = BitmapFactory.decodeStream(img)
 | 
			
		||||
        val result = decodeV1ImageNative(decoded, chapter.toInt(), view_cnt.toInt())
 | 
			
		||||
 | 
			
		||||
        val output = ByteArrayOutputStream()
 | 
			
		||||
        result.compress(Bitmap.CompressFormat.PNG, 100, output)
 | 
			
		||||
        return output.toByteArray()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private fun substringBetween(target: String, prefix: String, suffix: String): String = {
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit
 | 
			
		||||
 **/
 | 
			
		||||
class MangaShowMe : ParsedHttpSource() {
 | 
			
		||||
    override val name = "MangaShow.Me"
 | 
			
		||||
    override val baseUrl = "https://manamoa.net"
 | 
			
		||||
    override val baseUrl = "https://manamoa2.net"
 | 
			
		||||
    override val lang: String = "ko"
 | 
			
		||||
 | 
			
		||||
    // Latest updates currently returns duplicate manga as it separates manga into chapters
 | 
			
		||||
@ -33,9 +33,38 @@ class MangaShowMe : ParsedHttpSource() {
 | 
			
		||||
            .connectTimeout(10, TimeUnit.SECONDS)
 | 
			
		||||
            .readTimeout(30, TimeUnit.SECONDS)
 | 
			
		||||
            .addInterceptor(ImageDecoderInterceptor())
 | 
			
		||||
            .addInterceptor { chain ->
 | 
			
		||||
                val req = chain.request()
 | 
			
		||||
 | 
			
		||||
                // only for image Request
 | 
			
		||||
                if (!req.url().host().contains("filecdn.xyz")) return@addInterceptor chain.proceed(req)
 | 
			
		||||
 | 
			
		||||
                val secondUrl = req.header("SecondUrlToRequest")
 | 
			
		||||
 | 
			
		||||
                fun get(flag: Int = 0): Request {
 | 
			
		||||
                    val url = when (flag) {
 | 
			
		||||
                        1 -> req.url().toString().replace("img.", "s3.")
 | 
			
		||||
                        2 -> secondUrl!!
 | 
			
		||||
                        else -> req.url().toString()
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return req.newBuilder()!!.url(url)
 | 
			
		||||
                            .removeHeader("ImageDecodeRequest")
 | 
			
		||||
                            .removeHeader("SecondUrlToRequest")
 | 
			
		||||
                            .build()!!
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val res = chain.proceed(get())
 | 
			
		||||
                val length = res.header("content-length")
 | 
			
		||||
                if (length == null || length.toInt() < 50000) {
 | 
			
		||||
                    val s3res = chain.proceed(get(1)) // s3
 | 
			
		||||
                    if (!s3res.isSuccessful && secondUrl != null) {
 | 
			
		||||
                        chain.proceed(get(2)) // secondUrl
 | 
			
		||||
                    } else s3res
 | 
			
		||||
                } else res
 | 
			
		||||
            }
 | 
			
		||||
            .build()!!
 | 
			
		||||
 | 
			
		||||
    //override fun popularMangaSelector() = "div.basic-post-gallery > div >  div.post-row"
 | 
			
		||||
    override fun popularMangaSelector() = "div.manga-list-gallery > div > div.post-row"
 | 
			
		||||
 | 
			
		||||
    override fun popularMangaFromElement(element: Element): SManga {
 | 
			
		||||
@ -84,8 +113,8 @@ class MangaShowMe : ParsedHttpSource() {
 | 
			
		||||
        val publishTypeText = thumbnailElement.select("a.publish_type").text() ?: ""
 | 
			
		||||
        val authorText = thumbnailElement.select("a.author").text() ?: ""
 | 
			
		||||
        val mangaLike = info.select("div.recommend > i.fa").first().text() ?: "0"
 | 
			
		||||
        val mangaChaptersLike = mangaElementsSum(document.select("div.addedAt i.fa.fa-thumbs-up > span"))
 | 
			
		||||
        val mangaComments = mangaElementsSum(document.select("div.addedAt i.fa.fa-comment > span"))
 | 
			
		||||
        val mangaChaptersLike = mangaElementsSum(document.select(".title i.fa.fa-thumbs-up > span"))
 | 
			
		||||
        val mangaComments = mangaElementsSum(document.select(".title i.fa.fa-comment > span"))
 | 
			
		||||
        val genres = mutableListOf<String>()
 | 
			
		||||
        document.select("div.left-info > .manga-tags > a.tag").forEach {
 | 
			
		||||
            genres.add(it.text())
 | 
			
		||||
@ -180,14 +209,30 @@ class MangaShowMe : ParsedHttpSource() {
 | 
			
		||||
        val pages = mutableListOf<Page>()
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            val element = document.select("div.col-md-9.at-col.at-main script")
 | 
			
		||||
            val imageUrl = element.html().substringAfter("var img_list = [").substringBefore("];")
 | 
			
		||||
            val element = document.select("div.col-md-9.at-col.at-main script").html()
 | 
			
		||||
            val imageUrl = element.substringAfter("var img_list = [").substringBefore("];")
 | 
			
		||||
            val imageUrls = JSONArray("[$imageUrl]")
 | 
			
		||||
            val decoder = ImageDecoder("v1", element.html())
 | 
			
		||||
 | 
			
		||||
            (0 until imageUrls.length())
 | 
			
		||||
                    .map { imageUrls.getString(it) }
 | 
			
		||||
                    .forEach { pages.add(Page(pages.size, "", decoder.request(it))) }
 | 
			
		||||
            val imageUrl1 = element.substringAfter("var img_list1 = [").substringBefore("];")
 | 
			
		||||
            val imageUrls1 = JSONArray("[$imageUrl1]")
 | 
			
		||||
 | 
			
		||||
            val decoder = ImageDecoder(element)
 | 
			
		||||
 | 
			
		||||
            if (imageUrls.length() != imageUrls1.length()) {
 | 
			
		||||
                (0 until imageUrls.length())
 | 
			
		||||
                        .map { imageUrls.getString(it) }
 | 
			
		||||
                        .forEach { pages.add(Page(pages.size, decoder.request(it), "${it.substringBefore("!!")}?quick")) }
 | 
			
		||||
            } else {
 | 
			
		||||
                (0 until imageUrls.length())
 | 
			
		||||
                        .map {
 | 
			
		||||
                            imageUrls.getString(it) + try {
 | 
			
		||||
                                "!!${imageUrls1.getString(it)}"
 | 
			
		||||
                            } catch (_: Exception) {
 | 
			
		||||
                                ""
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        .forEach { pages.add(Page(pages.size, decoder.request(it), "${it.substringBefore("!!")}?quick")) }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (e: Exception) {
 | 
			
		||||
            e.printStackTrace()
 | 
			
		||||
        }
 | 
			
		||||
@ -195,6 +240,29 @@ class MangaShowMe : ParsedHttpSource() {
 | 
			
		||||
        return pages
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun imageRequest(page: Page): Request {
 | 
			
		||||
        val requestHeaders = try {
 | 
			
		||||
            val data = page.url.substringAfter("??", "")
 | 
			
		||||
            val secondUrl = page.url.substringAfter("!!", "").substringBefore("??")
 | 
			
		||||
 | 
			
		||||
            val builder = headers.newBuilder()!!
 | 
			
		||||
 | 
			
		||||
            if (data.isNotBlank()) {
 | 
			
		||||
                builder.add("ImageDecodeRequest", data)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (secondUrl.isNotBlank()) {
 | 
			
		||||
                builder.add("SecondUrlToRequest", secondUrl)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            builder.build()!!
 | 
			
		||||
        } catch (_: Exception) {
 | 
			
		||||
            headers
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return GET(page.imageUrl!!, requestHeaders)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Latest not supported
 | 
			
		||||
    override fun latestUpdatesSelector() = throw UnsupportedOperationException("This method should not be called!")
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,8 @@ apply plugin: 'kotlin-android'
 | 
			
		||||
ext {
 | 
			
		||||
    appName = 'Tachiyomi: NewToki'
 | 
			
		||||
    pkgNameSuffix = 'ko.newtoki'
 | 
			
		||||
    extClass = '.NewToki'
 | 
			
		||||
    extVersionCode = 6
 | 
			
		||||
    extClass = '.NewTokiFactory'
 | 
			
		||||
    extVersionCode = 7
 | 
			
		||||
    libVersion = '1.2'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,9 +16,7 @@ import java.util.*
 | 
			
		||||
/**
 | 
			
		||||
 * NewToki Source
 | 
			
		||||
 **/
 | 
			
		||||
class NewToki : ParsedHttpSource() {
 | 
			
		||||
    override val name = "NewToki"
 | 
			
		||||
    override val baseUrl = "https://newtoki7.net"
 | 
			
		||||
open class NewToki(override val name: String, override val baseUrl: String, private val boardName: String) : ParsedHttpSource() {
 | 
			
		||||
    override val lang: String = "ko"
 | 
			
		||||
    override val supportsLatest = true
 | 
			
		||||
    override val client: OkHttpClient = network.cloudflareClient
 | 
			
		||||
@ -39,7 +37,7 @@ class NewToki : ParsedHttpSource() {
 | 
			
		||||
    override fun popularMangaNextPageSelector() = "ul.pagination > li:not(.disabled)"
 | 
			
		||||
 | 
			
		||||
    // Do not add page parameter if page is 1 to prevent tracking.
 | 
			
		||||
    override fun popularMangaRequest(page: Int) = GET("$baseUrl/comic" + if (page > 1) "/p$page" else "")
 | 
			
		||||
    override fun popularMangaRequest(page: Int) = GET("$baseUrl/$boardName" + if (page > 1) "/p$page" else "")
 | 
			
		||||
 | 
			
		||||
    override fun popularMangaParse(response: Response): MangasPage {
 | 
			
		||||
        val document = response.asJsoup()
 | 
			
		||||
@ -61,7 +59,7 @@ class NewToki : ParsedHttpSource() {
 | 
			
		||||
    override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
 | 
			
		||||
    override fun searchMangaNextPageSelector() = popularMangaSelector()
 | 
			
		||||
    override fun searchMangaParse(response: Response) = popularMangaParse(response)
 | 
			
		||||
    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/comic" + (if (page > 1) "/p$page" else "") + "?stx=$query")
 | 
			
		||||
    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/$boardName" + (if (page > 1) "/p$page" else "") + "?stx=$query")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    override fun mangaDetailsParse(document: Document): SManga {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,47 @@
 | 
			
		||||
package eu.kanade.tachiyomi.extension.ko.newtoki
 | 
			
		||||
 | 
			
		||||
import eu.kanade.tachiyomi.network.GET
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceFactory
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Filter
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.FilterList
 | 
			
		||||
import okhttp3.HttpUrl
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
 | 
			
		||||
private const val baseDomain = "newtoki10"
 | 
			
		||||
 | 
			
		||||
class NewTokiFactory : SourceFactory {
 | 
			
		||||
    override fun createSources(): List<Source> = listOf(
 | 
			
		||||
            NewTokiManga(),
 | 
			
		||||
            NewTokiWebtoon()
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NewTokiManga : NewToki("NewToki", "https://$baseDomain.net", "comic")
 | 
			
		||||
 | 
			
		||||
class NewTokiWebtoon : NewToki("NewToki (Webtoon)", "https://$baseDomain.com", "webtoon") {
 | 
			
		||||
    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
 | 
			
		||||
        val url = HttpUrl.parse("$baseUrl/webtoon" + (if (page > 1) "/p$page" else ""))!!.newBuilder()
 | 
			
		||||
        filters.forEach { filter ->
 | 
			
		||||
            when (filter) {
 | 
			
		||||
                is SearchTypeList -> {
 | 
			
		||||
                    if (filter.state > 0) {
 | 
			
		||||
                        url.addQueryParameter("toon", filter.values[filter.state])
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!query.isBlank()) {
 | 
			
		||||
            url.addQueryParameter("stx", query)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return GET(url.toString())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class SearchTypeList : Filter.Select<String>("Type", arrayOf("전체", "일반웹툰", "성인웹툰", "BL/GL", "완결웹툰"))
 | 
			
		||||
 | 
			
		||||
    override fun getFilterList() = FilterList(
 | 
			
		||||
            SearchTypeList()
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user