diff --git a/app/build.gradle b/app/build.gradle index 725488af..d462c6db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'ru.cleverpumpkin.proguard-dictionaries-generator' + id 'org.jetbrains.kotlin.android' } java { toolchain { @@ -39,6 +40,9 @@ android { unitTests.returnDefaultValues = true unitTests.includeAndroidResources = true } + kotlinOptions { + jvmTarget = '1.8' + } configurations.configureEach { resolutionStrategy { @@ -57,6 +61,7 @@ dependencies { implementation 'com.google.zxing:core:3.3.0' implementation 'com.orhanobut:logger:2.2.0' implementation 'org.jsoup:jsoup:1.15.3' + implementation 'androidx.core:core-ktx:1.10.1' // Required -- JUnit 4 framework testImplementation 'junit:junit:4.12' diff --git a/app/src/main/java/com/github/catvod/spider/NGkt.kt b/app/src/main/java/com/github/catvod/spider/NGkt.kt new file mode 100644 index 00000000..3f005bdb --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/NGkt.kt @@ -0,0 +1,277 @@ +package com.github.catvod.spider + + +import com.github.catvod.bean.Class +import com.github.catvod.bean.Filter +import com.github.catvod.bean.Result +import com.github.catvod.bean.Vod +import com.github.catvod.crawler.Spider +import com.github.catvod.crawler.SpiderDebug +import com.github.catvod.net.OkHttp +import com.github.catvod.utils.Json +import com.github.catvod.utils.ProxyVideo +import com.github.catvod.utils.Util +import com.google.gson.JsonParser +import com.google.gson.annotations.SerializedName +import com.google.gson.reflect.TypeToken +import java.net.URLEncoder + + +class NGkt : Spider() { + private var COMMON_URL: String = Util.base64Decode("aHR0cDovL3lzLmNoYW5nbWVuZ3l1bi5jb20=") + private val FIND_VIDEO_VOD_LIST: String = "/api.php/provide/vod_list" + private val FIND_CLASSIFICATION: String = "/api.php/provide/home_nav" + private val VIDEO_DETAIL: String = "/api.php/provide/vod_detail" + private val SEARCH_SEARCH: String = "/api.php/provide/search_result" + + + private val classList = mutableListOf() + private val filters = LinkedHashMap>() + + + private fun getParams(): Map { + val hashMap: HashMap = java.util.HashMap() + hashMap["devices"] = "android" + hashMap["deviceModel"] = "ASUS_I003DD" + hashMap["deviceBrand"] = "ASUS" + hashMap["deviceVersion"] = "9" + hashMap["deviceScreen"] = "2340*1080" + hashMap["appVersionCode"] = "9" + hashMap["appVersionName"] = "1.0.9" + hashMap["time"] = (System.currentTimeMillis() / 1000).toString() + hashMap["imei"] = "" + hashMap["app"] = "ylys" + return hashMap + } + + fun getHeaders(): Map { + val headers = HashMap() + val currentTimeMillis = System.currentTimeMillis() + headers.put("timeMillis", currentTimeMillis.toString()) + headers.put( + "sign", Util.MD5(Util.base64Decode("I3VCRnN6ZEVNMG9MMEpSbkA=") + "$currentTimeMillis") + ) + return headers + } + + override fun homeContent(filter: Boolean): String { + if (classList.isEmpty()) { + val string = OkHttp.string("$COMMON_URL$FIND_CLASSIFICATION", getParams(), getHeaders()) + val filterList = JsonParser.parseString(string).asJsonArray + for ((index, jsonElement) in filterList.withIndex()) { + if (index == 0) continue + val obj = jsonElement.asJsonObject + val id = obj.get("id").asInt + val name = obj.get("name").asString + val clazz = Class(id.toString(), name) + classList.add(clazz) +// val msgs = obj.get("msg").asJsonArray +// if(msgs.isEmpty){ +// continue +// } +// for (msg in msgs) { +// val msgObj = msg.asJsonObject +// val dataArray = msgObj.get("data").asJsonArray +// val list = mutableListOf() +// for ((index, jsonElement1) in dataArray.withIndex()) { +// if(index == 0) continue +// list.add(Filter.Value(jsonElement1.asString, jsonElement1.asString)) +// } +// +// if(filters[id.toString()].isNullOrEmpty()){ +// filters[id.toString()] = mutableListOf(Filter(msgObj.get("name").asString, dataArray.get(0).asString, list)) +// }else{ +// filters[id.toString()]!!.add(Filter(msgObj.get("name").asString, dataArray.get(0).asString, list)) +// } +// } + } + } + return Result.string(classList, filters) + } + + override fun categoryContent( + tid: String, pg: String, filter: Boolean, extend: java.util.HashMap + ): String { + val params = getParams().toMutableMap() + extend.forEach { (t, u) -> + params[t] = URLEncoder.encode(u, "UTF-8") + } + params["page"] = pg + params["id"] = tid + val string = OkHttp.string("$COMMON_URL$FIND_VIDEO_VOD_LIST", params, getHeaders()) + val type = object : TypeToken>() {}.type + val resp = Json.parseSafe>(string, type) + var vodList = listOf() + if (resp.isSuccess()) { + vodList = resp.list.toVodList() + } else { + SpiderDebug.log("ng cate error: $string") + } + return Result.string(classList, vodList, filters) + } + + override fun detailContent(ids: MutableList): String { + val map = getParams().toMutableMap() + map["id"] = ids[0] + val string = OkHttp.string("$COMMON_URL$VIDEO_DETAIL", map, getHeaders()) + val type = object : TypeToken>() {}.type + val dt = Json.parseSafe>(string, type) + if (!dt.isSuccess()) { + SpiderDebug.log("ng detail err: ${dt.msg}") + return Result.error(dt.msg) + } + return Result.string(dt.data.toVod().apply { setVodId(ids[0]) }) + } + + override fun playerContent(flag: String, id: String, vipFlags: MutableList): String { + val string = OkHttp.string(id) + val type = object : TypeToken>() {}.type + val rst = Json.parseSafe>(string, type) + if (!rst.isSuccess()) { + SpiderDebug.log("play err: ${rst.msg}") + return Result.error(rst.msg) + } + val filter = rst.data.header.filter { it.key.equals("User-Agent", true) } + return Result.get().url(ProxyVideo.buildCommonProxyUrl(rst.data.url, filter)).string() + } + + override fun searchContent(key: String, quick: Boolean): String { + val params = getParams().toMutableMap() + params["video_name"] = URLEncoder.encode(key, "UTF-8") + val string = OkHttp.string("$COMMON_URL$SEARCH_SEARCH", params, getHeaders()) + val type = object : TypeToken>>() {}.type + val rst = Json.parseSafe>>(string, type) + if (!rst.isSuccess()) { + SpiderDebug.log("ng search error:${rst.msg}") + return Result.error(rst.msg) + } + return Result.string(rst.data[0].toVodList()) + } + + + data class Rst( + val code: Int, + val msg: String, + val limit: String, + val pagecount: Int, + val total: Int, + val list: List, + val data: T + ) { + fun isSuccess(): Boolean { + return code == 1 + } + } + + + data class It( + val id: Int, + val img: String, + val name: String, + val score: String, + val msg: String, + ) { + fun toVod(): Vod { + val vod = Vod() + vod.setVodId(id.toString()) + vod.setVodName(name) + vod.setVodRemarks(score) + vod.setVodPic(img) + return vod + } + } + + data class Dt( + val name: String, + val year: String, + val score: String, + val hits: Int, + val type: String, + val img: String, + val info: String, + @SerializedName("total_count") val totalCount: Int, + @SerializedName("player_info") val playerInfo: List + ) { + fun toVod(): Vod { + val vod = Vod() + vod.setVodId(name + score) + vod.setVodName(name) + vod.setVodPic(img) + vod.setVodTag(type) + vod.setVodRemarks(year) + vod.vodContent = info + val playFrom = StringBuilder() + val playUrl = StringBuilder() + for ((_, _, show, _, videoInfo) in playerInfo) { + playFrom.append(show).append("$$$") + for ((_, name1, _, url) in videoInfo) { + playUrl.append(name1).append("$").append(url[0]) + playUrl.append("#") + } + playUrl.append("$$$") + } + vod.setVodPlayFrom(playFrom.toString()) + vod.vodPlayUrl = playUrl.toString() + return vod + } + } + + data class DtIt( + val id: Int, + val from: String, + val show: String, + @SerializedName("url_count") val urlCount: Int, + @SerializedName("video_info") val videoInfo: List + ) + + data class VtInfo( + val id: Int, val name: String, val pic: String, val url: List + ) + + private fun List.toVodList(): MutableList { + val list = mutableListOf() + for (it in this) { + list.add(it.toVod()) + } + return list + } + + data class PlayRst( + val url: String, val header: Map + ) + + data class SearchRst( + val id: Int, val name: String, val data: List + ) { + fun toVodList(): MutableList { + val list = mutableListOf() + for (datum in data) { + list.add(datum.toVOd()) + } + return list + } + } + + data class SearchRstItem( + val id: Int, + val type: Int, + @SerializedName("video_name") val videoName: String, + val qingxidu: String, + val img: String, + val director: String, + @SerializedName("main_actor") val mainActor: String, + val category: String + ) { + fun toVOd(): Vod { + val vod = Vod() + vod.setVodId(id.toString()) + vod.setVodTag(qingxidu) + vod.setVodPic(img) + vod.setVodRemarks(category) + vod.setVodName(videoName) + vod.setVodActor(mainActor) + return vod + } + } + +} \ No newline at end of file diff --git a/app/src/test/java/NGTest.java b/app/src/test/java/NGTest.java index fa959541..7d0e1aae 100644 --- a/app/src/test/java/NGTest.java +++ b/app/src/test/java/NGTest.java @@ -2,6 +2,7 @@ import android.app.Application; import com.github.catvod.spider.Init; import com.github.catvod.spider.NG; +import com.github.catvod.spider.NGkt; import com.github.catvod.utils.Json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -21,13 +22,13 @@ public class NGTest { // @Mock private Application mockContext; - private NG spider; + private NGkt spider; @org.junit.Before public void setUp() throws Exception { mockContext = RuntimeEnvironment.application; Init.init(mockContext); - spider = new NG(); + spider = new NGkt(); spider.init(mockContext, "https://www.czzy.site/"); } diff --git a/build.gradle b/build.gradle index 4f8a5bab..bcf49e38 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { id 'ru.cleverpumpkin.proguard-dictionaries-generator' version '1.0.8' apply false id 'com.android.application' version '8.5.0' apply false id 'com.android.library' version '8.5.0' apply false + id 'org.jetbrains.kotlin.android' version '2.0.10' apply false } tasks.register('clean', Delete) { diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index b0c75795..24c750b2 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index e222f173..16ec2041 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -3521ddb2dfe88c1a32f690de2c64da17 +1f2e3362ef4ccefef998a9f4ea525924 diff --git a/json/index.json b/json/index.json index 5e299051..b8259487 100644 --- a/json/index.json +++ b/json/index.json @@ -1,5 +1,5 @@ { - "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;3521ddb2dfe88c1a32f690de2c64da17", + "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;1f2e3362ef4ccefef998a9f4ea525924", "lives": [ { "name": "直播ipv6", @@ -113,7 +113,7 @@ "filterable": 1 }, { - "key": "NG", + "key": "NGkt", "name": "瓜瓜", "type": 3, "api": "csp_NG", diff --git a/json/index1.json b/json/index1.json index 71d54468..89ff844f 100644 --- a/json/index1.json +++ b/json/index1.json @@ -1,5 +1,5 @@ { - "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;3521ddb2dfe88c1a32f690de2c64da17", + "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;1f2e3362ef4ccefef998a9f4ea525924", "lives": [ { "name": "直播ipv6",