diff --git a/app/src/main/java/com/github/catvod/api/Pan123Api.kt b/app/src/main/java/com/github/catvod/api/Pan123Api.kt new file mode 100644 index 00000000..822ec52a --- /dev/null +++ b/app/src/main/java/com/github/catvod/api/Pan123Api.kt @@ -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 { + 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 { + // 获取分享信息 + val cate = getShareInfo(shareKey, sharePwd, 0, 0) + + return cate + } + + + /** + * 获取分享信息 + */ + private fun getShareInfo( + shareKey: String, sharePwd: String, next: Int, parentFileId: Long + ): List { + + + //文件夹 + val folders = mutableListOf() + //视频 + val videos = mutableListOf() + + + 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> { + + + 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>() + 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 { + 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(); + 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(); + + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/api/Pan123Handler.kt b/app/src/main/java/com/github/catvod/api/Pan123Handler.kt new file mode 100644 index 00000000..0e845ebd --- /dev/null +++ b/app/src/main/java/com/github/catvod/api/Pan123Handler.kt @@ -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) { + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/bean/pan123/Cache.java b/app/src/main/java/com/github/catvod/bean/pan123/Cache.java new file mode 100644 index 00000000..54081e50 --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/pan123/Cache.java @@ -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); + } + + +} diff --git a/app/src/main/java/com/github/catvod/bean/pan123/ShareInfo.kt b/app/src/main/java/com/github/catvod/bean/pan123/ShareInfo.kt new file mode 100644 index 00000000..9f24524b --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/pan123/ShareInfo.kt @@ -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 + ) \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/bean/pan123/User.java b/app/src/main/java/com/github/catvod/bean/pan123/User.java new file mode 100644 index 00000000..3d372e41 --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/pan123/User.java @@ -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 = ""; + + } +} diff --git a/app/src/main/java/com/github/catvod/spider/Cloud.java b/app/src/main/java/com/github/catvod/spider/Cloud.java index 769bfaf4..3e4d5f9e 100644 --- a/app/src/main/java/com/github/catvod/spider/Cloud.java +++ b/app/src/main/java/com/github/catvod/spider/Cloud.java @@ -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; @@ -19,11 +21,12 @@ import static com.github.catvod.api.TianyiApi.URL_START; */ public class Cloud extends Spider { private Quark quark = null; - /* private Ali ali = null; - private UC uc = null;*/ + /* private Ali ali = null; + private UC uc = null;*/ 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,43 +45,52 @@ 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 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); - } */else if (shareUrl.get(0).startsWith(TianyiApi.URL_START)) { + } */ else if (shareUrl.get(0).startsWith(TianyiApi.URL_START)) { 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)) { + } 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 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")) { return uc.playerContent(flag, id, vipFlags); - } */else if (flag.contains("天意")) { + } */ else if (flag.contains("天意")) { return tianYi.playerContent(flag, id, vipFlags); } else if (flag.contains("移动")) { 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,17 +102,19 @@ 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)); - } */else if (shareLink.startsWith(URL_START)) { + } */ else if (shareLink.startsWith(URL_START)) { 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,16 +126,19 @@ 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))); - } */else if (shareLink.startsWith(URL_START)) { + } */ else if (shareLink.startsWith(URL_START)) { 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)) { + } 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); diff --git a/app/src/main/java/com/github/catvod/spider/Pan123.java b/app/src/main/java/com/github/catvod/spider/Pan123.java new file mode 100644 index 00000000..9230d2b6 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/Pan123.java @@ -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 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 vipFlags) throws Exception { + return Pan123Api.INSTANCE.playerContent(id, flag); + + } + + /** + * 獲取詳情內容視頻播放來源(多 shared_link) + * + * @param ids share_link 集合 + * @param + * @return 詳情內容視頻播放來源 + */ + public String detailContentVodPlayFrom(List ids, int index) { + List 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 ids) throws Exception { + List 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); + } + + +} diff --git a/app/src/main/java/com/github/catvod/spider/Push.java b/app/src/main/java/com/github/catvod/spider/Push.java index c0b9387f..cdf55636 100644 --- a/app/src/main/java/com/github/catvod/spider/Push.java +++ b/app/src/main/java/com/github/catvod/spider/Push.java @@ -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 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 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) { diff --git a/app/src/main/java/com/github/catvod/utils/DownloadMT.kt b/app/src/main/java/com/github/catvod/utils/DownloadMT.kt index fd5c975e..d1425509 100644 --- a/app/src/main/java/com/github/catvod/utils/DownloadMT.kt +++ b/app/src/main/java/com/github/catvod/utils/DownloadMT.kt @@ -4,28 +4,22 @@ 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>(); - fun proxyMultiThread(url: String, headers: Map): Array? = - runBlocking { - proxyAsync(url, headers) - } + fun proxyMultiThread(url: String, headers: Map): Array? = runBlocking { + proxyAsync(url, headers) + } /** * 获取是否分片信息,顺带请求一个1MB块 @@ -52,11 +46,10 @@ object DownloadMT { if (info == null) { infos.clear() info = CoroutineScope(Dispatchers.IO).async { getInfo(url, headers) }.await() - infos[url] = info - /* //支持分片,先返回这个1MB块 - if (info[0] as Int == 206) { - return info - }*/ + infos[url] = info/* //支持分片,先返回这个1MB块 + if (info[0] as Int == 206) { + return info + }*/ } val code = info[0] as Int @@ -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, total: String): List { 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() diff --git a/app/src/main/java/com/github/catvod/utils/ProxyServer.kt b/app/src/main/java/com/github/catvod/utils/ProxyServer.kt index 85068922..87b8bbd2 100644 --- a/app/src/main/java/com/github/catvod/utils/ProxyServer.kt +++ b/app/src/main/java/com/github/catvod/utils/ProxyServer.kt @@ -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 diff --git a/app/src/test/java/Pan123Test.java b/app/src/test/java/Pan123Test.java new file mode 100644 index 00000000..233aeac7 --- /dev/null +++ b/app/src/test/java/Pan123Test.java @@ -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){ + + } + } +} \ No newline at end of file diff --git a/app/src/test/java/TgSearchTest.java b/app/src/test/java/TgSearchTest.java index e04462b8..94f616ed 100644 --- a/app/src/test/java/TgSearchTest.java +++ b/app/src/test/java/TgSearchTest.java @@ -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)); diff --git a/app/src/test/java/com/github/catvod/api/Pan123Test.kt b/app/src/test/java/com/github/catvod/api/Pan123Test.kt new file mode 100644 index 00000000..6032c384 --- /dev/null +++ b/app/src/test/java/com/github/catvod/api/Pan123Test.kt @@ -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 = 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 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>> result = pan123.processShareData("https://caiyun.139.com/w/i/2nQQVZWCR24yf"); + System.out.println(result); + for (String s : result.keySet()) { + for (Map 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); + } + } + //; + + + } + +*/ +} \ No newline at end of file diff --git a/build.bat b/build.bat index 93990eaf..d1162e2f 100644 --- a/build.bat +++ b/build.bat @@ -1,5 +1,5 @@ @echo off -call "%~dp0\gradlew" clean + call "%~dp0\gradlew" assembleRelease --no-daemon diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 5afd6461..0c04da05 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index 1464f26a..bc02a0ca 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -8a1cc4b31a331b1937bf6a449e94e4de +77ff0d77d6fccecddd174ee82161f3bd diff --git a/json/test.json b/json/test.json index d462e719..c47ff645 100644 --- a/json/test.json +++ b/json/test.json @@ -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": "电视直播",