add Manhuagui(zh-CN) (#1156)

* copy from pufei

* add manhuagui

* fix regex

* fix search

* add icon

by http://bigjpg.com

* remove comment

* fix baseurl
This commit is contained in:
fei long 2019-06-09 05:48:13 +08:00 committed by Eugene
parent 3f179ee9bf
commit a2fe7fd57f
11 changed files with 149 additions and 0 deletions

View File

@ -0,0 +1,17 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
appName = 'Tachiyomi: ManHuaGui'
pkgNameSuffix = 'zh.manhuagui'
extClass = '.Manhuagui'
extVersionCode = 1
libVersion = '1.2'
}
dependencies {
compileOnly project(':duktape-stub')
compileOnly 'com.google.code.gson:gson:2.8.5'
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

View File

@ -0,0 +1,18 @@
package eu.kanade.tachiyomi.extension.zh.manhuagui
data class Comic(
val bid: Int? = 0,
val block_cc: String? = "",
val bname: String? = "",
val bpic: String? = "",
val cid: Int? = 0,
val cname: String? = "",
val files: List<String?>? = listOf(),
val finished: Boolean? = false,
val len: Int? = 0,
val nextId: Int? = 0,
val path: String? = "",
val prevId: Int? = 0,
val sl: Sl? = Sl(),
val status: Int? = 0
)

View File

@ -0,0 +1,109 @@
package eu.kanade.tachiyomi.extension.zh.manhuagui
import android.util.Log
import com.google.gson.Gson
import com.squareup.duktape.Duktape
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.*
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
class Manhuagui : ParsedHttpSource() {
override val name = "漫画柜"
override val baseUrl = "https://www.manhuagui.com"
override val lang = "zh"
override val supportsLatest = true
val imageServer = arrayOf("https://i.hamreus.com")
private val gson = Gson()
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/view_p$page.html", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/list/update_p$page.html", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request
= GET("$baseUrl/s/${query}_p$page.html", headers)
override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url, headers)
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
override fun popularMangaSelector() = "ul#contList > li"
override fun latestUpdatesSelector() = popularMangaSelector()
override fun searchMangaSelector() = "div.book-result > ul > li"
override fun chapterListSelector() = "ul > li > a.status0"
override fun searchMangaNextPageSelector() = "a.prev"
override fun popularMangaNextPageSelector() = searchMangaNextPageSelector()
override fun latestUpdatesNextPageSelector() = searchMangaNextPageSelector()
override fun headersBuilder() = super.headersBuilder()
.add("Referer", baseUrl)
override fun popularMangaFromElement(element: Element) = mangaFromElement(element)
override fun latestUpdatesFromElement(element: Element) = mangaFromElement(element)
private fun mangaFromElement(element: Element): SManga {
val manga = SManga.create()
element.select("a.bcover").first().let {
manga.url = it.attr("href")
manga.title = it.attr("title").trim()
manga.thumbnail_url = it.select("img").first().attr("src")
}
return manga
}
override fun searchMangaFromElement(element: Element): SManga {
val manga = SManga.create()
element.select("div.book-cover > a.bcover > img").first().attr("src")
element.select("div.book-detail").first().let {
manga.url = it.select("dl > dt > a").first().attr("href")
manga.title = it.select("dl > dt > a").first().attr("title").trim()
}
return manga
}
override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()
chapter.url = element.attr("href")
chapter.name = element.attr("title").trim()
return chapter
}
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.description = document.select("div#intro-all").text().trim()
return manga
}
private val jsDecodeFunc = """
var LZString=(function(){var f=String.fromCharCode;var keyStrBase64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var baseReverseDic={};function getBaseValue(alphabet,character){if(!baseReverseDic[alphabet]){baseReverseDic[alphabet]={};for(var i=0;i<alphabet.length;i++){baseReverseDic[alphabet][alphabet.charAt(i)]=i}}return baseReverseDic[alphabet][character]}var LZString={decompressFromBase64:function(input){if(input==null)return"";if(input=="")return null;return LZString._0(input.length,32,function(index){return getBaseValue(keyStrBase64,input.charAt(index))})},_0:function(length,resetValue,getNextValue){var dictionary=[],next,enlargeIn=4,dictSize=4,numBits=3,entry="",result=[],i,w,bits,resb,maxpower,power,c,data={val:getNextValue(0),position:resetValue,index:1};for(i=0;i<3;i+=1){dictionary[i]=i}bits=0;maxpower=Math.pow(2,2);power=1;while(power!=maxpower){resb=data.val&data.position;data.position>>=1;if(data.position==0){data.position=resetValue;data.val=getNextValue(data.index++)}bits|=(resb>0?1:0)*power;power<<=1}switch(next=bits){case 0:bits=0;maxpower=Math.pow(2,8);power=1;while(power!=maxpower){resb=data.val&data.position;data.position>>=1;if(data.position==0){data.position=resetValue;data.val=getNextValue(data.index++)}bits|=(resb>0?1:0)*power;power<<=1}c=f(bits);break;case 1:bits=0;maxpower=Math.pow(2,16);power=1;while(power!=maxpower){resb=data.val&data.position;data.position>>=1;if(data.position==0){data.position=resetValue;data.val=getNextValue(data.index++)}bits|=(resb>0?1:0)*power;power<<=1}c=f(bits);break;case 2:return""}dictionary[3]=c;w=c;result.push(c);while(true){if(data.index>length){return""}bits=0;maxpower=Math.pow(2,numBits);power=1;while(power!=maxpower){resb=data.val&data.position;data.position>>=1;if(data.position==0){data.position=resetValue;data.val=getNextValue(data.index++)}bits|=(resb>0?1:0)*power;power<<=1}switch(c=bits){case 0:bits=0;maxpower=Math.pow(2,8);power=1;while(power!=maxpower){resb=data.val&data.position;data.position>>=1;if(data.position==0){data.position=resetValue;data.val=getNextValue(data.index++)}bits|=(resb>0?1:0)*power;power<<=1}dictionary[dictSize++]=f(bits);c=dictSize-1;enlargeIn--;break;case 1:bits=0;maxpower=Math.pow(2,16);power=1;while(power!=maxpower){resb=data.val&data.position;data.position>>=1;if(data.position==0){data.position=resetValue;data.val=getNextValue(data.index++)}bits|=(resb>0?1:0)*power;power<<=1}dictionary[dictSize++]=f(bits);c=dictSize-1;enlargeIn--;break;case 2:return result.join('')}if(enlargeIn==0){enlargeIn=Math.pow(2,numBits);numBits++}if(dictionary[c]){entry=dictionary[c]}else{if(c===dictSize){entry=w+w.charAt(0)}else{return null}}result.push(entry);dictionary[dictSize++]=w+entry.charAt(0);enlargeIn--;w=entry;if(enlargeIn==0){enlargeIn=Math.pow(2,numBits);numBits++}}}};return LZString})();String.prototype.splic=function(f){return LZString.decompressFromBase64(this).split(f)};
"""
override fun pageListParse(document: Document): List<Page> {
val html = document.html()
val re = Regex("""window\[".*?"\](\(.*\)\s*\{[\s\S]+\}\s*\(.*\))""")
val imgCode = re.find(html)?.groups?.get(1)?.value
val imgDecode = Duktape.create().use {
it.evaluate(jsDecodeFunc + imgCode) as String
}
Log.i("jsonresult", imgDecode)
val re2 = Regex("""\{.*\}""")
val imgJsonStr = re2.find(imgDecode)?.groups?.get(0)?.value
val imageJson: Comic = gson.fromJson(imgJsonStr, Comic::class.java)
return imageJson.files!!.mapIndexed { i, imgStr ->
val imgurl = "${imageServer[0]}${imageJson.path}$imgStr?cid=${imageJson.cid}&md5=${imageJson.sl?.md5}"
Log.i("image", imgurl)
Page(i, "", imgurl)
}
}
override fun imageUrlParse(document: Document) = ""
}

View File

@ -0,0 +1,5 @@
package eu.kanade.tachiyomi.extension.zh.manhuagui
data class Sl(
val md5: String? = ""
)