Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/refactor 增加漫画楼 #3

Open
wants to merge 28 commits into
base: feature/refactor
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
52d9e84
Update gradle-wrapper.properties
mabDc Jul 26, 2019
50ebc37
add source https://www.manhualou.com
mabDc Jul 26, 2019
5ae50b4
add source https://www.manhualou.com
mabDc Jul 26, 2019
b0da57c
fix source https://www.manhualou.com
mabDc Jul 27, 2019
76ff4d1
Revert "Update gradle-wrapper.properties"
mabDc Jul 27, 2019
bd1c54d
fix source https://www.manhualou.com
mabDc Jul 27, 2019
ddbfb4c
add source https://www.manhualou.com
mabDc Jul 27, 2019
4e6fc93
Update gradle-wrapper.properties
mabDc Jul 27, 2019
60807bf
add source https://www.tohomh123.com
mabDc Jul 27, 2019
5208ffd
Merge remote-tracking branch 'origin/feature/refactor' into feature/r…
mabDc Jul 27, 2019
d1f0132
add source https://manga.bilibili.com
mabDc Aug 6, 2019
13b2ee2
add source https://manga.bilibili.com
mabDc Aug 6, 2019
049e1dc
add source http://www.u17.com
mabDc Aug 6, 2019
4ee5f02
add source http://www.u17.com
mabDc Aug 6, 2019
5cc4c9b
fix
mabDc Aug 7, 2019
01f10a2
add source https://ac.qq.com/
mabDc Aug 8, 2019
0bbc16e
add source 姑且叫做漫画台
mabDc Aug 9, 2019
75ccc3e
add source https://www.dongmanmanhua.cn
mabDc Aug 9, 2019
f9eaaa9
fix
mabDc Aug 9, 2019
6356d0e
replace u17 to http://app.u17.com
mabDc Aug 10, 2019
d60628b
fix
mabDc Aug 10, 2019
2b54834
fix
mabDc Aug 14, 2019
a1561fb
Revert "fix"
mabDc Aug 15, 2019
2f15ab9
Revert "fix"
mabDc Aug 15, 2019
635e875
commit
mabDc Nov 9, 2019
f530f07
commit
mabDc Nov 9, 2019
27e41a0
fix manhuadui
mabDc Nov 9, 2019
f98d9ce
fix manhuadui
mabDc Nov 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,36 @@ apply plugin: 'kotlin-android-extensions'

apply plugin: 'kotlin-kapt'

def keystorePropertiesFile = rootProject.file(".travis/keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
def keyStoreFile = file(keystoreProperties['storeFileLocal'])
if (!keyStoreFile.exists()){
keyStoreFile = file(keystoreProperties['storeFileCI'])
}
//def keystorePropertiesFile = rootProject.file(".travis/keystore.properties")
//def keystoreProperties = new Properties()
//keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
//def keyStoreFile = file(keystoreProperties['storeFileLocal'])
//if (!keyStoreFile.exists()){
// keyStoreFile = file(keystoreProperties['storeFileCI'])
//}

android {
lintOptions {
checkReleaseBuilds false
abortOnError false
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPwd']
storeFile keyStoreFile
storePassword keystoreProperties['storePwd']
myConfig {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
v1SigningEnabled true
v2SigningEnabled true
}
}
compileSdkVersion 28
defaultConfig {
applicationId "top.rechinx.meow"
minSdkVersion 16
targetSdkVersion 27
versionCode 6
versionName "1.0.6"
versionCode 8
versionName "1.0.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
Expand All @@ -38,7 +44,7 @@ android {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
signingConfig signingConfigs.myConfig
}
debug {
applicationIdSuffix ".debug"
Expand Down
5 changes: 5 additions & 0 deletions app/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# RELEASE_STORE_FILE = "..\\key.properties.jks"
RELEASE_STORE_FILE=.\\key.properties.jks
RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=key0
RELEASE_STORE_PASSWORD=android
Binary file added app/key.properties.jks
Binary file not shown.
14 changes: 12 additions & 2 deletions app/src/main/java/top/rechinx/meow/core/source/SourceManager.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package top.rechinx.meow.core.source

import android.content.Context
import top.rechinx.meow.core.source.internal.Dmzj
import top.rechinx.meow.core.source.internal.*
import top.rechinx.meowo.core.source.internal.Tohomh

class SourceManager(private val context: Context) {

Expand Down Expand Up @@ -36,7 +37,16 @@ class SourceManager(private val context: Context) {
}

private fun createInternalSources(): List<Source> = listOf(
Dmzj()
Dmzj(),
ManHuaLou(),
Tohomh(),
Bilibili(),
//U17www(),
Tencent(),
ManHuaTai(),
DongMan(),
U17(),
ManHuaDui()
//Shuhui(),
//EHentai()
)
Expand Down
248 changes: 248 additions & 0 deletions app/src/main/java/top/rechinx/meow/core/source/internal/Bilibili.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
package top.rechinx.meow.core.source.internal

import okhttp3.*
import org.json.JSONObject
import top.rechinx.meow.core.source.HttpSource
import top.rechinx.meow.core.source.model.*
import java.util.zip.ZipInputStream
import kotlin.experimental.xor

class Bilibili:HttpSource() {

override val name = "Bilibili"
override val baseUrl = "https://manga.bilibili.com"
private val cleanRegex = Regex("</?em.*?>")

private fun POST(url: String, json:String) = Request.Builder()
.url(url)
.post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json))
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36")
.build()

override fun searchMangaRequest(keyword: String, page: Int, filters: FilterList): Request {
if("" != keyword){
return POST("$baseUrl/twirp/comic.v1.Comic/Search?device=pc&platform=web",
"{\"key_word\":\"$keyword\",\"page_num\":$page,\"page_size\":9}")
} else{
val json = filters.map { (it as UriPartFilter).getUrl() }.joinToString(",")
return POST("$baseUrl/twirp/comic.v1.Comic/ClassPage?device=pc&platform=web",
"{$json,\"page_num\":$page,\"page_size\":18}")
}
}

private fun commonMangaParse(response: Response): PagedList<SManga> {
val json = JSONObject(response.body()!!.string())
if(response.request().url().toString().contains("Search")){
val data = json.getJSONObject("data")
val arr = data.getJSONArray("list")
val ret = ArrayList<SManga>()
for (i in 0 until arr.length()) {
val info = arr.getJSONObject(i)
ret.add(SManga.create().apply {
title = info.getString("title").replace(cleanRegex, "")
thumbnail_url = info.getString("vertical_cover")
url = info.getInt("id").toString()

val tmp = ArrayList<String>()
val styles = info.getJSONArray("styles")
for (j in 0 until styles.length()) {
tmp.add(styles.getString(j))
}
genre = tmp.joinToString(", ")

tmp.clear()
val authors = info.getJSONArray("author_name")
for (j in 0 until authors.length()) {
tmp.add(authors.getString(j))
}
author = tmp.joinToString(", ").replace(cleanRegex, "")
})
}
return PagedList(ret, true)
}
else{
val arr = json.getJSONArray("data")
val ret = ArrayList<SManga>(arr.length())
for (i in 0 until arr.length()) {
val info = arr.getJSONObject(i)
ret.add(SManga.create().apply {
title = info.getString("title")
thumbnail_url = info.getString("vertical_cover")
url = info.getInt("season_id").toString()
})
}
return PagedList(ret, true)
}
}

override fun searchMangaParse(response: Response): PagedList<SManga> = commonMangaParse(response)

override fun popularMangaRequest(page: Int): Request = POST("$baseUrl/twirp/comic.v1.Comic/ClassPage?device=pc&platform=web",
"{\"style_id\":-1,\"area_id\":-1,\"is_finish\":-1,\"order\":0,\"page_num\":$page,\"page_size\":18,\"is_free\":-1}")

override fun popularMangaParse(response: Response): PagedList<SManga> = commonMangaParse(response)

override fun mangaInfoRequest(url: String): Request = POST("$baseUrl/twirp/comic.v2.Comic/ComicDetail?device=pc&platform=web","{\"comic_id\":$url}")

override fun mangaInfoParse(response: Response): SManga = SManga.create().apply {
val json = JSONObject(response.body()!!.string())
val data = json.getJSONObject("data")
title = data.getString("title")
thumbnail_url = data.getString("vertical_cover")
url = data.getInt("id").toString()

val tmp = ArrayList<String>()
val authors = data.getJSONArray("author_name")
for (j in 0 until authors.length()) {
tmp.add(authors.getString(j))
}
author = tmp.joinToString(", ")

status = when(data.getInt("is_finish")) {
1 -> SManga.COMPLETED
0 -> SManga.ONGOING
else -> SManga.UNKNOWN
}

tmp.clear()
val styles = data.getJSONArray("styles")
for (j in 0 until styles.length()) {
tmp.add(styles.getString(j))
}
genre = tmp.joinToString(", ")

description = data.getString("evaluate")
}

override fun chaptersRequest(page: Int, url: String): Request = POST("$baseUrl/twirp/comic.v2.Comic/ComicDetail?device=pc&platform=web","{\"comic_id\":$url}")

override fun chaptersParse(response: Response): PagedList<SChapter> {
val json = JSONObject(response.body()!!.string())
val data = json.getJSONObject("data")
val list = data.getJSONArray("ep_list")

val ret = ArrayList<SChapter>()
for (i in 0 until list.length()) {
val chapter = list.getJSONObject(i)
ret.add(SChapter.create().apply {
name = (when(chapter.getBoolean("is_locked")){
true -> "🔒" + chapter.getString("short_title")
false -> chapter.getString("short_title")
})
url = chapter.getInt("id").toString()
})
}
return PagedList(ret, false)
}

override fun mangaPagesRequest(chapter: SChapter): Request = POST("$baseUrl/twirp/comic.v1.Comic/GetImageIndex?device=pc&platform=web","{\"ep_id\":${chapter.url}}")


override fun mangaPagesParse(response: Response): List<MangaPage> {
val json = JSONObject(response.body()!!.string())
if("" != json.getString("msg")){
val ret = ArrayList<MangaPage>()
ret.add(MangaPage(0, "", "https://i0.hdslb.com/bfs/activity-plat/cover/20171017/496nrnmz9x.png"))
return ret
}

val data = json.getJSONObject("data")
val path = data.getString("path")
var host = "https://i0.hdslb.com"
if(data.has("host") && ""!=data.getString("host")){
host = data.getString("host")
}
val m = Regex("^/bfs/manga/(\\d+)/(\\d+)").find(path)!!
val cid = m.groupValues[1].toInt()
val epid = m.groupValues[2].toInt()

var bytes = client.newCall(Request.Builder()
.url(host+path)
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36")
.build()).execute().body()!!.bytes()
bytes = bytes.sliceArray(9 until bytes.size)

val key = ByteArray(8)
key[0] = epid.toByte()
key[1] = epid.shr(8).toByte()
key[2] = epid.shr(16).toByte()
key[3] = epid.shr(24).toByte()
key[4] = cid.toByte()
key[5] = cid.shr(8).toByte()
key[6] = cid.shr(16).toByte()
key[7] = cid.shr(24).toByte()
for (i in 0 until bytes.size){
bytes[i] = bytes[i].xor(key[i % 8])
}

val zis = ZipInputStream(bytes.inputStream())
zis.nextEntry
val pics = JSONObject(zis.bufferedReader().use { it.readText() }).getJSONArray("pics")
val tokens = JSONObject(client.newCall(POST("$baseUrl/twirp/comic.v1.Comic/ImageToken?device=pc&platform=web",
"{\"urls\":\"${pics.toString().replace("\"","\\\"")}\"}"))
.execute().body()!!.string()).getJSONArray("data")
val ret = ArrayList<MangaPage>()
for (i in 0 until tokens.length()) {
val token = tokens.getJSONObject(i)
ret.add(MangaPage(i, "", "${token.getString("url")}?token=${token.getString("token")}"))
}
return ret
}

override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Unused method was called somehow!")

override fun getFilterList(): FilterList = FilterList(StylesFilter(), AreasFilter(), StatusFilter(), PricesFilter(), OrdersFilter())

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 getUrl() = vals[state].second
}

private class StylesFilter : UriPartFilter("题材", arrayOf(
Pair("全部", "\"style_id\":-1"),
Pair("冒险", "\"style_id\":1013"),
Pair("热血", "\"style_id\":999"),
Pair("搞笑", "\"style_id\":994"),
Pair("恋爱", "\"style_id\":995"),
Pair("少女", "\"style_id\":1026"),
Pair("日常", "\"style_id\":1020"),
Pair("校园", "\"style_id\":1001"),
Pair("运动", "\"style_id\":1010"),
Pair("正能量", "\"style_id\":1028"),
Pair("治愈", "\"style_id\":1007"),
Pair("古风", "\"style_id\":997"),
Pair("玄幻", "\"style_id\":1016"),
Pair("奇幻", "\"style_id\":998"),
Pair("惊奇", "\"style_id\":996"),
Pair("悬疑", "\"style_id\":1023"),
Pair("都市", "\"style_id\":1002"),
Pair("总裁", "\"style_id\":1004")
))

private class AreasFilter : UriPartFilter("地区", arrayOf(
Pair("全部", "\"area_id\":-1"),
Pair("大陆", "\"area_id\":1"),
Pair("日本", "\"area_id\":2"),
Pair("其他", "\"area_id\":5")
))

private class StatusFilter : UriPartFilter("进度", arrayOf(
Pair("全部", "\"is_finish\":-1"),
Pair("连载", "\"is_finish\":0"),
Pair("完结", "\"is_finish\":1"),
Pair("新上架", "\"is_finish\":2")
))

private class PricesFilter : UriPartFilter("收费", arrayOf(
Pair("全部", "\"is_free\":-1"),
Pair("免费", "\"is_free\":1"),
Pair("付费", "\"is_free\":2")
))

private class OrdersFilter : UriPartFilter("排序", arrayOf(
Pair("人气推荐", "\"order\":0"),
Pair("更新时间", "\"order\":1"),
Pair("追漫人数", "\"order\":2")
))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Dmzj: HttpSource() {

private fun GET(url: String) = Request.Builder()
.url(url)
.addHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 ")
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36")
.build()

override fun searchMangaRequest(query: String, page: Int, filterList: FilterList): Request {
Expand Down
Loading