Add Dmzj manga source (#218)
This commit is contained in:
parent
8320d2b8a6
commit
f026f7e55f
|
@ -0,0 +1,13 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
|
ext {
|
||||||
|
appName = 'Tachiyomi: Dmzj'
|
||||||
|
pkgNameSuffix = "zh.dmzj"
|
||||||
|
extClass = '.Dmzj'
|
||||||
|
extVersionCode = 1
|
||||||
|
extVersionSuffix = 0
|
||||||
|
libVersion = '1.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$rootDir/common.gradle"
|
|
@ -0,0 +1,260 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.zh.dmzj
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.model.*
|
||||||
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.text.Regex
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
/**
|
||||||
|
* Dmzj source
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Dmzj : HttpSource() {
|
||||||
|
override val lang = "zh"
|
||||||
|
private val TAG: String = "Dmzj"
|
||||||
|
override val supportsLatest = true
|
||||||
|
override val name = "动漫之家"
|
||||||
|
override val baseUrl = "http://v2.api.dmzj.com"
|
||||||
|
|
||||||
|
private fun cleanUrl(url: String) = if (url.startsWith("//"))
|
||||||
|
"http:$url"
|
||||||
|
else url
|
||||||
|
|
||||||
|
private fun mangaFromJSON1(json: String): MangasPage {
|
||||||
|
val arr = JSONArray(json)
|
||||||
|
val ret = ArrayList<SManga>(arr.length())
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
var obj = arr.getJSONObject(i)
|
||||||
|
var cid = obj.getString("id")
|
||||||
|
ret.add(SManga.create().apply {
|
||||||
|
title = obj.getString("name")
|
||||||
|
thumbnail_url = cleanUrl(obj.getString("cover"))
|
||||||
|
author = obj.optString("authors")
|
||||||
|
status = when(obj.getString("status_tag_id")) {
|
||||||
|
"2310" -> SManga.COMPLETED
|
||||||
|
"2309" -> SManga.ONGOING
|
||||||
|
else -> SManga.UNKNOWN
|
||||||
|
}
|
||||||
|
description = obj.getString("description")
|
||||||
|
url = "/comic/$cid.json"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return MangasPage(ret, arr.length() != 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mangaFromJSON2(json: String): MangasPage {
|
||||||
|
val arr = JSONArray(json)
|
||||||
|
val ret = ArrayList<SManga>(arr.length())
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
var obj = arr.getJSONObject(i)
|
||||||
|
var cid = obj.getString("id")
|
||||||
|
ret.add(SManga.create().apply {
|
||||||
|
title = obj.getString("title")
|
||||||
|
thumbnail_url = obj.getString("cover")
|
||||||
|
author = obj.optString("authors")
|
||||||
|
status = when(obj.getString("status")) {
|
||||||
|
"已完结" -> SManga.COMPLETED
|
||||||
|
"连载中" -> SManga.ONGOING
|
||||||
|
else -> SManga.UNKNOWN
|
||||||
|
}
|
||||||
|
url = "/comic/$cid.json"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return MangasPage(ret, arr.length() != 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun popularMangaRequest(page: Int) = GET("http://v2.api.dmzj.com/classify/0/0/${page-1}.json")
|
||||||
|
|
||||||
|
override fun popularMangaParse(response: Response) = searchMangaParse(response)
|
||||||
|
|
||||||
|
override fun latestUpdatesRequest(page: Int) = GET("http://v2.api.dmzj.com/classify/0/1/${page-1}.json")
|
||||||
|
|
||||||
|
override fun latestUpdatesParse(response: Response): MangasPage = searchMangaParse(response)
|
||||||
|
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
if (query != "") {
|
||||||
|
val uri = Uri.parse("http://s.acg.dmzj.com/comicsum/search.php").buildUpon()
|
||||||
|
uri.appendQueryParameter("s", query)
|
||||||
|
return GET(uri.toString())
|
||||||
|
} else {
|
||||||
|
var params = filters.map {
|
||||||
|
if (it !is SortFilter && it is UriPartFilter) {
|
||||||
|
it.toUriPart()
|
||||||
|
} else ""
|
||||||
|
}.filter { it != "" }.joinToString("-")
|
||||||
|
if (params == "") {
|
||||||
|
params = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
val order = filters.filter { it is SortFilter }.map { (it as UriPartFilter).toUriPart() }.joinToString("")
|
||||||
|
|
||||||
|
return GET("http://v2.api.dmzj.com/classify/$params/$order/${page-1}.json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
|
val res = response.body()!!.string()
|
||||||
|
val r = Regex("g_search_data = (.*)")
|
||||||
|
val m = r.find(res)
|
||||||
|
if (m != null) {
|
||||||
|
return mangaFromJSON1(m.groupValues.get(1))
|
||||||
|
} else {
|
||||||
|
return mangaFromJSON2(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mangaDetailsParse(response: Response) = SManga.create().apply {
|
||||||
|
val obj = JSONObject(response.body()!!.string())
|
||||||
|
|
||||||
|
title = obj.getString("title")
|
||||||
|
thumbnail_url = obj.getString("cover")
|
||||||
|
|
||||||
|
var arr = obj.getJSONArray("authors")
|
||||||
|
var tmparr = ArrayList<String>(arr.length())
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
tmparr.add(arr.getJSONObject(i).getString("tag_name"))
|
||||||
|
}
|
||||||
|
author = tmparr.joinToString(", ")
|
||||||
|
|
||||||
|
arr = obj.getJSONArray("types")
|
||||||
|
tmparr.clear()
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
tmparr.add(arr.getJSONObject(i).getString("tag_name"))
|
||||||
|
}
|
||||||
|
genre = tmparr.joinToString(", ")
|
||||||
|
|
||||||
|
description = obj.getString("description")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
val obj = JSONObject(response.body()!!.string())
|
||||||
|
val ret = ArrayList<SChapter>()
|
||||||
|
val cid = obj.getString("id")
|
||||||
|
val arr = obj.getJSONArray("chapters")
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
val obj2 = arr.getJSONObject(i)
|
||||||
|
val arr2 = obj2.getJSONArray("data")
|
||||||
|
val prefix = obj2.getString("title")
|
||||||
|
for (j in 0 until arr2.length()) {
|
||||||
|
val chapter = arr2.getJSONObject(j)
|
||||||
|
ret.add(SChapter.create().apply {
|
||||||
|
name = "$prefix: ${chapter.getString("chapter_title")}"
|
||||||
|
date_upload = chapter.getString("updatetime").toLong()
|
||||||
|
url = "/chapter/$cid/${chapter.getString("chapter_id")}.json"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
|
val obj = JSONObject(response.body()!!.string())
|
||||||
|
val arr = obj.getJSONArray("page_url")
|
||||||
|
val ret = ArrayList<Page>(arr.length())
|
||||||
|
for (i in 0 until arr.length()) {
|
||||||
|
ret.add(Page(i+1, "", arr.getString(i)))
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
//Unused, we can get image urls directly from the chapter page
|
||||||
|
override fun imageUrlParse(response: Response)
|
||||||
|
= throw UnsupportedOperationException("This method should not be called!")
|
||||||
|
|
||||||
|
override fun getFilterList() = FilterList(
|
||||||
|
SortFilter(),
|
||||||
|
GenreGroup(),
|
||||||
|
StatusFilter(),
|
||||||
|
TypeFilter(),
|
||||||
|
ReaderFilter()
|
||||||
|
)
|
||||||
|
|
||||||
|
private class GenreGroup : UriPartFilter("分类", arrayOf(
|
||||||
|
Pair("全部", ""),
|
||||||
|
Pair("冒险", "4"),
|
||||||
|
Pair("百合", "3243"),
|
||||||
|
Pair("生活", "3242"),
|
||||||
|
Pair("四格", "17"),
|
||||||
|
Pair("伪娘", "3244"),
|
||||||
|
Pair("悬疑", "3245"),
|
||||||
|
Pair("后宫", "3249"),
|
||||||
|
Pair("热血", "3248"),
|
||||||
|
Pair("耽美", "3246"),
|
||||||
|
Pair("其他", "16"),
|
||||||
|
Pair("恐怖", "14"),
|
||||||
|
Pair("科幻", "7"),
|
||||||
|
Pair("格斗", "6"),
|
||||||
|
Pair("欢乐向", "5"),
|
||||||
|
Pair("爱情", "8"),
|
||||||
|
Pair("侦探", "9"),
|
||||||
|
Pair("校园", "13"),
|
||||||
|
Pair("神鬼", "12"),
|
||||||
|
Pair("魔法", "11"),
|
||||||
|
Pair("竞技", "10"),
|
||||||
|
Pair("历史", "3250"),
|
||||||
|
Pair("战争", "3251"),
|
||||||
|
Pair("魔幻", "5806"),
|
||||||
|
Pair("扶她", "5345"),
|
||||||
|
Pair("东方", "5077"),
|
||||||
|
Pair("奇幻", "5848"),
|
||||||
|
Pair("轻小说", "6316"),
|
||||||
|
Pair("仙侠", "7900"),
|
||||||
|
Pair("搞笑", "7568"),
|
||||||
|
Pair("颜艺", "6437"),
|
||||||
|
Pair("性转换", "4518"),
|
||||||
|
Pair("高清单行", "4459"),
|
||||||
|
Pair("治愈", "3254"),
|
||||||
|
Pair("宅系", "3253"),
|
||||||
|
Pair("萌系", "3252"),
|
||||||
|
Pair("励志", "3255"),
|
||||||
|
Pair("节操", "6219"),
|
||||||
|
Pair("职场", "3328"),
|
||||||
|
Pair("西方魔幻", "3365"),
|
||||||
|
Pair("音乐舞蹈", "3326"),
|
||||||
|
Pair("机战", "3325")
|
||||||
|
))
|
||||||
|
|
||||||
|
private class StatusFilter : UriPartFilter("连载状态", arrayOf(
|
||||||
|
Pair("全部", ""),
|
||||||
|
Pair("连载", "2309"),
|
||||||
|
Pair("完结", "2310")
|
||||||
|
))
|
||||||
|
|
||||||
|
private class TypeFilter : UriPartFilter("地区", arrayOf(
|
||||||
|
Pair("全部", ""),
|
||||||
|
Pair("日本", "2304"),
|
||||||
|
Pair("韩国", "2305"),
|
||||||
|
Pair("欧美", "2306"),
|
||||||
|
Pair("港台", "2307"),
|
||||||
|
Pair("内地", "2308"),
|
||||||
|
Pair("其他", "8453")
|
||||||
|
))
|
||||||
|
|
||||||
|
private class SortFilter : UriPartFilter("排序", arrayOf(
|
||||||
|
Pair("更新", "1"),
|
||||||
|
Pair("人气", "0")
|
||||||
|
))
|
||||||
|
|
||||||
|
private class ReaderFilter : UriPartFilter("读者", arrayOf(
|
||||||
|
Pair("全部", ""),
|
||||||
|
Pair("少年", "3262"),
|
||||||
|
Pair("少女", "3263"),
|
||||||
|
Pair("青年", "3264")
|
||||||
|
))
|
||||||
|
|
||||||
|
//Headers
|
||||||
|
override fun headersBuilder()
|
||||||
|
= super.headersBuilder().add("Referer", "https://manhua.dmzj.com")!!
|
||||||
|
|
||||||
|
private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>,
|
||||||
|
defaultValue: Int = 0) :
|
||||||
|
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray(), defaultValue) {
|
||||||
|
open fun toUriPart() = vals[state].second
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue