Add Maofly (#11930)
This commit is contained in:
parent
547e628f2b
commit
9d058adbf9
2
src/zh/maofly/AndroidManifest.xml
Normal file
2
src/zh/maofly/AndroidManifest.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="eu.kanade.tachiyomi.extension" />
|
13
src/zh/maofly/build.gradle
Normal file
13
src/zh/maofly/build.gradle
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
ext {
|
||||
extName = 'Maofly'
|
||||
pkgNameSuffix = 'zh.maofly'
|
||||
extClass = '.Maofly'
|
||||
extVersionCode = 1
|
||||
}
|
||||
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
BIN
src/zh/maofly/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
src/zh/maofly/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
src/zh/maofly/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
src/zh/maofly/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
src/zh/maofly/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
src/zh/maofly/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
BIN
src/zh/maofly/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
src/zh/maofly/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
src/zh/maofly/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
src/zh/maofly/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
src/zh/maofly/res/web_hi_res_512.png
Normal file
BIN
src/zh/maofly/res/web_hi_res_512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
@ -0,0 +1,96 @@
|
||||
package eu.kanade.tachiyomi.extension.zh.maofly
|
||||
|
||||
import android.net.Uri
|
||||
import com.squareup.duktape.Duktape
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
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.source.online.ParsedHttpSource
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Request
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
class Maofly : ParsedHttpSource() {
|
||||
override val name: String = "漫画猫"
|
||||
override val lang: String = "zh"
|
||||
override val supportsLatest: Boolean = false
|
||||
override val baseUrl: String = "https://www.maofly.com"
|
||||
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
|
||||
|
||||
// Popular
|
||||
|
||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list-page-$page.html", headers)
|
||||
override fun popularMangaNextPageSelector(): String? = "li.page-item > a:contains(下一页)"
|
||||
override fun popularMangaSelector(): String = "div.comic-main-section > div.comic-book-unit"
|
||||
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||
title = element.selectFirst("h2 > a").text()
|
||||
setUrlWithoutDomain(element.selectFirst("h2 > a").attr("href"))
|
||||
thumbnail_url = element.selectFirst("img").attr("src")
|
||||
}
|
||||
|
||||
// Latest
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("Not used.")
|
||||
override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException("Not used.")
|
||||
override fun latestUpdatesSelector(): String = throw UnsupportedOperationException("Not used.")
|
||||
override fun latestUpdatesFromElement(element: Element): SManga = throw UnsupportedOperationException("Not used.")
|
||||
|
||||
// Search
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val uri = Uri.parse(baseUrl).buildUpon()
|
||||
.appendPath("search.html")
|
||||
.appendQueryParameter("q", query)
|
||||
.appendQueryParameter("page", page.toString())
|
||||
return GET(uri.toString(), headers)
|
||||
}
|
||||
|
||||
override fun searchMangaNextPageSelector(): String? = popularMangaNextPageSelector()
|
||||
override fun searchMangaSelector(): String = "div.comic-main-section > div > div"
|
||||
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
|
||||
|
||||
// Details
|
||||
|
||||
override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
|
||||
title = document.selectFirst("h1.comic-title").text().dropLast(1).drop(1)
|
||||
thumbnail_url = document.selectFirst("td.comic-cover > img").attr("abs:src")
|
||||
author = document.selectFirst("td.pub-duration").text()
|
||||
artist = author
|
||||
description = document.selectFirst("div.comic-info > p.comic_story").text()
|
||||
genre = document.select("div.comic-info > ul.tags > li").eachText().joinToString(", ")
|
||||
status = when {
|
||||
!document.select("td.comic-titles > a:contains(已完结)").isEmpty() -> SManga.COMPLETED
|
||||
!document.select("td.comic-titles > a:contains(连载中)").isEmpty() -> SManga.ONGOING
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
// Chapters
|
||||
|
||||
override fun chapterListSelector(): String = "div#comic-book-list li.sort_div"
|
||||
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.select("a").attr("href"))
|
||||
name = element.select("a").text()
|
||||
}
|
||||
|
||||
// Pages
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
val script = document.selectFirst("script:containsData(img_data)").data()
|
||||
val imgData = script.substringAfter("img_data = ").substringBefore("\n")
|
||||
val decoded = Duktape.create().use { it.evaluate("${LZSTRING}LZString.decompressFromBase64($imgData)").toString() }
|
||||
val imgServer = document.selectFirst("div.vg-r-data").attr("data-chapter-domain")
|
||||
return decoded.split(",").mapIndexed { i, url ->
|
||||
Page(i, "", "$imgServer/uploads/$url")
|
||||
}
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used.")
|
||||
|
||||
companion object {
|
||||
const val LZSTRING = """var LZString=function(){function o(o,r){if(!t[o]){t[o]={};for(var n=0;n<o.length;n++)t[o][o.charAt(n)]=n}return t[o][r]}var r=String.fromCharCode,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-${'$'}",t={},i={compressToBase64:function(o){if(null==o)return"";var r=i._compress(o,6,function(o){return n.charAt(o)});switch(r.length%4){default:case 0:return r;case 1:return r+"===";case 2:return r+"==";case 3:return r+"="}},decompressFromBase64:function(r){return null==r?"":""==r?null:i._decompress(r.length,32,function(e){return o(n,r.charAt(e))})},compressToUTF16:function(o){return null==o?"":i._compress(o,15,function(o){return r(o+32)})+" "},decompressFromUTF16:function(o){return null==o?"":""==o?null:i._decompress(o.length,16384,function(r){return o.charCodeAt(r)-32})},compressToUint8Array:function(o){for(var r=i.compress(o),n=new Uint8Array(2*r.length),e=0,t=r.length;t>e;e++){var s=r.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null===o||void 0===o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;t>e;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o))}),i.decompress(s.join(""))},compressToEncodedURIComponent:function(o){return null==o?"":i._compress(o,6,function(o){return e.charAt(o)})},decompressFromEncodedURIComponent:function(r){return null==r?"":""==r?null:(r=r.replace(/ /g,"+"),i._decompress(r.length,32,function(n){return o(e,r.charAt(n))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(o,r,n){if(null==o)return"";var e,t,i,s={},p={},u="",c="",a="",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;i<o.length;i+=1)if(u=o.charAt(i),Object.prototype.hasOwnProperty.call(s,u)||(s[u]=f++,p[u]=!0),c=a+u,Object.prototype.hasOwnProperty.call(s,c))a=c;else{if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a]}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++),s[c]=f++,a=String(u)}if(""!==a){if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a]}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==r-1){d.push(n(m));break}v++}return d.join("")},decompress:function(o){return null==o?"":""==o?null:i._decompress(o.length,32768,function(r){return o.charCodeAt(r)})},_decompress:function(o,n,e){var t,i,s,p,u,c,a,l,f=[],h=4,d=4,m=3,v="",w=[],A={val:e(0),position:n,index:1};for(i=0;3>i;i+=1)f[i]=i;for(p=0,c=Math.pow(2,2),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(t=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 2:return""}for(f[3]=l,s=l,w.push(l);;){if(A.index>o)return"";for(p=0,c=Math.pow(2,m),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(l=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 2:return w.join("")}if(0==h&&(h=Math.pow(2,m),m++),f[l])v=f[l];else{if(l!==d)return null;v=s+s.charAt(0)}w.push(v),f[d++]=s+v.charAt(0),h--,s=v,0==h&&(h=Math.pow(2,m),m++)}}};return i}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module&&(module.exports=LZString);"""
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user