网盘优化
This commit is contained in:
parent
ecd1467d33
commit
52347dd0fd
|
|
@ -0,0 +1,258 @@
|
||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import com.github.catvod.bean.Result;
|
||||||
|
import com.github.catvod.bean.Vod;
|
||||||
|
import com.github.catvod.net.OkHttp;
|
||||||
|
import com.github.catvod.net.OkResult;
|
||||||
|
import com.github.catvod.utils.Json;
|
||||||
|
import com.github.catvod.utils.Util;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TgSearch123 extends Cloud {
|
||||||
|
private static final String KEY_API_URLS = "api_urls";
|
||||||
|
private static final String KEY_DOMAIN_MAP = "siteurl";
|
||||||
|
private static final String KEY_SOURCES = "sources";
|
||||||
|
private static final int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
private List<String> apiUrls = new ArrayList<>();
|
||||||
|
private Map<String, String> domainMap = new HashMap<String, String>() {{
|
||||||
|
put("alipan", "阿里");
|
||||||
|
put("aliyundrive", "阿里");
|
||||||
|
put("quark", "夸克");
|
||||||
|
put("115cdn", "115");
|
||||||
|
put("baidu.com", "百度");
|
||||||
|
put("uc", "UC");
|
||||||
|
put("189.cn", "天翼");
|
||||||
|
put("139.com", "移动");
|
||||||
|
put("123", "123盘");
|
||||||
|
}};
|
||||||
|
private Set<String> sources = new HashSet<>();
|
||||||
|
private String[] extInfos = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(Context context, String extend) throws Exception {
|
||||||
|
super.init(context, extend);
|
||||||
|
|
||||||
|
this.apiUrls.clear();
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(extend)) {
|
||||||
|
try {
|
||||||
|
if (extend.contains("###")) {
|
||||||
|
String[] infos = extend.split("###");
|
||||||
|
this.extInfos = infos;
|
||||||
|
|
||||||
|
if (infos.length > 0 && !TextUtils.isEmpty(infos[0])) {
|
||||||
|
processExtendConfig(infos[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.extInfos = new String[]{extend};
|
||||||
|
processExtendConfig(extend);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.extInfos = null; // 重置,避免内存泄漏
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processExtendConfig(String config) {
|
||||||
|
try {
|
||||||
|
// 检查是否为HTTP URL
|
||||||
|
if (isValidUrl(config)) {
|
||||||
|
if (!this.apiUrls.contains(config)) {
|
||||||
|
this.apiUrls.add(config);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试JSON格式解析
|
||||||
|
JsonObject ext = Json.safeObject(config);
|
||||||
|
|
||||||
|
// 处理API URLs配置
|
||||||
|
processApiUrls(ext);
|
||||||
|
|
||||||
|
// 处理域名映射配置
|
||||||
|
processDomainMap(ext);
|
||||||
|
|
||||||
|
// 处理来源过滤配置
|
||||||
|
processSources(ext, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 可以添加日志记录
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processApiUrls(JsonObject config) {
|
||||||
|
if (config.has(KEY_API_URLS) && config.get(KEY_API_URLS).isJsonArray()) {
|
||||||
|
JsonArray urlsArray = config.getAsJsonArray(KEY_API_URLS);
|
||||||
|
for (JsonElement element : urlsArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String url = element.getAsString();
|
||||||
|
if (isValidUrl(url) && !this.apiUrls.contains(url)) {
|
||||||
|
this.apiUrls.add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDomainMap(JsonObject config) {
|
||||||
|
if (config.has(KEY_DOMAIN_MAP) && config.get(KEY_DOMAIN_MAP).isJsonObject()) {
|
||||||
|
JsonObject customDomains = config.getAsJsonObject(KEY_DOMAIN_MAP);
|
||||||
|
for (Map.Entry<String, JsonElement> entry : customDomains.entrySet()) {
|
||||||
|
if (entry == null || entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
String domain = entry.getKey();
|
||||||
|
String sourceName = "";
|
||||||
|
try {
|
||||||
|
sourceName = entry.getValue().getAsString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(sourceName) && !domainMap.containsKey(domain)) {
|
||||||
|
domainMap.put(domain, sourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSources(JsonObject config, boolean clearExisting) {
|
||||||
|
if (config.has(KEY_SOURCES) && config.get(KEY_SOURCES).isJsonArray()) {
|
||||||
|
if (clearExisting) {
|
||||||
|
this.sources.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray sourcesArray = config.getAsJsonArray(KEY_SOURCES);
|
||||||
|
for (JsonElement element : sourcesArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String source = element.getAsString();
|
||||||
|
if (!TextUtils.isEmpty(source) && !sources.contains(source)) {
|
||||||
|
sources.add(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidUrl(String url) {
|
||||||
|
return !TextUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (key == null || key.trim().isEmpty()) {
|
||||||
|
return Result.error("关键词不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
return performSearch(key, 1, DEFAULT_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String performSearch(String key, int page, int pageSize) throws Exception {
|
||||||
|
List<Vod> list = new ArrayList<>();
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("kw", key);
|
||||||
|
params.put("page", String.valueOf(page));
|
||||||
|
params.put("size", String.valueOf(pageSize));
|
||||||
|
|
||||||
|
for (String apiUrl : apiUrls) {
|
||||||
|
if (!isValidUrl(apiUrl)) continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
OkResult result = OkHttp.get(apiUrl, params, getHeader());
|
||||||
|
if (result.getCode() == 500 || TextUtils.isEmpty(result.getBody())) continue;
|
||||||
|
|
||||||
|
JsonObject jsonObject = Json.safeObject(result.getBody());
|
||||||
|
if (!jsonObject.has("code") || jsonObject.get("code").getAsInt() != 0 || !jsonObject.has("data"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JsonObject data = jsonObject.getAsJsonObject("data");
|
||||||
|
|
||||||
|
total = data.has("total") && !data.get("total").isJsonNull() ? data.get("total").getAsInt() : 0;
|
||||||
|
|
||||||
|
// 直接检查merged_by_type字段,无需三重判断
|
||||||
|
if (!data.has("merged_by_type") || !data.get("merged_by_type").isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject mergedByType = data.getAsJsonObject("merged_by_type");
|
||||||
|
|
||||||
|
for (Map.Entry<String, JsonElement> categoryEntry : mergedByType.entrySet()) {
|
||||||
|
if (!categoryEntry.getValue().isJsonArray()) continue;
|
||||||
|
|
||||||
|
JsonArray items = categoryEntry.getValue().getAsJsonArray();
|
||||||
|
|
||||||
|
for (JsonElement item : items) {
|
||||||
|
if (!item.isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject entry = item.getAsJsonObject();
|
||||||
|
|
||||||
|
String vodUrl = entry.has("url") && !entry.get("url").isJsonNull() ? entry.get("url").getAsString() : "";
|
||||||
|
if (TextUtils.isEmpty(vodUrl)) continue;
|
||||||
|
|
||||||
|
// 获取来源信息并映射
|
||||||
|
String originalSource = entry.has("source") && !entry.get("source").isJsonNull() ? entry.get("source").getAsString() : "未知来源";
|
||||||
|
String sourceName = mapSource(vodUrl, originalSource);
|
||||||
|
|
||||||
|
// 获取标题
|
||||||
|
String title = entry.has("note") && !entry.get("note").isJsonNull() ? entry.get("note").getAsString() : "未命名资源";
|
||||||
|
|
||||||
|
// 获取图片
|
||||||
|
String pic = getFirstImage(entry);
|
||||||
|
|
||||||
|
// 简化VodPlayBuilder的使用
|
||||||
|
Vod vod = new Vod(vodUrl, title, pic, sourceName + " (" + originalSource + ")");
|
||||||
|
// 由于只有一个播放源,直接设置播放信息
|
||||||
|
vod.setVodPlayFrom(sourceName);
|
||||||
|
vod.setVodPlayUrl("播放源$" + vodUrl);
|
||||||
|
|
||||||
|
// 来源过滤
|
||||||
|
if (sources.isEmpty() || sources.contains(sourceName)) {
|
||||||
|
list.add(vod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pageCount = total > 0 && pageSize > 0 ? (total + pageSize - 1) / pageSize : 1;
|
||||||
|
return Result.string(page, pageCount, pageSize, total, list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 出错时继续尝试下一个API
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.error("无法连接到任何搜索API");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取来源映射逻辑为单独方法
|
||||||
|
private String mapSource(String vodUrl, String originalSource) {
|
||||||
|
for (Map.Entry<String, String> domainEntry : domainMap.entrySet()) {
|
||||||
|
if (vodUrl.contains(domainEntry.getKey())) {
|
||||||
|
return domainEntry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取图片获取逻辑为单独方法
|
||||||
|
private String getFirstImage(JsonObject entry) {
|
||||||
|
if (entry.has("images") && !entry.get("images").isJsonNull() && entry.get("images").isJsonArray()) {
|
||||||
|
JsonArray images = entry.getAsJsonArray("images");
|
||||||
|
if (images.size() > 0 && !images.get(0).isJsonNull() && images.get(0).isJsonPrimitive()) {
|
||||||
|
return images.get(0).getAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,258 @@
|
||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import com.github.catvod.bean.Result;
|
||||||
|
import com.github.catvod.bean.Vod;
|
||||||
|
import com.github.catvod.net.OkHttp;
|
||||||
|
import com.github.catvod.net.OkResult;
|
||||||
|
import com.github.catvod.utils.Json;
|
||||||
|
import com.github.catvod.utils.Util;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TgSearch139 extends Cloud {
|
||||||
|
private static final String KEY_API_URLS = "api_urls";
|
||||||
|
private static final String KEY_DOMAIN_MAP = "siteurl";
|
||||||
|
private static final String KEY_SOURCES = "sources";
|
||||||
|
private static final int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
private List<String> apiUrls = new ArrayList<>();
|
||||||
|
private Map<String, String> domainMap = new HashMap<String, String>() {{
|
||||||
|
put("alipan", "阿里");
|
||||||
|
put("aliyundrive", "阿里");
|
||||||
|
put("quark", "夸克");
|
||||||
|
put("115cdn", "115");
|
||||||
|
put("baidu.com", "百度");
|
||||||
|
put("uc", "UC");
|
||||||
|
put("189.cn", "天翼");
|
||||||
|
put("139.com", "移动");
|
||||||
|
put("123", "123盘");
|
||||||
|
}};
|
||||||
|
private Set<String> sources = new HashSet<>();
|
||||||
|
private String[] extInfos = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(Context context, String extend) throws Exception {
|
||||||
|
super.init(context, extend);
|
||||||
|
|
||||||
|
this.apiUrls.clear();
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(extend)) {
|
||||||
|
try {
|
||||||
|
if (extend.contains("###")) {
|
||||||
|
String[] infos = extend.split("###");
|
||||||
|
this.extInfos = infos;
|
||||||
|
|
||||||
|
if (infos.length > 0 && !TextUtils.isEmpty(infos[0])) {
|
||||||
|
processExtendConfig(infos[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.extInfos = new String[]{extend};
|
||||||
|
processExtendConfig(extend);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.extInfos = null; // 重置,避免内存泄漏
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processExtendConfig(String config) {
|
||||||
|
try {
|
||||||
|
// 检查是否为HTTP URL
|
||||||
|
if (isValidUrl(config)) {
|
||||||
|
if (!this.apiUrls.contains(config)) {
|
||||||
|
this.apiUrls.add(config);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试JSON格式解析
|
||||||
|
JsonObject ext = Json.safeObject(config);
|
||||||
|
|
||||||
|
// 处理API URLs配置
|
||||||
|
processApiUrls(ext);
|
||||||
|
|
||||||
|
// 处理域名映射配置
|
||||||
|
processDomainMap(ext);
|
||||||
|
|
||||||
|
// 处理来源过滤配置
|
||||||
|
processSources(ext, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 可以添加日志记录
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processApiUrls(JsonObject config) {
|
||||||
|
if (config.has(KEY_API_URLS) && config.get(KEY_API_URLS).isJsonArray()) {
|
||||||
|
JsonArray urlsArray = config.getAsJsonArray(KEY_API_URLS);
|
||||||
|
for (JsonElement element : urlsArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String url = element.getAsString();
|
||||||
|
if (isValidUrl(url) && !this.apiUrls.contains(url)) {
|
||||||
|
this.apiUrls.add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDomainMap(JsonObject config) {
|
||||||
|
if (config.has(KEY_DOMAIN_MAP) && config.get(KEY_DOMAIN_MAP).isJsonObject()) {
|
||||||
|
JsonObject customDomains = config.getAsJsonObject(KEY_DOMAIN_MAP);
|
||||||
|
for (Map.Entry<String, JsonElement> entry : customDomains.entrySet()) {
|
||||||
|
if (entry == null || entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
String domain = entry.getKey();
|
||||||
|
String sourceName = "";
|
||||||
|
try {
|
||||||
|
sourceName = entry.getValue().getAsString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(sourceName) && !domainMap.containsKey(domain)) {
|
||||||
|
domainMap.put(domain, sourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSources(JsonObject config, boolean clearExisting) {
|
||||||
|
if (config.has(KEY_SOURCES) && config.get(KEY_SOURCES).isJsonArray()) {
|
||||||
|
if (clearExisting) {
|
||||||
|
this.sources.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray sourcesArray = config.getAsJsonArray(KEY_SOURCES);
|
||||||
|
for (JsonElement element : sourcesArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String source = element.getAsString();
|
||||||
|
if (!TextUtils.isEmpty(source) && !sources.contains(source)) {
|
||||||
|
sources.add(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidUrl(String url) {
|
||||||
|
return !TextUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (key == null || key.trim().isEmpty()) {
|
||||||
|
return Result.error("关键词不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
return performSearch(key, 1, DEFAULT_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String performSearch(String key, int page, int pageSize) throws Exception {
|
||||||
|
List<Vod> list = new ArrayList<>();
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("kw", key);
|
||||||
|
params.put("page", String.valueOf(page));
|
||||||
|
params.put("size", String.valueOf(pageSize));
|
||||||
|
|
||||||
|
for (String apiUrl : apiUrls) {
|
||||||
|
if (!isValidUrl(apiUrl)) continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
OkResult result = OkHttp.get(apiUrl, params, getHeader());
|
||||||
|
if (result.getCode() == 500 || TextUtils.isEmpty(result.getBody())) continue;
|
||||||
|
|
||||||
|
JsonObject jsonObject = Json.safeObject(result.getBody());
|
||||||
|
if (!jsonObject.has("code") || jsonObject.get("code").getAsInt() != 0 || !jsonObject.has("data"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JsonObject data = jsonObject.getAsJsonObject("data");
|
||||||
|
|
||||||
|
total = data.has("total") && !data.get("total").isJsonNull() ? data.get("total").getAsInt() : 0;
|
||||||
|
|
||||||
|
// 直接检查merged_by_type字段,无需三重判断
|
||||||
|
if (!data.has("merged_by_type") || !data.get("merged_by_type").isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject mergedByType = data.getAsJsonObject("merged_by_type");
|
||||||
|
|
||||||
|
for (Map.Entry<String, JsonElement> categoryEntry : mergedByType.entrySet()) {
|
||||||
|
if (!categoryEntry.getValue().isJsonArray()) continue;
|
||||||
|
|
||||||
|
JsonArray items = categoryEntry.getValue().getAsJsonArray();
|
||||||
|
|
||||||
|
for (JsonElement item : items) {
|
||||||
|
if (!item.isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject entry = item.getAsJsonObject();
|
||||||
|
|
||||||
|
String vodUrl = entry.has("url") && !entry.get("url").isJsonNull() ? entry.get("url").getAsString() : "";
|
||||||
|
if (TextUtils.isEmpty(vodUrl)) continue;
|
||||||
|
|
||||||
|
// 获取来源信息并映射
|
||||||
|
String originalSource = entry.has("source") && !entry.get("source").isJsonNull() ? entry.get("source").getAsString() : "未知来源";
|
||||||
|
String sourceName = mapSource(vodUrl, originalSource);
|
||||||
|
|
||||||
|
// 获取标题
|
||||||
|
String title = entry.has("note") && !entry.get("note").isJsonNull() ? entry.get("note").getAsString() : "未命名资源";
|
||||||
|
|
||||||
|
// 获取图片
|
||||||
|
String pic = getFirstImage(entry);
|
||||||
|
|
||||||
|
// 简化VodPlayBuilder的使用
|
||||||
|
Vod vod = new Vod(vodUrl, title, pic, sourceName + " (" + originalSource + ")");
|
||||||
|
// 由于只有一个播放源,直接设置播放信息
|
||||||
|
vod.setVodPlayFrom(sourceName);
|
||||||
|
vod.setVodPlayUrl("播放源$" + vodUrl);
|
||||||
|
|
||||||
|
// 来源过滤
|
||||||
|
if (sources.isEmpty() || sources.contains(sourceName)) {
|
||||||
|
list.add(vod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pageCount = total > 0 && pageSize > 0 ? (total + pageSize - 1) / pageSize : 1;
|
||||||
|
return Result.string(page, pageCount, pageSize, total, list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 出错时继续尝试下一个API
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.error("无法连接到任何搜索API");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取来源映射逻辑为单独方法
|
||||||
|
private String mapSource(String vodUrl, String originalSource) {
|
||||||
|
for (Map.Entry<String, String> domainEntry : domainMap.entrySet()) {
|
||||||
|
if (vodUrl.contains(domainEntry.getKey())) {
|
||||||
|
return domainEntry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取图片获取逻辑为单独方法
|
||||||
|
private String getFirstImage(JsonObject entry) {
|
||||||
|
if (entry.has("images") && !entry.get("images").isJsonNull() && entry.get("images").isJsonArray()) {
|
||||||
|
JsonArray images = entry.getAsJsonArray("images");
|
||||||
|
if (images.size() > 0 && !images.get(0).isJsonNull() && images.get(0).isJsonPrimitive()) {
|
||||||
|
return images.get(0).getAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,258 @@
|
||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import com.github.catvod.bean.Result;
|
||||||
|
import com.github.catvod.bean.Vod;
|
||||||
|
import com.github.catvod.net.OkHttp;
|
||||||
|
import com.github.catvod.net.OkResult;
|
||||||
|
import com.github.catvod.utils.Json;
|
||||||
|
import com.github.catvod.utils.Util;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TgSearch189 extends Cloud {
|
||||||
|
private static final String KEY_API_URLS = "api_urls";
|
||||||
|
private static final String KEY_DOMAIN_MAP = "siteurl";
|
||||||
|
private static final String KEY_SOURCES = "sources";
|
||||||
|
private static final int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
private List<String> apiUrls = new ArrayList<>();
|
||||||
|
private Map<String, String> domainMap = new HashMap<String, String>() {{
|
||||||
|
put("alipan", "阿里");
|
||||||
|
put("aliyundrive", "阿里");
|
||||||
|
put("quark", "夸克");
|
||||||
|
put("115cdn", "115");
|
||||||
|
put("baidu.com", "百度");
|
||||||
|
put("uc", "UC");
|
||||||
|
put("189.cn", "天翼");
|
||||||
|
put("139.com", "移动");
|
||||||
|
put("123", "123盘");
|
||||||
|
}};
|
||||||
|
private Set<String> sources = new HashSet<>();
|
||||||
|
private String[] extInfos = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(Context context, String extend) throws Exception {
|
||||||
|
super.init(context, extend);
|
||||||
|
|
||||||
|
this.apiUrls.clear();
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(extend)) {
|
||||||
|
try {
|
||||||
|
if (extend.contains("###")) {
|
||||||
|
String[] infos = extend.split("###");
|
||||||
|
this.extInfos = infos;
|
||||||
|
|
||||||
|
if (infos.length > 0 && !TextUtils.isEmpty(infos[0])) {
|
||||||
|
processExtendConfig(infos[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.extInfos = new String[]{extend};
|
||||||
|
processExtendConfig(extend);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.extInfos = null; // 重置,避免内存泄漏
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processExtendConfig(String config) {
|
||||||
|
try {
|
||||||
|
// 检查是否为HTTP URL
|
||||||
|
if (isValidUrl(config)) {
|
||||||
|
if (!this.apiUrls.contains(config)) {
|
||||||
|
this.apiUrls.add(config);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试JSON格式解析
|
||||||
|
JsonObject ext = Json.safeObject(config);
|
||||||
|
|
||||||
|
// 处理API URLs配置
|
||||||
|
processApiUrls(ext);
|
||||||
|
|
||||||
|
// 处理域名映射配置
|
||||||
|
processDomainMap(ext);
|
||||||
|
|
||||||
|
// 处理来源过滤配置
|
||||||
|
processSources(ext, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 可以添加日志记录
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processApiUrls(JsonObject config) {
|
||||||
|
if (config.has(KEY_API_URLS) && config.get(KEY_API_URLS).isJsonArray()) {
|
||||||
|
JsonArray urlsArray = config.getAsJsonArray(KEY_API_URLS);
|
||||||
|
for (JsonElement element : urlsArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String url = element.getAsString();
|
||||||
|
if (isValidUrl(url) && !this.apiUrls.contains(url)) {
|
||||||
|
this.apiUrls.add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDomainMap(JsonObject config) {
|
||||||
|
if (config.has(KEY_DOMAIN_MAP) && config.get(KEY_DOMAIN_MAP).isJsonObject()) {
|
||||||
|
JsonObject customDomains = config.getAsJsonObject(KEY_DOMAIN_MAP);
|
||||||
|
for (Map.Entry<String, JsonElement> entry : customDomains.entrySet()) {
|
||||||
|
if (entry == null || entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
String domain = entry.getKey();
|
||||||
|
String sourceName = "";
|
||||||
|
try {
|
||||||
|
sourceName = entry.getValue().getAsString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(sourceName) && !domainMap.containsKey(domain)) {
|
||||||
|
domainMap.put(domain, sourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSources(JsonObject config, boolean clearExisting) {
|
||||||
|
if (config.has(KEY_SOURCES) && config.get(KEY_SOURCES).isJsonArray()) {
|
||||||
|
if (clearExisting) {
|
||||||
|
this.sources.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray sourcesArray = config.getAsJsonArray(KEY_SOURCES);
|
||||||
|
for (JsonElement element : sourcesArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String source = element.getAsString();
|
||||||
|
if (!TextUtils.isEmpty(source) && !sources.contains(source)) {
|
||||||
|
sources.add(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidUrl(String url) {
|
||||||
|
return !TextUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (key == null || key.trim().isEmpty()) {
|
||||||
|
return Result.error("关键词不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
return performSearch(key, 1, DEFAULT_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String performSearch(String key, int page, int pageSize) throws Exception {
|
||||||
|
List<Vod> list = new ArrayList<>();
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("kw", key);
|
||||||
|
params.put("page", String.valueOf(page));
|
||||||
|
params.put("size", String.valueOf(pageSize));
|
||||||
|
|
||||||
|
for (String apiUrl : apiUrls) {
|
||||||
|
if (!isValidUrl(apiUrl)) continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
OkResult result = OkHttp.get(apiUrl, params, getHeader());
|
||||||
|
if (result.getCode() == 500 || TextUtils.isEmpty(result.getBody())) continue;
|
||||||
|
|
||||||
|
JsonObject jsonObject = Json.safeObject(result.getBody());
|
||||||
|
if (!jsonObject.has("code") || jsonObject.get("code").getAsInt() != 0 || !jsonObject.has("data"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JsonObject data = jsonObject.getAsJsonObject("data");
|
||||||
|
|
||||||
|
total = data.has("total") && !data.get("total").isJsonNull() ? data.get("total").getAsInt() : 0;
|
||||||
|
|
||||||
|
// 直接检查merged_by_type字段,无需三重判断
|
||||||
|
if (!data.has("merged_by_type") || !data.get("merged_by_type").isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject mergedByType = data.getAsJsonObject("merged_by_type");
|
||||||
|
|
||||||
|
for (Map.Entry<String, JsonElement> categoryEntry : mergedByType.entrySet()) {
|
||||||
|
if (!categoryEntry.getValue().isJsonArray()) continue;
|
||||||
|
|
||||||
|
JsonArray items = categoryEntry.getValue().getAsJsonArray();
|
||||||
|
|
||||||
|
for (JsonElement item : items) {
|
||||||
|
if (!item.isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject entry = item.getAsJsonObject();
|
||||||
|
|
||||||
|
String vodUrl = entry.has("url") && !entry.get("url").isJsonNull() ? entry.get("url").getAsString() : "";
|
||||||
|
if (TextUtils.isEmpty(vodUrl)) continue;
|
||||||
|
|
||||||
|
// 获取来源信息并映射
|
||||||
|
String originalSource = entry.has("source") && !entry.get("source").isJsonNull() ? entry.get("source").getAsString() : "未知来源";
|
||||||
|
String sourceName = mapSource(vodUrl, originalSource);
|
||||||
|
|
||||||
|
// 获取标题
|
||||||
|
String title = entry.has("note") && !entry.get("note").isJsonNull() ? entry.get("note").getAsString() : "未命名资源";
|
||||||
|
|
||||||
|
// 获取图片
|
||||||
|
String pic = getFirstImage(entry);
|
||||||
|
|
||||||
|
// 简化VodPlayBuilder的使用
|
||||||
|
Vod vod = new Vod(vodUrl, title, pic, sourceName + " (" + originalSource + ")");
|
||||||
|
// 由于只有一个播放源,直接设置播放信息
|
||||||
|
vod.setVodPlayFrom(sourceName);
|
||||||
|
vod.setVodPlayUrl("播放源$" + vodUrl);
|
||||||
|
|
||||||
|
// 来源过滤
|
||||||
|
if (sources.isEmpty() || sources.contains(sourceName)) {
|
||||||
|
list.add(vod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pageCount = total > 0 && pageSize > 0 ? (total + pageSize - 1) / pageSize : 1;
|
||||||
|
return Result.string(page, pageCount, pageSize, total, list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 出错时继续尝试下一个API
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.error("无法连接到任何搜索API");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取来源映射逻辑为单独方法
|
||||||
|
private String mapSource(String vodUrl, String originalSource) {
|
||||||
|
for (Map.Entry<String, String> domainEntry : domainMap.entrySet()) {
|
||||||
|
if (vodUrl.contains(domainEntry.getKey())) {
|
||||||
|
return domainEntry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取图片获取逻辑为单独方法
|
||||||
|
private String getFirstImage(JsonObject entry) {
|
||||||
|
if (entry.has("images") && !entry.get("images").isJsonNull() && entry.get("images").isJsonArray()) {
|
||||||
|
JsonArray images = entry.getAsJsonArray("images");
|
||||||
|
if (images.size() > 0 && !images.get(0).isJsonNull() && images.get(0).isJsonPrimitive()) {
|
||||||
|
return images.get(0).getAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,258 @@
|
||||||
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import com.github.catvod.bean.Result;
|
||||||
|
import com.github.catvod.bean.Vod;
|
||||||
|
import com.github.catvod.net.OkHttp;
|
||||||
|
import com.github.catvod.net.OkResult;
|
||||||
|
import com.github.catvod.utils.Json;
|
||||||
|
import com.github.catvod.utils.Util;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TgSearchQuark extends Cloud {
|
||||||
|
private static final String KEY_API_URLS = "api_urls";
|
||||||
|
private static final String KEY_DOMAIN_MAP = "siteurl";
|
||||||
|
private static final String KEY_SOURCES = "sources";
|
||||||
|
private static final int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
private List<String> apiUrls = new ArrayList<>();
|
||||||
|
private Map<String, String> domainMap = new HashMap<String, String>() {{
|
||||||
|
put("alipan", "阿里");
|
||||||
|
put("aliyundrive", "阿里");
|
||||||
|
put("quark", "夸克");
|
||||||
|
put("115cdn", "115");
|
||||||
|
put("baidu.com", "百度");
|
||||||
|
put("uc", "UC");
|
||||||
|
put("189.cn", "天翼");
|
||||||
|
put("139.com", "移动");
|
||||||
|
put("123", "123盘");
|
||||||
|
}};
|
||||||
|
private Set<String> sources = new HashSet<>();
|
||||||
|
private String[] extInfos = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(Context context, String extend) throws Exception {
|
||||||
|
super.init(context, extend);
|
||||||
|
|
||||||
|
this.apiUrls.clear();
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(extend)) {
|
||||||
|
try {
|
||||||
|
if (extend.contains("###")) {
|
||||||
|
String[] infos = extend.split("###");
|
||||||
|
this.extInfos = infos;
|
||||||
|
|
||||||
|
if (infos.length > 0 && !TextUtils.isEmpty(infos[0])) {
|
||||||
|
processExtendConfig(infos[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.extInfos = new String[]{extend};
|
||||||
|
processExtendConfig(extend);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.extInfos = null; // 重置,避免内存泄漏
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processExtendConfig(String config) {
|
||||||
|
try {
|
||||||
|
// 检查是否为HTTP URL
|
||||||
|
if (isValidUrl(config)) {
|
||||||
|
if (!this.apiUrls.contains(config)) {
|
||||||
|
this.apiUrls.add(config);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试JSON格式解析
|
||||||
|
JsonObject ext = Json.safeObject(config);
|
||||||
|
|
||||||
|
// 处理API URLs配置
|
||||||
|
processApiUrls(ext);
|
||||||
|
|
||||||
|
// 处理域名映射配置
|
||||||
|
processDomainMap(ext);
|
||||||
|
|
||||||
|
// 处理来源过滤配置
|
||||||
|
processSources(ext, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 可以添加日志记录
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processApiUrls(JsonObject config) {
|
||||||
|
if (config.has(KEY_API_URLS) && config.get(KEY_API_URLS).isJsonArray()) {
|
||||||
|
JsonArray urlsArray = config.getAsJsonArray(KEY_API_URLS);
|
||||||
|
for (JsonElement element : urlsArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String url = element.getAsString();
|
||||||
|
if (isValidUrl(url) && !this.apiUrls.contains(url)) {
|
||||||
|
this.apiUrls.add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDomainMap(JsonObject config) {
|
||||||
|
if (config.has(KEY_DOMAIN_MAP) && config.get(KEY_DOMAIN_MAP).isJsonObject()) {
|
||||||
|
JsonObject customDomains = config.getAsJsonObject(KEY_DOMAIN_MAP);
|
||||||
|
for (Map.Entry<String, JsonElement> entry : customDomains.entrySet()) {
|
||||||
|
if (entry == null || entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
String domain = entry.getKey();
|
||||||
|
String sourceName = "";
|
||||||
|
try {
|
||||||
|
sourceName = entry.getValue().getAsString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(sourceName) && !domainMap.containsKey(domain)) {
|
||||||
|
domainMap.put(domain, sourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSources(JsonObject config, boolean clearExisting) {
|
||||||
|
if (config.has(KEY_SOURCES) && config.get(KEY_SOURCES).isJsonArray()) {
|
||||||
|
if (clearExisting) {
|
||||||
|
this.sources.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray sourcesArray = config.getAsJsonArray(KEY_SOURCES);
|
||||||
|
for (JsonElement element : sourcesArray) {
|
||||||
|
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
|
||||||
|
String source = element.getAsString();
|
||||||
|
if (!TextUtils.isEmpty(source) && !sources.contains(source)) {
|
||||||
|
sources.add(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidUrl(String url) {
|
||||||
|
return !TextUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (key == null || key.trim().isEmpty()) {
|
||||||
|
return Result.error("关键词不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
return performSearch(key, 1, DEFAULT_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String performSearch(String key, int page, int pageSize) throws Exception {
|
||||||
|
List<Vod> list = new ArrayList<>();
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("kw", key);
|
||||||
|
params.put("page", String.valueOf(page));
|
||||||
|
params.put("size", String.valueOf(pageSize));
|
||||||
|
|
||||||
|
for (String apiUrl : apiUrls) {
|
||||||
|
if (!isValidUrl(apiUrl)) continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
OkResult result = OkHttp.get(apiUrl, params, getHeader());
|
||||||
|
if (result.getCode() == 500 || TextUtils.isEmpty(result.getBody())) continue;
|
||||||
|
|
||||||
|
JsonObject jsonObject = Json.safeObject(result.getBody());
|
||||||
|
if (!jsonObject.has("code") || jsonObject.get("code").getAsInt() != 0 || !jsonObject.has("data"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JsonObject data = jsonObject.getAsJsonObject("data");
|
||||||
|
|
||||||
|
total = data.has("total") && !data.get("total").isJsonNull() ? data.get("total").getAsInt() : 0;
|
||||||
|
|
||||||
|
// 直接检查merged_by_type字段,无需三重判断
|
||||||
|
if (!data.has("merged_by_type") || !data.get("merged_by_type").isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject mergedByType = data.getAsJsonObject("merged_by_type");
|
||||||
|
|
||||||
|
for (Map.Entry<String, JsonElement> categoryEntry : mergedByType.entrySet()) {
|
||||||
|
if (!categoryEntry.getValue().isJsonArray()) continue;
|
||||||
|
|
||||||
|
JsonArray items = categoryEntry.getValue().getAsJsonArray();
|
||||||
|
|
||||||
|
for (JsonElement item : items) {
|
||||||
|
if (!item.isJsonObject()) continue;
|
||||||
|
|
||||||
|
JsonObject entry = item.getAsJsonObject();
|
||||||
|
|
||||||
|
String vodUrl = entry.has("url") && !entry.get("url").isJsonNull() ? entry.get("url").getAsString() : "";
|
||||||
|
if (TextUtils.isEmpty(vodUrl)) continue;
|
||||||
|
|
||||||
|
// 获取来源信息并映射
|
||||||
|
String originalSource = entry.has("source") && !entry.get("source").isJsonNull() ? entry.get("source").getAsString() : "未知来源";
|
||||||
|
String sourceName = mapSource(vodUrl, originalSource);
|
||||||
|
|
||||||
|
// 获取标题
|
||||||
|
String title = entry.has("note") && !entry.get("note").isJsonNull() ? entry.get("note").getAsString() : "未命名资源";
|
||||||
|
|
||||||
|
// 获取图片
|
||||||
|
String pic = getFirstImage(entry);
|
||||||
|
|
||||||
|
// 简化VodPlayBuilder的使用
|
||||||
|
Vod vod = new Vod(vodUrl, title, pic, sourceName + " (" + originalSource + ")");
|
||||||
|
// 由于只有一个播放源,直接设置播放信息
|
||||||
|
vod.setVodPlayFrom(sourceName);
|
||||||
|
vod.setVodPlayUrl("播放源$" + vodUrl);
|
||||||
|
|
||||||
|
// 来源过滤
|
||||||
|
if (sources.isEmpty() || sources.contains(sourceName)) {
|
||||||
|
list.add(vod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pageCount = total > 0 && pageSize > 0 ? (total + pageSize - 1) / pageSize : 1;
|
||||||
|
return Result.string(page, pageCount, pageSize, total, list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 出错时继续尝试下一个API
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.error("无法连接到任何搜索API");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取来源映射逻辑为单独方法
|
||||||
|
private String mapSource(String vodUrl, String originalSource) {
|
||||||
|
for (Map.Entry<String, String> domainEntry : domainMap.entrySet()) {
|
||||||
|
if (vodUrl.contains(domainEntry.getKey())) {
|
||||||
|
return domainEntry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取图片获取逻辑为单独方法
|
||||||
|
private String getFirstImage(JsonObject entry) {
|
||||||
|
if (entry.has("images") && !entry.get("images").isJsonNull() && entry.get("images").isJsonArray()) {
|
||||||
|
JsonArray images = entry.getAsJsonArray("images");
|
||||||
|
if (images.size() > 0 && !images.get(0).isJsonNull() && images.get(0).isJsonPrimitive()) {
|
||||||
|
return images.get(0).getAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ public class QuarkTest {
|
||||||
Init.init(mockContext);
|
Init.init(mockContext);
|
||||||
spider = new Quark();
|
spider = new Quark();
|
||||||
// spider.init(mockContext, "b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; _UP_A4A_11_=wb9661c6dfb642f88f73d8e0c7edd398; b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; ctoken=wla6p3EUOLyn1FSB8IKp1SEW; grey-id=5583e32b-39df-4bf0-f39f-1adf83f604a2; grey-id.sig=p8ReBIMG2BeZu1sYvsuOAZxYbx-MVrsfKEiCv87MsTM; isQuark=true; isQuark.sig=hUgqObykqFom5Y09bll94T1sS9abT1X-4Df_lzgl8nM; _UP_F7E_8D_=ZkyvVHnrBLp1A1NFJIjWi0PwKLOVbxJPcg0RzQPI6KmBtV6ZMgPh38l93pgubgHDQqhaZ2Sfc0qv%2BRantbfg1mWGAUpRMP4RqXP78Wvu%2FCfvkWWGc5NhCTV71tGOIGgDBR3%2Bu6%2Fjj44KlE5biSNDOWW7Bigcz27lvOTidzNw8s%2FWtKAIxWbnCzZn4%2FJMBUub1SIMcW89g57k4mfPmDlCgpZKzxwl6beSfdtZ4RUWXmZOn5v5NkxVKhU4wR0Pq7NklczEGdRq2nIAcu7v22Uw2o%2FxMY0xBdeC9Korm5%2FNHnxl6K%2Bd6FXSoT9a3XIMQO359auZPiZWzrNlZe%2BqnOahXcx7KAhQIRqSOapSmL4ygJor4r5isJhRuDoXy7vJAVuH%2FRDtEJJ8rZTq0BdC23Bz%2B0MrsdgbK%2BiW; _UP_D_=pc; __wpkreporterwid_=3d3f74a7-99b7-4916-3f78-911fc2eb9d87; tfstk=fIoZNxjnbhKwPOu0TWZ4LsaRqirTcudSSmNbnxD0C5VgClMm8xMyB-GsnSu4tjpOflAOmSD-9PNiGl120XrgkVNb1SrqHbJBN3tSBAEYoQOWVUUg9qZ8n1bGGkD3CqGYINKSBABhjnXgp3_Vywz6gSc0Syj3BWf0mr2DLW24eZfiiovEKWefj1q0swq3E82iNEMinMy7SLrcpA4Fh3z_ZAViCfih3PbtdW5N_DuU77AaTijmYRkL2Wq54ENoy5a7ZXxCbok33XzS7QSZgxD-oyoVsdGotql0p2dVu7umC4nLStbiLmParc4FELHrI-c0u2dPVRrs8zoZWKCnIbNZrlHfUCMUz2z8KyXVSlgSFmUojh58OzeqTzgwaGll4YCYKwctDV5coP2LL79eKHxpNTXHmre1kZU32JPWCR_AkP2LL79eLZQY-WeUNdw1.; __pus=2051c82285199d8be553be41dd5a2100AAQ+mmv35G4FDDZ5x+3Mhe2OMbNgweQ1ODbW8zDt9YuP1LQVqHUuAAz9KWLsPjpNtim0AVGHusN4MCosTmbq/khM; __kp=e6604120-6051-11ef-bfe4-c31b6cdd0766; __kps=AATcZArVgS76EPn0FMaV4HEj; __ktd=sii/iz4ePzEaoVirXul7QQ==; __uid=AATcZArVgS76EPn0FMaV4HEj; __itrace_wid=5829b95d-dac1-48d3-bfd5-f60cd9462786; __puus=7da0b96cb710fa1b376934485f977e05AATp/q8/QupT7IiBR1GWqZhxlIRT677smMvoHlLxQA0Lk6CkP0YJBOTl+p9DZgzlMz6w4hPXPgWsokukk8PW7ZfhFfPmv8tKMgLpCGLW+tk57luhNghmSdTeVPkAF59STtyCPBEtiNzNAd/zZJ6qILJDi5ywEBAAAg+gOyWHoLHNUR+QxeHRuQa8g5WWA95J8jebIlrr8rCvI1vjTbtiYktT");
|
// spider.init(mockContext, "b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; _UP_A4A_11_=wb9661c6dfb642f88f73d8e0c7edd398; b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; ctoken=wla6p3EUOLyn1FSB8IKp1SEW; grey-id=5583e32b-39df-4bf0-f39f-1adf83f604a2; grey-id.sig=p8ReBIMG2BeZu1sYvsuOAZxYbx-MVrsfKEiCv87MsTM; isQuark=true; isQuark.sig=hUgqObykqFom5Y09bll94T1sS9abT1X-4Df_lzgl8nM; _UP_F7E_8D_=ZkyvVHnrBLp1A1NFJIjWi0PwKLOVbxJPcg0RzQPI6KmBtV6ZMgPh38l93pgubgHDQqhaZ2Sfc0qv%2BRantbfg1mWGAUpRMP4RqXP78Wvu%2FCfvkWWGc5NhCTV71tGOIGgDBR3%2Bu6%2Fjj44KlE5biSNDOWW7Bigcz27lvOTidzNw8s%2FWtKAIxWbnCzZn4%2FJMBUub1SIMcW89g57k4mfPmDlCgpZKzxwl6beSfdtZ4RUWXmZOn5v5NkxVKhU4wR0Pq7NklczEGdRq2nIAcu7v22Uw2o%2FxMY0xBdeC9Korm5%2FNHnxl6K%2Bd6FXSoT9a3XIMQO359auZPiZWzrNlZe%2BqnOahXcx7KAhQIRqSOapSmL4ygJor4r5isJhRuDoXy7vJAVuH%2FRDtEJJ8rZTq0BdC23Bz%2B0MrsdgbK%2BiW; _UP_D_=pc; __wpkreporterwid_=3d3f74a7-99b7-4916-3f78-911fc2eb9d87; tfstk=fIoZNxjnbhKwPOu0TWZ4LsaRqirTcudSSmNbnxD0C5VgClMm8xMyB-GsnSu4tjpOflAOmSD-9PNiGl120XrgkVNb1SrqHbJBN3tSBAEYoQOWVUUg9qZ8n1bGGkD3CqGYINKSBABhjnXgp3_Vywz6gSc0Syj3BWf0mr2DLW24eZfiiovEKWefj1q0swq3E82iNEMinMy7SLrcpA4Fh3z_ZAViCfih3PbtdW5N_DuU77AaTijmYRkL2Wq54ENoy5a7ZXxCbok33XzS7QSZgxD-oyoVsdGotql0p2dVu7umC4nLStbiLmParc4FELHrI-c0u2dPVRrs8zoZWKCnIbNZrlHfUCMUz2z8KyXVSlgSFmUojh58OzeqTzgwaGll4YCYKwctDV5coP2LL79eKHxpNTXHmre1kZU32JPWCR_AkP2LL79eLZQY-WeUNdw1.; __pus=2051c82285199d8be553be41dd5a2100AAQ+mmv35G4FDDZ5x+3Mhe2OMbNgweQ1ODbW8zDt9YuP1LQVqHUuAAz9KWLsPjpNtim0AVGHusN4MCosTmbq/khM; __kp=e6604120-6051-11ef-bfe4-c31b6cdd0766; __kps=AATcZArVgS76EPn0FMaV4HEj; __ktd=sii/iz4ePzEaoVirXul7QQ==; __uid=AATcZArVgS76EPn0FMaV4HEj; __itrace_wid=5829b95d-dac1-48d3-bfd5-f60cd9462786; __puus=7da0b96cb710fa1b376934485f977e05AATp/q8/QupT7IiBR1GWqZhxlIRT677smMvoHlLxQA0Lk6CkP0YJBOTl+p9DZgzlMz6w4hPXPgWsokukk8PW7ZfhFfPmv8tKMgLpCGLW+tk57luhNghmSdTeVPkAF59STtyCPBEtiNzNAd/zZJ6qILJDi5ywEBAAAg+gOyWHoLHNUR+QxeHRuQa8g5WWA95J8jebIlrr8rCvI1vjTbtiYktT");
|
||||||
spider.init(mockContext, "_UP_A4A_11_=wb9681fbaed6454a8112f31e53b5c0be; __pus=45beefa93e8775c9211487d0c8ddd2b1AASCmV5S7LY0dfX90N3p4wU/G4f/oS0gZK6cpxZMZiDtXt9s7KiSs3tVZOXnIDel69C9KaQ61IQlnLYH2rS4NGjO; __kp=fe663a90-68d5-11ef-8b23-e77b0eaa352c; __kps=AAT32Fob+vq66znO5UHSHAPi; __ktd=39oXE+BT53YlFgUfFVq9kw==; __uid=AAT32Fob+vq66znO5UHSHAPi; xlly_s=1; b-user-id=91d551ad-db9e-f092-2b42-aa4db35b8ed0; isg=BNXVFRgkH_dXwTuJ8PizGl2W5NGP0onkjXrhLld60cybrvegHyMutYcsfLIYrqGc; tfstk=fNlSqGqmrgj57RpyCwL4hfk8bfFCODOw9waKS2CPJ7F-JWib0zWyEJ-IhDn42_P82ZEQ7caRpHf8M9aTxuFEUuzKc2nJry8uwiCY7PzLvzeLHsUUP6Ud9WQoncuOabJuT6NutWKwbCRZz4V39rUtZ-SukyUWT_U8JbtmmvxwbCR2eZFBVhkeml_RcyqYyzEdwENYSyFdv_nLD-UT7gFKvWLbHy4G2aCLJoUYJoEL9WnKkjXR5y97q4TY2O9qutVEyo1soja-eT0zc6CKGxw7XBrf96hbPqfsiZf6LlHg4RrtDI57OqUIcRkWf_iIJVDLhXsJzcnxdDUmnH6Qfv3rIj2RJT3jOuwtw-_9SVg8JDeInh1aP7kbCbMk-i3-buMTZ2764qwshR4YHw68aAuZtRhJNGq4IyibQYt1NcIzH1r_KcBClRfQll8Xl9Xh_6YQJFIaDQy8ozw2lEs-K8U0ll8Xl9X3er477ETf2vf..; __puus=514ad4334da84f912529719d557085b2AASV1aKJKLRXGjvHRfwQJ5gupjOzlxgeAImozKKYdppZduMrKS7Q5+3hUZZ0f6zk7YpAGu7p0GVPYojTpZdhvnamXzCBLryM3ULhlqkw9yR6oVeTr3b1MituYgqfeFM4jHi4ASNiLk22pCNKteAtD6aowAM0K1ZFVc7j7xlpxLEgS1CoNSttupAb56Zf+ruuTkDPsjZPiRW1S4yM/kduA247");
|
spider.init(mockContext, "_UP_28A_52_=386;_UP_BT_=html5;_UP_F7E_8D_=0z44HdIBxZZTFH3p1NV%2FwWJIkAWBTYaH20RoPCksvMmyhI6XxrMIHoi8gAqVoKf%2Bfw0hw4mmmcFLHpvA%2Fhicy1HUTu2LBlCP6GF%2FnM%2Bm0IJoj1BQdak3tm1o3OeN1OV9dQAEQ0UDfWTXDik4ZZxmO5Iwvj6IsFkb5GPrrCl5M87ivs0EP%2FjAQTQimMgEdat62Byd22%2BZGM703ymU3s8N9B3XRdiyy8E7vOTidzNw8s%2FWtKAIxWbnCzZn4%2FJMBUubLuroBmVIB9UVOMEdD6uzZJXMxBnUatpyAHLu79tlMNqP8TGNMQXXgvSqK5ufzR58ZeivnehV0qE%2FWt1yDEDt%2BfWrmT4mVs6zZWXvqpzmoV3MeygIUCEakh2GAn6rsLT1b2ZsrSkQkrM6F8u7yQFbh%2F0Q7RCSfK2U6tAXQttwc%2FtDK7HYGyvolg%3D%3D;_UP_6D1_64_=069;_UP_A4A_11_=wb9cc1693e1d486b8b2ac58e4839d64e;_UP_D_=mobilectoken=4IUaeDKAfn3pV-MKaWfg_GHG;__pus=76f683009a07bdd1c1a7c04f05838d4bAASVSWCD2jiL0GI43jmIC5x50sk6Tgbh4UtXFf/vqOUyaX8Aory/bsGsGCTl68Lo7sJPpZpBJdif81oItfZizhzH;__kp=d8da7a20-7522-11f0-8e98-7daef001221f;__kps=AATcZArVgS76EPn0FMaV4HEj;__ktd=sii/iz4ePzEaoVirXul7QQ==;__uid=AATcZArVgS76EPn0FMaV4HEj;__puus=b4617d4cdadeb05679ed39be924d99d8AATp/q8/QupT7IiBR1GWqZhx6c42nqKQR/5g49EMGJ5TE742htjk9EkPPibrpvSh8/N8ybuC/Wc4BP1YbLBb5ZFEEOPrmFBTCZtKVEh5HcqkSL6T6LoyeKfvGe32k9HckqoPn9MxbAThhpRlbHg8QgH8OwxLHp0V2cAYcsGY72XN2ZPL7JzZyOAwmSsJwpX9B0+LYNvco+Ixucn5KaaCTKND");
|
||||||
Server.get().start();
|
Server.get().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class QuarkTest {
|
||||||
@org.junit.Test
|
@org.junit.Test
|
||||||
public void detailContent() throws Exception {
|
public void detailContent() throws Exception {
|
||||||
|
|
||||||
String content = spider.detailContent(Arrays.asList("https://pan.quark.cn/s/38c5e16d71f7"));
|
String content = spider.detailContent(Arrays.asList("https://pan.quark.cn/s/469c2acf8640"));
|
||||||
System.out.println("detailContent--" + content);
|
System.out.println("detailContent--" + content);
|
||||||
JsonObject map = Json.safeObject(content);
|
JsonObject map = Json.safeObject(content);
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
@ -52,7 +52,7 @@ public class QuarkTest {
|
||||||
@org.junit.Test
|
@org.junit.Test
|
||||||
public void playerContent() throws Exception {
|
public void playerContent() throws Exception {
|
||||||
|
|
||||||
String content = spider.playerContent("普画","41ea9a50cbdd4e50b019bcd78687ebc1++22fc6fa8350d22e0eaecc49035368e81++38c5e16d71f7++WFcYTmRhjJpKTui56aleYdzBZi9R203GERBVzYNxDxI=",new ArrayList<>());
|
String content = spider.playerContent("quark原画","a04522f504a742db8ebaf69e3b7f50d6++cf35e6096b5be563ed747a4538ceab60++469c2acf8640++lbhatsGLyszqGYVHwO+DJPeyRkwbsCr7JzcoZhPVYBI=",new ArrayList<>());
|
||||||
System.out.println("playerContent--" + content);
|
System.out.println("playerContent--" + content);
|
||||||
JsonObject map = Json.safeObject(content);
|
JsonObject map = Json.safeObject(content);
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
|
||||||
|
|
@ -101,32 +101,23 @@
|
||||||
"searchable": 1,
|
"searchable": 1,
|
||||||
"changeable": 1,
|
"changeable": 1,
|
||||||
"ext": {}
|
"ext": {}
|
||||||
},{
|
}, {
|
||||||
"key": "TgSearch",
|
"key": "TgSearchQuark",
|
||||||
"name": "TgSearch|Pan",
|
"name": "☁TgSearchQuark┃网盘",
|
||||||
"type": 3,
|
"type": 3,
|
||||||
"api": "csp_TgSearch",
|
"api": "csp_TgSearchQuark",
|
||||||
"searchable": 1,
|
"searchable": 1,
|
||||||
"changeable": 1,
|
"filterable": 0,
|
||||||
"ext": {}
|
"ext": {
|
||||||
},
|
"api_urls": [
|
||||||
{
|
"https://psweb.banye.tech:7777/api/search",
|
||||||
"key": "TgQuarkSearch",
|
"https://so.566987.xyz/api/search",
|
||||||
"name": "TgQuarkSearch|Pan",
|
"http://152.69.222.142:8088/api/search"
|
||||||
"type": 3,
|
],
|
||||||
"api": "csp_TgQuarkSearch",
|
"sources": [
|
||||||
"searchable": 1,
|
"夸克"
|
||||||
"changeable": 1,
|
]
|
||||||
"ext": {}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Tg189Search",
|
|
||||||
"name": "Tg189Search|Pan",
|
|
||||||
"type": 3,
|
|
||||||
"api": "csp_Tg189Search",
|
|
||||||
"searchable": 1,
|
|
||||||
"changeable": 1,
|
|
||||||
"ext": {}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "TgSearchBaidu",
|
"key": "TgSearchBaidu",
|
||||||
|
|
@ -142,7 +133,60 @@
|
||||||
"http://152.69.222.142:8088/api/search"
|
"http://152.69.222.142:8088/api/search"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"夸克", "百度","123盘","天翼","移动"
|
"百度"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TgSearch123",
|
||||||
|
"name": "☁TgSearch123┃网盘",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_TgSearch123",
|
||||||
|
"searchable": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": {
|
||||||
|
"api_urls": [
|
||||||
|
"https://psweb.banye.tech:7777/api/search",
|
||||||
|
"https://so.566987.xyz/api/search",
|
||||||
|
"http://152.69.222.142:8088/api/search"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
"123盘"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TgSearch189",
|
||||||
|
"name": "☁TgSearch189┃网盘",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_TgSearch189",
|
||||||
|
"searchable": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": {
|
||||||
|
"api_urls": [
|
||||||
|
"https://psweb.banye.tech:7777/api/search",
|
||||||
|
"https://so.566987.xyz/api/search",
|
||||||
|
"http://152.69.222.142:8088/api/search"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
"天翼"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"key": "TgSearch139",
|
||||||
|
"name": "☁TgSearch139┃网盘",
|
||||||
|
"type": 3,
|
||||||
|
"api": "csp_TgSearch139",
|
||||||
|
"searchable": 1,
|
||||||
|
"filterable": 0,
|
||||||
|
"ext": {
|
||||||
|
"api_urls": [
|
||||||
|
"https://psweb.banye.tech:7777/api/search",
|
||||||
|
"https://so.566987.xyz/api/search",
|
||||||
|
"http://152.69.222.142:8088/api/search"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
"移动"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue