bd网盘
This commit is contained in:
parent
b672af3b1d
commit
873e10b31e
|
|
@ -0,0 +1,37 @@
|
|||
package com.github.catvod.api;
|
||||
|
||||
|
||||
|
||||
import com.github.catvod.bean.BD.Cache;
|
||||
import com.github.catvod.bean.yun.User;
|
||||
import com.github.catvod.utils.Path;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class BaiDuYunHandler {
|
||||
|
||||
private final Cache cache;
|
||||
|
||||
public File getCache() {
|
||||
return Path.tv("bd");
|
||||
}
|
||||
|
||||
private BaiDuYunHandler() {
|
||||
cache = Cache.objectFrom(Path.read(getCache()));
|
||||
}
|
||||
|
||||
private static class Loader {
|
||||
static volatile BaiDuYunHandler INSTANCE = new BaiDuYunHandler();
|
||||
}
|
||||
|
||||
public static BaiDuYunHandler get() {
|
||||
return BaiDuYunHandler.Loader.INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
public String getToken() {
|
||||
User user = cache.getUser();
|
||||
return user.getCookie();
|
||||
//return "cGM6MTg4OTY3ODE2MDE6eTM1Tjd1dG58MXxSQ1N8MTc1NDQ2OTgwNzEyOXxzMlN0T1VEV3lOVmF5V3pNbGFfM2tJbVp1ZmlqSHBqaEhTSzVyNHZqVXNRLmlhV3loSUxHNDFkMUI5N1BqXzhWN0dtVWtKLnBTclhpNGpZU1EuTGZWMTV3MVFoZmNpcEVoZkxUV2tvYjB0bkFTYV9RTUhhaHhveWx6YkdmcEhQdjNCS1lrbnp1LkxaWDdKOE40YkNNRjkzT3piNmx2Y0d3TWdVUkl5b18ubVUt";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
package com.github.catvod.api
|
||||
|
||||
import com.github.catvod.bean.Result
|
||||
import com.github.catvod.bean.Vod
|
||||
import com.github.catvod.bean.Vod.VodPlayBuilder
|
||||
import com.github.catvod.net.OkHttp
|
||||
import com.github.catvod.utils.Json
|
||||
import com.github.catvod.utils.ProxyVideo
|
||||
import com.github.catvod.utils.ProxyServer.buildProxyUrl
|
||||
import com.github.catvod.utils.Util
|
||||
import com.github.catvod.utils.Util.MEDIA
|
||||
import com.google.gson.JsonObject
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import java.security.MessageDigest
|
||||
import java.util.*
|
||||
|
||||
class BaiduDrive {
|
||||
object BaiduDrive {
|
||||
private val cache = mutableMapOf<String, String>();
|
||||
|
||||
private val headers = mapOf(
|
||||
"User-Agent" to "Mozilla/5.0 (Linux; Android 12; SM-X800) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.40 Safari/537.36",
|
||||
|
|
@ -22,23 +22,27 @@ class BaiduDrive {
|
|||
"Referer" to "https://pan.baidu.com/"
|
||||
)
|
||||
|
||||
private val cookies =
|
||||
"BIDUPSID=D122360716A06862B6689D4FE32053A1; PSTM=1756869077; MAWEBCUID=web_KAGxElHEQyrFImqrzARlkIssFfvhfCLGaXDsxmWKbhxsfEsvhs; PANWEB=1; delPer=0; ZFY=LJHc036:AkCyc1OPqFkXugSCgXnfaMIH:AjDQUOfkXtP4:C; BDRCVFR[uPX25oyLwh6]=mk3SLVN4HKm; BAIDUID_REF=B0FC75130A1A8DF92DC8685381870C9E:FG=1; H_WISE_SIDS_BFESS=110085_656765_660924_665265_666660_667682_662823_668348_668761_668756_669314_667565_669628_669693_669848_669685_669681_670119_670114_670116_670307_669051_670308_670357_670598_669700_670824_669791_669664_670557_667838_669418_663788; MCITY=-276%3A; ZD_ENTRY=baidu; PSINO=5; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDRCVFR[S4-dAuiWMmn]=I67x6TjHwwYf0; BA_HECTOR=a0a1a50hakakah242g25a18kah41801kejiv325; BAIDUID=102896B6EA4554BB74C3F8C78B676C7B:FG=1; BAIDUID_BFESS=102896B6EA4554BB74C3F8C78B676C7B:FG=1; H_WISE_SIDS=60273_63141_64007_64982_65120_65190_65227_65246_65254_65273_65280_65310_65361_65368_65417_65457_65451_65510_65543_65572_65596_65620_65599_65636_65476; H_PS_PSSID=60273_63141_64007_64982_65120_65190_65227_65246_65254_65273_65280_65310_65361_65368_65417_65457_65451_65510_65543_65572_65596_65620_65599_65636_65476; csrfToken=6tn2uwGoOUgn87ZBElHEGjCD; newlogin=1; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGmVXQmqM6seEAgB/LlOs0+zGEimjy3MrXEpSuItnI4KDwxAMUTOS16BfoXMcd2lpC/ZmOvCi7lsE0/UM0w4HSMVhh7EfifsXEYHtGj52zkQan6UDL686lBL6BHUyL9m3lfGgLbz7OSojK1zRbqBESR5Pdk2R9IA3lxxOVzA+Iw1TWLSgWjlFVG9Xmh1+20oPSbrzvDjYtVPmZ+9/6evcXmhcO1Y58MgLozKnaQIaLfWRFwa8A3ZyTRp/cDxRMhYc97xUSUZS0ReZYJMPG6nCsxNJlhI2UyeJA6QroZFMelR7tnTNS/pLMWceus0e757/UMPmrThfasmhDJrMFcBfoSrAAv3LCf1Y7/fHL3PTSf9vid/u2VLX4h1nBtx8EF07eCMhWVv+2qjbPV7ZhXk3reaWRFEeso3s/Kc9n/UXtUfNU1sHiCdbrCW5yYsuSM9SPGDZsl7FhTAKw7qIu38vFZiq+DRc8Vbf7jOiN9xPe0lOdZHUhGHZ82rL5jTCsILwcRVCndrarbwmu7G154MpYiKmTXZkqV7Alo4QZzicdyMbWvwvmR2/m//YVTM8qeZWgDSHjDmtehgLWM45zARbPujeqU0T92Gmgs89l2htrSKITeYE0TpfIvjPXsgyQghyP8U3sViHT1z07gbfu1XO5QQ/upk1AkHGkWrkbMWm+rpwpdImdyxYIjA1uSy2hfTFv/d3cnXH4nh+maaicAPllDgrppZTr0lDf2Vsiy73L8egP9ck5gsaaSE4obz9V1JGvyp8lNw+IyCN2Gou0efGgcYWqtuH+3KMtXW4uAv+XUaBDreXqEwrDxmyUrecavkqQ9rGRChHnhPuJeIKACPXiVuli9ItRLEkdb1mLxNHAk3uJy88YX/Rf/sKUjR12zxRTDxxJNDJS+Dlsbqu3n4I65ujli/3rQ8Zk1MjmTOsz9+kTqOM4upsnQ6IWq/zeZTItMCgHpQhuhr4ip73honuzoJgge1cqWBFYvpabAPTOERTOP1kmx5SXPARX5uxyJzAiNILBC8zh7fGfNXOWV37O9gEbYklWGnWpu55tg8Y8GaT7BFVDtu1KaJzjx51nTN1+xVI8c7otOFm3py1Y+wrt2CfI5v5JSd2kRNZE7s6bQrA5yMI31SfUDgxDrsd6lPtUU=; XFI=627d86b0-a655-11f0-b1eb-0f9d37032cfb; XFCS=B8C411ADE99EE9C3B29FDF31558D538BB636F205DF4F52FE2E57F1312E01079F; XFT=yvSTf+EcMsgYHnGyS774OLqljjYcjil0ZkCgy1g0Aso=; BDUSS=55b2xxaGRqOTdSNE0xVUltZFRRTWdkLXZ0VWtmT2steWw5OHNYUFVDa1FZUkZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDU6WgQ1OloWk; BDUSS_BFESS=55b2xxaGRqOTdSNE0xVUltZFRRTWdkLXZ0VWtmT2steWw5OHNYUFVDa1FZUkZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDU6WgQ1OloWk; STOKEN=987012cdf0b7fd13bbd965b4d1c68f53eac6c0e7d6b4535e6d027f648dd4acae; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1760154644; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1760161311; BDCLND=nGNVyBu9MKpWH7zlTs5oUxFdRQXvai300GnFk9MGb1A%3D; PANPSC=15679126166052069121%3Au9Rut0jYI4qaUfTgVmgBplcS2d9ns3O5C61tf8CKQkineeMhfK4oNnqD0KGUduys6WRWG5ljYM%2BmSRyxE8aegpNZSd%2B1SXYsBm6rqQ5QdYLMOw0WWU7tUSqLe%2F%2Bg%2FDWP4i2i1JdCg%2BQ3uGXWluwqDsVi7NXtJ9t339k3FioH%2FAqA1gqZJvix0rmqJrAOClKcX0r3JWTW68Ah7IX89yGaj0Eyueu6wBwEDZC8PXQ9dy48%2FX4Y2hjenzCvC2qz1EInzo%2F1llKJ4P7gQiGlDEks0p8M%2Flyi7z69BCKhGHn%2Fawh9ff8YI35KVRVksnPVbyr%2FTaFwbj9JM%2FCSsVZaqyA8TA%3D%3D; ndut_fmt=DACA0AD3BE7AF69A4F5690C5C8C96C528423560F2C90164DB3A1486ED8014AB7; ab_sr=1.0.1_Yjg0ZTYxNzc2MjUxNzUyMjMzNWYzNzY0ODA5Y2JhMmMxMjZiNDg2MTcyNjM0NGJiY2NkMzkzMjEzMjM0ZTVhMThlYTU5YzE5M2VkODRiYzFjYTRkY2Q4OGI5OWE3ZjgxMzM4NmRhZTMzNjE2MTc0MWJkYTMyZmE5OWRlNGIyZGI3ZDhkZDU5ZjZmMGNhODFhZWFhZmUzODAwZDVhOGZhMTYyNTgzNjk3OWRlMWNhYjUxYjBmMTQyZDZhMzQ4ZGRh"
|
||||
private val apiHost = "https://pan.baidu.com"
|
||||
private val name = "baidu"
|
||||
private val displayName = listOf("百度原画", "百度转码")
|
||||
private val saveDirName = "TVBOX_BD"
|
||||
|
||||
fun canHandle(url: String): Boolean {
|
||||
return "pan.baidu" in url
|
||||
private var cookies = BaiDuYunHandler.get().token
|
||||
|
||||
|
||||
private val apiHost = "https://pan.baidu.com"
|
||||
private val displayName = listOf("BD原画")
|
||||
|
||||
|
||||
fun setCookie(extend: String) {
|
||||
if (extend.isEmpty()) return
|
||||
cookies = extend
|
||||
}
|
||||
|
||||
suspend fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> {
|
||||
fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> {
|
||||
if (urls.isEmpty()) return emptyList<String>() to emptyList()
|
||||
|
||||
return coroutineScope {
|
||||
|
||||
val results = urls.map { url ->
|
||||
async { processSingleLink(url) }
|
||||
}.awaitAll()
|
||||
processSingleLink(url)
|
||||
}
|
||||
|
||||
val names = mutableListOf<String>()
|
||||
val allVideos = mutableListOf<String>()
|
||||
|
|
@ -48,15 +52,16 @@ class BaiduDrive {
|
|||
val (avideos, videos) = result
|
||||
names.addAll(displayName)
|
||||
allVideos.add(avideos.joinToString("#"))
|
||||
allVideos.add(videos.joinToString("#"))
|
||||
//allVideos.add(videos.joinToString("#"))
|
||||
}
|
||||
}
|
||||
|
||||
names to allVideos
|
||||
}
|
||||
return names to allVideos
|
||||
|
||||
|
||||
}
|
||||
|
||||
private suspend fun processSingleLink(url: String): Pair<List<String>, List<String>>? {
|
||||
private fun processSingleLink(url: String): Pair<List<String>, List<String>>? {
|
||||
return try {
|
||||
val urlInfo = parseShareUrl(url)
|
||||
if (urlInfo.containsKey("error")) return null
|
||||
|
|
@ -71,7 +76,7 @@ class BaiduDrive {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun parseShareUrl(url: String): Map<String, String> {
|
||||
private fun parseShareUrl(url: String): Map<String, String> {
|
||||
var lurl = url
|
||||
if ("提取码" in url) lurl = url.replace("提取码:", "?pwd=")
|
||||
|
||||
|
|
@ -114,7 +119,7 @@ class BaiduDrive {
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun getAllVideos(tokenInfo: Map<String, String>): Pair<List<String>, List<String>> {
|
||||
private fun getAllVideos(tokenInfo: Map<String, String>): Pair<List<String>, List<String>> {
|
||||
val videos = mutableListOf<String>()
|
||||
val avideos = mutableListOf<String>()
|
||||
val seenFolders = mutableSetOf<String>()
|
||||
|
|
@ -181,8 +186,8 @@ class BaiduDrive {
|
|||
pendingFolders.clear()
|
||||
|
||||
val results = currentBatch.map { folderInfo ->
|
||||
coroutineScope { async { getFolderContents(folderInfo) } }
|
||||
}.awaitAll()
|
||||
getFolderContents(folderInfo)
|
||||
}
|
||||
|
||||
results.forEachIndexed { i, result ->
|
||||
val folderInfo = currentBatch[i]
|
||||
|
|
@ -327,9 +332,10 @@ class BaiduDrive {
|
|||
}
|
||||
|
||||
|
||||
fun getBdUid(): String? {/* if (Cache.get("baidu:uid") != null) {
|
||||
return Cache.get("baidu:uid") as? String
|
||||
}*/
|
||||
fun getBdUid(): String? {
|
||||
if (cache["uid"] != null) {
|
||||
return cache["uid"]
|
||||
}
|
||||
val tempHeader = headers.toMutableMap()
|
||||
tempHeader.put("Cookie", cookies)
|
||||
try {
|
||||
|
|
@ -349,7 +355,7 @@ class BaiduDrive {
|
|||
val uidValue = fields?.get("uid")?.asString
|
||||
|
||||
if (uidValue != null) {
|
||||
// Cache.set("baidu:uid", uidValue)
|
||||
cache["uid"] = uidValue
|
||||
return uidValue
|
||||
} else {
|
||||
throw Exception("Failed to retrieve UID from Baidu Drive.")
|
||||
|
|
@ -360,7 +366,7 @@ class BaiduDrive {
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun _getSign(videoData: JsonObject): Pair<String, String> {
|
||||
fun _getSign(videoData: JsonObject): Pair<String, String> {
|
||||
val tempHeader = headers.toMutableMap()
|
||||
tempHeader.put("Cookie", cookies)
|
||||
val response: String? = OkHttp.string(
|
||||
|
|
@ -380,7 +386,7 @@ class BaiduDrive {
|
|||
}
|
||||
|
||||
|
||||
suspend fun _getDownloadUrl(videoData: JsonObject): String {
|
||||
fun _getDownloadUrl(videoData: JsonObject): String {
|
||||
return try {
|
||||
var cookie = ""
|
||||
val BDCLND = "BDCLND=" + videoData["randsk"].asString
|
||||
|
|
@ -409,10 +415,15 @@ class BaiduDrive {
|
|||
"Referer" to "https://pan.baidu.com",
|
||||
"Cookie" to cookie
|
||||
)
|
||||
// 先清空文件夹在创建文件夹
|
||||
|
||||
_deleteTransferFile("/$saveDirName")
|
||||
//创建路径
|
||||
createSaveDir()
|
||||
|
||||
|
||||
val data =
|
||||
"from=${videoData["uk"].asString}&shareid=${videoData["shareid"].asString}&ondup=newcopy&path=/&fsidlist=[${videoData["fid"].asString}]"
|
||||
"from=${videoData["uk"].asString}&shareid=${videoData["shareid"].asString}&ondup=newcopy&path=/${saveDirName}&fsidlist=[${videoData["fid"].asString}]"
|
||||
|
||||
var to = ""
|
||||
for (i in 1..30) {
|
||||
|
|
@ -424,7 +435,7 @@ class BaiduDrive {
|
|||
val result = Json.safeObject(response.body)
|
||||
|
||||
try {
|
||||
to = (result["extra"].asJsonObject)["list"] .asJsonArray[0].asJsonObject["to"].asString
|
||||
to = (result["extra"].asJsonObject)["list"].asJsonArray[0].asJsonObject["to"].asString
|
||||
// videoData["to"] = to
|
||||
if (to.isNotEmpty()) {
|
||||
println("成功转存文件到: $to")
|
||||
|
|
@ -471,18 +482,18 @@ class BaiduDrive {
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun getVideoUrl(videoData: JsonObject): Map<String, Any> {
|
||||
fun getVideoUrl(videoData: JsonObject, flag: String): Map<String, Any> {
|
||||
return try {
|
||||
val bdUid = getBdUid()
|
||||
println("获取百度网盘用户ID: $bdUid")
|
||||
val plist = mutableListOf<Pair<String, String>>()
|
||||
if (videoData["qtype"].asString == "original") {
|
||||
var app = true
|
||||
|
||||
if (flag.contains("原画")) {
|
||||
|
||||
var headersApp = mapOf("User-Agent" to "netdisk;P2SP;2.2.91.136;android-android;")
|
||||
|
||||
var downloadUrl = _getAppDownloadUrl(videoData)
|
||||
if (downloadUrl.isEmpty()) {
|
||||
app = false
|
||||
|
||||
headersApp = mapOf(
|
||||
|
||||
"User-Agent" to "netdisk;1.4.2;22021211RC;android-android;12;JSbridge4.4.0;jointBridge;1.1.0;"
|
||||
|
|
@ -491,14 +502,11 @@ class BaiduDrive {
|
|||
downloadUrl = _getDownloadUrl(videoData)
|
||||
}
|
||||
if (downloadUrl.isNotEmpty()) {
|
||||
plist.add(Pair("原画", ProxyVideo.buildCommonProxyUrl(downloadUrl, headersApp)))
|
||||
|
||||
val result = mapOf(
|
||||
"parse" to 0, "url" to plist, "header" to headersApp.toString()
|
||||
"parse" to "0", "url" to downloadUrl, "header" to headersApp
|
||||
)
|
||||
// 使用线程而不是asyncio任务
|
||||
Thread {
|
||||
// _runDeleteInThread(videoData["to"] as? String)
|
||||
}.start()
|
||||
|
||||
result
|
||||
} else {
|
||||
_handleError
|
||||
|
|
@ -508,12 +516,11 @@ class BaiduDrive {
|
|||
if (sign.isEmpty() || time.isEmpty()) {
|
||||
return _handleError
|
||||
}
|
||||
val plist = _getPlayList(videoData, sign, time)/* val headers = Headers.build {
|
||||
append(HttpHeaders.UserAgent, USER_AGENT)
|
||||
append(HttpHeaders.Cookie, dictToCookieStr(cookies))
|
||||
}*/
|
||||
val plist = _getPlayList(videoData, sign, time)
|
||||
val tempHeader = headers.toMutableMap()
|
||||
tempHeader.put("Cookie", cookies)
|
||||
mapOf(
|
||||
"parse" to 0, "url" to plist, "header" to headers.toString()
|
||||
"parse" to "0", "url" to plist[0], "header" to tempHeader
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -522,7 +529,7 @@ class BaiduDrive {
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun _getAppDownloadUrl(videoData: JsonObject): String {
|
||||
private fun _getAppDownloadUrl(videoData: JsonObject): String {
|
||||
return try {
|
||||
val headers = mapOf<String, String>(
|
||||
|
||||
|
|
@ -547,15 +554,21 @@ class BaiduDrive {
|
|||
"time" to t.toString()
|
||||
).toMutableMap()
|
||||
|
||||
val randstr =
|
||||
this.sha1(this.sha1(Util.findByRegex("BDUSS=(.+?);",cookies,1)) + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF$t${params["devuid"]}11.30.2ae5821440fab5e1a61a025f014bd8972")
|
||||
val randstr = this.sha1(
|
||||
this.sha1(
|
||||
Util.findByRegex(
|
||||
"BDUSS=(.+?);", cookies, 1
|
||||
)
|
||||
) + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF$t${params["devuid"]}11.30.2ae5821440fab5e1a61a025f014bd8972"
|
||||
)
|
||||
|
||||
params.put("rand", sha1(randstr))
|
||||
params.put("rand", randstr)
|
||||
|
||||
val response = OkHttp.string(
|
||||
"${apiHost}/share/list", params, headers
|
||||
)
|
||||
|
||||
val json = Json.safeObject(response)
|
||||
val dlink = json["list"].asJsonArray[0].asJsonObject["dlink"].asString
|
||||
|
||||
/* val url = response["data"] as Map<String, Any>
|
||||
val list = url["list"] as List<Map<String, Any>>
|
||||
|
|
@ -570,104 +583,142 @@ class BaiduDrive {
|
|||
|
||||
val pUrl = pDataResponse.headers[HttpHeaders.Location]?.toString()
|
||||
pUrl ?: dlink*/
|
||||
""
|
||||
dlink
|
||||
} catch (e: Exception) {
|
||||
println("获取下载链接失败: ${e.message}")
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
private fun _getPlayList(videoData: JsonObject, sign: String, time: String): List<Pair<String, String>> {
|
||||
val hz = listOf("1080P", "720P", "480P")
|
||||
val plist = mutableListOf<Pair<String, String>>()
|
||||
private fun _getPlayList(videoData: JsonObject, sign: String, time: String): List<String> {
|
||||
val hz = getPlayFormatList()
|
||||
val plist = mutableListOf<String>()
|
||||
|
||||
for (quality in hz) {
|
||||
val url =
|
||||
("${apiHost}/share/streaming?" + "uk=${videoData["uk"]}&" + "fid=${videoData["fid"]}&" + "sign=$sign&" + "timestamp=$time&" + "shareid=${videoData["shareid"]}&" + "type=M3U8_AUTO_${
|
||||
("${apiHost}/share/streaming?" + "uk=${videoData["uk"].asString}&" + "fid=${videoData["fid"].asString}&" + "sign=$sign&" + "timestamp=$time&" + "shareid=${videoData["shareid"].asString}&" + "type=M3U8_AUTO_${
|
||||
quality.replace(
|
||||
"P", ""
|
||||
)
|
||||
}")
|
||||
plist.add(Pair(quality, url))
|
||||
plist.add(url)
|
||||
}
|
||||
|
||||
return plist
|
||||
}/*
|
||||
|
||||
private suspend fun _deleteTransferFile(filePath: String) {
|
||||
try {
|
||||
val url = "$API_HOST/api/filemanager"
|
||||
val params = Parameters.build {
|
||||
append("opera", "delete")
|
||||
append("clienttype", "1")
|
||||
}
|
||||
val deleteHeaders = Headers.build {
|
||||
append(HttpHeaders.UserAgent, "Android")
|
||||
append(HttpHeaders.Connection, CONNECTION)
|
||||
append(HttpHeaders.AcceptEncoding, "br,gzip")
|
||||
append(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
|
||||
append(HttpHeaders.AcceptLanguage, ACCEPT_LANGUAGE)
|
||||
append("charset", CHARSET)
|
||||
}
|
||||
val data = "filelist=[\"$filePath\"]"
|
||||
|
||||
val response: HttpResponse = client.post(url) {
|
||||
parameters(params)
|
||||
headers { this@_deleteTransferFile.deleteHeaders.forEach { name, value -> append(name, value) } }
|
||||
cookies?.let { setCookie(it) }
|
||||
body = data
|
||||
timeout.socketTimeoutMillis = 10000
|
||||
}
|
||||
|
||||
val result = try {
|
||||
response.receive<Map<String, Any>>()
|
||||
/**
|
||||
* 创建保存目录
|
||||
*/
|
||||
fun createSaveDir(): Long? {
|
||||
var saveDirId: Long? = null
|
||||
// 创建保存目录
|
||||
if (cookies.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
val tempHeader = headers.toMutableMap()
|
||||
tempHeader.put("Cookie", cookies)
|
||||
return try {
|
||||
val listResp = OkHttp.string(
|
||||
"${apiHost}/api/list", mapOf(
|
||||
"dir" to "/",
|
||||
"order" to "name",
|
||||
"desc" to "0",
|
||||
"showempty" to "0",
|
||||
"web" to "1",
|
||||
"app_id" to "250528"
|
||||
), tempHeader
|
||||
)
|
||||
val json = Json.safeObject(listResp)
|
||||
|
||||
if (json["errno"].asInt != 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
val drpyDir = json["list"].asJsonArray.find { item ->
|
||||
item.asJsonObject.get("isdir").asInt == 1 && item.asJsonObject.get("server_filename").asString == saveDirName
|
||||
|
||||
}
|
||||
|
||||
if (drpyDir != null) {
|
||||
saveDirId = drpyDir.asJsonObject.get("fs_id").asLong
|
||||
return saveDirId
|
||||
}
|
||||
|
||||
val createResp = OkHttp.post(
|
||||
"${apiHost}/api/create?a=commit&bdstoken=${getBdstoken()}&clienttype=0&app_id=250528&web=1&dp-logid=73131200762376420075",
|
||||
mapOf(
|
||||
"path" to "//$saveDirName",
|
||||
"isdir" to "1",
|
||||
"block_list" to "[]",
|
||||
|
||||
),
|
||||
tempHeader
|
||||
)
|
||||
val createJson = Json.safeObject(createResp.body)
|
||||
|
||||
|
||||
|
||||
saveDirId = createJson["fs_id"].asLong
|
||||
saveDirId
|
||||
|
||||
} catch (e: Exception) {
|
||||
response.readBytes().decodeToString()
|
||||
println("创建保存目录失败: ${e.message}")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
println("删除文件响应: $result")
|
||||
println("响应状态码: ${response.status.value}")
|
||||
fun getBdstoken(): String {
|
||||
if (cache["bdstoken"] != null) {
|
||||
return cache["bdstoken"]!!
|
||||
}
|
||||
val tempHeader = headers.toMutableMap()
|
||||
tempHeader.put("Cookie", cookies)
|
||||
val userInfo = OkHttp.string(
|
||||
"${apiHost}/api/gettemplatevariable?clienttype=0&app_id=250528&web=1&fields=[\"bdstoken\",\"token\",\"uk\",\"isdocuser\",\"servertime\"]",
|
||||
mapOf(),
|
||||
tempHeader
|
||||
|
||||
)
|
||||
val json = Json.safeObject(userInfo)
|
||||
|
||||
val bdstoken: String? = json["result"]?.asJsonObject?.get("bdstoken")?.asString
|
||||
cache["bdstoken"] = bdstoken ?: ""
|
||||
return bdstoken ?: ""
|
||||
}
|
||||
|
||||
|
||||
private fun _deleteTransferFile(filePath: String) {
|
||||
try {
|
||||
val url =
|
||||
"$apiHost/api/filemanager?async=2&onnest=fail&opera=delete&bdstoken=${getBdstoken()}&newVerify=1&clienttype=0&app_id=250528&web=1&dp-logid=39292100213290200076"
|
||||
val params = mapOf(
|
||||
"filelist" to "[\"$filePath\"]"
|
||||
)
|
||||
|
||||
val headers = mutableMapOf(
|
||||
"User-Agent" to "Android",
|
||||
"Connection" to "Keep-Alive",
|
||||
"Accept-Encoding" to "br,gzip",
|
||||
"Content-Type" to "application/x-www-form-urlencoded; charset=utf-8",
|
||||
"Accept-Language" to "zh-CN,zh;q=0.8",
|
||||
"charset" to "UTF-8",
|
||||
"Cookie" to cookies,
|
||||
)
|
||||
|
||||
|
||||
val response = OkHttp.post(url, params, headers)
|
||||
|
||||
|
||||
|
||||
println("删除文件响应: ${response.body}")
|
||||
println("响应状态码: ${response.code}")
|
||||
} catch (e: Exception) {
|
||||
println("删除文件出错: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun _delayedDeleteFile(to: String) {
|
||||
try {
|
||||
println("开始延迟删除文件: $to")
|
||||
delay(2000)
|
||||
println("开始执行删除操作: $to")
|
||||
withContext(Dispatchers.IO) {
|
||||
_deleteTransferFile(to)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
println("延迟删除文件出错: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun _runDeleteInThread(to: String?) {
|
||||
try {
|
||||
println("开始延迟删除文件(线程): $to")
|
||||
Thread.sleep(2000)
|
||||
println("开始执行删除操作(线程): $to")
|
||||
|
||||
runBlocking {
|
||||
_deleteTransferFile(to!!)
|
||||
}
|
||||
|
||||
println("删除操作完成: $to")
|
||||
} catch (e: Exception) {
|
||||
println("线程中删除文件出错: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun dictToCookieStr(cookieDict: Map<String, String>?): String {
|
||||
return cookieDict?.map { "${it.key}=${it.value}" }?.joinToString("; ") ?: ""
|
||||
}*/
|
||||
|
||||
private fun unquote(encoded: String): String {
|
||||
return encoded.replace("%([0-9A-Fa-f]{2})".toRegex()) { match ->
|
||||
|
|
@ -676,17 +727,56 @@ class BaiduDrive {
|
|||
}
|
||||
|
||||
private fun sha1(input: String): String {
|
||||
val bytes = MessageDigest.getInstance("SHA-1").digest(input.toByteArray())
|
||||
return Util.base64Encode(bytes)
|
||||
|
||||
return Util.sha1Hex(input)
|
||||
}
|
||||
|
||||
private val _handleError = mapOf(
|
||||
"parse" to 1, "msg" to "Error retrieving video URL"
|
||||
"parse" to "1", "msg" to "Error retrieving video URL"
|
||||
)
|
||||
|
||||
private fun threadUrl(url: String, threads: Int): String {
|
||||
// Implement the logic for threading URL processing here
|
||||
return url
|
||||
|
||||
fun getVod(shareUrl: String): Vod {
|
||||
val (froms, urls) = processShareLinks(listOf(shareUrl))
|
||||
val builder = VodPlayBuilder()
|
||||
for (i in froms.indices) {
|
||||
val playUrls = mutableListOf<VodPlayBuilder.PlayUrl>();
|
||||
for (url in urls[i].split("#")) {
|
||||
val arr = url.split("$")
|
||||
val play = VodPlayBuilder.PlayUrl()
|
||||
play.name = arr[0]
|
||||
play.url = arr[1]
|
||||
|
||||
playUrls.add(play)
|
||||
|
||||
}
|
||||
builder.append(froms[i], playUrls)
|
||||
}
|
||||
val buildResult = builder.build();
|
||||
|
||||
val vod = Vod()
|
||||
vod.setVodId(shareUrl)
|
||||
vod.setVodPic("")
|
||||
vod.setVodYear("")
|
||||
vod.setVodName("")
|
||||
vod.setVodContent("")
|
||||
vod.setVodPlayFrom(buildResult.vodPlayFrom)
|
||||
vod.setVodPlayUrl(buildResult.vodPlayUrl)
|
||||
return vod
|
||||
}
|
||||
|
||||
fun playerContent(json: JsonObject, flag: String): String {
|
||||
val play = getVideoUrl(json, flag);
|
||||
val header = play["header"] as Map<String, String>
|
||||
return Result.get().url(buildProxyUrl(play["url"] as String, header) ).octet().header(header).string();
|
||||
}
|
||||
|
||||
fun getPlayFormatList(): Array<String> {
|
||||
return listOf("1080P").toTypedArray()
|
||||
}
|
||||
|
||||
fun proxyVideo(params: MutableMap<String, String>): Array<Any> {
|
||||
return emptyList<Any>().toTypedArray()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
package com.github.catvod.bean.BD;
|
||||
|
||||
|
||||
import com.github.catvod.api.BaiDuYunHandler;
|
||||
import com.github.catvod.api.YunTokenHandler;
|
||||
import com.github.catvod.bean.yun.User;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Cache {
|
||||
|
||||
@SerializedName("user")
|
||||
private User user;
|
||||
|
||||
|
||||
public static Cache objectFrom(String str) {
|
||||
Cache item = new Gson().fromJson(str, Cache.class);
|
||||
return item == null ? new Cache() : item;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user == null ? new User("") : user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
this.save();
|
||||
}
|
||||
|
||||
|
||||
public void save() {
|
||||
Init.execute(() -> Path.write(BaiDuYunHandler.get().getCache(), toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package com.github.catvod.spider
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import com.github.catvod.api.BaiduDrive
|
||||
import com.github.catvod.api.BaiduDrive.getPlayFormatList
|
||||
import com.github.catvod.api.BaiduDrive.getVod
|
||||
import com.github.catvod.api.BaiduDrive.playerContent
|
||||
import com.github.catvod.api.BaiduDrive.setCookie
|
||||
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.utils.Json
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author ColaMint & Adam & FongMi
|
||||
*/
|
||||
class BaiDuPan : Spider() {
|
||||
@Throws(Exception::class)
|
||||
override fun init(context: Context?, extend: String) {
|
||||
setCookie(extend)
|
||||
}
|
||||
|
||||
/**
|
||||
* ids 為 share_link
|
||||
* @param ids
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
override fun detailContent(ids: MutableList<String>): String? {
|
||||
var vod: Vod? = null;
|
||||
runBlocking {
|
||||
vod = getVod(ids[0])
|
||||
}
|
||||
return Result.string(vod);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun playerContent(flag: String, id: String, vipFlags: MutableList<String?>?): String {
|
||||
var content = ""
|
||||
runBlocking {
|
||||
content = playerContent(Json.safeObject(com.github.catvod.utils.Util.base64Decode(id)), flag)
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取詳情內容視頻播放來源(多 shared_link)
|
||||
*
|
||||
* @param ids share_link 集合
|
||||
* @param i
|
||||
* @return 詳情內容視頻播放來源
|
||||
*/
|
||||
fun detailContentVodPlayFrom(ids: MutableList<String?>, index: Int): String? {
|
||||
val playFrom: MutableList<String?> = ArrayList<String?>()
|
||||
|
||||
/* if (ids.size() < 2){
|
||||
return TextUtils.join("$$$", BaiduDrive.get().getPlayFormatList());
|
||||
}*/
|
||||
for (i in 1..ids.size) {
|
||||
playFrom.add("BD原画" + i + index)
|
||||
/* for (s in getPlayFormatList()) {
|
||||
playFrom.add(String.format(Locale.getDefault(), "BD" + s + "#%02d%02d", i, index))
|
||||
}*/
|
||||
}
|
||||
return TextUtils.join("$$$", playFrom)
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取詳情內容視頻播放地址(多 share_link)
|
||||
*
|
||||
* @param ids share_link 集合
|
||||
* @return 詳情內容視頻播放地址
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
fun detailContentVodPlayUrl(ids: List<String>): String? {
|
||||
val playUrl: MutableList<String?> = ArrayList<String?>()
|
||||
for (id in ids) {
|
||||
try {
|
||||
playUrl.add(getVod(id).getVodPlayUrl())
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("获取播放地址出错:" + e.message)
|
||||
}
|
||||
}
|
||||
return TextUtils.join("$$$", playUrl)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
var URL_START = "https://pan.baidu.com"
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun proxy(params: MutableMap<String, String>): Array<Any> {
|
||||
val type = params["type"]
|
||||
if ("video" == type) return BaiduDrive.proxyVideo(params)
|
||||
//if ("sub".equals(type)) return AliYun.get().proxySub(params);
|
||||
return arrayOf<Any>()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ public class Cloud extends Spider {
|
|||
private UC uc = null;*/
|
||||
private TianYi tianYi = null;
|
||||
private YiDongYun yiDongYun = null;
|
||||
private BaiDuPan baiDuPan = null;
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
|
|
@ -32,12 +33,14 @@ public class Cloud extends Spider {
|
|||
ali = new Ali();*/
|
||||
tianYi = new TianYi();
|
||||
yiDongYun = new YiDongYun();
|
||||
baiDuPan = new BaiDuPan();
|
||||
boolean first = Objects.nonNull(ext);
|
||||
quark.init(context, first && ext.has("cookie") ? ext.get("cookie").getAsString() : "");
|
||||
/* uc.init(context, first && ext.has("uccookie") ? ext.get("uccookie").getAsString() : "");
|
||||
ali.init(context, first && ext.has("token") ? ext.get("token").getAsString() : "");*/
|
||||
tianYi.init(context, first && ext.has("tianyicookie") ? ext.get("tianyicookie").getAsString() : "");
|
||||
yiDongYun.init(context, "");
|
||||
baiDuPan.init(context, "");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +56,8 @@ public class Cloud extends Spider {
|
|||
return tianYi.detailContent(shareUrl);
|
||||
} else if (shareUrl.get(0).contains(YiDongYun.URL_START)) {
|
||||
return yiDongYun.detailContent(shareUrl);
|
||||
}else if (shareUrl.get(0).contains(BaiDuPan.URL_START)) {
|
||||
return baiDuPan.detailContent(shareUrl);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -70,6 +75,10 @@ public class Cloud extends Spider {
|
|||
}/* else {
|
||||
return ali.playerContent(flag, id, vipFlags);
|
||||
}*/
|
||||
|
||||
else if (flag.contains("BD")) {
|
||||
return baiDuPan.playerContent(flag, id, vipFlags);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +98,9 @@ public class Cloud extends Spider {
|
|||
} else if (shareLink.contains(YiDongYun.URL_START)) {
|
||||
from.add(yiDongYun.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
}
|
||||
else if (shareLink.contains(BaiDuPan.URL_START)) {
|
||||
from.add(baiDuPan.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
}
|
||||
}
|
||||
|
||||
return TextUtils.join("$$$", from);
|
||||
|
|
@ -107,6 +119,8 @@ public class Cloud extends Spider {
|
|||
urls.add(tianYi.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
} else if (shareLink.contains(YiDongYun.URL_START)) {
|
||||
urls.add(yiDongYun.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
}else if (shareLink.contains(BaiDuPan.URL_START)) {
|
||||
urls.add(baiDuPan.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
}
|
||||
}
|
||||
return TextUtils.join("$$$", urls);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,257 @@
|
|||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.net.OkResult;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TgSearchBaidu extends Cloud {
|
||||
private static final String KEY_API_URLS = "api_urls";
|
||||
private static final String KEY_DOMAIN_MAP = "siteurl";
|
||||
private static final String KEY_SOURCES = "sources";
|
||||
private static final int DEFAULT_PAGE_SIZE = 10;
|
||||
|
||||
private List<String> apiUrls = new ArrayList<>();
|
||||
private Map<String, String> domainMap = new HashMap<String, String>() {{
|
||||
put("alipan", "阿里");
|
||||
put("aliyundrive", "阿里");
|
||||
put("quark", "夸克");
|
||||
put("115cdn", "115");
|
||||
put("baidu.com", "百度");
|
||||
put("uc", "UC");
|
||||
put("189.cn", "天翼");
|
||||
put("139.com", "移动");
|
||||
put("123", "123盘");
|
||||
}};
|
||||
private Set<String> sources = new HashSet<>();
|
||||
private String[] extInfos = null;
|
||||
|
||||
@Override
|
||||
public synchronized void init(Context context, String extend) throws Exception {
|
||||
super.init(context, extend);
|
||||
|
||||
this.apiUrls.clear();
|
||||
|
||||
if (!TextUtils.isEmpty(extend)) {
|
||||
try {
|
||||
if (extend.contains("###")) {
|
||||
String[] infos = extend.split("###");
|
||||
this.extInfos = infos;
|
||||
|
||||
if (infos.length > 0 && !TextUtils.isEmpty(infos[0])) {
|
||||
processExtendConfig(infos[0]);
|
||||
}
|
||||
} else {
|
||||
this.extInfos = new String[]{extend};
|
||||
processExtendConfig(extend);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
this.extInfos = null; // 重置,避免内存泄漏
|
||||
}
|
||||
|
||||
private void processExtendConfig(String config) {
|
||||
try {
|
||||
// 检查是否为HTTP URL
|
||||
if (isValidUrl(config)) {
|
||||
if (!this.apiUrls.contains(config)) {
|
||||
this.apiUrls.add(config);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 尝试JSON格式解析
|
||||
JsonObject ext = Json.safeObject(config);
|
||||
|
||||
// 处理API URLs配置
|
||||
processApiUrls(ext);
|
||||
|
||||
// 处理域名映射配置
|
||||
processDomainMap(ext);
|
||||
|
||||
// 处理来源过滤配置
|
||||
processSources(ext, true);
|
||||
} catch (Exception e) {
|
||||
// 可以添加日志记录
|
||||
}
|
||||
}
|
||||
|
||||
private void processApiUrls(JsonObject config) {
|
||||
if (config.has(KEY_API_URLS) && config.get(KEY_API_URLS).isJsonArray()) {
|
||||
JsonArray urlsArray = config.getAsJsonArray(KEY_API_URLS);
|
||||
for (JsonElement element : urlsArray) {
|
||||
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||
String url = element.getAsString();
|
||||
if (isValidUrl(url) && !this.apiUrls.contains(url)) {
|
||||
this.apiUrls.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processDomainMap(JsonObject config) {
|
||||
if (config.has(KEY_DOMAIN_MAP) && config.get(KEY_DOMAIN_MAP).isJsonObject()) {
|
||||
JsonObject customDomains = config.getAsJsonObject(KEY_DOMAIN_MAP);
|
||||
for (Map.Entry<String, JsonElement> entry : customDomains.entrySet()) {
|
||||
if (entry == null || entry.getValue() == null) continue;
|
||||
|
||||
String domain = entry.getKey();
|
||||
String sourceName = "";
|
||||
try { sourceName = entry.getValue().getAsString(); } catch (Exception e) { continue; }
|
||||
|
||||
if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(sourceName) && !domainMap.containsKey(domain)) {
|
||||
domainMap.put(domain, sourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processSources(JsonObject config, boolean clearExisting) {
|
||||
if (config.has(KEY_SOURCES) && config.get(KEY_SOURCES).isJsonArray()) {
|
||||
if (clearExisting) {
|
||||
this.sources.clear();
|
||||
}
|
||||
|
||||
JsonArray sourcesArray = config.getAsJsonArray(KEY_SOURCES);
|
||||
for (JsonElement element : sourcesArray) {
|
||||
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||
String source = element.getAsString();
|
||||
if (!TextUtils.isEmpty(source) && !sources.contains(source)) {
|
||||
sources.add(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidUrl(String url) {
|
||||
return !TextUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
if (key == null || key.trim().isEmpty()) {
|
||||
return Result.error("关键词不能为空");
|
||||
}
|
||||
|
||||
return performSearch(key, 1, DEFAULT_PAGE_SIZE);
|
||||
}
|
||||
|
||||
private String performSearch(String key, int page, int pageSize) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
int total = 0;
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("kw", key);
|
||||
params.put("page", String.valueOf(page));
|
||||
params.put("size", String.valueOf(pageSize));
|
||||
|
||||
for (String apiUrl : apiUrls) {
|
||||
if (!isValidUrl(apiUrl)) continue;
|
||||
|
||||
try {
|
||||
OkResult result = OkHttp.get(apiUrl, params, getHeader());
|
||||
if (result.getCode() == 500 || TextUtils.isEmpty(result.getBody())) continue;
|
||||
|
||||
JsonObject jsonObject = Json.safeObject(result.getBody());
|
||||
if (!jsonObject.has("code") || jsonObject.get("code").getAsInt() != 0 || !jsonObject.has("data")) continue;
|
||||
|
||||
JsonObject data = jsonObject.getAsJsonObject("data");
|
||||
|
||||
total = data.has("total") && !data.get("total").isJsonNull() ? data.get("total").getAsInt() : 0;
|
||||
|
||||
// 直接检查merged_by_type字段,无需三重判断
|
||||
if (!data.has("merged_by_type") || !data.get("merged_by_type").isJsonObject()) continue;
|
||||
|
||||
JsonObject mergedByType = data.getAsJsonObject("merged_by_type");
|
||||
|
||||
for (Map.Entry<String, JsonElement> categoryEntry : mergedByType.entrySet()) {
|
||||
if (!categoryEntry.getValue().isJsonArray()) continue;
|
||||
|
||||
JsonArray items = categoryEntry.getValue().getAsJsonArray();
|
||||
|
||||
for (JsonElement item : items) {
|
||||
if (!item.isJsonObject()) continue;
|
||||
|
||||
JsonObject entry = item.getAsJsonObject();
|
||||
|
||||
String vodUrl = entry.has("url") && !entry.get("url").isJsonNull() ? entry.get("url").getAsString() : "";
|
||||
if (TextUtils.isEmpty(vodUrl)) continue;
|
||||
|
||||
// 获取来源信息并映射
|
||||
String originalSource = entry.has("source") && !entry.get("source").isJsonNull() ? entry.get("source").getAsString() : "未知来源";
|
||||
String sourceName = mapSource(vodUrl, originalSource);
|
||||
|
||||
// 获取标题
|
||||
String title = entry.has("note") && !entry.get("note").isJsonNull() ? entry.get("note").getAsString() : "未命名资源";
|
||||
|
||||
// 获取图片
|
||||
String pic = getFirstImage(entry);
|
||||
|
||||
// 简化VodPlayBuilder的使用
|
||||
Vod vod = new Vod("push://" + vodUrl, title, pic, sourceName + " (" + originalSource + ")");
|
||||
// 由于只有一个播放源,直接设置播放信息
|
||||
vod.setVodPlayFrom(sourceName);
|
||||
vod.setVodPlayUrl("播放源$" + vodUrl);
|
||||
|
||||
// 来源过滤
|
||||
if (sources.isEmpty() || sources.contains(sourceName)) {
|
||||
list.add(vod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pageCount = total > 0 && pageSize > 0 ? (total + pageSize - 1) / pageSize : 1;
|
||||
return Result.string(page, pageCount, pageSize, total, list);
|
||||
} catch (Exception e) {
|
||||
// 出错时继续尝试下一个API
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.error("无法连接到任何搜索API");
|
||||
}
|
||||
|
||||
// 提取来源映射逻辑为单独方法
|
||||
private String mapSource(String vodUrl, String originalSource) {
|
||||
for (Map.Entry<String, String> domainEntry : domainMap.entrySet()) {
|
||||
if (vodUrl.contains(domainEntry.getKey())) {
|
||||
return domainEntry.getValue();
|
||||
}
|
||||
}
|
||||
return originalSource;
|
||||
}
|
||||
|
||||
// 提取图片获取逻辑为单独方法
|
||||
private String getFirstImage(JsonObject entry) {
|
||||
if (entry.has("images") && !entry.get("images").isJsonNull() && entry.get("images").isJsonArray()) {
|
||||
JsonArray images = entry.getAsJsonArray("images");
|
||||
if (images.size() > 0 && !images.get(0).isJsonNull() && images.get(0).isJsonPrimitive()) {
|
||||
return images.get(0).getAsString();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -120,6 +120,8 @@ public class YunPanBa extends Cloud {
|
|||
shareLinks.add(element.attr("href").trim());
|
||||
} else if (element.attr("href").matches(Util.patternAli)) {
|
||||
shareLinks.add(element.attr("href").trim());
|
||||
} else if (element.attr("href").startsWith(BaiDuPan.URL_START)) {
|
||||
shareLinks.add(element.attr("href").trim());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
import android.app.Application;
|
||||
import com.github.catvod.spider.BaiDuPan;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.junit.Assert;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BaiDuPanTest {
|
||||
|
||||
private Application mockContext;
|
||||
|
||||
private BaiDuPan spider;
|
||||
|
||||
@org.junit.Before
|
||||
public void setUp() throws Exception {
|
||||
mockContext = RuntimeEnvironment.application;
|
||||
Init.init(mockContext);
|
||||
spider = new BaiDuPan();
|
||||
// spider.init(mockContext, "b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; _UP_A4A_11_=wb9661c6dfb642f88f73d8e0c7edd398; b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; ctoken=wla6p3EUOLyn1FSB8IKp1SEW; grey-id=5583e32b-39df-4bf0-f39f-1adf83f604a2; grey-id.sig=p8ReBIMG2BeZu1sYvsuOAZxYbx-MVrsfKEiCv87MsTM; isQuark=true; isQuark.sig=hUgqObykqFom5Y09bll94T1sS9abT1X-4Df_lzgl8nM; _UP_F7E_8D_=ZkyvVHnrBLp1A1NFJIjWi0PwKLOVbxJPcg0RzQPI6KmBtV6ZMgPh38l93pgubgHDQqhaZ2Sfc0qv%2BRantbfg1mWGAUpRMP4RqXP78Wvu%2FCfvkWWGc5NhCTV71tGOIGgDBR3%2Bu6%2Fjj44KlE5biSNDOWW7Bigcz27lvOTidzNw8s%2FWtKAIxWbnCzZn4%2FJMBUub1SIMcW89g57k4mfPmDlCgpZKzxwl6beSfdtZ4RUWXmZOn5v5NkxVKhU4wR0Pq7NklczEGdRq2nIAcu7v22Uw2o%2FxMY0xBdeC9Korm5%2FNHnxl6K%2Bd6FXSoT9a3XIMQO359auZPiZWzrNlZe%2BqnOahXcx7KAhQIRqSOapSmL4ygJor4r5isJhRuDoXy7vJAVuH%2FRDtEJJ8rZTq0BdC23Bz%2B0MrsdgbK%2BiW; _UP_D_=pc; __wpkreporterwid_=3d3f74a7-99b7-4916-3f78-911fc2eb9d87; tfstk=fIoZNxjnbhKwPOu0TWZ4LsaRqirTcudSSmNbnxD0C5VgClMm8xMyB-GsnSu4tjpOflAOmSD-9PNiGl120XrgkVNb1SrqHbJBN3tSBAEYoQOWVUUg9qZ8n1bGGkD3CqGYINKSBABhjnXgp3_Vywz6gSc0Syj3BWf0mr2DLW24eZfiiovEKWefj1q0swq3E82iNEMinMy7SLrcpA4Fh3z_ZAViCfih3PbtdW5N_DuU77AaTijmYRkL2Wq54ENoy5a7ZXxCbok33XzS7QSZgxD-oyoVsdGotql0p2dVu7umC4nLStbiLmParc4FELHrI-c0u2dPVRrs8zoZWKCnIbNZrlHfUCMUz2z8KyXVSlgSFmUojh58OzeqTzgwaGll4YCYKwctDV5coP2LL79eKHxpNTXHmre1kZU32JPWCR_AkP2LL79eLZQY-WeUNdw1.; __pus=2051c82285199d8be553be41dd5a2100AAQ+mmv35G4FDDZ5x+3Mhe2OMbNgweQ1ODbW8zDt9YuP1LQVqHUuAAz9KWLsPjpNtim0AVGHusN4MCosTmbq/khM; __kp=e6604120-6051-11ef-bfe4-c31b6cdd0766; __kps=AATcZArVgS76EPn0FMaV4HEj; __ktd=sii/iz4ePzEaoVirXul7QQ==; __uid=AATcZArVgS76EPn0FMaV4HEj; __itrace_wid=5829b95d-dac1-48d3-bfd5-f60cd9462786; __puus=7da0b96cb710fa1b376934485f977e05AATp/q8/QupT7IiBR1GWqZhxlIRT677smMvoHlLxQA0Lk6CkP0YJBOTl+p9DZgzlMz6w4hPXPgWsokukk8PW7ZfhFfPmv8tKMgLpCGLW+tk57luhNghmSdTeVPkAF59STtyCPBEtiNzNAd/zZJ6qILJDi5ywEBAAAg+gOyWHoLHNUR+QxeHRuQa8g5WWA95J8jebIlrr8rCvI1vjTbtiYktT");
|
||||
spider.init(mockContext, "BIDUPSID=D122360716A06862B6689D4FE32053A1; PSTM=1756869077; MAWEBCUID=web_KAGxElHEQyrFImqrzARlkIssFfvhfCLGaXDsxmWKbhxsfEsvhs; PANWEB=1; H_WISE_SIDS_BFESS=110085_656765_660924_665265_666660_667682_662823_668348_668761_668756_669314_667565_669628_669693_669848_669685_669681_670119_670114_670116_670307_669051_670308_670357_670598_669700_670824_669791_669664_670557_667838_669418_663788; MCITY=-276%3A; csrfToken=6tn2uwGoOUgn87ZBElHEGjCD; newlogin=1; XFI=627d86b0-a655-11f0-b1eb-0f9d37032cfb; XFCS=B8C411ADE99EE9C3B29FDF31558D538BB636F205DF4F52FE2E57F1312E01079F; XFT=yvSTf+EcMsgYHnGyS774OLqljjYcjil0ZkCgy1g0Aso=; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1760154644; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; Hm_lvt_fa0277816200010a74ab7d2895df481b=1760339732; Hm_lpvt_fa0277816200010a74ab7d2895df481b=1760344537; BAIDUID=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; H_PS_PSSID=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BAIDUID_BFESS=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; delPer=0; PSINO=5; H_WISE_SIDS=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BA_HECTOR=ak24050g8ha5ah018l0g2g802ke50i1ker7km25; ZFY=LJHc036:AkCyc1OPqFkXugSCgXnfaMIH:AjDQUOfkXtP4:C; BDCLND=vGxYxxMPQqznqvbjTPyD6CQEOejzkIZgEuuv9D5ctzM%3D; ndut_fmt=C6428C500AB0E62AC4B1CBB9671EF7803530C20D2457081012790E5079FD5D8E; ab_sr=1.0.1_MjFjNTFiYTgwYzAxOWFlOWJmYTRmYjUwYmQwNmJkYTg4NTkxYzA4YTk1YTU0MWIxMDQ1YjgzN2QzZGU4Y2MxMzRlNGQ4M2YxNjJmNzliNWFkMjg0N2U4ZWUzOGRiMzljNzM0MmJmMjc2YzQwYmJhYzdmMWU2NThkYmQ4MjRlODRlZDA0Mjc2ZWE3YmQxNGZiZGE3Yzk1MDU1Njk3NmVlOQ==; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGmVXQmqM6seEAgB/LlOs0+zGEimjy3MrXEpSuItnI4KDwxAMUTOS16BfoXMcd2lpC/ZmOvCi7lsE0/UM0w4HSMVhh7EfifsXEYHtGj52zkQan6UDL686lBL6BHUyL9m3lfGgLbz7OSojK1zRbqBESR5Pdk2R9IA3lxxOVzA+Iw1TWLSgWjlFVG9Xmh1+20oPSbrzvDjYtVPmZ+9/6evcXmhcO1Y58MgLozKnaQIaLfWRFwa8A3ZyTRp/cDxRMhYc97xUSUZS0ReZYJMPG6nCsxNJlhI2UyeJA6QroZFMelR7tnTNS/pLMWceus0e757/UMPmrThfasmhDJrMFcBfoSrAAv3LCf1Y7/fHL3PTSf9vid/u2VLX4h1nBtx8EF07eCMhWVv+2qjbPV7ZhXk3reaWRFEeso3s/Kc9n/UXtUfNU1sHiCdbrCW5yYsuSM9SPGDZsl7FhTAKw7qIu38vFZiq+DRc8Vbf7jOiN9xPe0lOdZHUhGHZ82rL5jTCsILwcRVCndrarbwmu7G154MpYiKmTXZkqV7Alo4QZzicdyMbWvwvmR2/m//YVTM8qeZWgDSHjDmtehgLWM45zARbPujeqU0T92Gmgs89l2htrSKITeYE0TpfIvjPXsgyQghyP8U3sViHT1z07gbfu1XO5QQ/upk1AkHGkWrkbMWm+rpwpdImdyxYIjA1uSy2hfTFv/d3cnXH4nh+maaicAPllDgrppZTr0lDf2Vsiy73L8egP9ck5gsaaSE4obz9V1JGvyp8lNw+IyCN2Gou0efGgcYWqtuH+3KMtXW4uAv+XUaBDreXqEwrDxmyUrecavkqQ9rGRChHnhPuJeIKACPXiVuli9ItRLEkdb1mLxNHAk3uJy88YX/Rf/sKUjR12zxRTDxxJNDJS+Dlsbqu3n4I65ujli/3rQ8Zk1MjmTOsz9+kTqOM4upsnQ6IWq/zeZTItMCgHpQhuhr4ip73honuzoJgge1cqWBFYvpabAPTOERTOP1kmx5SXPARX5uxyJzAiNILBC8zh7fGfNXOWV37O9gEbYklWGnWpu55tg8Y8GaT7BFVDtu1KaJzjx51nTN1+xVI8c7otOFm3py1Y+wrt2CfI5v5JSd2kRNZE7s6bQrA5yMI31SfUDgxDrsd6lPtUU=; BDUSS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; BDUSS_BFESS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; STOKEN=7970ecc47cebf55b8bbd63fee5e5e4b612753bceae56d51073b1b69bab616df6; PANPSC=17920541514426231310%3Au9Rut0jYI4omsQqGlPk7plcS2d9ns3O5C61tf8CKQkigT9ngiMB1eA3MPJHnDhkC6WRWG5ljYM%2BmSRyxE8aegpNZSd%2B1SXYsBm6rqQ5QdYLMOw0WWU7tUSqLe%2F%2Bg%2FDWP4i2i1JdCg%2BQ3uGXWluwqDsVi7NXtJ9t339k3FioH%2FAqA1gqZJvix0rmqJrAOClKcX0r3JWTW68Ah7IX89yGaj0Eyueu6wBwEDZC8PXQ9dy48%2FX4Y2hjenzCvC2qz1EInzo%2F1llKJ4P7gQiGlDEks0p8M%2Flyi7z69BCKhGHn%2Fawh9ff8YI35KVRVksnPVbyr%2FTaFwbj9JM%2FCSsVZaqyA8TA%3D%3D; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1760406982");
|
||||
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void init() throws Exception {
|
||||
spider.init(mockContext, "BIDUPSID=D122360716A06862B6689D4FE32053A1; PSTM=1756869077; MAWEBCUID=web_KAGxElHEQyrFImqrzARlkIssFfvhfCLGaXDsxmWKbhxsfEsvhs; PANWEB=1; H_WISE_SIDS_BFESS=110085_656765_660924_665265_666660_667682_662823_668348_668761_668756_669314_667565_669628_669693_669848_669685_669681_670119_670114_670116_670307_669051_670308_670357_670598_669700_670824_669791_669664_670557_667838_669418_663788; MCITY=-276%3A; csrfToken=6tn2uwGoOUgn87ZBElHEGjCD; newlogin=1; XFI=627d86b0-a655-11f0-b1eb-0f9d37032cfb; XFCS=B8C411ADE99EE9C3B29FDF31558D538BB636F205DF4F52FE2E57F1312E01079F; XFT=yvSTf+EcMsgYHnGyS774OLqljjYcjil0ZkCgy1g0Aso=; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1760154644; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; Hm_lvt_fa0277816200010a74ab7d2895df481b=1760339732; Hm_lpvt_fa0277816200010a74ab7d2895df481b=1760344537; BAIDUID=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; H_PS_PSSID=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BAIDUID_BFESS=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; delPer=0; PSINO=5; H_WISE_SIDS=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BA_HECTOR=ak24050g8ha5ah018l0g2g802ke50i1ker7km25; ZFY=LJHc036:AkCyc1OPqFkXugSCgXnfaMIH:AjDQUOfkXtP4:C; BDCLND=vGxYxxMPQqznqvbjTPyD6CQEOejzkIZgEuuv9D5ctzM%3D; ndut_fmt=C6428C500AB0E62AC4B1CBB9671EF7803530C20D2457081012790E5079FD5D8E; ab_sr=1.0.1_MjFjNTFiYTgwYzAxOWFlOWJmYTRmYjUwYmQwNmJkYTg4NTkxYzA4YTk1YTU0MWIxMDQ1YjgzN2QzZGU4Y2MxMzRlNGQ4M2YxNjJmNzliNWFkMjg0N2U4ZWUzOGRiMzljNzM0MmJmMjc2YzQwYmJhYzdmMWU2NThkYmQ4MjRlODRlZDA0Mjc2ZWE3YmQxNGZiZGE3Yzk1MDU1Njk3NmVlOQ==; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGmVXQmqM6seEAgB/LlOs0+zGEimjy3MrXEpSuItnI4KDwxAMUTOS16BfoXMcd2lpC/ZmOvCi7lsE0/UM0w4HSMVhh7EfifsXEYHtGj52zkQan6UDL686lBL6BHUyL9m3lfGgLbz7OSojK1zRbqBESR5Pdk2R9IA3lxxOVzA+Iw1TWLSgWjlFVG9Xmh1+20oPSbrzvDjYtVPmZ+9/6evcXmhcO1Y58MgLozKnaQIaLfWRFwa8A3ZyTRp/cDxRMhYc97xUSUZS0ReZYJMPG6nCsxNJlhI2UyeJA6QroZFMelR7tnTNS/pLMWceus0e757/UMPmrThfasmhDJrMFcBfoSrAAv3LCf1Y7/fHL3PTSf9vid/u2VLX4h1nBtx8EF07eCMhWVv+2qjbPV7ZhXk3reaWRFEeso3s/Kc9n/UXtUfNU1sHiCdbrCW5yYsuSM9SPGDZsl7FhTAKw7qIu38vFZiq+DRc8Vbf7jOiN9xPe0lOdZHUhGHZ82rL5jTCsILwcRVCndrarbwmu7G154MpYiKmTXZkqV7Alo4QZzicdyMbWvwvmR2/m//YVTM8qeZWgDSHjDmtehgLWM45zARbPujeqU0T92Gmgs89l2htrSKITeYE0TpfIvjPXsgyQghyP8U3sViHT1z07gbfu1XO5QQ/upk1AkHGkWrkbMWm+rpwpdImdyxYIjA1uSy2hfTFv/d3cnXH4nh+maaicAPllDgrppZTr0lDf2Vsiy73L8egP9ck5gsaaSE4obz9V1JGvyp8lNw+IyCN2Gou0efGgcYWqtuH+3KMtXW4uAv+XUaBDreXqEwrDxmyUrecavkqQ9rGRChHnhPuJeIKACPXiVuli9ItRLEkdb1mLxNHAk3uJy88YX/Rf/sKUjR12zxRTDxxJNDJS+Dlsbqu3n4I65ujli/3rQ8Zk1MjmTOsz9+kTqOM4upsnQ6IWq/zeZTItMCgHpQhuhr4ip73honuzoJgge1cqWBFYvpabAPTOERTOP1kmx5SXPARX5uxyJzAiNILBC8zh7fGfNXOWV37O9gEbYklWGnWpu55tg8Y8GaT7BFVDtu1KaJzjx51nTN1+xVI8c7otOFm3py1Y+wrt2CfI5v5JSd2kRNZE7s6bQrA5yMI31SfUDgxDrsd6lPtUU=; BDUSS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; BDUSS_BFESS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; STOKEN=7970ecc47cebf55b8bbd63fee5e5e4b612753bceae56d51073b1b69bab616df6; PANPSC=17920541514426231310%3Au9Rut0jYI4omsQqGlPk7plcS2d9ns3O5C61tf8CKQkigT9ngiMB1eA3MPJHnDhkC6WRWG5ljYM%2BmSRyxE8aegpNZSd%2B1SXYsBm6rqQ5QdYLMOw0WWU7tUSqLe%2F%2Bg%2FDWP4i2i1JdCg%2BQ3uGXWluwqDsVi7NXtJ9t339k3FioH%2FAqA1gqZJvix0rmqJrAOClKcX0r3JWTW68Ah7IX89yGaj0Eyueu6wBwEDZC8PXQ9dy48%2FX4Y2hjenzCvC2qz1EInzo%2F1llKJ4P7gQiGlDEks0p8M%2Flyi7z69BCKhGHn%2Fawh9ff8YI35KVRVksnPVbyr%2FTaFwbj9JM%2FCSsVZaqyA8TA%3D%3D; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1760406982");
|
||||
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void detailContent() throws Exception {
|
||||
|
||||
String content = spider.detailContent(Arrays.asList("https://pan.baidu.com/s/1Ov0S6S7rqnyW_S3AondhmQ?pwd=8888"));
|
||||
System.out.println("detailContent--" + content);
|
||||
JsonObject map = Json.safeObject(content);
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
System.out.println("detailContent--" + gson.toJson(map));
|
||||
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void playerContent() throws Exception {
|
||||
|
||||
String content = spider.playerContent("BD原画", "eyJ1ayI6IjExMDMyNzkxMjIzNDEiLCJzaGFyZWlkIjoiMjk1NzE4ODcyOTgiLCJmaWQiOjMxOTM5NTUxMTQyOTU4MCwicmFuZHNrIjoidkd4WXh4TVBRcXpucXZialRQeUQ2Q1FFT2VqemtJWmdFdXV2OUQ1Y3R6TSUzRCIsInBuYW1lIjoiRHJhZ29uIEJhbGwgREFJTUEuUzAxRTAxLjIwMjQuMTA4MHAuQ1IuV0VCLURMLngyNjQuQUFDLm1rdiIsInF0eXBlIjoib3JpZ2luYWwifQ==", new ArrayList<>());
|
||||
// String content = spider.playerContent("BD转码", "eyJ1ayI6IjExMDMyNzkxMjIzNDEiLCJmaWQiOjMxOTE2ODY2NDUxMzY1Nywic2hhcmVpZCI6IjI5NTcxODg3Mjk4Iiwic3VybCI6IjFPdjBTNlM3cnFueVdfUzNBb25kaG1RIiwicG5hbWUiOiJEcmFnb24gQmFsbCBEQUlNQS5TMDFFMjAuMjAyNC4xMDgwcC5DUi5XRUItREwueDI2NC5BQUMubWt2IiwicXR5cGUiOiJwcmV2aWV3In0=", new ArrayList<>());
|
||||
System.out.println("playerContent--" + content);
|
||||
JsonObject map = Json.safeObject(content);
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
System.out.println("playerContent--" + gson.toJson(map));
|
||||
Assert.assertFalse(map.getAsJsonPrimitive("url").getAsString().isEmpty());
|
||||
while (true) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,26 +2,20 @@ package com.github.catvod.api
|
|||
|
||||
import com.github.catvod.utils.Json
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class BaiduDriveTest {
|
||||
var yunDrive: BaiduDrive? = null
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
yunDrive = BaiduDrive()
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun getShareList() {
|
||||
|
||||
runBlocking {
|
||||
val reslut = yunDrive?.processShareLinks(listOf("https://pan.baidu.com/s/1f0y60RkYcSsp4EwWolKgJg?pwd=c26q"))
|
||||
val reslut =
|
||||
BaiduDrive.processShareLinks(listOf("https://pan.baidu.com/s/1Ov0S6S7rqnyW_S3AondhmQ?pwd=8888"))
|
||||
System.out.println(Json.toJson(reslut))
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +24,7 @@ class BaiduDriveTest {
|
|||
fun getBdUid() {
|
||||
|
||||
runBlocking {
|
||||
val reslut = yunDrive?.getBdUid()
|
||||
val reslut = BaiduDrive.getBdUid()
|
||||
System.out.println(reslut)
|
||||
}
|
||||
}
|
||||
|
|
@ -41,24 +35,44 @@ class BaiduDriveTest {
|
|||
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
|
||||
val obj = Json.safeObject(jsonStr)
|
||||
runBlocking {
|
||||
val reslut = yunDrive?._getSign(obj)
|
||||
val reslut = BaiduDrive._getSign(obj)
|
||||
System.out.println(reslut)
|
||||
}
|
||||
}@Test
|
||||
fun getVideoUrl() {
|
||||
/* val jsonStr =
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getVideoUrl() {/* val jsonStr =
|
||||
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
|
||||
val obj = Json.safeObject(jsonStr)
|
||||
runBlocking {
|
||||
val reslut = yunDrive?.getVideoUrl(obj)
|
||||
System.out.println(reslut)
|
||||
}*/ val jsonStr =
|
||||
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJzaGFyZWlkIjoiNTM0NzQwNjk3MjQiLCJmaWQiOjgzNDA3NTIyODU4MjM4NywicmFuZHNrIjoibkdOVnlCdTlNS3BXSDd6bFRzNW9VeEZkUlFYdmFpMzAwR25GazlNR2IxQSUzRCIsInBuYW1lIjoiMDEgNEsubXA0IiwicXR5cGUiOiJvcmlnaW5hbCJ9")
|
||||
}*/
|
||||
val jsonStr =
|
||||
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDMyNzkxMjIzNDEiLCJzaGFyZWlkIjoiMjk1NzE4ODcyOTgiLCJmaWQiOjMxOTM5NTUxMTQyOTU4MCwicmFuZHNrIjoidkd4WXh4TVBRcXpucXZialRQeUQ2Q1FFT2VqemtJWmdFdXV2OUQ1Y3R6TSUzRCIsInBuYW1lIjoiRHJhZ29uIEJhbGwgREFJTUEuUzAxRTAxLjIwMjQuMTA4MHAuQ1IuV0VCLURMLngyNjQuQUFDLm1rdiIsInF0eXBlIjoib3JpZ2luYWwifQ==")
|
||||
val obj = Json.safeObject(jsonStr)
|
||||
runBlocking {
|
||||
val reslut = yunDrive?.getVideoUrl(obj)
|
||||
val reslut = BaiduDrive.getVideoUrl(obj, "BD原画1")
|
||||
System.out.println(reslut)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createSaveDir() {/* val jsonStr =
|
||||
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
|
||||
val obj = Json.safeObject(jsonStr)
|
||||
runBlocking {
|
||||
val reslut = yunDrive?.getVideoUrl(obj)
|
||||
System.out.println(reslut)
|
||||
}*/
|
||||
|
||||
runBlocking {
|
||||
val reslut = BaiduDrive.createSaveDir()
|
||||
System.out.println(reslut)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://wget.la/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/bd/jar/custom_spider.jar;md5;851711824c28c744517e650d914bf07d",
|
||||
"spider": "https://andoridspidermt.netlify.app/jar/custom_spider.jar;md5;49c24003ea2a52abb468ad7661ae1730",
|
||||
"lives": [
|
||||
{
|
||||
"name": "电视直播",
|
||||
|
|
|
|||
Loading…
Reference in New Issue