Add Dmzj manga source (#218)

This commit is contained in:
yshui 2018-02-26 14:27:15 -05:00 committed by Carlos
parent 8320d2b8a6
commit f026f7e55f
2 changed files with 273 additions and 0 deletions

13
src/zh/dmzj/build.gradle Normal file
View File

@ -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"

View File

@ -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
}
}