夸克盘扫码

This commit is contained in:
lushunming 2024-09-02 14:34:21 +08:00
parent 0a93475e54
commit cc001735e0
13 changed files with 1002 additions and 118 deletions

View File

@ -12,22 +12,19 @@ import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.bean.quark.Cache;
import com.github.catvod.bean.quark.Item;
import com.github.catvod.bean.quark.ShareData;
import com.github.catvod.bean.quark.User;
import com.github.catvod.bean.quark.*;
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.utils.*;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@ -49,6 +46,7 @@ public class QuarkApi {
private final Cache cache;
private ScheduledExecutorService service;
private AlertDialog dialog;
private String serviceTicket;
private static class Loader {
static volatile QuarkApi INSTANCE = new QuarkApi();
@ -62,6 +60,23 @@ public class QuarkApi {
this.cookie = token;
}
private Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch");
headers.put("Referer", "https://pan.quark.cn/");
headers.put("Content-Type", "application/json");
headers.put("Cookie", this.cookie);
headers.put("Host", "drive-pc.quark.cn");
return headers;
}
private Map<String, String> getWebHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch");
headers.put("Referer", "https://pan.quark.cn/");
headers.put("Cookie", this.cookie);
return headers;
}
public void initQuark(String cookie) throws Exception {
this.ckey = Util.MD5(cookie);
@ -83,7 +98,7 @@ public class QuarkApi {
getShareToken(shareData);
List<Item> files = new ArrayList<>();
List<Item> subs = new ArrayList<>();
List<Map<String, Object>> listData = listFile(1, shareData, files, subs, shareData.getShareId(), shareData.getFolderId(), 1);
List<Item> listData = listFile(1, shareData, files, subs, shareData.getShareId(), shareData.getFolderId(), 1);
List<String> playFrom = QuarkApi.get().getPlayFormatList();
@ -118,8 +133,7 @@ public class QuarkApi {
public String playerContent(String[] split, String flag) throws Exception {
String[] id_list = split;
String shareId = id_list[2], stoken = id_list[3], fileId = id_list[0], fileToken = id_list[1];
String fileId = split[0], fileToken = split[1], shareId = split[2], stoken = split[3];
String playUrl = "";
if (flag.contains("原画")) {
playUrl = this.getDownload(shareId, stoken, fileId, fileToken, true);
@ -133,16 +147,6 @@ public class QuarkApi {
}
private Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch");
headers.put("Referer", "https://pan.quark.cn/");
headers.put("Content-Type", "application/json");
headers.put("Cookie", this.cookie);
headers.put("Host", "drive-pc.quark.cn");
return headers;
}
/**
* @param url
* @param params get 参数
@ -168,16 +172,6 @@ public class QuarkApi {
}
/*if (okResult.getResp().get("Set-Cookie") != null) {
Matcher matcher = Pattern.compile("__puus=([^;]+)").matcher(StringUtils.join(okResult.getResp().get("Set-Cookie"), ";;;"));
if (matcher.find()) {
Matcher cookieMatcher = Pattern.compile("__puus=([^;]+)").matcher(this.cookie);
if (cookieMatcher.find() && !cookieMatcher.group(1).equals(matcher.group(1))) {
this.cookie = this.cookie.replaceAll("__puus=[^;]+", "__puus=" + matcher.group(1));
}
}
}*/
if (okResult.getCode() != 200 && leftRetry > 0) {
Thread.sleep(1000);
return api(url, params, data, leftRetry - 1, method);
@ -192,18 +186,20 @@ public class QuarkApi {
SpiderDebug.log("cookie为空");
throw new RuntimeException("cookie为空");
}
String token = cache.getUser().getCookie();
if (token.isEmpty()) token = cookie;
String token = serviceTicket;
OkResult result = OkHttp.get("https://pan.quark.cn/account/info?st=" + token + "&lw=scan", new HashMap<>(), getWebHeaders());
AccountInfo json = Json.parseSafe(result.getBody(), AccountInfo.class);
if (json.isSuccess()) {
List<String> cookies = result.getResp().get("set-Cookie");
List<String> cookieList = new ArrayList<>();
for (String cookie : cookies) {
cookieList.add(cookie.split(";")[0]);
}
this.cookie += TextUtils.join(";", cookieList);
OkResult result = OkHttp.get("https://pan.quark.cn/account/info?st=" + token, new HashMap<>(), Map.of("set-cookie", "my-set-cookie"));
Map<String, Object> json = Json.parseSafe(result.getBody(), Map.class);
if (json.get("code").equals("ok")) {
String cook = result.getResp().get("my-set-cookie").get(0);
cache.setUser(User.objectFrom(cook));
if (cache.getUser().getCookie().isEmpty()) throw new Exception(cook);
initQuark(cook);
cache.setUser(User.objectFrom(this.cookie));
if (cache.getUser().getCookie().isEmpty()) throw new Exception(this.cookie);
initQuark(this.cookie);
return true;
}
return false;
@ -229,11 +225,18 @@ public class QuarkApi {
params.put("client_id", "386");
params.put("v", "1.2");
params.put("request_id", UUID.randomUUID().toString());
String res = OkHttp.string("https://uop.quark.cn/cas/ajax/getTokenForQrcodeLogin", params);
Map<String, Object> json = new HashMap<>();
json = Json.parseSafe(res, json.getClass());
if (json.get("message").equals("ok")) {
return (String) ((Map<String, Object>) ((Map<String, Object>) json.get("data")).get("members")).get("token");
OkResult res = OkHttp.get("https://uop.quark.cn/cas/ajax/getTokenForQrcodeLogin", params, new HashMap<>());
if (this.cookie.isEmpty()) {
List<String> cookies = res.getResp().get("set-Cookie");
List<String> cookieList = new ArrayList<>();
for (String cookie : cookies) {
cookieList.add(cookie.split(";")[0]);
}
this.cookie = TextUtils.join(";", cookieList);
}
WebApiResponse json = Json.parseSafe(res.getBody(), WebApiResponse.class);
if (json.getMessage().equals("ok")) {
return json.getData().getMembers().getToken();
}
return "";
}
@ -246,11 +249,11 @@ public class QuarkApi {
*
* @return 返回包含token的二维码URL字符串
*/
private String getQrCodeContent() {
private String getQrCodeToken() {
// 获取用于二维码登录的token
String token = getTokenForQrcodeLogin();
// 组装二维码URL包含token和客户端标识
return "https://su.quark.cn/4_eMHBJ?uc_param_str=&token=" + token + "&client_id=532&uc_biz_str=S%3Acustom%7COPT%3ASAREA%400%7COPT%3AIMMERSIVE%401%7COPT%3ABACK_BTN_STYLE%400";
return token;
}
@ -294,31 +297,33 @@ public class QuarkApi {
}
}
private List<Map<String, Object>> listFile(int shareIndex, ShareData shareData, List<Item> videos, List<Item> subtitles, String shareId, String folderId, Integer page) throws Exception {
private List<Item> listFile(int shareIndex, ShareData shareData, List<Item> videos, List<Item> subtitles, String shareId, String folderId, Integer page) throws Exception {
int prePage = 200;
page = page != null ? page : 1;
Map<String, Object> listData = Json.parseSafe(api("share/sharepage/detail?" + this.pr + "&pwd_id=" + shareId + "&stoken=" + encodeURIComponent((String) this.shareTokenCache.get(shareId).get("stoken")) + "&pdir_fid=" + folderId + "&force=0&_page=" + page + "&_size=" + prePage + "&_sort=file_type:asc,file_name:asc", Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), Map.class);
if (listData.get("data") == null) return Collections.emptyList();
List<Map<String, Object>> items = (List<Map<String, Object>>) ((Map<String, Object>) listData.get("data")).get("list");
Type type = new TypeToken<ApiResponse<Data>>() {
}.getType();
ApiResponse<Data> listData = Json.parseSafe(api("share/sharepage/detail?" + this.pr + "&pwd_id=" + shareId + "&stoken=" + encodeURIComponent((String) this.shareTokenCache.get(shareId).get("stoken")) + "&pdir_fid=" + folderId + "&force=0&_page=" + page + "&_size=" + prePage + "&_sort=file_type:asc,file_name:asc", Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), type);
if (listData.getData() == null) return Collections.emptyList();
List<Item> items = listData.getData().getList();
if (items == null) return Collections.emptyList();
List<Map<String, Object>> subDir = new ArrayList<>();
for (Map<String, Object> item : items) {
if (Boolean.TRUE.equals(item.get("dir"))) {
List<Item> subDir = new ArrayList<>();
for (Item item : items) {
if (Boolean.TRUE.equals(item.isDir())) {
subDir.add(item);
} else if (Boolean.TRUE.equals(item.get("file")) && "video".equals(item.get("obj_category"))) {
if ((Double) item.get("size") < 1024 * 1024 * 5) continue;
item.put("stoken", this.shareTokenCache.get(shareData.getShareId()).get("stoken"));
} else if (Boolean.TRUE.equals(item.isFile()) && "video".equals(item.getObjCategory())) {
if (item.getSize() < 1024 * 1024 * 5) continue;
item.setShareToken((String) this.shareTokenCache.get(shareData.getShareId()).get("stoken"));
videos.add(Item.objectFrom(item, shareData.getShareId(), shareIndex));
} else if ("file".equals(item.get("type")) && this.subtitleExts.contains("." + Util.getExt((String) item.get("file_name")))) {
} else if ("file".equals(item.getFileType()) && this.subtitleExts.contains("." + Util.getExt(item.getFileName()))) {
subtitles.add(Item.objectFrom(item, shareData.getShareId(), shareIndex));
}
}
if (page < Math.ceil((double) ((Map<String, Object>) listData.get("metadata")).get("_total") / prePage)) {
List<Map<String, Object>> nextItems = listFile(shareIndex, shareData, videos, subtitles, shareId, folderId, page + 1);
if (page < Math.ceil((double) listData.getMetadata().getTotal() / prePage)) {
List<Item> nextItems = listFile(shareIndex, shareData, videos, subtitles, shareId, folderId, page + 1);
items.addAll(nextItems);
}
for (Map<String, Object> dir : subDir) {
List<Map<String, Object>> subItems = listFile(shareIndex, shareData, videos, subtitles, shareId, dir.get("fid").toString(), null);
for (Item dir : subDir) {
List<Item> subItems = listFile(shareIndex, shareData, videos, subtitles, shareId, dir.getFid(), null);
items.addAll(subItems);
}
return items;
@ -328,7 +333,7 @@ public class QuarkApi {
List<Map<String, Object>> results = new ArrayList<>();
int bestMatchIndex = 0;
for (int i = 0; i < targetItems.size(); i++) {
Util.LCSResult currentLCS = Util.lcs(mainItem.getName(), targetItems.get(i).getName());
Util.LCSResult currentLCS = Util.lcs(mainItem.getFileName(), targetItems.get(i).getFileName());
Map<String, Object> result = new HashMap<>();
result.put("target", targetItems.get(i));
result.put("lcs", currentLCS);
@ -366,11 +371,13 @@ public class QuarkApi {
}
private void clearSaveDir() throws Exception {
Map<String, Object> listData = Json.parseSafe(api("file/sort?" + this.pr + "&pdir_fid=" + this.saveDirId + "&_page=1&_size=200&_sort=file_type:asc,updated_at:desc", Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), Map.class);
if (listData.get("data") != null && ((List<Map<String, Object>>) ((Map<String, Object>) listData.get("data")).get("list")).size() > 0) {
Type type = new TypeToken<ApiResponse<Data>>() {
}.getType();
ApiResponse<Data> listData = Json.parseSafe(api("file/sort?" + this.pr + "&pdir_fid=" + this.saveDirId + "&_page=1&_size=200&_sort=file_type:asc,updated_at:desc", Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), type);
if (listData.getData() != null && !listData.getData().getList().isEmpty()) {
List<String> list = new ArrayList<>();
for (Map<String, Object> stringStringMap : ((List<Map<String, Object>>) ((Map<String, Object>) listData.get("data")).get("list"))) {
list.add((String) stringStringMap.get("fid"));
for (Item stringStringMap : listData.getData().getList()) {
list.add(stringStringMap.getFid());
}
api("file/delete?" + this.pr, Collections.emptyMap(), Map.of("action_type", "2", "filelist", Json.toJson(list), "exclude_fids", ""), 0, "POST");
}
@ -381,11 +388,13 @@ public class QuarkApi {
if (clean) clearSaveDir();
return;
}
Map<String, Object> listData = Json.parseSafe(api("file/sort?" + this.pr + "&pdir_fid=0&_page=1&_size=200&_sort=file_type:asc,updated_at:desc", Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), Map.class);
if (listData.get("data") != null) {
for (Map<String, Object> item : (List<Map<String, Object>>) ((Map<String, Object>) listData.get("data")).get("list")) {
if (this.saveDirName.equals(item.get("file_name"))) {
this.saveDirId = item.get("fid").toString();
Type type = new TypeToken<ApiResponse<Data>>() {
}.getType();
ApiResponse<Data> listData = Json.parseSafe(api("file/sort?" + this.pr + "&pdir_fid=0&_page=1&_size=200&_sort=file_type:asc,updated_at:desc", Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), type);
if (listData.getData() != null) {
for (Item item : listData.getData().getList()) {
if (this.saveDirName.equals(item.getFileName())) {
this.saveDirId = item.getFid();
clearSaveDir();
break;
}
@ -409,13 +418,17 @@ public class QuarkApi {
getShareToken(new ShareData(shareId, null));
if (!this.shareTokenCache.containsKey(shareId)) return null;
}
Map<String, Object> saveResult = Json.parseSafe(api("share/sharepage/save?" + this.pr, null, Map.of("fid_list", List.of(fileId), "fid_token_list", List.of(fileToken), "to_pdir_fid", this.saveDirId, "pwd_id", shareId, "stoken", stoken != null ? stoken : (String) this.shareTokenCache.get(shareId).get("stoken"), "pdir_fid", "0", "scene", "link"), 0, "POST"), Map.class);
if (saveResult.get("data") != null && ((Map<String, Object>) saveResult.get("data")).get("task_id") != null) {
Type type = new TypeToken<ApiResponse<Map<String, String>>>() {
}.getType();
ApiResponse<Map<String, String>> saveResult = Json.parseSafe(api("share/sharepage/save?" + this.pr, null, Map.of("fid_list", List.of(fileId), "fid_token_list", List.of(fileToken), "to_pdir_fid", this.saveDirId, "pwd_id", shareId, "stoken", stoken != null ? stoken : (String) this.shareTokenCache.get(shareId).get("stoken"), "pdir_fid", "0", "scene", "link"), 0, "POST"), type);
if (saveResult.getData() != null && (saveResult.getData()).get("task_id") != null) {
int retry = 0;
while (true) {
Map<String, Object> taskResult = Json.parseSafe(api("task?" + this.pr + "&task_id=" + ((Map<String, Object>) saveResult.get("data")).get("task_id") + "&retry_index=" + retry, Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), Map.class);
if (taskResult.get("data") != null && ((Map<String, Object>) taskResult.get("data")).get("save_as") != null && ((Map<String, Object>) ((Map<String, Object>) taskResult.get("data")).get("save_as")).get("save_as_top_fids") != null && ((List<String>) ((Map<String, Object>) ((Map<String, Object>) taskResult.get("data")).get("save_as")).get("save_as_top_fids")).size() > 0) {
return ((List<String>) ((Map<String, Object>) ((Map<String, Object>) taskResult.get("data")).get("save_as")).get("save_as_top_fids")).get(0);
Type type2 = new TypeToken<ApiResponse<Map<String, Object>>>() {
}.getType();
ApiResponse<Map<String, Object>> taskResult = Json.parseSafe(api("task?" + this.pr + "&task_id=" + (saveResult.getData()).get("task_id") + "&retry_index=" + retry, Collections.emptyMap(), Collections.emptyMap(), 0, "GET"), type2);
if (taskResult.getData() != null && taskResult.getData().get("save_as") != null && ((Map<String, Object>) taskResult.getData().get("save_as")).get("save_as_top_fids") != null && ((List<String>) ((Map<String, Object>) ((Map<String, Object>) taskResult.getData()).get("save_as")).get("save_as_top_fids")).size() > 0) {
return ((List<String>) ((Map<String, Object>) (taskResult.getData()).get("save_as")).get("save_as_top_fids")).get(0);
}
retry++;
if (retry > 2) break;
@ -431,17 +444,19 @@ public class QuarkApi {
if (saveFileId == null) return null;
this.saveFileIdCaches.put(fileId, saveFileId);
}
Map<String, Object> transcoding = Json.parseSafe(api("file/v2/play?" + this.pr, Collections.emptyMap(), Map.of("fid", this.saveFileIdCaches.get(fileId), "resolutions", "normal,low,high,super,2k,4k", "supports", "fmp4"), 0, "POST"), Map.class);
if (transcoding.get("data") != null && ((Map<String, Object>) transcoding.get("data")).get("video_list") != null) {
Type type2 = new TypeToken<ApiResponse<Map<String, Object>>>() {
}.getType();
ApiResponse<Map<String, Object>> transcoding = Json.parseSafe(api("file/v2/play?" + this.pr, Collections.emptyMap(), Map.of("fid", this.saveFileIdCaches.get(fileId), "resolutions", "normal,low,high,super,2k,4k", "supports", "fmp4"), 0, "POST"), type2);
if (transcoding.getData() != null && (transcoding.getData()).get("video_list") != null) {
String flagId = flag.split("-")[flag.split("-").length - 1];
int index = Util.findAllIndexes(getPlayFormatList(), flagId);
String quarkFormat = getPlayFormatQuarkList().get(index);
for (Map<String, Object> video : (List<Map<String, Object>>) ((Map<String, Object>) transcoding.get("data")).get("video_list")) {
for (Map<String, Object> video : (List<Map<String, Object>>) (transcoding.getData()).get("video_list")) {
if (video.get("resolution").equals(quarkFormat)) {
return (String) ((Map<String, Object>) video.get("video_info")).get("url");
}
}
return (String) ((Map<String, Object>) ((List<Map<String, Object>>) ((Map<String, Object>) transcoding.get("data")).get("video_list")).get(index).get("video_info")).get("url");
return (String) ((Map<String, Object>) ((List<Map<String, Object>>) (transcoding.getData()).get("video_list")).get(index).get("video_info")).get("url");
}
return null;
}
@ -508,21 +523,22 @@ public class QuarkApi {
}
private void getQRCode() {
String content = getQrCodeContent();
Init.run(() -> openApp(content));
String token = getQrCodeToken();
Init.run(() -> openApp(token));
}
private void openApp(String json) {
private void openApp(String token) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClassName("com.alicloud.databox", "com.taobao.login4android.scan.QrScanActivity");
intent.putExtra("key_scanParam", json);
intent.putExtra("key_scanParam", token);
Init.getActivity().startActivity(intent);
} catch (Exception e) {
showQRCode(json);
showQRCode("https://su.quark.cn/4_eMHBJ?uc_param_str=&token=" + token + "&client_id=532&uc_biz_str=S%3Acustom%7COPT%3ASAREA%400%7COPT%3AIMMERSIVE%401%7COPT%3ABACK_BTN_STYLE%400");
} finally {
Map<String, String> map = new HashMap<>();
map.put("token", json);
map.put("token", token);
Init.execute(() -> startService(map));
}
}
@ -550,21 +566,21 @@ public class QuarkApi {
params.put("request_id", UUID.randomUUID().toString());
service = Executors.newScheduledThreadPool(1);
service.scheduleWithFixedDelay(() -> {
String result = OkHttp.string("https://uop.quark.cn/cas/ajax/getServiceTicketByQrcodeToken", params, getHeaders());
Map<String, Object> json = new HashMap<>();
json = Json.parseSafe(result, json.getClass());
if (json.get("status").equals(2000000)) {
String result = OkHttp.string("https://uop.quark.cn/cas/ajax/getServiceTicketByQrcodeToken", params, getWebHeaders());
setToken((String) ((Map<String, Object>) ((Map<String, Object>) json.get("data")).get("members")).get("service_ticket"));
WebApiResponse json = Json.parseSafe(result, WebApiResponse.class);
if (json.getStatus() == 2000000) {
setToken(json.getData().getMembers().getServiceTicket());
}
}, 1, 1, TimeUnit.SECONDS);
}
private void setToken(String value) {
cache.getUser().setCookie(value);
SpiderDebug.log("Token:" + value);
Notify.show("Token:" + value);
this.serviceTicket = value;
SpiderDebug.log("ServiceTicket:" + value);
Notify.show("ServiceTicket:" + value);
refreshAccessToken();
stopService();
}

View File

@ -0,0 +1,74 @@
package com.github.catvod.bean.quark;
public class AccountInfo {
private boolean success;
private Data data;
private String code;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public static class Data {
private String nickname;
private String avatarUri;
private String mobilekps;
private Config config;
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getAvatarUri() {
return avatarUri;
}
public void setAvatarUri(String avatarUri) {
this.avatarUri = avatarUri;
}
public String getMobilekps() {
return mobilekps;
}
public void setMobilekps(String mobilekps) {
this.mobilekps = mobilekps;
}
public Config getConfig() {
return config;
}
public void setConfig(Config config) {
this.config = config;
}
}
public static class Config {
// 可以根据实际情况添加属性
}
}

View File

@ -0,0 +1,71 @@
package com.github.catvod.bean.quark;
import com.google.gson.annotations.SerializedName;
public class ApiResponse<T> {
@SerializedName("status")
private int status;
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("timestamp")
private long timestamp;
@SerializedName("data")
private T data;
@SerializedName("metadata")
private Metadata metadata;
// Getters and Setters
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
}

View File

@ -0,0 +1,30 @@
package com.github.catvod.bean.quark;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Data {
@SerializedName("is_owner")
private int isOwner;
@SerializedName("list")
private List<Item> list;
// Getters and Setters
public int getIsOwner() {
return isOwner;
}
public void setIsOwner(int isOwner) {
this.isOwner = isOwner;
}
public List<Item> getList() {
return list;
}
public void setList(List<Item> list) {
this.list = list;
}
}

View File

@ -1,27 +1,139 @@
package com.github.catvod.bean.quark;
import com.github.catvod.utils.Util;
import com.google.gson.annotations.SerializedName;
import java.util.Map;
import java.util.regex.Pattern;
public class Item {
private String fileId;
@SerializedName("fid")
private String fid;
@SerializedName("file_name")
private String fileName;
@SerializedName("pdir_fid")
private String pdirFid;
private int category;
private int fileType;
private long size;
@SerializedName("format_type")
private String formatType;
private int status;
private String tags;
@SerializedName("owner_ucid")
private String ownerUcid;
@SerializedName("l_created_at")
private long lCreatedAt;
@SerializedName("l_updated_at")
private long lUpdatedAt;
private String extra;
@SerializedName("source")
private String source;
@SerializedName("file_source")
private String fileSource;
private int nameSpace;
@SerializedName("l_shot_at")
private long lShotAt;
@SerializedName("series_id")
private String seriesId;
private String thumbnail;
private String bigThumbnail;
@SerializedName("preview_url")
private String previewUrl;
@SerializedName("video_max_resolution")
private String videoMaxResolution;
@SerializedName("source_display")
private String sourceDisplay;
private int videoWidth;
private boolean seriesDir;
private boolean uploadCameraRootDir;
private int videoHeight;
private int videoRotate;
private double fps;
private int like;
@SerializedName("operated_at")
private long operatedAt;
private int riskType;
private int backupSign;
@SerializedName("obj_category")
private String objCategory;
@SerializedName("file_name_hl")
private String fileNameHl;
@SerializedName("file_name_hl_start")
private int fileNameHlStart;
@SerializedName("file_name_hl_end")
private int fileNameHlEnd;
private int duration;
private Map<String, Object> eventExtra;
private int scrapeStatus;
@SerializedName("update_view_at")
private long updateViewAt;
@SerializedName("last_update_at")
private long lastUpdateAt;
@SerializedName("share_fid_token")
private String shareFidToken;
private boolean ban;
@SerializedName("save_as_source")
private boolean saveAsSource;
private int curVersionOrDefault;
private int rawNameSpace;
private boolean backupSource;
private boolean offlineSource;
@SerializedName("owner_drive_type_or_default")
private int ownerDriveTypeOrDefault;
private boolean dir;
private boolean file;
@SerializedName("created_at")
private long createdAt;
@SerializedName("updated_at")
private long updatedAt;
private String shareId;
private String shareToken;
private String shareFileToken;
private String seriesId;
private String name;
private String type;
private String formatType;
private Double size;
private String parent;
private String shareData;
private int shareIndex;
private Double lastUpdateAt;
private String subtitle;
public Item() {
public static Item objectFrom(Item item, String shareId, int shareIndex) {
item.setShareId(shareId);
item.setShareIndex(shareIndex);
return item;
}
public String getShareToken() {
return shareToken;
}
public void setShareToken(String shareToken) {
this.shareToken = shareToken;
}
private int shareIndex;
public int getShareIndex() {
return shareIndex;
}
public void setShareIndex(int shareIndex) {
this.shareIndex = shareIndex;
}
public String getShareId() {
return shareId;
}
public void setShareId(String shareId) {
this.shareId = shareId;
}
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
/* public Item() {
this.fileId = "";
this.shareId = "";
this.shareToken = "";
@ -52,14 +164,14 @@ public class Item {
item.lastUpdateAt = item_json.get("last_update_at") != null ? (Double) item_json.get("last_update_at") : Double.valueOf(0d);
item.shareIndex = shareIndex;
return item;
}
}*/
public String getFileExtension() {
String[] arr = name.split("\\.");
String[] arr = fileName.split("\\.");
return arr[arr.length - 1];
}
public String getSubtitle() {
/* public String getSubtitle() {
return subtitle;
}
@ -86,10 +198,10 @@ public class Item {
public int getShareIndex() {
return shareIndex;
}
}*/
public String getDisplayName(String type_name) {
String name = getName();
String name = getFileName();
if (type_name.equals("电视剧")) {
String[] replaceNameList = {"4k", "4K"};
name = name.replaceAll("\\." + getFileExtension(), "");
@ -106,7 +218,442 @@ public class Item {
}
public String getEpisodeUrl(String type_name) {
return getDisplayName(type_name) + "$" + getFileId() + "++" + shareFileToken + "++" + shareId + "++" + shareToken;
return getDisplayName(type_name) + "$" + getFid() + "++" + getShareFidToken() + "++" + getShareId() + "++" + getShareToken();
}
public Item() {
}
public String getFid() {
return fid;
}
public void setFid(String fid) {
this.fid = fid;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getPdirFid() {
return pdirFid;
}
public void setPdirFid(String pdirFid) {
this.pdirFid = pdirFid;
}
public int getCategory() {
return category;
}
public void setCategory(int category) {
this.category = category;
}
public int getFileType() {
return fileType;
}
public void setFileType(int fileType) {
this.fileType = fileType;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getFormatType() {
return formatType;
}
public void setFormatType(String formatType) {
this.formatType = formatType;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public String getOwnerUcid() {
return ownerUcid;
}
public void setOwnerUcid(String ownerUcid) {
this.ownerUcid = ownerUcid;
}
public long getlCreatedAt() {
return lCreatedAt;
}
public void setlCreatedAt(long lCreatedAt) {
this.lCreatedAt = lCreatedAt;
}
public long getlUpdatedAt() {
return lUpdatedAt;
}
public void setlUpdatedAt(long lUpdatedAt) {
this.lUpdatedAt = lUpdatedAt;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getFileSource() {
return fileSource;
}
public void setFileSource(String fileSource) {
this.fileSource = fileSource;
}
public int getNameSpace() {
return nameSpace;
}
public void setNameSpace(int nameSpace) {
this.nameSpace = nameSpace;
}
public long getlShotAt() {
return lShotAt;
}
public void setlShotAt(long lShotAt) {
this.lShotAt = lShotAt;
}
public String getSeriesId() {
return seriesId;
}
public void setSeriesId(String seriesId) {
this.seriesId = seriesId;
}
public String getThumbnail() {
return thumbnail;
}
public void setThumbnail(String thumbnail) {
this.thumbnail = thumbnail;
}
public String getBigThumbnail() {
return bigThumbnail;
}
public void setBigThumbnail(String bigThumbnail) {
this.bigThumbnail = bigThumbnail;
}
public String getPreviewUrl() {
return previewUrl;
}
public void setPreviewUrl(String previewUrl) {
this.previewUrl = previewUrl;
}
public String getVideoMaxResolution() {
return videoMaxResolution;
}
public void setVideoMaxResolution(String videoMaxResolution) {
this.videoMaxResolution = videoMaxResolution;
}
public String getSourceDisplay() {
return sourceDisplay;
}
public void setSourceDisplay(String sourceDisplay) {
this.sourceDisplay = sourceDisplay;
}
public int getVideoWidth() {
return videoWidth;
}
public void setVideoWidth(int videoWidth) {
this.videoWidth = videoWidth;
}
public boolean isSeriesDir() {
return seriesDir;
}
public void setSeriesDir(boolean seriesDir) {
this.seriesDir = seriesDir;
}
public boolean isUploadCameraRootDir() {
return uploadCameraRootDir;
}
public void setUploadCameraRootDir(boolean uploadCameraRootDir) {
this.uploadCameraRootDir = uploadCameraRootDir;
}
public int getVideoHeight() {
return videoHeight;
}
public void setVideoHeight(int videoHeight) {
this.videoHeight = videoHeight;
}
public int getVideoRotate() {
return videoRotate;
}
public void setVideoRotate(int videoRotate) {
this.videoRotate = videoRotate;
}
public double getFps() {
return fps;
}
public void setFps(double fps) {
this.fps = fps;
}
public int getLike() {
return like;
}
public void setLike(int like) {
this.like = like;
}
public long getOperatedAt() {
return operatedAt;
}
public void setOperatedAt(long operatedAt) {
this.operatedAt = operatedAt;
}
public int getRiskType() {
return riskType;
}
public void setRiskType(int riskType) {
this.riskType = riskType;
}
public int getBackupSign() {
return backupSign;
}
public void setBackupSign(int backupSign) {
this.backupSign = backupSign;
}
public String getObjCategory() {
return objCategory;
}
public void setObjCategory(String objCategory) {
this.objCategory = objCategory;
}
public String getFileNameHl() {
return fileNameHl;
}
public void setFileNameHl(String fileNameHl) {
this.fileNameHl = fileNameHl;
}
public int getFileNameHlStart() {
return fileNameHlStart;
}
public void setFileNameHlStart(int fileNameHlStart) {
this.fileNameHlStart = fileNameHlStart;
}
public int getFileNameHlEnd() {
return fileNameHlEnd;
}
public void setFileNameHlEnd(int fileNameHlEnd) {
this.fileNameHlEnd = fileNameHlEnd;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public Map<String, Object> getEventExtra() {
return eventExtra;
}
public void setEventExtra(Map<String, Object> eventExtra) {
this.eventExtra = eventExtra;
}
public int getScrapeStatus() {
return scrapeStatus;
}
public void setScrapeStatus(int scrapeStatus) {
this.scrapeStatus = scrapeStatus;
}
public long getUpdateViewAt() {
return updateViewAt;
}
public void setUpdateViewAt(long updateViewAt) {
this.updateViewAt = updateViewAt;
}
public long getLastUpdateAt() {
return lastUpdateAt;
}
public void setLastUpdateAt(long lastUpdateAt) {
this.lastUpdateAt = lastUpdateAt;
}
public String getShareFidToken() {
return shareFidToken;
}
public void setShareFidToken(String shareFidToken) {
this.shareFidToken = shareFidToken;
}
public boolean isBan() {
return ban;
}
public void setBan(boolean ban) {
this.ban = ban;
}
public boolean isSaveAsSource() {
return saveAsSource;
}
public void setSaveAsSource(boolean saveAsSource) {
this.saveAsSource = saveAsSource;
}
public int getCurVersionOrDefault() {
return curVersionOrDefault;
}
public void setCurVersionOrDefault(int curVersionOrDefault) {
this.curVersionOrDefault = curVersionOrDefault;
}
public int getRawNameSpace() {
return rawNameSpace;
}
public void setRawNameSpace(int rawNameSpace) {
this.rawNameSpace = rawNameSpace;
}
public boolean isBackupSource() {
return backupSource;
}
public void setBackupSource(boolean backupSource) {
this.backupSource = backupSource;
}
public boolean isOfflineSource() {
return offlineSource;
}
public void setOfflineSource(boolean offlineSource) {
this.offlineSource = offlineSource;
}
public int getOwnerDriveTypeOrDefault() {
return ownerDriveTypeOrDefault;
}
public void setOwnerDriveTypeOrDefault(int ownerDriveTypeOrDefault) {
this.ownerDriveTypeOrDefault = ownerDriveTypeOrDefault;
}
public boolean isDir() {
return dir;
}
public void setDir(boolean dir) {
this.dir = dir;
}
public boolean isFile() {
return file;
}
public void setFile(boolean file) {
this.file = file;
}
public long getCreatedAt() {
return createdAt;
}
public void setCreatedAt(long createdAt) {
this.createdAt = createdAt;
}
public long getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(long updatedAt) {
this.updatedAt = updatedAt;
}
}

View File

@ -0,0 +1,79 @@
package com.github.catvod.bean.quark;
import com.google.gson.annotations.SerializedName;
import java.util.Map;
public class Metadata {
@SerializedName("_size")
private int size;
@SerializedName("_page")
private int page;
@SerializedName("_count")
private int count;
@SerializedName("_total")
private int total;
@SerializedName("check_fid_token")
private int checkFidToken;
@SerializedName("_g_group")
private String gGroup;
@SerializedName("_t_group")
private String tGroup;
// Getters and Setters
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getCheckFidToken() {
return checkFidToken;
}
public void setCheckFidToken(int checkFidToken) {
this.checkFidToken = checkFidToken;
}
public String getGGroup() {
return gGroup;
}
public void setGGroup(String gGroup) {
this.gGroup = gGroup;
}
public String getTGroup() {
return tGroup;
}
public void setTGroup(String tGroup) {
this.tGroup = tGroup;
}
}

View File

@ -0,0 +1,67 @@
package com.github.catvod.bean.quark;
import com.google.gson.annotations.SerializedName;
public class WebApiResponse {
private int status;
private String message;
private Data data;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
private Members members;
public Members getMembers() {
return members;
}
public void setMembers(Members members) {
this.members = members;
}
}
public static class Members {
private String token;
@SerializedName("service_ticket")
private String serviceTicket;
public String getServiceTicket() {
return serviceTicket;
}
public void setServiceTicket(String serviceTicket) {
this.serviceTicket = serviceTicket;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
}

View File

@ -81,7 +81,7 @@ public class WoggTest {
@org.junit.Test
public void playerContent() throws Exception {
String content = spider.playerContent("quark4K", "d787d13c003c40bf8149f52ab9e24bd5++1b3bb0d1ab4ef09276e2a1e50cacdd0f++154a891ab53e++h5qQJe8ZhapYxmFUdCX8rRYdnBnJ+kfoSaZJTCDgOtE=", new ArrayList<>());
String content = spider.playerContent("quark4K", "c3f6b5fa48234c53909c65a4ff0f1888++f5fdf4f5e43aaef4db028cac23f20739++38c5e16d71f7++Yh7f4+dwB7CRa/HMcWOy0crfVjI6Yo8wtfuUwcnop3A=", new ArrayList<>());
System.out.println("playerContent--" + content);
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();

Binary file not shown.

View File

@ -1 +1 @@
93b340b932b9bb78d1adfb16fe254198
4537aa56277df82697b60bf7f0c0ed1c

View File

@ -1,5 +1,5 @@
{
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;93b340b932b9bb78d1adfb16fe254198",
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;4537aa56277df82697b60bf7f0c0ed1c",
"lives": [
{
"name": "直播ipv6",

View File

@ -1,5 +1,5 @@
{
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;93b340b932b9bb78d1adfb16fe254198",
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;4537aa56277df82697b60bf7f0c0ed1c",
"lives": [
{
"name": "直播ipv6",

View File

@ -1,5 +1,5 @@
{
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;93b340b932b9bb78d1adfb16fe254198",
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;4537aa56277df82697b60bf7f0c0ed1c",
"lives": [
{
"name": "直播ipv6",