123盘基本完成
This commit is contained in:
parent
fc1403c4a8
commit
0fd1d6df7c
|
|
@ -0,0 +1,394 @@
|
|||
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.bean.pan123.ShareInfo
|
||||
import com.github.catvod.crawler.SpiderDebug
|
||||
import com.github.catvod.net.OkHttp
|
||||
import com.github.catvod.utils.Json
|
||||
import com.github.catvod.utils.ProxyServer.buildProxyUrl
|
||||
import com.github.catvod.utils.Util
|
||||
import okhttp3.HttpUrl
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* 123网盘API操作类
|
||||
* 提供123网盘的文件分享、下载、播放等功能
|
||||
*/
|
||||
object Pan123Api {
|
||||
public const val regex =
|
||||
"https://(123592\\.com|123912\\.com|123865\\.com|123684\\.com|www\\.123684\\.com|www\\.123865\\.com|www\\.123912\\.com|www\\.123pan\\.com|www\\.123pan\\.cn|www\\.123592\\.com)/s/([^/]+)"
|
||||
|
||||
private const val api = "https://www.123684.com/b/api/share/"
|
||||
private const val loginUrl = "https://login.123pan.com/api/user/sign_in"
|
||||
|
||||
private var authToken = ""
|
||||
|
||||
|
||||
/**
|
||||
* 初始化方法,检查登录状态
|
||||
*/
|
||||
fun init() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取认证token
|
||||
*/
|
||||
private fun getAuth(): String {
|
||||
if (authToken.isNotBlank()) {
|
||||
return authToken
|
||||
}
|
||||
return Pan123Handler.getAuth()
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
*/
|
||||
fun login(passport: String, password: String): String? {
|
||||
|
||||
val data = mapOf(
|
||||
"passport" to passport, "password" to password, "remember" to true
|
||||
)
|
||||
|
||||
val headers = mapOf(
|
||||
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
|
||||
"Content-Type" to "application/json",
|
||||
"App-Version" to "43",
|
||||
"Referer" to "https://login.123pan.com/centerlogin?redirect_url=https%3A%2F%2Fwww.123684.com&source_page=website",
|
||||
"Accept" to "application/json, text/plain, */*",
|
||||
"Origin" to "https://login.123pan.com",
|
||||
"Connection" to "keep-alive",
|
||||
"Accept-Language" to "zh-CN,zh;q=0.9"
|
||||
)
|
||||
|
||||
try {
|
||||
val response = OkHttp.post(loginUrl, Json.toJson(data), headers)
|
||||
SpiderDebug.log("登录请求信息:")
|
||||
SpiderDebug.log("URL: $loginUrl")
|
||||
SpiderDebug.log("账号: ${passport}")
|
||||
SpiderDebug.log("响应内容: ${response.body}")
|
||||
|
||||
if (response.code == 200) {
|
||||
val authData = Json.safeObject(response.body)
|
||||
SpiderDebug.log("解析后的响应数据: $authData")
|
||||
if (authData.has("data") && authData.getAsJsonObject("data").has("token")) {
|
||||
val token = authData.getAsJsonObject("data").get("token").asString
|
||||
// setAuth(token)
|
||||
SpiderDebug.log("登录成功")
|
||||
|
||||
return token
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception("登录失败: HTTP状态码=${response.code}, 响应=${response.body}")
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("登录过程中发生错误: ${e.message}")
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析分享链接,提取分享密钥和提取码
|
||||
*/
|
||||
fun getShareData(url: String): Map<String, String> {
|
||||
SpiderDebug.log("123链接:$url")
|
||||
var sharePwd = ""
|
||||
var lurl = java.net.URLDecoder.decode(url, "UTF-8")
|
||||
|
||||
// 处理提取码格式
|
||||
if ("提取码" in lurl && "?" !in lurl) {
|
||||
lurl = lurl.replace(Regex("提取码[::]"), "?")
|
||||
}
|
||||
if ("提取码" in lurl && "?" in lurl) {
|
||||
lurl = lurl.replace(Regex("提取码[::]?"), "")
|
||||
}
|
||||
if (":" in lurl) {
|
||||
lurl = lurl.replace(":", "")
|
||||
}
|
||||
|
||||
val matcher = Pattern.compile(regex).matcher(lurl)
|
||||
|
||||
// 提取分享密码
|
||||
if ("?" in lurl) {
|
||||
val queryPart = lurl.split("?")[1]
|
||||
val pwdMatcher = Regex("[A-Za-z0-9]+").find(queryPart)
|
||||
if (pwdMatcher != null) {
|
||||
sharePwd = pwdMatcher.value
|
||||
}
|
||||
}
|
||||
|
||||
if (matcher.find()) {
|
||||
val match = matcher.group(2) ?: ""
|
||||
val key = when {
|
||||
"?" in match -> match.split("?")[0]
|
||||
".html" in match -> match.replace(".html", "")
|
||||
"www" in match -> matcher.group(1) ?: match
|
||||
else -> match
|
||||
}
|
||||
return mapOf("key" to key, "sharePwd" to sharePwd)
|
||||
}
|
||||
|
||||
return emptyMap()
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分享链接获取文件列表
|
||||
*/
|
||||
fun getFilesByShareUrl(shareKey: String, sharePwd: String): List<ShareInfo> {
|
||||
// 获取分享信息
|
||||
val cate = getShareInfo(shareKey, sharePwd, 0, 0)
|
||||
|
||||
return cate
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取分享信息
|
||||
*/
|
||||
private fun getShareInfo(
|
||||
shareKey: String, sharePwd: String, next: Int, parentFileId: Long
|
||||
): List<ShareInfo> {
|
||||
|
||||
|
||||
//文件夹
|
||||
val folders = mutableListOf<ShareInfo>()
|
||||
//视频
|
||||
val videos = mutableListOf<ShareInfo>()
|
||||
|
||||
|
||||
val url =
|
||||
"${api}get?limit=100&next=$next&orderBy=file_name&orderDirection=asc&shareKey=${shareKey.trim()}&SharePwd=${sharePwd.ifEmpty { "" }}&ParentFileId=$parentFileId&Page=1"
|
||||
|
||||
try {
|
||||
val response = OkHttp.string(
|
||||
url, mapOf(
|
||||
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
|
||||
)
|
||||
)
|
||||
|
||||
val data = Json.safeObject(response)
|
||||
if (data.has("code") && data.get("code").asInt == 5103) {
|
||||
SpiderDebug.log("123获取文件列表出错:" + data.get("message").asString)
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val info = data.getAsJsonObject("data")
|
||||
//其下没有文件
|
||||
if (info.get("Len").asLong <= 0) {
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
val nextValue = info.get("Next").asInt
|
||||
val infoList = info.getAsJsonArray("InfoList")
|
||||
|
||||
// 处理文件夹
|
||||
for (item in infoList) {
|
||||
val itemObj = item.asJsonObject
|
||||
//文件夹
|
||||
if (itemObj.get("Category").asInt == 0) {
|
||||
folders.add(
|
||||
ShareInfo(
|
||||
itemObj.get("FileName").asString,
|
||||
shareKey,
|
||||
sharePwd,
|
||||
nextValue,
|
||||
itemObj.get("FileId").asLong,
|
||||
itemObj["S3KeyFlag"].asString,
|
||||
itemObj["Size"].asLong,
|
||||
itemObj["Etag"].asString,
|
||||
|
||||
)
|
||||
)
|
||||
} else if (itemObj.get("Category").asInt == 2) {
|
||||
videos.add(
|
||||
ShareInfo(
|
||||
itemObj.get("FileName").asString,
|
||||
shareKey,
|
||||
sharePwd,
|
||||
nextValue,
|
||||
itemObj.get("FileId").asLong,
|
||||
itemObj["S3KeyFlag"].asString,
|
||||
itemObj["Size"].asLong,
|
||||
itemObj["Etag"].asString,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 递归获取子文件夹信息
|
||||
|
||||
for (item in folders) {
|
||||
val result = getShareInfo(
|
||||
item.shareKey, item.sharePwd, item.next, item.fileId
|
||||
)
|
||||
videos.addAll(result)
|
||||
}
|
||||
|
||||
return videos
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("获取分享信息时发生错误: ${e.message}")
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文件下载链接
|
||||
*/
|
||||
fun getDownload(
|
||||
shareKey: String, fileId: Long, s3KeyFlag: String, size: Long, etag: String
|
||||
): String {
|
||||
|
||||
|
||||
SpiderDebug.log("获取下载链接参数:")
|
||||
SpiderDebug.log("ShareKey: $shareKey")
|
||||
SpiderDebug.log("FileID: $fileId")
|
||||
SpiderDebug.log("S3KeyFlag: $s3KeyFlag")
|
||||
SpiderDebug.log("Size: $size")
|
||||
SpiderDebug.log("Etag: $etag")
|
||||
SpiderDebug.log("Auth Token: ${getAuth().take(30)}...")
|
||||
|
||||
val data = mapOf(
|
||||
"ShareKey" to shareKey, "FileID" to fileId, "S3KeyFlag" to s3KeyFlag, "Size" to size, "Etag" to etag
|
||||
)
|
||||
|
||||
val url = "${api}download/info"
|
||||
SpiderDebug.log("请求URL: $url")
|
||||
SpiderDebug.log("请求数据: ${Json.toJson(data)}")
|
||||
|
||||
val headers = mapOf(
|
||||
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
|
||||
"Content-Type" to "application/json",
|
||||
"Authorization" to "Bearer ${getAuth()}"
|
||||
)
|
||||
|
||||
try {
|
||||
val response = OkHttp.post(url, Json.toJson(data), headers)
|
||||
SpiderDebug.log("响应状态码: ${response.code}")
|
||||
SpiderDebug.log("响应内容: ${response.body}")
|
||||
|
||||
if (response.code == 200) {
|
||||
val responseData = Json.safeObject(response.body)
|
||||
if (responseData.has("data") && responseData.getAsJsonObject("data").has("DownloadURL")) {
|
||||
val encodeUrl = responseData.getAsJsonObject("data").get("DownloadURL").asString
|
||||
return Util.base64Decode(HttpUrl.parse(encodeUrl)?.queryParameter("params"))
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception("获取下载链接失败: HTTP状态码=${response.code}, 响应=${response.body}")
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("获取下载链接时发生错误: ${e.message}")
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频在线播放链接
|
||||
*/
|
||||
fun getLiveTranscoding(
|
||||
shareKey: String, fileId: Long, s3KeyFlag: String, size: Long, etag: String
|
||||
): List<Map<String, String>> {
|
||||
|
||||
|
||||
val url = "https://www.123684.com/b/api/video/play/info?" + "etag=$etag&size=$size&from=1&shareKey=$shareKey"
|
||||
|
||||
val headers = mapOf(
|
||||
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
|
||||
"Authorization" to "Bearer ${getAuth()}",
|
||||
"Content-Type" to "application/json;charset=UTF-8",
|
||||
"platform" to "android"
|
||||
)
|
||||
|
||||
try {
|
||||
val response = OkHttp.string(url, headers)
|
||||
|
||||
val downData = Json.safeObject(response)
|
||||
if (downData.has("data") && downData.getAsJsonObject("data").has("video_play_info")) {
|
||||
val videoInfo = mutableListOf<Map<String, String>>()
|
||||
val videoPlayInfo = downData.getAsJsonObject("data").getAsJsonArray("video_play_info")
|
||||
|
||||
for (item in videoPlayInfo) {
|
||||
val itemObj = item.asJsonObject
|
||||
if (itemObj.has("url") && !itemObj.get("url").isJsonNull) {
|
||||
val resolution = if (itemObj.has("resolution")) itemObj.get("resolution").asString else ""
|
||||
val urlValue = itemObj.get("url").asString
|
||||
|
||||
videoInfo.add(
|
||||
mapOf(
|
||||
"name" to resolution, "url" to urlValue
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return videoInfo
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("获取视频播放链接时发生错误: ${e.message}")
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
fun getPlayFormatList(): Array<String> {
|
||||
return arrayOf("原画")
|
||||
}
|
||||
|
||||
fun getVod(key: String, sharePwd: String): Vod {
|
||||
val list = getFilesByShareUrl(key, sharePwd)
|
||||
|
||||
val builder = VodPlayBuilder()
|
||||
for (i in getPlayFormatList().indices) {
|
||||
val playUrls = mutableListOf<VodPlayBuilder.PlayUrl>();
|
||||
for (item in list) {
|
||||
|
||||
val play = VodPlayBuilder.PlayUrl()
|
||||
play.name = "[${Util.getSize(item.Size.toDouble())}]${item.filename}"
|
||||
play.url =
|
||||
listOf(item.shareKey, item.fileId, item.S3KeyFlag, item.Size, item.Etag).joinToString("\\+\\+")
|
||||
|
||||
playUrls.add(play)
|
||||
|
||||
}
|
||||
builder.append("pan123" + getPlayFormatList()[i], playUrls)
|
||||
}
|
||||
val buildResult = builder.build();
|
||||
|
||||
val vod = Vod()
|
||||
vod.setVodId(key + "++" + sharePwd)
|
||||
vod.setVodPic("")
|
||||
vod.setVodYear("")
|
||||
vod.setVodName("")
|
||||
vod.setVodContent("")
|
||||
vod.setVodPlayFrom(buildResult.vodPlayFrom)
|
||||
vod.setVodPlayUrl(buildResult.vodPlayUrl)
|
||||
return vod
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun playerContent(id: String, flag: String): String {
|
||||
val itemJson = id.split("\\+\\+")
|
||||
|
||||
SpiderDebug.log("播放参数:$itemJson")
|
||||
val url = getDownload(
|
||||
itemJson[0], itemJson[1].toLong(), itemJson[2], itemJson[3].toLong(), itemJson[4]
|
||||
)
|
||||
val header = mapOf(
|
||||
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
|
||||
)
|
||||
|
||||
return Result.get().url(buildProxyUrl(url, header)).octet().header(header).string();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
package com.github.catvod.api
|
||||
|
||||
|
||||
import android.R
|
||||
import android.app.AlertDialog
|
||||
import android.content.DialogInterface
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import com.github.catvod.api.Pan123Api.login
|
||||
import com.github.catvod.bean.pan123.Cache
|
||||
import com.github.catvod.bean.pan123.User
|
||||
import com.github.catvod.crawler.SpiderDebug
|
||||
import com.github.catvod.spider.Init
|
||||
import com.github.catvod.utils.Notify
|
||||
import com.github.catvod.utils.Path
|
||||
import com.github.catvod.utils.ResUtil
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import java.io.File
|
||||
|
||||
object Pan123Handler {
|
||||
|
||||
|
||||
private var cache: Cache? = null
|
||||
private var dialog: AlertDialog? = null
|
||||
|
||||
private var auth = ""
|
||||
private var userName = ""
|
||||
private var passwd = ""
|
||||
|
||||
fun getCache(): File {
|
||||
return Path.tv("pan123")
|
||||
}
|
||||
|
||||
fun getAuth(): String {
|
||||
return auth
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
|
||||
cache = Cache.objectFrom(Path.read(getCache()))
|
||||
if (cache == null) {
|
||||
SpiderDebug.log("cache 为null")
|
||||
startFlow()
|
||||
} else {
|
||||
userName = cache!!.user.userName
|
||||
passwd = cache!!.user.password
|
||||
auth = cache!!.user.cookie
|
||||
if (StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(passwd)) {
|
||||
if (StringUtils.isBlank(auth)) {
|
||||
SpiderDebug.log("userName passwd 不为空,auth 为空")
|
||||
this.loginWithPassword(userName, passwd)
|
||||
}
|
||||
|
||||
} else {
|
||||
SpiderDebug.log("userName passwd 为空")
|
||||
startFlow()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun loginWithPassword(uname: String?, passwd: String?) {
|
||||
SpiderDebug.log("loginWithPassword uname: $uname,passwd:$passwd")
|
||||
|
||||
try {
|
||||
//保存的账号密码
|
||||
val auth = login(uname!!, passwd!!)
|
||||
if (StringUtils.isNotBlank(auth)) {
|
||||
val user = User()
|
||||
user.cookie = auth
|
||||
user.password = passwd
|
||||
user.userName = uname
|
||||
this.auth = auth ?: ""
|
||||
cache?.setUserInfo(user)
|
||||
Notify.show("123登录成功")
|
||||
} else {
|
||||
Notify.show("123登录失败")
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("登录失败: " + e.message)
|
||||
Notify.show("123登录失败: " + e.message)
|
||||
}
|
||||
}
|
||||
|
||||
fun startFlow() {
|
||||
Init.run { this.showInput() }
|
||||
}
|
||||
|
||||
|
||||
private fun showInput() {
|
||||
try {
|
||||
val margin = ResUtil.dp2px(16)
|
||||
val params =
|
||||
LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
val frame = LinearLayout(Init.context())
|
||||
frame.setOrientation(LinearLayout.VERTICAL)
|
||||
// frame.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
// params.setMargins(margin, margin, margin, margin);
|
||||
val username = EditText(Init.context())
|
||||
username.setHint("请输入123用户名")
|
||||
val password = EditText(Init.context())
|
||||
password.setHint("请输入123密码")
|
||||
frame.addView(username, params)
|
||||
frame.addView(password, params)
|
||||
dialog = AlertDialog.Builder(Init.getActivity()).setTitle("请输入123用户名和密码").setView(frame)
|
||||
.setNegativeButton(
|
||||
R.string.cancel, null
|
||||
).setPositiveButton(
|
||||
R.string.ok, DialogInterface.OnClickListener { dialog: DialogInterface?, which: Int ->
|
||||
onPositive(
|
||||
username.getText().toString(), password.getText().toString()
|
||||
)
|
||||
}).show()
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun onPositive(username: String?, password: String?) {
|
||||
SpiderDebug.log("123用户名: $username")
|
||||
SpiderDebug.log("123密码: $password")
|
||||
dismiss()
|
||||
Init.execute(Runnable {
|
||||
loginWithPassword(username, password)
|
||||
})
|
||||
}
|
||||
|
||||
private fun dismiss() {
|
||||
try {
|
||||
if (dialog != null) dialog!!.dismiss()
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.github.catvod.bean.pan123;
|
||||
|
||||
import com.github.catvod.api.Pan123Handler;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
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) {
|
||||
if(str.isEmpty()) return new Cache();
|
||||
SpiderDebug.log("Cache.objectFrom: " + 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 setUserInfo(User user) {
|
||||
this.user = user;
|
||||
this.saveUser();
|
||||
}
|
||||
|
||||
public void saveUser() {
|
||||
SpiderDebug.log("Cache.saveUser: " + toString());
|
||||
SpiderDebug.log("Cache.path: " + Pan123Handler.INSTANCE.getCache().getAbsolutePath());
|
||||
Init.execute(() -> Path.write(Pan123Handler.INSTANCE.getCache(), toString()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.github.catvod.bean.pan123
|
||||
|
||||
data class ShareInfo(
|
||||
val filename: String,
|
||||
val shareKey: String,
|
||||
val sharePwd: String,
|
||||
val next: Int,
|
||||
val fileId: Long,
|
||||
val S3KeyFlag: String,
|
||||
val Size: Long,
|
||||
val Etag: String
|
||||
)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.github.catvod.bean.pan123;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class User {
|
||||
|
||||
|
||||
@SerializedName("cookie")
|
||||
private String cookie;
|
||||
|
||||
@SerializedName("userName")
|
||||
private String userName;
|
||||
@SerializedName("password")
|
||||
private String password;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getCookie() {
|
||||
return cookie;
|
||||
}
|
||||
|
||||
public void setCookie(String cookie) {
|
||||
this.cookie = cookie;
|
||||
}
|
||||
|
||||
public static User objectFrom(String str) {
|
||||
User item = new Gson().fromJson(str, User.class);
|
||||
return item == null ? new User() : item;
|
||||
}
|
||||
|
||||
|
||||
public void clean() {
|
||||
this.cookie = "";
|
||||
this.userName = "";
|
||||
this.password = "";
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,10 @@ package com.github.catvod.spider;
|
|||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import com.github.catvod.api.Pan123Api;
|
||||
import com.github.catvod.api.TianyiApi;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.JsonObject;
|
||||
|
|
@ -24,6 +26,7 @@ public class Cloud extends Spider {
|
|||
private TianYi tianYi = null;
|
||||
private YiDongYun yiDongYun = null;
|
||||
private BaiDuPan baiDuPan = null;
|
||||
private Pan123 pan123 = null;
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
|
|
@ -34,6 +37,7 @@ public class Cloud extends Spider {
|
|||
tianYi = new TianYi();
|
||||
yiDongYun = new YiDongYun();
|
||||
baiDuPan = new BaiDuPan();
|
||||
pan123 = new Pan123();
|
||||
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() : "");
|
||||
|
|
@ -41,14 +45,18 @@ public class Cloud extends Spider {
|
|||
tianYi.init(context, first && ext.has("tianyicookie") ? ext.get("tianyicookie").getAsString() : "");
|
||||
yiDongYun.init(context, "");
|
||||
baiDuPan.init(context, "");
|
||||
pan123.init(context, "");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> shareUrl) throws Exception {
|
||||
SpiderDebug.log("cloud detailContent shareUrl:" + Json.toJson(shareUrl));
|
||||
|
||||
/* if (shareUrl.get(0).matches(Util.patternAli)) {
|
||||
return ali.detailContent(shareUrl);
|
||||
} else */if (shareUrl.get(0).matches(Util.patternQuark)) {
|
||||
} else */
|
||||
if (shareUrl.get(0).matches(Util.patternQuark)) {
|
||||
return quark.detailContent(shareUrl);
|
||||
} /*else if (shareUrl.get(0).matches(Util.patternUC)) {
|
||||
return uc.detailContent(shareUrl);
|
||||
|
|
@ -58,12 +66,17 @@ public class Cloud extends Spider {
|
|||
return yiDongYun.detailContent(shareUrl);
|
||||
} else if (shareUrl.get(0).contains(BaiDuPan.URL_START)) {
|
||||
return baiDuPan.detailContent(shareUrl);
|
||||
} else if (shareUrl.get(0).matches(Pan123Api.regex)) {
|
||||
SpiderDebug.log("Pan123Api shareUrl:" + Json.toJson(shareUrl));
|
||||
return pan123.detailContent(shareUrl);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
SpiderDebug.log("cloud playerContent flag:" + flag + " id:" + id);
|
||||
|
||||
if (flag.contains("quark")) {
|
||||
return quark.playerContent(flag, id, vipFlags);
|
||||
} /*else if (flag.contains("uc")) {
|
||||
|
|
@ -74,10 +87,10 @@ public class Cloud extends Spider {
|
|||
return yiDongYun.playerContent(flag, id, vipFlags);
|
||||
}/* else {
|
||||
return ali.playerContent(flag, id, vipFlags);
|
||||
}*/
|
||||
|
||||
else if (flag.contains("BD")) {
|
||||
}*/ else if (flag.contains("BD")) {
|
||||
return baiDuPan.playerContent(flag, id, vipFlags);
|
||||
} else if (flag.contains("pan123")) {
|
||||
return pan123.playerContent(flag, id, vipFlags);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
|
@ -89,7 +102,8 @@ public class Cloud extends Spider {
|
|||
i++;
|
||||
/*if (shareLink.matches(Util.patternUC)) {
|
||||
from.add(uc.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
} else*/ if (shareLink.matches(Util.patternQuark)) {
|
||||
} else*/
|
||||
if (shareLink.matches(Util.patternQuark)) {
|
||||
from.add(quark.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
} /*else if (shareLink.matches(Util.patternAli)) {
|
||||
from.add(ali.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
|
|
@ -97,9 +111,10 @@ public class Cloud extends Spider {
|
|||
from.add(tianYi.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
} else if (shareLink.contains(YiDongYun.URL_START)) {
|
||||
from.add(yiDongYun.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
}
|
||||
else if (shareLink.contains(BaiDuPan.URL_START)) {
|
||||
} else if (shareLink.contains(BaiDuPan.URL_START)) {
|
||||
from.add(baiDuPan.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
} else if (shareLink.matches(Pan123Api.regex)) {
|
||||
from.add(pan123.detailContentVodPlayFrom(List.of(shareLink), i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +126,8 @@ public class Cloud extends Spider {
|
|||
for (String shareLink : shareLinks) {
|
||||
/* if (shareLink.matches(Util.patternUC)) {
|
||||
urls.add(uc.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
} else */if (shareLink.matches(Util.patternQuark)) {
|
||||
} else */
|
||||
if (shareLink.matches(Util.patternQuark)) {
|
||||
urls.add(quark.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
}/* else if (shareLink.matches(Util.patternAli)) {
|
||||
urls.add(ali.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
|
|
@ -121,6 +137,8 @@ public class Cloud extends Spider {
|
|||
urls.add(yiDongYun.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
} else if (shareLink.contains(BaiDuPan.URL_START)) {
|
||||
urls.add(baiDuPan.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
} else if (shareLink.matches(Pan123Api.regex)) {
|
||||
urls.add(pan123.detailContentVodPlayUrl(List.of(shareLink)));
|
||||
}
|
||||
}
|
||||
return TextUtils.join("$$$", urls);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import com.github.catvod.api.Pan123Api;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lushunming
|
||||
*/
|
||||
public class Pan123 extends Spider {
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
|
||||
if (StringUtils.isNoneBlank(extend)) {
|
||||
// Pan123Api.INSTANCE.setAuth(extend);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
|
||||
@NotNull Map<@NotNull String, @NotNull String> shareData = Pan123Api.INSTANCE.getShareData(ids.get(0));
|
||||
return Result.string(Pan123Api.INSTANCE.getVod(shareData.get("key"), shareData.get("sharePwd")));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Pan123Api.INSTANCE.playerContent(id, flag);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取詳情內容視頻播放來源(多 shared_link)
|
||||
*
|
||||
* @param ids share_link 集合
|
||||
* @param
|
||||
* @return 詳情內容視頻播放來源
|
||||
*/
|
||||
public String detailContentVodPlayFrom(List<String> ids, int index) {
|
||||
List<String> playFrom = new ArrayList<>();
|
||||
/* if (ids.size() < 2){
|
||||
return TextUtils.join("$$$", Pan123Api.INSTANCE.getPlayFormatList());
|
||||
}*/
|
||||
|
||||
for (int i = 1; i <= ids.size(); i++) {
|
||||
|
||||
for (String s : Pan123Api.INSTANCE.getPlayFormatList()) {
|
||||
playFrom.add(String.format(Locale.getDefault(), "pan123" + s + "#%02d%02d", i, index));
|
||||
|
||||
}
|
||||
// playFrom.add("天意" + i + index);
|
||||
}
|
||||
return TextUtils.join("$$$", playFrom);
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取詳情內容視頻播放地址(多 share_link)
|
||||
*
|
||||
* @param ids share_link 集合
|
||||
* @return 詳情內容視頻播放地址
|
||||
*/
|
||||
public String detailContentVodPlayUrl(List<String> ids) throws Exception {
|
||||
List<String> playUrl = new ArrayList<>();
|
||||
for (String id : ids) {
|
||||
@NotNull Map<@NotNull String, @NotNull String> shareData = Pan123Api.INSTANCE.getShareData(id);
|
||||
try {
|
||||
playUrl.add(Pan123Api.INSTANCE.getVod(shareData.get("key"), shareData.get("sharePwd")).getVodPlayUrl());
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log("获取播放地址出错:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
return TextUtils.join("$$$", playUrl);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.github.catvod.bean.Result;
|
|||
import com.github.catvod.bean.Sub;
|
||||
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.Image;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
|
@ -19,31 +20,54 @@ import java.util.List;
|
|||
|
||||
public class Push extends Spider {
|
||||
|
||||
private final Ali ali;
|
||||
private Cloud cloud;
|
||||
|
||||
public Push() {
|
||||
ali = new Ali();
|
||||
cloud = new Cloud();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
ali.init(context, extend);
|
||||
try {
|
||||
cloud.init(context, extend);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log("Cloud init error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
if (Ali.pattern.matcher(ids.get(0)).find()) return ali.detailContent(ids);
|
||||
return Result.string(vod(ids.get(0)));
|
||||
String url = ids.get(0);
|
||||
|
||||
// 使用Cloud类处理各种云盘链接
|
||||
String cloudResult = cloud.detailContent(ids);
|
||||
if (cloudResult != null) {
|
||||
return cloudResult;
|
||||
}
|
||||
|
||||
// 如果不是云盘链接,返回普通链接处理结果
|
||||
return Result.string(vod(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 使用Cloud类处理云盘链接的播放
|
||||
String cloudResult = cloud.playerContent(flag, id, vipFlags);
|
||||
if (cloudResult != null) {
|
||||
return cloudResult;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log("Cloud playerContent error: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 原有逻辑处理其他类型链接
|
||||
if (id.startsWith("http") && id.contains("***")) id = id.replace("***", "#");
|
||||
if (flag.equals("直連")) return Result.get().url(id).subs(getSubs(id)).string();
|
||||
if (flag.equals("解析")) return Result.get().parse().jx().url(id).string();
|
||||
if (flag.equals("嗅探")) return Result.get().parse().url(id).string();
|
||||
if (flag.equals("迅雷")) return Result.get().url(id).string();
|
||||
return ali.playerContent(flag, id, vipFlags);
|
||||
return Result.get().url(id).string();
|
||||
}
|
||||
|
||||
private Vod vod(String url) {
|
||||
|
|
|
|||
|
|
@ -4,26 +4,20 @@ import com.github.catvod.crawler.SpiderDebug
|
|||
import com.github.catvod.net.OkHttp
|
||||
import com.github.catvod.utils.ProxyVideo.getMimeType
|
||||
import com.github.catvod.utils.ProxyVideo.parseRange
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.*
|
||||
import okhttp3.Response
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import java.io.InputStream
|
||||
import java.io.SequenceInputStream
|
||||
import java.util.Vector
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
object DownloadMT {
|
||||
private val THREAD_NUM: Int = Runtime.getRuntime().availableProcessors() * 2
|
||||
private val THREAD_NUM: Int = 16
|
||||
|
||||
private val infos = mutableMapOf<String, Array<Any>>();
|
||||
|
||||
fun proxyMultiThread(url: String, headers: Map<String, String>): Array<out Any?>? =
|
||||
runBlocking {
|
||||
fun proxyMultiThread(url: String, headers: Map<String, String>): Array<out Any?>? = runBlocking {
|
||||
proxyAsync(url, headers)
|
||||
}
|
||||
|
||||
|
|
@ -52,8 +46,7 @@ object DownloadMT {
|
|||
if (info == null) {
|
||||
infos.clear()
|
||||
info = CoroutineScope(Dispatchers.IO).async { getInfo(url, headers) }.await()
|
||||
infos[url] = info
|
||||
/* //支持分片,先返回这个1MB块
|
||||
infos[url] = info/* //支持分片,先返回这个1MB块
|
||||
if (info[0] as Int == 206) {
|
||||
return info
|
||||
}*/
|
||||
|
|
@ -78,8 +71,7 @@ object DownloadMT {
|
|||
/* if (total.toLong() < 1024 * 1024 * 100) {
|
||||
return proxy(url, headers)
|
||||
}*/
|
||||
var range =
|
||||
if (StringUtils.isAllBlank(headers["range"])) headers["Range"] else headers["range"]
|
||||
var range = if (StringUtils.isAllBlank(headers["range"])) headers["Range"] else headers["range"]
|
||||
if (StringUtils.isAllBlank(range)) range = "bytes=0-";
|
||||
SpiderDebug.log("---proxyMultiThread,Range:$range")
|
||||
val rangeObj = parseRange(
|
||||
|
|
@ -128,8 +120,7 @@ object DownloadMT {
|
|||
|
||||
/* respHeaders.put("Access-Control-Allow-Credentials", "true");
|
||||
respHeaders.put("Access-Control-Allow-Origin", "*");*/
|
||||
resHeader["Content-Length"] =
|
||||
(partList[THREAD_NUM - 1][1] - partList[0][0] + 1).toString()
|
||||
resHeader["Content-Length"] = (partList[THREAD_NUM - 1][1] - partList[0][0] + 1).toString()
|
||||
resHeader.remove("content-length")
|
||||
|
||||
resHeader["Content-Range"] = String.format(
|
||||
|
|
@ -156,12 +147,10 @@ object DownloadMT {
|
|||
fun generatePart(rangeObj: Map<String?, String>, total: String): List<LongArray> {
|
||||
val totalSize = total.toLong()
|
||||
//超过10GB,分块是32Mb,不然是16MB
|
||||
val partSize =
|
||||
if (totalSize > 1024L * 1024L * 1024L * 10L) 1024 * 1024 * 8 * 4L else 1024 * 1024 * 8 * 2L
|
||||
val partSize = if (totalSize > 1024L * 1024L * 1024L * 10L) 1024 * 1024 * 8 * 4L else 1024 * 1024 * 8 * 2L
|
||||
|
||||
var start = rangeObj["start"]!!.toLong()
|
||||
var end =
|
||||
if (StringUtils.isAllBlank(rangeObj["end"])) start + partSize else rangeObj["end"]!!.toLong()
|
||||
var end = if (StringUtils.isAllBlank(rangeObj["end"])) start + partSize else rangeObj["end"]!!.toLong()
|
||||
|
||||
|
||||
end = min(end.toDouble(), (totalSize - 1).toDouble()).toLong()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import kotlinx.coroutines.runBlocking
|
|||
|
||||
|
||||
object ProxyServer {
|
||||
private val THREAD_NUM = Runtime.getRuntime().availableProcessors()
|
||||
private const val THREAD_NUM = 16
|
||||
private val partSize = 1024 * 1024 * 2
|
||||
private var port = 12345
|
||||
private var httpServer: AdvancedHttpServer? = null
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
import android.app.Application;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.spider.Pan123;
|
||||
import com.github.catvod.spider.TianYi;
|
||||
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 Pan123Test {
|
||||
|
||||
private Application mockContext;
|
||||
|
||||
private Pan123 spider;
|
||||
|
||||
@org.junit.Before
|
||||
public void setUp() throws Exception {
|
||||
mockContext = RuntimeEnvironment.application;
|
||||
Init.init(mockContext);
|
||||
spider = new Pan123();
|
||||
// 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, "{\"open.e.189.cn\":[{\"name\":\"SSON\",\"value\":\"dc466c8192e3109eaea837c1d136c1fd065253ce1c7d3a66ca1520d7d6d6307b10a1fe65c7becac73b95f24a6e681e654ec4f47c39533ebcc48bb78d6d6e63d1bbf3334e6e97eaa7092d34f87bf1209ee35f344871bc5a329eac34ae948d399d4a6b3b28a929c4f353ade0981657e9e0f09ce27cc1c15d8322c6e45a8ebb21eb431509f1dd7dc3a7856b32b0991d654d5ced73dd20b764ca8737600cbe699c37ccf59b3c610893fc42bdc08b477c5d394e290c14d175d1ca0ee9fa61a1a8dcac7007e9219fd0ae6ccd5dc760524213f85b6b8c6166af01a31336dab797d9118010b81a5a3c26e08e\",\"expiresAt\":253402300799999,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":true,\"httpOnly\":true,\"persistent\":true,\"hostOnly\":false},{\"name\":\"GUID\",\"value\":\"525d8874e53e46a7ba3ed8907e9fef1f\",\"expiresAt\":1775176321000,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":false,\"persistent\":true,\"hostOnly\":false},{\"name\":\"pageOp\",\"value\":\"336b9ddc820212fa6c9b5a0cfd7bf5b3\",\"expiresAt\":253402300799999,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":false,\"persistent\":false,\"hostOnly\":false},{\"name\":\"OPENINFO\",\"value\":\"33c28688ef52ce9e3a9ef87388047efbde5e3e2e4c7ef6ef267632468c7dfaf294ff59fa59d34801\",\"expiresAt\":253402300799999,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":true,\"persistent\":false,\"hostOnly\":false},{\"name\":\"GRAYNUMBER\",\"value\":\"319DE3F68C8730862F3BEF66F3D635B7\",\"expiresAt\":1775177653000,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":false,\"persistent\":true,\"hostOnly\":false}],\"cloud.189.cn\":[{\"name\":\"JSESSIONID\",\"value\":\"431787526C43DF21B6373E914FE597EC\",\"expiresAt\":253402300799999,\"domain\":\"cloud.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":true,\"persistent\":false,\"hostOnly\":true},{\"name\":\"COOKIE_LOGIN_USER\",\"value\":\"0C7407F59A6E5896EB6B777056E160DB020BAE67B121B5930CCD4777073744055308F7E8CD03F2FC2399E4823F60ECDD74120CEE4C529017\",\"expiresAt\":253402300799999,\"domain\":\"cloud.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":true,\"persistent\":false,\"hostOnly\":false}]}");
|
||||
// Server.get().start();
|
||||
spider.init(mockContext, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjE1MjEyNzksImlhdCI6MTc2MDkxNjQ3OSwiaWQiOjE4NDc0Mjg3NzAsIm1haWwiOiIiLCJuaWNrbmFtZSI6IjE4ODk2NzgxNjAxIiwic3VwcGVyIjpmYWxzZSwidXNlcm5hbWUiOjE4ODk2NzgxNjAxLCJ2IjowfQ.gVhIfG1t2tUts68eYY-AdUfJoBKBNeG41k3XGYfwCek");
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void init() throws Exception {
|
||||
spider.init(mockContext, "{\"open.e.189.cn\":[{\"name\":\"SSON\",\"value\":\"dc466c8192e3109eaea837c1d136c1fd065253ce1c7d3a66ca1520d7d6d6307b10a1fe65c7becac73b95f24a6e681e654ec4f47c39533ebcc48bb78d6d6e63d1bbf3334e6e97eaa7092d34f87bf1209ee35f344871bc5a329eac34ae948d399d4a6b3b28a929c4f353ade0981657e9e0f09ce27cc1c15d8322c6e45a8ebb21eb431509f1dd7dc3a7856b32b0991d654d5ced73dd20b764ca8737600cbe699c37ccf59b3c610893fc42bdc08b477c5d394e290c14d175d1ca0ee9fa61a1a8dcac7007e9219fd0ae6ccd5dc760524213f85b6b8c6166af01a31336dab797d9118010b81a5a3c26e08e\",\"expiresAt\":253402300799999,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":true,\"httpOnly\":true,\"persistent\":true,\"hostOnly\":false},{\"name\":\"GUID\",\"value\":\"525d8874e53e46a7ba3ed8907e9fef1f\",\"expiresAt\":1775176321000,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":false,\"persistent\":true,\"hostOnly\":false},{\"name\":\"pageOp\",\"value\":\"336b9ddc820212fa6c9b5a0cfd7bf5b3\",\"expiresAt\":253402300799999,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":false,\"persistent\":false,\"hostOnly\":false},{\"name\":\"OPENINFO\",\"value\":\"33c28688ef52ce9e3a9ef87388047efbde5e3e2e4c7ef6ef267632468c7dfaf294ff59fa59d34801\",\"expiresAt\":253402300799999,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":true,\"persistent\":false,\"hostOnly\":false},{\"name\":\"GRAYNUMBER\",\"value\":\"319DE3F68C8730862F3BEF66F3D635B7\",\"expiresAt\":1775177653000,\"domain\":\"e.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":false,\"persistent\":true,\"hostOnly\":false}],\"cloud.189.cn\":[{\"name\":\"JSESSIONID\",\"value\":\"431787526C43DF21B6373E914FE597EC\",\"expiresAt\":253402300799999,\"domain\":\"cloud.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":true,\"persistent\":false,\"hostOnly\":true},{\"name\":\"COOKIE_LOGIN_USER\",\"value\":\"0C7407F59A6E5896EB6B777056E160DB020BAE67B121B5930CCD4777073744055308F7E8CD03F2FC2399E4823F60ECDD74120CEE4C529017\",\"expiresAt\":253402300799999,\"domain\":\"cloud.189.cn\",\"path\":\"/\",\"secure\":false,\"httpOnly\":true,\"persistent\":false,\"hostOnly\":false}]}");
|
||||
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void detailContent() throws Exception {
|
||||
|
||||
String content = spider.detailContent(Arrays.asList("https://www.123865.com/s/u9izjv-6hSWv"));
|
||||
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("pan123原画","eyJmaWxlbmFtZSI6IuWRveaCrOS4gOeUny5TMDFFMDEuMjAyNS4yMTYwcC5XRUItREwuSDI2NS5ERFA1LjEubWt2Iiwic2hhcmVLZXkiOiJ1OWl6anYtNmhTV3YiLCJzaGFyZVB3ZCI6IiIsIm5leHQiOi0xLCJmaWxlSWQiOjI3MzQ0MjY3LCJTM0tleUZsYWciOiIxODI3MDg2NzQ5LTAiLCJTaXplIjoxNDExNDM3ODI2LCJFdGFnIjoiZGZmOGZlZWU2N2JkYzRhOTQxMjlhZTJlNTg1YmI0Y2QifQ==",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){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,7 @@
|
|||
import android.app.Application;
|
||||
import com.github.catvod.server.Server;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.spider.PanSearch;
|
||||
import com.github.catvod.spider.Tg189Search;
|
||||
import com.github.catvod.spider.TgQuarkSearch;
|
||||
import com.github.catvod.spider.TgSearch;
|
||||
import com.github.catvod.spider.TianYiSo;
|
||||
import com.github.catvod.spider.TgSearchBaidu;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
|
@ -15,6 +11,7 @@ import org.junit.runner.RunWith;
|
|||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
|
|
@ -22,23 +19,23 @@ public class TgSearchTest {
|
|||
|
||||
private Application mockContext;
|
||||
|
||||
private TgQuarkSearch spider;
|
||||
private TgSearchBaidu spider;
|
||||
|
||||
@org.junit.Before
|
||||
public void setUp() throws Exception {
|
||||
mockContext = RuntimeEnvironment.application;
|
||||
Init.init(mockContext);
|
||||
spider = new TgQuarkSearch();
|
||||
spider = new TgSearchBaidu();
|
||||
Server.get().start();
|
||||
// spider.init(mockContext, "{\"cookie\":\"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\",\"token\":\"26fc6787afff43e78b78992e782502f1\"}");
|
||||
spider.init(mockContext,"{\n" +
|
||||
/* spider.init(mockContext,"{\n" +
|
||||
"\t\"username\":\"18896781601\" ,\"password\":\"Lushunming@0526\"\n" +
|
||||
"}"); // spider.init(mockContext, "");
|
||||
"}"); */
|
||||
|
||||
spider.init(mockContext, "{\n" + " \"api_urls\": [\n" + " \"https://psweb.banye.tech:7777/api/search\",\n" + " \"https://so.566987.xyz/api/search\",\n" + " \"http://152.69.222.142:8088/api/search\"\n" + " ],\n" + " \"sources\": [\n" + " \"123盘\"\n" + " ]\n" + " }");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@org.junit.Test
|
||||
public void searchContent() throws Exception {
|
||||
String content = spider.searchContent("水饺皇后", false);
|
||||
|
|
@ -51,7 +48,18 @@ public class TgSearchTest {
|
|||
@org.junit.Test
|
||||
public void detailContent() throws Exception {
|
||||
|
||||
String content = spider.detailContent(Arrays.asList("/s/LEvn4lUGB6ufdQ"));
|
||||
String content = spider.detailContent(Arrays.asList("https://123684.com/s/u9izjv-smUWv"));
|
||||
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 content1 = spider.detailContent(Arrays.asList("https://123684.com/s/u9izjv-smUWv"));
|
||||
|
||||
String content = spider.playerContent("pan123原画", "eyJmaWxlbmFtZSI6IlRoZS5EdW1wbGluZy5RdWVlbi4yMDI1LjEwODBwLldFQi1ETC5IMjY0LkFBQy5tcDQiLCJzaGFyZUtleSI6InU5aXpqdi1zbVVXdiIsInNoYXJlUHdkIjoiIiwibmV4dCI6LTEsImZpbGVJZCI6MTg1NjgwODEsIlMzS2V5RmxhZyI6IjE4NDMwNTU4NTItMCIsIlNpemUiOjY0MDQyNTYzMTIsIkV0YWciOiIwYjNjZGIyOTYxZWM2NmQ5MjAyMTViOTRmZGY2MDZjNyJ9", new ArrayList<>());
|
||||
JsonObject map = Json.safeObject(content);
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
System.out.println("detailContent--" + gson.toJson(map));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package com.github.catvod.api
|
||||
|
||||
import com.github.catvod.utils.Util
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class Pan123Test {
|
||||
var pan123: Pan123Api? = null
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
pan123 = Pan123Api
|
||||
// pan123!!.login()
|
||||
}
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun login() {
|
||||
//pan123!!.login()
|
||||
"https://123684.com/s/u9izjv-smUWv".matches(Pan123Api.regex.toRegex())
|
||||
"https://www.123865.com/s/u9izjv-6hSWv".matches(Util.patternQuark.toRegex())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun processShareData() {
|
||||
val result: Map<String, String> = pan123!!.getShareData("https://www.123865.com/s/u9izjv-6hSWv")
|
||||
println(result)
|
||||
|
||||
|
||||
val files= pan123!!.getFilesByShareUrl(result["key"]!!, result["sharePwd"]!!);
|
||||
println(files)
|
||||
|
||||
/* if (files != null) {
|
||||
for (file in files) {
|
||||
val playUrl = pan123!!.getDownload(result["key"]!!, file.fileId, file.S3KeyFlag, file.Size, file.Etag)
|
||||
println(playUrl)
|
||||
}
|
||||
}*/ if (files != null) {
|
||||
for (file in files) {
|
||||
val playUrl = pan123!!.getLiveTranscoding(result["key"]!!, file.fileId, file.S3KeyFlag, file.Size, file.Etag)
|
||||
println(playUrl)
|
||||
}
|
||||
}
|
||||
|
||||
/*for (String s : result.keySet()) {
|
||||
for (Map<String, String> stringStringMap : result.get(s)) {
|
||||
String playUrl = pan123.fetchPlayUrl(stringStringMap.get("contentId"), "");
|
||||
System.out.println(stringStringMap.get("name") + ":" + playUrl);
|
||||
}
|
||||
|
||||
|
||||
}*/
|
||||
} /* @Test
|
||||
public void download() throws Exception {
|
||||
|
||||
Map<String, List<Map<String, String>>> result = pan123.processShareData("https://caiyun.139.com/w/i/2nQQVZWCR24yf");
|
||||
System.out.println(result);
|
||||
for (String s : result.keySet()) {
|
||||
for (Map<String, String> stringStringMap : result.get(s)) {
|
||||
String playUrl = pan123.fetchPlayUrl(stringStringMap.get("contentId"), stringStringMap.get("linkID"));
|
||||
String url2 = pan123.get4kVideoInfo(stringStringMap.get("linkID"), stringStringMap.get("path"));
|
||||
System.out.println(stringStringMap.get("name") + ":" + playUrl);
|
||||
System.out.println(stringStringMap.get("url2") + ":" + url2);
|
||||
}
|
||||
}
|
||||
//;
|
||||
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
@echo off
|
||||
call "%~dp0\gradlew" clean
|
||||
|
||||
|
||||
call "%~dp0\gradlew" assembleRelease --no-daemon
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
8a1cc4b31a331b1937bf6a449e94e4de
|
||||
77ff0d77d6fccecddd174ee82161f3bd
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/123/jar/custom_spider.jar;md5;8a1cc4b31a331b1937bf6a449e94e4de",
|
||||
"spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/123/jar/custom_spider.jar;md5;77ff0d77d6fccecddd174ee82161f3bd",
|
||||
"lives": [
|
||||
{
|
||||
"name": "电视直播",
|
||||
|
|
|
|||
Loading…
Reference in New Issue