mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 20:33:03 +00:00
1. 缓存优化
This commit is contained in:
@@ -66,7 +66,7 @@ public class ShareLinkInfo {
|
||||
// 建造者类
|
||||
public static class Builder {
|
||||
private String shareKey; // 分享键
|
||||
private String type; // 分享类型
|
||||
private String type; // 分享类型 (网盘模板枚举的小写)
|
||||
private String sharePassword = ""; // 分享密码(如果存在)
|
||||
private String shareUrl; // 原始分享链接
|
||||
private String standardUrl; // 规范化的标准链接
|
||||
|
||||
@@ -4,28 +4,4 @@ import io.vertx.core.Future;
|
||||
|
||||
public interface IPanTool {
|
||||
Future<String> parse();
|
||||
// 基于枚举PanDomainTemplate匹配分享链接类型
|
||||
static IPanTool typeMatching(String type, String key, String pwd) {
|
||||
try {
|
||||
return PanDomainTemplate
|
||||
.fromShortName(type)
|
||||
.generateShareLink(key)
|
||||
.setShareLinkInfoPwd(pwd)
|
||||
.createTool();
|
||||
} catch (Exception e) {
|
||||
throw new UnsupportedOperationException("未知分享类型", e);
|
||||
}
|
||||
}
|
||||
|
||||
static IPanTool shareURLPrefixMatching(String url, String pwd) {
|
||||
try {
|
||||
return PanDomainTemplate
|
||||
.fromShareUrl(url)
|
||||
.setShareLinkInfoPwd(pwd)
|
||||
.createTool();
|
||||
} catch (Exception e) {
|
||||
throw new UnsupportedOperationException("未知分享类型", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
package cn.qaiu.parser;
|
||||
|
||||
import cn.qaiu.entity.ShareLinkInfo;
|
||||
import cn.qaiu.parser.impl.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 枚举类 PanDomainTemplate 定义了不同网盘服务的模板信息,包括:
|
||||
* <ul>
|
||||
* <li>displayName: 网盘服务的显示名称,用于用户界面展示。</li>
|
||||
* <li>shortName: 网盘服务的简称,用于内部逻辑处理,例如API路径。</li>
|
||||
* <li>regexPattern: 用于匹配和解析分享链接的正则表达式。</li>
|
||||
* <li>standardUrlTemplate: 网盘服务的标准URL模板,用于规范化分享链接。</li>
|
||||
* <li>toolClass: 网盘解析工具实现类。</li>
|
||||
* </ul>
|
||||
* 该类提供方法来解析和规范化不同来源的分享链接,确保它们可以转换为统一的标准链接格式。
|
||||
* 通过这种方式,应用程序可以更容易地处理和识别不同网盘服务的分享链接.
|
||||
*
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
* at 2023/6/13 4:26
|
||||
@@ -26,7 +18,6 @@ public enum PanDomainTemplate {
|
||||
|
||||
// 网盘定义
|
||||
LZ("蓝奏云",
|
||||
"lz",
|
||||
"https://([a-z]+)?\\.?lanzou[a-z]\\.com/(.+/)?(.+)",
|
||||
"https://lanzoux.com/{shareKey}",
|
||||
LzTool.class),
|
||||
@@ -34,64 +25,54 @@ public enum PanDomainTemplate {
|
||||
// https://www.feijix.com/s/
|
||||
// https://share.feijipan.com/s/
|
||||
FJ("小飞机网盘",
|
||||
"fj",
|
||||
"https://(share\\.feijipan\\.com|www\\.feijix\\.com)/s/(.+)",
|
||||
"https://www.feijix.com/s/{shareKey}",
|
||||
FjTool.class),
|
||||
|
||||
// https://lecloud.lenovo.com/share/
|
||||
LE("联想乐云",
|
||||
"le",
|
||||
"https://lecloud?\\.lenovo\\.com/share/(.+)",
|
||||
"https://lecloud.lenovo.com/share/{shareKey}",
|
||||
LeTool.class),
|
||||
|
||||
// https://v2.fangcloud.com/s/
|
||||
FC("亿方云",
|
||||
"fc",
|
||||
"https://v2\\.fangcloud\\.(com|cn)/(s|sharing)/([^/]+)",
|
||||
"https://v2.fangcloud.com/s/{shareKey}",
|
||||
FcTool.class),
|
||||
// https://www.ilanzou.com/s/
|
||||
IZ("蓝奏云优享",
|
||||
"iz",
|
||||
"https://www\\.ilanzou\\.com/s/(.+)",
|
||||
"https://www.ilanzou.com/s/{shareKey}",
|
||||
IzTool.class),
|
||||
// https://wx.mail.qq.com/ftn/download?
|
||||
QQ("QQ邮箱中转站",
|
||||
"qq",
|
||||
"https://i?wx\\.mail\\.qq\\.com/ftn/download\\?(.+)",
|
||||
"https://iwx.mail.qq.com/ftn/download/{shareKey}",
|
||||
QQTool.class),
|
||||
// https://f.ws59.cn/f/或者https://www.wenshushu.cn/f/
|
||||
WS("文叔叔",
|
||||
"ws",
|
||||
"https://(f\\.ws59\\.cn|www\\.wenshushu\\.cn)/f/(.+)",
|
||||
"https://f.ws59.cn/f/{shareKey}",
|
||||
WsTool.class),
|
||||
// https://www.123pan.com/s/
|
||||
YE("123网盘",
|
||||
"ye",
|
||||
"https://www\\.123pan\\.com/s/(.+)\\.html",
|
||||
"https://www.123pan.com/s/{shareKey}.html",
|
||||
YeTool.class),
|
||||
// https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data={code}&isShare=1
|
||||
EC("移动云空间",
|
||||
"ec",
|
||||
"https://www\\.ecpan\\.cn/web(/%23|/#)?/yunpanProxy\\?path=.*&data=" +
|
||||
"([^&]+)&isShare=1",
|
||||
"https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data={shareKey}&isShare=1",
|
||||
EcTool.class),
|
||||
// https://cowtransfer.com/s/
|
||||
COW("奶牛快传",
|
||||
"cow",
|
||||
"https://(.*)cowtransfer\\.com/s/(.+)",
|
||||
"https://cowtransfer.com/s/{shareKey}",
|
||||
CowTool.class),
|
||||
// https://pan.huang1111.cn/s/
|
||||
CE("huang1111",
|
||||
"ce",
|
||||
"https://pan\\.huang1111\\.cn/s/(.+)",
|
||||
"https://pan.huang1111.cn/s/{shareKey}",
|
||||
CeTool.class);
|
||||
@@ -100,79 +81,25 @@ public enum PanDomainTemplate {
|
||||
// 网盘的显示名称,用于用户界面显示
|
||||
private final String displayName;
|
||||
|
||||
// 网盘的简短名称,用于内部逻辑处理,如REST API路径
|
||||
private final String shortName;
|
||||
|
||||
// 用于匹配和解析分享链接的正则表达式
|
||||
private final String regexPattern;
|
||||
|
||||
// 网盘的标准链接模板,不含占位符,用于规范化分享链接
|
||||
private final String standardUrlTemplate;
|
||||
private final ShareLinkInfo shareLinkInfo;
|
||||
// 指向IPanTool实现类
|
||||
|
||||
// 指向解析工具IPanTool实现类
|
||||
private final Class<? extends IPanTool> toolClass;
|
||||
|
||||
PanDomainTemplate(String displayName, String shortName, String regexPattern,
|
||||
String standardUrlTemplate, Class<? extends IPanTool> toolClass) {
|
||||
PanDomainTemplate(String displayName, String regexPattern, String standardUrlTemplate,
|
||||
Class<? extends IPanTool> toolClass) {
|
||||
this.displayName = displayName;
|
||||
this.shortName = shortName;
|
||||
this.regexPattern = regexPattern;
|
||||
this.standardUrlTemplate = standardUrlTemplate;
|
||||
this.toolClass = toolClass;
|
||||
this.shareLinkInfo = ShareLinkInfo.newBuilder().type(shortName).build();
|
||||
}
|
||||
|
||||
|
||||
// 解析并规范化分享链接
|
||||
synchronized public PanDomainTemplate normalizeShareLink() {
|
||||
if (shareLinkInfo == null) {
|
||||
throw new IllegalArgumentException("ShareLinkInfo not init");
|
||||
}
|
||||
// 匹配并提取shareKey
|
||||
String shareUrl = shareLinkInfo.getShareUrl();
|
||||
if (StringUtils.isEmpty(shareUrl)) {
|
||||
throw new IllegalArgumentException("ShareLinkInfo shareUrl is empty");
|
||||
}
|
||||
Pattern pattern = Pattern.compile(regexPattern);
|
||||
Matcher matcher = pattern.matcher(shareUrl);
|
||||
if (matcher.find()) {
|
||||
String shareKey = matcher.group(matcher.groupCount());
|
||||
// 返回规范化的标准链接
|
||||
String standardUrl = standardUrlTemplate.replace("{shareKey}", shareKey);
|
||||
shareLinkInfo.setShareUrl(shareUrl);
|
||||
shareLinkInfo.setShareKey(shareKey);
|
||||
shareLinkInfo.setStandardUrl(standardUrl);
|
||||
return this;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid share URL for " + displayName);
|
||||
}
|
||||
|
||||
public IPanTool createTool() {
|
||||
if (shareLinkInfo == null || StringUtils.isEmpty(shareLinkInfo.getType())) {
|
||||
throw new IllegalArgumentException("ShareLinkInfo not init or type is empty");
|
||||
}
|
||||
if (StringUtils.isEmpty(shareLinkInfo.getShareKey())) {
|
||||
this.normalizeShareLink();
|
||||
}
|
||||
try {
|
||||
return toolClass
|
||||
.getDeclaredConstructor(ShareLinkInfo.class)
|
||||
.newInstance(shareLinkInfo);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("无法创建工具实例: " + toolClass.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成分享链接的方法
|
||||
synchronized public PanDomainTemplate generateShareLink(String shareKey) {
|
||||
shareLinkInfo.setShareKey(shareKey);
|
||||
shareLinkInfo.setStandardUrl(standardUrlTemplate.replace("{shareKey}", shareKey));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public String getDisplayName() {
|
||||
return this.displayName;
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getRegexPattern() {
|
||||
@@ -183,43 +110,7 @@ public enum PanDomainTemplate {
|
||||
return standardUrlTemplate;
|
||||
}
|
||||
|
||||
|
||||
public ShareLinkInfo getShareLinkInfo() {
|
||||
return shareLinkInfo;
|
||||
}
|
||||
|
||||
synchronized public PanDomainTemplate setShareLinkInfoPwd(String pwd) {
|
||||
shareLinkInfo.setSharePassword(pwd);
|
||||
return this;
|
||||
}
|
||||
|
||||
synchronized public PanDomainTemplate setShareLinkInfoUrl(String pwd) {
|
||||
shareLinkInfo.setSharePassword(pwd);
|
||||
return this;
|
||||
}
|
||||
|
||||
// 根据分享链接获取PanDomainTemplate实例
|
||||
synchronized public static PanDomainTemplate fromShareUrl(String shareUrl) {
|
||||
for (PanDomainTemplate template : values()) {
|
||||
if (shareUrl.matches(template.regexPattern)) {
|
||||
template.getShareLinkInfo().setShareUrl(shareUrl);
|
||||
return template.normalizeShareLink();
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported share URL");
|
||||
}
|
||||
|
||||
// 根据shortName获取枚举实例
|
||||
public static PanDomainTemplate fromShortName(String shortName) {
|
||||
try {
|
||||
return Enum.valueOf(PanDomainTemplate.class, shortName.toUpperCase());
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
// 如果没有找到对应的枚举实例,抛出异常
|
||||
throw new IllegalArgumentException("No enum constant for short name: " + shortName);
|
||||
}
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
public Class<? extends IPanTool> getToolClass() {
|
||||
return toolClass;
|
||||
}
|
||||
}
|
||||
|
||||
113
parser/src/main/java/cn/qaiu/parser/ParserCreate.java
Normal file
113
parser/src/main/java/cn/qaiu/parser/ParserCreate.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package cn.qaiu.parser;
|
||||
|
||||
import cn.qaiu.entity.ShareLinkInfo;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* 该类提供方法来解析和规范化不同来源的分享链接,确保它们可以转换为统一的标准链接格式。
|
||||
* 通过这种方式,应用程序可以更容易地处理和识别不同网盘服务的分享链接。
|
||||
*
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
* @date 2024/9/15 14:10
|
||||
*/
|
||||
public class ParserCreate {
|
||||
private final PanDomainTemplate panDomainTemplate;
|
||||
private final ShareLinkInfo shareLinkInfo;
|
||||
|
||||
public ParserCreate(PanDomainTemplate panDomainTemplate, ShareLinkInfo shareLinkInfo) {
|
||||
this.panDomainTemplate = panDomainTemplate;
|
||||
this.shareLinkInfo = shareLinkInfo;
|
||||
}
|
||||
|
||||
|
||||
// 解析并规范化分享链接
|
||||
public ParserCreate normalizeShareLink() {
|
||||
if (shareLinkInfo == null) {
|
||||
throw new IllegalArgumentException("ShareLinkInfo not init");
|
||||
}
|
||||
// 匹配并提取shareKey
|
||||
String shareUrl = shareLinkInfo.getShareUrl();
|
||||
if (StringUtils.isEmpty(shareUrl)) {
|
||||
throw new IllegalArgumentException("ShareLinkInfo shareUrl is empty");
|
||||
}
|
||||
Pattern pattern = Pattern.compile(this.panDomainTemplate.getRegexPattern());
|
||||
Matcher matcher = pattern.matcher(shareUrl);
|
||||
if (matcher.find()) {
|
||||
String shareKey = matcher.group(matcher.groupCount());
|
||||
// 返回规范化的标准链接
|
||||
String standardUrl = getStandardUrlTemplate().replace("{shareKey}", shareKey);
|
||||
shareLinkInfo.setShareUrl(shareUrl);
|
||||
shareLinkInfo.setShareKey(shareKey);
|
||||
shareLinkInfo.setStandardUrl(standardUrl);
|
||||
return this;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid share URL for " + this.panDomainTemplate.getDisplayName());
|
||||
}
|
||||
|
||||
public IPanTool createTool() {
|
||||
if (shareLinkInfo == null || StringUtils.isEmpty(shareLinkInfo.getType())) {
|
||||
throw new IllegalArgumentException("ShareLinkInfo not init or type is empty");
|
||||
}
|
||||
if (StringUtils.isEmpty(shareLinkInfo.getShareKey())) {
|
||||
this.normalizeShareLink();
|
||||
}
|
||||
try {
|
||||
return this.panDomainTemplate.getToolClass()
|
||||
.getDeclaredConstructor(ShareLinkInfo.class)
|
||||
.newInstance(shareLinkInfo);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("无法创建工具实例: " + panDomainTemplate.getToolClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// set share key
|
||||
public ParserCreate shareKey(String shareKey) {
|
||||
shareLinkInfo.setShareKey(shareKey);
|
||||
shareLinkInfo.setStandardUrl(panDomainTemplate.getStandardUrlTemplate().replace("{shareKey}", shareKey));
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getStandardUrlTemplate() {
|
||||
return this.panDomainTemplate.getStandardUrlTemplate();
|
||||
}
|
||||
|
||||
public ShareLinkInfo getShareLinkInfo() {
|
||||
return shareLinkInfo;
|
||||
}
|
||||
|
||||
public ParserCreate setShareLinkInfoPwd(String pwd) {
|
||||
shareLinkInfo.setSharePassword(pwd);
|
||||
return this;
|
||||
}
|
||||
|
||||
// 根据分享链接获取PanDomainTemplate实例
|
||||
public synchronized static ParserCreate fromShareUrl(String shareUrl) {
|
||||
for (PanDomainTemplate panDomainTemplate : PanDomainTemplate.values()) {
|
||||
if (shareUrl.matches(panDomainTemplate.getRegexPattern())) {
|
||||
ShareLinkInfo shareLinkInfo = ShareLinkInfo.newBuilder()
|
||||
.type(panDomainTemplate.name().toLowerCase())
|
||||
.shareUrl(shareUrl).build();
|
||||
ParserCreate parserCreate = new ParserCreate(panDomainTemplate, shareLinkInfo);
|
||||
return parserCreate.normalizeShareLink();
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported share URL");
|
||||
}
|
||||
|
||||
// 根据type获取枚举实例
|
||||
public synchronized static ParserCreate fromType(String type) {
|
||||
try {
|
||||
PanDomainTemplate panDomainTemplate = Enum.valueOf(PanDomainTemplate.class, type.toUpperCase());
|
||||
ShareLinkInfo shareLinkInfo = ShareLinkInfo.newBuilder()
|
||||
.type(type.toLowerCase()).build();
|
||||
return new ParserCreate(panDomainTemplate, shareLinkInfo);
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
// 如果没有找到对应的枚举实例,抛出异常
|
||||
throw new IllegalArgumentException("No enum constant for type name: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,15 +19,15 @@ public class PanDomainTemplateTest {
|
||||
// 准备测试数据
|
||||
String testShareUrl = "https://test.lanzoux.com/s/someShareKey";
|
||||
|
||||
PanDomainTemplate template = PanDomainTemplate.fromShareUrl(testShareUrl); // 假设使用LZ网盘模板
|
||||
ParserCreate parserCreate = ParserCreate.fromShareUrl(testShareUrl); // 假设使用LZ网盘模板
|
||||
|
||||
// 调用normalizeShareLink方法
|
||||
ShareLinkInfo result = template.getShareLinkInfo();
|
||||
ShareLinkInfo result = parserCreate.getShareLinkInfo();
|
||||
System.out.println(result);
|
||||
// 断言结果是否符合预期
|
||||
assertNotNull("Result should not be null", result);
|
||||
assertEquals("Share key should match", "someShareKey", result.getShareKey());
|
||||
assertEquals("Standard URL should be generated correctly", template.getStandardUrlTemplate().replace("{shareKey}", "someShareKey"), result.getStandardUrl());
|
||||
assertEquals("Standard URL should be generated correctly", parserCreate.getStandardUrlTemplate().replace("{shareKey}", "someShareKey"), result.getStandardUrl());
|
||||
// 可以添加更多的断言来验证其他字段
|
||||
}
|
||||
|
||||
@@ -38,25 +38,25 @@ public class PanDomainTemplateTest {
|
||||
String cowUrl = "https://cowtransfer.com/s/9a644fe3e3a748";
|
||||
String ceUrl = "https://pan.huang1111.cn/s/g31PcQ";
|
||||
String wsUrl = "https://f.ws59.cn/f/f25625rv6p6";
|
||||
PanDomainTemplate.fromShareUrl(wsUrl).createTool()
|
||||
.parse().onSuccess(System.out::println);
|
||||
PanDomainTemplate.fromShareUrl(lzUrl).createTool()
|
||||
.parse().onSuccess(System.out::println);
|
||||
PanDomainTemplate.fromShareUrl(cowUrl).createTool()
|
||||
.parse().onSuccess(System.out::println);
|
||||
PanDomainTemplate.fromShareUrl(lzUrl).createTool()
|
||||
// ParserCreate.fromShareUrl(wsUrl).createTool()
|
||||
// .parse().onSuccess(System.out::println);
|
||||
// ParserCreate.fromShareUrl(lzUrl).createTool()
|
||||
// .parse().onSuccess(System.out::println);
|
||||
// ParserCreate.fromShareUrl(cowUrl).createTool()
|
||||
// .parse().onSuccess(System.out::println);
|
||||
ParserCreate.fromShareUrl(lzUrl).createTool()
|
||||
.parse().onSuccess(System.out::println);
|
||||
|
||||
// PanDomainTemplate.fromShortName("lz").generateShareLink("ihLkw1gezutg")
|
||||
// ParserCreate.fromType("lz").shareKey("ihLkw1gezutg")
|
||||
// .createTool().parse().onSuccess(System.out::println);
|
||||
// PanDomainTemplate.LZ.generateShareLink("ihLkw1gezutg")
|
||||
// ParserCreate.LZ.shareKey("ihLkw1gezutg")
|
||||
// .createTool().parse().onSuccess(System.out::println);
|
||||
|
||||
|
||||
// 调用fromShareUrl方法
|
||||
// PanDomainTemplate resultTemplate = PanDomainTemplate.fromShareUrl(testShareUrl);
|
||||
// PanDomainTemplate resultTemplate = ParserCreate.fromShareUrl(testShareUrl);
|
||||
// System.out.println(resultTemplate.normalizeShareLink(testShareUrl));
|
||||
// System.out.println(resultTemplate.generateShareLink("xxx"));
|
||||
// System.out.println(resultTemplate.shareKey("xxx"));
|
||||
// System.out.println(resultTemplate.createTool("xxx",null).parse()
|
||||
// .onSuccess(System.out::println));
|
||||
// System.out.println(resultTemplate.getDisplayName());
|
||||
@@ -65,7 +65,7 @@ public class PanDomainTemplateTest {
|
||||
//
|
||||
// // 断言结果是否符合预期
|
||||
// assertNotNull("Result should not be null", resultTemplate);
|
||||
// assertEquals("Should return the correct template", PanDomainTemplate.LZ, resultTemplate);
|
||||
// assertEquals("Should return the correct template", ParserCreate.LZ, resultTemplate);
|
||||
// // 可以添加更多的断言来验证正则表达式匹配逻辑
|
||||
// new Scanner(System.in).nextLine();
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
|
||||
Reference in New Issue
Block a user