Merge branch 'main' of https://github.com/FongMi/CatVodSpider
This commit is contained in:
commit
0f2a055cc9
|
|
@ -19,9 +19,13 @@ import com.github.catvod.bean.Sub;
|
|||
import com.github.catvod.bean.Vod;
|
||||
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.Res;
|
||||
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;
|
||||
|
|
@ -31,9 +35,7 @@ import com.github.catvod.spider.Proxy;
|
|||
import com.github.catvod.utils.FileUtil;
|
||||
import com.github.catvod.utils.QRCode;
|
||||
import com.github.catvod.utils.Utils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
|
|
@ -58,10 +60,9 @@ public class AliYun {
|
|||
private String refreshToken;
|
||||
private String shareToken;
|
||||
private String shareId;
|
||||
private String driveId;
|
||||
private OAuth oauth;
|
||||
private User user;
|
||||
private Drive drive;
|
||||
private User user;
|
||||
|
||||
private static class Loader {
|
||||
static volatile AliYun INSTANCE = new AliYun();
|
||||
|
|
@ -85,8 +86,8 @@ public class AliYun {
|
|||
|
||||
private AliYun() {
|
||||
tempIds = new ArrayList<>();
|
||||
oauth = OAuth.objectFrom(FileUtil.read(getOAuthCache()));
|
||||
user = User.objectFrom(FileUtil.read(getUserCache()));
|
||||
oauth = OAuth.objectFrom(FileUtil.read(getOAuthCache()));
|
||||
drive = Drive.objectFrom(FileUtil.read(getDriveCache()));
|
||||
}
|
||||
|
||||
|
|
@ -103,9 +104,10 @@ public class AliYun {
|
|||
}
|
||||
|
||||
public void setShareId(String shareId) {
|
||||
if (!getOAuthCache().exists()) oauth.clean().save();
|
||||
if (!getUserCache().exists()) user.clean().save();
|
||||
if (!getOAuthCache().exists()) oauth.clean().save();
|
||||
if (!getDriveCache().exists()) drive.clean().save();
|
||||
if (shareId.equals(this.shareId)) return;
|
||||
this.shareId = shareId;
|
||||
refreshShareToken();
|
||||
}
|
||||
|
|
@ -131,21 +133,18 @@ public class AliYun {
|
|||
return headers;
|
||||
}
|
||||
|
||||
private boolean alist(String url, JSONObject body) {
|
||||
//https://api-cf.nn.ci/alist/ali_open/
|
||||
//https://api.xhofe.top/alist/ali_open/
|
||||
//https://sni_api_nn_ci.cooluc.com/alist/ali_open/
|
||||
private boolean alist(String url, JsonObject param) {
|
||||
String api = "https://aliapi.ewwe.gq/alist/ali_open/" + url;
|
||||
OkResult result = OkHttp.postJson(api, body.toString(), getHeader());
|
||||
OkResult result = OkHttp.postJson(api, param.toString(), getHeader());
|
||||
SpiderDebug.log(result.getCode() + "," + api + "," + result.getBody());
|
||||
if (isManyRequest(result.getBody())) return false;
|
||||
oauth = OAuth.objectFrom(result.getBody()).save();
|
||||
return true;
|
||||
}
|
||||
|
||||
private String post(String url, JSONObject body) {
|
||||
private String post(String url, JsonObject param) {
|
||||
url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url;
|
||||
OkResult result = OkHttp.postJson(url, body.toString(), getHeader());
|
||||
OkResult result = OkHttp.postJson(url, param.toString(), getHeader());
|
||||
SpiderDebug.log(result.getCode() + "," + url + "," + result.getBody());
|
||||
return result.getBody();
|
||||
}
|
||||
|
|
@ -180,31 +179,27 @@ public class AliYun {
|
|||
}
|
||||
|
||||
private void refreshShareToken() {
|
||||
try {
|
||||
SpiderDebug.log("refreshShareToken...");
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("share_id", shareId);
|
||||
body.put("share_pwd", "");
|
||||
String result = post("v2/share_link/get_share_token", body);
|
||||
shareToken = new JSONObject(result).getString("share_token");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utils.notify("來晚啦,該分享已失效。");
|
||||
}
|
||||
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);
|
||||
shareToken = Share.objectFrom(json).getShareToken();
|
||||
if (shareToken.isEmpty()) Utils.notify("來晚啦,該分享已失效。");
|
||||
}
|
||||
|
||||
private boolean refreshAccessToken() {
|
||||
try {
|
||||
SpiderDebug.log("refreshAccessToken...");
|
||||
JSONObject body = new JSONObject();
|
||||
JsonObject param = new JsonObject();
|
||||
String token = user.getRefreshToken();
|
||||
if (token.isEmpty()) token = refreshToken;
|
||||
if (token.startsWith("http")) token = OkHttp.string(token).trim();
|
||||
body.put("refresh_token", token);
|
||||
body.put("grant_type", "refresh_token");
|
||||
String result = post("https://auth.aliyundrive.com/v2/account/token", body);
|
||||
user = User.objectFrom(result).save();
|
||||
if (user.getAccessToken().isEmpty()) throw new Exception(result);
|
||||
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);
|
||||
user = User.objectFrom(json).save();
|
||||
if (user.getAccessToken().isEmpty()) throw new Exception(json);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
if (e instanceof TimeoutException) return onTimeout();
|
||||
|
|
@ -218,103 +213,77 @@ public class AliYun {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean getDriveId() {
|
||||
try {
|
||||
SpiderDebug.log("Obtain drive id...");
|
||||
String result = auth("https://user.aliyundrive.com/v2/user/get", "{}", false);
|
||||
drive = Drive.objectFrom(result).save();
|
||||
driveId = drive.getResourceDriveId().isEmpty() ? drive.getDriveId() : drive.getResourceDriveId();
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
drive.clean().save();
|
||||
return true;
|
||||
}
|
||||
private void getDriveId() {
|
||||
SpiderDebug.log("Get Drive Id...");
|
||||
String json = auth("https://user.aliyundrive.com/v2/user/get", "{}", true);
|
||||
drive = Drive.objectFrom(json).save();
|
||||
}
|
||||
|
||||
private boolean oauthRequest() {
|
||||
try {
|
||||
SpiderDebug.log("OAuth Request...");
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("authorize", 1);
|
||||
body.put("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 result = auth(url, body.toString(), true);
|
||||
return oauthRedirect(Code.objectFrom(result).getCode());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
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) {
|
||||
try {
|
||||
SpiderDebug.log("OAuth Redirect...");
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("code", code);
|
||||
body.put("grant_type", "authorization_code");
|
||||
return alist("code", body);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
oauth.clean().save();
|
||||
return false;
|
||||
}
|
||||
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() {
|
||||
try {
|
||||
if (oauth.getRefreshToken().isEmpty()) return oauthRequest();
|
||||
SpiderDebug.log("refreshOpenToken...");
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("grant_type", "refresh_token");
|
||||
body.put("refresh_token", oauth.getRefreshToken());
|
||||
return alist("token", body);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
oauth.clean().save();
|
||||
return false;
|
||||
}
|
||||
if (oauth.getRefreshToken().isEmpty()) return oauthRequest();
|
||||
SpiderDebug.log("refreshOpenToken...");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("grant_type", "refresh_token");
|
||||
param.addProperty("refresh_token", oauth.getRefreshToken());
|
||||
return alist("token", param);
|
||||
}
|
||||
|
||||
public Vod getVod(String url, String fileId) throws Exception {
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("share_id", shareId);
|
||||
String result = post("adrive/v3/share_link/get_share_by_anonymous", body);
|
||||
JSONObject object = new JSONObject(result);
|
||||
public Vod getVod(String url, String fileId) {
|
||||
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(new Item(getParentFileId(fileId, object)), files, subs);
|
||||
listFiles(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() + "$" + file.getFileId() + findSubs(file.getName(), subs));
|
||||
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(object.getString("avatar"));
|
||||
vod.setVodName(object.getString("share_name"));
|
||||
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(Item folder, List<Item> files, List<Item> subs) throws Exception {
|
||||
private void listFiles(Item folder, List<Item> files, List<Item> subs) {
|
||||
listFiles(folder, files, subs, "");
|
||||
}
|
||||
|
||||
private void listFiles(Item parent, List<Item> files, List<Item> subs, String marker) throws Exception {
|
||||
JSONObject body = new JSONObject();
|
||||
private void listFiles(Item parent, List<Item> files, List<Item> subs, String marker) {
|
||||
List<Item> folders = new ArrayList<>();
|
||||
body.put("limit", 200);
|
||||
body.put("share_id", shareId);
|
||||
body.put("parent_file_id", parent.getFileId());
|
||||
body.put("order_by", "name");
|
||||
body.put("order_direction", "ASC");
|
||||
if (marker.length() > 0) body.put("marker", marker);
|
||||
Item item = Item.objectFrom(auth("adrive/v3/file/list", body.toString(), true));
|
||||
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);
|
||||
|
|
@ -332,14 +301,11 @@ public class AliYun {
|
|||
}
|
||||
}
|
||||
|
||||
private String getParentFileId(String fileId, JSONObject shareInfo) throws Exception {
|
||||
JSONArray array = shareInfo.getJSONArray("file_infos");
|
||||
private String getParentFileId(String fileId, Share share) {
|
||||
if (!TextUtils.isEmpty(fileId)) return fileId;
|
||||
if (array.length() == 0) return "";
|
||||
JSONObject fileInfo = array.getJSONObject(0);
|
||||
if (fileInfo.getString("type").equals("folder")) return fileInfo.getString("file_id");
|
||||
if (fileInfo.getString("type").equals("file") && fileInfo.getString("category").equals("video")) return "root";
|
||||
return "";
|
||||
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) {
|
||||
|
|
@ -374,13 +340,12 @@ public class AliYun {
|
|||
public String getDownloadUrl(String fileId) {
|
||||
try {
|
||||
SpiderDebug.log("getDownloadUrl..." + fileId);
|
||||
if (getDriveId()) throw new Exception("unable obtain drive id");
|
||||
tempIds.add(0, copy(fileId));
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("file_id", tempIds.get(0));
|
||||
body.put("drive_id", driveId);
|
||||
String json = oauth("openFile/getDownloadUrl", body.toString(), true);
|
||||
return new JSONObject(json).getString("url");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", tempIds.get(0));
|
||||
param.addProperty("drive_id", drive.getDriveId());
|
||||
String json = oauth("openFile/getDownloadUrl", param.toString(), true);
|
||||
return Download.objectFrom(json).getUrl();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
|
|
@ -389,21 +354,20 @@ public class AliYun {
|
|||
}
|
||||
}
|
||||
|
||||
public JSONObject getVideoPreviewPlayInfo(String fileId) {
|
||||
public Preview.Info getVideoPreviewPlayInfo(String fileId) {
|
||||
try {
|
||||
SpiderDebug.log("getVideoPreviewPlayInfo..." + fileId);
|
||||
if (getDriveId()) throw new Exception("unable obtain drive id");
|
||||
tempIds.add(0, copy(fileId));
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("file_id", tempIds.get(0));
|
||||
body.put("drive_id", driveId);
|
||||
body.put("category", "live_transcoding");
|
||||
body.put("url_expire_sec", "14400");
|
||||
String json = oauth("openFile/getVideoPreviewPlayInfo", body.toString(), true);
|
||||
return new JSONObject(json).getJSONObject("video_preview_play_info");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", tempIds.get(0));
|
||||
param.addProperty("drive_id", drive.getDriveId());
|
||||
param.addProperty("category", "live_transcoding");
|
||||
param.addProperty("url_expire_sec", "14400");
|
||||
String json = oauth("openFile/getVideoPreviewPlayInfo", param.toString(), true);
|
||||
return Preview.objectFrom(json).getVideoPreviewPlayInfo();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new JSONObject();
|
||||
return new Preview.Info();
|
||||
} finally {
|
||||
Init.execute(this::deleteAll);
|
||||
}
|
||||
|
|
@ -415,51 +379,36 @@ public class AliYun {
|
|||
}
|
||||
|
||||
private String getPreviewContent(String[] ids) {
|
||||
try {
|
||||
JSONObject playInfo = getVideoPreviewPlayInfo(ids[0]);
|
||||
List<String> url = getPreviewUrl(playInfo);
|
||||
List<Sub> subs = getSubs(ids);
|
||||
subs.addAll(getSubs(playInfo));
|
||||
return Result.get().url(url).m3u8().subs(subs).header(getHeader()).string();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.get().url("").string();
|
||||
}
|
||||
Preview.Info info = getVideoPreviewPlayInfo(ids[0]);
|
||||
List<String> url = getPreviewUrl(info);
|
||||
List<Sub> subs = getSubs(ids);
|
||||
subs.addAll(getSubs(info));
|
||||
return Result.get().url(url).m3u8().subs(subs).header(getHeader()).string();
|
||||
}
|
||||
|
||||
private List<String> getPreviewUrl(JSONObject playInfo) throws Exception {
|
||||
if (!playInfo.has("live_transcoding_task_list")) return Collections.emptyList();
|
||||
JSONArray taskList = playInfo.getJSONArray("live_transcoding_task_list");
|
||||
private List<String> getPreviewUrl(Preview.Info info) {
|
||||
List<Preview.LiveTranscodingTask> tasks = info.getLiveTranscodingTaskList();
|
||||
List<String> url = new ArrayList<>();
|
||||
for (int i = taskList.length() - 1; i >= 0; i--) {
|
||||
JSONObject task = taskList.getJSONObject(i);
|
||||
if (!task.optString("status").equals("finished")) continue;
|
||||
url.add(task.optString("template_id"));
|
||||
url.add(task.optString("url"));
|
||||
for (int i = tasks.size() - 1; i >= 0; i--) {
|
||||
url.add(tasks.get(i).getTemplateId());
|
||||
url.add(tasks.get(i).getUrl());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private List<Sub> getSubs(JSONObject playInfo) throws Exception {
|
||||
if (!playInfo.has("live_transcoding_subtitle_task_list")) return Collections.emptyList();
|
||||
JSONArray taskList = playInfo.getJSONArray("live_transcoding_subtitle_task_list");
|
||||
private List<Sub> getSubs(Preview.Info info) {
|
||||
List<Sub> subs = new ArrayList<>();
|
||||
for (int i = 0; i < taskList.length(); ++i) {
|
||||
JSONObject task = taskList.getJSONObject(i);
|
||||
String lang = task.getString("language");
|
||||
String url = task.getString("url");
|
||||
subs.add(Sub.create().url(url).name(lang).lang(lang).ext("vtt"));
|
||||
}
|
||||
for (Preview.LiveTranscodingTask task : info.getLiveTranscodingSubtitleTaskList()) subs.add(task.getSub());
|
||||
return subs;
|
||||
}
|
||||
|
||||
private String copy(String fileId) throws Exception {
|
||||
SpiderDebug.log("Copy..." + fileId);
|
||||
private String copy(String fileId) {
|
||||
if (drive.getDriveId().isEmpty()) getDriveId();
|
||||
SpiderDebug.log("Copy..." + fileId + "," + shareId + "," + drive.getDriveId());
|
||||
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, driveId);
|
||||
String result = auth("adrive/v2/batch", json, true);
|
||||
if (result.contains("ForbiddenNoPermission.File")) return copy(fileId);
|
||||
return new JSONObject(result).getJSONArray("responses").getJSONObject(0).getJSONObject("body").getString("file_id");
|
||||
json = String.format(json, fileId, shareId, drive.getDriveId());
|
||||
Res res = Res.objectFrom(auth("adrive/v2/batch", json, true));
|
||||
return res.getResponse().getBody().getFileId();
|
||||
}
|
||||
|
||||
private void deleteAll() {
|
||||
|
|
@ -471,15 +420,11 @@ public class AliYun {
|
|||
}
|
||||
|
||||
private boolean delete(String fileId) {
|
||||
try {
|
||||
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, driveId, fileId, fileId);
|
||||
String result = auth("adrive/v2/batch", json, true);
|
||||
return result.length() == 211;
|
||||
} catch (Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
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, drive.getDriveId(), fileId, fileId);
|
||||
Res res = Res.objectFrom(auth("adrive/v2/batch", json, true));
|
||||
return res.getResponse().getStatus() == 404;
|
||||
}
|
||||
|
||||
public Object[] proxySub(Map<String, String> params) throws Exception {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.github.catvod.bean;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
|
|
@ -54,6 +55,10 @@ public class Result {
|
|||
return Result.get().classes(classes).vod(list).filters(filters).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();
|
||||
}
|
||||
|
|
@ -105,6 +110,13 @@ public class Result {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ public class Vod {
|
|||
this.vodPlayUrl = vodPlayUrl;
|
||||
}
|
||||
|
||||
public String getVodPlayUrl() {
|
||||
return vodPlayUrl;
|
||||
}
|
||||
|
||||
public void setVodTag(String vodTag) {
|
||||
this.vodTag = vodTag;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,43 +10,29 @@ import com.google.gson.annotations.SerializedName;
|
|||
public class Drive {
|
||||
|
||||
@SerializedName("default_drive_id")
|
||||
private String driveId;
|
||||
@SerializedName("user_id")
|
||||
private String userId;
|
||||
@SerializedName("backup_drive_id")
|
||||
private String backupDriveId;
|
||||
private String defaultDriveId;
|
||||
@SerializedName("resource_drive_id")
|
||||
private String resourceDriveId;
|
||||
@SerializedName("sbox_drive_id")
|
||||
private String sboxDriveId;
|
||||
|
||||
public static Drive objectFrom(String str) {
|
||||
Drive item = new Gson().fromJson(str, Drive.class);
|
||||
return item == null ? new Drive() : item;
|
||||
}
|
||||
|
||||
public String getDriveId() {
|
||||
return TextUtils.isEmpty(driveId) ? "" : driveId;
|
||||
private String getDefaultDriveId() {
|
||||
return TextUtils.isEmpty(defaultDriveId) ? "" : defaultDriveId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return TextUtils.isEmpty(userId) ? "" : userId;
|
||||
}
|
||||
|
||||
public String getBackupDriveId() {
|
||||
return TextUtils.isEmpty(backupDriveId) ? "" : backupDriveId;
|
||||
}
|
||||
|
||||
public String getResourceDriveId() {
|
||||
private String getResourceDriveId() {
|
||||
return TextUtils.isEmpty(resourceDriveId) ? "" : resourceDriveId;
|
||||
}
|
||||
|
||||
public String getSboxDriveId() {
|
||||
return TextUtils.isEmpty(sboxDriveId) ? "" : sboxDriveId;
|
||||
public String getDriveId() {
|
||||
return getResourceDriveId().isEmpty() ? getDefaultDriveId() : getResourceDriveId();
|
||||
}
|
||||
|
||||
public Drive clean() {
|
||||
this.driveId = "";
|
||||
this.defaultDriveId = "";
|
||||
this.resourceDriveId = "";
|
||||
return this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.github.catvod.bean.ali;
|
|||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.utils.ChineseComparator;
|
||||
import com.github.catvod.utils.Utils;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
|
@ -88,6 +89,6 @@ public class Item implements Comparable<Item> {
|
|||
|
||||
@Override
|
||||
public int compareTo(Item item) {
|
||||
return this.getName().compareTo(item.getName());
|
||||
return ChineseComparator.compare(this.getDisplayName(), item.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 Res {
|
||||
|
||||
@SerializedName("responses")
|
||||
private List<Res> responses;
|
||||
@SerializedName("body")
|
||||
private Body body;
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
@SerializedName("status")
|
||||
private int status;
|
||||
|
||||
public static Res objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Res.class);
|
||||
}
|
||||
|
||||
public List<Res> getResponses() {
|
||||
return responses == null ? Collections.emptyList() : responses;
|
||||
}
|
||||
|
||||
public Res getResponse() {
|
||||
return getResponses().isEmpty() ? new Res() : 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
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_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;
|
||||
|
||||
public static Share objectFrom(String str) {
|
||||
return new Gson().fromJson(str, Share.class);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
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;
|
||||
|
|
@ -25,24 +30,59 @@ public class Ali extends Spider {
|
|||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) throws Exception {
|
||||
String url = ids.get(0).trim();
|
||||
Matcher matcher = pattern.matcher(url);
|
||||
if (!matcher.find()) return "";
|
||||
String shareId = matcher.group(1);
|
||||
String fileId = matcher.groupCount() == 3 ? matcher.group(3) : "";
|
||||
AliYun.get().setShareId(shareId);
|
||||
return Result.string(AliYun.get().getVod(url, fileId));
|
||||
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.equals("原畫"));
|
||||
AliYun.get().setShareId(id.split("@")[0]);
|
||||
return AliYun.get().playerContent(id.split("@")[1].split("\\+"), flag.split("#")[0].equals("原畫"));
|
||||
}
|
||||
|
||||
private Vod parseVod(Matcher matcher, String id) {
|
||||
String shareId = matcher.group(1);
|
||||
String fileId = matcher.groupCount() == 3 ? matcher.group(3) : "";
|
||||
AliYun.get().setShareId(shareId);
|
||||
return AliYun.get().getVod(id, 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));
|
||||
}
|
||||
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 (type.equals("sub")) return AliYun.get().proxySub(params);
|
||||
if (type.equals("token")) return AliYun.get().getToken();
|
||||
if ("sub".equals(type)) return AliYun.get().proxySub(params);
|
||||
if ("token".equals(type)) return AliYun.get().getToken();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,18 +2,21 @@ 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.Utils;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
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;
|
||||
|
|
@ -25,9 +28,11 @@ import java.util.regex.Pattern;
|
|||
*/
|
||||
public class Wogg extends Ali {
|
||||
|
||||
private final String siteURL = "http://tvfan.xxooo.cf";
|
||||
private final String siteUrl = "http://tvfan.xxooo.cf";
|
||||
private final Pattern regexCategory = Pattern.compile("/vodtype/(\\w+).html");
|
||||
private final Pattern regexPageTotal = Pattern.compile("\\$\\(\"\\.mac_total\"\\)\\.text\\('(\\d+)'\\);");
|
||||
|
||||
private final Pattern regexAli = Pattern.compile("(https://www.aliyundrive.com/s/[^\"]+)");
|
||||
private JsonObject extend;
|
||||
|
||||
private Map<String, String> getHeader() {
|
||||
Map<String, String> header = new HashMap<>();
|
||||
|
|
@ -37,14 +42,87 @@ public class Wogg extends Ali {
|
|||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
super.init(context, extend);
|
||||
this.extend = JsonParser.parseString(extend).getAsJsonObject();
|
||||
super.init(context, this.extend.get("token").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
List<Class> classes = new ArrayList<>();
|
||||
String url = extend.get("filter").getAsString();
|
||||
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), filter ? JsonParser.parseString(OkHttp.string(url)) : null);
|
||||
}
|
||||
|
||||
@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 {
|
||||
Matcher matcher = regexAli.matcher(OkHttp.string(siteURL + ids.get(0), getHeader()));
|
||||
if (matcher.find()) return super.detailContent(Arrays.asList(matcher.group(1)));
|
||||
return "";
|
||||
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");
|
||||
item.setVodPlayFrom(super.detailContentVodPlayFrom(shareLinks));
|
||||
item.setVodPlayUrl(super.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
|
||||
|
|
@ -58,7 +136,7 @@ public class Wogg extends Ali {
|
|||
}
|
||||
|
||||
private String searchContent(String key, String pg) {
|
||||
String searchURL = siteURL + String.format("/index.php/vodsearch/%s----------%s---.html", URLEncoder.encode(key), 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<>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
package com.github.catvod.utils;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 按照 Windows 排序风格,对给定的数字、字母、汉字字符串进行排序
|
||||
*
|
||||
* @author Oiltea
|
||||
*/
|
||||
public class ChineseComparator {
|
||||
|
||||
private static final Integer TYPE_NUMBER = 0;
|
||||
private static final Integer TYPE_CHARACTER = 1;
|
||||
|
||||
public static int compare(String o1, String o2) {
|
||||
// 根据字符数组生成带分类的字符列表
|
||||
// List<Object>的第一位为该字符的类型(TYPE_NUMBER, TYPE_CHARACTER)
|
||||
// List<Object>的第二位为该字符的内容(一位数字, 一位非数字, 多位数字)
|
||||
List<List<Object>> o1CharList = getCharList(o1);
|
||||
List<List<Object>> o2CharList = getCharList(o2);
|
||||
|
||||
// 统一CharList的长度
|
||||
int max = Math.max(o1CharList.size(), o2CharList.size());
|
||||
while (o1CharList.size() < max) {
|
||||
o1CharList.add(new ArrayList<>());
|
||||
}
|
||||
while (o2CharList.size() < max) {
|
||||
o2CharList.add(new ArrayList<>());
|
||||
}
|
||||
|
||||
// 开始比较
|
||||
int compare = 0;
|
||||
for (int i = 0; i < max; i++) {
|
||||
List<Object> o1list = o1CharList.get(i);
|
||||
List<Object> o2list = o2CharList.get(i);
|
||||
|
||||
// CharList短的,排在前面
|
||||
if (o1list.size() == 0) {
|
||||
compare = -1;
|
||||
break;
|
||||
}
|
||||
if (o2list.size() == 0) {
|
||||
compare = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// 先比较类型
|
||||
Integer o1Type = (Integer) o1list.get(0);
|
||||
Integer o2Type = (Integer) o2list.get(0);
|
||||
int typeCompare = Integer.compare(o1Type, o2Type);
|
||||
if (typeCompare != 0) {
|
||||
// 类型不同,则数字在前,非数字在后
|
||||
compare = typeCompare;
|
||||
break;
|
||||
} else {
|
||||
// 类型相同,则比较内容
|
||||
if (TYPE_NUMBER.equals(o1Type)) {
|
||||
// 比较数字
|
||||
int o1Content = Integer.parseInt(o1list.get(1).toString());
|
||||
int o2Content = Integer.parseInt(o2list.get(1).toString());
|
||||
compare = Integer.compare(o1Content, o2Content);
|
||||
} else if (TYPE_CHARACTER.equals(o1Type)) {
|
||||
// 比较非数字
|
||||
String o1Content = (String) o1list.get(1);
|
||||
String o2Content = (String) o2list.get(1);
|
||||
compare = Collator.getInstance(Locale.CHINESE).compare(o1Content, o2Content);
|
||||
}
|
||||
// 如果不相等,则退出比较
|
||||
if (compare != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字符数组生成带分类的字符列表
|
||||
*
|
||||
* @param text 字符串
|
||||
* @return 带分类的字符列表,List<Object>的第一位为该字符的类型(TYPE_NUMBER, TYPE_CHARACTER),第二位为该字符的内容
|
||||
*/
|
||||
private static List<List<Object>> getCharList(String text) {
|
||||
char[] chars = text.toCharArray();
|
||||
List<List<Object>> charList = new ArrayList<>();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
// 是否为数字
|
||||
char c = chars[i];
|
||||
if ((int) c >= '0' && (int) c <= '9') {
|
||||
StringBuilder str = new StringBuilder();
|
||||
// 下一位是否为数字,如果为数字则组成多位数
|
||||
do {
|
||||
str.append(c);
|
||||
if (i + 1 < chars.length) {
|
||||
c = chars[++i];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while ((int) c >= '0' && (int) c <= '9');
|
||||
if (!(i + 1 == chars.length) || !((int) c >= '0' && (int) c <= '9')) {
|
||||
i--;
|
||||
}
|
||||
list.add(TYPE_NUMBER);
|
||||
list.add(str.toString());
|
||||
} else {
|
||||
list.add(TYPE_CHARACTER);
|
||||
list.add(String.valueOf(c));
|
||||
}
|
||||
charList.add(list);
|
||||
}
|
||||
return charList;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
dede7a67d11523b79d649c152910fd6a
|
||||
a2204506315000174d11fe509f88259c
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://fongmi.cachefly.net/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;dede7a67d11523b79d649c152910fd6a",
|
||||
"spider": "https://fongmi.cachefly.net/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;a2204506315000174d11fe509f88259c",
|
||||
"wallpaper": "https://gao.chuqiuyu.tk",
|
||||
"sites": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://fongmi.cachefly.net/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;dede7a67d11523b79d649c152910fd6a",
|
||||
"spider": "https://fongmi.cachefly.net/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;a2204506315000174d11fe509f88259c",
|
||||
"wallpaper": "http://饭太硬.top/深色壁纸/api.php",
|
||||
"sites": [
|
||||
{
|
||||
|
|
@ -65,6 +65,18 @@
|
|||
"searchable": 1,
|
||||
"changeable": 1
|
||||
},
|
||||
{
|
||||
"key": "玩偶",
|
||||
"name": "玩偶",
|
||||
"type": 3,
|
||||
"api": "csp_Wogg",
|
||||
"searchable": 1,
|
||||
"changeable": 0,
|
||||
"ext": {
|
||||
"token": "影視天下第一",
|
||||
"filter": "https://fongmi.cachefly.net/FongMi/CatVodSpider/main/json/wogg.json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "星星",
|
||||
"name": "星星",
|
||||
|
|
@ -146,14 +158,6 @@
|
|||
"searchable": 1,
|
||||
"changeable": 1
|
||||
},
|
||||
{
|
||||
"key": "玩偶",
|
||||
"name": "玩偶",
|
||||
"type": 3,
|
||||
"api": "csp_Wogg",
|
||||
"searchable": 1,
|
||||
"changeable": 0
|
||||
},
|
||||
{
|
||||
"key": "七夜",
|
||||
"name": "七夜",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue