add rawotaku (#1111)
This commit is contained in:
		
							parent
							
								
									95d3671f3d
								
							
						
					
					
						commit
						d8f4f38676
					
				
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.4 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.0 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 7.1 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 13 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 18 KiB  | 
							
								
								
									
										251
									
								
								multisrc/overrides/mangareader/rawotaku/src/RawOtaku.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								multisrc/overrides/mangareader/rawotaku/src/RawOtaku.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,251 @@
 | 
				
			|||||||
 | 
					package eu.kanade.tachiyomi.extension.ja.rawotaku
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.multisrc.mangareader.MangaReader
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.network.GET
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.network.asObservableSuccess
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.network.interceptor.rateLimit
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.source.model.Filter
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.source.model.FilterList
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.source.model.Page
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.source.model.SChapter
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.source.model.SManga
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.util.asJsoup
 | 
				
			||||||
 | 
					import kotlinx.serialization.json.Json
 | 
				
			||||||
 | 
					import kotlinx.serialization.json.jsonObject
 | 
				
			||||||
 | 
					import kotlinx.serialization.json.jsonPrimitive
 | 
				
			||||||
 | 
					import okhttp3.HttpUrl.Companion.toHttpUrl
 | 
				
			||||||
 | 
					import okhttp3.Request
 | 
				
			||||||
 | 
					import okhttp3.Response
 | 
				
			||||||
 | 
					import org.jsoup.Jsoup
 | 
				
			||||||
 | 
					import org.jsoup.nodes.Document
 | 
				
			||||||
 | 
					import org.jsoup.nodes.Element
 | 
				
			||||||
 | 
					import org.jsoup.nodes.TextNode
 | 
				
			||||||
 | 
					import org.jsoup.select.Evaluator
 | 
				
			||||||
 | 
					import rx.Observable
 | 
				
			||||||
 | 
					import java.net.URLEncoder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RawOtaku : MangaReader() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override val name = "Raw Otaku"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override val lang = "ja"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override val baseUrl = "https://rawotaku.com"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override val client = network.cloudflareClient.newBuilder()
 | 
				
			||||||
 | 
					        .rateLimit(2)
 | 
				
			||||||
 | 
					        .build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun headersBuilder() = super.headersBuilder()
 | 
				
			||||||
 | 
					        .add("Referer", "$baseUrl/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ============================== Popular ===============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun popularMangaRequest(page: Int) =
 | 
				
			||||||
 | 
					        GET("$baseUrl/filter/?type=all&status=all&language=all&sort=most-viewed&p=$page", headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =============================== Latest ===============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun latestUpdatesRequest(page: Int) =
 | 
				
			||||||
 | 
					        GET("$baseUrl/filter/?type=all&status=all&language=all&sort=latest-updated&p=$page", headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =============================== Search ===============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
 | 
				
			||||||
 | 
					        val url = baseUrl.toHttpUrl().newBuilder().apply {
 | 
				
			||||||
 | 
					            if (query.isNotBlank()) {
 | 
				
			||||||
 | 
					                addQueryParameter("q", query)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                addPathSegment("filter")
 | 
				
			||||||
 | 
					                addPathSegment("")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                filters.ifEmpty(::getFilterList).forEach { filter ->
 | 
				
			||||||
 | 
					                    when (filter) {
 | 
				
			||||||
 | 
					                        is TypeFilter -> {
 | 
				
			||||||
 | 
					                            addQueryParameter(filter.param, filter.selection)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        is StatusFilter -> {
 | 
				
			||||||
 | 
					                            addQueryParameter(filter.param, filter.selection)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        is LanguageFilter -> {
 | 
				
			||||||
 | 
					                            addQueryParameter(filter.param, filter.selection)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        is SortFilter -> {
 | 
				
			||||||
 | 
					                            addQueryParameter(filter.param, filter.selection)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        is GenresFilter -> {
 | 
				
			||||||
 | 
					                            filter.state.forEach {
 | 
				
			||||||
 | 
					                                if (it.state) {
 | 
				
			||||||
 | 
					                                    addQueryParameter(filter.param, it.id)
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else -> { }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            addQueryParameter("p", page.toString())
 | 
				
			||||||
 | 
					        }.build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return GET(url, headers)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun searchMangaSelector() = ".manga_list-sbs .manga-poster"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun searchMangaFromElement(element: Element) =
 | 
				
			||||||
 | 
					        SManga.create().apply {
 | 
				
			||||||
 | 
					            setUrlWithoutDomain(element.attr("href"))
 | 
				
			||||||
 | 
					            element.selectFirst(Evaluator.Tag("img"))!!.let {
 | 
				
			||||||
 | 
					                title = it.attr("alt")
 | 
				
			||||||
 | 
					                thumbnail_url = it.imgAttr()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun searchMangaNextPageSelector() = "ul.pagination > li.active + li"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =============================== Filters ==============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun getFilterList() =
 | 
				
			||||||
 | 
					        FilterList(
 | 
				
			||||||
 | 
					            Note,
 | 
				
			||||||
 | 
					            Filter.Separator(),
 | 
				
			||||||
 | 
					            TypeFilter(),
 | 
				
			||||||
 | 
					            StatusFilter(),
 | 
				
			||||||
 | 
					            LanguageFilter(),
 | 
				
			||||||
 | 
					            SortFilter(),
 | 
				
			||||||
 | 
					            GenresFilter(),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =========================== Manga Details ============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun mangaDetailsParse(document: Document) = SManga.create().apply {
 | 
				
			||||||
 | 
					        val root = document.selectFirst(Evaluator.Id("ani_detail"))!!
 | 
				
			||||||
 | 
					        val mangaTitle = root.selectFirst(Evaluator.Class("manga-name"))!!.ownText()
 | 
				
			||||||
 | 
					        title = mangaTitle
 | 
				
			||||||
 | 
					        description = buildString {
 | 
				
			||||||
 | 
					            root.selectFirst(".description")?.ownText()?.let { append(it) }
 | 
				
			||||||
 | 
					            append("\n\n")
 | 
				
			||||||
 | 
					            root.selectFirst(".manga-name-or")?.ownText()?.let {
 | 
				
			||||||
 | 
					                if (it.isNotEmpty() && it != mangaTitle) {
 | 
				
			||||||
 | 
					                    append("Alternative Title: ")
 | 
				
			||||||
 | 
					                    append(it)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }.trim()
 | 
				
			||||||
 | 
					        thumbnail_url = root.selectFirst(Evaluator.Tag("img"))!!.imgAttr()
 | 
				
			||||||
 | 
					        genre = root.selectFirst(Evaluator.Class("genres"))!!.children().joinToString { it.ownText() }
 | 
				
			||||||
 | 
					        for (item in root.selectFirst(Evaluator.Class("anisc-info"))!!.children()) {
 | 
				
			||||||
 | 
					            if (item.hasClass("item").not()) continue
 | 
				
			||||||
 | 
					            when (item.selectFirst(Evaluator.Class("item-head"))!!.ownText()) {
 | 
				
			||||||
 | 
					                "著者:" -> item.parseAuthorsTo(this)
 | 
				
			||||||
 | 
					                "地位:" -> status = when (item.selectFirst(Evaluator.Class("name"))!!.ownText().lowercase()) {
 | 
				
			||||||
 | 
					                    "ongoing" -> SManga.ONGOING
 | 
				
			||||||
 | 
					                    "completed" -> SManga.COMPLETED
 | 
				
			||||||
 | 
					                    "on-hold" -> SManga.ON_HIATUS
 | 
				
			||||||
 | 
					                    "canceled" -> SManga.CANCELLED
 | 
				
			||||||
 | 
					                    else -> SManga.UNKNOWN
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun Element.parseAuthorsTo(manga: SManga) {
 | 
				
			||||||
 | 
					        val authors = select(Evaluator.Tag("a"))
 | 
				
			||||||
 | 
					        val text = authors.map { it.ownText().replace(",", "") }
 | 
				
			||||||
 | 
					        val count = authors.size
 | 
				
			||||||
 | 
					        when (count) {
 | 
				
			||||||
 | 
					            0 -> return
 | 
				
			||||||
 | 
					            1 -> {
 | 
				
			||||||
 | 
					                manga.author = text[0]
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        val authorList = ArrayList<String>(count)
 | 
				
			||||||
 | 
					        val artistList = ArrayList<String>(count)
 | 
				
			||||||
 | 
					        for ((index, author) in authors.withIndex()) {
 | 
				
			||||||
 | 
					            val textNode = author.nextSibling() as? TextNode
 | 
				
			||||||
 | 
					            val list = if (textNode != null && "(Art)" in textNode.wholeText) artistList else authorList
 | 
				
			||||||
 | 
					            list.add(text[index])
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (authorList.isEmpty().not()) manga.author = authorList.joinToString()
 | 
				
			||||||
 | 
					        if (artistList.isEmpty().not()) manga.artist = artistList.joinToString()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ============================== Chapters ==============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun chapterListRequest(mangaUrl: String, type: String): Request =
 | 
				
			||||||
 | 
					        GET(baseUrl + mangaUrl, headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun parseChapterElements(response: Response, isVolume: Boolean): List<Element> {
 | 
				
			||||||
 | 
					        TODO("Not yet implemented")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override val chapterType = ""
 | 
				
			||||||
 | 
					    override val volumeType = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
 | 
				
			||||||
 | 
					        return client.newCall(chapterListRequest(manga))
 | 
				
			||||||
 | 
					            .asObservableSuccess()
 | 
				
			||||||
 | 
					            .map(::parseChapterList)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun parseChapterList(response: Response): List<SChapter> {
 | 
				
			||||||
 | 
					        val document = response.use { it.asJsoup() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return document.select(chapterListSelector())
 | 
				
			||||||
 | 
					            .map(::chapterFromElement)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun chapterListSelector(): String = "#ja-chaps > .chapter-item"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
 | 
				
			||||||
 | 
					        val id = element.attr("data-id")
 | 
				
			||||||
 | 
					        element.selectFirst("a")!!.run {
 | 
				
			||||||
 | 
					            setUrlWithoutDomain(attr("href") + "#$id")
 | 
				
			||||||
 | 
					            name = selectFirst(".name")?.text() ?: text()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =============================== Pages ================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun fetchPageList(chapter: SChapter): Observable<List<Page>> = Observable.fromCallable {
 | 
				
			||||||
 | 
					        val id = chapter.url.substringAfterLast("#")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val ajaxHeaders = super.headersBuilder().apply {
 | 
				
			||||||
 | 
					            add("Accept", "application/json, text/javascript, */*; q=0.01")
 | 
				
			||||||
 | 
					            add("Referer", URLEncoder.encode(baseUrl + chapter.url.substringBeforeLast("#"), "utf-8"))
 | 
				
			||||||
 | 
					            add("X-Requested-With", "XMLHttpRequest")
 | 
				
			||||||
 | 
					        }.build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val ajaxUrl = "$baseUrl/json/chapter?mode=vertical&id=$id"
 | 
				
			||||||
 | 
					        client.newCall(GET(ajaxUrl, ajaxHeaders)).execute().let(::pageListParse)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun pageListParse(response: Response): List<Page> {
 | 
				
			||||||
 | 
					        val document = response.use { it.parseHtmlProperty() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val pageList = document.select(".container-reader-chapter > div > img").map {
 | 
				
			||||||
 | 
					            val index = it.attr("alt").toInt()
 | 
				
			||||||
 | 
					            val imgUrl = it.imgAttr()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Page(index, imageUrl = imgUrl)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return pageList
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ============================= Utilities ==============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun Element.imgAttr(): String = when {
 | 
				
			||||||
 | 
					        hasAttr("data-lazy-src") -> attr("abs:data-lazy-src")
 | 
				
			||||||
 | 
					        hasAttr("data-src") -> attr("abs:data-src")
 | 
				
			||||||
 | 
					        else -> attr("abs:src")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun Response.parseHtmlProperty(): Document {
 | 
				
			||||||
 | 
					        val html = Json.parseToJsonElement(body.string()).jsonObject["html"]!!.jsonPrimitive.content
 | 
				
			||||||
 | 
					        return Jsoup.parseBodyFragment(html)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										110
									
								
								multisrc/overrides/mangareader/rawotaku/src/RawOtakuFilters.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								multisrc/overrides/mangareader/rawotaku/src/RawOtakuFilters.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					package eu.kanade.tachiyomi.extension.ja.rawotaku
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import eu.kanade.tachiyomi.source.model.Filter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object Note : Filter.Header("NOTE: Ignored if using text search!")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sealed class Select(
 | 
				
			||||||
 | 
					    name: String,
 | 
				
			||||||
 | 
					    val param: String,
 | 
				
			||||||
 | 
					    values: Array<String>,
 | 
				
			||||||
 | 
					) : Filter.Select<String>(name, values) {
 | 
				
			||||||
 | 
					    open val selection: String
 | 
				
			||||||
 | 
					        get() = if (state == 0) "" else state.toString()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TypeFilter(
 | 
				
			||||||
 | 
					    values: Array<String> = types.keys.toTypedArray(),
 | 
				
			||||||
 | 
					) : Select("タイプ", "type", values) {
 | 
				
			||||||
 | 
					    override val selection: String
 | 
				
			||||||
 | 
					        get() = types[values[state]]!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        private val types = mapOf(
 | 
				
			||||||
 | 
					            "全て" to "all",
 | 
				
			||||||
 | 
					            "Raw Manga" to "Raw Manga",
 | 
				
			||||||
 | 
					            "BLコミック" to "BLコミック",
 | 
				
			||||||
 | 
					            "TLコミック" to "TLコミック",
 | 
				
			||||||
 | 
					            "オトナコミック" to "オトナコミック",
 | 
				
			||||||
 | 
					            "女性マンガ" to "女性マンガ",
 | 
				
			||||||
 | 
					            "少女マンガ" to "少女マンガ",
 | 
				
			||||||
 | 
					            "少年マンガ" to "少年マンガ",
 | 
				
			||||||
 | 
					            "青年マンガ" to "青年マンガ",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StatusFilter(
 | 
				
			||||||
 | 
					    values: Array<String> = statuses.keys.toTypedArray(),
 | 
				
			||||||
 | 
					) : Select("地位", "status", values) {
 | 
				
			||||||
 | 
					    override val selection: String
 | 
				
			||||||
 | 
					        get() = statuses[values[state]]!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        private val statuses = mapOf(
 | 
				
			||||||
 | 
					            "全て" to "all",
 | 
				
			||||||
 | 
					            "Publishing" to "Publishing",
 | 
				
			||||||
 | 
					            "Finished" to "Finished",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LanguageFilter(
 | 
				
			||||||
 | 
					    values: Array<String> = languages.keys.toTypedArray(),
 | 
				
			||||||
 | 
					) : Select("言語", "language", values) {
 | 
				
			||||||
 | 
					    override val selection: String
 | 
				
			||||||
 | 
					        get() = languages[values[state]]!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        private val languages = mapOf(
 | 
				
			||||||
 | 
					            "全て" to "all",
 | 
				
			||||||
 | 
					            "Japanese" to "ja",
 | 
				
			||||||
 | 
					            "English" to "en",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SortFilter(
 | 
				
			||||||
 | 
					    values: Array<String> = sort.keys.toTypedArray(),
 | 
				
			||||||
 | 
					) : Select("選別", "sort", values) {
 | 
				
			||||||
 | 
					    override val selection: String
 | 
				
			||||||
 | 
					        get() = sort[values[state]]!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        private val sort = mapOf(
 | 
				
			||||||
 | 
					            "デフォルト" to "default",
 | 
				
			||||||
 | 
					            "最新の更新" to "latest-updated",
 | 
				
			||||||
 | 
					            "最も見られました" to "most-viewed",
 | 
				
			||||||
 | 
					            "Title [A-Z]" to "title-az",
 | 
				
			||||||
 | 
					            "Title [Z-A]" to "title-za",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Genre(name: String, val id: String) : Filter.CheckBox(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GenresFilter(
 | 
				
			||||||
 | 
					    values: List<Genre> = genres,
 | 
				
			||||||
 | 
					) : Filter.Group<Genre>("ジャンル", values) {
 | 
				
			||||||
 | 
					    val param = "genre[]"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        private val genres: List<Genre>
 | 
				
			||||||
 | 
					            get() = listOf(
 | 
				
			||||||
 | 
					                Genre("アクション", "55"),
 | 
				
			||||||
 | 
					                Genre("エッチ", "15706"),
 | 
				
			||||||
 | 
					                Genre("コメディ", "91"),
 | 
				
			||||||
 | 
					                Genre("ドラマ", "56"),
 | 
				
			||||||
 | 
					                Genre("ハーレム", "20"),
 | 
				
			||||||
 | 
					                Genre("ファンタジー", "1"),
 | 
				
			||||||
 | 
					                Genre("冒険", "54"),
 | 
				
			||||||
 | 
					                Genre("悪魔", "6820"),
 | 
				
			||||||
 | 
					                Genre("武道", "1064"),
 | 
				
			||||||
 | 
					                Genre("歴史的", "9600"),
 | 
				
			||||||
 | 
					                Genre("警察・特殊部隊", "6089"),
 | 
				
			||||||
 | 
					                Genre("車・バイク", "4329"),
 | 
				
			||||||
 | 
					                Genre("音楽", "473"),
 | 
				
			||||||
 | 
					                Genre("魔法", "1416"),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -33,6 +33,12 @@ class MangaReaderGenerator : ThemeSourceGenerator {
 | 
				
			|||||||
            pkgName = "comickiba",
 | 
					            pkgName = "comickiba",
 | 
				
			||||||
            overrideVersionCode = 33,
 | 
					            overrideVersionCode = 33,
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					        SingleLang(
 | 
				
			||||||
 | 
					            name = "Raw Otaku",
 | 
				
			||||||
 | 
					            baseUrl = "https://rawotaku.com",
 | 
				
			||||||
 | 
					            lang = "ja",
 | 
				
			||||||
 | 
					            isNsfw = true,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object {
 | 
					    companion object {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user