mirror of
https://github.com/bizhangjie/CatVodSpider.git
synced 2025-10-25 17:12:17 +00:00
'第一版'
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.gradle
|
||||
.idea
|
||||
*build
|
||||
/local.properties
|
||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# CatVodSpider
|
||||
|
||||
### Based on CatVod
|
||||
|
||||
https://github.com/CatVodTVOfficial/CatVodTVSpider
|
||||
53
app/build.gradle
Normal file
53
app/build.gradle
Normal file
@@ -0,0 +1,53 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'ru.cleverpumpkin.proguard-dictionaries-generator'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.github.catvod.demo"
|
||||
minSdk 17
|
||||
targetSdk 28
|
||||
buildConfigField("String", "CLIENT_ID", "\"${clientId}\"")
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles 'proguard-rules.pro'
|
||||
proguardDictionaries {
|
||||
dictionaryNames = ["build/class-dictionary", "build/package-dictionary", "build/obfuscation-dictionary"]
|
||||
minLineLength 1
|
||||
maxLineLength 3
|
||||
linesCountInDictionary 100000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
namespace 'com.github.catvod'
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy {
|
||||
force 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
|
||||
implementation 'com.github.thegrizzlylabs:sardine-android:0.8'
|
||||
implementation 'wang.harlon.quickjs:wrapper-android:0.21.1'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
implementation 'cn.wanghaomiao:JsoupXpath:2.5.1'
|
||||
implementation 'org.nanohttpd:nanohttpd:2.3.1'
|
||||
implementation 'com.google.zxing:core:3.3.0'
|
||||
implementation 'com.orhanobut:logger:2.2.0'
|
||||
implementation 'org.jsoup:jsoup:1.15.3'
|
||||
}
|
||||
53
app/proguard-rules.pro
vendored
Normal file
53
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# Merge
|
||||
-flattenpackagehierarchy com.github.catvod.spider.merge
|
||||
-dontwarn org.slf4j.impl.StaticLoggerBinder
|
||||
|
||||
# Spider
|
||||
-keep class com.github.catvod.js.* { *; }
|
||||
-keep class com.github.catvod.crawler.* { *; }
|
||||
-keep class com.github.catvod.spider.* { public <methods>; }
|
||||
-keep class com.github.catvod.parser.* { public <methods>; }
|
||||
|
||||
# AndroidX
|
||||
-keep class androidx.core.** { *; }
|
||||
|
||||
# Gson
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-dontwarn sun.misc.**
|
||||
-keep class com.google.gson.** { *; }
|
||||
-keep class * extends com.google.gson.TypeAdapter
|
||||
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||
-keep class * implements com.google.gson.JsonSerializer
|
||||
-keep class * implements com.google.gson.JsonDeserializer
|
||||
-keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName <fields>; }
|
||||
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
|
||||
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
|
||||
|
||||
# Nano
|
||||
-keep class fi.iki.elonen.** { *; }
|
||||
|
||||
# OkHttp
|
||||
-dontwarn okhttp3.**
|
||||
-keep class okio.** { *; }
|
||||
-keep class okhttp3.** { *; }
|
||||
|
||||
# Logger
|
||||
-keep class com.orhanobut.logger.** { *; }
|
||||
|
||||
# QuickJS
|
||||
-keep class com.whl.quickjs.** { *; }
|
||||
|
||||
# Sardine
|
||||
-keep class com.thegrizzlylabs.sardineandroid.** { *; }
|
||||
|
||||
# Smbj
|
||||
-keep class com.hierynomus.** { *; }
|
||||
-keep class net.engio.mbassy.** { *; }
|
||||
|
||||
# Zxing
|
||||
-keep class com.google.zxing.** { *; }
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
26
app/src/main/AndroidManifest.xml
Normal file
26
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.whl.quickjs.android" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:usesCleartextTraffic="true">
|
||||
|
||||
<activity
|
||||
android:name=".debug.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
659
app/src/main/java/com/github/catvod/api/AliYun.java
Normal file
659
app/src/main/java/com/github/catvod/api/AliYun.java
Normal file
@@ -0,0 +1,659 @@
|
||||
package com.github.catvod.api;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.net.UrlQuerySanitizer;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.github.catvod.BuildConfig;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Sub;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.ali.Cache;
|
||||
import com.github.catvod.bean.ali.Code;
|
||||
import com.github.catvod.bean.ali.Data;
|
||||
import com.github.catvod.bean.ali.Download;
|
||||
import com.github.catvod.bean.ali.Drive;
|
||||
import com.github.catvod.bean.ali.Item;
|
||||
import com.github.catvod.bean.ali.OAuth;
|
||||
import com.github.catvod.bean.ali.Preview;
|
||||
import com.github.catvod.bean.ali.Resp;
|
||||
import com.github.catvod.bean.ali.Share;
|
||||
import com.github.catvod.bean.ali.User;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.net.OkResult;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.spider.Proxy;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Notify;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.github.catvod.utils.ProxyVideo;
|
||||
import com.github.catvod.utils.QRCode;
|
||||
import com.github.catvod.utils.ResUtil;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import okhttp3.Response;
|
||||
|
||||
public class AliYun {
|
||||
|
||||
private final Map<String, Map<String, String>> m3u8MediaMap;
|
||||
private final Map<String, String> shareDownloadMap;
|
||||
private final Map<String, String> downloadMap;
|
||||
private final List<String> tempIds;
|
||||
private final ReentrantLock lock;
|
||||
private final Cache cache;
|
||||
private ScheduledExecutorService service;
|
||||
private String refreshToken;
|
||||
private AlertDialog dialog;
|
||||
private Share share;
|
||||
|
||||
private static class Loader {
|
||||
static volatile AliYun INSTANCE = new AliYun();
|
||||
}
|
||||
|
||||
public static AliYun get() {
|
||||
return Loader.INSTANCE;
|
||||
}
|
||||
|
||||
public File getCache() {
|
||||
return Path.tv("aliyun");
|
||||
}
|
||||
|
||||
private AliYun() {
|
||||
Init.checkPermission();
|
||||
lock = new ReentrantLock();
|
||||
tempIds = new ArrayList<>();
|
||||
downloadMap = new HashMap<>();
|
||||
m3u8MediaMap = new HashMap<>();
|
||||
shareDownloadMap = new HashMap<>();
|
||||
cache = Cache.objectFrom(Path.read(getCache()));
|
||||
}
|
||||
|
||||
public void setRefreshToken(String token) {
|
||||
this.refreshToken = token;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getHeader() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
headers.put("Referer", "https://www.aliyundrive.com/");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = getHeader();
|
||||
headers.put("x-share-token", share.getShareToken());
|
||||
headers.put("X-Canary", "client=Android,app=adrive,version=v4.3.1");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaderAuth() {
|
||||
HashMap<String, String> headers = getHeader();
|
||||
headers.put("x-share-token", share.getShareToken());
|
||||
headers.put("X-Canary", "client=Android,app=adrive,version=v4.3.1");
|
||||
if (cache.getUser().isAuthed()) headers.put("authorization", cache.getUser().getAuthorization());
|
||||
return headers;
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaderOpen() {
|
||||
HashMap<String, String> headers = getHeader();
|
||||
headers.put("authorization", cache.getOAuth().getAuthorization());
|
||||
return headers;
|
||||
}
|
||||
|
||||
private boolean alist(String url, JsonObject param) {
|
||||
String api = "https://api.xhofe.top/alist/ali_open/" + url;
|
||||
OkResult result = OkHttp.post(api, param.toString(), getHeader());
|
||||
SpiderDebug.log(result.getCode() + "," + api + "," + result.getBody());
|
||||
if (isManyRequest(result.getBody())) return false;
|
||||
cache.setOAuth(OAuth.objectFrom(result.getBody()));
|
||||
return true;
|
||||
}
|
||||
|
||||
private String post(String url, JsonObject param) {
|
||||
url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url;
|
||||
OkResult result = OkHttp.post(url, param.toString(), getHeader());
|
||||
SpiderDebug.log(result.getCode() + "," + url + "," + result.getBody());
|
||||
return result.getBody();
|
||||
}
|
||||
|
||||
private String auth(String url, String json, boolean retry) {
|
||||
url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url;
|
||||
OkResult result = OkHttp.post(url, json, url.contains("file/list") ? getHeaders() : getHeaderAuth());
|
||||
SpiderDebug.log(result.getCode() + "," + url + "," + result.getBody());
|
||||
if (retry && result.getCode() == 401 && refreshAccessToken()) return auth(url, json, false);
|
||||
if (retry && result.getCode() == 429) return auth(url, json, false);
|
||||
return result.getBody();
|
||||
}
|
||||
|
||||
private String oauth(String url, String json, boolean retry) {
|
||||
url = url.startsWith("https") ? url : "https://open.aliyundrive.com/adrive/v1.0/" + url;
|
||||
OkResult result = OkHttp.post(url, json, getHeaderOpen());
|
||||
SpiderDebug.log(result.getCode() + "," + url + "," + result.getBody());
|
||||
if (retry && (result.getCode() == 400 || result.getCode() == 401) && refreshOpenToken()) return oauth(url, json, false);
|
||||
return result.getBody();
|
||||
}
|
||||
|
||||
private boolean isManyRequest(String result) {
|
||||
if (!result.contains("Too Many Requests")) return false;
|
||||
Notify.show("洗洗睡吧,Too Many Requests。");
|
||||
cache.getOAuth().clean();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onTimeout() {
|
||||
stopService();
|
||||
return false;
|
||||
}
|
||||
|
||||
private void refreshShareToken(String shareId) {
|
||||
if (share != null && share.alive(shareId)) return;
|
||||
SpiderDebug.log("refreshShareToken...");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("share_id", shareId);
|
||||
param.addProperty("share_pwd", "");
|
||||
String json = post("v2/share_link/get_share_token", param);
|
||||
share = Share.objectFrom(json).setShareId(shareId).setTime();
|
||||
if (share.getShareToken().isEmpty()) Notify.show("來晚啦,該分享已失效。");
|
||||
}
|
||||
|
||||
private boolean refreshAccessToken() {
|
||||
try {
|
||||
SpiderDebug.log("refreshAccessToken...");
|
||||
JsonObject param = new JsonObject();
|
||||
String token = cache.getUser().getRefreshToken();
|
||||
if (token.isEmpty()) token = refreshToken;
|
||||
if (token != null && token.startsWith("http")) token = OkHttp.string(token).trim();
|
||||
param.addProperty("refresh_token", token);
|
||||
param.addProperty("grant_type", "refresh_token");
|
||||
String json = post("https://auth.aliyundrive.com/v2/account/token", param);
|
||||
cache.setUser(User.objectFrom(json));
|
||||
if (cache.getUser().getAccessToken().isEmpty()) throw new Exception(json);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
if (e instanceof TimeoutException) return onTimeout();
|
||||
cache.getUser().clean();
|
||||
e.printStackTrace();
|
||||
stopService();
|
||||
startFlow();
|
||||
return true;
|
||||
} finally {
|
||||
while (cache.getUser().getAccessToken().isEmpty()) SystemClock.sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
private void getDriveId() {
|
||||
SpiderDebug.log("Get Drive Id...");
|
||||
String json = auth("https://user.aliyundrive.com/v2/user/get", "{}", true);
|
||||
cache.setDrive(Drive.objectFrom(json));
|
||||
}
|
||||
|
||||
private boolean oauthRequest() {
|
||||
SpiderDebug.log("OAuth Request...");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("authorize", 1);
|
||||
param.addProperty("scope", "user:base,file:all:read,file:all:write");
|
||||
String url = "https://open.aliyundrive.com/oauth/users/authorize?client_id=" + BuildConfig.CLIENT_ID + "&redirect_uri=https://alist.nn.ci/tool/aliyundrive/callback&scope=user:base,file:all:read,file:all:write&state=";
|
||||
String json = auth(url, param.toString(), true);
|
||||
return oauthRedirect(Code.objectFrom(json).getCode());
|
||||
}
|
||||
|
||||
private boolean oauthRedirect(String code) {
|
||||
SpiderDebug.log("OAuth Redirect...");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("code", code);
|
||||
param.addProperty("grant_type", "authorization_code");
|
||||
return alist("code", param);
|
||||
}
|
||||
|
||||
private boolean refreshOpenToken() {
|
||||
if (cache.getOAuth().getRefreshToken().isEmpty()) return oauthRequest();
|
||||
SpiderDebug.log("refreshOpenToken...");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("grant_type", "refresh_token");
|
||||
param.addProperty("refresh_token", cache.getOAuth().getRefreshToken());
|
||||
return alist("token", param);
|
||||
}
|
||||
|
||||
public Vod getVod(String url, String shareId, String fileId) {
|
||||
refreshShareToken(shareId);
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("share_id", shareId);
|
||||
Share share = Share.objectFrom(post("adrive/v3/share_link/get_share_by_anonymous", param));
|
||||
List<Item> files = new ArrayList<>();
|
||||
List<Item> subs = new ArrayList<>();
|
||||
listFiles(shareId, new Item(getParentFileId(fileId, share)), files, subs);
|
||||
Collections.sort(files);
|
||||
List<String> playFrom = Arrays.asList("轉存原畫", "分享原畫", "代理普畫");
|
||||
List<String> episode = new ArrayList<>();
|
||||
List<String> playUrl = new ArrayList<>();
|
||||
for (Item file : files) episode.add(file.getDisplayName() + "$" + shareId + "+" + file.getFileId() + findSubs(file.getName(), subs));
|
||||
for (int i = 0; i < playFrom.size(); i++) playUrl.add(TextUtils.join("#", episode));
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(url);
|
||||
vod.setVodContent(url);
|
||||
vod.setVodPic(share.getAvatar());
|
||||
vod.setVodName(share.getShareName());
|
||||
vod.setVodPlayUrl(TextUtils.join("$$$", playUrl));
|
||||
vod.setVodPlayFrom(TextUtils.join("$$$", playFrom));
|
||||
vod.setTypeName("阿里雲盤");
|
||||
return vod;
|
||||
}
|
||||
|
||||
private void listFiles(String shareId, Item folder, List<Item> files, List<Item> subs) {
|
||||
listFiles(shareId, folder, files, subs, "");
|
||||
}
|
||||
|
||||
private void listFiles(String shareId, Item parent, List<Item> files, List<Item> subs, String marker) {
|
||||
List<Item> folders = new ArrayList<>();
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("limit", 200);
|
||||
param.addProperty("share_id", shareId);
|
||||
param.addProperty("parent_file_id", parent.getFileId());
|
||||
param.addProperty("order_by", "name");
|
||||
param.addProperty("order_direction", "ASC");
|
||||
if (marker.length() > 0) param.addProperty("marker", marker);
|
||||
Item item = Item.objectFrom(auth("adrive/v3/file/list", param.toString(), true));
|
||||
for (Item file : item.getItems()) {
|
||||
if (file.getType().equals("folder")) {
|
||||
folders.add(file);
|
||||
} else if (file.getCategory().equals("video") || file.getCategory().equals("audio")) {
|
||||
files.add(file.parent(parent.getName()));
|
||||
} else if (Util.isSub(file.getExt())) {
|
||||
subs.add(file);
|
||||
}
|
||||
}
|
||||
if (item.getNextMarker().length() > 0) {
|
||||
listFiles(shareId, parent, files, subs, item.getNextMarker());
|
||||
}
|
||||
for (Item folder : folders) {
|
||||
listFiles(shareId, folder, files, subs);
|
||||
}
|
||||
}
|
||||
|
||||
private String getParentFileId(String fileId, Share share) {
|
||||
if (!TextUtils.isEmpty(fileId)) return fileId;
|
||||
if (share.getFileInfos().isEmpty()) return "";
|
||||
Item item = share.getFileInfos().get(0);
|
||||
return item.getType().equals("folder") ? item.getFileId() : "root";
|
||||
}
|
||||
|
||||
private void pair(String name1, List<Item> items, List<Item> subs) {
|
||||
for (Item item : items) {
|
||||
String name2 = Util.removeExt(item.getName()).toLowerCase();
|
||||
if (name1.contains(name2) || name2.contains(name1)) subs.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private String findSubs(String name1, List<Item> items) {
|
||||
List<Item> subs = new ArrayList<>();
|
||||
pair(Util.removeExt(name1).toLowerCase(), items, subs);
|
||||
if (subs.isEmpty()) subs.addAll(items);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Item sub : subs) sb.append("+").append(Util.removeExt(sub.getName())).append("@@@").append(sub.getExt()).append("@@@").append(sub.getFileId());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public List<Sub> getSubs(String[] ids) {
|
||||
List<Sub> sub = new ArrayList<>();
|
||||
for (String text : ids) {
|
||||
if (!text.contains("@@@")) continue;
|
||||
String[] split = text.split("@@@");
|
||||
String name = split[0];
|
||||
String ext = split[1];
|
||||
String url = Proxy.getUrl() + "?do=ali&type=sub&shareId=" + ids[0] + "&fileId=" + split[2];
|
||||
sub.add(Sub.create().name(name).ext(ext).url(url));
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
|
||||
public String getShareDownloadUrl(String shareId, String fileId) {
|
||||
try {
|
||||
if (shareDownloadMap.containsKey(fileId) && shareDownloadMap.get(fileId) != null && !isExpire(shareDownloadMap.get(fileId))) return shareDownloadMap.get(fileId);
|
||||
refreshShareToken(shareId);
|
||||
SpiderDebug.log("getShareDownloadUrl..." + fileId);
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", fileId);
|
||||
param.addProperty("share_id", shareId);
|
||||
param.addProperty("expire_sec", 600);
|
||||
String json = auth("v2/file/get_share_link_download_url", param.toString(), false);
|
||||
String url = Json.parse(json).getAsJsonObject().get("download_url").getAsString();
|
||||
shareDownloadMap.put(fileId, url);
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String getDownloadUrl(String shareId, String fileId) {
|
||||
try {
|
||||
if (downloadMap.containsKey(fileId) && downloadMap.get(fileId) != null && !isExpire(downloadMap.get(fileId))) return downloadMap.get(fileId);
|
||||
refreshShareToken(shareId);
|
||||
SpiderDebug.log("getDownloadUrl..." + fileId);
|
||||
tempIds.add(0, copy(shareId, fileId));
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", tempIds.get(0));
|
||||
param.addProperty("drive_id", cache.getDrive().getDriveId());
|
||||
param.addProperty("expire_sec", 900);
|
||||
String json = oauth("openFile/getDownloadUrl", param.toString(), true);
|
||||
String url = Download.objectFrom(json).getUrl();
|
||||
downloadMap.put(fileId, url);
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
} finally {
|
||||
Init.execute(this::deleteAll);
|
||||
}
|
||||
}
|
||||
|
||||
public Preview.Info getVideoPreviewPlayInfo(String shareId, String fileId) {
|
||||
try {
|
||||
refreshShareToken(shareId);
|
||||
SpiderDebug.log("getVideoPreviewPlayInfo..." + fileId);
|
||||
tempIds.add(0, copy(shareId, fileId));
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", tempIds.get(0));
|
||||
param.addProperty("drive_id", cache.getDrive().getDriveId());
|
||||
param.addProperty("category", "live_transcoding");
|
||||
param.addProperty("url_expire_sec", 900);
|
||||
String json = oauth("openFile/getVideoPreviewPlayInfo", param.toString(), true);
|
||||
return Preview.objectFrom(json).getVideoPreviewPlayInfo();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new Preview.Info();
|
||||
} finally {
|
||||
Init.execute(this::deleteAll);
|
||||
}
|
||||
}
|
||||
|
||||
public String playerContent(String[] ids, String flag) {
|
||||
if (flag.split("#")[0].equals("代理普畫")) {
|
||||
return getPreviewContent(ids);
|
||||
} else if (flag.split("#")[0].equals("轉存原畫")) {
|
||||
return Result.get().url(proxyVideoUrl("open", ids[0], ids[1])).octet().subs(getSubs(ids)).header(getHeader()).string();
|
||||
} else if (flag.split("#")[0].equals("分享原畫")) {
|
||||
return Result.get().url(proxyVideoUrl("share", ids[0], ids[1])).octet().subs(getSubs(ids)).header(getHeader()).string();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getPreviewContent(String[] ids) {
|
||||
Preview.Info info = getVideoPreviewPlayInfo(ids[0], ids[1]);
|
||||
List<String> url = getPreviewUrl(info, ids[0], ids[1], true);
|
||||
List<Sub> subs = getSubs(ids);
|
||||
subs.addAll(getSubs(info));
|
||||
return Result.get().url(url).m3u8().subs(subs).header(getHeader()).string();
|
||||
}
|
||||
|
||||
private List<String> getPreviewUrl(Preview.Info info, String shareId, String fileId, boolean proxy) {
|
||||
List<Preview.LiveTranscodingTask> tasks = info.getLiveTranscodingTaskList();
|
||||
List<String> url = new ArrayList<>();
|
||||
for (int i = tasks.size() - 1; i >= 0; i--) {
|
||||
url.add(tasks.get(i).getTemplateId());
|
||||
url.add(proxy ? proxyVideoUrl("preview", shareId, fileId, tasks.get(i).getTemplateId()) : tasks.get(i).getUrl());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private List<Sub> getSubs(Preview.Info info) {
|
||||
List<Sub> subs = new ArrayList<>();
|
||||
for (Preview.LiveTranscodingTask task : info.getLiveTranscodingSubtitleTaskList()) subs.add(task.getSub());
|
||||
return subs;
|
||||
}
|
||||
|
||||
private String copy(String shareId, String fileId) {
|
||||
if (cache.getDrive().getDriveId().isEmpty()) getDriveId();
|
||||
SpiderDebug.log("Copy..." + fileId);
|
||||
String json = "{\"requests\":[{\"body\":{\"file_id\":\"%s\",\"share_id\":\"%s\",\"auto_rename\":true,\"to_parent_file_id\":\"root\",\"to_drive_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"0\",\"method\":\"POST\",\"url\":\"/file/copy\"}],\"resource\":\"file\"}";
|
||||
json = String.format(json, fileId, shareId, cache.getDrive().getDriveId());
|
||||
Resp resp = Resp.objectFrom(auth("adrive/v2/batch", json, true));
|
||||
return resp.getResponse().getBody().getFileId();
|
||||
}
|
||||
|
||||
private void deleteAll() {
|
||||
List<String> ids = new ArrayList<>(tempIds);
|
||||
for (String id : ids) {
|
||||
boolean deleted = delete(id);
|
||||
if (deleted) tempIds.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean delete(String fileId) {
|
||||
SpiderDebug.log("Delete..." + fileId);
|
||||
String json = "{\"requests\":[{\"body\":{\"drive_id\":\"%s\",\"file_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"%s\",\"method\":\"POST\",\"url\":\"/file/delete\"}],\"resource\":\"file\"}";
|
||||
json = String.format(json, cache.getDrive().getDriveId(), fileId, fileId);
|
||||
Resp resp = Resp.objectFrom(auth("adrive/v2/batch", json, true));
|
||||
return resp.getResponse().getStatus() == 404;
|
||||
}
|
||||
|
||||
private String proxyVideoUrl(String cate, String shareId, String fileId) {
|
||||
return String.format(Proxy.getUrl() + "?do=ali&type=video&cate=%s&shareId=%s&fileId=%s", cate, shareId, fileId);
|
||||
}
|
||||
|
||||
private String proxyVideoUrl(String cate, String shareId, String fileId, String templateId) {
|
||||
return String.format(Proxy.getUrl() + "?do=ali&type=video&cate=%s&shareId=%s&fileId=%s&templateId=%s", cate, shareId, fileId, templateId);
|
||||
}
|
||||
|
||||
private String proxyVideoUrl(String cate, String shareId, String fileId, String templateId, String mediaId) {
|
||||
return String.format(Proxy.getUrl() + "?do=ali&type=video&cate=%s&shareId=%s&fileId=%s&templateId=%s&mediaId=%s", cate, shareId, fileId, templateId, mediaId);
|
||||
}
|
||||
|
||||
private static boolean isExpire(String url) {
|
||||
String expires = new UrlQuerySanitizer(url).getValue("x-oss-expires");
|
||||
if (TextUtils.isEmpty(expires)) return false;
|
||||
return Long.parseLong(expires) - getTimeStamp() <= 60;
|
||||
}
|
||||
|
||||
private static long getTimeStamp() {
|
||||
return System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
public Object[] proxyVideo(Map<String, String> params) throws Exception {
|
||||
if (dialog != null && dialog.isShowing()) return null;
|
||||
String templateId = params.get("templateId");
|
||||
String shareId = params.get("shareId");
|
||||
String mediaId = params.get("mediaId");
|
||||
String fileId = params.get("fileId");
|
||||
String cate = params.get("cate");
|
||||
String downloadUrl = "";
|
||||
|
||||
if ("preview".equals(cate)) {
|
||||
return new Object[]{200, "application/vnd.apple.mpegurl", new ByteArrayInputStream(getM3u8(shareId, fileId, templateId).getBytes())};
|
||||
}
|
||||
|
||||
if ("open".equals(cate)) {
|
||||
downloadUrl = getDownloadUrl(shareId, fileId);
|
||||
} else if ("share".equals(cate)) {
|
||||
downloadUrl = getShareDownloadUrl(shareId, fileId);
|
||||
} else if ("m3u8".equals(cate)) {
|
||||
lock.lock();
|
||||
String mediaUrl = m3u8MediaMap.get(fileId).get(mediaId);
|
||||
if (isExpire(mediaUrl)) {
|
||||
getM3u8(shareId, fileId, templateId);
|
||||
mediaUrl = m3u8MediaMap.get(fileId).get(mediaId);
|
||||
}
|
||||
lock.unlock();
|
||||
downloadUrl = mediaUrl;
|
||||
}
|
||||
|
||||
Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
for (String key : params.keySet()) {
|
||||
if (key.equals("referer") || key.equals("icy-metadata") || key.equals("range") || key.equals("connection") || key.equals("accept-encoding") || key.equals("user-agent")) {
|
||||
headers.put(key, params.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
return new Object[]{ProxyVideo.proxy(downloadUrl, headers)};
|
||||
}
|
||||
|
||||
private String getM3u8Url(String shareId, String fileId, String templateId) {
|
||||
Preview.Info info = getVideoPreviewPlayInfo(shareId, fileId);
|
||||
List<String> url = getPreviewUrl(info, shareId, fileId, false);
|
||||
Map<String, String> previewMap = new HashMap<>();
|
||||
for (int i = 0; i < url.size(); i = i + 2) {
|
||||
previewMap.put(url.get(i), url.get(i + 1));
|
||||
}
|
||||
return previewMap.get(templateId);
|
||||
}
|
||||
|
||||
private String getM3u8(String shareId, String fileId, String templateId) {
|
||||
String m3u8Url = getM3u8Url(shareId, fileId, templateId);
|
||||
String m3u8 = OkHttp.string(m3u8Url, getHeader());
|
||||
String[] m3u8Arr = m3u8.split("\n");
|
||||
List<String> listM3u8 = new ArrayList<>();
|
||||
Map<String, String> media = new HashMap<>();
|
||||
String site = m3u8Url.substring(0, m3u8Url.lastIndexOf("/")) + "/";
|
||||
int mediaId = 0;
|
||||
for (String oneLine : m3u8Arr) {
|
||||
String thisOne = oneLine;
|
||||
if (oneLine.contains("x-oss-expires")) {
|
||||
media.put(String.valueOf(mediaId), site + thisOne);
|
||||
thisOne = proxyVideoUrl("m3u8", shareId, fileId, templateId, String.valueOf(mediaId));
|
||||
mediaId++;
|
||||
}
|
||||
listM3u8.add(thisOne);
|
||||
}
|
||||
m3u8MediaMap.put(fileId, media);
|
||||
return TextUtils.join("\n", listM3u8);
|
||||
}
|
||||
|
||||
public Object[] proxySub(Map<String, String> params) throws Exception {
|
||||
String fileId = params.get("fileId");
|
||||
String shareId = params.get("shareId");
|
||||
Response res = OkHttp.newCall(getDownloadUrl(shareId, fileId), getHeaderAuth());
|
||||
byte[] body = Util.toUtf8(res.body().bytes());
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = "application/octet-stream";
|
||||
result[2] = new ByteArrayInputStream(body);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void startFlow() {
|
||||
Init.run(this::showInput);
|
||||
}
|
||||
|
||||
private void showInput() {
|
||||
try {
|
||||
int margin = ResUtil.dp2px(16);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
FrameLayout frame = new FrameLayout(Init.context());
|
||||
params.setMargins(margin, margin, margin, margin);
|
||||
EditText input = new EditText(Init.context());
|
||||
frame.addView(input, params);
|
||||
dialog = new AlertDialog.Builder(Init.getActivity()).setTitle("請輸入Token").setView(frame).setNeutralButton("QRCode", (dialog, which) -> onNeutral()).setNegativeButton(android.R.string.cancel, null).setPositiveButton(android.R.string.ok, (dialog, which) -> onPositive(input.getText().toString())).show();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private void onNeutral() {
|
||||
dismiss();
|
||||
Init.execute(this::getQRCode);
|
||||
}
|
||||
|
||||
private void onPositive(String text) {
|
||||
dismiss();
|
||||
Init.execute(() -> {
|
||||
if (text.startsWith("http")) setToken(OkHttp.string(text));
|
||||
else setToken(text);
|
||||
});
|
||||
}
|
||||
|
||||
private void getQRCode() {
|
||||
String json = OkHttp.string("https://passport.aliyundrive.com/newlogin/qrcode/generate.do?appName=aliyun_drive&fromSite=52&appName=aliyun_drive&appEntrance=web&isMobile=false&lang=zh_CN&returnUrl=&bizParams=&_bx-v=2.2.3");
|
||||
Data data = Data.objectFrom(json).getContent().getData();
|
||||
Init.run(() -> openApp(json, data));
|
||||
}
|
||||
|
||||
private void openApp(String json, Data data) {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setClassName("com.alicloud.databox", "com.taobao.login4android.scan.QrScanActivity");
|
||||
intent.putExtra("key_scanParam", json);
|
||||
Init.getActivity().startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
showQRCode(data);
|
||||
} finally {
|
||||
Init.execute(() -> startService(data.getParams()));
|
||||
}
|
||||
}
|
||||
|
||||
private void showQRCode(Data data) {
|
||||
try {
|
||||
int size = ResUtil.dp2px(240);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size, size);
|
||||
ImageView image = new ImageView(Init.context());
|
||||
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
image.setImageBitmap(QRCode.getBitmap(data.getCodeContent(), size, 2));
|
||||
FrameLayout frame = new FrameLayout(Init.context());
|
||||
params.gravity = Gravity.CENTER;
|
||||
frame.addView(image, params);
|
||||
dialog = new AlertDialog.Builder(Init.getActivity()).setView(frame).setOnCancelListener(this::dismiss).setOnDismissListener(this::dismiss).show();
|
||||
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
Notify.show("請使用阿里雲盤 App 掃描二維碼");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private void startService(Map<String, String> params) {
|
||||
service = Executors.newScheduledThreadPool(1);
|
||||
service.scheduleAtFixedRate(() -> {
|
||||
String result = OkHttp.post("https://passport.aliyundrive.com/newlogin/qrcode/query.do?appName=aliyun_drive&fromSite=52&_bx-v=2.2.3", params);
|
||||
Data data = Data.objectFrom(result).getContent().getData();
|
||||
if (data.hasToken()) setToken(data.getToken());
|
||||
}, 1, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void setToken(String value) {
|
||||
cache.getUser().setRefreshToken(value);
|
||||
SpiderDebug.log("Token:" + value);
|
||||
Notify.show("Token:" + value);
|
||||
refreshAccessToken();
|
||||
stopService();
|
||||
}
|
||||
|
||||
private void stopService() {
|
||||
if (service != null) service.shutdownNow();
|
||||
Init.run(this::dismiss);
|
||||
}
|
||||
|
||||
private void dismiss(DialogInterface dialog) {
|
||||
stopService();
|
||||
}
|
||||
|
||||
private void dismiss() {
|
||||
try {
|
||||
if (dialog != null) dialog.dismiss();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
49
app/src/main/java/com/github/catvod/bean/Class.java
Normal file
49
app/src/main/java/com/github/catvod/bean/Class.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.github.catvod.bean;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class Class {
|
||||
|
||||
@SerializedName("type_id")
|
||||
private String typeId;
|
||||
@SerializedName("type_name")
|
||||
private String typeName;
|
||||
@SerializedName("type_flag")
|
||||
private String typeFlag;
|
||||
|
||||
public static List<Class> arrayFrom(String str) {
|
||||
Type listType = new TypeToken<List<Class>>() {}.getType();
|
||||
return new Gson().fromJson(str, listType);
|
||||
}
|
||||
|
||||
public Class(String typeId) {
|
||||
this(typeId, typeId);
|
||||
}
|
||||
|
||||
public Class(String typeId, String typeName) {
|
||||
this(typeId, typeName, null);
|
||||
}
|
||||
|
||||
public Class(String typeId, String typeName, String typeFlag) {
|
||||
this.typeId = typeId;
|
||||
this.typeName = typeName;
|
||||
this.typeFlag = typeFlag;
|
||||
}
|
||||
|
||||
public String getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Class)) return false;
|
||||
Class it = (Class) obj;
|
||||
return getTypeId().equals(it.getTypeId());
|
||||
}
|
||||
}
|
||||
39
app/src/main/java/com/github/catvod/bean/Filter.java
Normal file
39
app/src/main/java/com/github/catvod/bean/Filter.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.github.catvod.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Filter {
|
||||
|
||||
@SerializedName("key")
|
||||
private String key;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("value")
|
||||
private List<Value> value;
|
||||
|
||||
public Filter(String key, String name, List<Value> value) {
|
||||
this.key = key;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static class Value {
|
||||
|
||||
@SerializedName("n")
|
||||
private String n;
|
||||
@SerializedName("v")
|
||||
private String v;
|
||||
|
||||
public Value(String value) {
|
||||
this.n = value;
|
||||
this.v = value;
|
||||
}
|
||||
|
||||
public Value(String n, String v) {
|
||||
this.n = n;
|
||||
this.v = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
240
app/src/main/java/com/github/catvod/bean/Result.java
Normal file
240
app/src/main/java/com/github/catvod/bean/Result.java
Normal file
@@ -0,0 +1,240 @@
|
||||
package com.github.catvod.bean;
|
||||
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Result {
|
||||
|
||||
@SerializedName("class")
|
||||
private List<Class> classes;
|
||||
@SerializedName("list")
|
||||
private List<Vod> list;
|
||||
@SerializedName("filters")
|
||||
private LinkedHashMap<String, List<Filter>> filters;
|
||||
@SerializedName("header")
|
||||
private String header;
|
||||
@SerializedName("format")
|
||||
private String format;
|
||||
@SerializedName("danmaku")
|
||||
private String danmaku;
|
||||
@SerializedName("msg")
|
||||
private String msg;
|
||||
@SerializedName("url")
|
||||
private Object url;
|
||||
@SerializedName("subs")
|
||||
private List<Sub> subs;
|
||||
@SerializedName("parse")
|
||||
private int parse;
|
||||
@SerializedName("jx")
|
||||
private int jx;
|
||||
@SerializedName("page")
|
||||
private Integer page;
|
||||
@SerializedName("pagecount")
|
||||
private Integer pagecount;
|
||||
@SerializedName("limit")
|
||||
private Integer limit;
|
||||
@SerializedName("total")
|
||||
private Integer total;
|
||||
|
||||
public static Result objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Result.class);
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, List<Vod> list, LinkedHashMap<String, List<Filter>> filters) {
|
||||
return Result.get().classes(classes).vod(list).filters(filters).string();
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, List<Vod> list, JSONObject filters) {
|
||||
return Result.get().classes(classes).vod(list).filters(filters).string();
|
||||
}
|
||||
|
||||
public static String string(Integer page,Integer pagecount,Integer limit,Integer total,List<Vod> list){
|
||||
return Result.get().page(page,pagecount,limit,total).vod(list).string();
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, List<Vod> list, JsonElement filters) {
|
||||
return Result.get().classes(classes).vod(list).filters(filters).string();
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, LinkedHashMap<String, List<Filter>> filters) {
|
||||
return Result.get().classes(classes).filters(filters).string();
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, JsonElement filters) {
|
||||
return Result.get().classes(classes).filters(filters).string();
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, JSONObject filters) {
|
||||
return Result.get().classes(classes).filters(filters).string();
|
||||
}
|
||||
|
||||
public static String string(List<Class> classes, List<Vod> list) {
|
||||
return Result.get().classes(classes).vod(list).string();
|
||||
}
|
||||
|
||||
public static String string(List<Vod> list) {
|
||||
return Result.get().vod(list).string();
|
||||
}
|
||||
|
||||
public static String string(Vod item) {
|
||||
return Result.get().vod(item).string();
|
||||
}
|
||||
|
||||
public static String error(String msg) {
|
||||
return Result.get().vod(Collections.emptyList()).msg(msg).string();
|
||||
}
|
||||
|
||||
public static Result get() {
|
||||
return new Result();
|
||||
}
|
||||
|
||||
public Result classes(List<Class> classes) {
|
||||
this.classes = classes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result vod(List<Vod> list) {
|
||||
this.list = list;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result vod(Vod item) {
|
||||
this.list = Arrays.asList(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result filters(LinkedHashMap<String, List<Filter>> filters) {
|
||||
this.filters = filters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result filters(JSONObject object) {
|
||||
if (object == null) return this;
|
||||
Type listType = new TypeToken<LinkedHashMap<String, List<Filter>>>() {}.getType();
|
||||
this.filters = new Gson().fromJson(object.toString(), listType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result filters(JsonElement element) {
|
||||
if (element == null) return this;
|
||||
Type listType = new TypeToken<LinkedHashMap<String, List<Filter>>>() {}.getType();
|
||||
this.filters = new Gson().fromJson(element.toString(), listType);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result header(Map<String, String> header) {
|
||||
if (header.isEmpty()) return this;
|
||||
this.header = new Gson().toJson(header);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result chrome() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
header(header);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result parse() {
|
||||
this.parse = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result parse(int parse) {
|
||||
this.parse = parse;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result jx() {
|
||||
this.jx = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result url(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result url(List<String> url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result danmaku(String danmaku) {
|
||||
this.danmaku = danmaku;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result msg(String msg) {
|
||||
this.msg = msg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result format(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result subs(List<Sub> subs) {
|
||||
this.subs = subs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result dash() {
|
||||
this.format = "application/dash+xml";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result m3u8() {
|
||||
this.format = "application/x-mpegURL";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result rtsp() {
|
||||
this.format = "application/x-rtsp";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result octet() {
|
||||
this.format = "application/octet-stream";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result page() {
|
||||
return page(1, 1, 0, 1);
|
||||
}
|
||||
|
||||
public Result page(int page, int count, int limit, int total) {
|
||||
this.page = page > 0 ? page : Integer.MAX_VALUE;
|
||||
this.limit = limit > 0 ? limit : Integer.MAX_VALUE;
|
||||
this.total = total > 0 ? total : Integer.MAX_VALUE;
|
||||
this.pagecount = count > 0 ? count : Integer.MAX_VALUE;
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<Vod> getList() {
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
}
|
||||
|
||||
public String string() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().newBuilder().disableHtmlEscaping().create().toJson(this);
|
||||
}
|
||||
}
|
||||
51
app/src/main/java/com/github/catvod/bean/Sub.java
Normal file
51
app/src/main/java/com/github/catvod/bean/Sub.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.github.catvod.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Sub {
|
||||
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("lang")
|
||||
private String lang;
|
||||
@SerializedName("format")
|
||||
private String format;
|
||||
|
||||
public static Sub create() {
|
||||
return new Sub();
|
||||
}
|
||||
|
||||
public Sub name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sub url(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sub lang(String lang) {
|
||||
this.lang = lang;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sub format(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sub ext(String ext) {
|
||||
switch (ext) {
|
||||
case "vtt":
|
||||
return format("text/vtt");
|
||||
case "ass":
|
||||
case "ssa":
|
||||
return format("text/x-ssa");
|
||||
default:
|
||||
return format("application/x-subrip");
|
||||
}
|
||||
}
|
||||
}
|
||||
174
app/src/main/java/com/github/catvod/bean/Vod.java
Normal file
174
app/src/main/java/com/github/catvod/bean/Vod.java
Normal file
@@ -0,0 +1,174 @@
|
||||
package com.github.catvod.bean;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Vod {
|
||||
|
||||
@SerializedName("type_name")
|
||||
private String typeName;
|
||||
@SerializedName("vod_id")
|
||||
private String vodId;
|
||||
@SerializedName("vod_name")
|
||||
private String vodName;
|
||||
@SerializedName("vod_pic")
|
||||
private String vodPic;
|
||||
@SerializedName("vod_remarks")
|
||||
private String vodRemarks;
|
||||
@SerializedName("vod_year")
|
||||
private String vodYear;
|
||||
@SerializedName("vod_area")
|
||||
private String vodArea;
|
||||
@SerializedName("vod_actor")
|
||||
private String vodActor;
|
||||
@SerializedName("vod_director")
|
||||
private String vodDirector;
|
||||
@SerializedName("vod_content")
|
||||
private String vodContent;
|
||||
@SerializedName("vod_play_from")
|
||||
private String vodPlayFrom;
|
||||
@SerializedName("vod_play_url")
|
||||
private String vodPlayUrl;
|
||||
@SerializedName("vod_tag")
|
||||
private String vodTag;
|
||||
@SerializedName("style")
|
||||
private Style style;
|
||||
|
||||
public static Vod objectFrom(String str) {
|
||||
Vod item = new Gson().fromJson(str, Vod.class);
|
||||
return item == null ? new Vod() : item;
|
||||
}
|
||||
|
||||
public Vod() {
|
||||
}
|
||||
|
||||
public Vod(String vodId, String vodName, String vodPic) {
|
||||
setVodId(vodId);
|
||||
setVodName(vodName);
|
||||
setVodPic(vodPic);
|
||||
}
|
||||
|
||||
public Vod(String vodId, String vodName, String vodPic, String vodRemarks) {
|
||||
setVodId(vodId);
|
||||
setVodName(vodName);
|
||||
setVodPic(vodPic);
|
||||
setVodRemarks(vodRemarks);
|
||||
}
|
||||
|
||||
public Vod(String vodId, String vodName, String vodPic, String vodRemarks, Style style) {
|
||||
setVodId(vodId);
|
||||
setVodName(vodName);
|
||||
setVodPic(vodPic);
|
||||
setVodRemarks(vodRemarks);
|
||||
setStyle(style);
|
||||
}
|
||||
|
||||
public Vod(String vodId, String vodName, String vodPic, String vodRemarks, boolean folder) {
|
||||
setVodId(vodId);
|
||||
setVodName(vodName);
|
||||
setVodPic(vodPic);
|
||||
setVodRemarks(vodRemarks);
|
||||
setVodTag(folder ? "folder" : "file");
|
||||
}
|
||||
|
||||
public void setTypeName(String typeName) {
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public void setVodId(String vodId) {
|
||||
this.vodId = vodId;
|
||||
}
|
||||
|
||||
public void setVodName(String vodName) {
|
||||
this.vodName = vodName;
|
||||
}
|
||||
|
||||
public void setVodPic(String vodPic) {
|
||||
this.vodPic = vodPic;
|
||||
}
|
||||
|
||||
public void setVodRemarks(String vodRemarks) {
|
||||
this.vodRemarks = vodRemarks;
|
||||
}
|
||||
|
||||
public void setVodYear(String vodYear) {
|
||||
this.vodYear = vodYear;
|
||||
}
|
||||
|
||||
public void setVodArea(String vodArea) {
|
||||
this.vodArea = vodArea;
|
||||
}
|
||||
|
||||
public void setVodActor(String vodActor) {
|
||||
this.vodActor = vodActor;
|
||||
}
|
||||
|
||||
public void setVodDirector(String vodDirector) {
|
||||
this.vodDirector = vodDirector;
|
||||
}
|
||||
|
||||
public void setVodContent(String vodContent) {
|
||||
this.vodContent = vodContent;
|
||||
}
|
||||
|
||||
public String getVodContent() {
|
||||
return vodContent;
|
||||
}
|
||||
|
||||
public void setVodPlayFrom(String vodPlayFrom) {
|
||||
this.vodPlayFrom = vodPlayFrom;
|
||||
}
|
||||
|
||||
public void setVodPlayUrl(String vodPlayUrl) {
|
||||
this.vodPlayUrl = vodPlayUrl;
|
||||
}
|
||||
|
||||
public String getVodPlayUrl() {
|
||||
return vodPlayUrl;
|
||||
}
|
||||
|
||||
public void setVodTag(String vodTag) {
|
||||
this.vodTag = vodTag;
|
||||
}
|
||||
|
||||
public void setStyle(Style style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public static class Style {
|
||||
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
@SerializedName("ratio")
|
||||
private Float ratio;
|
||||
|
||||
public static Style rect() {
|
||||
return rect(0.75f);
|
||||
}
|
||||
|
||||
public static Style rect(float ratio) {
|
||||
return new Style("rect", ratio);
|
||||
}
|
||||
|
||||
public static Style oval() {
|
||||
return new Style("oval", 1.0f);
|
||||
}
|
||||
|
||||
public static Style full() {
|
||||
return new Style("full");
|
||||
}
|
||||
|
||||
public static Style list() {
|
||||
return new Style("list");
|
||||
}
|
||||
|
||||
public Style(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Style(String type, Float ratio) {
|
||||
this.type = type;
|
||||
this.ratio = ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
app/src/main/java/com/github/catvod/bean/ali/Biz.java
Normal file
66
app/src/main/java/com/github/catvod/bean/ali/Biz.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Biz {
|
||||
|
||||
@SerializedName("pds_login_result")
|
||||
private Biz pdsLoginResult;
|
||||
@SerializedName("role")
|
||||
private String role;
|
||||
@SerializedName("isFirstLogin")
|
||||
private Boolean isFirstLogin;
|
||||
@SerializedName("needLink")
|
||||
private Boolean needLink;
|
||||
@SerializedName("loginType")
|
||||
private String loginType;
|
||||
@SerializedName("nickName")
|
||||
private String nickName;
|
||||
@SerializedName("needRpVerify")
|
||||
private Boolean needRpVerify;
|
||||
@SerializedName("avatar")
|
||||
private String avatar;
|
||||
@SerializedName("accessToken")
|
||||
private String accessToken;
|
||||
@SerializedName("userName")
|
||||
private String userName;
|
||||
@SerializedName("userId")
|
||||
private String userId;
|
||||
@SerializedName("defaultDriveId")
|
||||
private String defaultDriveId;
|
||||
@SerializedName("existLink")
|
||||
private List<?> existLink;
|
||||
@SerializedName("expiresIn")
|
||||
private Integer expiresIn;
|
||||
@SerializedName("expireTime")
|
||||
private String expireTime;
|
||||
@SerializedName("requestId")
|
||||
private String requestId;
|
||||
@SerializedName("dataPinSetup")
|
||||
private Boolean dataPinSetup;
|
||||
@SerializedName("state")
|
||||
private String state;
|
||||
@SerializedName("tokenType")
|
||||
private String tokenType;
|
||||
@SerializedName("dataPinSaved")
|
||||
private Boolean dataPinSaved;
|
||||
@SerializedName("refreshToken")
|
||||
private String refreshToken;
|
||||
@SerializedName("status")
|
||||
private String status;
|
||||
|
||||
public static Biz objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Biz.class);
|
||||
}
|
||||
|
||||
public Biz getPdsLoginResult() {
|
||||
return pdsLoginResult;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
}
|
||||
58
app/src/main/java/com/github/catvod/bean/ali/Cache.java
Normal file
58
app/src/main/java/com/github/catvod/bean/ali/Cache.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import com.github.catvod.api.AliYun;
|
||||
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;
|
||||
@SerializedName("oauth")
|
||||
private OAuth oauth;
|
||||
@SerializedName("drive")
|
||||
private Drive drive;
|
||||
|
||||
public static Cache objectFrom(String str) {
|
||||
Cache item = new Gson().fromJson(str, Cache.class);
|
||||
return item == null ? new Cache() : item;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user == null ? new User() : user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public OAuth getOAuth() {
|
||||
return oauth == null ? new OAuth() : oauth;
|
||||
}
|
||||
|
||||
public void setOAuth(OAuth oauth) {
|
||||
this.oauth = oauth;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public Drive getDrive() {
|
||||
return drive == null ? new Drive() : drive;
|
||||
}
|
||||
|
||||
public void setDrive(Drive drive) {
|
||||
this.drive = drive;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
Init.execute(() -> Path.write(AliYun.get().getCache(), toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
24
app/src/main/java/com/github/catvod/bean/ali/Code.java
Normal file
24
app/src/main/java/com/github/catvod/bean/ali/Code.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Code {
|
||||
|
||||
@SerializedName("redirectUri")
|
||||
private String redirectUri;
|
||||
|
||||
public static Code objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Code.class);
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return TextUtils.isEmpty(redirectUri) ? "" : redirectUri;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return getRedirectUri().split("code=")[1];
|
||||
}
|
||||
}
|
||||
88
app/src/main/java/com/github/catvod/bean/ali/Data.java
Normal file
88
app/src/main/java/com/github/catvod/bean/ali/Data.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Data {
|
||||
|
||||
@SerializedName("data")
|
||||
private Data data;
|
||||
@SerializedName("content")
|
||||
private Data content;
|
||||
@SerializedName("t")
|
||||
private String t;
|
||||
@SerializedName("ck")
|
||||
private String ck;
|
||||
@SerializedName("codeContent")
|
||||
private String codeContent;
|
||||
@SerializedName("qrCodeStatus")
|
||||
private String qrCodeStatus;
|
||||
@SerializedName("bizExt")
|
||||
private String bizExt;
|
||||
|
||||
public static Data objectFrom(String str) {
|
||||
try {
|
||||
Data data = new Gson().fromJson(str, Data.class);
|
||||
return data == null ? new Data() : data;
|
||||
} catch (Exception e) {
|
||||
return new Data();
|
||||
}
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data == null ? new Data() : data;
|
||||
}
|
||||
|
||||
public Data getContent() {
|
||||
return content == null ? new Data() : content;
|
||||
}
|
||||
|
||||
public String getT() {
|
||||
return t == null ? "" : t;
|
||||
}
|
||||
|
||||
public String getCk() {
|
||||
return ck == null ? "" : ck;
|
||||
}
|
||||
|
||||
public String getCodeContent() {
|
||||
return codeContent == null ? "" : codeContent;
|
||||
}
|
||||
|
||||
public String getQrCodeStatus() {
|
||||
return qrCodeStatus == null ? "" : qrCodeStatus;
|
||||
}
|
||||
|
||||
public String getBizExt() {
|
||||
return bizExt == null ? "" : bizExt;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return Biz.objectFrom(new String(Base64.decode(getBizExt(), Base64.DEFAULT))).getPdsLoginResult().getRefreshToken();
|
||||
}
|
||||
|
||||
public boolean hasToken() {
|
||||
return getQrCodeStatus().equals("CONFIRMED") && getBizExt().length() > 0;
|
||||
}
|
||||
|
||||
public Map<String, String> getParams() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("t", getT());
|
||||
params.put("ck", getCk());
|
||||
params.put("appName", "aliyun_drive");
|
||||
params.put("appEntrance", "web");
|
||||
params.put("isMobile", "false");
|
||||
params.put("lang", "zh_CN");
|
||||
params.put("returnUrl", "");
|
||||
params.put("fromSite", "52");
|
||||
params.put("bizParams", "");
|
||||
params.put("navlanguage", "zh-CN");
|
||||
params.put("navPlatform", "MacIntel");
|
||||
return params;
|
||||
}
|
||||
}
|
||||
32
app/src/main/java/com/github/catvod/bean/ali/Download.java
Normal file
32
app/src/main/java/com/github/catvod/bean/ali/Download.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Download {
|
||||
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
@SerializedName("file_id")
|
||||
private String fileId;
|
||||
@SerializedName("expiration")
|
||||
private String expiration;
|
||||
|
||||
public static Download objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Download.class);
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return TextUtils.isEmpty(url) ? "" : url;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return TextUtils.isEmpty(fileId) ? "" : fileId;
|
||||
}
|
||||
|
||||
public String getExpiration() {
|
||||
return TextUtils.isEmpty(expiration) ? "" : expiration;
|
||||
}
|
||||
}
|
||||
31
app/src/main/java/com/github/catvod/bean/ali/Drive.java
Normal file
31
app/src/main/java/com/github/catvod/bean/ali/Drive.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Drive {
|
||||
|
||||
@SerializedName("default_drive_id")
|
||||
private String defaultDriveId;
|
||||
@SerializedName("resource_drive_id")
|
||||
private String resourceDriveId;
|
||||
|
||||
public static Drive objectFrom(String str) {
|
||||
Drive item = new Gson().fromJson(str, Drive.class);
|
||||
return item == null ? new Drive() : item;
|
||||
}
|
||||
|
||||
private String getDefaultDriveId() {
|
||||
return TextUtils.isEmpty(defaultDriveId) ? "" : defaultDriveId;
|
||||
}
|
||||
|
||||
private String getResourceDriveId() {
|
||||
return TextUtils.isEmpty(resourceDriveId) ? "" : resourceDriveId;
|
||||
}
|
||||
|
||||
public String getDriveId() {
|
||||
return getResourceDriveId().isEmpty() ? getDefaultDriveId() : getResourceDriveId();
|
||||
}
|
||||
}
|
||||
97
app/src/main/java/com/github/catvod/bean/ali/Item.java
Normal file
97
app/src/main/java/com/github/catvod/bean/ali/Item.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Item implements Comparable<Item> {
|
||||
|
||||
@SerializedName("items")
|
||||
private List<Item> items;
|
||||
@SerializedName("next_marker")
|
||||
private String nextMarker;
|
||||
@SerializedName("file_id")
|
||||
private String fileId;
|
||||
@SerializedName("share_id")
|
||||
private String shareId;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
@SerializedName("file_extension")
|
||||
private String fileExtension;
|
||||
@SerializedName("category")
|
||||
private String category;
|
||||
@SerializedName("size")
|
||||
private double size;
|
||||
@SerializedName("parent")
|
||||
private String parent;
|
||||
|
||||
public static Item objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Item.class);
|
||||
}
|
||||
|
||||
public Item(String fileId) {
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
public List<Item> getItems() {
|
||||
return items == null ? Collections.emptyList() : items;
|
||||
}
|
||||
|
||||
public String getNextMarker() {
|
||||
return TextUtils.isEmpty(nextMarker) ? "" : nextMarker;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return TextUtils.isEmpty(fileId) ? "" : fileId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return TextUtils.isEmpty(type) ? "" : type;
|
||||
}
|
||||
|
||||
public String getExt() {
|
||||
return TextUtils.isEmpty(fileExtension) ? "" : fileExtension;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return TextUtils.isEmpty(category) ? "" : category;
|
||||
}
|
||||
|
||||
public String getSize() {
|
||||
return size == 0 ? "" : "[" + Util.getSize(size) + "]";
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
return TextUtils.isEmpty(parent) ? "" : "[" + parent + "]";
|
||||
}
|
||||
|
||||
public Item parent(String parent) {
|
||||
this.parent = parent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return TextUtils.join(" ", Arrays.asList(getParent(), getName(), getSize())).trim();
|
||||
}
|
||||
|
||||
public String getSortName() {
|
||||
return TextUtils.join(" ", Arrays.asList(getParent(), Util.getDigit(getName()))).trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Item item) {
|
||||
return getSortName().compareTo(item.getSortName());
|
||||
}
|
||||
}
|
||||
42
app/src/main/java/com/github/catvod/bean/ali/OAuth.java
Normal file
42
app/src/main/java/com/github/catvod/bean/ali/OAuth.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class OAuth {
|
||||
|
||||
@SerializedName("token_type")
|
||||
private String tokenType;
|
||||
@SerializedName("access_token")
|
||||
private String accessToken;
|
||||
@SerializedName("refresh_token")
|
||||
private String refreshToken;
|
||||
|
||||
public static OAuth objectFrom(String str) {
|
||||
OAuth item = new Gson().fromJson(str, OAuth.class);
|
||||
return item == null ? new OAuth() : item;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return TextUtils.isEmpty(tokenType) ? "" : tokenType;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return TextUtils.isEmpty(accessToken) ? "" : accessToken;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return TextUtils.isEmpty(refreshToken) ? "" : refreshToken;
|
||||
}
|
||||
|
||||
public String getAuthorization() {
|
||||
return getTokenType() + " " + getAccessToken();
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
this.refreshToken = "";
|
||||
this.accessToken = "";
|
||||
}
|
||||
}
|
||||
84
app/src/main/java/com/github/catvod/bean/ali/Preview.java
Normal file
84
app/src/main/java/com/github/catvod/bean/ali/Preview.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Sub;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Preview {
|
||||
|
||||
@SerializedName("video_preview_play_info")
|
||||
private Info videoPreviewPlayInfo;
|
||||
@SerializedName("drive_id")
|
||||
private String driveId;
|
||||
@SerializedName("file_id")
|
||||
private String fileId;
|
||||
|
||||
public static Preview objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Preview.class);
|
||||
}
|
||||
|
||||
public Info getVideoPreviewPlayInfo() {
|
||||
return videoPreviewPlayInfo == null ? new Info() : videoPreviewPlayInfo;
|
||||
}
|
||||
|
||||
public String getDriveId() {
|
||||
return TextUtils.isEmpty(driveId) ? "" : driveId;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return TextUtils.isEmpty(fileId) ? "" : fileId;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
|
||||
@SerializedName("live_transcoding_task_list")
|
||||
private List<LiveTranscodingTask> liveTranscodingTaskList;
|
||||
@SerializedName("live_transcoding_subtitle_task_list")
|
||||
private List<LiveTranscodingTask> liveTranscodingSubtitleTaskList;
|
||||
|
||||
public List<LiveTranscodingTask> getLiveTranscodingTaskList() {
|
||||
return liveTranscodingTaskList == null ? Collections.emptyList() : liveTranscodingTaskList;
|
||||
}
|
||||
|
||||
public List<LiveTranscodingTask> getLiveTranscodingSubtitleTaskList() {
|
||||
return liveTranscodingSubtitleTaskList == null ? Collections.emptyList() : liveTranscodingSubtitleTaskList;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LiveTranscodingTask {
|
||||
|
||||
@SerializedName("template_id")
|
||||
private String templateId;
|
||||
@SerializedName("language")
|
||||
private String language;
|
||||
@SerializedName("status")
|
||||
private String status;
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
|
||||
public String getTemplateId() {
|
||||
return TextUtils.isEmpty(templateId) ? "" : templateId;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return TextUtils.isEmpty(language) ? "" : language;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return TextUtils.isEmpty(status) ? "" : status;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return TextUtils.isEmpty(url) ? "" : url;
|
||||
}
|
||||
|
||||
public Sub getSub() {
|
||||
return Sub.create().url(getUrl()).name(getLanguage()).lang(getLanguage()).ext("vtt");
|
||||
}
|
||||
}
|
||||
}
|
||||
79
app/src/main/java/com/github/catvod/bean/ali/Resp.java
Normal file
79
app/src/main/java/com/github/catvod/bean/ali/Resp.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Resp {
|
||||
|
||||
@SerializedName("responses")
|
||||
private List<Resp> responses;
|
||||
@SerializedName("body")
|
||||
private Body body;
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
@SerializedName("status")
|
||||
private int status;
|
||||
|
||||
public static Resp objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Resp.class);
|
||||
}
|
||||
|
||||
public List<Resp> getResponses() {
|
||||
return responses == null ? Collections.emptyList() : responses;
|
||||
}
|
||||
|
||||
public Resp getResponse() {
|
||||
return getResponses().isEmpty() ? new Resp() : getResponses().get(0);
|
||||
}
|
||||
|
||||
public Body getBody() {
|
||||
return body == null ? new Body() : body;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return TextUtils.isEmpty(id) ? "" : id;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static class Body {
|
||||
|
||||
@SerializedName("domain_id")
|
||||
private String domainId;
|
||||
@SerializedName("drive_id")
|
||||
private String driveId;
|
||||
@SerializedName("file_id")
|
||||
private String fileId;
|
||||
@SerializedName("code")
|
||||
private String code;
|
||||
@SerializedName("message")
|
||||
private String message;
|
||||
|
||||
public String getDomainId() {
|
||||
return TextUtils.isEmpty(domainId) ? "" : domainId;
|
||||
}
|
||||
|
||||
public String getDriveId() {
|
||||
return TextUtils.isEmpty(driveId) ? "" : driveId;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return TextUtils.isEmpty(fileId) ? "" : fileId;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return TextUtils.isEmpty(code) ? "" : code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return TextUtils.isEmpty(message) ? "" : message;
|
||||
}
|
||||
}
|
||||
}
|
||||
130
app/src/main/java/com/github/catvod/bean/ali/Share.java
Normal file
130
app/src/main/java/com/github/catvod/bean/ali/Share.java
Normal file
@@ -0,0 +1,130 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Share {
|
||||
|
||||
@SerializedName("share_id")
|
||||
private String shareId;
|
||||
@SerializedName("share_token")
|
||||
private String shareToken;
|
||||
@SerializedName("expire_time")
|
||||
private String expireTime;
|
||||
@SerializedName("expires_in")
|
||||
private int expiresIn;
|
||||
|
||||
@SerializedName("creator_id")
|
||||
private String creatorId;
|
||||
@SerializedName("creator_name")
|
||||
private String creatorName;
|
||||
@SerializedName("creator_phone")
|
||||
private String creatorPhone;
|
||||
@SerializedName("expiration")
|
||||
private String expiration;
|
||||
@SerializedName("updated_at")
|
||||
private String updatedAt;
|
||||
@SerializedName("vip")
|
||||
private String vip;
|
||||
@SerializedName("avatar")
|
||||
private String avatar;
|
||||
@SerializedName("share_name")
|
||||
private String shareName;
|
||||
@SerializedName("display_name")
|
||||
private String displayName;
|
||||
@SerializedName("share_title")
|
||||
private String shareTitle;
|
||||
@SerializedName("has_pwd")
|
||||
private boolean hasPwd;
|
||||
@SerializedName("file_infos")
|
||||
private List<Item> fileInfos;
|
||||
|
||||
private long time;
|
||||
|
||||
public static Share objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Share.class);
|
||||
}
|
||||
|
||||
public String getShareId() {
|
||||
return TextUtils.isEmpty(shareId) ? "" : shareId;
|
||||
}
|
||||
|
||||
public String getShareToken() {
|
||||
return TextUtils.isEmpty(shareToken) ? "" : shareToken;
|
||||
}
|
||||
|
||||
public String getExpireTime() {
|
||||
return TextUtils.isEmpty(expireTime) ? "" : expireTime;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public String getCreatorId() {
|
||||
return TextUtils.isEmpty(creatorId) ? "" : creatorId;
|
||||
}
|
||||
|
||||
public String getCreatorName() {
|
||||
return TextUtils.isEmpty(creatorName) ? "" : creatorName;
|
||||
}
|
||||
|
||||
public String getCreatorPhone() {
|
||||
return TextUtils.isEmpty(creatorPhone) ? "" : creatorPhone;
|
||||
}
|
||||
|
||||
public String getExpiration() {
|
||||
return TextUtils.isEmpty(expiration) ? "" : expiration;
|
||||
}
|
||||
|
||||
public String getUpdatedAt() {
|
||||
return TextUtils.isEmpty(updatedAt) ? "" : updatedAt;
|
||||
}
|
||||
|
||||
public String getVip() {
|
||||
return TextUtils.isEmpty(vip) ? "" : vip;
|
||||
}
|
||||
|
||||
public String getAvatar() {
|
||||
return TextUtils.isEmpty(avatar) ? "" : avatar;
|
||||
}
|
||||
|
||||
public String getShareName() {
|
||||
return TextUtils.isEmpty(shareName) ? "" : shareName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return TextUtils.isEmpty(displayName) ? "" : displayName;
|
||||
}
|
||||
|
||||
public String getShareTitle() {
|
||||
return TextUtils.isEmpty(shareTitle) ? "" : shareTitle;
|
||||
}
|
||||
|
||||
public boolean isHasPwd() {
|
||||
return hasPwd;
|
||||
}
|
||||
|
||||
public List<Item> getFileInfos() {
|
||||
return fileInfos == null ? Collections.emptyList() : fileInfos;
|
||||
}
|
||||
|
||||
public Share setTime() {
|
||||
this.time = System.currentTimeMillis() + 60 * 60 * 1000;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Share setShareId(String shareId) {
|
||||
this.shareId = shareId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean alive(String shareId) {
|
||||
return getShareId().equals(shareId) && System.currentTimeMillis() <= time;
|
||||
}
|
||||
}
|
||||
50
app/src/main/java/com/github/catvod/bean/ali/User.java
Normal file
50
app/src/main/java/com/github/catvod/bean/ali/User.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.github.catvod.bean.ali;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class User {
|
||||
|
||||
@SerializedName("token_type")
|
||||
private String tokenType;
|
||||
@SerializedName("access_token")
|
||||
private String accessToken;
|
||||
@SerializedName("refresh_token")
|
||||
private String refreshToken;
|
||||
|
||||
public static User objectFrom(String str) {
|
||||
User item = new Gson().fromJson(str, User.class);
|
||||
return item == null ? new User() : item;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return TextUtils.isEmpty(tokenType) ? "" : tokenType;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return TextUtils.isEmpty(accessToken) ? "" : accessToken;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return TextUtils.isEmpty(refreshToken) ? "" : refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public String getAuthorization() {
|
||||
return getTokenType() + " " + getAccessToken();
|
||||
}
|
||||
|
||||
public boolean isAuthed() {
|
||||
return getTokenType().length() > 0 && getAccessToken().length() > 0;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
this.refreshToken = "";
|
||||
this.accessToken = "";
|
||||
}
|
||||
}
|
||||
184
app/src/main/java/com/github/catvod/bean/alist/Drive.java
Normal file
184
app/src/main/java/com/github/catvod/bean/alist/Drive.java
Normal file
@@ -0,0 +1,184 @@
|
||||
package com.github.catvod.bean.alist;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Image;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Drive {
|
||||
|
||||
@SerializedName("drives")
|
||||
private List<Drive> drives;
|
||||
@SerializedName("params")
|
||||
private List<Param> params;
|
||||
@SerializedName("login")
|
||||
private Login login;
|
||||
@SerializedName("vodPic")
|
||||
private String vodPic;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("server")
|
||||
private String server;
|
||||
@SerializedName("version")
|
||||
private int version;
|
||||
@SerializedName("path")
|
||||
private String path;
|
||||
@SerializedName("token")
|
||||
private String token;
|
||||
@SerializedName("search")
|
||||
private Boolean search;
|
||||
@SerializedName("hidden")
|
||||
private Boolean hidden;
|
||||
|
||||
public static Drive objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Drive.class);
|
||||
}
|
||||
|
||||
public List<Drive> getDrives() {
|
||||
return drives == null ? new ArrayList<>() : drives;
|
||||
}
|
||||
|
||||
public List<Param> getParams() {
|
||||
return params == null ? new ArrayList<>() : params;
|
||||
}
|
||||
|
||||
public Login getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public Drive(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getVodPic() {
|
||||
return TextUtils.isEmpty(vodPic) ? Image.FOLDER : vodPic;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getServer() {
|
||||
return TextUtils.isEmpty(server) ? "" : server;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return TextUtils.isEmpty(path) ? "" : path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = TextUtils.isEmpty(path) ? "" : path;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return TextUtils.isEmpty(token) ? "" : token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public Boolean search() {
|
||||
return search == null || search;
|
||||
}
|
||||
|
||||
public Boolean hidden() {
|
||||
return hidden != null && hidden;
|
||||
}
|
||||
|
||||
public boolean isNew() {
|
||||
return getVersion() == 3;
|
||||
}
|
||||
|
||||
public Class toType() {
|
||||
return new Class(getName(), getName(), "1");
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return getServer().replace(getPath(), "");
|
||||
}
|
||||
|
||||
public String settingsApi() {
|
||||
return getHost() + "/api/public/settings";
|
||||
}
|
||||
|
||||
public String loginApi() {
|
||||
return getHost() + "/api/auth/login";
|
||||
}
|
||||
|
||||
public String listApi() {
|
||||
return getHost() + (isNew() ? "/api/fs/list" : "/api/public/path");
|
||||
}
|
||||
|
||||
public String getApi() {
|
||||
return getHost() + (isNew() ? "/api/fs/get" : "/api/public/path");
|
||||
}
|
||||
|
||||
public String searchApi() {
|
||||
return getHost() + (isNew() ? "/api/fs/search" : "/api/public/search");
|
||||
}
|
||||
|
||||
public String searchApi(String param) {
|
||||
return getHost() + "/search?box=" + param + "&url=&type=video";
|
||||
}
|
||||
|
||||
public Drive check() {
|
||||
if (path == null) setPath(Uri.parse(getServer()).getPath());
|
||||
if (version == 0) setVersion(OkHttp.string(settingsApi()).contains("v2.") ? 2 : 3);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String params(String keyword) {
|
||||
if (isNew()) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("keywords", keyword);
|
||||
params.put("page", 1);
|
||||
params.put("parent", "/");
|
||||
params.put("per_page", 100);
|
||||
return new Gson().toJson(params);
|
||||
} else {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("keyword", keyword);
|
||||
params.put("path", "/");
|
||||
return new Gson().toJson(params);
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<String, String> getHeader() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
if (!getToken().isEmpty()) headers.put("Authorization", token);
|
||||
return headers;
|
||||
}
|
||||
|
||||
public String findPass(String path) {
|
||||
for (Param param : getParams()) if (path.startsWith(param.getPath())) return param.getPass();
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Drive)) return false;
|
||||
Drive it = (Drive) obj;
|
||||
return getName().equals(it.getName());
|
||||
}
|
||||
}
|
||||
135
app/src/main/java/com/github/catvod/bean/alist/Item.java
Normal file
135
app/src/main/java/com/github/catvod/bean/alist/Item.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package com.github.catvod.bean.alist;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Item {
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName(value = "path", alternate = "parent")
|
||||
private String path;
|
||||
@SerializedName("type")
|
||||
private int type;
|
||||
@SerializedName("size")
|
||||
private long size;
|
||||
@SerializedName(value = "thumb", alternate = "thumbnail")
|
||||
private String thumb;
|
||||
@SerializedName(value = "url", alternate = "raw_url")
|
||||
private String url;
|
||||
@SerializedName(value = "modified", alternate = "updated_at")
|
||||
private String modified;
|
||||
|
||||
public static Item objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Item.class);
|
||||
}
|
||||
|
||||
public static List<Item> arrayFrom(String str) {
|
||||
Type listType = new TypeToken<List<Item>>() {}.getType();
|
||||
return new Gson().fromJson(str, listType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return TextUtils.isEmpty(path) ? "" : path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getThumb() {
|
||||
return TextUtils.isEmpty(thumb) ? "" : thumb;
|
||||
}
|
||||
|
||||
public void setThumb(String thumb) {
|
||||
this.thumb = thumb;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return TextUtils.isEmpty(url) ? "" : url.startsWith("//") ? "http:" + url : url;
|
||||
}
|
||||
|
||||
public String getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
try {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault());
|
||||
return format.parse(getModified());
|
||||
} catch (Exception e) {
|
||||
return new Date();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFolder() {
|
||||
return getType() == 1;
|
||||
}
|
||||
|
||||
public boolean isMedia(boolean isNew) {
|
||||
if (getName().endsWith(".ts") || getName().endsWith(".mpg")) return true;
|
||||
if (isNew) return getType() == 2 || getType() == 3;
|
||||
return getType() == 3 || getType() == 4;
|
||||
}
|
||||
|
||||
public boolean ignore(boolean isNew) {
|
||||
if (getName().endsWith(".ts") || getName().endsWith(".mpg")) return false;
|
||||
if (isNew) return getType() == 0 || getType() == 4;
|
||||
return getType() == 0 || getType() == 2 || getType() == 5;
|
||||
}
|
||||
|
||||
public String getExt() {
|
||||
return Util.getExt(getName());
|
||||
}
|
||||
|
||||
public String getVodId(String id) {
|
||||
return id + getPath() + "/" + getName();
|
||||
}
|
||||
|
||||
public String getPic(String pic) {
|
||||
return getThumb().isEmpty() && isFolder() ? pic : getThumb();
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return Util.getSize(getSize());
|
||||
}
|
||||
|
||||
public Vod getVod(String id, String pic) {
|
||||
return new Vod(getVodId(id), getName(), getPic(pic), getRemark(), isFolder());
|
||||
}
|
||||
|
||||
public Vod getVod(Drive drive, String pic) {
|
||||
return new Vod(getVodId(drive.getName()), getName(), getPic(pic), drive.getName(), isFolder());
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/github/catvod/bean/alist/Login.java
Normal file
21
app/src/main/java/com/github/catvod/bean/alist/Login.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.github.catvod.bean.alist;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Login {
|
||||
|
||||
@SerializedName("username")
|
||||
private String username;
|
||||
@SerializedName("password")
|
||||
private String password;
|
||||
|
||||
public String getUsername() {
|
||||
return TextUtils.isEmpty(username) ? "" : username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return TextUtils.isEmpty(password) ? "" : password;
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/github/catvod/bean/alist/Param.java
Normal file
21
app/src/main/java/com/github/catvod/bean/alist/Param.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.github.catvod.bean.alist;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Param {
|
||||
|
||||
@SerializedName("path")
|
||||
private String path;
|
||||
@SerializedName("pass")
|
||||
private String pass;
|
||||
|
||||
public String getPath() {
|
||||
return TextUtils.isEmpty(path) ? "" : path;
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return TextUtils.isEmpty(pass) ? "" : pass;
|
||||
}
|
||||
}
|
||||
35
app/src/main/java/com/github/catvod/bean/alist/Sorter.java
Normal file
35
app/src/main/java/com/github/catvod/bean/alist/Sorter.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.github.catvod.bean.alist;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class Sorter implements Comparator<Item> {
|
||||
|
||||
private final String type;
|
||||
private final String order;
|
||||
|
||||
public static void sort(String type, String order, List<Item> items) {
|
||||
Collections.sort(items, new Sorter(type, order));
|
||||
}
|
||||
|
||||
public Sorter(String type, String order) {
|
||||
this.type = type;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Item o1, Item o2) {
|
||||
boolean asc = order.equals("asc");
|
||||
switch (type) {
|
||||
case "name":
|
||||
return asc ? o1.getName().compareTo(o2.getName()) : o2.getName().compareTo(o1.getName());
|
||||
case "size":
|
||||
return asc ? Long.compare(o1.getSize(), o2.getSize()) : Long.compare(o2.getSize(), o1.getSize());
|
||||
case "date":
|
||||
return asc ? o1.getDate().compareTo(o2.getDate()) : o2.getDate().compareTo(o1.getDate());
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
app/src/main/java/com/github/catvod/bean/bili/Dash.java
Normal file
39
app/src/main/java/com/github/catvod/bean/bili/Dash.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Dash {
|
||||
|
||||
@SerializedName("duration")
|
||||
private String duration;
|
||||
@SerializedName("minBufferTime")
|
||||
private String minBufferTime;
|
||||
@SerializedName("video")
|
||||
private List<Media> video;
|
||||
@SerializedName("audio")
|
||||
private List<Media> audio;
|
||||
|
||||
public static Dash objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Dash.class);
|
||||
}
|
||||
|
||||
public String getDuration() {
|
||||
return duration == null ? "0" : duration;
|
||||
}
|
||||
|
||||
public String getMinBufferTime() {
|
||||
return minBufferTime == null ? "0" : minBufferTime;
|
||||
}
|
||||
|
||||
public List<Media> getVideo() {
|
||||
return video == null ? Collections.emptyList() : video;
|
||||
}
|
||||
|
||||
public List<Media> getAudio() {
|
||||
return audio == null ? Collections.emptyList() : audio;
|
||||
}
|
||||
}
|
||||
131
app/src/main/java/com/github/catvod/bean/bili/Data.java
Normal file
131
app/src/main/java/com/github/catvod/bean/bili/Data.java
Normal file
@@ -0,0 +1,131 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Data {
|
||||
|
||||
@SerializedName("result")
|
||||
private JsonElement result;
|
||||
@SerializedName("list")
|
||||
private JsonElement list;
|
||||
@SerializedName("isLogin")
|
||||
private Boolean isLogin;
|
||||
@SerializedName("vipStatus")
|
||||
private Integer vipStatus;
|
||||
@SerializedName("qrcode_key")
|
||||
private String qrcodeKey;
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
@SerializedName("aid")
|
||||
private String aid;
|
||||
@SerializedName("cid")
|
||||
private String cid;
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
@SerializedName("tname")
|
||||
private String tname;
|
||||
@SerializedName("pic")
|
||||
private String pic;
|
||||
@SerializedName("duration")
|
||||
private Long duration;
|
||||
@SerializedName("desc")
|
||||
private String desc;
|
||||
@SerializedName("accept_description")
|
||||
private List<String> acceptDescription;
|
||||
@SerializedName("accept_quality")
|
||||
private List<Integer> acceptQuality;
|
||||
@SerializedName("pages")
|
||||
private List<Page> pages;
|
||||
@SerializedName("dash")
|
||||
private Dash dash;
|
||||
@SerializedName("owner")
|
||||
private Owner owner;
|
||||
@SerializedName("wbi_img")
|
||||
private Wbi wbi;
|
||||
|
||||
public JsonElement getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public JsonElement getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public boolean isLogin() {
|
||||
return isLogin != null && isLogin;
|
||||
}
|
||||
|
||||
public Integer getVipStatus() {
|
||||
return vipStatus;
|
||||
}
|
||||
|
||||
public boolean isVip() {
|
||||
return vipStatus != null && vipStatus != 0;
|
||||
}
|
||||
|
||||
public String getQrcodeKey() {
|
||||
return TextUtils.isEmpty(qrcodeKey) ? "" : qrcodeKey;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return TextUtils.isEmpty(url) ? "" : url;
|
||||
}
|
||||
|
||||
public String getAid() {
|
||||
return TextUtils.isEmpty(aid) ? "" : aid;
|
||||
}
|
||||
|
||||
public String getCid() {
|
||||
return TextUtils.isEmpty(cid) ? "" : cid;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return TextUtils.isEmpty(title) ? "" : title;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return TextUtils.isEmpty(tname) ? "" : tname;
|
||||
}
|
||||
|
||||
public String getPic() {
|
||||
return TextUtils.isEmpty(pic) ? "" : pic;
|
||||
}
|
||||
|
||||
public Long getDuration() {
|
||||
return duration == null ? 0 : duration;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return TextUtils.isEmpty(desc) ? "" : desc;
|
||||
}
|
||||
|
||||
public List<String> getAcceptDescription() {
|
||||
return acceptDescription == null ? Collections.emptyList() : acceptDescription;
|
||||
}
|
||||
|
||||
public List<Integer> getAcceptQuality() {
|
||||
return acceptQuality == null ? Collections.emptyList() : acceptQuality;
|
||||
}
|
||||
|
||||
public List<Page> getPages() {
|
||||
return pages == null ? Collections.emptyList() : pages;
|
||||
}
|
||||
|
||||
public Dash getDash() {
|
||||
return dash == null ? new Dash() : dash;
|
||||
}
|
||||
|
||||
public Owner getOwner() {
|
||||
return owner == null ? new Owner() : owner;
|
||||
}
|
||||
|
||||
public Wbi getWbi() {
|
||||
return wbi == null ? new Wbi() : wbi;
|
||||
}
|
||||
}
|
||||
79
app/src/main/java/com/github/catvod/bean/bili/Media.java
Normal file
79
app/src/main/java/com/github/catvod/bean/bili/Media.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Media {
|
||||
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
@SerializedName("baseUrl")
|
||||
private String baseUrl;
|
||||
@SerializedName("bandwidth")
|
||||
private String bandwidth;
|
||||
@SerializedName("mimeType")
|
||||
private String mimeType;
|
||||
@SerializedName("codecs")
|
||||
private String codecs;
|
||||
@SerializedName("width")
|
||||
private String width;
|
||||
@SerializedName("height")
|
||||
private String height;
|
||||
@SerializedName("frameRate")
|
||||
private String frameRate;
|
||||
@SerializedName("sar")
|
||||
private String sar;
|
||||
@SerializedName("startWithSap")
|
||||
private String startWithSap;
|
||||
@SerializedName("SegmentBase")
|
||||
private Segment segmentBase;
|
||||
@SerializedName("codecid")
|
||||
private String codecid;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
public String getBandWidth() {
|
||||
return bandwidth;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public String getCodecs() {
|
||||
return codecs;
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public String getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public String getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
|
||||
public String getSar() {
|
||||
return sar;
|
||||
}
|
||||
|
||||
public String getStartWithSap() {
|
||||
return startWithSap;
|
||||
}
|
||||
|
||||
public Segment getSegmentBase() {
|
||||
return segmentBase;
|
||||
}
|
||||
|
||||
public String getCodecId() {
|
||||
return codecid;
|
||||
}
|
||||
}
|
||||
25
app/src/main/java/com/github/catvod/bean/bili/Owner.java
Normal file
25
app/src/main/java/com/github/catvod/bean/bili/Owner.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Owner {
|
||||
|
||||
@SerializedName("mid")
|
||||
private String mid;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
|
||||
public String getMid() {
|
||||
return TextUtils.isEmpty(mid) ? "" : mid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return String.format("[a=cr:{\"id\":\"%s\",\"name\":\"%s\"}/]%s[/a]", getMid() + "/{pg}", getName(), getName());
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/github/catvod/bean/bili/Page.java
Normal file
21
app/src/main/java/com/github/catvod/bean/bili/Page.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Page {
|
||||
|
||||
@SerializedName("cid")
|
||||
private String cid;
|
||||
@SerializedName("part")
|
||||
private String part;
|
||||
|
||||
public String getCid() {
|
||||
return TextUtils.isEmpty(cid) ? "" : cid;
|
||||
}
|
||||
|
||||
public String getPart() {
|
||||
return TextUtils.isEmpty(part) ? "" : part;
|
||||
}
|
||||
}
|
||||
86
app/src/main/java/com/github/catvod/bean/bili/Resp.java
Normal file
86
app/src/main/java/com/github/catvod/bean/bili/Resp.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class Resp {
|
||||
|
||||
@SerializedName("code")
|
||||
private Integer code;
|
||||
@SerializedName("message")
|
||||
private String message;
|
||||
@SerializedName("data")
|
||||
private Data data;
|
||||
|
||||
public static Resp objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Resp.class);
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data == null ? new Data() : data;
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
|
||||
@SerializedName("bvid")
|
||||
private String bvid;
|
||||
@SerializedName("aid")
|
||||
private String aid;
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
@SerializedName("pic")
|
||||
private String pic;
|
||||
@SerializedName("duration")
|
||||
private String duration;
|
||||
@SerializedName("length")
|
||||
private String length;
|
||||
|
||||
public static List<Result> arrayFrom(JsonElement str) {
|
||||
Type listType = new TypeToken<List<Result>>() {}.getType();
|
||||
return new Gson().fromJson(str, listType);
|
||||
}
|
||||
|
||||
public String getBvId() {
|
||||
return TextUtils.isEmpty(bvid) ? "" : bvid;
|
||||
}
|
||||
|
||||
public String getAid() {
|
||||
return TextUtils.isEmpty(aid) ? "" : aid;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return TextUtils.isEmpty(title) ? "" : title;
|
||||
}
|
||||
|
||||
public String getDuration() {
|
||||
return TextUtils.isEmpty(duration) ? getLength() : duration.split(":")[0] + "分鐘";
|
||||
}
|
||||
|
||||
public String getLength() {
|
||||
return TextUtils.isEmpty(length) ? "" : length;
|
||||
}
|
||||
|
||||
public String getPic() {
|
||||
return TextUtils.isEmpty(pic) ? "" : pic;
|
||||
}
|
||||
|
||||
public Vod getVod() {
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(getBvId() + "@" + getAid());
|
||||
vod.setVodName(Jsoup.parse(getTitle()).text());
|
||||
vod.setVodPic(getPic().startsWith("//") ? "https:" + getPic() : getPic());
|
||||
vod.setVodRemarks(getDuration());
|
||||
return vod;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
app/src/main/java/com/github/catvod/bean/bili/Segment.java
Normal file
19
app/src/main/java/com/github/catvod/bean/bili/Segment.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Segment {
|
||||
|
||||
@SerializedName("Initialization")
|
||||
private String initialization;
|
||||
@SerializedName("indexRange")
|
||||
private String indexRange;
|
||||
|
||||
public String getInitialization() {
|
||||
return initialization;
|
||||
}
|
||||
|
||||
public String getIndexRange() {
|
||||
return indexRange;
|
||||
}
|
||||
}
|
||||
47
app/src/main/java/com/github/catvod/bean/bili/Wbi.java
Normal file
47
app/src/main/java/com/github/catvod/bean/bili/Wbi.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.github.catvod.bean.bili;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class Wbi {
|
||||
|
||||
private final int[] mixinKeyEncTab = new int[]{46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52};
|
||||
|
||||
@SerializedName("img_url")
|
||||
private String imgUrl;
|
||||
@SerializedName("sub_url")
|
||||
private String subUrl;
|
||||
|
||||
public String getImgUrl() {
|
||||
return TextUtils.isEmpty(imgUrl) ? "" : imgUrl;
|
||||
}
|
||||
|
||||
public String getSubUrl() {
|
||||
return TextUtils.isEmpty(subUrl) ? "" : subUrl;
|
||||
}
|
||||
|
||||
private String getMixinKey(String imgKey, String subKey) {
|
||||
String s = imgKey + subKey;
|
||||
StringBuilder key = new StringBuilder();
|
||||
for (int i = 0; i < 32; i++) key.append(s.charAt(mixinKeyEncTab[i]));
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
public String getQuery(LinkedHashMap<String, Object> params) {
|
||||
String imgKey = Uri.parse(getImgUrl()).getLastPathSegment().split("\\.")[0];
|
||||
String subKey = Uri.parse(getSubUrl()).getLastPathSegment().split("\\.")[0];
|
||||
String mixinKey = getMixinKey(imgKey, subKey);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
params.put("wts", System.currentTimeMillis() / 1000);
|
||||
for (String key : params.keySet()) sb.append(key).append("=").append(URLEncoder.encode(params.get(key).toString())).append("&");
|
||||
String query = Util.substring(sb.toString());
|
||||
String w_rid = Util.MD5(query + mixinKey);
|
||||
return query + "&w_rid=" + w_rid;
|
||||
}
|
||||
}
|
||||
130
app/src/main/java/com/github/catvod/bean/jianpian/Data.java
Normal file
130
app/src/main/java/com/github/catvod/bean/jianpian/Data.java
Normal file
@@ -0,0 +1,130 @@
|
||||
package com.github.catvod.bean.jianpian;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Data {
|
||||
|
||||
@SerializedName(value = "jump_id", alternate = "id")
|
||||
private String jumpId;
|
||||
@SerializedName(value = "thumbnail", alternate = "path")
|
||||
private String thumbnail;
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
@SerializedName("mask")
|
||||
private String mask;
|
||||
@SerializedName("description")
|
||||
private String description;
|
||||
@SerializedName("playlist")
|
||||
private Value playlist;
|
||||
@SerializedName("year")
|
||||
private Value year;
|
||||
@SerializedName("area")
|
||||
private Value area;
|
||||
@SerializedName("types")
|
||||
private List<Value> types;
|
||||
@SerializedName("actors")
|
||||
private List<Value> actors;
|
||||
@SerializedName("directors")
|
||||
private List<Value> directors;
|
||||
@SerializedName("btbo_downlist")
|
||||
private List<BtboDown> btboDownlist;
|
||||
|
||||
public String getJumpId() {
|
||||
return TextUtils.isEmpty(jumpId) ? "" : jumpId;
|
||||
}
|
||||
|
||||
public String getThumbnail() {
|
||||
return TextUtils.isEmpty(thumbnail) ? "" : thumbnail + "@Referer=www.jianpianapp.com@User-Agent=jianpian-version362";
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return TextUtils.isEmpty(title) ? "" : title;
|
||||
}
|
||||
|
||||
public String getMask() {
|
||||
return TextUtils.isEmpty(mask) ? getPlaylist() : mask;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return TextUtils.isEmpty(description) ? "" : description.replace(" ", "");
|
||||
}
|
||||
|
||||
public String getPlaylist() {
|
||||
return playlist == null ? "" : playlist.getTitle();
|
||||
}
|
||||
|
||||
public String getYear() {
|
||||
return year == null ? "" : year.getTitle();
|
||||
}
|
||||
|
||||
public String getArea() {
|
||||
return area == null ? "" : area.getTitle();
|
||||
}
|
||||
|
||||
public String getTypes() {
|
||||
return types == null ? "" : getValues(types, false);
|
||||
}
|
||||
|
||||
public String getActors() {
|
||||
return actors == null ? "" : getValues(actors, true);
|
||||
}
|
||||
|
||||
public String getDirectors() {
|
||||
return directors == null ? "" : getValues(directors, true);
|
||||
}
|
||||
|
||||
public List<BtboDown> getBtboDownlist() {
|
||||
return btboDownlist == null ? Collections.emptyList() : btboDownlist;
|
||||
}
|
||||
|
||||
public Vod vod() {
|
||||
return new Vod(getJumpId(), getTitle(), getThumbnail(), getMask());
|
||||
}
|
||||
|
||||
public String getValues(List<Value> items, boolean link) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Value value : items) sb.append(value.getValue(link)).append(" ");
|
||||
return Util.substring(sb.toString());
|
||||
}
|
||||
|
||||
public String getPlayUrl() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (BtboDown value : getBtboDownlist()) sb.append(value.getVal()).append("#");
|
||||
return Util.substring(sb.toString());
|
||||
}
|
||||
|
||||
public static class Value {
|
||||
|
||||
@SerializedName(value = "title", alternate = "name")
|
||||
private String title;
|
||||
|
||||
private String getTitle() {
|
||||
return TextUtils.isEmpty(title) ? "" : title;
|
||||
}
|
||||
|
||||
private String getLink() {
|
||||
return String.format("[a=cr:{\"id\":\"%s\",\"name\":\"%s\"}/]%s[/a]", getTitle() + "/{pg}", getTitle(), getTitle());
|
||||
}
|
||||
|
||||
public String getValue(boolean link) {
|
||||
return link ? getLink() : getTitle();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BtboDown {
|
||||
|
||||
@SerializedName("val")
|
||||
private String val;
|
||||
|
||||
public String getVal() {
|
||||
return TextUtils.isEmpty(val) ? "" : val.replaceAll("ftp", "tvbox-xg:ftp");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.catvod.bean.jianpian;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Detail {
|
||||
|
||||
@SerializedName("data")
|
||||
private Data data;
|
||||
|
||||
public static Detail objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Detail.class);
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data == null ? new Data() : data;
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/github/catvod/bean/jianpian/Resp.java
Normal file
21
app/src/main/java/com/github/catvod/bean/jianpian/Resp.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.github.catvod.bean.jianpian;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Resp {
|
||||
|
||||
@SerializedName("data")
|
||||
private List<Data> data;
|
||||
|
||||
public static Resp objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Resp.class);
|
||||
}
|
||||
|
||||
public List<Data> getData() {
|
||||
return data == null ? Collections.emptyList() : data;
|
||||
}
|
||||
}
|
||||
45
app/src/main/java/com/github/catvod/bean/market/Data.java
Normal file
45
app/src/main/java/com/github/catvod/bean/market/Data.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package com.github.catvod.bean.market;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Data {
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("list")
|
||||
private List<Item> list;
|
||||
|
||||
public static List<Data> arrayFrom(String str) {
|
||||
Type listType = new TypeToken<ArrayList<Data>>() {}.getType();
|
||||
return new Gson().fromJson(str, listType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public List<Item> getList() {
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
}
|
||||
|
||||
public List<Vod> getVod() {
|
||||
List<Vod> vodList = new ArrayList<>();
|
||||
for (Item item : getList()) vodList.add(item.vod());
|
||||
return vodList;
|
||||
}
|
||||
|
||||
public Class type() {
|
||||
return new Class(getName(), getName());
|
||||
}
|
||||
}
|
||||
56
app/src/main/java/com/github/catvod/bean/market/Item.java
Normal file
56
app/src/main/java/com/github/catvod/bean/market/Item.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package com.github.catvod.bean.market;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Item {
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
@SerializedName("icon")
|
||||
private String icon;
|
||||
@SerializedName("copy")
|
||||
private String copy;
|
||||
@SerializedName("version")
|
||||
private String version;
|
||||
|
||||
public Item(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return TextUtils.isEmpty(url) ? "" : url;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return TextUtils.isEmpty(icon) ? "" : icon;
|
||||
}
|
||||
|
||||
public String getCopy() {
|
||||
return TextUtils.isEmpty(copy) ? "" : copy;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return TextUtils.isEmpty(version) ? "" : version;
|
||||
}
|
||||
|
||||
public Vod vod() {
|
||||
return new Vod(getUrl(), getName(), getIcon(), getVersion(), Vod.Style.rect(1.0f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Item)) return false;
|
||||
Item it = (Item) obj;
|
||||
return getUrl().equals(it.getUrl());
|
||||
}
|
||||
}
|
||||
61
app/src/main/java/com/github/catvod/bean/star/Card.java
Normal file
61
app/src/main/java/com/github/catvod/bean/star/Card.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Card {
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName(value = "img", alternate = "picurl")
|
||||
private String img;
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
@SerializedName("countStr")
|
||||
private String countStr;
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
@SerializedName("cards")
|
||||
private List<Card> cards;
|
||||
|
||||
public static List<Card> arrayFrom(String str) {
|
||||
Type listType = new TypeToken<List<Card>>() {}.getType();
|
||||
return new Gson().fromJson(str, listType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getImg() {
|
||||
return TextUtils.isEmpty(img) ? "" : img;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return TextUtils.isEmpty(id) ? "" : id;
|
||||
}
|
||||
|
||||
public String getCountStr() {
|
||||
return TextUtils.isEmpty(countStr) ? "" : countStr;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return TextUtils.isEmpty(url) ? "" : url;
|
||||
}
|
||||
|
||||
public List<Card> getCards() {
|
||||
return cards == null ? Collections.emptyList() : cards;
|
||||
}
|
||||
|
||||
public Vod vod() {
|
||||
return new Vod(getId(), getName(), getImg(), getCountStr());
|
||||
}
|
||||
}
|
||||
65
app/src/main/java/com/github/catvod/bean/star/Condition.java
Normal file
65
app/src/main/java/com/github/catvod/bean/star/Condition.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Condition {
|
||||
|
||||
@SerializedName("label")
|
||||
private List<List<String>> label;
|
||||
@SerializedName("country")
|
||||
private List<String> country;
|
||||
@SerializedName("time")
|
||||
private List<Integer> time;
|
||||
|
||||
public static Condition objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Condition.class);
|
||||
}
|
||||
|
||||
public List<List<String>> getLabel() {
|
||||
return label == null ? Collections.emptyList() : label;
|
||||
}
|
||||
|
||||
public List<String> getCountry() {
|
||||
return country == null ? Collections.emptyList() : country;
|
||||
}
|
||||
|
||||
public List<Integer> getTime() {
|
||||
return time == null ? Collections.emptyList() : time;
|
||||
}
|
||||
|
||||
public List<Filter> getFilter() {
|
||||
List<Filter> filters = new ArrayList<>();
|
||||
filters.add(new Filter("type", "類型", getTypeValues()));
|
||||
filters.add(new Filter("area", "地區", getAreaValues()));
|
||||
filters.add(new Filter("year", "年份", getYearValues()));
|
||||
return filters;
|
||||
}
|
||||
|
||||
private List<Filter.Value> getTypeValues() {
|
||||
List<Filter.Value> values = new ArrayList<>();
|
||||
values.add(new Filter.Value("全部", ""));
|
||||
for (List<String> list : getLabel()) values.add(new Filter.Value(list.get(0)));
|
||||
return values;
|
||||
}
|
||||
|
||||
private List<Filter.Value> getAreaValues() {
|
||||
List<Filter.Value> values = new ArrayList<>();
|
||||
values.add(new Filter.Value("全部", ""));
|
||||
for (String text : getCountry()) values.add(new Filter.Value(text));
|
||||
return values;
|
||||
}
|
||||
|
||||
private List<Filter.Value> getYearValues() {
|
||||
List<Filter.Value> values = new ArrayList<>();
|
||||
values.add(new Filter.Value("全部", ""));
|
||||
Collections.sort(getTime(), Collections.reverseOrder());
|
||||
for (Integer year : getTime()) if (year >= 2010) values.add(new Filter.Value(String.valueOf(year)));
|
||||
return values;
|
||||
}
|
||||
}
|
||||
24
app/src/main/java/com/github/catvod/bean/star/Group.java
Normal file
24
app/src/main/java/com/github/catvod/bean/star/Group.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Group {
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("videos")
|
||||
private List<Video> videos;
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public List<Video> getVideos() {
|
||||
return videos == null ? Collections.emptyList() : videos;
|
||||
}
|
||||
}
|
||||
71
app/src/main/java/com/github/catvod/bean/star/Info.java
Normal file
71
app/src/main/java/com/github/catvod/bean/star/Info.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Info {
|
||||
|
||||
@SerializedName("videosGroup")
|
||||
private List<Group> videosGroup;
|
||||
@SerializedName("actor")
|
||||
private List<Person> actor;
|
||||
@SerializedName("country")
|
||||
private String country;
|
||||
@SerializedName("desc")
|
||||
private String desc;
|
||||
@SerializedName("director")
|
||||
private List<Person> director;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("picurl")
|
||||
private String picurl;
|
||||
@SerializedName("time")
|
||||
private String time;
|
||||
@SerializedName("countStr")
|
||||
private String countStr;
|
||||
|
||||
public static Info objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Info.class);
|
||||
}
|
||||
|
||||
public List<Group> getVideosGroup() {
|
||||
return videosGroup == null ? Collections.emptyList() : videosGroup;
|
||||
}
|
||||
|
||||
public List<Person> getActor() {
|
||||
return actor == null ? Collections.emptyList() : actor;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return TextUtils.isEmpty(country) ? "" : country;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return TextUtils.isEmpty(desc) ? "" : desc;
|
||||
}
|
||||
|
||||
public List<Person> getDirector() {
|
||||
return director == null ? Collections.emptyList() : director;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getPicurl() {
|
||||
return TextUtils.isEmpty(picurl) ? "" : picurl;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return TextUtils.isEmpty(time) ? "" : time;
|
||||
}
|
||||
|
||||
public String getCountStr() {
|
||||
return TextUtils.isEmpty(countStr) ? "" : countStr;
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/github/catvod/bean/star/Person.java
Normal file
21
app/src/main/java/com/github/catvod/bean/star/Person.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Person {
|
||||
|
||||
@SerializedName("id")
|
||||
private int id;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
}
|
||||
60
app/src/main/java/com/github/catvod/bean/star/Query.java
Normal file
60
app/src/main/java/com/github/catvod/bean/star/Query.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Query {
|
||||
|
||||
@SerializedName("country")
|
||||
private String country;
|
||||
@SerializedName("label")
|
||||
private String label;
|
||||
@SerializedName("chName")
|
||||
private String chName;
|
||||
@SerializedName("startTime")
|
||||
private Integer startTime;
|
||||
@SerializedName("endTime")
|
||||
private Integer endTime;
|
||||
@SerializedName("pageSize")
|
||||
private Integer pageSize;
|
||||
@SerializedName("page")
|
||||
private Integer page;
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public void setChName(String chName) {
|
||||
this.chName = chName;
|
||||
}
|
||||
|
||||
public void setStartTime(Integer startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public void setEndTime(Integer endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public void setPageSize(Integer pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public void setPage(Integer page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public void setYear(String year) {
|
||||
setStartTime(Integer.parseInt(year));
|
||||
setEndTime(Integer.parseInt(year));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/github/catvod/bean/star/Video.java
Normal file
21
app/src/main/java/com/github/catvod/bean/star/Video.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.github.catvod.bean.star;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Video {
|
||||
|
||||
@SerializedName("purl")
|
||||
private String purl;
|
||||
@SerializedName("eporder")
|
||||
private int eporder;
|
||||
|
||||
public String getPurl() {
|
||||
return TextUtils.isEmpty(purl) ? "" : purl;
|
||||
}
|
||||
|
||||
public int getEporder() {
|
||||
return eporder;
|
||||
}
|
||||
}
|
||||
27
app/src/main/java/com/github/catvod/bean/upyun/Data.java
Normal file
27
app/src/main/java/com/github/catvod/bean/upyun/Data.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.github.catvod.bean.upyun;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Data {
|
||||
|
||||
@SerializedName("result")
|
||||
private Data result;
|
||||
@SerializedName("items")
|
||||
private List<Item> items;
|
||||
|
||||
public static Data objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Data.class);
|
||||
}
|
||||
|
||||
public Data getResult() {
|
||||
return result == null ? new Data() : result;
|
||||
}
|
||||
|
||||
public List<Item> getItems() {
|
||||
return items == null ? Collections.emptyList() : items;
|
||||
}
|
||||
}
|
||||
37
app/src/main/java/com/github/catvod/bean/upyun/Item.java
Normal file
37
app/src/main/java/com/github/catvod/bean/upyun/Item.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.github.catvod.bean.upyun;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Item {
|
||||
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
@SerializedName("page_url")
|
||||
private String pageUrl;
|
||||
@SerializedName("insert_time")
|
||||
private String insertTime;
|
||||
|
||||
public String getTitle() {
|
||||
return TextUtils.isEmpty(title) ? "" : title.replaceAll("<em>", "").replaceAll("</em>", "");
|
||||
}
|
||||
|
||||
public String getPageUrl() {
|
||||
return TextUtils.isEmpty(pageUrl) ? "" : pageUrl;
|
||||
}
|
||||
|
||||
public String getInsertTime() {
|
||||
return TextUtils.isEmpty(insertTime) ? "" : insertTime;
|
||||
}
|
||||
|
||||
public Item url(String pageUrl) {
|
||||
this.pageUrl = pageUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vod getVod() {
|
||||
return new Vod(getPageUrl(), getTitle(), "https://inews.gtimg.com/newsapp_bt/0/13263837859/1000", getInsertTime());
|
||||
}
|
||||
}
|
||||
101
app/src/main/java/com/github/catvod/bean/webdav/Drive.java
Normal file
101
app/src/main/java/com/github/catvod/bean/webdav/Drive.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package com.github.catvod.bean.webdav;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.thegrizzlylabs.sardineandroid.DavResource;
|
||||
import com.thegrizzlylabs.sardineandroid.Sardine;
|
||||
import com.thegrizzlylabs.sardineandroid.impl.OkHttpSardine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Drive {
|
||||
|
||||
@SerializedName("drives")
|
||||
private List<Drive> drives;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("server")
|
||||
private String server;
|
||||
@SerializedName("user")
|
||||
private String user;
|
||||
@SerializedName("pass")
|
||||
private String pass;
|
||||
@SerializedName("path")
|
||||
private String path;
|
||||
@SerializedName("webdav")
|
||||
private Sardine webdav;
|
||||
|
||||
public static Drive objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Drive.class);
|
||||
}
|
||||
|
||||
public Drive(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Drive> getDrives() {
|
||||
return drives == null ? new ArrayList<>() : drives;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TextUtils.isEmpty(name) ? "" : name;
|
||||
}
|
||||
|
||||
public String getServer() {
|
||||
return TextUtils.isEmpty(server) ? "" : server;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return TextUtils.isEmpty(user) ? "" : user;
|
||||
}
|
||||
|
||||
public String getPass() {
|
||||
return TextUtils.isEmpty(pass) ? "" : pass;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return TextUtils.isEmpty(path) ? "" : path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = TextUtils.isEmpty(path) ? "" : path;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return getServer().replace(getPath(), "");
|
||||
}
|
||||
|
||||
public Sardine getWebdav() {
|
||||
if (webdav == null) init();
|
||||
return webdav;
|
||||
}
|
||||
|
||||
public Class toType() {
|
||||
return new Class(getName(), getName(), "1");
|
||||
}
|
||||
|
||||
private void init() {
|
||||
webdav = new OkHttpSardine();
|
||||
webdav.setCredentials(getUser(), getPass());
|
||||
setPath(Uri.parse(getServer()).getPath());
|
||||
}
|
||||
|
||||
public Vod vod(DavResource item, String vodPic) {
|
||||
return new Vod(getName() + item.getPath(), item.getName(), vodPic, Util.getSize(item.getContentLength()), item.isDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Drive)) return false;
|
||||
Drive it = (Drive) obj;
|
||||
return getName().equals(it.getName());
|
||||
}
|
||||
}
|
||||
37
app/src/main/java/com/github/catvod/bean/webdav/Sorter.java
Normal file
37
app/src/main/java/com/github/catvod/bean/webdav/Sorter.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.github.catvod.bean.webdav;
|
||||
|
||||
import com.thegrizzlylabs.sardineandroid.DavResource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class Sorter implements Comparator<DavResource> {
|
||||
|
||||
private final String type;
|
||||
private final String order;
|
||||
|
||||
public static void sort(String type, String order, List<DavResource> items) {
|
||||
Collections.sort(items, new Sorter(type, order));
|
||||
}
|
||||
|
||||
public Sorter(String type, String order) {
|
||||
this.type = type;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(DavResource o1, DavResource o2) {
|
||||
boolean asc = order.equals("asc");
|
||||
switch (type) {
|
||||
case "name":
|
||||
return asc ? o1.getName().compareTo(o2.getName()) : o2.getName().compareTo(o1.getName());
|
||||
case "size":
|
||||
return asc ? Long.compare(o1.getContentLength(), o2.getContentLength()) : Long.compare(o2.getContentLength(), o1.getContentLength());
|
||||
case "date":
|
||||
return asc ? o1.getModified().compareTo(o2.getModified()) : o2.getModified().compareTo(o1.getModified());
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
695
app/src/main/java/com/github/catvod/bean/xpath/Rule.java
Normal file
695
app/src/main/java/com/github/catvod/bean/xpath/Rule.java
Normal file
@@ -0,0 +1,695 @@
|
||||
package com.github.catvod.bean.xpath;
|
||||
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Rule {
|
||||
/**
|
||||
* user-agent
|
||||
*/
|
||||
private String ua;
|
||||
/**
|
||||
* 取得分類和首頁推薦的Url
|
||||
*/
|
||||
private String homeUrl;
|
||||
/**
|
||||
* 分類節點 xpath
|
||||
*/
|
||||
private String cateNode;
|
||||
/**
|
||||
* 分類節點名 xpath
|
||||
*/
|
||||
private String cateName;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern cateNameR;
|
||||
/**
|
||||
* 分類節點 id xpath
|
||||
*/
|
||||
private String cateId;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern cateIdR;
|
||||
/**
|
||||
* 手動指定分類如果有則不從 homeUrl 中獲取分類
|
||||
*/
|
||||
private final LinkedHashMap<String, String> cateManual = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* 篩選
|
||||
*/
|
||||
private JSONObject filter;
|
||||
|
||||
/**
|
||||
* 更新推薦影片節點 xpath
|
||||
*/
|
||||
private String homeVodNode;
|
||||
/**
|
||||
* 更新推薦影片名稱 xpath
|
||||
*/
|
||||
private String homeVodName;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern homeVodNameR;
|
||||
/**
|
||||
* 更新推薦影片 id xpath
|
||||
*/
|
||||
private String homeVodId;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern homeVodIdR;
|
||||
/**
|
||||
* 更新推薦影片圖片 xpath
|
||||
*/
|
||||
private String homeVodImg;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern homeVodImgR;
|
||||
/**
|
||||
* 更新推薦影片簡介 xpath
|
||||
*/
|
||||
private String homeVodMark;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern homeVodMarkR;
|
||||
/**
|
||||
* 分類頁地址
|
||||
*/
|
||||
private String cateUrl;
|
||||
/**
|
||||
* 分類頁影片節點 xpath
|
||||
*/
|
||||
private String cateVodNode;
|
||||
/**
|
||||
* 分類頁影片名稱 xpath
|
||||
*/
|
||||
private String cateVodName;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern cateVodNameR;
|
||||
/**
|
||||
* 分類頁影片影片id xpath
|
||||
*/
|
||||
private String cateVodId;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern cateVodIdR;
|
||||
/**
|
||||
* 分類頁影片影片圖片 xpath
|
||||
*/
|
||||
private String cateVodImg;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern cateVodImgR;
|
||||
/**
|
||||
* 分類頁影片影片簡介 xpath
|
||||
*/
|
||||
private String cateVodMark;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern cateVodMarkR;
|
||||
|
||||
/**
|
||||
* 詳情頁面
|
||||
*/
|
||||
private String dtUrl;
|
||||
/**
|
||||
* 詳情節點 xpath
|
||||
*/
|
||||
private String dtNode;
|
||||
/**
|
||||
* 詳情影片 xpath
|
||||
*/
|
||||
private String dtName;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtNameR;
|
||||
/**
|
||||
* 詳情影片圖片 xpath
|
||||
*/
|
||||
private String dtImg;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtImgR;
|
||||
/**
|
||||
* 詳情影片分類 xpath
|
||||
*/
|
||||
private String dtCate;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtCateR;
|
||||
/**
|
||||
* 詳情影片年份 xpath
|
||||
*/
|
||||
private String dtYear;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtYearR;
|
||||
/**
|
||||
* 詳情影片地區 xpath
|
||||
*/
|
||||
private String dtArea;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtAreaR;
|
||||
/**
|
||||
* 詳情影片簡介 xpath
|
||||
*/
|
||||
private String dtMark;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtMarkR;
|
||||
/**
|
||||
* 詳情演員 xpath
|
||||
*/
|
||||
private String dtActor;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtActorR;
|
||||
/**
|
||||
* 詳情導演 xpath
|
||||
*/
|
||||
private String dtDirector;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtDirectorR;
|
||||
/**
|
||||
* 詳情說明 xpath
|
||||
*/
|
||||
private String dtDesc;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern dtDescR;
|
||||
|
||||
/**
|
||||
* 詳情播放來源節點
|
||||
*/
|
||||
private String dtFromNode;
|
||||
/**
|
||||
* 詳情播放來源名稱 xpath
|
||||
*/
|
||||
private String dtFromName;
|
||||
/**
|
||||
* 詳情
|
||||
*/
|
||||
private Pattern dtFromNameR;
|
||||
/**
|
||||
* 詳情播放地址列表節點 xpath
|
||||
*/
|
||||
private String dtUrlNode;
|
||||
/**
|
||||
* 詳情播放地址節點 xpath
|
||||
*/
|
||||
private String dtUrlSubNode;
|
||||
/**
|
||||
* 詳情播放地址id xpath
|
||||
*/
|
||||
private String dtUrlId;
|
||||
/**
|
||||
* 詳情
|
||||
*/
|
||||
private Pattern dtUrlIdR;
|
||||
/**
|
||||
* 詳情播放地址名稱 xpath
|
||||
*/
|
||||
private String dtUrlName;
|
||||
/**
|
||||
* 詳情
|
||||
*/
|
||||
private Pattern dtUrlNameR;
|
||||
/**
|
||||
* 播放頁面url
|
||||
*/
|
||||
private String playUrl;
|
||||
/**
|
||||
* 播放解析調用ua
|
||||
*/
|
||||
private String playUa;
|
||||
/**
|
||||
* 播放解析調用referer
|
||||
*/
|
||||
private String playReferer;
|
||||
|
||||
/**
|
||||
* 搜尋頁地址
|
||||
*/
|
||||
private String searchUrl;
|
||||
|
||||
/**
|
||||
* 搜尋頁影片節點 xpath
|
||||
*/
|
||||
private String scVodNode;
|
||||
/**
|
||||
* 搜尋頁影片名稱 xpath
|
||||
*/
|
||||
private String scVodName;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern scVodNameR;
|
||||
/**
|
||||
* 搜尋頁影片id xpath
|
||||
*/
|
||||
private String scVodId;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern scVodIdR;
|
||||
/**
|
||||
* 搜尋頁影片圖片 xpath
|
||||
*/
|
||||
private String scVodImg;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern scVodImgR;
|
||||
/**
|
||||
* 搜尋頁影片簡介 xpath
|
||||
*/
|
||||
private String scVodMark;
|
||||
/**
|
||||
* 正則對取到的數據進行二次處理
|
||||
*/
|
||||
private Pattern scVodMarkR;
|
||||
|
||||
private static Pattern getPattern(JSONObject json, String key) {
|
||||
String v = json.optString(key).trim();
|
||||
if (v.isEmpty())
|
||||
return null;
|
||||
else {
|
||||
try {
|
||||
return Pattern.compile(v);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||
if (pattern == null)
|
||||
return src;
|
||||
try {
|
||||
Matcher matcher = pattern.matcher(src);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).trim();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
public static Rule fromJson(String json) {
|
||||
try {
|
||||
JSONObject jsonObj = new JSONObject(json);
|
||||
Rule rule = new Rule();
|
||||
rule.ua = jsonObj.optString("ua");
|
||||
rule.homeUrl = jsonObj.optString("homeUrl").trim();
|
||||
rule.cateNode = jsonObj.optString("cateNode").trim();
|
||||
rule.cateName = jsonObj.optString("cateName").trim();
|
||||
rule.cateNameR = getPattern(jsonObj, "cateNameR");
|
||||
rule.cateId = jsonObj.optString("cateId").trim();
|
||||
rule.cateIdR = getPattern(jsonObj, "cateIdR");
|
||||
JSONObject navs = jsonObj.optJSONObject("cateManual");
|
||||
if (navs != null) {
|
||||
Iterator<String> keys = navs.keys();
|
||||
while (keys.hasNext()) {
|
||||
String name = keys.next();
|
||||
rule.cateManual.put(name.trim(), navs.getString(name).trim());
|
||||
}
|
||||
}
|
||||
rule.filter = jsonObj.optJSONObject("filter");
|
||||
rule.homeVodNode = jsonObj.optString("homeVodNode").trim();
|
||||
rule.homeVodName = jsonObj.optString("homeVodName").trim();
|
||||
rule.homeVodNameR = getPattern(jsonObj, "homeVodNameR");
|
||||
rule.homeVodId = jsonObj.optString("homeVodId").trim();
|
||||
rule.homeVodIdR = getPattern(jsonObj, "homeVodIdR");
|
||||
rule.homeVodImg = jsonObj.optString("homeVodImg").trim();
|
||||
rule.homeVodImgR = getPattern(jsonObj, "homeVodImgR");
|
||||
rule.homeVodMark = jsonObj.optString("homeVodMark").trim();
|
||||
rule.homeVodMarkR = getPattern(jsonObj, "homeVodMarkR");
|
||||
rule.cateUrl = jsonObj.optString("cateUrl").trim();
|
||||
rule.cateVodNode = jsonObj.optString("cateVodNode").trim();
|
||||
rule.cateVodName = jsonObj.optString("cateVodName").trim();
|
||||
rule.cateVodNameR = getPattern(jsonObj, "cateVodNameR");
|
||||
rule.cateVodId = jsonObj.optString("cateVodId").trim();
|
||||
rule.cateVodIdR = getPattern(jsonObj, "cateVodIdR");
|
||||
rule.cateVodImg = jsonObj.optString("cateVodImg").trim();
|
||||
rule.cateVodImgR = getPattern(jsonObj, "cateVodImgR");
|
||||
rule.cateVodMark = jsonObj.optString("cateVodMark").trim();
|
||||
rule.cateVodMarkR = getPattern(jsonObj, "cateVodMarkR");
|
||||
rule.dtUrl = jsonObj.optString("dtUrl");
|
||||
rule.dtNode = jsonObj.optString("dtNode");
|
||||
rule.dtName = jsonObj.optString("dtName");
|
||||
rule.dtNameR = getPattern(jsonObj, "dtNameR");
|
||||
rule.dtImg = jsonObj.optString("dtImg");
|
||||
rule.dtImgR = getPattern(jsonObj, "dtImgR");
|
||||
rule.dtCate = jsonObj.optString("dtCate");
|
||||
rule.dtCateR = getPattern(jsonObj, "dtCateR");
|
||||
rule.dtYear = jsonObj.optString("dtYear");
|
||||
rule.dtYearR = getPattern(jsonObj, "dtYearR");
|
||||
rule.dtArea = jsonObj.optString("dtArea");
|
||||
rule.dtAreaR = getPattern(jsonObj, "dtAreaR");
|
||||
rule.dtMark = jsonObj.optString("dtMark");
|
||||
rule.dtMarkR = getPattern(jsonObj, "dtMarkR");
|
||||
rule.dtActor = jsonObj.optString("dtActor");
|
||||
rule.dtActorR = getPattern(jsonObj, "dtActorR");
|
||||
rule.dtDirector = jsonObj.optString("dtDirector");
|
||||
rule.dtDirectorR = getPattern(jsonObj, "dtDirectorR");
|
||||
rule.dtDesc = jsonObj.optString("dtDesc");
|
||||
rule.dtDescR = getPattern(jsonObj, "dtDescR");
|
||||
rule.dtFromNode = jsonObj.optString("dtFromNode");
|
||||
rule.dtFromName = jsonObj.optString("dtFromName");
|
||||
rule.dtFromNameR = getPattern(jsonObj, "dtFromNameR");
|
||||
rule.dtUrlNode = jsonObj.optString("dtUrlNode");
|
||||
rule.dtUrlSubNode = jsonObj.optString("dtUrlSubNode");
|
||||
rule.dtUrlId = jsonObj.optString("dtUrlId");
|
||||
rule.dtUrlIdR = getPattern(jsonObj, "dtUrlIdR");
|
||||
rule.dtUrlName = jsonObj.optString("dtUrlName");
|
||||
rule.dtUrlNameR = getPattern(jsonObj, "dtUrlNameR");
|
||||
rule.playUrl = jsonObj.optString("playUrl");
|
||||
rule.playUa = jsonObj.optString("playUa");
|
||||
rule.playReferer = jsonObj.optString("playReferer");
|
||||
rule.searchUrl = jsonObj.optString("searchUrl");
|
||||
rule.scVodNode = jsonObj.optString("scVodNode").trim();
|
||||
rule.scVodName = jsonObj.optString("scVodName").trim();
|
||||
rule.scVodNameR = getPattern(jsonObj, "scVodNameR");
|
||||
rule.scVodId = jsonObj.optString("scVodId").trim();
|
||||
rule.scVodIdR = getPattern(jsonObj, "scVodIdR");
|
||||
rule.scVodImg = jsonObj.optString("scVodImg").trim();
|
||||
rule.scVodImgR = getPattern(jsonObj, "scVodImgR");
|
||||
rule.scVodMark = jsonObj.optString("scVodMark").trim();
|
||||
rule.scVodMarkR = getPattern(jsonObj, "scVodMarkR");
|
||||
return rule;
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getUa() {
|
||||
return ua;
|
||||
}
|
||||
|
||||
public String getHomeUrl() {
|
||||
return homeUrl;
|
||||
}
|
||||
|
||||
public String getCateNode() {
|
||||
return cateNode;
|
||||
}
|
||||
|
||||
public String getCateName() {
|
||||
return cateName;
|
||||
}
|
||||
|
||||
public String getCateNameR(String src) {
|
||||
return doReplaceRegex(cateNameR, src);
|
||||
}
|
||||
|
||||
public String getCateId() {
|
||||
return cateId;
|
||||
}
|
||||
|
||||
public String getCateIdR(String src) {
|
||||
return doReplaceRegex(cateIdR, src);
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, String> getCateManual() {
|
||||
return cateManual;
|
||||
}
|
||||
|
||||
public JSONObject getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public String getHomeVodNode() {
|
||||
return homeVodNode;
|
||||
}
|
||||
|
||||
public String getHomeVodName() {
|
||||
return homeVodName;
|
||||
}
|
||||
|
||||
public String getHomeVodNameR(String src) {
|
||||
return doReplaceRegex(homeVodNameR, src);
|
||||
}
|
||||
|
||||
public String getHomeVodId() {
|
||||
return homeVodId;
|
||||
}
|
||||
|
||||
public String getHomeVodIdR(String src) {
|
||||
return doReplaceRegex(homeVodIdR, src);
|
||||
}
|
||||
|
||||
public String getHomeVodImg() {
|
||||
return homeVodImg;
|
||||
}
|
||||
|
||||
public String getHomeVodImgR(String src) {
|
||||
return doReplaceRegex(homeVodImgR, src);
|
||||
}
|
||||
|
||||
public String getHomeVodMark() {
|
||||
return homeVodMark;
|
||||
}
|
||||
|
||||
public String getHomeVodMarkR(String src) {
|
||||
return doReplaceRegex(homeVodMarkR, src);
|
||||
}
|
||||
|
||||
public String getCateUrl() {
|
||||
return cateUrl;
|
||||
}
|
||||
|
||||
public String getCateVodNode() {
|
||||
return cateVodNode;
|
||||
}
|
||||
|
||||
public String getCateVodName() {
|
||||
return cateVodName;
|
||||
}
|
||||
|
||||
public String getCateVodNameR(String src) {
|
||||
return doReplaceRegex(cateVodNameR, src);
|
||||
}
|
||||
|
||||
public String getCateVodId() {
|
||||
return cateVodId;
|
||||
}
|
||||
|
||||
public String getCateVodIdR(String src) {
|
||||
return doReplaceRegex(cateVodIdR, src);
|
||||
}
|
||||
|
||||
public String getCateVodImg() {
|
||||
return cateVodImg;
|
||||
}
|
||||
|
||||
public String getCateVodImgR(String src) {
|
||||
return doReplaceRegex(cateVodImgR, src);
|
||||
}
|
||||
|
||||
public String getCateVodMark() {
|
||||
return cateVodMark;
|
||||
}
|
||||
|
||||
public String getCateVodMarkR(String src) {
|
||||
return doReplaceRegex(cateVodNameR, src);
|
||||
}
|
||||
|
||||
public String getDetailUrl() {
|
||||
return dtUrl;
|
||||
}
|
||||
|
||||
public String getDetailNode() {
|
||||
return dtNode;
|
||||
}
|
||||
|
||||
public String getDetailName() {
|
||||
return dtName;
|
||||
}
|
||||
|
||||
public String getDetailNameR(String src) {
|
||||
return doReplaceRegex(dtNameR, src);
|
||||
}
|
||||
|
||||
public String getDetailImg() {
|
||||
return dtImg;
|
||||
}
|
||||
|
||||
public String getDetailImgR(String src) {
|
||||
return doReplaceRegex(dtImgR, src);
|
||||
}
|
||||
|
||||
public String getDetailCate() {
|
||||
return dtCate;
|
||||
}
|
||||
|
||||
public String getDetailCateR(String src) {
|
||||
return doReplaceRegex(dtCateR, src);
|
||||
}
|
||||
|
||||
public String getDetailYear() {
|
||||
return dtYear;
|
||||
}
|
||||
|
||||
public String getDetailYearR(String src) {
|
||||
return doReplaceRegex(dtYearR, src);
|
||||
}
|
||||
|
||||
public String getDetailArea() {
|
||||
return dtArea;
|
||||
}
|
||||
|
||||
public String getDetailAreaR(String src) {
|
||||
return doReplaceRegex(dtAreaR, src);
|
||||
}
|
||||
|
||||
public String getDetailMark() {
|
||||
return dtMark;
|
||||
}
|
||||
|
||||
public String getDetailMarkR(String src) {
|
||||
return doReplaceRegex(dtMarkR, src);
|
||||
}
|
||||
|
||||
public String getDetailActor() {
|
||||
return dtActor;
|
||||
}
|
||||
|
||||
public String getDetailActorR(String src) {
|
||||
return doReplaceRegex(dtActorR, src);
|
||||
}
|
||||
|
||||
public String getDetailDirector() {
|
||||
return dtDirector;
|
||||
}
|
||||
|
||||
public String getDetailDirectorR(String src) {
|
||||
return doReplaceRegex(dtDirectorR, src);
|
||||
}
|
||||
|
||||
public String getDetailDesc() {
|
||||
return dtDesc;
|
||||
}
|
||||
|
||||
public String getDetailDescR(String src) {
|
||||
return doReplaceRegex(dtDescR, src);
|
||||
}
|
||||
|
||||
public String getDetailFromNode() {
|
||||
return dtFromNode;
|
||||
}
|
||||
|
||||
public String getDetailFromName() {
|
||||
return dtFromName;
|
||||
}
|
||||
|
||||
public String getDetailFromNameR(String src) {
|
||||
return doReplaceRegex(dtFromNameR, src);
|
||||
}
|
||||
|
||||
public String getDetailUrlNode() {
|
||||
return dtUrlNode;
|
||||
}
|
||||
|
||||
public String getDetailUrlSubNode() {
|
||||
return dtUrlSubNode;
|
||||
}
|
||||
|
||||
public String getDetailUrlId() {
|
||||
return dtUrlId;
|
||||
}
|
||||
|
||||
public String getDetailUrlIdR(String src) {
|
||||
return doReplaceRegex(dtUrlIdR, src);
|
||||
}
|
||||
|
||||
public String getDetailUrlName() {
|
||||
return dtUrlName;
|
||||
}
|
||||
|
||||
public String getDetailUrlNameR(String src) {
|
||||
return doReplaceRegex(dtUrlNameR, src);
|
||||
}
|
||||
|
||||
public String getPlayUrl() {
|
||||
return playUrl;
|
||||
}
|
||||
|
||||
public String getPlayUa() {
|
||||
return playUa;
|
||||
}
|
||||
|
||||
public String getPlayReferer() {
|
||||
return playReferer;
|
||||
}
|
||||
|
||||
public String getSearchUrl() {
|
||||
return searchUrl;
|
||||
}
|
||||
|
||||
public String getSearchVodNode() {
|
||||
return scVodNode;
|
||||
}
|
||||
|
||||
public String getSearchVodName() {
|
||||
return scVodName;
|
||||
}
|
||||
|
||||
public String getSearchVodNameR(String src) {
|
||||
return doReplaceRegex(scVodNameR, src);
|
||||
}
|
||||
|
||||
public String getSearchVodId() {
|
||||
return scVodId;
|
||||
}
|
||||
|
||||
public String getSearchVodIdR(String src) {
|
||||
return doReplaceRegex(scVodIdR, src);
|
||||
}
|
||||
|
||||
public String getSearchVodImg() {
|
||||
return scVodImg;
|
||||
}
|
||||
|
||||
public String getSearchVodImgR(String src) {
|
||||
return doReplaceRegex(scVodImgR, src);
|
||||
}
|
||||
|
||||
public String getSearchVodMark() {
|
||||
return scVodMark;
|
||||
}
|
||||
|
||||
public String getSearchVodMarkR(String src) {
|
||||
return doReplaceRegex(scVodMarkR, src);
|
||||
}
|
||||
}
|
||||
71
app/src/main/java/com/github/catvod/crawler/Spider.java
Normal file
71
app/src/main/java/com/github/catvod/crawler/Spider.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package com.github.catvod.crawler;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.Dns;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public abstract class Spider {
|
||||
|
||||
public void init(Context context) throws Exception {
|
||||
}
|
||||
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
init(context);
|
||||
}
|
||||
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String homeVideoContent() throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean manualVideoCheck() throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVideoFormat(String url) throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object[] proxyLocal(Map<String, String> params) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public static Dns safeDns() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static OkHttpClient client() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
16
app/src/main/java/com/github/catvod/crawler/SpiderDebug.java
Normal file
16
app/src/main/java/com/github/catvod/crawler/SpiderDebug.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.github.catvod.crawler;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class SpiderDebug {
|
||||
|
||||
private static final String TAG = SpiderDebug.class.getSimpleName();
|
||||
|
||||
public static void log(Throwable e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
public static void log(String msg) {
|
||||
Log.d(TAG, msg);
|
||||
}
|
||||
}
|
||||
111
app/src/main/java/com/github/catvod/debug/MainActivity.java
Normal file
111
app/src/main/java/com/github/catvod/debug/MainActivity.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package com.github.catvod.debug;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.catvod.R;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.spider.Cg51;
|
||||
import com.github.catvod.spider.Douban;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.spider.J91;
|
||||
import com.github.catvod.spider.Jable;
|
||||
import com.github.catvod.spider.QxiTv;
|
||||
import com.github.catvod.spider.Wogg;
|
||||
import com.github.catvod.spider.Zhaozy;
|
||||
import com.orhanobut.logger.AndroidLogAdapter;
|
||||
import com.orhanobut.logger.Logger;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
private ExecutorService executor;
|
||||
private Spider spider;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
Button homeContent = findViewById(R.id.homeContent);
|
||||
Button homeVideoContent = findViewById(R.id.homeVideoContent);
|
||||
Button categoryContent = findViewById(R.id.categoryContent);
|
||||
Button detailContent = findViewById(R.id.detailContent);
|
||||
Button playerContent = findViewById(R.id.playerContent);
|
||||
Button searchContent = findViewById(R.id.searchContent);
|
||||
homeContent.setOnClickListener(view -> executor.execute(this::homeContent));
|
||||
homeVideoContent.setOnClickListener(view -> executor.execute(this::homeVideoContent));
|
||||
categoryContent.setOnClickListener(view -> executor.execute(this::categoryContent));
|
||||
detailContent.setOnClickListener(view -> executor.execute(this::detailContent));
|
||||
playerContent.setOnClickListener(view -> executor.execute(this::playerContent));
|
||||
searchContent.setOnClickListener(view -> executor.execute(this::searchContent));
|
||||
Logger.addLogAdapter(new AndroidLogAdapter());
|
||||
executor = Executors.newCachedThreadPool();
|
||||
executor.execute(this::initSpider);
|
||||
}
|
||||
|
||||
private void initSpider() {
|
||||
try {
|
||||
Init.init(getApplicationContext());
|
||||
spider = new Cg51();
|
||||
spider.init(this, "");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void homeContent() {
|
||||
try {
|
||||
Logger.t("homeContent").d(spider.homeContent(true));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void homeVideoContent() {
|
||||
try {
|
||||
Logger.t("homeVideoContent").d(spider.homeVideoContent());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void categoryContent() {
|
||||
try {
|
||||
Logger.t("categoryContent").d(spider.categoryContent("wpcz", "6", true, new HashMap<>()));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void detailContent() {
|
||||
try {
|
||||
Logger.t("detailContent").d(spider.detailContent(Arrays.asList("123488")));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void playerContent() {
|
||||
try {
|
||||
Logger.t("playerContent").d(spider.playerContent("轉存原畫", "kahf2rw5Uuk+652f55f6943ee2f75d8e4fa590b4ec65fd007f8c", new ArrayList<>()));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void searchContent() {
|
||||
try {
|
||||
Logger.t("searchContent").d(spider.searchContent("空姐", false));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
19
app/src/main/java/com/github/catvod/js/Method.java
Normal file
19
app/src/main/java/com/github/catvod/js/Method.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.github.catvod.js;
|
||||
|
||||
import com.github.catvod.utils.Notify;
|
||||
import com.whl.quickjs.wrapper.JSMethod;
|
||||
import com.whl.quickjs.wrapper.QuickJSContext;
|
||||
|
||||
public class Method {
|
||||
|
||||
private QuickJSContext ctx;
|
||||
|
||||
public Method(QuickJSContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
@JSMethod
|
||||
public void showToast(String msg) {
|
||||
Notify.show(msg);
|
||||
}
|
||||
}
|
||||
107
app/src/main/java/com/github/catvod/net/OkHttp.java
Normal file
107
app/src/main/java/com/github/catvod/net/OkHttp.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package com.github.catvod.net;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Dns;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class OkHttp {
|
||||
|
||||
public static final String POST = "POST";
|
||||
public static final String GET = "GET";
|
||||
|
||||
private OkHttpClient client;
|
||||
|
||||
private static class Loader {
|
||||
static volatile OkHttp INSTANCE = new OkHttp();
|
||||
}
|
||||
|
||||
private static OkHttp get() {
|
||||
return Loader.INSTANCE;
|
||||
}
|
||||
|
||||
public static Response newCall(Request request) throws IOException {
|
||||
return client().newCall(request).execute();
|
||||
}
|
||||
|
||||
public static Response newCall(String url) throws IOException {
|
||||
return client().newCall(new Request.Builder().url(url).build()).execute();
|
||||
}
|
||||
|
||||
public static Response newCall(String url, Map<String, String> header) throws IOException {
|
||||
return client().newCall(new Request.Builder().url(url).headers(Headers.of(header)).build()).execute();
|
||||
}
|
||||
|
||||
public static String string(String url) {
|
||||
return string(url, null);
|
||||
}
|
||||
|
||||
public static String string(String url, Map<String, String> header) {
|
||||
return string(url, null, header);
|
||||
}
|
||||
|
||||
public static String string(String url, Map<String, String> params, Map<String, String> header) {
|
||||
return url.startsWith("http") ? new OkRequest(GET, url, params, header).execute(client()).getBody() : "";
|
||||
}
|
||||
|
||||
public static String post(String url, Map<String, String> params) {
|
||||
return post(url, params, null).getBody();
|
||||
}
|
||||
|
||||
public static OkResult post(String url, Map<String, String> params, Map<String, String> header) {
|
||||
return new OkRequest(POST, url, params, header).execute(client());
|
||||
}
|
||||
|
||||
public static String post(String url, String json) {
|
||||
return post(url, json, null).getBody();
|
||||
}
|
||||
|
||||
public static OkResult post(String url, String json, Map<String, String> header) {
|
||||
return new OkRequest(POST, url, json, header).execute(client());
|
||||
}
|
||||
|
||||
public static String getLocation(String url, Map<String, String> header) throws IOException {
|
||||
return getLocation(client().newBuilder().followRedirects(false).followSslRedirects(false).build().newCall(new Request.Builder().url(url).headers(Headers.of(header)).build()).execute().headers().toMultimap());
|
||||
}
|
||||
|
||||
public static String getLocation(Map<String, List<String>> headers) {
|
||||
if (headers == null) return null;
|
||||
if (headers.containsKey("location")) return headers.get("location").get(0);
|
||||
if (headers.containsKey("Location")) return headers.get("Location").get(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static OkHttpClient build() {
|
||||
if (get().client != null) return get().client;
|
||||
return get().client = getBuilder().build();
|
||||
}
|
||||
|
||||
private static OkHttpClient.Builder getBuilder() {
|
||||
return new OkHttpClient.Builder().dns(safeDns()).connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).hostnameVerifier((hostname, session) -> true).sslSocketFactory(new SSLCompat(), SSLCompat.TM);
|
||||
}
|
||||
|
||||
private static OkHttpClient client() {
|
||||
try {
|
||||
return Objects.requireNonNull(Spider.client());
|
||||
} catch (Throwable e) {
|
||||
return build();
|
||||
}
|
||||
}
|
||||
|
||||
private static Dns safeDns() {
|
||||
try {
|
||||
return Objects.requireNonNull(Spider.safeDns());
|
||||
} catch (Throwable e) {
|
||||
return Dns.SYSTEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
72
app/src/main/java/com/github/catvod/net/OkRequest.java
Normal file
72
app/src/main/java/com/github/catvod/net/OkRequest.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package com.github.catvod.net;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
class OkRequest {
|
||||
|
||||
private final Map<String, String> header;
|
||||
private final Map<String, String> params;
|
||||
private final String method;
|
||||
private final String json;
|
||||
private Request request;
|
||||
private String url;
|
||||
|
||||
OkRequest(String method, String url, Map<String, String> params, Map<String, String> header) {
|
||||
this(method, url, params, null, header);
|
||||
}
|
||||
|
||||
OkRequest(String method, String url, String json, Map<String, String> header) {
|
||||
this(method, url, null, json, header);
|
||||
}
|
||||
|
||||
private OkRequest(String method, String url, Map<String, String> params, String json, Map<String, String> header) {
|
||||
this.url = url;
|
||||
this.json = json;
|
||||
this.method = method;
|
||||
this.params = params;
|
||||
this.header = header;
|
||||
getInstance();
|
||||
}
|
||||
|
||||
private void getInstance() {
|
||||
Request.Builder builder = new Request.Builder();
|
||||
if (method.equals(OkHttp.GET) && params != null) setParams();
|
||||
if (method.equals(OkHttp.POST)) builder.post(getRequestBody());
|
||||
if (header != null) for (String key : header.keySet()) builder.addHeader(key, header.get(key));
|
||||
request = builder.url(url).build();
|
||||
}
|
||||
|
||||
private RequestBody getRequestBody() {
|
||||
if (!TextUtils.isEmpty(json)) return RequestBody.create(MediaType.get("application/json; charset=utf-8"), json);
|
||||
FormBody.Builder formBody = new FormBody.Builder();
|
||||
if (params != null) for (String key : params.keySet()) formBody.add(key, params.get(key));
|
||||
return formBody.build();
|
||||
}
|
||||
|
||||
private void setParams() {
|
||||
url = url + "?";
|
||||
for (String key : params.keySet()) url = url.concat(key + "=" + params.get(key) + "&");
|
||||
url = Util.substring(url);
|
||||
}
|
||||
|
||||
public OkResult execute(OkHttpClient client) {
|
||||
try {
|
||||
Response response = client.newCall(request).execute();
|
||||
return new OkResult(response.code(), response.body().string(), response.headers().toMultimap());
|
||||
} catch (IOException e) {
|
||||
return new OkResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
38
app/src/main/java/com/github/catvod/net/OkResult.java
Normal file
38
app/src/main/java/com/github/catvod/net/OkResult.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.github.catvod.net;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OkResult {
|
||||
|
||||
private final int code;
|
||||
private final String body;
|
||||
private final Map<String, List<String>> resp;
|
||||
|
||||
public OkResult() {
|
||||
this.code = 500;
|
||||
this.body = "";
|
||||
this.resp = new HashMap<>();
|
||||
}
|
||||
|
||||
public OkResult(int code, String body, Map<String, List<String>> resp) {
|
||||
this.code = code;
|
||||
this.body = body;
|
||||
this.resp = resp;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return TextUtils.isEmpty(body) ? "" : body;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getResp() {
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
112
app/src/main/java/com/github/catvod/net/SSLCompat.java
Normal file
112
app/src/main/java/com/github/catvod/net/SSLCompat.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.github.catvod.net;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
public class SSLCompat extends SSLSocketFactory {
|
||||
|
||||
private SSLSocketFactory factory;
|
||||
private String[] cipherSuites;
|
||||
private String[] protocols;
|
||||
|
||||
public SSLCompat() {
|
||||
try {
|
||||
List<String> list = new LinkedList<>();
|
||||
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
|
||||
for (String protocol : socket.getSupportedProtocols()) if (!protocol.toUpperCase().contains("SSL")) list.add(protocol);
|
||||
protocols = list.toArray(new String[0]);
|
||||
List<String> allowedCiphers = Arrays.asList("TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECHDE_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
|
||||
List<String> availableCiphers = Arrays.asList(socket.getSupportedCipherSuites());
|
||||
HashSet<String> preferredCiphers = new HashSet<>(allowedCiphers);
|
||||
preferredCiphers.retainAll(availableCiphers);
|
||||
preferredCiphers.addAll(new HashSet<>(Arrays.asList(socket.getEnabledCipherSuites())));
|
||||
cipherSuites = preferredCiphers.toArray(new String[0]);
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, new X509TrustManager[]{TM}, null);
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(factory = context.getSocketFactory());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultCipherSuites() {
|
||||
return cipherSuites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedCipherSuites() {
|
||||
return cipherSuites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
||||
Socket ssl = factory.createSocket(s, host, port, autoClose);
|
||||
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port) throws IOException {
|
||||
Socket ssl = factory.createSocket(host, port);
|
||||
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
|
||||
Socket ssl = factory.createSocket(host, port, localHost, localPort);
|
||||
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||
Socket ssl = factory.createSocket(host, port);
|
||||
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
|
||||
Socket ssl = factory.createSocket(address, port, localAddress, localPort);
|
||||
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
|
||||
return ssl;
|
||||
}
|
||||
|
||||
private void upgradeTLS(SSLSocket ssl) {
|
||||
if (protocols != null) ssl.setEnabledProtocols(protocols);
|
||||
if (cipherSuites != null) ssl.setEnabledCipherSuites(cipherSuites);
|
||||
}
|
||||
|
||||
@SuppressLint({"TrustAllX509TrustManager", "CustomX509TrustManager"})
|
||||
public static final X509TrustManager TM = new X509TrustManager() {
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[]{};
|
||||
}
|
||||
};
|
||||
}
|
||||
291
app/src/main/java/com/github/catvod/spider/AList.java
Normal file
291
app/src/main/java/com/github/catvod/spider/AList.java
Normal file
@@ -0,0 +1,291 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Sub;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.alist.Drive;
|
||||
import com.github.catvod.bean.alist.Item;
|
||||
import com.github.catvod.bean.alist.Sorter;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AList extends Spider {
|
||||
|
||||
private List<Drive> drives;
|
||||
private String vodPic;
|
||||
private String ext;
|
||||
|
||||
private List<Filter> getFilter() {
|
||||
List<Filter> items = new ArrayList<>();
|
||||
items.add(new Filter("type", "排序類型", Arrays.asList(new Filter.Value("預設", ""), new Filter.Value("名稱", "name"), new Filter.Value("大小", "size"), new Filter.Value("修改時間", "date"))));
|
||||
items.add(new Filter("order", "排序方式", Arrays.asList(new Filter.Value("預設", ""), new Filter.Value("⬆", "asc"), new Filter.Value("⬇", "desc"))));
|
||||
return items;
|
||||
}
|
||||
|
||||
private void fetchRule() {
|
||||
if (drives != null && !drives.isEmpty()) return;
|
||||
if (ext.startsWith("http")) ext = OkHttp.string(ext);
|
||||
Drive drive = Drive.objectFrom(ext);
|
||||
drives = drive.getDrives();
|
||||
vodPic = drive.getVodPic();
|
||||
}
|
||||
|
||||
private Drive getDrive(String name) {
|
||||
return drives.get(drives.indexOf(new Drive(name))).check();
|
||||
}
|
||||
|
||||
private String post(Drive drive, String url, String param) {
|
||||
return post(drive, url, param, true);
|
||||
}
|
||||
|
||||
private String post(Drive drive, String url, String param, boolean retry) {
|
||||
String response = OkHttp.post(url, param, drive.getHeader()).getBody();
|
||||
SpiderDebug.log(response);
|
||||
if (retry && response.contains("Guest user is disabled") && login(drive)) return post(drive, url, param, false);
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
try {
|
||||
ext = extend;
|
||||
fetchRule();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
fetchRule();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
for (Drive drive : drives) if (!drive.hidden()) classes.add(drive.toType());
|
||||
for (Class item : classes) filters.put(item.getTypeId(), getFilter());
|
||||
return Result.string(classes, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
fetchRule();
|
||||
String type = extend.containsKey("type") ? extend.get("type") : "";
|
||||
String order = extend.containsKey("order") ? extend.get("order") : "";
|
||||
List<Item> folders = new ArrayList<>();
|
||||
List<Item> files = new ArrayList<>();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
|
||||
for (Item item : getList(tid, true)) {
|
||||
if (item.isFolder()) folders.add(item);
|
||||
else files.add(item);
|
||||
}
|
||||
if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(order)) {
|
||||
Sorter.sort(type, order, folders);
|
||||
Sorter.sort(type, order, files);
|
||||
}
|
||||
|
||||
for (Item item : folders) list.add(item.getVod(tid, vodPic));
|
||||
for (Item item : files) list.add(item.getVod(tid, vodPic));
|
||||
return Result.get().vod(list).page().string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
fetchRule();
|
||||
String id = ids.get(0);
|
||||
String key = id.contains("/") ? id.substring(0, id.indexOf("/")) : id;
|
||||
String path = id.substring(0, id.lastIndexOf("/"));
|
||||
String name = path.substring(path.lastIndexOf("/") + 1);
|
||||
Drive drive = getDrive(key);
|
||||
List<Item> parents = getList(path, false);
|
||||
Sorter.sort("name", "asc", parents);
|
||||
Vod vod = new Vod();
|
||||
vod.setVodPlayFrom(key);
|
||||
vod.setVodId(id);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPic(vodPic);
|
||||
List<String> playUrls = new ArrayList<>();
|
||||
for (Item item : parents) if (item.isMedia(drive.isNew())) playUrls.add(item.getName() + "$" + item.getVodId(path) + findSubs(path, parents));
|
||||
vod.setVodPlayUrl(TextUtils.join("#", playUrls));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String keyword, boolean quick) throws Exception {
|
||||
fetchRule();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Job> jobs = new ArrayList<>();
|
||||
ExecutorService executor = Executors.newCachedThreadPool();
|
||||
for (Drive drive : drives) if (drive.search()) jobs.add(new Job(drive.check(), keyword));
|
||||
for (Future<List<Vod>> future : executor.invokeAll(jobs, 15, TimeUnit.SECONDS)) list.addAll(future.get());
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
String[] ids = id.split("~~~");
|
||||
return Result.get().url(getDetail(ids[0]).getUrl()).subs(getSub(ids)).string();
|
||||
}
|
||||
|
||||
private boolean login(Drive drive) {
|
||||
try {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("username", drive.getLogin().getUsername());
|
||||
params.put("password", drive.getLogin().getPassword());
|
||||
String response = OkHttp.post(drive.loginApi(), params.toString());
|
||||
drive.setToken(new JSONObject(response).getJSONObject("data").getString("token"));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Item getDetail(String id) {
|
||||
try {
|
||||
String key = id.contains("/") ? id.substring(0, id.indexOf("/")) : id;
|
||||
String path = id.contains("/") ? id.substring(id.indexOf("/")) : "";
|
||||
Drive drive = getDrive(key);
|
||||
path = path.startsWith(drive.getPath()) ? path : drive.getPath() + path;
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("path", path);
|
||||
params.put("password", drive.findPass(path));
|
||||
String response = post(drive, drive.getApi(), params.toString());
|
||||
return Item.objectFrom(getDetailJson(drive.isNew(), response));
|
||||
} catch (Exception e) {
|
||||
return new Item();
|
||||
}
|
||||
}
|
||||
|
||||
private List<Item> getList(String id, boolean filter) {
|
||||
try {
|
||||
String key = id.contains("/") ? id.substring(0, id.indexOf("/")) : id;
|
||||
String path = id.contains("/") ? id.substring(id.indexOf("/")) : "";
|
||||
Drive drive = getDrive(key);
|
||||
path = path.startsWith(drive.getPath()) ? path : drive.getPath() + path;
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("path", path);
|
||||
params.put("password", drive.findPass(path));
|
||||
String response = post(drive, drive.listApi(), params.toString());
|
||||
List<Item> items = Item.arrayFrom(getListJson(drive.isNew(), response));
|
||||
Iterator<Item> iterator = items.iterator();
|
||||
if (filter) while (iterator.hasNext()) if (iterator.next().ignore(drive.isNew())) iterator.remove();
|
||||
return items;
|
||||
} catch (Exception e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private String getListJson(boolean isNew, String response) throws Exception {
|
||||
if (isNew) {
|
||||
return new JSONObject(response).getJSONObject("data").getJSONArray("content").toString();
|
||||
} else {
|
||||
return new JSONObject(response).getJSONObject("data").getJSONArray("files").toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String getDetailJson(boolean isNew, String response) throws Exception {
|
||||
if (isNew) {
|
||||
return new JSONObject(response).getJSONObject("data").toString();
|
||||
} else {
|
||||
return new JSONObject(response).getJSONObject("data").getJSONArray("files").getJSONObject(0).toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String getSearchJson(boolean isNew, String response) throws Exception {
|
||||
if (isNew) {
|
||||
return new JSONObject(response).getJSONObject("data").getJSONArray("content").toString();
|
||||
} else {
|
||||
return new JSONObject(response).getJSONArray("data").toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String findSubs(String path, List<Item> items) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Item item : items) if (Util.isSub(item.getExt())) sb.append("~~~").append(item.getName()).append("@@@").append(item.getExt()).append("@@@").append(item.getVodId(path));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<Sub> getSub(String[] ids) {
|
||||
List<Sub> sub = new ArrayList<>();
|
||||
for (String text : ids) {
|
||||
if (!text.contains("@@@")) continue;
|
||||
String[] split = text.split("@@@");
|
||||
String name = split[0];
|
||||
String ext = split[1];
|
||||
String url = getDetail(split[2]).getUrl();
|
||||
sub.add(Sub.create().name(name).ext(ext).url(url));
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
|
||||
class Job implements Callable<List<Vod>> {
|
||||
|
||||
private final Drive drive;
|
||||
private final String keyword;
|
||||
|
||||
public Job(Drive drive, String keyword) {
|
||||
this.drive = drive;
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Vod> call() {
|
||||
List<Vod> alist = alist();
|
||||
return alist.size() > 0 ? alist : xiaoya();
|
||||
}
|
||||
|
||||
private List<Vod> xiaoya() {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(drive.searchApi(keyword)));
|
||||
for (Element a : doc.select("ul > a")) {
|
||||
String[] splits = a.text().split("#");
|
||||
if (!splits[0].contains("/")) continue;
|
||||
int index = splits[0].lastIndexOf("/");
|
||||
boolean file = Util.isMedia(splits[0]);
|
||||
Item item = new Item();
|
||||
item.setType(file ? 0 : 1);
|
||||
item.setThumb(splits.length > 3 ? splits[4] : "");
|
||||
item.setPath("/" + splits[0].substring(0, index));
|
||||
item.setName(splits[0].substring(index + 1));
|
||||
list.add(item.getVod(drive, vodPic));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<Vod> alist() {
|
||||
try {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String response = post(drive, drive.searchApi(), drive.params(keyword));
|
||||
List<Item> items = Item.arrayFrom(getSearchJson(drive.isNew(), response));
|
||||
for (Item item : items) if (!item.ignore(drive.isNew())) list.add(item.getVod(drive, vodPic));
|
||||
return list;
|
||||
} catch (Exception e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
app/src/main/java/com/github/catvod/spider/Ali.java
Normal file
87
app/src/main/java/com/github/catvod/spider/Ali.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.api.AliYun;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author ColaMint & Adam & FongMi
|
||||
*/
|
||||
public class Ali extends Spider {
|
||||
|
||||
public static final Pattern pattern = Pattern.compile("(www.aliyundrive.com|www.alipan.com)/s/([^/]+)(/folder/([^/]+))?");
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
AliYun.get().setRefreshToken(extend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String id = ids.get(0).trim();
|
||||
Matcher matcher = pattern.matcher(id);
|
||||
return matcher.find() ? Result.string(parseVod(matcher, id)) : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
return AliYun.get().playerContent(id.split("\\+"), flag);
|
||||
}
|
||||
|
||||
private Vod parseVod(Matcher matcher, String id) {
|
||||
String shareId = matcher.group(2);
|
||||
String fileId = matcher.groupCount() == 4 ? matcher.group(4) : "";
|
||||
return AliYun.get().getVod(id, shareId, fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取詳情內容視頻播放來源(多 shared_link)
|
||||
*
|
||||
* @param ids share_link 集合
|
||||
* @return 詳情內容視頻播放來源
|
||||
*/
|
||||
public String detailContentVodPlayFrom(List<String> ids) {
|
||||
List<String> playFrom = new ArrayList<>();
|
||||
if (ids.size() < 2) return TextUtils.join("$$$", Arrays.asList("轉存原畫", "分享原畫", "代理普畫"));
|
||||
for (int i = 1; i <= ids.size(); i++) {
|
||||
playFrom.add(String.format(Locale.getDefault(), "轉存原畫#%02d", i));
|
||||
playFrom.add(String.format(Locale.getDefault(), "分享原畫#%02d", i));
|
||||
playFrom.add(String.format(Locale.getDefault(), "代理普畫#%02d", i));
|
||||
}
|
||||
return TextUtils.join("$$$", playFrom);
|
||||
}
|
||||
|
||||
/**
|
||||
* 獲取詳情內容視頻播放地址(多 share_link)
|
||||
*
|
||||
* @param ids share_link 集合
|
||||
* @return 詳情內容視頻播放地址
|
||||
*/
|
||||
public String detailContentVodPlayUrl(List<String> ids) {
|
||||
List<String> playUrl = new ArrayList<>();
|
||||
for (String id : ids) {
|
||||
Matcher matcher = pattern.matcher(id);
|
||||
if (matcher.find()) playUrl.add(parseVod(matcher, id).getVodPlayUrl());
|
||||
}
|
||||
return TextUtils.join("$$$", playUrl);
|
||||
}
|
||||
|
||||
public static Object[] proxy(Map<String, String> params) throws Exception {
|
||||
String type = params.get("type");
|
||||
if ("video".equals(type)) return AliYun.get().proxyVideo(params);
|
||||
if ("sub".equals(type)) return AliYun.get().proxySub(params);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
820
app/src/main/java/com/github/catvod/spider/AppYsV2.java
Normal file
820
app/src/main/java/com/github/catvod/spider/AppYsV2.java
Normal file
@@ -0,0 +1,820 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* M浏览器中的App影视
|
||||
* Author: 群友 不负此生
|
||||
*/
|
||||
public class AppYsV2 extends Spider {
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
super.init(context, extend);
|
||||
try {
|
||||
extInfos = extend.split("###");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
String url = getCateUrl(getApiUrl());
|
||||
JSONArray jsonArray = null;
|
||||
if (!url.isEmpty()) {
|
||||
SpiderDebug.log(url);
|
||||
String json = OkHttp.string(url, getHeaders(url));
|
||||
JSONObject obj = new JSONObject(json);
|
||||
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONArray("list");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONArray("data");
|
||||
}
|
||||
} else { // 通过filter列表读分类
|
||||
String filterStr = getFilterTypes(url, null);
|
||||
String[] classes = filterStr.split("\n")[0].split("\\+");
|
||||
jsonArray = new JSONArray();
|
||||
for (int i = 1; i < classes.length; i++) {
|
||||
String[] kv = classes[i].trim().split("=");
|
||||
if (kv.length < 2) continue;
|
||||
JSONObject newCls = new JSONObject();
|
||||
newCls.put("type_name", kv[0].trim());
|
||||
newCls.put("type_id", kv[1].trim());
|
||||
jsonArray.put(newCls);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray classes = new JSONArray();
|
||||
if (jsonArray != null) {
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jObj = jsonArray.getJSONObject(i);
|
||||
String typeName = jObj.getString("type_name");
|
||||
String typeId = jObj.getString("type_id");
|
||||
JSONObject newCls = new JSONObject();
|
||||
newCls.put("type_id", typeId);
|
||||
newCls.put("type_name", typeName);
|
||||
JSONObject typeExtend = jObj.optJSONObject("type_extend");
|
||||
if (filter) {
|
||||
String filterStr = getFilterTypes(url, typeExtend);
|
||||
String[] filters = filterStr.split("\n");
|
||||
JSONArray filterArr = new JSONArray();
|
||||
for (int k = url.isEmpty() ? 1 : 0; k < filters.length; k++) {
|
||||
String l = filters[k].trim();
|
||||
if (l.isEmpty()) continue;
|
||||
String[] oneLine = l.split("\\+");
|
||||
String type = oneLine[0].trim();
|
||||
String typeN = type;
|
||||
if (type.contains("筛选")) {
|
||||
type = type.replace("筛选", "");
|
||||
switch (type) {
|
||||
case "class":
|
||||
typeN = "类型";
|
||||
break;
|
||||
case "area":
|
||||
typeN = "地区";
|
||||
break;
|
||||
case "lang":
|
||||
typeN = "语言";
|
||||
break;
|
||||
case "year":
|
||||
typeN = "年份";
|
||||
break;
|
||||
}
|
||||
}
|
||||
JSONObject jOne = new JSONObject();
|
||||
jOne.put("key", type);
|
||||
jOne.put("name", typeN);
|
||||
JSONArray valueArr = new JSONArray();
|
||||
for (int j = 1; j < oneLine.length; j++) {
|
||||
JSONObject kvo = new JSONObject();
|
||||
String kv = oneLine[j].trim();
|
||||
int sp = kv.indexOf("=");
|
||||
if (sp == -1) {
|
||||
kvo.put("n", kv);
|
||||
kvo.put("v", kv);
|
||||
} else {
|
||||
String n = kv.substring(0, sp);
|
||||
kvo.put("n", n.trim());
|
||||
kvo.put("v", kv.substring(sp + 1).trim());
|
||||
}
|
||||
valueArr.put(kvo);
|
||||
}
|
||||
jOne.put("value", valueArr);
|
||||
filterArr.put(jOne);
|
||||
}
|
||||
if (!result.has("filters")) {
|
||||
result.put("filters", new JSONObject());
|
||||
}
|
||||
result.getJSONObject("filters").put(typeId, filterArr);
|
||||
}
|
||||
classes.put(newCls);
|
||||
}
|
||||
}
|
||||
result.put("class", classes);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() throws Exception {
|
||||
String apiUrl = getApiUrl();
|
||||
String url = getRecommendUrl(apiUrl);
|
||||
boolean isTV = false;
|
||||
if (url.isEmpty()) {
|
||||
url = getCateFilterUrlPrefix(apiUrl) + "movie&page=1&area=&type=&start=";
|
||||
isTV = true;
|
||||
}
|
||||
SpiderDebug.log(url);
|
||||
String json = OkHttp.string(url, getHeaders(url));
|
||||
JSONObject obj = new JSONObject(json);
|
||||
JSONArray videos = new JSONArray();
|
||||
if (isTV) {
|
||||
JSONArray jsonArray = obj.getJSONArray("data");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("nextlink"));
|
||||
v.put("vod_name", vObj.getString("title"));
|
||||
v.put("vod_pic", vObj.getString("pic"));
|
||||
v.put("vod_remarks", vObj.getString("state"));
|
||||
videos.put(v);
|
||||
}
|
||||
} else {
|
||||
ArrayList<JSONArray> arrays = new ArrayList<>();
|
||||
findJsonArray(obj, "vlist", arrays);
|
||||
if (arrays.isEmpty()) {
|
||||
findJsonArray(obj, "vod_list", arrays);
|
||||
}
|
||||
List<String> ids = new ArrayList<>();
|
||||
for (JSONArray jsonArray : arrays) {
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
String vid = vObj.getString("vod_id");
|
||||
if (ids.contains(vid)) continue;
|
||||
ids.add(vid);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vid);
|
||||
v.put("vod_name", vObj.getString("vod_name"));
|
||||
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String apiUrl = getApiUrl();
|
||||
String url = getCateFilterUrlPrefix(apiUrl) + tid + getCateFilterUrlSuffix(apiUrl);
|
||||
url = url.replace("#PN#", pg);
|
||||
url = url.replace("筛选class", (extend != null && extend.containsKey("class")) ? extend.get("class") : "");
|
||||
url = url.replace("筛选area", (extend != null && extend.containsKey("area")) ? extend.get("area") : "");
|
||||
url = url.replace("筛选lang", (extend != null && extend.containsKey("lang")) ? extend.get("lang") : "");
|
||||
url = url.replace("筛选year", (extend != null && extend.containsKey("year")) ? extend.get("year") : "");
|
||||
url = url.replace("排序", (extend != null && extend.containsKey("排序")) ? extend.get("排序") : "");
|
||||
SpiderDebug.log(url);
|
||||
String json = OkHttp.string(url, getHeaders(url));
|
||||
JSONObject obj = new JSONObject(json);
|
||||
int totalPg = Integer.MAX_VALUE;
|
||||
try {
|
||||
if (obj.has("totalpage") && obj.get("totalpage") instanceof Integer) {
|
||||
totalPg = obj.getInt("totalpage");
|
||||
} else if (obj.has("pagecount") && obj.get("pagecount") instanceof Integer) {
|
||||
totalPg = obj.getInt("pagecount");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && (obj.getJSONObject("data").has("total") && obj.getJSONObject("data").get("total") instanceof Integer && obj.getJSONObject("data").has("limit") && obj.getJSONObject("data").get("limit") instanceof Integer)) {
|
||||
int limit = obj.getJSONObject("data").getInt("limit");
|
||||
int total = obj.getJSONObject("data").getInt("total");
|
||||
totalPg = total % limit == 0 ? (total / limit) : (total / limit + 1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
|
||||
JSONArray jsonArray = null;
|
||||
JSONArray videos = new JSONArray();
|
||||
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONArray("list");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONArray("data");
|
||||
}
|
||||
if (jsonArray != null) {
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
if (vObj.has("vod_id")) {
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("vod_id"));
|
||||
v.put("vod_name", vObj.getString("vod_name"));
|
||||
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||
videos.put(v);
|
||||
} else {
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("nextlink"));
|
||||
v.put("vod_name", vObj.getString("title"));
|
||||
v.put("vod_pic", vObj.getString("pic"));
|
||||
v.put("vod_remarks", vObj.getString("state"));
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("page", pg);
|
||||
result.put("pagecount", totalPg);
|
||||
result.put("limit", 90);
|
||||
result.put("total", Integer.MAX_VALUE);
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String apiUrl = getApiUrl();
|
||||
String url = getPlayUrlPrefix(apiUrl) + ids.get(0);
|
||||
SpiderDebug.log(url);
|
||||
String json = OkHttp.string(url, getHeaders(url));
|
||||
JSONObject obj = new JSONObject(json);
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vod = new JSONObject();
|
||||
genPlayList(apiUrl, obj, json, vod, ids.get(0));
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vod);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
String apiUrl = getApiUrl();
|
||||
String url = getSearchUrl(apiUrl, URLEncoder.encode(key));
|
||||
String json = OkHttp.string(url, getHeaders(url));
|
||||
JSONObject obj = new JSONObject(json);
|
||||
JSONArray jsonArray = null;
|
||||
JSONArray videos = new JSONArray();
|
||||
if (obj.has("list") && obj.get("list") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONArray("list");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONObject && obj.getJSONObject("data").has("list") && obj.getJSONObject("data").get("list") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONObject("data").getJSONArray("list");
|
||||
} else if (obj.has("data") && obj.get("data") instanceof JSONArray) {
|
||||
jsonArray = obj.getJSONArray("data");
|
||||
}
|
||||
if (jsonArray != null) {
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
if (vObj.has("vod_id")) {
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("vod_id"));
|
||||
v.put("vod_name", vObj.getString("vod_name"));
|
||||
v.put("vod_pic", vObj.getString("vod_pic"));
|
||||
v.put("vod_remarks", vObj.getString("vod_remarks"));
|
||||
videos.put(v);
|
||||
} else {
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("nextlink"));
|
||||
v.put("vod_name", vObj.getString("title"));
|
||||
v.put("vod_pic", vObj.getString("pic"));
|
||||
v.put("vod_remarks", vObj.getString("state"));
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
if (flag.contains("fanqie") && Util.isVideoFormat(id)) {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
return result.toString();
|
||||
}
|
||||
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||
if (parseUrls == null) parseUrls = new ArrayList<>();
|
||||
if (!parseUrls.isEmpty()) {
|
||||
JSONObject result = getFinalVideo(flag, parseUrls, id);
|
||||
if (result != null) return result.toString();
|
||||
}
|
||||
if (Util.isVideoFormat(id)) {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
return result.toString();
|
||||
} else {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 1);
|
||||
result.put("jx", "1");
|
||||
result.put("url", id);
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private void findJsonArray(JSONObject obj, String match, ArrayList<JSONArray> result) {
|
||||
Iterator<String> keys = obj.keys();
|
||||
while (keys.hasNext()) {
|
||||
String k = keys.next();
|
||||
try {
|
||||
Object o = obj.get(k);
|
||||
if (k.equals(match) && o instanceof JSONArray) result.add((JSONArray) o);
|
||||
if (o instanceof JSONObject) {
|
||||
findJsonArray((JSONObject) o, match, result);
|
||||
} else if (o instanceof JSONArray) {
|
||||
JSONArray array = (JSONArray) o;
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
findJsonArray(array.getJSONObject(i), match, result);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String jsonArr2Str(JSONArray array) {
|
||||
try {
|
||||
ArrayList<String> strings = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
strings.add(array.getString(i));
|
||||
}
|
||||
return TextUtils.join(",", strings);
|
||||
} catch (JSONException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaders(String URL) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", UA(URL));
|
||||
return headers;
|
||||
}
|
||||
|
||||
// M 扩展方法
|
||||
// ######重组搜索
|
||||
private String getSearchUrl(String URL, String KEY) {
|
||||
if (URL.contains(".vod")) {
|
||||
if (URL.contains("iopenyun.com")) {
|
||||
return URL + "/list?wd=" + KEY + "&page=";
|
||||
} else {
|
||||
return URL + "?wd=" + KEY + "&page=";
|
||||
}
|
||||
} else if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
return URL + "search?text=" + KEY + "&pg=";
|
||||
} else if (urlPattern1.matcher(URL).find()) {
|
||||
if (URL.contains("esellauto") || URL.contains("1.14.63.101") || URL.contains("zjys") || URL.contains("dcd") || URL.contains("lxue") || URL.contains("weetai.cn") || URL.contains("haokanju1") || URL.contains("fit:8") || URL.contains("zjj.life") || URL.contains("love9989") || URL.contains("8d8q") || URL.contains("lk.pxun") || URL.contains("hgyx") || URL.contains("521x5") || URL.contains("lxyyy") || URL.contains("0818tv") || URL.contains("diyoui") || URL.contains("diliktv") || URL.contains("ppzhu") || URL.contains("aitesucai") || URL.contains("zz.ci") || URL.contains("chxjon") || URL.contains("watchmi") || URL.contains("vipbp") || URL.contains("bhtv") || URL.contains("xfykl")) {
|
||||
return URL + "?ac=list&" + "wd=" + KEY + "&page=";
|
||||
} else {
|
||||
return URL + "?ac=list&" + "zm=" + KEY + "&page=";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// ######UA
|
||||
private static final Pattern urlPattern1 = Pattern.compile("api\\.php/.*?/vod");
|
||||
private static final Pattern urlPattern2 = Pattern.compile("api\\.php/.+?\\.vod");
|
||||
private static final Pattern parsePattern = Pattern.compile("/.+\\?.+=");
|
||||
private static final Pattern parsePattern1 = Pattern.compile(".*(url|v|vid|php\\?id)=");
|
||||
private static final Pattern parsePattern2 = Pattern.compile("https?://[^/]*");
|
||||
|
||||
protected static final Pattern[] htmlVideoKeyMatch = new Pattern[]{Pattern.compile("player=new"), Pattern.compile("<div id=\"video\""), Pattern.compile("<div id=\"[^\"]*?player\""), Pattern.compile("//视频链接"), Pattern.compile("HlsJsPlayer\\("), Pattern.compile("<iframe[\\s\\S]*?src=\"[^\"]+?\""), Pattern.compile("<video[\\s\\S]*?src=\"[^\"]+?\"")};
|
||||
|
||||
private String UA(String URL) {
|
||||
if (URL.contains("vod.9e03.com")) {
|
||||
return "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36";
|
||||
} else if (URL.contains("api.php/app") || URL.contains("xgapp") || URL.contains("freekan")) {
|
||||
return "Dart/2.14 (dart:io)";
|
||||
} else if (URL.contains("zsb") || URL.contains("fkxs") || URL.contains("xays") || URL.contains("xcys") || URL.contains("szys") || URL.contains("dxys") || URL.contains("ytys") || URL.contains("qnys")) {
|
||||
return "Dart/2.15 (dart:io)";
|
||||
} else if (URL.contains(".vod")) {
|
||||
return "okhttp/4.1.0";
|
||||
} else {
|
||||
return "Dalvik/2.1.0";
|
||||
}
|
||||
}
|
||||
|
||||
// ######获取分类地址
|
||||
String getCateUrl(String URL) {
|
||||
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
return URL + "nav?token=";
|
||||
} else if (URL.contains(".vod")) {
|
||||
if (URL.contains("iopenyun.com")) {
|
||||
return URL + "/list?type";
|
||||
} else {
|
||||
return URL + "/types";
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// ######分类筛选前缀地址
|
||||
String getCateFilterUrlPrefix(String URL) {
|
||||
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
if (URL.contains("dijiaxia")) {
|
||||
URL = "http://www.dijiaxia.com/api.php/app/";
|
||||
return URL + "video?tid=";
|
||||
} else {
|
||||
return URL + "video?tid=";
|
||||
}
|
||||
} else if (URL.contains(".vod")) {
|
||||
if (URL.contains("tv.bulei.cc")) {
|
||||
return "https://tv.bulei.cc/api2.php/v1.vod?type=";
|
||||
}
|
||||
if (URL.contains("iopenyun")) {
|
||||
return URL + "/list?type=";
|
||||
} else {
|
||||
return URL + "?type=";
|
||||
}
|
||||
} else {
|
||||
return URL + "?ac=list&class=";
|
||||
}
|
||||
}
|
||||
|
||||
// ######分类筛选后缀地址
|
||||
String getCateFilterUrlSuffix(String URL) {
|
||||
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&limit=18&pg=#PN#";
|
||||
} else if (URL.contains(".vod")) {
|
||||
return "&class=筛选class&area=筛选area&lang=筛选lang&year=筛选year&by=排序&limit=18&page=#PN#";
|
||||
} else {
|
||||
return "&page=#PN#&area=筛选area&type=筛选class&start=筛选year";
|
||||
}
|
||||
}
|
||||
|
||||
// ######筛选内容
|
||||
String getFilterTypes(String URL, JSONObject typeExtend) {
|
||||
String str = "";
|
||||
if (typeExtend != null) {
|
||||
Iterator<String> typeExtendKeys = typeExtend.keys();
|
||||
while (typeExtendKeys.hasNext()) {
|
||||
String key = typeExtendKeys.next();
|
||||
if (key.equals("class") || key.equals("area") || key.equals("lang") || key.equals("year")) {
|
||||
try {
|
||||
str = str + "筛选" + key + "+全部=+" + typeExtend.getString(key).replace(",", "+") + "\n";
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (URL.contains(".vod")) {
|
||||
str += "\n" + "排序+全部=+最新=time+最热=hits+评分=score";
|
||||
} else if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
} else {
|
||||
str = "分类+全部=+电影=movie+连续剧=tvplay+综艺=tvshow+动漫=comic+4K=movie_4k+体育=tiyu\n筛选class+全部=+喜剧+爱情+恐怖+动作+科幻+剧情+战争+警匪+犯罪+动画+奇幻+武侠+冒险+枪战+恐怖+悬疑+惊悚+经典+青春+文艺+微电影+古装+历史+运动+农村+惊悚+惊悚+伦理+情色+福利+三级+儿童+网络电影\n筛选area+全部=+大陆+香港+台湾+美国+英国+法国+日本+韩国+德国+泰国+印度+西班牙+加拿大+其他\n筛选year+全部=+2023+2022+2021+2020+2019+2018+2017+2016+2015+2014+2013+2012+2011+2010+2009+2008+2007+2006+2005+2004+2003+2002+2001+2000";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// ######推荐地址
|
||||
String getRecommendUrl(String URL) {
|
||||
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
return URL + "index_video?token=";
|
||||
} else if (URL.contains(".vod")) {
|
||||
return URL + "/vodPhbAll";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// ######播放器前缀地址
|
||||
String getPlayUrlPrefix(String URL) {
|
||||
if (URL.contains("api.php/app") || URL.contains("xgapp")) {
|
||||
if (URL.contains("dijiaxia")) {
|
||||
URL = "https://www.dijiaxia.com/api.php/app/";
|
||||
return URL + "video_detail?id=";
|
||||
} else if (URL.contains("1010dy")) {
|
||||
URL = "http://www.1010dy.cc/api.php/app/";
|
||||
return URL + "video_detail?id=";
|
||||
} else {
|
||||
return URL + "video_detail?id=";
|
||||
}
|
||||
} else if (URL.contains(".vod")) {
|
||||
if (URL.contains("iopenyun")) {
|
||||
return URL + "/detailID?vod_id=";
|
||||
} else {
|
||||
return URL + "/detail?vod_id=";
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// ######选集
|
||||
protected final HashMap<String, ArrayList<String>> parseUrlMap = new HashMap<>();
|
||||
|
||||
private void genPlayList(String URL, JSONObject object, String json, JSONObject vod, String vid) throws JSONException {
|
||||
ArrayList<String> playUrls = new ArrayList<>();
|
||||
ArrayList<String> playFlags = new ArrayList<>();
|
||||
if (URL.contains("api.php/app/")) {
|
||||
JSONObject data = object.getJSONObject("data");
|
||||
vod.put("vod_id", data.optString("vod_id", vid));
|
||||
vod.put("vod_name", data.getString("vod_name"));
|
||||
vod.put("vod_pic", data.getString("vod_pic"));
|
||||
vod.put("type_name", data.optString("vod_class"));
|
||||
vod.put("vod_year", data.optString("vod_year"));
|
||||
vod.put("vod_area", data.optString("vod_area"));
|
||||
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||
vod.put("vod_actor", data.optString("vod_actor"));
|
||||
vod.put("vod_director", data.optString("vod_director"));
|
||||
vod.put("vod_content", data.optString("vod_content"));
|
||||
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_url_with_player");
|
||||
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||
String flag = from.optString("code").trim();
|
||||
if (flag.isEmpty()) flag = from.getString("name").trim();
|
||||
playFlags.add(flag);
|
||||
playUrls.add(from.getString("url"));
|
||||
String purl = from.optString("parse_api").trim();
|
||||
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||
if (parseUrls == null) {
|
||||
parseUrls = new ArrayList<>();
|
||||
parseUrlMap.put(flag, parseUrls);
|
||||
}
|
||||
if (!purl.isEmpty() && !parseUrls.contains(purl)) parseUrls.add(purl);
|
||||
}
|
||||
} else if (URL.contains("xgapp")) {
|
||||
JSONObject data = object.getJSONObject("data").getJSONObject("vod_info");
|
||||
vod.put("vod_id", data.optString("vod_id", vid));
|
||||
vod.put("vod_name", data.getString("vod_name"));
|
||||
vod.put("vod_pic", data.getString("vod_pic"));
|
||||
vod.put("type_name", data.optString("vod_class"));
|
||||
vod.put("vod_year", data.optString("vod_year"));
|
||||
vod.put("vod_area", data.optString("vod_area"));
|
||||
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||
vod.put("vod_actor", data.optString("vod_actor"));
|
||||
vod.put("vod_director", data.optString("vod_director"));
|
||||
vod.put("vod_content", data.optString("vod_content"));
|
||||
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_url_with_player");
|
||||
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||
String flag = from.optString("code").trim();
|
||||
if (flag.isEmpty()) flag = from.getString("name").trim();
|
||||
playFlags.add(flag);
|
||||
playUrls.add(from.getString("url"));
|
||||
String purl = from.optString("parse_api").trim();
|
||||
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||
if (parseUrls == null) {
|
||||
parseUrls = new ArrayList<>();
|
||||
parseUrlMap.put(flag, parseUrls);
|
||||
}
|
||||
if (!purl.isEmpty() && !parseUrls.contains(purl)) parseUrls.add(purl);
|
||||
}
|
||||
} else if (/*urlPattern2.matcher(URL).find()*/URL.contains(".vod")) {
|
||||
JSONObject data = object.getJSONObject("data");
|
||||
vod.put("vod_id", data.optString("vod_id", vid));
|
||||
vod.put("vod_name", data.getString("vod_name"));
|
||||
vod.put("vod_pic", data.getString("vod_pic"));
|
||||
vod.put("type_name", data.optString("vod_class"));
|
||||
vod.put("vod_year", data.optString("vod_year"));
|
||||
vod.put("vod_area", data.optString("vod_area"));
|
||||
vod.put("vod_remarks", data.optString("vod_remarks"));
|
||||
vod.put("vod_actor", data.optString("vod_actor"));
|
||||
vod.put("vod_director", data.optString("vod_director"));
|
||||
vod.put("vod_content", data.optString("vod_content"));
|
||||
JSONArray vodUrlWithPlayer = data.getJSONArray("vod_play_list");
|
||||
for (int i = 0; i < vodUrlWithPlayer.length(); i++) {
|
||||
JSONObject from = vodUrlWithPlayer.getJSONObject(i);
|
||||
String flag = from.getJSONObject("player_info").optString("from").trim();
|
||||
if (flag.isEmpty()) flag = from.getJSONObject("player_info").optString("show").trim();
|
||||
playFlags.add(flag);
|
||||
playUrls.add(from.getString("url"));
|
||||
try {
|
||||
ArrayList<String> parses = new ArrayList<>();
|
||||
String[] parse1 = from.getJSONObject("player_info").optString("parse").split(",");
|
||||
String[] parse2 = from.getJSONObject("player_info").optString("parse2").split(",");
|
||||
parses.addAll(Arrays.asList(parse1));
|
||||
parses.addAll(Arrays.asList(parse2));
|
||||
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||
if (parseUrls == null) {
|
||||
parseUrls = new ArrayList<>();
|
||||
parseUrlMap.put(flag, parseUrls);
|
||||
}
|
||||
for (String purl : parses) {
|
||||
if (purl.contains("http")) {
|
||||
Matcher matcher = parsePattern1.matcher(purl);
|
||||
if (matcher.find()) {
|
||||
purl = matcher.group(0);
|
||||
}
|
||||
} else if (purl.contains("//")) {
|
||||
Matcher matcher = parsePattern1.matcher(purl);
|
||||
if (matcher.find()) {
|
||||
purl = "http:" + matcher.group(0);
|
||||
}
|
||||
} else {
|
||||
Matcher matcher = parsePattern2.matcher(URL);
|
||||
if (matcher.find()) {
|
||||
Matcher matcher1 = parsePattern1.matcher(URL);
|
||||
if (matcher1.find()) {
|
||||
purl = matcher.group(0) + matcher1.group(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
purl = purl.replace("..", ".").trim();
|
||||
if (!purl.isEmpty() && !parseUrls.contains(purl)) parseUrls.add(purl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
} else if (urlPattern1.matcher(URL).find()) {
|
||||
JSONObject data = object;
|
||||
vod.put("vod_id", data.optString("vod_id", vid));
|
||||
vod.put("vod_name", data.getString("title"));
|
||||
vod.put("vod_pic", data.getString("img_url"));
|
||||
vod.put("type_name", jsonArr2Str(data.optJSONArray("type")));
|
||||
vod.put("vod_year", data.optString("pubtime"));
|
||||
vod.put("vod_area", jsonArr2Str(data.optJSONArray("area")));
|
||||
vod.put("vod_remarks", data.optString("trunk"));
|
||||
vod.put("vod_actor", jsonArr2Str(data.optJSONArray("actor")));
|
||||
vod.put("vod_director", jsonArr2Str(data.optJSONArray("director")));
|
||||
vod.put("vod_content", data.optString("intro"));
|
||||
JSONObject playList = data.getJSONObject("videolist");
|
||||
Iterator<String> playListKeys = playList.keys();
|
||||
while (playListKeys.hasNext()) {
|
||||
String flag = playListKeys.next();
|
||||
ArrayList<String> parseUrls = parseUrlMap.get(flag);
|
||||
if (parseUrls == null) {
|
||||
parseUrls = new ArrayList<>();
|
||||
parseUrlMap.put(flag, parseUrls);
|
||||
}
|
||||
JSONArray playListUrls = playList.getJSONArray(flag);
|
||||
ArrayList<String> urls = new ArrayList<>();
|
||||
for (int j = 0; j < playListUrls.length(); j++) {
|
||||
JSONObject urlObj = playListUrls.getJSONObject(j);
|
||||
String url = urlObj.getString("url");
|
||||
if (url.contains("url=")) {
|
||||
int spIdx = url.indexOf("url=") + 4;
|
||||
String pUrl = url.substring(0, spIdx).trim();
|
||||
if (!pUrl.isEmpty() && !parseUrls.contains(pUrl)) parseUrls.add(pUrl);
|
||||
urls.add(urlObj.getString("title") + "$" + url.substring(spIdx).trim());
|
||||
} else {
|
||||
urls.add(urlObj.getString("title") + "$" + url);
|
||||
}
|
||||
}
|
||||
playFlags.add(flag);
|
||||
playUrls.add(TextUtils.join("#", urls));
|
||||
}
|
||||
}
|
||||
vod.put("vod_play_from", TextUtils.join("$$$", playFlags));
|
||||
vod.put("vod_play_url", TextUtils.join("$$$", playUrls));
|
||||
}
|
||||
|
||||
// ######视频地址
|
||||
protected JSONObject getFinalVideo(String flag, ArrayList<String> parseUrls, String url) throws JSONException {
|
||||
String htmlPlayUrl = "";
|
||||
for (String parseUrl : parseUrls) {
|
||||
if (parseUrl.isEmpty() || parseUrl.equals("null")) continue;
|
||||
String playUrl = parseUrl + url;
|
||||
String content = OkHttp.string(playUrl);
|
||||
JSONObject tryJson = null;
|
||||
try {
|
||||
tryJson = jsonParse(url, content);
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
if (tryJson != null && tryJson.has("url") && tryJson.has("header")) {
|
||||
tryJson.put("header", tryJson.getJSONObject("header").toString());
|
||||
return tryJson;
|
||||
}
|
||||
if (content.contains("<html")) {
|
||||
boolean sniffer = false;
|
||||
for (Pattern p : htmlVideoKeyMatch) {
|
||||
if (p.matcher(content).find()) {
|
||||
sniffer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sniffer) {
|
||||
htmlPlayUrl = parseUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!htmlPlayUrl.isEmpty()) {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 1);
|
||||
result.put("playUrl", htmlPlayUrl);
|
||||
result.put("url", url);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean manualVideoCheck() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideoFormat(String url) {
|
||||
return Util.isVideoFormat(url);
|
||||
}
|
||||
|
||||
private String getApiUrl() {
|
||||
if (extInfos == null || extInfos.length < 1) return "";
|
||||
return extInfos[0].trim();
|
||||
}
|
||||
|
||||
private String[] extInfos = null;
|
||||
|
||||
public static JSONObject jsonParse(String input, String json) throws JSONException {
|
||||
//处理解析接口返回的报文,如果返回的报文中包含header信息,就加到返回值中
|
||||
JSONObject jsonPlayData = new JSONObject(json);
|
||||
if (jsonPlayData.has("data") && jsonPlayData.get("data") instanceof JSONObject && !jsonPlayData.has("url")) {
|
||||
jsonPlayData = jsonPlayData.getJSONObject("data");
|
||||
}
|
||||
String url = jsonPlayData.getString("url");
|
||||
if (url.startsWith("//")) {
|
||||
url = "https:" + url;
|
||||
}
|
||||
if (!url.trim().startsWith("http")) {
|
||||
return null;
|
||||
}
|
||||
if (url.equals(input)) {
|
||||
if (Util.isVip(url) || !Util.isVideoFormat(url)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (Util.isBlackVodUrl(url)) {
|
||||
return null;
|
||||
}
|
||||
JSONObject headers = new JSONObject();
|
||||
if (jsonPlayData.has("header")) {
|
||||
headers = jsonPlayData.optJSONObject("header");
|
||||
} else if (jsonPlayData.has("Header")) {
|
||||
headers = jsonPlayData.optJSONObject("Header");
|
||||
} else if (jsonPlayData.has("headers")) {
|
||||
headers = jsonPlayData.optJSONObject("headers");
|
||||
} else if (jsonPlayData.has("Headers")) {
|
||||
headers = jsonPlayData.optJSONObject("Headers");
|
||||
}
|
||||
String ua = "";
|
||||
if (jsonPlayData.has("user-agent")) {
|
||||
ua = jsonPlayData.optString("user-agent", "");
|
||||
} else if (jsonPlayData.has("User-Agent")) {
|
||||
ua = jsonPlayData.optString("User-Agent", "");
|
||||
}
|
||||
if (ua.trim().length() > 0) {
|
||||
headers.put("User-Agent", " " + ua);
|
||||
}
|
||||
String referer = "";
|
||||
if (jsonPlayData.has("referer")) {
|
||||
referer = jsonPlayData.optString("referer", "");
|
||||
} else if (jsonPlayData.has("Referer")) {
|
||||
referer = jsonPlayData.optString("Referer", "");
|
||||
}
|
||||
if (referer.trim().length() > 0) {
|
||||
headers.put("Referer", " " + referer);
|
||||
}
|
||||
|
||||
headers = fixJsonVodHeader(headers, input, url);
|
||||
JSONObject taskResult = new JSONObject();
|
||||
taskResult.put("header", headers);
|
||||
taskResult.put("url", url);
|
||||
taskResult.put("parse", "0");
|
||||
return taskResult;
|
||||
}
|
||||
|
||||
public static JSONObject fixJsonVodHeader(JSONObject headers, String input, String url) throws JSONException {
|
||||
if (headers == null) headers = new JSONObject();
|
||||
if (input.contains("www.mgtv.com")) {
|
||||
headers.put("Referer", " ");
|
||||
headers.put("User-Agent", " Mozilla/5.0");
|
||||
} else if (url.contains("titan.mgtv")) {
|
||||
headers.put("Referer", " ");
|
||||
headers.put("User-Agent", " Mozilla/5.0");
|
||||
} else if (input.contains("bilibili")) {
|
||||
headers.put("Referer", " https://www.bilibili.com/");
|
||||
headers.put("User-Agent", " " + Util.CHROME);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
280
app/src/main/java/com/github/catvod/spider/Bili.java
Normal file
280
app/src/main/java/com/github/catvod/spider/Bili.java
Normal file
@@ -0,0 +1,280 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.bili.Dash;
|
||||
import com.github.catvod.bean.bili.Data;
|
||||
import com.github.catvod.bean.bili.Media;
|
||||
import com.github.catvod.bean.bili.Page;
|
||||
import com.github.catvod.bean.bili.Resp;
|
||||
import com.github.catvod.bean.bili.Wbi;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ColaMint & FongMi & 唐三
|
||||
*/
|
||||
public class Bili extends Spider {
|
||||
|
||||
private static final String COOKIE = "buvid3=84B0395D-C9F2-C490-E92E-A09AB48FE26E71636infoc";
|
||||
private static Map<String, String> audios;
|
||||
private static String cookie;
|
||||
|
||||
private JsonObject extend;
|
||||
private boolean login;
|
||||
private boolean isVip;
|
||||
private Wbi wbi;
|
||||
|
||||
private static Map<String, String> getHeader() {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
headers.put("Referer", "https://www.bilibili.com");
|
||||
if (cookie != null) headers.put("cookie", cookie);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private void setAudio() {
|
||||
audios = new HashMap<>();
|
||||
audios.put("30280", "192000");
|
||||
audios.put("30232", "132000");
|
||||
audios.put("30216", "64000");
|
||||
}
|
||||
|
||||
private void setCookie() {
|
||||
cookie = extend.get("cookie").getAsString();
|
||||
if (cookie.startsWith("http")) cookie = OkHttp.string(cookie).trim();
|
||||
if (TextUtils.isEmpty(cookie)) cookie = Path.read(getCache());
|
||||
if (TextUtils.isEmpty(cookie)) cookie = COOKIE;
|
||||
}
|
||||
|
||||
private List<Filter> getFilter() {
|
||||
List<Filter> items = new ArrayList<>();
|
||||
items.add(new Filter("order", "排序", Arrays.asList(new Filter.Value("預設", "totalrank"), new Filter.Value("最多點擊", "click"), new Filter.Value("最新發布", "pubdate"), new Filter.Value("最多彈幕", "dm"), new Filter.Value("最多收藏", "stow"))));
|
||||
items.add(new Filter("duration", "時長", Arrays.asList(new Filter.Value("全部時長", "0"), new Filter.Value("60分鐘以上", "4"), new Filter.Value("30~60分鐘", "3"), new Filter.Value("10~30分鐘", "2"), new Filter.Value("10分鐘以下", "1"))));
|
||||
return items;
|
||||
}
|
||||
|
||||
private File getCache() {
|
||||
return Path.tv("bilibili");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
this.extend = Json.safeObject(extend);
|
||||
setCookie();
|
||||
setAudio();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
if (extend.has("json")) return OkHttp.string(extend.get("json").getAsString());
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
String[] types = extend.get("type").getAsString().split("#");
|
||||
for (String type : types) {
|
||||
classes.add(new Class(type));
|
||||
filters.put(type, getFilter());
|
||||
}
|
||||
return Result.string(classes, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() {
|
||||
String api = "https://api.bilibili.com/x/web-interface/popular?ps=20";
|
||||
String json = OkHttp.string(api, getHeader());
|
||||
Resp resp = Resp.objectFrom(json);
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Resp.Result item : Resp.Result.arrayFrom(resp.getData().getList())) list.add(item.getVod());
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
if (tid.endsWith("/{pg}")) {
|
||||
LinkedHashMap<String, Object> params = new LinkedHashMap<>();
|
||||
params.put("mid", tid.split("/")[0]);
|
||||
params.put("pn", pg);
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String json = OkHttp.string("https://api.bilibili.com/x/space/wbi/arc/search?" + wbi.getQuery(params), getHeader());
|
||||
for (Resp.Result item : Resp.Result.arrayFrom(Resp.objectFrom(json).getData().getList().getAsJsonObject().get("vlist"))) list.add(item.getVod());
|
||||
return Result.string(list);
|
||||
} else {
|
||||
String order = extend.containsKey("order") ? extend.get("order") : "totalrank";
|
||||
String duration = extend.containsKey("duration") ? extend.get("duration") : "0";
|
||||
if (extend.containsKey("tid")) tid = tid + " " + extend.get("tid");
|
||||
String api = "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=" + URLEncoder.encode(tid) + "&order=" + order + "&duration=" + duration + "&page=" + pg;
|
||||
String json = OkHttp.string(api, getHeader());
|
||||
Resp resp = Resp.objectFrom(json);
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Resp.Result item : Resp.Result.arrayFrom(resp.getData().getResult())) list.add(item.getVod());
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
if (!login) checkLogin();
|
||||
|
||||
String[] split = ids.get(0).split("@");
|
||||
String bvid = split[0];
|
||||
String aid = split[1];
|
||||
|
||||
String api = "https://api.bilibili.com/x/web-interface/view?aid=" + aid;
|
||||
String json = OkHttp.string(api, getHeader());
|
||||
Data detail = Resp.objectFrom(json).getData();
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(detail.getPic());
|
||||
vod.setVodName(detail.getTitle());
|
||||
vod.setTypeName(detail.getType());
|
||||
vod.setVodContent(detail.getDesc());
|
||||
vod.setVodDirector(detail.getOwner().getFormat());
|
||||
vod.setVodRemarks(detail.getDuration() / 60 + "分鐘");
|
||||
|
||||
List<String> acceptDesc = new ArrayList<>();
|
||||
List<Integer> acceptQuality = new ArrayList<>();
|
||||
api = "https://api.bilibili.com/x/player/playurl?avid=" + aid + "&cid=" + detail.getCid() + "&qn=127&fnval=4048&fourk=1";
|
||||
json = OkHttp.string(api, getHeader());
|
||||
Data play = Resp.objectFrom(json).getData();
|
||||
for (int i = 0; i < play.getAcceptQuality().size(); i++) {
|
||||
int qn = play.getAcceptQuality().get(i);
|
||||
if (!login && qn > 32) continue;
|
||||
if (!isVip && qn > 80) continue;
|
||||
acceptQuality.add(play.getAcceptQuality().get(i));
|
||||
acceptDesc.add(play.getAcceptDescription().get(i));
|
||||
}
|
||||
|
||||
List<String> episode = new ArrayList<>();
|
||||
LinkedHashMap<String, String> flag = new LinkedHashMap<>();
|
||||
for (Page page : detail.getPages()) episode.add(page.getPart() + "$" + aid + "+" + page.getCid() + "+" + TextUtils.join(":", acceptQuality) + "+" + TextUtils.join(":", acceptDesc));
|
||||
flag.put("B站", TextUtils.join("#", episode));
|
||||
|
||||
episode = new ArrayList<>();
|
||||
api = "https://api.bilibili.com/x/web-interface/archive/related?bvid=" + bvid;
|
||||
json = OkHttp.string(api, getHeader());
|
||||
JsonArray array = Json.parse(json).getAsJsonObject().getAsJsonArray("data");
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
JsonObject object = array.get(i).getAsJsonObject();
|
||||
episode.add(object.get("title").getAsString() + "$" + object.get("aid").getAsInt() + "+" + object.get("cid").getAsInt() + "+" + TextUtils.join(":", acceptQuality) + "+" + TextUtils.join(":", acceptDesc));
|
||||
}
|
||||
flag.put("相关", TextUtils.join("#", episode));
|
||||
|
||||
vod.setVodPlayFrom(TextUtils.join("$$$", flag.keySet()));
|
||||
vod.setVodPlayUrl(TextUtils.join("$$$", flag.values()));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return categoryContent(key, "1", true, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return categoryContent(key, pg, true, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
String[] ids = id.split("\\+");
|
||||
String aid = ids[0];
|
||||
String cid = ids[1];
|
||||
String[] acceptDesc = ids[3].split(":");
|
||||
String[] acceptQuality = ids[2].split(":");
|
||||
List<String> url = new ArrayList<>();
|
||||
String dan = "https://api.bilibili.com/x/v1/dm/list.so?oid=".concat(cid);
|
||||
for (int i = 0; i < acceptDesc.length; i++) {
|
||||
url.add(acceptDesc[i]);
|
||||
url.add(Proxy.getUrl() + "?do=bili" + "&aid=" + aid + "&cid=" + cid + "&qn=" + acceptQuality[i] + "&type=mpd");
|
||||
}
|
||||
return Result.get().url(url).danmaku(dan).dash().header(getHeader()).string();
|
||||
}
|
||||
|
||||
public static Object[] proxy(Map<String, String> params) {
|
||||
String aid = params.get("aid");
|
||||
String cid = params.get("cid");
|
||||
String qn = params.get("qn");
|
||||
String api = "https://api.bilibili.com/x/player/playurl?avid=" + aid + "&cid=" + cid + "&qn=" + qn + "&fnval=4048&fourk=1";
|
||||
String json = OkHttp.string(api, getHeader());
|
||||
Resp resp = Resp.objectFrom(json);
|
||||
Dash dash = resp.getData().getDash();
|
||||
StringBuilder video = new StringBuilder();
|
||||
StringBuilder audio = new StringBuilder();
|
||||
findAudio(dash, audio);
|
||||
findVideo(dash, video, qn);
|
||||
String mpd = getMpd(dash, video.toString(), audio.toString());
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = "application/dash+xml";
|
||||
result[2] = new ByteArrayInputStream(mpd.getBytes());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void findAudio(Dash dash, StringBuilder sb) {
|
||||
for (Media audio : dash.getAudio()) {
|
||||
for (String key : audios.keySet()) {
|
||||
if (audio.getId().equals(key)) {
|
||||
sb.append(getMedia(audio));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void findVideo(Dash dash, StringBuilder sb, String qn) {
|
||||
for (Media video : dash.getVideo()) {
|
||||
if (video.getId().equals(qn)) {
|
||||
sb.append(getMedia(video));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMedia(Media media) {
|
||||
if (media.getMimeType().startsWith("video")) {
|
||||
return getAdaptationSet(media, String.format(Locale.getDefault(), "height='%s' width='%s' frameRate='%s' sar='%s'", media.getHeight(), media.getWidth(), media.getFrameRate(), media.getSar()));
|
||||
} else if (media.getMimeType().startsWith("audio")) {
|
||||
return getAdaptationSet(media, String.format("numChannels='2' sampleRate='%s'", audios.get(media.getId())));
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String getAdaptationSet(Media media, String params) {
|
||||
String id = media.getId() + "_" + media.getCodecId();
|
||||
String type = media.getMimeType().split("/")[0];
|
||||
String baseUrl = media.getBaseUrl().replace("&", "&");
|
||||
return String.format(Locale.getDefault(), "<AdaptationSet>\n" + "<ContentComponent contentType=\"%s\"/>\n" + "<Representation id=\"%s\" bandwidth=\"%s\" codecs=\"%s\" mimeType=\"%s\" %s startWithSAP=\"%s\">\n" + "<BaseURL>%s</BaseURL>\n" + "<SegmentBase indexRange=\"%s\">\n" + "<Initialization range=\"%s\"/>\n" + "</SegmentBase>\n" + "</Representation>\n" + "</AdaptationSet>", type, id, media.getBandWidth(), media.getCodecs(), media.getMimeType(), params, media.getStartWithSap(), baseUrl, media.getSegmentBase().getIndexRange(), media.getSegmentBase().getInitialization());
|
||||
}
|
||||
|
||||
private static String getMpd(Dash dash, String videoList, String audioList) {
|
||||
return String.format(Locale.getDefault(), "<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" type=\"static\" mediaPresentationDuration=\"PT%sS\" minBufferTime=\"PT%sS\" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\">\n" + "<Period duration=\"PT%sS\" start=\"PT0S\">\n" + "%s\n" + "%s\n" + "</Period>\n" + "</MPD>", dash.getDuration(), dash.getMinBufferTime(), dash.getDuration(), videoList, audioList);
|
||||
}
|
||||
|
||||
private void checkLogin() {
|
||||
String json = OkHttp.string("https://api.bilibili.com/x/web-interface/nav", getHeader());
|
||||
Data data = Resp.objectFrom(json).getData();
|
||||
login = data.isLogin();
|
||||
isVip = data.isVip();
|
||||
wbi = data.getWbi();
|
||||
}
|
||||
}
|
||||
123
app/src/main/java/com/github/catvod/spider/Cg51.java
Normal file
123
app/src/main/java/com/github/catvod/spider/Cg51.java
Normal file
@@ -0,0 +1,123 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Cg51 extends Spider {
|
||||
|
||||
private static final String proxyImgUrl = "https://api.buxiangyao.link/51cg/img/?url=";
|
||||
|
||||
private static final String siteUrl = "https://h25dz1.gxhfkyztz.com";
|
||||
private static final String cateUrl = siteUrl + "/category/";
|
||||
private static final String detailUrl = siteUrl + "/archives/";
|
||||
private static final String searchUrl = siteUrl + "/search?keywords=";
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private List<Vod> parseVods(Document doc) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element element : doc.select("article")) {
|
||||
String pic = String.valueOf(element.select("script"));
|
||||
String pattern = "'(https?://[^']+)";
|
||||
Pattern regex = Pattern.compile(pattern);
|
||||
Matcher matcher = regex.matcher(pic);
|
||||
String PicAddress = "";
|
||||
if (matcher.find()) {
|
||||
PicAddress = proxyImgUrl + matcher.group(1);
|
||||
} else {
|
||||
}
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select(".post-card-title").text();
|
||||
String id = url.split("/")[2];
|
||||
if (name != "" && url != ""){
|
||||
list.add(new Vod(id, name, PicAddress));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
String[] typeIdList = {"wpcz","mrdg","rdsj","bkdg","whhl","xsxy","whmx"};
|
||||
String[] typeNameList = {"今日吃瓜","每日大瓜","热门吃瓜","必看大瓜","网红黑料","学生学校","明星黑料"};
|
||||
for (int i = 0; i < typeNameList.length; i++) {
|
||||
classes.add(new Class(typeIdList[i], typeNameList[i]));
|
||||
}
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
|
||||
List<Vod> list = parseVods(doc);
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String target = cateUrl + tid + "/" + pg + "/";
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
List<Vod> list = parseVods(doc);
|
||||
Integer total = (Integer.parseInt(pg)+1)*20;
|
||||
return Result.string(Integer.parseInt(pg),Integer.parseInt(pg)+1,20,total,list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders()));
|
||||
String playUrl = "";
|
||||
int index = 1;
|
||||
for (Element element : doc.select("div.dplayer")) {
|
||||
String play = element.attr("data-config");
|
||||
JSONObject jsonObject = new JSONObject(play);
|
||||
if (playUrl == ""){
|
||||
playUrl = "第" + index + "集$" + jsonObject.get("url");
|
||||
}else {
|
||||
playUrl = playUrl + "#第" + index + "集$" + jsonObject.get("url");
|
||||
}
|
||||
index++;
|
||||
}
|
||||
String name = doc.select("meta[property=og:title]").attr("content");
|
||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
||||
String year = doc.select("meta[property=video:release_date]").attr("content");
|
||||
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodYear(year);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("Cg51");
|
||||
vod.setVodPlayUrl(playUrl);
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)), getHeaders()));
|
||||
List<Vod> list = parseVods(doc);
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeaders()).string();
|
||||
}
|
||||
}
|
||||
179
app/src/main/java/com/github/catvod/spider/Dm84.java
Normal file
179
app/src/main/java/com/github/catvod/spider/Dm84.java
Normal file
@@ -0,0 +1,179 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author FongMi
|
||||
*/
|
||||
public class Dm84 extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://dm84.tv";
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
headers.put("Accept", Util.ACCEPT);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Filter getFilter(String name, String key, List<String> texts) {
|
||||
List<Filter.Value> values = new ArrayList<>();
|
||||
for (String text : texts) {
|
||||
if (text.isEmpty()) continue;
|
||||
String n = text.replace("按", "");
|
||||
String v = key.equals("by") ? replaceBy(text) : text;
|
||||
values.add(new Filter.Value(n, v));
|
||||
}
|
||||
return new Filter(key, name, values);
|
||||
}
|
||||
|
||||
private String replaceBy(String text) {
|
||||
return text.replace("按时间", "time").replace("按人气", "hits").replace("按评分", "score");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
|
||||
for (Element element : doc.select("ul.nav_row > li > a")) {
|
||||
if (element.attr("href").startsWith("/list")) {
|
||||
String id = element.attr("href").split("-")[1].substring(0, 1);
|
||||
String name = element.text().substring(0, 2);
|
||||
classes.add(new Class(id, name));
|
||||
}
|
||||
}
|
||||
for (Class item : classes) {
|
||||
doc = Jsoup.parse(OkHttp.string(siteUrl + "/list-" + item.getTypeId() + ".html", getHeaders()));
|
||||
Elements elements = doc.select("ul.list_filter > li > div");
|
||||
List<Filter> array = new ArrayList<>();
|
||||
array.add(getFilter("類型", "type", elements.get(0).select("a").eachText()));
|
||||
array.add(getFilter("時間", "year", elements.get(1).select("a").eachText()));
|
||||
array.add(getFilter("排序", "by", elements.get(2).select("a").eachText()));
|
||||
filters.put(item.getTypeId(), array);
|
||||
}
|
||||
for (Element element : doc.select("div.item")) {
|
||||
String img = element.select("a.cover").attr("data-bg");
|
||||
String url = element.select("a.title").attr("href");
|
||||
String name = element.select("a.title").text();
|
||||
String remark = element.select("span.desc").text();
|
||||
String id = url.split("/")[2];
|
||||
list.add(new Vod(id, name, img, remark));
|
||||
}
|
||||
return Result.string(classes, list, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
if (extend.get("type") == null) extend.put("type", "");
|
||||
if (extend.get("year") == null) extend.put("year", "");
|
||||
if (extend.get("by") == null) extend.put("by", "time");
|
||||
String by = extend.get("by");
|
||||
String type = URLEncoder.encode(extend.get("type"));
|
||||
String year = extend.get("year");
|
||||
String target = siteUrl + String.format("/show-%s--%s-%s--%s-%s.html", tid, by, type, year, pg);
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
for (Element element : doc.select("div.item")) {
|
||||
String img = element.select("a.cover").attr("data-bg");
|
||||
String url = element.select("a.title").attr("href");
|
||||
String name = element.select("a.title").text();
|
||||
String remark = element.select("span.desc").text();
|
||||
String id = url.split("/")[2];
|
||||
list.add(new Vod(id, name, img, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat("/v/").concat(ids.get(0)), getHeaders()));
|
||||
String name = doc.select("h1.v_title").text();
|
||||
String remarks = doc.select("p.v_desc > span.desc").text();
|
||||
String img = doc.select("meta[property=og:image]").attr("content");
|
||||
String area = doc.select("meta[name=og:video:area]").attr("content");
|
||||
String type = doc.select("meta[name=og:video:class]").attr("content");
|
||||
String actor = doc.select("meta[name=og:video:actor]").attr("content");
|
||||
String content = doc.select("meta[property=og:description]").attr("content");
|
||||
String year = doc.select("meta[name=og:video:release_date]").attr("content");
|
||||
String director = doc.select("meta[name=og:video:director]").attr("content");
|
||||
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(img);
|
||||
vod.setVodYear(year);
|
||||
vod.setVodName(name);
|
||||
vod.setVodArea(area);
|
||||
vod.setVodActor(actor);
|
||||
vod.setVodRemarks(remarks);
|
||||
vod.setVodContent(content);
|
||||
vod.setVodDirector(director);
|
||||
vod.setTypeName(type);
|
||||
|
||||
Map<String, String> sites = new LinkedHashMap<>();
|
||||
Elements sources = doc.select("ul.tab_control > li");
|
||||
Elements sourceList = doc.select("ul.play_list");
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
Elements playList = sourceList.get(i).select("a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
for (int j = 0; j < playList.size(); j++) {
|
||||
Element e = playList.get(j);
|
||||
vodItems.add(e.text() + "$" + e.attr("href"));
|
||||
}
|
||||
if (vodItems.size() > 0) {
|
||||
sites.put(sourceName, TextUtils.join("#", vodItems));
|
||||
}
|
||||
}
|
||||
if (sites.size() > 0) {
|
||||
vod.setVodPlayFrom(TextUtils.join("$$$", sites.keySet()));
|
||||
vod.setVodPlayUrl(TextUtils.join("$$$", sites.values()));
|
||||
}
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String target = siteUrl.concat("/s----------.html?wd=").concat(key);
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
for (Element element : doc.select("div.item")) {
|
||||
String img = element.select("a.cover").attr("data-bg");
|
||||
String url = element.select("a.title").attr("href");
|
||||
String name = element.select("a.title").text();
|
||||
String remark = element.select("span.desc").text();
|
||||
String id = url.split("/")[2];
|
||||
list.add(new Vod(id, name, img, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat(id), getHeaders()));
|
||||
String url = doc.select("iframe").attr("src");
|
||||
return Result.get().url(url).parse().header(getHeaders()).string();
|
||||
}
|
||||
}
|
||||
126
app/src/main/java/com/github/catvod/spider/Doll.java
Normal file
126
app/src/main/java/com/github/catvod/spider/Doll.java
Normal file
@@ -0,0 +1,126 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Doll extends Spider {
|
||||
|
||||
private final String url = "https://hongkongdollvideo.com/";
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(url));
|
||||
for (Element a : doc.select("ul#side-menu").get(0).select("li > a")) {
|
||||
String typeName = a.text();
|
||||
String typeId = a.attr("href").replace(url, "");
|
||||
classes.add(new Class(typeId, typeName));
|
||||
}
|
||||
for (Element div : doc.select("div.video-detail")) {
|
||||
String id = div.select("h3.video-title > a").attr("href").replace(url, "");
|
||||
String name = div.select("h3.video-title > a").text();
|
||||
String pic = url + div.select("div.thumb > a > img").attr("data-src");
|
||||
String remark = div.select("div.date").text();
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String target = pg.equals("1") ? url + tid : url + tid + "/" + pg + ".html";
|
||||
Document doc = Jsoup.parse(OkHttp.string(target));
|
||||
for (Element div : doc.select("div.video-detail")) {
|
||||
String id = div.select("h3.video-title > a").attr("href").replace(url, "");
|
||||
String name = div.select("h3.video-title > a").text();
|
||||
String pic = url + div.select("div.thumb > a > img").attr("data-src");
|
||||
String remark = div.select("div.date").text();
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String html = OkHttp.string(url + ids.get(0));
|
||||
Document doc = Jsoup.parse(html);
|
||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
||||
String name = doc.select("meta[property=og:title]").attr("content");
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("玩偶姐姐");
|
||||
vod.setVodPlayUrl("播放$" + url + ids.get(0));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
String key = "";
|
||||
String voteTag = "";
|
||||
StringBuilder code = new StringBuilder();
|
||||
String html = OkHttp.string(id);
|
||||
Document doc = Jsoup.parse(html);
|
||||
Matcher m = Pattern.compile("/video/(\\w+).html").matcher(id);
|
||||
if (m.find()) key = m.group(1);
|
||||
for (Element a : doc.select("script")) {
|
||||
if (a.html().startsWith("var voteTag")) {
|
||||
Pattern pattern = Pattern.compile("voteTag=\"([^&]+)\"");
|
||||
Matcher matcher = pattern.matcher(a.html());
|
||||
if (matcher.find()) voteTag = matcher.group(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(voteTag)) return Result.get().url(id).parse().string();
|
||||
voteTag = new String(Base64.decode(voteTag, 0));
|
||||
for (int i = 0; i < voteTag.length(); i++) {
|
||||
int k = i % key.length();
|
||||
code.append((char) (voteTag.charAt(i) ^ key.charAt(k)));
|
||||
}
|
||||
String playUrl = URLDecoder.decode(new String(Base64.decode(code.toString(), 0)));
|
||||
return Result.get().url(playUrl).string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent("search/" + key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent("search/" + key + "/" + pg + ".html");
|
||||
}
|
||||
|
||||
private String searchContent(String query) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(url + query));
|
||||
for (Element div : doc.select("div.video-detail")) {
|
||||
String id = div.select("h3.video-title > a").attr("href").replace(url, "");
|
||||
String name = div.select("h3.video-title > a").text();
|
||||
String pic = url + div.select("div.thumb > a > img").attr("data-src");
|
||||
String remark = div.select("div.date").text();
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
141
app/src/main/java/com/github/catvod/spider/Douban.java
Normal file
141
app/src/main/java/com/github/catvod/spider/Douban.java
Normal file
@@ -0,0 +1,141 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Douban extends Spider {
|
||||
|
||||
private final String siteUrl = "https://frodo.douban.com/api/v2";
|
||||
private final String apikey = "?apikey=0ac44ae016490db2204ce0a042db2916";
|
||||
private String extend;
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("Host", "frodo.douban.com");
|
||||
header.put("Connection", "Keep-Alive");
|
||||
header.put("Referer", "https://servicewechat.com/wx2f9b06c1de1ccfca/84/page-frame.html");
|
||||
header.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat");
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
this.extend = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("hot_gaia", "tv_hot", "show_hot", "movie", "tv", "rank_list_movie", "rank_list_tv");
|
||||
List<String> typeNames = Arrays.asList("热门电影", "热播剧集", "热播综艺", "电影筛选", "电视筛选", "电影榜单", "电视剧榜单");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
String recommendUrl = "http://api.douban.com/api/v2/subject_collection/subject_real_time_hotest/items" + apikey;
|
||||
JSONObject jsonObject = new JSONObject(OkHttp.string(recommendUrl, getHeader()));
|
||||
JSONArray items = jsonObject.optJSONArray("subject_collection_items");
|
||||
return Result.string(classes, parseVodListFromJSONArray(items), filter ? Json.parse(OkHttp.string(extend)) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String sort = extend.get("sort") == null ? "T" : extend.get("sort");
|
||||
String tags = URLEncoder.encode(getTags(extend));
|
||||
int start = (Integer.parseInt(pg) - 1) * 20;
|
||||
String cateUrl;
|
||||
String itemKey = "items";
|
||||
switch (tid) {
|
||||
case "hot_gaia":
|
||||
sort = extend.get("sort") == null ? "recommend" : extend.get("sort");
|
||||
String area = extend.get("area") == null ? "全部" : extend.get("area");
|
||||
sort = sort + "&area=" + URLEncoder.encode(area);
|
||||
cateUrl = siteUrl + "/movie/hot_gaia" + apikey + "&sort=" + sort + "&start=" + start + "&count=20";
|
||||
break;
|
||||
case "tv_hot":
|
||||
String type = extend.get("type") == null ? "tv_hot" : extend.get("type");
|
||||
cateUrl = siteUrl + "/subject_collection/" + type + "/items" + apikey + "&start=" + start + "&count=20";
|
||||
itemKey = "subject_collection_items";
|
||||
break;
|
||||
case "show_hot":
|
||||
String showType = extend.get("type") == null ? "show_hot" : extend.get("type");
|
||||
cateUrl = siteUrl + "/subject_collection/" + showType + "/items" + apikey + "&start=" + start + "&count=20";
|
||||
itemKey = "subject_collection_items";
|
||||
break;
|
||||
case "tv":
|
||||
cateUrl = siteUrl + "/tv/recommend" + apikey + "&sort=" + sort + "&tags=" + tags + "&start=" + start + "&count=20";
|
||||
break;
|
||||
case "rank_list_movie":
|
||||
String rankMovieType = extend.get("榜单") == null ? "movie_real_time_hotest" : extend.get("榜单");
|
||||
cateUrl = siteUrl + "/subject_collection/" + rankMovieType + "/items" + apikey + "&start=" + start + "&count=20";
|
||||
itemKey = "subject_collection_items";
|
||||
break;
|
||||
case "rank_list_tv":
|
||||
String rankTVType = extend.get("榜单") == null ? "tv_real_time_hotest" : extend.get("榜单");
|
||||
cateUrl = siteUrl + "/subject_collection/" + rankTVType + "/items" + apikey + "&start=" + start + "&count=20";
|
||||
itemKey = "subject_collection_items";
|
||||
break;
|
||||
default:
|
||||
cateUrl = siteUrl + "/movie/recommend" + apikey + "&sort=" + sort + "&tags=" + tags + "&start=" + start + "&count=20";
|
||||
break;
|
||||
}
|
||||
JSONObject object = new JSONObject(OkHttp.string(cateUrl, getHeader()));
|
||||
JSONArray array = object.getJSONArray(itemKey);
|
||||
List<Vod> list = parseVodListFromJSONArray(array);
|
||||
int page = Integer.parseInt(pg), count = Integer.MAX_VALUE, limit = 20, total = Integer.MAX_VALUE;
|
||||
return Result.get().vod(list).page(page, count, limit, total).string();
|
||||
}
|
||||
|
||||
private List<Vod> parseVodListFromJSONArray(JSONArray items) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (int i = 0; i < items.length(); i++) {
|
||||
JSONObject item = items.getJSONObject(i);
|
||||
String vodId = "msearch:" + item.optString("id");
|
||||
String name = item.optString("title");
|
||||
String pic = getPic(item);
|
||||
String remark = getRating(item);
|
||||
list.add(new Vod(vodId, name, pic, remark));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private String getRating(JSONObject item) {
|
||||
try {
|
||||
return "评分:" + item.getJSONObject("rating").optString("value");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getPic(JSONObject item) {
|
||||
try {
|
||||
return item.getJSONObject("pic").optString("normal") + "@Referer=https://api.douban.com/@User-Agent=" + Util.CHROME;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getTags(HashMap<String, String> extend) {
|
||||
try {
|
||||
StringBuilder tags = new StringBuilder();
|
||||
for (String key : extend.keySet()) if (!key.equals("sort")) tags.append(extend.get(key)).append(",");
|
||||
return Util.substring(tags.toString());
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
150
app/src/main/java/com/github/catvod/spider/Duanju.java
Normal file
150
app/src/main/java/com/github/catvod/spider/Duanju.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Qile
|
||||
*/
|
||||
public class Duanju extends Spider {
|
||||
|
||||
private static String siteUrl = "https://duanju.one";
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
if (!extend.isEmpty()) siteUrl = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("1", "2", "3", "26", "25", "27", "28", "32");
|
||||
List<String> typeNames = Arrays.asList("抖剧", "快剧", "都市", "穿越", "逆袭", "虐恋", "重生", "其他");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeader()));
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : doc.select("div.module-items").eq(0).select(".module-item")) {
|
||||
String vid = siteUrl + li.select(".module-item-pic a").attr("href");
|
||||
String name = li.select(".module-item-pic a").attr("title");
|
||||
String pic = li.select(".module-item-pic img").attr("data-src");
|
||||
String remark = li.select(".module-item-text").text();
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
HashMap<String, String> ext = new HashMap<>();
|
||||
if (extend != null && extend.size() > 0) ext.putAll(extend);
|
||||
String cateId = ext.get("cateId") == null ? tid : ext.get("cateId");
|
||||
String cateUrl = siteUrl + String.format("/vodshow/%s--------%s---.html", cateId, pg);
|
||||
Document doc = Jsoup.parse(OkHttp.string(cateUrl, getHeader()));
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : doc.select(".module-items .module-item")) {
|
||||
String vid = siteUrl + li.select(".module-item-pic a").attr("href");
|
||||
String name = li.select(".module-item-pic a").attr("title");
|
||||
String pic = li.select(".module-item-pic img").attr("data-src");
|
||||
String remark = li.select(".module-item-text").text();
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(ids.get(0), getHeader()));
|
||||
Elements circuits = doc.select(".module-tab-item.tab-item");
|
||||
Elements sources = doc.select("[class=scroll-content]");
|
||||
StringBuilder vod_play_url = new StringBuilder();
|
||||
StringBuilder vod_play_from = new StringBuilder();
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
String spanText = circuits.get(i).select("span").text();
|
||||
String smallText = circuits.get(i).select("small").text();
|
||||
String playFromText = spanText + "(共" + smallText + "集)";
|
||||
vod_play_from.append(playFromText).append("$$$");
|
||||
Elements aElementArray = sources.get(i).select("a");
|
||||
for (int j = 0; j < aElementArray.size(); j++) {
|
||||
Element a = aElementArray.get(j);
|
||||
String href = siteUrl + a.attr("href");
|
||||
String text = a.text();
|
||||
vod_play_url.append(text).append("$").append(href);
|
||||
boolean notLastEpisode = j < aElementArray.size() - 1;
|
||||
vod_play_url.append(notLastEpisode ? "#" : "$$$");
|
||||
}
|
||||
}
|
||||
String title = doc.select("h1.page-title").text();
|
||||
String classifyName = doc.select("div.tag-link a").text();
|
||||
String year = doc.select("a.tag-link").eq(1).text();
|
||||
String area = doc.select("a.tag-link").eq(2).text();
|
||||
String remark = doc.select("div.title-info span").text();
|
||||
String director = "Qile";
|
||||
String actor = "FongMi";
|
||||
String brief = "该剧由蜂蜜用爱发电制作,欢迎观看!";
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodYear(year);
|
||||
vod.setVodName(title);
|
||||
vod.setVodArea(area);
|
||||
vod.setVodActor(actor);
|
||||
vod.setVodRemarks(remark);
|
||||
vod.setVodContent(brief);
|
||||
vod.setVodDirector(director);
|
||||
vod.setTypeName(classifyName);
|
||||
vod.setVodPlayFrom(vod_play_from.toString());
|
||||
vod.setVodPlayUrl(vod_play_url.toString());
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
String searchUrl = siteUrl + "/vodsearch/" + URLEncoder.encode(key) + "-------------.html";
|
||||
Document doc = Jsoup.parse(OkHttp.string(searchUrl, getHeader()));
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : doc.select(".module-search-item")) {
|
||||
String vid = siteUrl + li.select(".module-item-pic a").attr("href");
|
||||
String name = li.select(".module-item-pic img").attr("alt");
|
||||
String pic = li.select(".module-item-pic img").attr("data-src");
|
||||
String remark = li.select(".video-info-header a.video-serial").text();
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
String content = OkHttp.string(id, getHeader());
|
||||
Matcher matcher = Pattern.compile("player_aaaa=(.*?)</script>").matcher(content);
|
||||
String json = matcher.find() ? matcher.group(1) : "";
|
||||
JSONObject player = new JSONObject(json);
|
||||
String realUrl = player.getString("url");
|
||||
return Result.get().url(realUrl).header(getHeader()).string();
|
||||
}
|
||||
}
|
||||
112
app/src/main/java/com/github/catvod/spider/Eighteen.java
Normal file
112
app/src/main/java/com/github/catvod/spider/Eighteen.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class Eighteen extends Spider {
|
||||
|
||||
private final String url = "https://mjv002.com/zh/";
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
OkHttp.newCall("https://mjv002.com/zh/chinese_IamOverEighteenYearsOld/19/index.html").close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(url));
|
||||
for (Element a : doc.select("ul.animenu__nav > li > a")) {
|
||||
String typeName = a.text();
|
||||
String typeId = a.attr("href").replace(url, "");
|
||||
if (!typeId.contains("random/all/")) continue;
|
||||
if (typeName.contains("18H")) break;
|
||||
classes.add(new Class(typeId, typeName));
|
||||
}
|
||||
for (Element div : doc.select("div.post")) {
|
||||
String id = div.select("a").attr("href").replace(url, "");
|
||||
String name = div.select("h3").text();
|
||||
String pic = div.select("a > img").attr("src");
|
||||
String remark = div.select("div.meta").text();
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
tid = tid.replace("random", "list");
|
||||
tid = tid.replace("index", pg);
|
||||
Document doc = Jsoup.parse(OkHttp.string(url + tid));
|
||||
for (Element div : doc.select("div.post")) {
|
||||
String id = div.select("a").attr("href").replace(url, "");
|
||||
String name = div.select("h3").text();
|
||||
String pic = div.select("a > img").attr("src");
|
||||
String remark = div.select("div.meta").text();
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(url + ids.get(0)));
|
||||
Element wrap = doc.select("div.video-wrap").get(0);
|
||||
String name = wrap.select("div.archive-title > h1").text();
|
||||
String pic = wrap.select("div.player-wrap > img").attr("src");
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("18AV");
|
||||
vod.setVodPlayUrl("播放$" + ids.get(0));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, pg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().parse().url(url + id).string();
|
||||
}
|
||||
|
||||
private String searchContent(String key, String pg) {
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
params.put("search_keyword", key);
|
||||
params.put("search_type", "fc");
|
||||
params.put("op", "search");
|
||||
String res = OkHttp.post(url + "searchform_search/all/" + pg + ".html", params);
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element div : Jsoup.parse(res).select("div.post")) {
|
||||
String id = div.select("a").attr("href").replace(url, "");
|
||||
String name = div.select("h3").text();
|
||||
String pic = div.select("a > img").attr("src");
|
||||
String remark = div.select("div.meta").text();
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
106
app/src/main/java/com/github/catvod/spider/FirstAid.java
Normal file
106
app/src/main/java/com/github/catvod/spider/FirstAid.java
Normal file
@@ -0,0 +1,106 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Qile
|
||||
*/
|
||||
public class FirstAid extends Spider {
|
||||
|
||||
private final String siteUrl = "https://m.youlai.cn";
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("jijiu|0", "jijiu|1", "jijiu|2", "jijiu|3", "jijiu|4", "jijiu|5", "jijiu|6", "jijiu|7");
|
||||
List<String> typeNames = Arrays.asList("急救技能", "家庭生活", "急危重症", "常见损伤", "动物致伤", "海洋急救", "中毒急救", "意外事故");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
return Result.string(classes, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String[] item = tid.split("\\|");
|
||||
String id = item[0];
|
||||
String digit = item[1];
|
||||
int digitValue = Integer.parseInt(digit);
|
||||
String cateId = extend.get("cateId") == null ? id : extend.get("cateId");
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl + String.format("/%s", cateId), getHeader()));
|
||||
String pic = "https:" + doc.select(".block100").eq(digitValue).attr("src");
|
||||
Elements lis = doc.select(".jj-title-li").eq(digitValue).select(".list-br3");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : lis) {
|
||||
String vid = siteUrl + li.select("a").attr("href");
|
||||
String name = li.select("a").text();
|
||||
list.add(new Vod(vid, name, pic));
|
||||
}
|
||||
return Result.get().page(1, 1, 0, lis.size()).vod(list).string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(ids.get(0), getHeader()));
|
||||
String title = doc.select(".video-title.h1-title").text();
|
||||
String pic = doc.select(".video-cover.list-flex-in img").attr("src");
|
||||
String actor = doc.select("span.doc-name").text();
|
||||
String area = "中国";
|
||||
String brief = doc.select(".img-text-con").text();
|
||||
String play_url = doc.select("#video source").attr("src");
|
||||
if (play_url.isEmpty()) play_url = doc.select("#video").attr("src");
|
||||
String vod_play_url = title + "$" + play_url;
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodName(title);
|
||||
vod.setVodActor(actor);
|
||||
vod.setVodArea(area);
|
||||
vod.setVodContent(brief);
|
||||
vod.setVodPlayFrom("Qile");
|
||||
vod.setVodPlayUrl(vod_play_url);
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
String searchUrl = siteUrl + "/cse/search?q=" + URLEncoder.encode(key);
|
||||
Elements lis = Jsoup.parse(OkHttp.string(searchUrl, getHeader())).select(".search-video-li.list-br2");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : lis) {
|
||||
String vid = siteUrl + li.select("a").attr("href");
|
||||
String name = li.select("h5.line-clamp1").text();
|
||||
String pic = li.select("dt.logo-bg img").attr("src");
|
||||
if (!pic.startsWith("https")) pic = "https:" + pic;
|
||||
list.add(new Vod(vid, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeader()).string();
|
||||
}
|
||||
}
|
||||
138
app/src/main/java/com/github/catvod/spider/Hanime.java
Normal file
138
app/src/main/java/com/github/catvod/spider/Hanime.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class Hanime extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://hanime1.me";
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Filter getFilter(String name, String key, List<String> texts) {
|
||||
List<Filter.Value> values = new ArrayList<>();
|
||||
if (!key.equals("by")) values.add(new Filter.Value("全部", ""));
|
||||
for (String text : texts) {
|
||||
if (text.isEmpty()) continue;
|
||||
values.add(new Filter.Value(text));
|
||||
}
|
||||
return new Filter(key, name, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
Document doc1 = Jsoup.parse(OkHttp.string(siteUrl.concat("/search?genre=裏番"), getHeaders()));
|
||||
List<String> sorts = doc1.select("div.hentai-sort-options-wrapper").eachText();
|
||||
List<String> years = doc1.getElementById("year").select("option").eachAttr("value");
|
||||
Document doc2 = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
|
||||
for (Element element : doc2.select("a.nav-item")) {
|
||||
String text = element.text();
|
||||
if (text.equals("新番預告") || text.equals("H漫畫")) continue;
|
||||
classes.add(new Class(text));
|
||||
List<Filter> array = new ArrayList<>();
|
||||
array.add(getFilter("排序", "by", sorts));
|
||||
array.add(getFilter("年份", "year", years));
|
||||
filters.put(text, array);
|
||||
}
|
||||
for (Element element : doc2.select("a")) {
|
||||
if (element.attr("href").contains("watch")) {
|
||||
String pic = element.select("div > img").attr("src");
|
||||
String url = element.attr("href");
|
||||
String name = element.select("div > div").text();
|
||||
String id = url.split("=")[1];
|
||||
if (name.contains("smart_display") || name.isEmpty()) continue;
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
}
|
||||
return Result.string(classes, list, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
if (extend.get("by") == null) extend.put("by", "最新上市");
|
||||
if (extend.get("year") == null) extend.put("year", "");
|
||||
String target = siteUrl.concat("/search?genre=").concat(tid).concat("&page=").concat(pg).concat("&sort=").concat(extend.get("by")).concat("&year=").concat(extend.get("year"));
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
for (Element element : doc.select("div.col-xs-6")) {
|
||||
String pic = element.select("img").get(1).attr("src");
|
||||
String url = element.select("a.overlay").attr("href");
|
||||
String name = element.select("div.card-mobile-title").text();
|
||||
String id = url.split("=")[1];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
for (Element element : doc.select("a")) {
|
||||
if (element.attr("href").contains("watch")) {
|
||||
String pic = element.select("div > img").attr("src");
|
||||
String url = element.attr("href");
|
||||
String name = element.select("div > div").text();
|
||||
String id = url.split("=")[1];
|
||||
if (name.contains("smart_display")) continue;
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat("/watch?v=").concat(ids.get(0)), getHeaders()));
|
||||
String name = doc.getElementById("shareBtn-title").text();
|
||||
JSONObject json = new JSONObject(doc.select("script[type=application/ld+json]").html().trim());
|
||||
String content = json.optString("description");
|
||||
String pic = json.optJSONArray("thumbnailUrl").optString(0);
|
||||
String url = json.optString("contentUrl");;
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodName(name);
|
||||
vod.setVodContent(content);
|
||||
vod.setVodPlayFrom("Hanime1");
|
||||
vod.setVodPlayUrl("播放$" + url);
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String target = siteUrl.concat("/search?query=").concat(key).concat("&genre=&sort=&year=&month=&duration=");
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
for (Element element : doc.select("div.col-xs-6")) {
|
||||
String pic = element.select("img").get(1).attr("src");
|
||||
String url = element.select("a.overlay").attr("href");
|
||||
String name = element.select("div.card-mobile-title").text();
|
||||
String id = url.split("=")[1];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeaders()).string();
|
||||
}
|
||||
}
|
||||
90
app/src/main/java/com/github/catvod/spider/Init.java
Normal file
90
app/src/main/java/com/github/catvod/spider/Init.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class Init {
|
||||
|
||||
private final ExecutorService executor;
|
||||
private final Handler handler;
|
||||
private Application app;
|
||||
|
||||
private static class Loader {
|
||||
static volatile Init INSTANCE = new Init();
|
||||
}
|
||||
|
||||
public static Init get() {
|
||||
return Loader.INSTANCE;
|
||||
}
|
||||
|
||||
public Init() {
|
||||
this.handler = new Handler(Looper.getMainLooper());
|
||||
this.executor = Executors.newFixedThreadPool(5);
|
||||
}
|
||||
|
||||
public static Application context() {
|
||||
return get().app;
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
get().app = ((Application) context);
|
||||
SpiderDebug.log("自定義爬蟲代碼載入成功!");
|
||||
}
|
||||
|
||||
public static void execute(Runnable runnable) {
|
||||
get().executor.execute(runnable);
|
||||
}
|
||||
|
||||
public static void run(Runnable runnable) {
|
||||
get().handler.post(runnable);
|
||||
}
|
||||
|
||||
public static void run(Runnable runnable, int delay) {
|
||||
get().handler.postDelayed(runnable, delay);
|
||||
}
|
||||
|
||||
public static void checkPermission() {
|
||||
try {
|
||||
Activity activity = Init.getActivity();
|
||||
if (activity == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
|
||||
if (activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) return;
|
||||
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 9999);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Activity getActivity() throws Exception {
|
||||
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
|
||||
Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
|
||||
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
|
||||
activitiesField.setAccessible(true);
|
||||
Map<?, ?> activities = (Map<?, ?>) activitiesField.get(activityThread);
|
||||
for (Object activityRecord : activities.values()) {
|
||||
Class<?> activityRecordClass = activityRecord.getClass();
|
||||
Field pausedField = activityRecordClass.getDeclaredField("paused");
|
||||
pausedField.setAccessible(true);
|
||||
if (!pausedField.getBoolean(activityRecord)) {
|
||||
Field activityField = activityRecordClass.getDeclaredField("activity");
|
||||
activityField.setAccessible(true);
|
||||
Activity activity = (Activity) activityField.get(activityRecord);
|
||||
SpiderDebug.log(activity.getComponentName().getClassName());
|
||||
return activity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
100
app/src/main/java/com/github/catvod/spider/J91.java
Normal file
100
app/src/main/java/com/github/catvod/spider/J91.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class J91 extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://pta.9a07g.com";
|
||||
private static final String cateUrl = siteUrl + "/video/category/";
|
||||
private static final String detailUrl = siteUrl + "/video/view/";
|
||||
private static final String searchUrl = siteUrl + "/search?keywords=";
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private List<Vod> parseVods(Document doc) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element element : doc.select("div.video-elem")) {
|
||||
String pic = element.select("div.img").attr("style");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("a.title").text();
|
||||
if (pic.endsWith(".gif") || name.isEmpty()) continue;
|
||||
if (!url.startsWith("http")) {
|
||||
pic = pic.replace("background-image: url('", "").replace("')", "");
|
||||
if (!pic.startsWith("http")) pic = "https:" + pic;
|
||||
String id = url.split("/")[3];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
String[] typeIdList = {"latest","hd","recent-favorite","hot-list","recent-rating","nonpaid","ori","long-list","longer-list","month-discuss","top-favorite","most-favorite","top-list","top-last"};
|
||||
String[] typeNameList = {"最近更新","高清视频","最近加精","当前最热","最近得分","非付费","91原创","10分钟以上","20分钟以上","本月讨论","本月收藏","收藏最多","本月最热","上月最热"};
|
||||
for (int i = 0; i < typeNameList.length; i++) {
|
||||
classes.add(new Class(typeIdList[i], typeNameList[i]));
|
||||
}
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
|
||||
List<Vod> list = parseVods(doc);
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String target = cateUrl + tid + "/" + pg;
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
List<Vod> list = parseVods(doc);
|
||||
Integer total = (Integer.parseInt(pg)+1) * 20;
|
||||
return Result.string(Integer.parseInt(pg),Integer.parseInt(pg)+1,20,total,list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders()));
|
||||
String name = doc.select("meta[property=og:title]").attr("content");
|
||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
||||
String year = doc.select("meta[property=video:release_date]").attr("content");
|
||||
String playUrl = doc.select("#video-play").attr("data-src");
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodYear(year);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("J91");
|
||||
vod.setVodPlayUrl("播放$" + playUrl);
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)), getHeaders()));
|
||||
List<Vod> list = parseVods(doc);
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeaders()).string();
|
||||
}
|
||||
}
|
||||
54
app/src/main/java/com/github/catvod/spider/JSDemo.java
Normal file
54
app/src/main/java/com/github/catvod/spider/JSDemo.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.whl.quickjs.android.QuickJSLoader;
|
||||
import com.whl.quickjs.wrapper.QuickJSContext;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class JSDemo extends Spider {
|
||||
|
||||
private ExecutorService executor;
|
||||
private QuickJSContext ctx;
|
||||
|
||||
private void submit(Runnable runnable) {
|
||||
executor.submit(runnable);
|
||||
}
|
||||
|
||||
private <T> Future<T> submit(Callable<T> callable) {
|
||||
return executor.submit(callable);
|
||||
}
|
||||
|
||||
private void initJS() {
|
||||
if (ctx != null) return;
|
||||
ctx = QuickJSContext.create();
|
||||
QuickJSLoader.initConsoleLog(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
submit(this::initJS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
return submit(() -> {
|
||||
ctx.evaluate("var text = 'homeContent';");
|
||||
return ctx.getGlobalObject().getString("text");
|
||||
}).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
submit(() -> {
|
||||
executor.shutdownNow();
|
||||
ctx.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
105
app/src/main/java/com/github/catvod/spider/Jable.java
Normal file
105
app/src/main/java/com/github/catvod/spider/Jable.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Jable extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://jable.tv";
|
||||
private static final String cateUrl = siteUrl + "/categories/";
|
||||
private static final String detailUrl = siteUrl + "/videos/";
|
||||
private static final String searchUrl = siteUrl + "/search/";
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(cateUrl, getHeaders()));
|
||||
for (Element element : doc.select("div.img-box")) {
|
||||
String typeId = element.select("a").attr("href").split("/")[4];
|
||||
String typeName = element.select("div.absolute-center > h4").text();
|
||||
classes.add(new Class(typeId, typeName));
|
||||
}
|
||||
doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
|
||||
for (Element element : doc.select("div.video-img-box")) {
|
||||
String pic = element.select("img").attr("data-src");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("div.detail > h6").text();
|
||||
if (pic.endsWith(".gif") || name.isEmpty()) continue;
|
||||
String id = url.split("/")[4];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String target = cateUrl + tid + "/?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=post_date&from=" + String.format(Locale.getDefault(), "%02d", Integer.parseInt(pg)) + "&_=" + System.currentTimeMillis();
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
for (Element element : doc.select("div.video-img-box")) {
|
||||
String pic = element.select("img").attr("data-src");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("div.detail > h6").text();
|
||||
String id = url.split("/")[4];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
Integer total = (Integer.parseInt(pg)+1)*20;
|
||||
return Result.string(Integer.parseInt(pg),Integer.parseInt(pg)+1,20,total,list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)).concat("/"), getHeaders()));
|
||||
String name = doc.select("meta[property=og:title]").attr("content");
|
||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
||||
String year = doc.select("span.inactive-color").get(0).text();
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodYear(year.replace("上市於 ", ""));
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("Jable");
|
||||
vod.setVodPlayUrl("播放$" + Util.getVar(doc.html(), "hlsUrl"));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)).concat("/"), getHeaders()));
|
||||
for (Element element : doc.select("div.video-img-box")) {
|
||||
String pic = element.select("img").attr("data-src");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("div.detail > h6").text();
|
||||
String id = url.split("/")[4];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeaders()).string();
|
||||
}
|
||||
}
|
||||
133
app/src/main/java/com/github/catvod/spider/JavDb.java
Normal file
133
app/src/main/java/com/github/catvod/spider/JavDb.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Qile
|
||||
*/
|
||||
public class JavDb extends Spider {
|
||||
|
||||
private static String siteUrl = "https://javdb523.com";
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
if (!extend.isEmpty()) siteUrl = extend;
|
||||
}
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
header.put("Referer", siteUrl + "/");
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("", "censored", "uncensored", "western");
|
||||
List<String> typeNames = Arrays.asList("全部", "有码", "无码", "欧美");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeader()));
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : doc.select(".item")) {
|
||||
String vid = siteUrl + li.select("a").attr("href");
|
||||
String name = li.select("a").attr("title");
|
||||
String pic = li.select("img").attr("src");
|
||||
list.add(new Vod(vid, name, pic));
|
||||
}
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String cateUrl = siteUrl + String.format("/%s?page=%s", tid, pg);
|
||||
Document doc = Jsoup.parse(OkHttp.string(cateUrl, getHeader()));
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : doc.select(".item")) {
|
||||
String vid = siteUrl + li.select("a").attr("href");
|
||||
String name = li.select("a").attr("title");
|
||||
String pic = li.select("img").attr("src");
|
||||
list.add(new Vod(vid, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(ids.get(0), getHeader()));
|
||||
if (doc.text().contains("歡迎登入")) return Result.error("该资源需要登入");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
Elements sourceList = doc.select(".item.columns");
|
||||
for (Element a : sourceList) {
|
||||
String episodeUrl = a.select("div a").attr("href");
|
||||
String episodeName = a.select("div a").text();
|
||||
vodItems.add(episodeName + "$" + episodeUrl);
|
||||
}
|
||||
Elements elements = doc.select(".panel-block");
|
||||
String classifyName = "";
|
||||
String year = "";
|
||||
String area = "";
|
||||
String remark = "";
|
||||
for (Element element : elements) {
|
||||
String text = element.text();
|
||||
if (text.startsWith("類別:")) {
|
||||
classifyName = element.select("span a").text();
|
||||
} else if (text.startsWith("片商:")) {
|
||||
area = element.select("span a").text();
|
||||
} else if (text.startsWith("日期:")) {
|
||||
year = element.select("span").text();
|
||||
} else if (text.startsWith("時長:")) {
|
||||
remark = element.select("span").text();
|
||||
}
|
||||
}
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodYear(year);
|
||||
vod.setVodArea(area);
|
||||
vod.setVodRemarks(remark);
|
||||
vod.setTypeName(classifyName);
|
||||
vod.setVodContent(ids.get(0));
|
||||
vod.setVodPlayFrom("Qile");
|
||||
vod.setVodPlayUrl(TextUtils.join("#", vodItems));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
String searchUrl = siteUrl + "/search?q=" + Uri.encode(key) + "&f=all";
|
||||
Document doc = Jsoup.parse(OkHttp.string(searchUrl, getHeader()));
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : doc.select(".item")) {
|
||||
String vid = siteUrl + li.select("a").attr("href");
|
||||
String name = li.select("a").attr("title");
|
||||
String pic = li.select("img").attr("src");
|
||||
list.add(new Vod(vid, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeader()).string();
|
||||
}
|
||||
}
|
||||
114
app/src/main/java/com/github/catvod/spider/Jianpian.java
Normal file
114
app/src/main/java/com/github/catvod/spider/Jianpian.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.jianpian.Data;
|
||||
import com.github.catvod.bean.jianpian.Detail;
|
||||
import com.github.catvod.bean.jianpian.Resp;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Json;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Qile
|
||||
*/
|
||||
public class Jianpian extends Spider {
|
||||
|
||||
private final String siteUrl = "http://api2.rinhome.com";
|
||||
private String extend;
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "jianpian-android/360");
|
||||
headers.put("JPAUTH", "y261ow7kF2dtzlxh1GS9EB8nbTxNmaK/QQIAjctlKiEv");
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
this.extend = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("0", "1", "2", "3", "4");
|
||||
List<String> typeNames = Arrays.asList("全部", "电影", "电视剧", "动漫", "综艺");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
return Result.string(classes, Json.parse(OkHttp.string(extend)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String url = siteUrl + "/api/slide/list?code=unknown9039b6856c3a3306&pos_id=888&channel=wandoujia";
|
||||
Resp resp = Resp.objectFrom(OkHttp.string(url, getHeader()));
|
||||
for (Data data : resp.getData()) list.add(data.vod());
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
if (tid.endsWith("/{pg}")) return searchContent(tid.split("/")[0], pg);
|
||||
List<Vod> list = new ArrayList<>();
|
||||
HashMap<String, String> ext = new HashMap<>();
|
||||
if (extend != null && extend.size() > 0) ext.putAll(extend);
|
||||
String cateId = ext.get("cateId") == null ? tid : ext.get("cateId");
|
||||
String area = ext.get("area") == null ? "0" : ext.get("area");
|
||||
String year = ext.get("year") == null ? "0" : ext.get("year");
|
||||
String by = ext.get("by") == null ? "hot" : ext.get("by");
|
||||
String url = siteUrl + String.format("/api/crumb/list?area=%s&category_id=%s&page=%s&type=0&limit=24&sort=%s&year=%s", area, cateId, pg, by, year);
|
||||
Resp resp = Resp.objectFrom(OkHttp.string(url, getHeader()));
|
||||
for (Data data : resp.getData()) list.add(data.vod());
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String url = siteUrl + "/api/node/detail?channel=wandoujia&token=&id=" + ids.get(0);
|
||||
Data data = Detail.objectFrom(OkHttp.string(url, getHeader())).getData();
|
||||
Vod vod = data.vod();
|
||||
vod.setVodPlayFrom("Jianpian");
|
||||
vod.setVodYear(data.getYear());
|
||||
vod.setVodArea(data.getArea());
|
||||
vod.setTypeName(data.getTypes());
|
||||
vod.setVodActor(data.getActors());
|
||||
vod.setVodPlayUrl(data.getPlayUrl());
|
||||
vod.setVodDirector(data.getDirectors());
|
||||
vod.setVodContent(data.getDescription());
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeader()).string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, pg);
|
||||
}
|
||||
|
||||
public String searchContent(String key, String pg) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String url = siteUrl + "/api/video/search?page=" + pg + "&key=" + URLEncoder.encode(key);
|
||||
Resp resp = Resp.objectFrom(OkHttp.string(url, getHeader()));
|
||||
for (Data data : resp.getData()) list.add(data.vod());
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
170
app/src/main/java/com/github/catvod/spider/JustLive.java
Normal file
170
app/src/main/java/com/github/catvod/spider/JustLive.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Qile
|
||||
*/
|
||||
public class JustLive extends Spider {
|
||||
|
||||
private String siteUrl = "http://live.yj1211.work";
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
if (!extend.isEmpty()) siteUrl = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("网游", "手游", "单机", "娱乐", "其他");
|
||||
List<String> typeNames = Arrays.asList("网游", "手游", "单机", "娱乐", "其他");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
String f = "{\"网游\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"英雄联盟\", \"v\": \"英雄联盟\"}, {\"n\": \"无畏契约\", \"v\": \"无畏契约\"}, {\"n\": \"CS:GO\", \"v\": \"CS:GO\"}, {\"n\": \"APEX英雄\", \"v\": \"APEX英雄\"}, {\"n\": \"永劫无间\", \"v\": \"永劫无间\"}, {\"n\": \"穿越火线\", \"v\": \"穿越火线\"}, {\"n\": \"命运方舟\", \"v\": \"命运方舟\"}, {\"n\": \"DOTA2\", \"v\": \"DOTA2\"}, {\"n\": \"吃鸡行动\", \"v\": \"吃鸡行动\"}, {\"n\": \"逃离塔科夫\", \"v\": \"逃离塔科夫\"}, {\"n\": \"传奇\", \"v\": \"传奇\"}, {\"n\": \"DNF\", \"v\": \"DNF\"}, {\"n\": \"卡拉彼丘\", \"v\": \"卡拉彼丘\"}, {\"n\": \"幕后高手\", \"v\": \"幕后高手\"}, {\"n\": \"生死狙击2\", \"v\": \"生死狙击2\"}, {\"n\": \"洛奇英雄传\", \"v\": \"洛奇英雄传\"}, {\"n\": \"最终幻想14\", \"v\": \"最终幻想14\"}, {\"n\": \"重生边缘\", \"v\": \"重生边缘\"}, {\"n\": \"星际战甲\", \"v\": \"星际战甲\"}, {\"n\": \"梦三国\", \"v\": \"梦三国\"}, {\"n\": \"英魂之刃\", \"v\": \"英魂之刃\"}, {\"n\": \"剑网3\", \"v\": \"剑网3\"}]}], \"手游\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"王者荣耀\", \"v\": \"王者荣耀\"}, {\"n\": \"和平精英\", \"v\": \"和平精英\"}, {\"n\": \"原神\", \"v\": \"原神\"}, {\"n\": \"崩坏:星穹铁道\", \"v\": \"崩坏:星穹铁道\"}, {\"n\": \"第五人格\", \"v\": \"第五人格\"}, {\"n\": \"LOL手游\", \"v\": \"LOL手游\"}, {\"n\": \"明日方舟\", \"v\": \"明日方舟\"}, {\"n\": \"黎明觉醒:生机\", \"v\": \"黎明觉醒:生机\"}, {\"n\": \"蛋仔派对\", \"v\": \"蛋仔派对\"}, {\"n\": \"冒险岛手游\", \"v\": \"冒险岛手游\"}, {\"n\": \"闪耀!优俊少女\", \"v\": \"闪耀!优俊少女\"}, {\"n\": \"斯露德\", \"v\": \"斯露德\"}, {\"n\": \"千年之旅\", \"v\": \"千年之旅\"}, {\"n\": \"白夜极光\", \"v\": \"白夜极光\"}, {\"n\": \"逆水寒手游\", \"v\": \"逆水寒手游\"}, {\"n\": \"率土之滨\", \"v\": \"率土之滨\"}, {\"n\": \"月圆之夜\", \"v\": \"月圆之夜\"}]}],\"单机\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"主机游戏\", \"v\": \"主机游戏\"}, {\"n\": \"我的世界\", \"v\": \"我的世界\"}, {\"n\": \"独立游戏\", \"v\": \"独立游戏\"}, {\"n\": \"怀旧游戏\", \"v\": \"怀旧游戏\"}, {\"n\": \"猛兽派对\", \"v\": \"猛兽派对\"}, {\"n\": \"星空\", \"v\": \"星空\"}, {\"n\": \"塞尔达传说\", \"v\": \"塞尔达传说\"}, {\"n\": \"苍翼:混沌效应\", \"v\": \"苍翼:混沌效应\"}, {\"n\": \"命运2\", \"v\": \"命运2\"}, {\"n\": \"收获日3\", \"v\": \"收获日3\"}, {\"n\": \"机战佣兵VI 境界天火\", \"v\": \"机战佣兵VI 境界天火\"}, {\"n\": \"暗黑破坏神Ⅳ\", \"v\": \"暗黑破坏神Ⅳ\"}, {\"n\": \"匹诺曹的谎言\", \"v\": \"匹诺曹的谎言\"}, {\"n\": \"博德之门3\", \"v\": \"博德之门3\"}, {\"n\": \"绝世好武功\", \"v\": \"绝世好武功\"}, {\"n\": \"恐怖游戏\", \"v\": \"恐怖游戏\"}, {\"n\": \"Dark and Darker\", \"v\": \"Dark and Darker\"}, {\"n\": \"Warlander\", \"v\": \"Warlander\"}, {\"n\": \"FORZA 极限竞速\", \"v\": \"FORZA 极限竞速\"}, {\"n\": \"边境\", \"v\": \"边境\"}, {\"n\": \"生化危机\", \"v\": \"生化危机\"}]}], \"娱乐\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"聊天室\", \"v\": \"聊天室\"}, {\"n\": \"视频唱见\", \"v\": \"视频唱见\"}, {\"n\": \"萌宅领域\", \"v\": \"萌宅领域\"}, {\"n\": \"视频聊天\", \"v\": \"视频聊天\"}, {\"n\": \"舞见\", \"v\": \"舞见\"}, {\"n\": \"唱见电台\", \"v\": \"唱见电台\"}, {\"n\": \"聊天电台\", \"v\": \"聊天电台\"}, {\"n\": \"甜宠电台\", \"v\": \"甜宠电台\"}, {\"n\": \"TopStar\", \"v\": \"TopStar\"}, {\"n\": \"虚拟Singer\", \"v\": \"虚拟Singer\"}, {\"n\": \"虚拟Gamer\", \"v\": \"虚拟Gamer\"}, {\"n\": \"虚拟声优\", \"v\": \"虚拟声优\"}, {\"n\": \"虚拟日常\", \"v\": \"虚拟日常\"}, {\"n\": \"星秀\", \"v\": \"星秀\"}]}], \"其他\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"生活分享\", \"v\": \"生活分享\"}, {\"n\": \"户外\", \"v\": \"户外\"}, {\"n\": \"日常\", \"v\": \"日常\"}, {\"n\": \"情感\", \"v\": \"情感\"}, {\"n\": \"运动\", \"v\": \"运动\"}, {\"n\": \"搞笑\", \"v\": \"搞笑\"}, {\"n\": \"手工绘画\", \"v\": \"手工绘画\"}, {\"n\": \"萌宠\", \"v\": \"萌宠\"}, {\"n\": \"美食\", \"v\": \"美食\"}, {\"n\": \"时尚\", \"v\": \"时尚\"}, {\"n\": \"社科法律心理\", \"v\": \"社科法律心理\"}, {\"n\": \"人文历史\", \"v\": \"人文历史\"}, {\"n\": \"校园学习\", \"v\": \"校园学习\"}, {\"n\": \"职场·技能\", \"v\": \"职场·技能\"}, {\"n\": \"科技\", \"v\": \"科技\"}]}]}";
|
||||
JSONObject filterConfig = new JSONObject(f);
|
||||
String content = OkHttp.string(siteUrl + "/api/live/getRecommend?page=1&size=20", getHeader());
|
||||
List<Vod> list = new ArrayList<>();
|
||||
JSONArray dataArray = new JSONObject(content).getJSONArray("data");
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject jsonObject = dataArray.getJSONObject(i);
|
||||
String platform = jsonObject.getString("platForm");
|
||||
String roomId = jsonObject.getString("roomId");
|
||||
String categoryName = jsonObject.getString("categoryName");
|
||||
String roomName = jsonObject.getString("roomName");
|
||||
String name = categoryName + roomName;
|
||||
String pic = jsonObject.getString("roomPic");
|
||||
String remark = jsonObject.getString("ownerName");
|
||||
String vid = "platform=" + platform + "&roomId=" + roomId;
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.string(classes, list, filterConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
Map<String, String> ClassTypeMap = new HashMap<>();
|
||||
ClassTypeMap.put("网游", "英雄联盟");
|
||||
ClassTypeMap.put("手游", "王者荣耀");
|
||||
ClassTypeMap.put("单机", "主机游戏");
|
||||
ClassTypeMap.put("娱乐", "聊天室");
|
||||
ClassTypeMap.put("其他", "生活分享");
|
||||
String cateId = extend.get("cateId") == null ? tid : extend.get("cateId");
|
||||
String classType = extend.get("class") == null ? ClassTypeMap.get(cateId) : extend.get("class");
|
||||
String cateUrl = siteUrl + String.format("/api/live/getRecommendByAreaAll?areaType=%s&area=%s&page=%s", cateId, classType, pg);
|
||||
String content = OkHttp.string(cateUrl, getHeader());
|
||||
List<Vod> list = new ArrayList<>();
|
||||
JSONArray dataArray = new JSONObject(content).getJSONArray("data");
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject jsonObject = dataArray.getJSONObject(i);
|
||||
String platform = jsonObject.getString("platForm");
|
||||
String roomId = jsonObject.getString("roomId");
|
||||
String categoryName = jsonObject.getString("categoryName");
|
||||
String name = jsonObject.getString("roomName");
|
||||
String pic = jsonObject.getString("roomPic");
|
||||
String remark = jsonObject.getString("ownerName");
|
||||
remark = remark + "-" + categoryName;
|
||||
String vid = "platform=" + platform + "&roomId=" + roomId;
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String getRoomInfo = siteUrl + "/api/live/getRoomInfo?" + ids.get(0);
|
||||
String getRealUrl = siteUrl + "/api/live/getRealUrlMultiSource?" + ids.get(0);
|
||||
String content = OkHttp.string(getRealUrl, getHeader());
|
||||
String content1 = OkHttp.string(getRoomInfo, getHeader());
|
||||
JSONObject dataObject = new JSONObject(content).getJSONObject("data");
|
||||
List<String> lineNames = new ArrayList<>();
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
Iterator<String> keys = dataObject.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
if (key.startsWith("线路")) lineNames.add(key);
|
||||
}
|
||||
Collections.sort(lineNames, (line1, line2) -> {
|
||||
int num1 = Integer.parseInt(line1.substring(2));
|
||||
int num2 = Integer.parseInt(line2.substring(2));
|
||||
return Integer.compare(num1, num2);
|
||||
});
|
||||
for (String lineName : lineNames) {
|
||||
JSONArray lineArray = dataObject.getJSONArray(lineName);
|
||||
List<String> episodeItems = new ArrayList<>();
|
||||
for (int i = 0; i < lineArray.length(); i++) {
|
||||
JSONObject item = lineArray.getJSONObject(i);
|
||||
String qualityName = item.getString("qualityName");
|
||||
String playUrl = item.getString("playUrl");
|
||||
episodeItems.add(qualityName + "$" + playUrl);
|
||||
}
|
||||
vodItems.add(TextUtils.join("#", episodeItems));
|
||||
}
|
||||
String vod_play_from = TextUtils.join("$$$", lineNames);
|
||||
String vod_play_urls = TextUtils.join("$$$", vodItems);
|
||||
JSONObject data = new JSONObject(content1).getJSONObject("data");
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(data.getString("roomPic"));
|
||||
vod.setVodName(data.getString("roomName"));
|
||||
vod.setVodArea(data.getString("platForm").replace("douyu", "斗鱼").replace("huya", "虎牙").replace("bilibili", "哔哩哔哩").replace("douyin", "抖音").replace("cc", "网易CC"));
|
||||
vod.setVodActor(data.getString("ownerName"));
|
||||
vod.setVodRemarks("在线" + data.getInt("online") + "人");
|
||||
vod.setVodContent(getRealUrl);
|
||||
vod.setVodDirector("Qile");
|
||||
vod.setTypeName(data.getString("categoryName"));
|
||||
vod.setVodPlayFrom(vod_play_from);
|
||||
vod.setVodPlayUrl(vod_play_urls);
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
String searchUrl = siteUrl + "/api/live/search?platform=all&keyWords=" + URLEncoder.encode(key) + "&uid=35717d71548f4ec9ab6f327cc16ad2bf";
|
||||
String content = OkHttp.string(searchUrl, getHeader());
|
||||
List<Vod> list = new ArrayList<>();
|
||||
JSONArray dataArray = new JSONObject(content).getJSONArray("data");
|
||||
for (int i = 0; i < dataArray.length(); i++) {
|
||||
JSONObject jsonObject = dataArray.getJSONObject(i);
|
||||
String platform = jsonObject.optString("platform");
|
||||
String roomId = jsonObject.optString("roomId");
|
||||
String name = jsonObject.optString("nickName");
|
||||
String pic = jsonObject.optString("headPic");
|
||||
String remark = jsonObject.optString("isLive");
|
||||
remark = remark.equals("1") ? "直播中" : "未开播";
|
||||
String vid = "platform=" + platform + "&roomId=" + roomId;
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeader()).string();
|
||||
}
|
||||
}
|
||||
102
app/src/main/java/com/github/catvod/spider/Kanqiu.java
Normal file
102
app/src/main/java/com/github/catvod/spider/Kanqiu.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Qile
|
||||
*/
|
||||
public class Kanqiu extends Spider {
|
||||
|
||||
private static String siteUrl = "http://www.88kanqiu.one";
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
if (!extend.isEmpty()) siteUrl = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("", "1", "8", "21");
|
||||
List<String> typeNames = Arrays.asList("全部直播", "篮球直播", "足球直播", "其他直播");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
String f = "{\"1\": [{\"key\": \"cateId\", \"name\": \"类型\", \"value\": [{\"n\": \"NBA\", \"v\": \"1\"}, {\"n\": \"CBA\", \"v\": \"2\"}, {\"n\": \"篮球综合\", \"v\": \"4\"}, {\"n\": \"纬来体育\", \"v\": \"21\"}]}],\"8\": [{\"key\": \"cateId\", \"name\": \"类型\", \"value\": [{\"n\": \"英超\", \"v\": \"8\"}, {\"n\": \"西甲\", \"v\": \"9\"}, {\"n\": \"意甲\", \"v\": \"10\"}, {\"n\": \"欧冠\", \"v\": \"12\"}, {\"n\": \"欧联\", \"v\": \"13\"}, {\"n\": \"德甲\", \"v\": \"14\"}, {\"n\": \"法甲\", \"v\": \"15\"}, {\"n\": \"欧国联\", \"v\": \"16\"}, {\"n\": \"足总杯\", \"v\": \"27\"}, {\"n\": \"国王杯\", \"v\": \"33\"}, {\"n\": \"中超\", \"v\": \"7\"}, {\"n\": \"亚冠\", \"v\": \"11\"}, {\"n\": \"足球综合\", \"v\": \"23\"}, {\"n\": \"欧协联\", \"v\": \"28\"}, {\"n\": \"美职联\", \"v\": \"26\"}]}], \"29\": [{\"key\": \"cateId\", \"name\": \"类型\", \"value\": [{\"n\": \"网球\", \"v\": \"29\"}, {\"n\": \"斯洛克\", \"v\": \"30\"}, {\"n\": \"MLB\", \"v\": \"38\"}, {\"n\": \"UFC\", \"v\": \"32\"}, {\"n\": \"NFL\", \"v\": \"25\"}, {\"n\": \"CCTV5\", \"v\": \"18\"}]}]}";
|
||||
JSONObject filterConfig = new JSONObject(f);
|
||||
return Result.string(classes, filterConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String cateId = extend.get("cateId") == null ? tid : extend.get("cateId");
|
||||
String urlPath = cateId == null || cateId.isEmpty() ? "" : String.format("/match/%s/live", cateId);
|
||||
Elements lis = Jsoup.parse(OkHttp.string(siteUrl + urlPath, getHeader())).select(".list-group-item");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element li : lis) {
|
||||
String vid = siteUrl + li.select(".btn.btn-primary").attr("href");
|
||||
String name = li.select(".row.d-none").text();
|
||||
if (name.isEmpty()) name = li.text();
|
||||
String pic = li.select(".col-xs-1").eq(0).select("img").attr("src");
|
||||
if (pic.isEmpty()) pic = "https://pic.imgdb.cn/item/657673d6c458853aeff94ab9.jpg";
|
||||
if (!pic.startsWith("http")) pic = siteUrl + pic;
|
||||
String remark = li.select(".btn.btn-primary").text();
|
||||
list.add(new Vod(vid, name, pic, remark));
|
||||
}
|
||||
return Result.get().page(1, 1, 0, lis.size()).vod(list).string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
if (ids.get(0).equals(siteUrl)) return Result.error("比賽尚未開始");
|
||||
Document doc = Jsoup.parse(OkHttp.string(ids.get(0), getHeader()));
|
||||
String t = doc.select("#t").attr("value");
|
||||
String result = t.substring(6);
|
||||
result = result.substring(0, result.length() - 2);
|
||||
String json = new String(Base64.decode(result, Base64.DEFAULT));
|
||||
JSONArray linksArray = new JSONObject(json).getJSONArray("links");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
for (int i = 0; i < linksArray.length(); i++) {
|
||||
JSONObject linkObject = linksArray.getJSONObject(i);
|
||||
String text = linkObject.optString("name");
|
||||
String href = linkObject.optString("url").replace("#", "***");
|
||||
vodItems.add(text + "$" + href);
|
||||
}
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPlayFrom("Qile");
|
||||
vod.setVodPlayUrl(TextUtils.join("#", vodItems));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id.replace("***", "#")).parse().header(getHeader()).string();
|
||||
}
|
||||
}
|
||||
97
app/src/main/java/com/github/catvod/spider/Kugou.java
Normal file
97
app/src/main/java/com/github/catvod/spider/Kugou.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Qile
|
||||
*/
|
||||
public class Kugou extends Spider {
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<String> typeIds = Arrays.asList("6666|0", "33162|1", "4681|2");
|
||||
List<String> typeNames = Arrays.asList("热门榜单", "特色音乐榜", "全球榜");
|
||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
HashMap<String, String> ext = new HashMap<>();
|
||||
if (extend != null && extend.size() > 0) ext.putAll(extend);
|
||||
String[] item = tid.split("\\|");
|
||||
String id = item[0];
|
||||
String digit = item[1];
|
||||
int digitValue = Integer.parseInt(digit);
|
||||
String cateId = ext.get("cateId") == null ? id : ext.get("cateId");
|
||||
String cateUrl = String.format("https://www.kugou.com/yy/rank/home/1-%s.html?from=rank", cateId);
|
||||
Document doc = Jsoup.parse(OkHttp.string(cateUrl, getHeader()));
|
||||
Elements lis = doc.select(".pc_rank_sidebar").eq(digitValue).select("ul li a");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (Element li : lis) {
|
||||
String vid = li.attr("href");
|
||||
String name = li.attr("title");
|
||||
JSONObject vod = new JSONObject().put("vod_id", vid).put("vod_name", name);
|
||||
videos.put(vod);
|
||||
}
|
||||
JSONObject result = new JSONObject().put("total", lis.size()).put("pagecount", 1).put("list", videos);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(ids.get(0), getHeader()));
|
||||
Elements playlist = doc.select(".pc_temp_songlist ul li");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
for (int j = 0; j < playlist.size(); j++) {
|
||||
Element a = playlist.get(j);
|
||||
String href = a.select("a.pc_temp_songname").attr("href");
|
||||
String text = a.select("a.pc_temp_songname").text();
|
||||
vodItems.add(text + "$" + href);
|
||||
}
|
||||
String title = doc.select(".pc_temp_title h3").text();
|
||||
String remark = doc.select(".rank_update").text();
|
||||
String vod_play_from = "Qile";
|
||||
String vod_play_url = TextUtils.join("#", vodItems);
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodName(title);
|
||||
vod.setVodRemarks(remark);
|
||||
vod.setVodPlayFrom(vod_play_from);
|
||||
vod.setVodPlayUrl(vod_play_url);
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).parse().header(getHeader()).string();
|
||||
}
|
||||
}
|
||||
117
app/src/main/java/com/github/catvod/spider/Local.java
Normal file
117
app/src/main/java/com/github/catvod/spider/Local.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
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.utils.Image;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Local extends Spider {
|
||||
|
||||
private SimpleDateFormat format;
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
classes.add(new Class(Environment.getExternalStorageDirectory().getAbsolutePath(), "本地文件", "1"));
|
||||
File[] files = new File("/storage").listFiles();
|
||||
if (files == null) return Result.string(classes, new ArrayList<>());
|
||||
List<String> exclude = Arrays.asList("emulated", "sdcard", "self");
|
||||
for (File file : files) {
|
||||
if (exclude.contains(file.getName())) continue;
|
||||
classes.add(new Class(file.getAbsolutePath(), file.getName(), "1"));
|
||||
}
|
||||
return Result.string(classes, new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> items = new ArrayList<>();
|
||||
List<Vod> media = new ArrayList<>();
|
||||
List<Vod> folders = new ArrayList<>();
|
||||
File[] files = new File(tid).listFiles();
|
||||
if (files == null) return Result.string(items);
|
||||
Arrays.sort(files, (a, b) -> a.getName().compareTo(b.getName()));
|
||||
for (File file : files) {
|
||||
if (file.getName().startsWith(".")) continue;
|
||||
if (file.isDirectory()) folders.add(create(file));
|
||||
else if (Util.isMedia(file.getName())) media.add(create(file));
|
||||
}
|
||||
items.addAll(folders);
|
||||
items.addAll(media);
|
||||
return Result.get().vod(items).page().string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
String url = ids.get(0);
|
||||
if (url.startsWith("http")) {
|
||||
String name = Uri.parse(url).getLastPathSegment();
|
||||
return Result.string(create(name, url));
|
||||
} else {
|
||||
File file = new File(ids.get(0));
|
||||
return Result.string(create(file.getName(), file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
if (id.startsWith("http")) {
|
||||
return Result.get().url(id).string();
|
||||
} else {
|
||||
return Result.get().url("file://" + id).subs(getSubs(id)).string();
|
||||
}
|
||||
}
|
||||
|
||||
private Vod create(String name, String url) {
|
||||
Vod vod = new Vod();
|
||||
vod.setTypeName("FongMi");
|
||||
vod.setVodId(url);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPic(Image.VIDEO);
|
||||
vod.setVodPlayFrom("播放");
|
||||
vod.setVodPlayUrl(name + "$" + url);
|
||||
return vod;
|
||||
}
|
||||
|
||||
private Vod create(File file) {
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(file.getAbsolutePath());
|
||||
vod.setVodName(file.getName());
|
||||
vod.setVodPic(Image.getIcon(file.isDirectory()));
|
||||
vod.setVodRemarks(format.format(file.lastModified()));
|
||||
vod.setVodTag(file.isDirectory() ? "folder" : "file");
|
||||
return vod;
|
||||
}
|
||||
|
||||
private List<Sub> getSubs(String path) {
|
||||
File file = new File(path);
|
||||
if (file.getParentFile() == null) return Collections.emptyList();
|
||||
List<Sub> subs = new ArrayList<>();
|
||||
for (File f : file.getParentFile().listFiles()) {
|
||||
String ext = Util.getExt(f.getName());
|
||||
if (Util.isSub(ext)) subs.add(Sub.create().name(Util.removeExt(f.getName())).ext(ext).url("file://" + f.getAbsolutePath()));
|
||||
}
|
||||
return subs;
|
||||
}
|
||||
}
|
||||
159
app/src/main/java/com/github/catvod/spider/Market.java
Normal file
159
app/src/main/java/com/github/catvod/spider/Market.java
Normal file
@@ -0,0 +1,159 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.market.Data;
|
||||
import com.github.catvod.bean.market.Item;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.FileUtil;
|
||||
import com.github.catvod.utils.Notify;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.Response;
|
||||
|
||||
public class Market extends Spider {
|
||||
|
||||
private ProgressDialog dialog;
|
||||
private List<Data> datas;
|
||||
private boolean busy;
|
||||
|
||||
public boolean isBusy() {
|
||||
return busy;
|
||||
}
|
||||
|
||||
public void setBusy(boolean busy) {
|
||||
this.busy = busy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) throws Exception {
|
||||
if (extend.startsWith("http")) extend = OkHttp.string(extend);
|
||||
datas = Data.arrayFrom(extend);
|
||||
Init.checkPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
if (datas.size() > 1) for (int i = 1; i < datas.size(); i++) classes.add(datas.get(i).type());
|
||||
return Result.string(classes, datas.get(0).getVod());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
for (Data data : datas) if (data.getName().equals(tid)) return Result.get().page().vod(data.getVod()).string();
|
||||
return super.categoryContent(tid, pg, filter, extend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Init.run(this::finish);
|
||||
Vod vod = new Vod();
|
||||
vod.setVodPlayFrom("FongMi");
|
||||
vod.setVodPlayUrl("FongMi$FongMi");
|
||||
Init.execute(() -> download(ids.get(0)));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
private void finish() {
|
||||
try {
|
||||
Activity activity = Init.getActivity();
|
||||
if (activity != null) activity.finish();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void download(String url) {
|
||||
try {
|
||||
if (isBusy()) return;
|
||||
setBusy(true);
|
||||
Init.run(this::setDialog, 500);
|
||||
Response response = OkHttp.newCall(url);
|
||||
File file = Path.create(new File(Path.download(), Uri.parse(url).getLastPathSegment()));
|
||||
download(file, response.body().byteStream(), Double.parseDouble(response.header("Content-Length", "1")));
|
||||
if (file.getName().endsWith(".zip")) FileUtil.unzip(file, Path.download());
|
||||
if (file.getName().endsWith(".apk")) FileUtil.openFile(file);
|
||||
else Notify.show("下載完成");
|
||||
checkCopy(url);
|
||||
dismiss();
|
||||
} catch (Exception e) {
|
||||
Notify.show(e.getMessage());
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private void download(File file, InputStream is, double length) throws Exception {
|
||||
FileOutputStream os = new FileOutputStream(file);
|
||||
try (BufferedInputStream input = new BufferedInputStream(is)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int readBytes;
|
||||
long totalBytes = 0;
|
||||
while ((readBytes = input.read(buffer)) != -1) {
|
||||
totalBytes += readBytes;
|
||||
os.write(buffer, 0, readBytes);
|
||||
setProgress((int) (totalBytes / length * 100.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCopy(String url) {
|
||||
for (Data data : datas) {
|
||||
int index = data.getList().indexOf(new Item(url));
|
||||
if (index == -1) continue;
|
||||
String text = data.getList().get(index).getCopy();
|
||||
if (!text.isEmpty()) Util.copy(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setDialog() {
|
||||
Init.run(() -> {
|
||||
try {
|
||||
dialog = new ProgressDialog(Init.getActivity());
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
dialog.setCancelable(false);
|
||||
if (isBusy()) dialog.show();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void dismiss() {
|
||||
Init.run(() -> {
|
||||
try {
|
||||
setBusy(false);
|
||||
if (dialog != null) dialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setProgress(int value) {
|
||||
Init.run(() -> {
|
||||
try {
|
||||
if (dialog != null) dialog.setProgress(value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
114
app/src/main/java/com/github/catvod/spider/Miss.java
Normal file
114
app/src/main/java/com/github/catvod/spider/Miss.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class Miss extends Spider {
|
||||
|
||||
private final String url = "https://missav.com/";
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(url));
|
||||
for (Element a : doc.select("a.block.px-4.py-2.text-sm.leading-5.text-nord5.bg-nord3")) {
|
||||
String typeId = a.attr("href").replace(url, "");
|
||||
if (typeId.startsWith("dm") || typeId.contains("VR")) {
|
||||
classes.add(new Class(typeId, a.text()));
|
||||
filters.put(typeId, Arrays.asList(new Filter("filters", "過濾", Arrays.asList(new Filter.Value("全部", ""), new Filter.Value("單人作品", "individual"), new Filter.Value("中文字幕", "chinese-subtitle")))));
|
||||
}
|
||||
}
|
||||
for (Element div : doc.select("div.thumbnail")) {
|
||||
String id = div.select("a.text-secondary").attr("href").replace(url, "");
|
||||
String name = div.select("a.text-secondary").text();
|
||||
String pic = div.select("img").attr("data-src");
|
||||
if (pic.isEmpty()) pic = div.select("img").attr("src");
|
||||
String remark = div.select("span").text();
|
||||
if (TextUtils.isEmpty(name)) continue;
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(classes, list, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String target = url + tid;
|
||||
String filters = extend.get("filters");
|
||||
if (TextUtils.isEmpty(filters)) target += "?page=" + pg;
|
||||
else target += "?filters=" + extend.get("filters") + "&page=" + pg;
|
||||
Document doc = Jsoup.parse(OkHttp.string(target));
|
||||
for (Element div : doc.select("div.thumbnail")) {
|
||||
String id = div.select("a.text-secondary").attr("href").replace(url, "");
|
||||
String name = div.select("a.text-secondary").text();
|
||||
String pic = div.select("img").attr("data-src");
|
||||
if (pic.isEmpty()) pic = div.select("img").attr("src");
|
||||
String remark = div.select("span").text();
|
||||
if (TextUtils.isEmpty(name)) continue;
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(url + ids.get(0)));
|
||||
String name = doc.select("meta[property=og:title]").attr("content");
|
||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("MissAV");
|
||||
vod.setVodPlayUrl("播放$" + ids.get(0));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, pg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().parse().url(url + id).string();
|
||||
}
|
||||
|
||||
private String searchContent(String key, String pg) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(url + "search/" + key + "?page=" + pg));
|
||||
for (Element div : doc.select("div.thumbnail")) {
|
||||
String id = div.select("a.text-secondary").attr("href").replace(url, "");
|
||||
String name = div.select("a.text-secondary").text();
|
||||
String pic = div.select("img").attr("data-src");
|
||||
if (pic.isEmpty()) pic = div.select("img").attr("src");
|
||||
String remark = div.select("span").text();
|
||||
if (TextUtils.isEmpty(name)) continue;
|
||||
list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
349
app/src/main/java/com/github/catvod/spider/NiNi.java
Normal file
349
app/src/main/java/com/github/catvod/spider/NiNi.java
Normal file
@@ -0,0 +1,349 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.security.Key;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
|
||||
public class NiNi extends Spider {
|
||||
|
||||
private static final String desktopUrl = "https://api.nivodz.com/index/desktop/WEB/3.4";
|
||||
private static final String rankingUrl = "https://api.nivodz.com/index/ranking/list/WEB/3.2";
|
||||
private static final String filterUrl = "https://api.nivodz.com/show/filter/condition/WEB/3.2";
|
||||
private static final String searchUrl = "https://api.nivodz.com/show/search/WEB/3.2";
|
||||
private static final String categoryUrl = "https://api.nivodz.com/show/filter/WEB/3.2";
|
||||
private static final String detailUrl = "https://api.nivodz.com/show/detail/WEB/3.2";
|
||||
private static final String playUrl = "https://api.nivodz.com/show/play/info/WEB/3.2";
|
||||
private static final String des_key = "diao.com";
|
||||
private boolean adult;
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
headers.put("Referer", "https://m.nbys.tv/");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Filter getFilter(String name, String key, JSONArray target, String n, String v) throws JSONException {
|
||||
List<Filter.Value> values = new ArrayList<>();
|
||||
if (!key.equals("by")) values.add(new Filter.Value("全部", ""));
|
||||
for (int j = 0; j < target.length(); j++) values.add(new Filter.Value(target.getJSONObject(j).get(n).toString(), target.getJSONObject(j).get(v).toString()));
|
||||
return new Filter(key, name, values);
|
||||
}
|
||||
|
||||
private void checkExtend(HashMap<String, String> extend, String key, String value) {
|
||||
if (extend.get(key) == null || extend.get(key).equals("")) extend.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
adult = !TextUtils.isEmpty(extend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
JSONObject object = new JSONObject(get(filterUrl));
|
||||
for (int i = 0; i < object.getJSONArray("channels").length(); i++) {
|
||||
String typeId = object.getJSONArray("channels").getJSONObject(i).get("channelId").toString();
|
||||
String typeName = object.getJSONArray("channels").getJSONObject(i).get("channelName").toString();
|
||||
if (!adult && typeName.contains("午夜")) continue;
|
||||
classes.add(adult && typeName.contains("午夜") ? 0 : classes.size(), new Class(typeId, typeName));
|
||||
List<Filter> array = new ArrayList<>();
|
||||
array.add(getFilter("排序", "by", object.getJSONObject("sortsMap").getJSONArray(typeId), "title", "id"));
|
||||
array.add(getFilter("語言", "lang", object.getJSONArray("langs"), "langName", "langId"));
|
||||
array.add(getFilter("地區", "area", object.getJSONArray("regions"), "regionName", "regionId"));
|
||||
array.add(getFilter("類型", "class", object.getJSONObject("typesMap").getJSONArray(typeId), "showTypeName", "showTypeId"));
|
||||
array.add(getFilter("年份", "year", object.getJSONArray("yearRanges"), "name", "code"));
|
||||
filters.put(typeId, array);
|
||||
}
|
||||
return Result.string(classes, filters);
|
||||
}
|
||||
|
||||
private String getAdultHome() throws Exception {
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("channel_id", "7");
|
||||
params.put("start", "0");
|
||||
params.put("more", "1");
|
||||
JSONObject object = new JSONObject(post(desktopUrl, params));
|
||||
JSONArray array = object.getJSONArray("list");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONArray rows = array.getJSONObject(i).getJSONArray("rows");
|
||||
for (int j = 0; j < rows.length(); j++) {
|
||||
JSONArray cells = rows.getJSONObject(j).getJSONArray("cells");
|
||||
for (int k = 0; k < cells.length(); k++) {
|
||||
JSONObject item = cells.getJSONObject(k).getJSONObject("show");
|
||||
String id = item.getString("showIdCode");
|
||||
String name = item.getString("showTitle");
|
||||
String pic = item.getString("showImg");
|
||||
list.add(new Vod(id, name, getPic(pic), getRemarks(item)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() throws Exception {
|
||||
if (adult) return getAdultHome();
|
||||
JSONObject object = new JSONObject(get(rankingUrl));
|
||||
JSONArray array = object.getJSONArray("list");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONArray dataItem = array.getJSONArray(i);
|
||||
for (int j = 0; j < dataItem.length(); j++) {
|
||||
JSONObject item = dataItem.getJSONObject(j);
|
||||
String id = item.getString("showIdCode");
|
||||
String name = item.getString("showTitle");
|
||||
String pic = item.getString("showImg");
|
||||
list.add(new Vod(id, name, getPic(pic), getRemarks(item)));
|
||||
}
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
int page = Integer.parseInt(pg) - 1;
|
||||
if (tid.endsWith("/{pg}")) return searchContent(tid.split("/")[0], page);
|
||||
checkExtend(extend, "by", "3");
|
||||
checkExtend(extend, "area", "0");
|
||||
checkExtend(extend, "lang", "0");
|
||||
checkExtend(extend, "year", "");
|
||||
checkExtend(extend, "class", "0");
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("sort_by", extend.get("by"));
|
||||
params.put("channel_id", tid);
|
||||
params.put("show_type_id", extend.get("class"));
|
||||
params.put("region_id", extend.get("area"));
|
||||
params.put("lang_id", extend.get("lang"));
|
||||
params.put("year_range", extend.get("year"));
|
||||
params.put("start", String.valueOf(page * 20));
|
||||
JSONObject object = new JSONObject(post(categoryUrl, params));
|
||||
JSONArray array = object.getJSONArray("list");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
boolean land = tid.equals("7") || tid.equals("16");
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject item = array.getJSONObject(i);
|
||||
String id = item.getString("showIdCode");
|
||||
String name = item.getString("showTitle");
|
||||
String pic = item.getString("showImg");
|
||||
if (land) list.add(new Vod(id, name, getPic(pic), getRemarks(item), Vod.Style.rect(1.33f)));
|
||||
else list.add(new Vod(id, name, getPic(pic), getRemarks(item)));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("show_id_code", ids.get(0));
|
||||
JSONObject object = new JSONObject(post(detailUrl, params));
|
||||
JSONObject entity = object.getJSONObject("entity");
|
||||
JSONArray plays = entity.getJSONArray("plays");
|
||||
String id = entity.optString("showIdCode");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
for (int j = 0; j < plays.length(); j++) {
|
||||
JSONObject item = plays.getJSONObject(j);
|
||||
String episodeName = item.getString("episodeName");
|
||||
episodeName = TextUtils.isEmpty(episodeName) ? "播放" : episodeName;
|
||||
vodItems.add(episodeName + "$" + id + "_" + item.getString("playIdCode"));
|
||||
}
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(id);
|
||||
vod.setVodName(entity.optString("showTitle"));
|
||||
vod.setVodPic(getPic(entity.optString("showImg")));
|
||||
vod.setVodContent(entity.optString("showDesc"));
|
||||
vod.setVodDirector(convert(entity.optString("director")));
|
||||
vod.setVodActor(convert(entity.optString("actors")));
|
||||
vod.setVodYear(entity.optString("postYear"));
|
||||
vod.setVodArea(entity.optString("regionName"));
|
||||
vod.setTypeName((entity.optString("channelName")));
|
||||
vod.setVodPlayUrl(TextUtils.join("#", vodItems));
|
||||
vod.setVodRemarks(getRemarks(entity));
|
||||
vod.setVodPlayFrom("泥巴");
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
String[] ids = id.split("_");
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("show_id_code", ids[0]);
|
||||
params.put("play_id_code", ids[1]);
|
||||
params.put("oid", "1");
|
||||
JSONObject object = new JSONObject(post(playUrl, params));
|
||||
String playUrl = object.getJSONObject("entity").optString("playUrl");
|
||||
return Result.get().url(playUrl).header(getHeaders()).string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, Integer.parseInt(pg) - 1);
|
||||
}
|
||||
|
||||
public String searchContent(String key, int pg) throws Exception {
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("keyword", key);
|
||||
params.put("start", String.valueOf(pg * 20));
|
||||
params.put("cat_id", adult ? "2" : "1");
|
||||
params.put("keyword_type", "0");
|
||||
JSONObject object = new JSONObject(post(searchUrl, params));
|
||||
JSONArray array = object.getJSONArray("list");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject item = array.getJSONObject(i);
|
||||
String id = item.getString("showIdCode");
|
||||
String name = item.getString("showTitle");
|
||||
String pic = item.getString("showImg");
|
||||
list.add(new Vod(id, name, getPic(pic), getRemarks(item)));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
private String genUrl(String url, Map<String, String> bodys) {
|
||||
String randomStr = "AABBCC";
|
||||
String oidTime = String.valueOf(new Date().getTime() - 10 * 60 * 1000);
|
||||
String oid = encode(oidTime + "_" + randomStr);
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("_ts", String.valueOf(new Date().getTime()));
|
||||
params.put("app_version", "1.0");
|
||||
params.put("platform", "3");
|
||||
params.put("market_id", "web_nivod");
|
||||
params.put("device_code", "web");
|
||||
params.put("versioncode", "1");
|
||||
params.put("oid", oid);
|
||||
StringBuilder sign_query = new StringBuilder("__QUERY::");
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
if (entry.getValue().equals("")) continue;
|
||||
sign_query.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
|
||||
}
|
||||
StringBuilder sign_body = new StringBuilder("__BODY::");
|
||||
for (Map.Entry<String, String> entry : bodys.entrySet()) {
|
||||
if (entry.getValue().equals("")) continue;
|
||||
sign_body.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
|
||||
}
|
||||
String _SECRET_PREFIX = "__KEY::";
|
||||
String secretKey = "2x_Give_it_a_shot";
|
||||
String has = Util.MD5(sign_query + sign_body.toString() + _SECRET_PREFIX + secretKey, "UTF-8");
|
||||
url += "?_ts=" + params.get("_ts") + "&app_version=" + params.get("app_version") + "&platform=" + params.get("platform") + "&market_id=" + params.get("market_id") + "&device_code=" + params.get("device_code") + "&versioncode=" + params.get("versioncode") + "&oid=" + params.get("oid") + "&sign=" + has;
|
||||
return url;
|
||||
}
|
||||
|
||||
private String getPic(String pic) {
|
||||
return pic.replace(".nivod4.", ".nivod.");
|
||||
}
|
||||
|
||||
private String getRemarks(JSONObject item) {
|
||||
String remark = item.optString("episodesTxt");
|
||||
remark = TextUtils.isEmpty(remark) || remark.equals("null") ? "" : remark;
|
||||
return remark;
|
||||
}
|
||||
|
||||
private String convert(String text) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : text.split(",")) sb.append(String.format("[a=cr:{\"id\":\"%s\",\"name\":\"%s\"}/]%s[/a]", s + "/{pg}", s, s)).append(",");
|
||||
return Util.substring(sb.toString());
|
||||
}
|
||||
|
||||
private String get(String url) {
|
||||
return decode(OkHttp.string(genUrl(url, new HashMap<>()), getHeaders()));
|
||||
}
|
||||
|
||||
private String post(String url, Map<String, String> params) {
|
||||
return decode(OkHttp.post(genUrl(url, params), params, getHeaders()).getBody());
|
||||
}
|
||||
|
||||
@SuppressLint("GetInstance")
|
||||
private Cipher getCipher(int mode) {
|
||||
try {
|
||||
DESKeySpec dks = new DESKeySpec(des_key.getBytes());
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||
Key secretKey = keyFactory.generateSecret(dks);
|
||||
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS7Padding");
|
||||
cipher.init(mode, secretKey);
|
||||
return cipher;
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String encode(String data) {
|
||||
try {
|
||||
if (data == null || data.isEmpty()) return "";
|
||||
Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
|
||||
if (cipher == null) return "";
|
||||
byte[] byteHex = cipher.doFinal(data.getBytes("UTF-8"));
|
||||
return byteToHexString(byteHex);
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String decode(String data) {
|
||||
try {
|
||||
if (data == null || data.isEmpty()) return "";
|
||||
byte[] b = hex2byte(data);
|
||||
Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
|
||||
if (cipher == null) return "";
|
||||
return new String(cipher.doFinal(b), "UTF-8");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String byteToHexString(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder(bytes.length);
|
||||
String sTemp;
|
||||
for (byte aByte : bytes) {
|
||||
sTemp = Integer.toHexString(0xFF & aByte);
|
||||
if (sTemp.length() < 2) sb.append(0);
|
||||
sb.append(sTemp.toUpperCase());
|
||||
}
|
||||
return sb.toString().toLowerCase();
|
||||
}
|
||||
|
||||
private byte[] hex2byte(String hex) throws IllegalArgumentException {
|
||||
char[] arr = hex.toCharArray();
|
||||
byte[] b = new byte[hex.length() / 2];
|
||||
for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
|
||||
String swap = String.valueOf(arr[i++]) + arr[i];
|
||||
int byteInt = Integer.parseInt(swap, 16) & 0xFF;
|
||||
b[j] = Integer.valueOf(byteInt).byteValue();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
||||
100
app/src/main/java/com/github/catvod/spider/Notice.java
Normal file
100
app/src/main/java/com/github/catvod/spider/Notice.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.Base64;
|
||||
import android.view.Gravity;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.ui.ScrollTextView;
|
||||
import com.github.catvod.utils.ResUtil;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
|
||||
public class Notice extends Spider {
|
||||
|
||||
private static final String SPACE = " ";
|
||||
private ScrollTextView view;
|
||||
private String extend;
|
||||
private int duration;
|
||||
private String msg;
|
||||
|
||||
public static void show(String extend) {
|
||||
try {
|
||||
Notice notice = new Notice();
|
||||
notice.init(null, extend);
|
||||
notice.homeContent(false);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
this.extend = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
|
||||
String json = extend.startsWith("http") ? OkHttp.string(extend) : new String(Base64.decode(extend, Base64.DEFAULT));
|
||||
JSONObject object = new JSONObject(json);
|
||||
msg = object.optString("msg");
|
||||
duration = object.optInt("duration", 30);
|
||||
String date = object.optString("date");
|
||||
boolean show = msg.length() > 0 && (date.isEmpty() || new Date().after(sdf.parse(date)));
|
||||
if (show) Init.run(this::createView, 500);
|
||||
return "";
|
||||
}
|
||||
|
||||
private void createView() {
|
||||
createText();
|
||||
createRoot();
|
||||
setColor();
|
||||
hide();
|
||||
}
|
||||
|
||||
private void createText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 2; i++) sb.append(SPACE).append(msg);
|
||||
view = new ScrollTextView(Init.context());
|
||||
view.setTextSize(20);
|
||||
view.setDuration(duration);
|
||||
view.setText(sb.toString());
|
||||
view.setTypeface(null, Typeface.BOLD);
|
||||
view.setPadding(0, ResUtil.dp2px(16), 0, ResUtil.dp2px(16));
|
||||
view.setBackgroundColor(Color.argb(200, 255, 255, 255));
|
||||
view.startScroll();
|
||||
}
|
||||
|
||||
private void createRoot() {
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
params.gravity = Gravity.TOP;
|
||||
Util.addView(view, params);
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
Init.run(() -> Util.removeView(view), duration * 1000);
|
||||
}
|
||||
|
||||
private void setColor() {
|
||||
Init.run(runnable, 500);
|
||||
}
|
||||
|
||||
private final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Random random = new Random();
|
||||
view.setTextColor(Color.argb(255, random.nextInt(128), random.nextInt(128), random.nextInt(128)));
|
||||
setColor();
|
||||
}
|
||||
};
|
||||
}
|
||||
60
app/src/main/java/com/github/catvod/spider/PanSearch.java
Normal file
60
app/src/main/java/com/github/catvod/spider/PanSearch.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zhixc
|
||||
*/
|
||||
public class PanSearch extends Ali {
|
||||
|
||||
private final String URL = "https://www.pansearch.me/";
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
private Map<String, String> getSearchHeader() {
|
||||
Map<String, String> header = getHeader();
|
||||
header.put("x-nextjs-data", "1");
|
||||
header.put("referer", URL);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
String html = OkHttp.string(URL, getHeader());
|
||||
String data = Jsoup.parse(html).select("script[id=__NEXT_DATA__]").get(0).data();
|
||||
String buildId = new JSONObject(data).getString("buildId");
|
||||
String url = URL + "_next/data/" + buildId + "/search.json?keyword=" + URLEncoder.encode(key) + "&pan=aliyundrive";
|
||||
String result = OkHttp.string(url, getSearchHeader());
|
||||
JSONArray array = new JSONObject(result).getJSONObject("pageProps").getJSONObject("data").getJSONArray("data");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject item = array.getJSONObject(i);
|
||||
String content = item.optString("content");
|
||||
String[] split = content.split("\\n");
|
||||
if (split.length == 0) continue;
|
||||
String vodId = Jsoup.parse(content).select("a").attr("href");
|
||||
String name = split[0].replaceAll("</?[^>]+>", "");
|
||||
String remark = item.optString("time");
|
||||
String pic = item.optString("image");
|
||||
list.add(new Vod(vodId, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
73
app/src/main/java/com/github/catvod/spider/PanSou.java
Normal file
73
app/src/main/java/com/github/catvod/spider/PanSou.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ColaMint & FongMi
|
||||
*/
|
||||
public class PanSou extends Ali {
|
||||
|
||||
private final String siteUrl = "https://www.alipansou.com";
|
||||
|
||||
private Map<String, String> getHeaders(String id) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
headers.put("Referer", siteUrl + id);
|
||||
headers.put("_bid", "6d14a5dd6c07980d9dc089a693805ad8");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
HashMap<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
if (pattern.matcher(ids.get(0)).find()) return super.detailContent(ids);
|
||||
String url = siteUrl + ids.get(0).replace("/s/", "/cv/");
|
||||
url = OkHttp.getLocation(url, getHeaders(ids.get(0)));
|
||||
return super.detailContent(Arrays.asList(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, pg);
|
||||
}
|
||||
|
||||
private String searchContent(String key, String pg) {
|
||||
String url = siteUrl + "/search?k=" + URLEncoder.encode(key) + "&page=" + pg + "&s=0&t=-1";
|
||||
Elements items = Jsoup.parse(OkHttp.string(url, getHeader())).select("van-row > a");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element item : items) {
|
||||
String title = item.selectFirst("template").text().trim();
|
||||
if (!title.contains(key)) continue;
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(item.attr("href"));
|
||||
vod.setVodPic("https://inews.gtimg.com/newsapp_bt/0/13263837859/1000");
|
||||
vod.setVodName(title);
|
||||
list.add(vod);
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
52
app/src/main/java/com/github/catvod/spider/Proxy.java
Normal file
52
app/src/main/java/com/github/catvod/spider/Proxy.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Map;
|
||||
|
||||
public class Proxy extends Spider {
|
||||
|
||||
private static int port = -1;
|
||||
|
||||
public static Object[] proxy(Map<String, String> params) throws Exception {
|
||||
switch (params.get("do")) {
|
||||
case "ck":
|
||||
return new Object[]{200, "text/plain; charset=utf-8", new ByteArrayInputStream("ok".getBytes("UTF-8"))};
|
||||
case "ali":
|
||||
return Ali.proxy(params);
|
||||
case "bili":
|
||||
return Bili.proxy(params);
|
||||
case "webdav":
|
||||
return WebDAV.vod(params);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static void adjustPort() {
|
||||
if (Proxy.port > 0) return;
|
||||
int port = 9978;
|
||||
while (port < 10000) {
|
||||
String resp = OkHttp.string("http://127.0.0.1:" + port + "/proxy?do=ck", null);
|
||||
if (resp.equals("ok")) {
|
||||
SpiderDebug.log("Found local server port " + port);
|
||||
Proxy.port = port;
|
||||
break;
|
||||
}
|
||||
port++;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getPort() {
|
||||
adjustPort();
|
||||
return port;
|
||||
}
|
||||
|
||||
public static String getUrl() {
|
||||
adjustPort();
|
||||
return "http://127.0.0.1:" + port + "/proxy";
|
||||
}
|
||||
}
|
||||
91
app/src/main/java/com/github/catvod/spider/Push.java
Normal file
91
app/src/main/java/com/github/catvod/spider/Push.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
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.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Push extends Spider {
|
||||
|
||||
private final Ali ali;
|
||||
|
||||
public Push() {
|
||||
ali = new Ali();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
ali.init(context, extend);
|
||||
}
|
||||
|
||||
@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)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
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);
|
||||
}
|
||||
|
||||
private Vod vod(String url) {
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(url);
|
||||
vod.setTypeName("FongMi");
|
||||
vod.setVodName(url.startsWith("file://") ? new File(url).getName() : url);
|
||||
if (url.startsWith("http") && url.contains("#")) url = url.replace("#", "***");
|
||||
vod.setVodPic("https://pic.rmb.bdstatic.com/bjh/1d0b02d0f57f0a42201f92caba5107ed.jpeg");
|
||||
String play = "播放$" + url;
|
||||
boolean thunder = Util.isThunder(url);
|
||||
vod.setVodPlayUrl(thunder ? play : TextUtils.join("$$$", Arrays.asList(play, play, play)));
|
||||
vod.setVodPlayFrom(thunder ? "迅雷" : TextUtils.join("$$$", Arrays.asList("直連", "嗅探", "解析")));
|
||||
return vod;
|
||||
}
|
||||
|
||||
private List<Sub> getSubs(String url) {
|
||||
List<Sub> subs = new ArrayList<>();
|
||||
if (url.startsWith("file://")) setFileSub(url, subs);
|
||||
if (url.startsWith("http://")) setHttpSub(url, subs);
|
||||
return subs;
|
||||
}
|
||||
|
||||
private void setHttpSub(String url, List<Sub> subs) {
|
||||
List<String> vodTypes = Arrays.asList("mp4", "mkv");
|
||||
List<String> subTypes = Arrays.asList("srt", "ass");
|
||||
if (!vodTypes.contains(Util.getExt(url))) return;
|
||||
for (String ext : subTypes) detectSub(url, ext, subs);
|
||||
}
|
||||
|
||||
private void detectSub(String url, String ext, List<Sub> subs) {
|
||||
url = Util.removeExt(url).concat(".").concat(ext);
|
||||
if (OkHttp.string(url).length() < 100) return;
|
||||
String name = Uri.parse(url).getLastPathSegment();
|
||||
subs.add(Sub.create().name(name).ext(ext).url(url));
|
||||
}
|
||||
|
||||
private void setFileSub(String url, List<Sub> subs) {
|
||||
File file = new File(url.replace("file://", ""));
|
||||
if (file.getParentFile() == null) return;
|
||||
for (File f : file.getParentFile().listFiles()) {
|
||||
String ext = Util.getExt(f.getName());
|
||||
if (Util.isSub(ext)) subs.add(Sub.create().name(Util.removeExt(f.getName())).ext(ext).url("file://" + f.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
110
app/src/main/java/com/github/catvod/spider/QxiTv.java
Normal file
110
app/src/main/java/com/github/catvod/spider/QxiTv.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.orhanobut.logger.Logger;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class QxiTv extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://7xi.tv";
|
||||
private static final String cateUrl = siteUrl + "/vodtype/";
|
||||
private static final String detailUrl = siteUrl + "/videos/";
|
||||
private static final String searchUrl = siteUrl + "/search/";
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(cateUrl.concat("1.html"), getHeaders()));
|
||||
// for (Element element : doc.select(".header_nav1 div.this-wap > a")) {
|
||||
// String typeId = element.attr("href");
|
||||
// String typeName = element.text();
|
||||
// classes.add(new Class(typeId, typeName));
|
||||
// }
|
||||
doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
|
||||
for (Element element : doc.select("div.public-list-div")) {
|
||||
try {
|
||||
String pic = element.select("img").attr("data-src");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("a.title").text();
|
||||
if (pic.endsWith(".gif") || name.isEmpty()) continue;
|
||||
String id = url.split("/")[2];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}catch (Exception e){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return Result.string(classes, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String target = cateUrl + tid + "/?mode=async&function=get_block&block_id=list_videos_common_videos_list&sort_by=post_date&from=" + String.format(Locale.getDefault(), "%02d", Integer.parseInt(pg)) + "&_=" + System.currentTimeMillis();
|
||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
||||
for (Element element : doc.select("div.video-img-box")) {
|
||||
String pic = element.select("img").attr("data-src");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("div.detail > h6").text();
|
||||
String id = url.split("/")[4];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)).concat("/"), getHeaders()));
|
||||
String name = doc.select("meta[property=og:title]").attr("content");
|
||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
||||
String year = doc.select("span.inactive-color").get(0).text();
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodPic(pic);
|
||||
vod.setVodYear(year.replace("上市於 ", ""));
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom("Jable");
|
||||
vod.setVodPlayUrl("播放$" + Util.getVar(doc.html(), "hlsUrl"));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)).concat("/"), getHeaders()));
|
||||
for (Element element : doc.select("div.video-img-box")) {
|
||||
String pic = element.select("img").attr("data-src");
|
||||
String url = element.select("a").attr("href");
|
||||
String name = element.select("div.detail > h6").text();
|
||||
String id = url.split("/")[4];
|
||||
list.add(new Vod(id, name, pic));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).header(getHeaders()).string();
|
||||
}
|
||||
}
|
||||
153
app/src/main/java/com/github/catvod/spider/Star.java
Normal file
153
app/src/main/java/com/github/catvod/spider/Star.java
Normal file
@@ -0,0 +1,153 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.star.Card;
|
||||
import com.github.catvod.bean.star.Condition;
|
||||
import com.github.catvod.bean.star.Group;
|
||||
import com.github.catvod.bean.star.Info;
|
||||
import com.github.catvod.bean.star.Person;
|
||||
import com.github.catvod.bean.star.Query;
|
||||
import com.github.catvod.bean.star.Video;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Star extends Spider {
|
||||
|
||||
private static final String apiUrl = "https://aws.ulivetv.net/v3/web/api/filter";
|
||||
private static final String siteUrl = "https://www.histar.tv/";
|
||||
private static final String detail = siteUrl + "vod/detail/";
|
||||
private static final String data = "_next/data/";
|
||||
private LinkedHashMap<String, String> map;
|
||||
private String ver;
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", Util.CHROME);
|
||||
headers.put("Referer", siteUrl);
|
||||
return headers;
|
||||
}
|
||||
|
||||
private String getVer() {
|
||||
for (Element script : Jsoup.parse(OkHttp.string(siteUrl, getHeader())).select("script")) if (script.attr("src").contains("buildManifest.js")) return script.attr("src").split("/")[3];
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
map = new LinkedHashMap<>();
|
||||
map.put("movie", "电影");
|
||||
map.put("drama", "电视剧");
|
||||
map.put("animation", "动漫");
|
||||
map.put("variety", "综艺");
|
||||
ver = getVer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) classes.add(new Class(entry.getKey(), entry.getValue()));
|
||||
for (Class type : classes) {
|
||||
Element script = Jsoup.parse(OkHttp.string(siteUrl + type.getTypeId() + "/all/all/all", getHeader())).select("#__NEXT_DATA__").get(0);
|
||||
JSONObject obj = new JSONObject(script.data()).getJSONObject("props").getJSONObject("pageProps").getJSONObject("filterCondition");
|
||||
Condition item = Condition.objectFrom(obj.toString());
|
||||
filters.put(type.getTypeId(), item.getFilter());
|
||||
}
|
||||
return Result.string(classes, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Element script = Jsoup.parse(OkHttp.string(siteUrl, getHeader())).select("#__NEXT_DATA__").get(0);
|
||||
List<Card> cards = Card.arrayFrom(new JSONObject(script.data()).getJSONObject("props").getJSONObject("pageProps").getJSONArray("cards").toString());
|
||||
for (Card card : cards) if (!card.getName().equals("电视直播")) for (Card item : card.getCards()) list.add(item.vod());
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
if (tid.endsWith("/{pg}")) return searchContent(tid.split("/")[0], true);
|
||||
String year = extend.containsKey("year") ? extend.get("year") : "";
|
||||
String type = extend.containsKey("type") ? extend.get("type") : "";
|
||||
String area = extend.containsKey("area") ? extend.get("area") : "";
|
||||
Query query = new Query();
|
||||
query.setPageSize(16);
|
||||
query.setChName(map.get(tid));
|
||||
query.setPage(Integer.parseInt(pg));
|
||||
if (year.length() > 0) query.setYear(year);
|
||||
if (type.length() > 0) query.setLabel(type);
|
||||
if (area.length() > 0) query.setCountry(area);
|
||||
String body = OkHttp.post(apiUrl, query.toString());
|
||||
List<Card> cards = Card.arrayFrom(new JSONObject(body).getJSONObject("data").getJSONArray("list").toString());
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Card card : cards) list.add(card.vod());
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
Element script = Jsoup.parse(OkHttp.string(detail.concat(ids.get(0)), getHeader())).select("#__NEXT_DATA__").get(0);
|
||||
Info detail = Info.objectFrom(new JSONObject(script.data()).getJSONObject("props").getJSONObject("pageProps").getJSONObject("collectionInfo").toString());
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodYear(detail.getTime());
|
||||
vod.setVodName(detail.getName());
|
||||
vod.setVodPic(detail.getPicurl());
|
||||
vod.setVodArea(detail.getCountry());
|
||||
vod.setVodContent(detail.getDesc());
|
||||
vod.setVodRemarks(detail.getCountStr());
|
||||
vod.setVodActor(convert(detail.getActor()));
|
||||
vod.setVodDirector(convert(detail.getDirector()));
|
||||
List<String> playFrom = new ArrayList<>();
|
||||
List<String> playUrls = new ArrayList<>();
|
||||
for (Group group : detail.getVideosGroup()) {
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Video video : group.getVideos()) urls.add(video.getEporder() + "$" + video.getPurl());
|
||||
playUrls.add(TextUtils.join("#", urls));
|
||||
playFrom.add(group.getName());
|
||||
}
|
||||
vod.setVodPlayUrl(TextUtils.join("$$$", playUrls));
|
||||
vod.setVodPlayFrom(TextUtils.join("$$$", playFrom));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String json = OkHttp.string(siteUrl + data + ver + "/search.json?word=" + URLEncoder.encode(key), getHeader());
|
||||
List<Card> items = Card.arrayFrom(new JSONObject(json).getJSONObject("pageProps").getJSONArray("initList").toString());
|
||||
for (Card item : items) list.add(item.vod());
|
||||
return Result.get().vod(list).page().string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
return Result.get().url(id).string();
|
||||
}
|
||||
|
||||
private String convert(List<Person> items) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Person item : items) sb.append(String.format("[a=cr:{\"id\":\"%s\",\"name\":\"%s\"}/]%s[/a]", item.getName() + "/{pg}", item.getName(), item.getName())).append(",");
|
||||
return Util.substring(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
53
app/src/main/java/com/github/catvod/spider/UpYun.java
Normal file
53
app/src/main/java/com/github/catvod/spider/UpYun.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class UpYun extends Ali {
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, pg);
|
||||
}
|
||||
|
||||
private String searchContent(String key, String pg) throws Exception {
|
||||
String searchUrl = "https://upapi.juapp9.com/search?keyword=" + URLEncoder.encode(key) + "&page=" + pg + "&s_type=2";
|
||||
String content = OkHttp.string(searchUrl, getHeader());
|
||||
String decodedContent = new String(Base64.decode(content, Base64.DEFAULT));
|
||||
JSONArray jsonArray = new JSONObject(decodedContent).getJSONObject("result").getJSONArray("items");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jsonObj = jsonArray.getJSONObject(i);
|
||||
String id = jsonObj.optString("page_url");
|
||||
String name = jsonObj.optString("title");
|
||||
String pic = "https://pic.imgdb.cn/item/65767399c458853aeff8a6a0.webp";
|
||||
String remark = jsonObj.optString("insert_time");
|
||||
if (name.contains(key)) list.add(new Vod(id, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
191
app/src/main/java/com/github/catvod/spider/WebDAV.java
Normal file
191
app/src/main/java/com/github/catvod/spider/WebDAV.java
Normal file
@@ -0,0 +1,191 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Filter;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Sub;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.webdav.Drive;
|
||||
import com.github.catvod.bean.webdav.Sorter;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Image;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.thegrizzlylabs.sardineandroid.DavResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WebDAV extends Spider {
|
||||
|
||||
private static List<Drive> drives;
|
||||
private List<String> allExt;
|
||||
private String extend;
|
||||
|
||||
private List<Filter> getFilter() {
|
||||
List<Filter> items = new ArrayList<>();
|
||||
items.add(new Filter("type", "排序類型", Arrays.asList(new Filter.Value("預設", ""), new Filter.Value("名稱", "name"), new Filter.Value("大小", "size"), new Filter.Value("修改時間", "date"))));
|
||||
items.add(new Filter("order", "排序方式", Arrays.asList(new Filter.Value("預設", ""), new Filter.Value("⬆", "asc"), new Filter.Value("⬇", "desc"))));
|
||||
return items;
|
||||
}
|
||||
|
||||
private void fetchRule() {
|
||||
if (drives != null && !drives.isEmpty()) return;
|
||||
if (extend.startsWith("http")) extend = OkHttp.string(extend);
|
||||
Drive drive = Drive.objectFrom(extend);
|
||||
drives = drive.getDrives();
|
||||
}
|
||||
|
||||
private String getExt(DavResource item) {
|
||||
return Util.getExt(item.getName());
|
||||
}
|
||||
|
||||
private String removeExt(DavResource item) {
|
||||
return Util.removeExt(item.getName());
|
||||
}
|
||||
|
||||
private static Drive getDrive(String name) {
|
||||
return drives.get(drives.indexOf(new Drive(name)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
this.allExt = new ArrayList<>(Arrays.asList("ass", "ssa", "srt"));
|
||||
this.allExt.addAll(Util.MEDIA);
|
||||
this.extend = extend;
|
||||
fetchRule();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) throws Exception {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
||||
for (Drive drive : drives) classes.add(drive.toType());
|
||||
for (Class item : classes) filters.put(item.getTypeId(), getFilter());
|
||||
return Result.string(classes, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
||||
String key = tid.contains("/") ? tid.substring(0, tid.indexOf("/")) : tid;
|
||||
String path = tid.contains("/") ? tid.substring(tid.indexOf("/")) : "";
|
||||
String order = extend.containsKey("order") ? extend.get("order") : "";
|
||||
String type = extend.containsKey("type") ? extend.get("type") : "";
|
||||
List<DavResource> folders = new ArrayList<>();
|
||||
List<DavResource> files = new ArrayList<>();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Drive drive = getDrive(key);
|
||||
for (DavResource item : getList(drive, path, Util.MEDIA)) {
|
||||
if (item.isDirectory()) folders.add(item);
|
||||
else files.add(item);
|
||||
}
|
||||
if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(order)) {
|
||||
Sorter.sort(type, order, folders);
|
||||
Sorter.sort(type, order, files);
|
||||
}
|
||||
for (DavResource item : folders) list.add(drive.vod(item, Image.FOLDER));
|
||||
for (DavResource item : files) list.add(drive.vod(item, Image.VIDEO));
|
||||
return Result.get().vod(list).page().string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String id = ids.get(0);
|
||||
String key = id.contains("/") ? id.substring(0, id.indexOf("/")) : id;
|
||||
String parent = id.substring(0, id.lastIndexOf("/"));
|
||||
String path = parent.contains("/") ? parent.substring(parent.indexOf("/")) + "/" : "";
|
||||
String name = parent.substring(parent.lastIndexOf("/") + 1);
|
||||
Drive drive = getDrive(key);
|
||||
List<DavResource> parents = getList(drive, path, allExt);
|
||||
List<DavResource> subs = getSubs(parents);
|
||||
Sorter.sort("name", "asc", parents);
|
||||
List<String> playUrls = new ArrayList<>();
|
||||
for (DavResource item : parents) {
|
||||
if (Util.isMedia(item.getName())) {
|
||||
playUrls.add(item.getName() + "$" + drive.getName() + item.getPath() + findSubs(drive, item, subs));
|
||||
}
|
||||
}
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(name);
|
||||
vod.setVodName(name);
|
||||
vod.setVodPlayFrom(key);
|
||||
vod.setVodPic(Image.VIDEO);
|
||||
vod.setVodPlayUrl(TextUtils.join("#", playUrls));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
||||
String[] ids = id.split("~~~");
|
||||
return Result.get().url(getProxyUrl(ids[0])).subs(getSub(ids)).string();
|
||||
}
|
||||
|
||||
private List<DavResource> getList(Drive drive, String path, List<String> ext) throws Exception {
|
||||
path = drive.getHost() + (path.startsWith(drive.getPath()) ? path : drive.getPath() + path);
|
||||
List<DavResource> items = drive.getWebdav().list(path);
|
||||
items.remove(0); //Remove parent
|
||||
Iterator<DavResource> iterator = items.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
DavResource item = iterator.next();
|
||||
if (!item.isDirectory() && !item.getName().contains(".")) iterator.remove();
|
||||
if (!item.isDirectory() && !ext.contains(getExt(item))) iterator.remove();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private List<DavResource> getSubs(List<DavResource> items) {
|
||||
List<DavResource> subs = new ArrayList<>();
|
||||
for (DavResource item : items) if (Util.isSub(getExt(item))) subs.add(item);
|
||||
return subs;
|
||||
}
|
||||
|
||||
private String findSubs(Drive drive, DavResource res, List<DavResource> items) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (DavResource item : items) if (removeExt(item).equals(removeExt(res))) sb.append("~~~").append(item.getName()).append("@@@").append(getExt(item)).append("@@@").append(drive.getName() + item.getPath());
|
||||
return sb.length() > 0 ? sb.toString() : findSubs(drive, items);
|
||||
}
|
||||
|
||||
private String findSubs(Drive drive, List<DavResource> items) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (DavResource item : items) sb.append("~~~").append(item.getName()).append("@@@").append(getExt(item)).append("@@@").append(drive.getName() + item.getPath());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<Sub> getSub(String[] ids) {
|
||||
List<Sub> sub = new ArrayList<>();
|
||||
for (String text : ids) {
|
||||
if (!text.contains("@@@")) continue;
|
||||
String[] split = text.split("@@@");
|
||||
String name = split[0];
|
||||
String ext = split[1];
|
||||
String url = getProxyUrl(split[2]);
|
||||
sub.add(Sub.create().name(name).ext(ext).url(url));
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
|
||||
private String getProxyUrl(String url) {
|
||||
return Proxy.getUrl() + "?do=webdav&url=" + url;
|
||||
}
|
||||
|
||||
public static Object[] vod(Map<String, String> params) throws IOException {
|
||||
String url = params.get("url");
|
||||
String key = url.contains("/") ? url.substring(0, url.indexOf("/")) : url;
|
||||
url = url.substring(key.length());
|
||||
Drive drive = getDrive(key);
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = "application/octet-stream";
|
||||
result[2] = drive.getWebdav().get(drive.getHost() + url);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
151
app/src/main/java/com/github/catvod/spider/Wogg.java
Normal file
151
app/src/main/java/com/github/catvod/spider/Wogg.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Json;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author zhixc
|
||||
*/
|
||||
public class Wogg extends Ali {
|
||||
|
||||
private final String siteUrl = "https://tvfan.xxooo.cf";
|
||||
private final Pattern regexCategory = Pattern.compile("/vodtype/(\\w+).html");
|
||||
private final Pattern regexPageTotal = Pattern.compile("\\$\\(\"\\.mac_total\"\\)\\.text\\('(\\d+)'\\);");
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("User-Agent", Util.CHROME);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
JsonObject ext = Json.safeObject(extend);
|
||||
super.init(context, ext.has("token") ? ext.get("token").getAsString() : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeader()));
|
||||
Elements elements = doc.select(".nav-link");
|
||||
for (Element e : elements) {
|
||||
Matcher mather = regexCategory.matcher(e.attr("href"));
|
||||
if (mather.find()) {
|
||||
classes.add(new Class(mather.group(1), e.text().trim()));
|
||||
}
|
||||
}
|
||||
return Result.string(classes, parseVodListFromDoc(doc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
String[] urlParams = new String[]{tid, "", "", "", "", "", "", "", pg, "", "", ""};
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (String key : extend.keySet()) {
|
||||
urlParams[Integer.parseInt(key)] = extend.get(key);
|
||||
}
|
||||
}
|
||||
Document doc = Jsoup.parse(OkHttp.string(String.format("%s/index.php/vodshow/%s.html", siteUrl, String.join("-", urlParams)), getHeader()));
|
||||
int page = Integer.parseInt(pg), limit = 72, total = 0;
|
||||
Matcher matcher = regexPageTotal.matcher(doc.html());
|
||||
if (matcher.find()) total = Integer.parseInt(matcher.group(1));
|
||||
int count = total <= limit ? 1 : ((int) Math.ceil(total / (double) limit));
|
||||
return Result.get().vod(parseVodListFromDoc(doc)).page(page, count, limit, total).string();
|
||||
}
|
||||
|
||||
private List<Vod> parseVodListFromDoc(Document doc) {
|
||||
List<Vod> list = new ArrayList<>();
|
||||
Elements elements = doc.select(".module-item");
|
||||
for (Element e : elements) {
|
||||
String vodId = e.selectFirst(".video-name a").attr("href");
|
||||
String vodPic = e.selectFirst(".module-item-pic > img").attr("data-src");
|
||||
String vodName = e.selectFirst(".video-name").text();
|
||||
String vodRemarks = e.selectFirst(".module-item-text").text();
|
||||
list.add(new Vod(vodId, vodName, vodPic, vodRemarks));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String vodId = ids.get(0);
|
||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl + vodId, getHeader()));
|
||||
|
||||
Vod item = new Vod();
|
||||
item.setVodId(vodId);
|
||||
item.setVodName(doc.selectFirst(".video-info-header > .page-title").text());
|
||||
item.setVodPic(doc.selectFirst(".module-item-pic img").attr("data-src"));
|
||||
item.setVodArea(doc.select(".video-info-header a.tag-link").last().text());
|
||||
item.setTypeName(String.join(",", doc.select(".video-info-header div.tag-link a").eachText()));
|
||||
|
||||
List<String> shareLinks = doc.select(".module-row-text").eachAttr("data-clipboard-text");
|
||||
for (int i = 0; i < shareLinks.size(); i++) shareLinks.set(i, shareLinks.get(i).trim());
|
||||
|
||||
item.setVodPlayFrom(detailContentVodPlayFrom(shareLinks));
|
||||
item.setVodPlayUrl(detailContentVodPlayUrl(shareLinks));
|
||||
|
||||
Elements elements = doc.select(".video-info-item");
|
||||
for (Element e : elements) {
|
||||
String title = e.previousElementSibling().text();
|
||||
if (title.contains("导演")) {
|
||||
item.setVodDirector(String.join(",", e.select("a").eachText()));
|
||||
} else if (title.contains("主演")) {
|
||||
item.setVodActor(String.join(",", e.select("a").eachText()));
|
||||
} else if (title.contains("年代")) {
|
||||
item.setVodYear(e.selectFirst("a").text().trim());
|
||||
} else if (title.contains("备注")) {
|
||||
item.setVodRemarks(e.text().trim());
|
||||
} else if (title.contains("剧情")) {
|
||||
item.setVodContent(e.selectFirst(".sqjj_a").text().replace("[收起部分]", "").trim());
|
||||
}
|
||||
}
|
||||
|
||||
return Result.string(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
return searchContent(key, "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
||||
return searchContent(key, pg);
|
||||
}
|
||||
|
||||
private String searchContent(String key, String pg) {
|
||||
String searchURL = siteUrl + String.format("/index.php/vodsearch/%s----------%s---.html", URLEncoder.encode(key), pg);
|
||||
String html = OkHttp.string(searchURL, getHeader());
|
||||
Elements items = Jsoup.parse(html).select(".module-search-item");
|
||||
List<Vod> list = new ArrayList<>();
|
||||
for (Element item : items) {
|
||||
String vodId = item.select(".video-serial").attr("href");
|
||||
String name = item.select(".video-serial").attr("title");
|
||||
String pic = item.select(".module-item-pic > img").attr("data-src");
|
||||
String remark = item.select(".video-tag-icon").text();
|
||||
list.add(new Vod(vodId, name, pic, remark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
}
|
||||
345
app/src/main/java/com/github/catvod/spider/XPath.java
Normal file
345
app/src/main/java/com/github/catvod/spider/XPath.java
Normal file
@@ -0,0 +1,345 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.xpath.Rule;
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import com.github.catvod.utils.Util;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.seimicrawler.xpath.JXDocument;
|
||||
import org.seimicrawler.xpath.JXNode;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class XPath extends Spider {
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", rule.getUa().isEmpty() ? Util.CHROME : rule.getUa());
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
this.ext = extend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
fetchRule();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
List<Class> classes = new ArrayList<>();
|
||||
if (rule.getCateManual().size() > 0) {
|
||||
Set<String> keys = rule.getCateManual().keySet();
|
||||
for (String k : keys) {
|
||||
classes.add(new Class(rule.getCateManual().get(k), k));
|
||||
}
|
||||
}
|
||||
String webUrl = rule.getHomeUrl();
|
||||
JXDocument doc = JXDocument.create(fetch(webUrl));
|
||||
if (rule.getCateManual().size() == 0) {
|
||||
List<JXNode> navNodes = doc.selN(rule.getCateNode());
|
||||
for (int i = 0; i < navNodes.size(); i++) {
|
||||
String name = navNodes.get(i).selOne(rule.getCateName()).asString().trim();
|
||||
name = rule.getCateNameR(name);
|
||||
String id = navNodes.get(i).selOne(rule.getCateId()).asString().trim();
|
||||
id = rule.getCateIdR(id);
|
||||
classes.add(new Class(id, name));
|
||||
}
|
||||
}
|
||||
if (!rule.getHomeVodNode().isEmpty()) {
|
||||
List<JXNode> vodNodes = doc.selN(rule.getHomeVodNode());
|
||||
for (int i = 0; i < vodNodes.size(); i++) {
|
||||
String name = vodNodes.get(i).selOne(rule.getHomeVodName()).asString().trim();
|
||||
name = rule.getHomeVodNameR(name);
|
||||
String id = vodNodes.get(i).selOne(rule.getHomeVodId()).asString().trim();
|
||||
id = rule.getHomeVodIdR(id);
|
||||
String pic = vodNodes.get(i).selOne(rule.getHomeVodImg()).asString().trim();
|
||||
pic = rule.getHomeVodImgR(pic);
|
||||
pic = Util.fixUrl(webUrl, pic);
|
||||
String mark = "";
|
||||
if (!rule.getHomeVodMark().isEmpty()) {
|
||||
try {
|
||||
mark = vodNodes.get(i).selOne(rule.getHomeVodMark()).asString().trim();
|
||||
mark = rule.getHomeVodMarkR(mark);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
list.add(new Vod(id, name, pic, mark));
|
||||
}
|
||||
}
|
||||
return Result.string(classes, list, rule.getFilter());
|
||||
}
|
||||
|
||||
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
return rule.getCateUrl().replace("{cateId}", tid).replace("{catePg}", pg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
fetchRule();
|
||||
List<Vod> list = new ArrayList<>();
|
||||
String webUrl = categoryUrl(tid, pg, filter, extend);
|
||||
JXDocument doc = JXDocument.create(fetch(webUrl));
|
||||
List<JXNode> vodNodes = doc.selN(rule.getCateVodNode());
|
||||
for (int i = 0; i < vodNodes.size(); i++) {
|
||||
String name = vodNodes.get(i).selOne(rule.getCateVodName()).asString().trim();
|
||||
name = rule.getCateVodNameR(name);
|
||||
String id = vodNodes.get(i).selOne(rule.getCateVodId()).asString().trim();
|
||||
id = rule.getCateVodIdR(id);
|
||||
String pic = vodNodes.get(i).selOne(rule.getCateVodImg()).asString().trim();
|
||||
pic = rule.getCateVodImgR(pic);
|
||||
pic = Util.fixUrl(webUrl, pic);
|
||||
String mark = "";
|
||||
if (!rule.getCateVodMark().isEmpty()) {
|
||||
try {
|
||||
mark = vodNodes.get(i).selOne(rule.getCateVodMark()).asString().trim();
|
||||
mark = rule.getCateVodMarkR(mark);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
list.add(new Vod(id, name, pic, mark));
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
fetchRule();
|
||||
String webUrl = rule.getDetailUrl().replace("{vid}", ids.get(0));
|
||||
String webContent = fetch(webUrl);
|
||||
JXDocument doc = JXDocument.create(webContent);
|
||||
JXNode vodNode = doc.selNOne(rule.getDetailNode());
|
||||
String cover = "", title = "", desc = "", category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
title = vodNode.selOne(rule.getDetailName()).asString().trim();
|
||||
title = rule.getDetailNameR(title);
|
||||
cover = vodNode.selOne(rule.getDetailImg()).asString().trim();
|
||||
cover = rule.getDetailImgR(cover);
|
||||
cover = Util.fixUrl(webUrl, cover);
|
||||
if (!rule.getDetailCate().isEmpty()) {
|
||||
try {
|
||||
category = vodNode.selOne(rule.getDetailCate()).asString().trim();
|
||||
category = rule.getDetailCateR(category);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (!rule.getDetailYear().isEmpty()) {
|
||||
try {
|
||||
year = vodNode.selOne(rule.getDetailYear()).asString().trim();
|
||||
year = rule.getDetailYearR(year);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (!rule.getDetailArea().isEmpty()) {
|
||||
try {
|
||||
area = vodNode.selOne(rule.getDetailArea()).asString().trim();
|
||||
area = rule.getDetailAreaR(area);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (!rule.getDetailMark().isEmpty()) {
|
||||
try {
|
||||
remark = vodNode.selOne(rule.getDetailMark()).asString().trim();
|
||||
remark = rule.getDetailMarkR(remark);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (!rule.getDetailActor().isEmpty()) {
|
||||
try {
|
||||
actor = vodNode.selOne(rule.getDetailActor()).asString().trim();
|
||||
actor = rule.getDetailActorR(actor);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (!rule.getDetailDirector().isEmpty()) {
|
||||
try {
|
||||
director = vodNode.selOne(rule.getDetailDirector()).asString().trim();
|
||||
director = rule.getDetailDirectorR(director);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (!rule.getDetailDesc().isEmpty()) {
|
||||
try {
|
||||
desc = vodNode.selOne(rule.getDetailDesc()).asString().trim();
|
||||
desc = rule.getDetailDescR(desc);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
Vod vod = new Vod();
|
||||
vod.setVodId(ids.get(0));
|
||||
vod.setVodName(title);
|
||||
vod.setVodPic(cover);
|
||||
vod.setTypeName(category);
|
||||
vod.setVodYear(year);
|
||||
vod.setVodArea(area);
|
||||
vod.setVodRemarks(remark);
|
||||
vod.setVodActor(actor);
|
||||
vod.setVodDirector(director);
|
||||
vod.setVodContent(desc);
|
||||
|
||||
ArrayList<String> playFrom = new ArrayList<>();
|
||||
List<JXNode> fromNodes = doc.selN(rule.getDetailFromNode());
|
||||
for (int i = 0; i < fromNodes.size(); i++) {
|
||||
String name = fromNodes.get(i).selOne(rule.getDetailFromName()).asString().trim();
|
||||
name = rule.getDetailFromNameR(name);
|
||||
playFrom.add(name);
|
||||
}
|
||||
|
||||
ArrayList<String> playList = new ArrayList<>();
|
||||
List<JXNode> urlListNodes = doc.selN(rule.getDetailUrlNode());
|
||||
for (int i = 0; i < urlListNodes.size(); i++) {
|
||||
List<JXNode> urlNodes = urlListNodes.get(i).sel(rule.getDetailUrlSubNode());
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
for (int j = 0; j < urlNodes.size(); j++) {
|
||||
String name = urlNodes.get(j).selOne(rule.getDetailUrlName()).asString().trim();
|
||||
name = rule.getDetailUrlNameR(name);
|
||||
String id = urlNodes.get(j).selOne(rule.getDetailUrlId()).asString().trim();
|
||||
id = rule.getDetailUrlIdR(id);
|
||||
vodItems.add(name + "$" + id);
|
||||
}
|
||||
// 排除播放列表為空的播放源
|
||||
if (vodItems.size() == 0 && playFrom.size() > i) {
|
||||
playFrom.set(i, "");
|
||||
}
|
||||
playList.add(TextUtils.join("#", vodItems));
|
||||
}
|
||||
// 排除播放列表為空的播放源
|
||||
for (int i = playFrom.size() - 1; i >= 0; i--) {
|
||||
if (playFrom.get(i).isEmpty()) playFrom.remove(i);
|
||||
}
|
||||
for (int i = playList.size() - 1; i >= 0; i--) {
|
||||
if (playList.get(i).isEmpty()) playList.remove(i);
|
||||
}
|
||||
for (int i = playList.size() - 1; i >= 0; i--) {
|
||||
if (i >= playFrom.size()) playList.remove(i);
|
||||
}
|
||||
vod.setVodPlayFrom(TextUtils.join("$$$", playFrom));
|
||||
vod.setVodPlayUrl(TextUtils.join("$$$", playList));
|
||||
return Result.string(vod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
fetchRule();
|
||||
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
|
||||
SpiderDebug.log(webUrl);
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
if (rule.getPlayUa().length() > 0) headers.put("User-Agent", rule.getPlayUa());
|
||||
if (rule.getPlayReferer().length() > 0) headers.put("Referer", rule.getPlayReferer());
|
||||
return Result.get().parse().url(webUrl).header(headers).string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) throws Exception {
|
||||
fetchRule();
|
||||
if (rule.getSearchUrl().isEmpty()) return "";
|
||||
String webUrl = rule.getSearchUrl().replace("{wd}", URLEncoder.encode(key));
|
||||
String webContent = fetch(webUrl);
|
||||
List<Vod> list = new ArrayList<>();
|
||||
if (rule.getSearchVodNode().startsWith("json:")) {
|
||||
String[] node = rule.getSearchVodNode().substring(5).split(">");
|
||||
JSONObject data = new JSONObject(webContent);
|
||||
for (int i = 0; i < node.length; i++) {
|
||||
if (i == node.length - 1) {
|
||||
JSONArray vodArray = data.getJSONArray(node[i]);
|
||||
for (int j = 0; j < vodArray.length(); j++) {
|
||||
JSONObject vod = vodArray.getJSONObject(j);
|
||||
String name = vod.optString(rule.getSearchVodName()).trim();
|
||||
name = rule.getSearchVodNameR(name);
|
||||
String id = vod.optString(rule.getSearchVodId()).trim();
|
||||
id = rule.getSearchVodIdR(id);
|
||||
String pic = vod.optString(rule.getSearchVodImg()).trim();
|
||||
pic = rule.getSearchVodImgR(pic);
|
||||
pic = Util.fixUrl(webUrl, pic);
|
||||
String mark = vod.optString(rule.getSearchVodMark()).trim();
|
||||
mark = rule.getSearchVodMarkR(mark);
|
||||
list.add(new Vod(id, name, pic, mark));
|
||||
}
|
||||
} else {
|
||||
data = data.getJSONObject(node[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JXDocument doc = JXDocument.create(webContent);
|
||||
List<JXNode> vodNodes = doc.selN(rule.getSearchVodNode());
|
||||
for (int i = 0; i < vodNodes.size(); i++) {
|
||||
String name = vodNodes.get(i).selOne(rule.getSearchVodName()).asString().trim();
|
||||
name = rule.getSearchVodNameR(name);
|
||||
String id = vodNodes.get(i).selOne(rule.getSearchVodId()).asString().trim();
|
||||
id = rule.getSearchVodIdR(id);
|
||||
String pic = vodNodes.get(i).selOne(rule.getSearchVodImg()).asString().trim();
|
||||
pic = rule.getSearchVodImgR(pic);
|
||||
pic = Util.fixUrl(webUrl, pic);
|
||||
String mark = "";
|
||||
if (!rule.getCateVodMark().isEmpty()) {
|
||||
try {
|
||||
mark = vodNodes.get(i).selOne(rule.getSearchVodMark()).asString().trim();
|
||||
mark = rule.getSearchVodMarkR(mark);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
list.add(new Vod(id, name, pic, mark));
|
||||
}
|
||||
}
|
||||
return Result.string(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean manualVideoCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideoFormat(String url) {
|
||||
return Util.isVideoFormat(url);
|
||||
}
|
||||
|
||||
protected String ext = null;
|
||||
protected Rule rule = null;
|
||||
|
||||
protected void fetchRule() {
|
||||
if (rule == null) {
|
||||
if (ext != null) {
|
||||
if (ext.startsWith("http")) {
|
||||
String json = OkHttp.string(ext, null);
|
||||
rule = Rule.fromJson(json);
|
||||
loadRuleExt(json);
|
||||
} else {
|
||||
rule = Rule.fromJson(ext);
|
||||
loadRuleExt(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadRuleExt(String json) {
|
||||
}
|
||||
|
||||
protected String fetch(String webUrl) {
|
||||
SpiderDebug.log(webUrl);
|
||||
return OkHttp.string(webUrl, getHeaders());
|
||||
}
|
||||
}
|
||||
34
app/src/main/java/com/github/catvod/spider/XPathFilter.java
Normal file
34
app/src/main/java/com/github/catvod/spider/XPathFilter.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class XPathFilter extends XPath {
|
||||
|
||||
@Override
|
||||
protected void loadRuleExt(String json) {
|
||||
super.loadRuleExt(json);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
String cateUrl = rule.getCateUrl();
|
||||
if (filter && extend != null && extend.size() > 0) {
|
||||
for (String key : extend.keySet()) {
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
cateUrl = cateUrl.replace("{cateId}", tid).replace("{catePg}", pg);
|
||||
Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(cateUrl);
|
||||
while (m.find()) {
|
||||
String n = m.group(0).replace("{", "").replace("}", "");
|
||||
cateUrl = cateUrl.replace(m.group(0), "").replace("/" + n + "/", "");
|
||||
}
|
||||
return cateUrl;
|
||||
}
|
||||
}
|
||||
196
app/src/main/java/com/github/catvod/spider/XPathMac.java
Normal file
196
app/src/main/java/com/github/catvod/spider/XPathMac.java
Normal file
@@ -0,0 +1,196 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.Util;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class XPathMac extends XPath {
|
||||
|
||||
// 嘗試分析直連
|
||||
private boolean decodePlayUrl;
|
||||
// 嘗試匹配官源標識以調用應用配置中的解析列表
|
||||
private boolean decodeVipFlag;
|
||||
// 播放器配置js
|
||||
private String playerConfigJs = "";
|
||||
// 播放器配置js取值正則
|
||||
private String playerConfigJsRegex = "[\\W|\\S|.]*?MacPlayerConfig.player_list[\\W|\\S|.]*?=([\\W|\\S|.]*?),MacPlayerConfig.downer_list";
|
||||
// 站點里播放源對應的真實官源
|
||||
private final HashMap<String, String> show2VipFlag = new HashMap<>();
|
||||
|
||||
/**
|
||||
* mac cms 直連和官源調用應用內播放列表支持
|
||||
*
|
||||
* @param context
|
||||
* @param extend
|
||||
*/
|
||||
public void init(Context context, String extend) {
|
||||
super.init(context, extend);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadRuleExt(String json) {
|
||||
try {
|
||||
JSONObject jsonObj = new JSONObject(json);
|
||||
decodePlayUrl = jsonObj.optBoolean("dcPlayUrl", false);
|
||||
decodeVipFlag = jsonObj.optBoolean("dcVipFlag", false);
|
||||
JSONObject dcShow2Vip = jsonObj.optJSONObject("dcShow2Vip");
|
||||
if (dcShow2Vip != null) {
|
||||
Iterator<String> keys = dcShow2Vip.keys();
|
||||
while (keys.hasNext()) {
|
||||
String name = keys.next();
|
||||
show2VipFlag.put(name.trim(), dcShow2Vip.getString(name).trim());
|
||||
}
|
||||
}
|
||||
playerConfigJs = jsonObj.optString("pCfgJs").trim();
|
||||
playerConfigJsRegex = jsonObj.optString("pCfgJsR", playerConfigJsRegex).trim();
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
String result = super.homeContent(filter);
|
||||
if (result.length() > 0 && playerConfigJs.length() > 0) { // 嘗試通過playerConfigJs獲取展示和flag匹配關系
|
||||
String webContent = fetch(playerConfigJs);
|
||||
Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(webContent);
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(matcher.group(1));
|
||||
Iterator<String> keys = jsonObject.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
JSONObject keyObj = jsonObject.optJSONObject(key);
|
||||
if (keyObj == null) continue;
|
||||
String show = keyObj.optString("show").trim();
|
||||
if (show.isEmpty()) continue;
|
||||
show2VipFlag.put(show, key);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
String result = super.detailContent(ids);
|
||||
if (decodeVipFlag && result.length() > 0) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(result);
|
||||
String[] playFrom = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$");
|
||||
if (playFrom.length > 0) {
|
||||
for (int i = 0; i < playFrom.length; i++) {
|
||||
if (show2VipFlag.containsKey(playFrom[i])) {
|
||||
playFrom[i] = show2VipFlag.get(playFrom[i]);
|
||||
}
|
||||
}
|
||||
jsonObject.optJSONArray("list").getJSONObject(0).put("vod_play_from", TextUtils.join("$$$", playFrom));
|
||||
result = jsonObject.toString();
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
SpiderDebug.log(th);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
fetchRule();
|
||||
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
|
||||
String videoUrl = null;
|
||||
// 嘗試分析直連
|
||||
if (decodePlayUrl) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(fetch(webUrl));
|
||||
Elements allScript = doc.select("script");
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) {
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
String videoUrlTmp = player.getString("url");
|
||||
if (player.has("encrypt")) {
|
||||
int encrypt = player.getInt("encrypt");
|
||||
if (encrypt == 1) {
|
||||
videoUrlTmp = URLDecoder.decode(videoUrlTmp);
|
||||
} else if (encrypt == 2) {
|
||||
videoUrlTmp = new String(Base64.decode(videoUrlTmp, Base64.DEFAULT));
|
||||
videoUrlTmp = URLDecoder.decode(videoUrlTmp);
|
||||
}
|
||||
}
|
||||
videoUrl = videoUrlTmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
if (videoUrl != null) {
|
||||
// 適配2.0.6的調用應用內解析列表的支持, 需要配合直連分析和匹配官源解析一起使用,參考cjt影視和極品直連
|
||||
if (decodeVipFlag && Util.isVip(videoUrl)) { // 使用jx:1
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 1);
|
||||
result.put("jx", "1");
|
||||
result.put("url", videoUrl);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
} else if (decodeVipFlag && vipFlags.contains(flag)) { // 是否使用應用內解析列表解析官源
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 1);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
// 如果是視頻直連 直接返回免解
|
||||
else if (isVideoFormat(videoUrl)) {
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", videoUrl);
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
if (rule.getPlayUa().length() > 0) headers.put("User-Agent", rule.getPlayUa());
|
||||
if (rule.getPlayReferer().length() > 0) headers.put("Referer", rule.getPlayReferer());
|
||||
result.put("header", new Gson().toJson(headers));
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 上述都失敗了就按默認模式走
|
||||
return super.playerContent(flag, id, vipFlags);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user