mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-15 11:53:02 +00:00
里程碑版本前奏: 1. 添加google云盘解析(需要联网), 2. web页面人工智障自动解析URL, 3. 优化一堆细节问题, 4: git换行配置(待验证), 5. 酷我解析可用
This commit is contained in:
8
.gitattributes
vendored
Normal file
8
.gitattributes
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# 文本文件使用 LF 换行符,适用于 Linux 和 macOS
|
||||
*.sh text eol=lf
|
||||
*.service text eol=lf
|
||||
|
||||
# Windows 执行的文件使用 CRLF 换行符
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
bin/nfd-service-template.xml text eol=crlf
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.qaiu.entity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ShareLinkInfo {
|
||||
@@ -101,7 +102,7 @@ public class ShareLinkInfo {
|
||||
private String sharePassword = ""; // 分享密码(如果存在)
|
||||
private String shareUrl; // 原始分享链接
|
||||
private String standardUrl; // 规范化的标准链接
|
||||
private Map<String, Object> otherParam; // 其他参数
|
||||
private Map<String, Object> otherParam = new HashMap<>(); // 其他参数
|
||||
|
||||
public Builder shareKey(String shareKey) {
|
||||
this.shareKey = shareKey;
|
||||
|
||||
@@ -2,11 +2,9 @@ package cn.qaiu.parser;
|
||||
|
||||
import cn.qaiu.parser.impl.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.regex.Pattern.compile;
|
||||
|
||||
@@ -27,7 +25,7 @@ public enum PanDomainTemplate {
|
||||
|
||||
// 网盘定义
|
||||
LZ("蓝奏云",
|
||||
compile("https://([a-z0-9-]+)?\\.?lanzou[a-z]\\.com/(.+/)?(?<KEY>.+)"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?lanzou[a-z]\\.com/(.+/)?(?<KEY>.+)"),
|
||||
"https://lanzoux.com/{shareKey}",
|
||||
LzTool.class),
|
||||
|
||||
@@ -48,6 +46,7 @@ public enum PanDomainTemplate {
|
||||
FC("亿方云",
|
||||
compile("https://v2\\.fangcloud\\.(com|cn)/(s|sharing)/(?<KEY>.+)"),
|
||||
"https://v2.fangcloud.com/s/{shareKey}",
|
||||
"https://www.fangcloud.com/",
|
||||
FcTool.class),
|
||||
// https://www.ilanzou.com/s/
|
||||
IZ("蓝奏云优享",
|
||||
@@ -58,10 +57,11 @@ public enum PanDomainTemplate {
|
||||
QQ("QQ邮箱中转站",
|
||||
compile("https://i?wx\\.mail\\.qq\\.com/ftn/download\\?(?<KEY>.+)"),
|
||||
"https://iwx.mail.qq.com/ftn/download/{shareKey}",
|
||||
"https://mail.qq.com",
|
||||
QQTool.class),
|
||||
// https://f.ws59.cn/f/或者https://www.wenshushu.cn/f/
|
||||
WS("文叔叔",
|
||||
compile("https://(f\\.ws([0-9]{2})\\.cn|www\\.wenshushu\\.cn)/f/(?<KEY>.+)"),
|
||||
compile("https://(f\\.ws(\\d{2})\\.cn|www\\.wenshushu\\.cn)/f/(?<KEY>.+)"),
|
||||
"https://www.wenshushu.cn/f/{shareKey}",
|
||||
WsTool.class),
|
||||
// https://www.123pan.com/s/
|
||||
@@ -81,25 +81,29 @@ public enum PanDomainTemplate {
|
||||
"https://cowtransfer.com/s/{shareKey}",
|
||||
CowTool.class),
|
||||
CT("城通网盘",
|
||||
compile("https://474b\\.com/file/(?<KEY>.+)"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?(ctfile|545c|u062|ghpym|474b)\\.com/file/(?<KEY>.+)"),
|
||||
"https://474b.com/file/{shareKey}",
|
||||
CtTool.class),
|
||||
// https://xxx.118pan.com/bxxx
|
||||
P118("118网盘",
|
||||
compile("https://((.*)\\.)?118pan\\.com/b(?<KEY>.+)"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?118pan\\.com/b(?<KEY>.+)"),
|
||||
"https://qaiu.118pan.com/b{shareKey}",
|
||||
P118Tool.class),
|
||||
// https://www.vyuyun.com/s/QMa6ie?password=I4KG7H
|
||||
PVYY("微雨云存储",
|
||||
compile("https://www\\.vyuyun\\.com/s/(?<KEY>[a-zA-Z0-9-]+)(\\?password=.*)?"),
|
||||
compile("https://www\\.vyuyun\\.com/s/(?<KEY>[a-zA-Z\\d-]+)(\\?password=.*)?"),
|
||||
"https://www.vyuyun.com/s/{shareKey}",
|
||||
PvyyTool.class),
|
||||
// https://1drv.ms/w/s!Alg0feQmCv2rnRFd60DQOmMa-Oh_?e=buaRtp
|
||||
//
|
||||
POD("OneCloud",
|
||||
POD("OneDrive",
|
||||
compile("https://1drv\\.ms/[uw]/s!(?<KEY>.+)"),
|
||||
"https://1drv.ms/w/s!{shareKey}",
|
||||
"https://onedrive.live.com/",
|
||||
PodTool.class),
|
||||
// 404网盘 https://drive.google.com/file/d/xxx/view?usp=sharing
|
||||
PGD("GoogleDrive",
|
||||
compile("https://drive\\.google\\.com/file/d/(?<KEY>.+)/view(\\?usp=(sharing|drive_link))?"),
|
||||
"https://drive.google.com/file/d/{shareKey}/view?usp=sharing",
|
||||
PgdTool.class),
|
||||
|
||||
// =====================音乐类解析 分享链接标志->MxxS (单歌曲/普通音质)==========================
|
||||
// http://163cn.tv/xxx
|
||||
@@ -114,7 +118,7 @@ public enum PanDomainTemplate {
|
||||
MnesTool.MneTool.class),
|
||||
// https://c6.y.qq.com/base/fcgi-bin/u?__=xxx
|
||||
MQQS("QQ音乐分享",
|
||||
compile("https://(.+)\\.y\\.qq\\.com/base/fcgi-bin/u\\?__=(?<KEY>.+)"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?y\\.qq\\.com/base/fcgi-bin/u\\?__=(?<KEY>.+)"),
|
||||
"https://c6.y.qq.com/base/fcgi-bin/u?__={shareKey}",
|
||||
MqqsTool.class),
|
||||
// https://y.qq.com/n/ryqq/songDetail/000XjcLg0fbRjv?songtype=0
|
||||
@@ -125,17 +129,17 @@ public enum PanDomainTemplate {
|
||||
|
||||
// https://t1.kugou.com/song.html?id=xxx
|
||||
MKGS("酷狗音乐分享",
|
||||
compile("https://(.+)\\.kugou\\.com/song\\.html\\?id=(?<KEY>.+)"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?kugou\\.com/song\\.html\\?id=(?<KEY>.+)"),
|
||||
"https://t1.kugou.com/song.html?id={shareKey}",
|
||||
MkgsTool.class),
|
||||
// https://www.kugou.com/share/2bi8Fe9CSV3.html?id=2bi8Fe9CSV3#6ed9gna4"
|
||||
MKGS2("酷狗音乐分享2",
|
||||
compile("https://(.+)\\.kugou\\.com/share/(?<KEY>.+).html.*"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?kugou\\.com/share/(?<KEY>.+).html.*"),
|
||||
"https://www.kugou.com/share/{shareKey}.html",
|
||||
MkgsTool.Mkgs2Tool.class),
|
||||
// https://www.kugou.com/mixsong/2bi8Fe9CSV3
|
||||
MKG("酷狗音乐歌曲详情",
|
||||
compile("https://(.+)\\.kugou\\.com/mixsong/(?<KEY>.+)\\.html.*"),
|
||||
compile("https://(?:[a-zA-Z\\d-]+\\.)?kugou\\.com/mixsong/(?<KEY>.+)\\.html.*"),
|
||||
"https://www.kugou.com/mixsong/{shareKey}.html",
|
||||
MkgsTool.MkgTool.class),
|
||||
// https://kuwo.cn/play_detail/395500809
|
||||
@@ -154,19 +158,21 @@ public enum PanDomainTemplate {
|
||||
// Cloudreve自定义域名解析, 解析器CeTool兜底策略, 即任意域名如果匹配不到对应的规则, 则由CeTool统一处理,
|
||||
// 如果不属于Cloudreve盘 则调用下一个自定义域名解析器, 若都处理不了则抛出异常, 这种匹配模式类似责任链
|
||||
// https://pan.huang1111.cn/s/xxx
|
||||
// 通用域名([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}
|
||||
// 通用域名([a-z\\d]+(-[a-z\\d]+)*\.)+[a-z]{2,}
|
||||
CE("Cloudreve",
|
||||
compile("http(s)?://([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\\.)+[a-zA-Z]{2,}(/s)?/(?<KEY>.+)"),
|
||||
compile("http(s)?://([a-zA-Z\\d]+(-[a-zA-Z\\d]+)*\\.)+[a-zA-Z]{2,}(/s)?/(?<KEY>.+)"),
|
||||
"https://{any}/s/{shareKey}",
|
||||
"https://cloudreve.org/",
|
||||
CeTool.class),
|
||||
// 可道云自定义域名解析
|
||||
KD("可道云",
|
||||
compile("http(s)?://([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\\.)+[a-zA-Z]{2,}(/#s)?/(?<KEY>.+)"),
|
||||
compile("http(s)?://([a-zA-Z\\d]+(-[a-zA-Z\\d]+)*\\.)+[a-zA-Z]{2,}(/#s)?/(?<KEY>.+)"),
|
||||
"https://{any}/#s/{shareKey}",
|
||||
"https://kodcloud.com/",
|
||||
KdTool.class),
|
||||
// 其他自定义域名解析
|
||||
OTHER("其他网盘",
|
||||
compile("http(s)?://([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\\.)+[a-zA-Z]{2,}/(?<KEY>.+)"),
|
||||
compile("http(s)?://([a-zA-Z\\d]+(-[a-zA-Z\\d]+)*\\.)+[a-zA-Z]{2,}/(?<KEY>.+)"),
|
||||
"https://{any}/{shareKey}",
|
||||
OtherTool.class);
|
||||
|
||||
@@ -183,6 +189,9 @@ public enum PanDomainTemplate {
|
||||
// 网盘的标准链接模板,不含占位符,用于规范化分享链接
|
||||
private final String standardUrlTemplate;
|
||||
|
||||
// 网盘的域名, 如果在分享链接里能提取到, 则可不写
|
||||
private String panDomain;
|
||||
|
||||
// 指向解析工具IPanTool实现类
|
||||
private final Class<? extends IPanTool> toolClass;
|
||||
|
||||
@@ -195,6 +204,16 @@ public enum PanDomainTemplate {
|
||||
this.toolClass = toolClass;
|
||||
}
|
||||
|
||||
PanDomainTemplate(String displayName, Pattern pattern, String standardUrlTemplate, String panDomain,
|
||||
Class<? extends IPanTool> toolClass) {
|
||||
this.displayName = displayName;
|
||||
this.pattern = pattern;
|
||||
this.regex = pattern.pattern();
|
||||
this.standardUrlTemplate = standardUrlTemplate;
|
||||
this.panDomain = panDomain;
|
||||
this.toolClass = toolClass;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
@@ -215,27 +234,17 @@ public enum PanDomainTemplate {
|
||||
return toolClass;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
public String getPanDomain() {
|
||||
if (panDomain == null) {
|
||||
String url = standardUrlTemplate
|
||||
.replace("{shareKey}", "");
|
||||
URL panDomainUrl = null;
|
||||
try {
|
||||
panDomainUrl = new URL(url);
|
||||
} catch (MalformedURLException ignored) {}
|
||||
|
||||
Matcher matcher = compile("https://1drv\\.ms/[uw]/s!(?<KEY>.+)")
|
||||
.matcher("https://1drv.ms/u/s!Alg0feQmCv2rpFvu444hg5yVqDcK?e=OggA4s");
|
||||
if (matcher.find()) {
|
||||
System.out.println(matcher.group());
|
||||
return panDomainUrl != null ? (panDomainUrl.getProtocol() + "://" + panDomainUrl.getHost()) : "无";
|
||||
}
|
||||
// 校验重复
|
||||
Set<String> collect =
|
||||
Arrays.stream(PanDomainTemplate.values()).map(PanDomainTemplate::getRegex).collect(Collectors.toSet());
|
||||
if (collect.size()<PanDomainTemplate.values().length) {
|
||||
System.out.println("有重复枚举正则");
|
||||
}
|
||||
Set<String> collect2 =
|
||||
Arrays.stream(PanDomainTemplate.values()).map(PanDomainTemplate::getStandardUrlTemplate).collect(Collectors.toSet());
|
||||
if (collect2.size()<PanDomainTemplate.values().length) {
|
||||
System.out.println("有重复枚举标准链接");
|
||||
}
|
||||
// System.out.println(collect);
|
||||
// System.out.println(collect2);
|
||||
|
||||
|
||||
return panDomain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,7 @@ public class MkwTool extends PanBase {
|
||||
}
|
||||
|
||||
public Future<String> parse() {
|
||||
// String shareUrl = shareLinkInfo.getStandardUrl();
|
||||
String shareUrl = "https://kuwo.cn/play_detail/395500809";
|
||||
String shareUrl = shareLinkInfo.getStandardUrl();
|
||||
clientSession.getAbs(shareUrl).send().onSuccess(result -> {
|
||||
String cookie = result.headers().get("set-cookie");
|
||||
|
||||
@@ -43,7 +42,7 @@ public class MkwTool extends PanBase {
|
||||
var token = matcher.group(2);
|
||||
String sign = JsExecUtils.getKwSign(token, key);
|
||||
System.out.println(sign);
|
||||
clientSession.getAbs(UriTemplate.of(API_URL)).setTemplateParam("mid", "395500809")
|
||||
clientSession.getAbs(UriTemplate.of(API_URL)).setTemplateParam("mid", shareLinkInfo.getShareKey())
|
||||
.putHeader("Secret", sign).send().onSuccess(res -> {
|
||||
JsonObject json = asJson(res);
|
||||
log.debug(json.encodePrettily());
|
||||
@@ -51,7 +50,7 @@ public class MkwTool extends PanBase {
|
||||
if (json.getInteger("code") == 200) {
|
||||
complete(json.getJsonObject("data").getString("url"));
|
||||
} else {
|
||||
fail("链接已失效");
|
||||
fail("链接已失效/需要VIP");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -66,11 +65,4 @@ public class MkwTool extends PanBase {
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
MkwTool() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new MkwTool().parse();
|
||||
}
|
||||
}
|
||||
|
||||
109
parser/src/main/java/cn/qaiu/parser/impl/PgdTool.java
Normal file
109
parser/src/main/java/cn/qaiu/parser/impl/PgdTool.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package cn.qaiu.parser.impl;
|
||||
|
||||
import cn.qaiu.entity.ShareLinkInfo;
|
||||
import cn.qaiu.parser.IPanTool;
|
||||
import cn.qaiu.parser.PanBase;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.buffer.Buffer;
|
||||
import io.vertx.core.net.ProxyOptions;
|
||||
import io.vertx.ext.web.client.HttpRequest;
|
||||
import io.vertx.ext.web.client.HttpResponse;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <a href="https://drive.google.com/">GoogleDrive</a>
|
||||
* Google Drive文件解析工具.
|
||||
*/
|
||||
public class PgdTool extends PanBase implements IPanTool {
|
||||
|
||||
private static final String DOWN_URL_TEMPLATE =
|
||||
"https://drive.usercontent.google.com/download";
|
||||
|
||||
private String downloadUrl;
|
||||
|
||||
public PgdTool(ShareLinkInfo shareLinkInfo) {
|
||||
super(shareLinkInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<String> parse() {
|
||||
downloadUrl = DOWN_URL_TEMPLATE + "?id=" + shareLinkInfo.getShareKey() + "&export=download";
|
||||
|
||||
if (true) {
|
||||
// if (shareLinkInfo.getOtherParam().containsKey("bypassCheck")
|
||||
// && "true".equalsIgnoreCase(shareLinkInfo.getOtherParam().get("bypassCheck").toString())) {
|
||||
// 发起请求但不真正下载文件, 只检查响应头
|
||||
HttpRequest<Buffer> clientAbs = client.headAbs(downloadUrl);
|
||||
// TODO 判断是否需要代理
|
||||
if (true) {
|
||||
clientAbs.proxy(new ProxyOptions().setHost("127.0.0.1").setPort(7890));
|
||||
}
|
||||
clientAbs
|
||||
.send()
|
||||
.onSuccess(this::handleResponse)
|
||||
.onFailure(handleFail("请求下载链接失败"));
|
||||
return future();
|
||||
}
|
||||
complete(downloadUrl);
|
||||
return future();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理下载链接的响应.
|
||||
*/
|
||||
private void handleResponse(HttpResponse<Buffer> response) {
|
||||
String contentType = response.getHeader("Content-Type");
|
||||
if (contentType != null && !contentType.contains("text/html")) {
|
||||
complete(downloadUrl);
|
||||
} else {
|
||||
// 如果不是文件流类型,从 HTML 中解析出真实下载链接
|
||||
HttpRequest<Buffer> clientAbs = client.getAbs(downloadUrl);
|
||||
// TODO 判断是否需要代理
|
||||
if (true) {
|
||||
clientAbs.proxy(new ProxyOptions().setHost("127.0.0.1").setPort(7890));
|
||||
}
|
||||
clientAbs
|
||||
.send()
|
||||
.onSuccess(res0 -> {
|
||||
parseHtmlForRealLink(res0.bodyAsString());
|
||||
})
|
||||
.onFailure(handleFail("请求下载链接失败"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从HTML内容中解析真实下载链接.
|
||||
*/
|
||||
private void parseHtmlForRealLink(String html) {
|
||||
// 使用正则表达式匹配 id、export、confirm、uuid、at 等参数
|
||||
String id = extractHiddenInputValue(html, "id");
|
||||
String confirm = extractHiddenInputValue(html, "confirm");
|
||||
String uuid = extractHiddenInputValue(html, "uuid");
|
||||
String at = extractHiddenInputValue(html, "at");
|
||||
|
||||
if (id != null && confirm != null && uuid != null) {
|
||||
String realDownloadLink = DOWN_URL_TEMPLATE +
|
||||
"?id=" + id +
|
||||
"&export=download" +
|
||||
"&confirm=" + confirm +
|
||||
"&uuid=" + uuid;
|
||||
if (at != null) {
|
||||
realDownloadLink += ( "&at=" + at);
|
||||
}
|
||||
complete(realDownloadLink);
|
||||
} else {
|
||||
fail("无法找到完整的下载链接参数");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助方法: 从HTML中提取指定name的input隐藏字段的value
|
||||
*/
|
||||
private String extractHiddenInputValue(String html, String name) {
|
||||
Pattern pattern = Pattern.compile("<input[^>]*name=\"" + name + "\"[^>]*value=\"([^\"]*)\"");
|
||||
Matcher matcher = pattern.matcher(html);
|
||||
return matcher.find() ? matcher.group(1) : null;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,13 @@ package cn.qaiu.parser;
|
||||
import cn.qaiu.entity.ShareLinkInfo;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.regex.Pattern.compile;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@@ -70,4 +75,32 @@ public class PanDomainTemplateTest {
|
||||
// new Scanner(System.in).nextLine();
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void verifyDuplicates() {
|
||||
|
||||
Matcher matcher = compile("https://(?:[a-zA-Z\\d-]+\\.)?drive\\.google\\.com/file/d/(?<KEY>.+)/view(\\?usp=(sharing|drive_link))?")
|
||||
.matcher("https://adsd.drive.google.com/file/d/151bR-nk-tOBm9QAFaozJIVt2WYyCMkoz/view");
|
||||
if (matcher.find()) {
|
||||
System.out.println(matcher.group());
|
||||
System.out.println(matcher.group("KEY"));
|
||||
}
|
||||
// 校验重复
|
||||
Set<String> collect =
|
||||
Arrays.stream(PanDomainTemplate.values()).map(PanDomainTemplate::getRegex).collect(Collectors.toSet());
|
||||
if (collect.size()<PanDomainTemplate.values().length) {
|
||||
System.out.println("有重复枚举正则");
|
||||
} else {
|
||||
System.out.println("正则无重复");
|
||||
}
|
||||
|
||||
Set<String> collect2 =
|
||||
Arrays.stream(PanDomainTemplate.values()).map(PanDomainTemplate::getStandardUrlTemplate).collect(Collectors.toSet());
|
||||
if (collect2.size()<PanDomainTemplate.values().length) {
|
||||
System.out.println("有重复枚举标准链接");
|
||||
} else {
|
||||
System.out.println("标准链接无重复");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# nfd-web
|
||||
解析服务的前端页面, 提供API测试, 统计查询, 二维码生成等
|
||||
解析服务的前端页面, 提供API测试, 统计查询, 二维码生成等;
|
||||
20241101 支持剪切板链接自动识别解析, 一键生成短链
|
||||
|
||||

|
||||

|
||||

|
||||
@@ -41,3 +43,8 @@ npm run lint
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
|
||||
|
||||
## 参考项目
|
||||
- https://github.com/HurryBy/CloudDiskAnalysis
|
||||
- https://github.com/syhyz1990/panAI
|
||||
|
||||
12186
web-front/package-lock.json
generated
12186
web-front/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -33,13 +33,24 @@
|
||||
<hr>
|
||||
<div class="main" v-loading="isLoading">
|
||||
<div class="grid-content">
|
||||
|
||||
<!-- 开关按钮,控制是否自动读取剪切板 -->
|
||||
<el-switch
|
||||
v-model="autoReadClipboard"
|
||||
active-text="自动识别剪切板"
|
||||
></el-switch>
|
||||
|
||||
<!-- 手动触发按钮 -->
|
||||
<el-button style="margin-left: 20px;margin-bottom: 20px" @click="() => getPaste(1)">读取剪切板</el-button>
|
||||
|
||||
<el-input placeholder="请粘贴分享链接" v-model="link" id="url" lass="input-with-select">
|
||||
<strong slot="prepend">分享链接</strong>
|
||||
</el-input>
|
||||
<el-input placeholder="请输入密码" v-model="password" id="url" lass="input-with-select">
|
||||
<strong slot="prepend">分享密码</strong>
|
||||
</el-input>
|
||||
<el-input v-show="respData.data" placeholder="解析地址" :value="getLink2" id="url" lass="input-with-select">
|
||||
<el-input v-show="getLink2" placeholder="解析地址" :value="getLink2" id="url" lass="input-with-select">
|
||||
<strong slot="prepend">智能直链</strong>
|
||||
<el-button slot="append" v-clipboard:copy="getLink2"
|
||||
v-clipboard:success="onCopy"
|
||||
v-clipboard:error="onError">点我复制
|
||||
@@ -110,34 +121,16 @@
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import QRCode from 'qrcode'
|
||||
/*
|
||||
蓝奏云 (lz)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
奶牛快传 (cow)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
移动云空间 (ec)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
UC网盘 (uc)似乎已经失效,需要登录
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
小飞机网盘 (fj)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
亿方云 (fc)
|
||||
登录, 上传, 下载, 分享
|
||||
直链解析
|
||||
123云盘 (ye)
|
||||
登录, 上传, 下载,, 分享
|
||||
*/
|
||||
|
||||
import parserUrl from './parserUrl1'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
data() {
|
||||
return {
|
||||
// baseAPI: `${location.protocol}//${location.hostname}:6400`,
|
||||
baseAPI: `${location.protocol}//${location.host}`,
|
||||
autoReadClipboard: true, // 开关状态,默认为自动读取
|
||||
current: {}, // 当前分享
|
||||
showQrc: false,
|
||||
codeUrl: '',
|
||||
@@ -313,16 +306,44 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
async getPaste() {
|
||||
|
||||
async getPaste(v) {
|
||||
const text = await navigator.clipboard.readText();
|
||||
console.log('获取到的文本内容是:', text)
|
||||
console.log('获取到的文本内容是:', text);
|
||||
let linkInfo = parserUrl.parseLink(text);
|
||||
let pwd = parserUrl.parsePwd(text) || '';
|
||||
if (linkInfo.link) {
|
||||
if(linkInfo.link !== this.link || pwd !== this.password ) {
|
||||
this.password = pwd;
|
||||
this.link = linkInfo.link;
|
||||
this.getLink2 = `${this.baseAPI}/parser?url=${this.link}`
|
||||
if (this.link) this.$message.success(`自动识别分享成功, 网盘类型: ${linkInfo.name}; 分享URL ${this.link}; 分享密码: ${this.password || '空'}`);
|
||||
} else {
|
||||
v || this.$message.warning(`[${linkInfo.name}]分享信息无变化`)
|
||||
}
|
||||
} else {
|
||||
this.$message.warning("未能提取到分享链接, 该分享可能尚未支持, 你可以复制任意网盘/音乐App的分享到该页面, 系统智能识别")
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getLinkInfo = `${this.baseAPI}/v2/linkInfo`
|
||||
this.getLink = `${this.baseAPI}/json/parser`
|
||||
this.getLink = `${this.baseAPI}/json/parser`
|
||||
this.getInfo()
|
||||
this.getPaste()
|
||||
|
||||
// 页面首次加载时,根据开关状态判断是否读取剪切板
|
||||
if (this.autoReadClipboard) {
|
||||
this.getPaste()
|
||||
}
|
||||
// 当文档获得焦点时触发
|
||||
window.addEventListener('focus', () => {
|
||||
console.log('文档获得了焦点');
|
||||
if (this.autoReadClipboard) {
|
||||
this.getPaste()
|
||||
}
|
||||
});
|
||||
|
||||
// this.getPaste()
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -1,762 +0,0 @@
|
||||
// ==UserScript==
|
||||
// @name 网盘智能识别助手
|
||||
// @namespace https://github.com/syhyz1990/panAI
|
||||
// @version 2.0.2
|
||||
// @author YouXiaoHou,52fisher
|
||||
// @description 智能识别选中文字中的🔗网盘链接和🔑提取码,识别成功打开网盘链接并自动填写提取码,省去手动复制提取码在输入的烦恼。支持识别 ✅百度网盘 ✅阿里云盘 ✅腾讯微云 ✅蓝奏云 ✅天翼云盘 ✅移动云盘 ✅迅雷云盘 ✅123云盘 ✅360云盘 ✅115网盘 ✅奶牛快传 ✅城通网盘 ✅夸克网盘 ✅FlowUs息流 ✅Chrome 扩展商店 ✅Edge 扩展商店 ✅Firefox 扩展商店 ✅Windows 应用商店。
|
||||
// @license AGPL-3.0-or-later
|
||||
// @homepage https://www.youxiaohou.com/tool/install-panai.html
|
||||
// @supportURL https://github.com/syhyz1990/panAI
|
||||
// @updateURL https://www.youxiaohou.com/panai.user.js
|
||||
// @downloadURL https://www.youxiaohou.com/panai.user.js
|
||||
// @match *://*/*
|
||||
// @require https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.js
|
||||
// @require https://unpkg.com/hotkeys-js@3.13.3/dist/hotkeys.min.js
|
||||
// @resource swalStyle https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.css
|
||||
// @run-at document-idle
|
||||
// @grant GM_openInTab
|
||||
// @grant GM_setValue
|
||||
// @grant GM_getValue
|
||||
// @grant GM_registerMenuCommand
|
||||
// @grant GM_getResourceText
|
||||
// @grant GM_info
|
||||
// @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjNDQ0Ii8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjZGI4NDEyIi8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNNjkuMiA0OWwxOS40IDE0LjhjMS45IDEuNSAzLjEgMy41IDMuNSA1Ljd2LjJjLjEuNC4xLjguMSAxLjIgMCAuNi0uMSAxLjEtLjIgMS42LS40IDIuMi0xLjcgNC4yLTMuNSA1LjZMNjkuMyA5M2MtMi42IDItNS40IDIuNS03LjcgMS40LS4xLS4xLS4yLS4xLS4yLS4yLTItMS4yLTMuMi0zLjUtMy4yLTYuNHYtNi42aC01LjdjLTYuOCAwLTEyLTQuNy0xMi0xMC45IDAtNC44IDIuNi04LjUgNy4yLTEwLjMgMS4zLS41IDIuNy4yIDMuMiAxLjVzLS4xIDIuOC0xLjQgMy4zYy0yLjcgMS4xLTQgMi45LTQgNS41IDAgMy41IDMgNiA3IDZoOC4xYy41IDAgMSAuMiAxLjQuNi43LjYgMS4xIDEuNyAxLjEgMi42djguNGMwIDEuMy40IDIgLjcgMi4xLjQuMiAxLjMgMCAyLjQtLjlsMTkuMi0xNC45YzEuMi0uOSAxLjgtMi4xIDEuOC0zLjNzLS42LTIuMy0xLjctMy4xTDY2LjIgNTNjLTEuMS0uOS0yLTEuMS0yLjQtLjktLjMuMi0uNy45LS43IDIuMXY3LjZjMCAuOS0uNSAxLjctMS4yIDIuMS0uNC4zLS44LjQtMS4zLjQtMS40IDAtMi41LTEuMS0yLjUtMi41di03LjZjMC0zLjEgMS4zLTUuNSAzLjUtNi42bC43LS4zYzIuMS0uNyA0LjYtLjEgNi45IDEuN3oiIGZpbGw9IiM0NDQiLz48L3N2Zz4=
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const customClass = {
|
||||
container: 'panai-container',
|
||||
popup: 'panai-popup',
|
||||
};
|
||||
|
||||
let toast = Swal.mixin({
|
||||
toast: true,
|
||||
position: 'top',
|
||||
showConfirmButton: false,
|
||||
timer: 3500,
|
||||
timerProgressBar: false,
|
||||
didOpen: (toast) => {
|
||||
toast.addEventListener('mouseenter', Swal.stopTimer);
|
||||
toast.addEventListener('mouseleave', Swal.resumeTimer);
|
||||
}
|
||||
});
|
||||
|
||||
let util = {
|
||||
clog(c) {
|
||||
console.group("%c %c [网盘智能识别助手]", `background:url(${GM_info.script.icon}) center center no-repeat;background-size:12px;padding:3px`, "");
|
||||
console.log(c);
|
||||
console.groupEnd();
|
||||
},
|
||||
|
||||
parseQuery(name) {
|
||||
let reg = new RegExp(`(?<=(?:${name})\\=)(?:wss:[a-zA-Z0-9]+|[\\w-]+)`, "i")
|
||||
let pd = location.href.replace(/%3A/g, ":").match(reg);
|
||||
if (pd) {
|
||||
return pd[0];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getValue(name) {
|
||||
return GM_getValue(name);
|
||||
},
|
||||
|
||||
setValue(name, value) {
|
||||
GM_setValue(name, value);
|
||||
},
|
||||
|
||||
sleep(time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
},
|
||||
|
||||
addStyle(id, tag, css) {
|
||||
tag = tag || 'style';
|
||||
let doc = document, styleDom = doc.getElementById(id);
|
||||
if (styleDom) return;
|
||||
let style = doc.createElement(tag);
|
||||
style.rel = 'stylesheet';
|
||||
style.id = id;
|
||||
tag === 'style' ? style.innerHTML = css : style.href = css;
|
||||
document.head.appendChild(style);
|
||||
},
|
||||
|
||||
isHidden(el) {
|
||||
try {
|
||||
return el.offsetParent === null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
isMobile: (() => !!navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone|HarmonyOS|MicroMessenger)/i))(),
|
||||
|
||||
query(selector) {
|
||||
if (Array.isArray(selector)) {
|
||||
let obj = null;
|
||||
for (let i = 0; i < selector.length; i++) {
|
||||
let o = document.querySelector(selector[i]);
|
||||
if (o) {
|
||||
obj = o;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
};
|
||||
|
||||
let opt = {
|
||||
'baidu': {
|
||||
reg: /((?:https?:\/\/)?(?:e?yun|pan)\.baidu\.com\/(doc\/|enterprise\/)?(?:s\/[\w~]*(((-)?\w*)*)?|share\/\S{4,}))/,
|
||||
host: /(pan|e?yun)\.baidu\.com/,
|
||||
input: ['#accessCode', '.share-access-code', '#wpdoc-share-page > .u-dialog__wrapper .u-input__inner'],
|
||||
button: ['#submitBtn', '.share-access .g-button', '#wpdoc-share-page > .u-dialog__wrapper .u-btn--primary'],
|
||||
name: '百度网盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'aliyun': {
|
||||
reg: /((?:https?:\/\/)?(?:(?:www\.)?(?:aliyundrive|alipan)\.com\/s|alywp\.net)\/[a-zA-Z\d]+)/,
|
||||
host: /www\.(aliyundrive|alipan)\.com|alywp\.net/,
|
||||
input: ['form .ant-input', 'form input[type="text"]', 'input[name="pwd"]'],
|
||||
button: ['form .button--fep7l', 'form button[type="submit"]'],
|
||||
name: '阿里云盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'weiyun': {
|
||||
reg: /((?:https?:\/\/)?share\.weiyun\.com\/[a-zA-Z\d]+)/,
|
||||
host: /share\.weiyun\.com/,
|
||||
input: ['.mod-card-s input[type=password]', 'input.pw-input'],
|
||||
button: ['.mod-card-s .btn-main', ".pw-btn-wrap button.btn"],
|
||||
name: '微云',
|
||||
storage: 'hash'
|
||||
},
|
||||
'lanzou': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?(?:lanzou[a-z]|lanzn)\.com\/[a-zA-Z\d_\-]+(?:\/[\w-]+)?)/,
|
||||
host: /(?:[a-zA-Z\d-.]+)?(?:lanzou[a-z]|lanzn)\.com/,
|
||||
input: ['#pwd'],
|
||||
button: ['.passwddiv-btn', '#sub'],
|
||||
name: '蓝奏云',
|
||||
storage: 'hash'
|
||||
},
|
||||
'tianyi': {
|
||||
reg: /((?:https?:\/\/)?cloud\.189\.cn\/(?:t\/|web\/share\?code=)?[a-zA-Z\d]+)/,
|
||||
host: /cloud\.189\.cn/,
|
||||
input: ['.access-code-item #code_txt', "input.access-code-input"],
|
||||
button: ['.access-code-item .visit', ".button"],
|
||||
name: '天翼云盘',
|
||||
storage: (() => util.isMobile === true ? 'local' : 'hash')(),
|
||||
storagePwdName: 'tmp_tianyi_pwd'
|
||||
},
|
||||
'caiyun': {
|
||||
reg: /((?:https?:\/\/)?caiyun\.139\.com\/(?:m\/i|w\/i\/|web\/|front\/#\/detail)\??(?:linkID=)?[a-zA-Z\d]+)/,
|
||||
host: /(?:cai)?yun\.139\.com/,
|
||||
input: ['.token-form input[type=text]'],
|
||||
button: ['.token-form .btn-token'],
|
||||
name: '移动云盘',
|
||||
storage: 'local',
|
||||
storagePwdName: 'tmp_caiyun_pwd'
|
||||
},
|
||||
'xunlei': {
|
||||
reg: /((?:https?:\/\/)?pan\.xunlei\.com\/s\/[\w-]{10,})/,
|
||||
host: /pan\.xunlei\.com/,
|
||||
input: ['.pass-input-wrap .td-input__inner'],
|
||||
button: ['.pass-input-wrap .td-button'],
|
||||
name: '迅雷云盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'123pan': {
|
||||
reg: /((?:https?:\/\/)?www\.123pan\.com\/s\/[\w-]{6,})/,
|
||||
host: /www\.123pan\.com/,
|
||||
input: ['.ca-fot input', ".appinput .appinput"],
|
||||
button: ['.ca-fot button', ".appinput button"],
|
||||
name: '123云盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'360': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d\-.]+)?(?:yunpan\.360\.cn|yunpan\.com)(\/lk)?\/surl_\w{6,})/,
|
||||
host: /[\w.]+?yunpan\.com/,
|
||||
input: ['.pwd-input'],
|
||||
button: ['.submit-btn'],
|
||||
name: '360云盘',
|
||||
storage: 'local',
|
||||
storagePwdName: 'tmp_360_pwd'
|
||||
},
|
||||
'115': {
|
||||
reg: /((?:https?:\/\/)?115\.com\/s\/[a-zA-Z\d]+)/,
|
||||
host: /115\.com/,
|
||||
input: ['.form-decode input'],
|
||||
button: ['.form-decode .submit a'],
|
||||
name: '115网盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'cowtransfer': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?cowtransfer\.com\/s\/[a-zA-Z\d]+)/,
|
||||
host: /(?:[a-zA-Z\d-.]+)?cowtransfer\.com/,
|
||||
input: ['.receive-code-input input'],
|
||||
button: ['.open-button'],
|
||||
name: '奶牛快传',
|
||||
storage: 'hash'
|
||||
},
|
||||
'ctfile': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|ghpym)\.com\/\w+\/[a-zA-Z\d-]+)/,
|
||||
host: /(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062)\.com/,
|
||||
input: ['#passcode'],
|
||||
button: ['.card-body button'],
|
||||
name: '城通网盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'quark': {
|
||||
reg: /((?:https?:\/\/)?pan\.quark\.cn\/s\/[a-zA-Z\d-]+)/,
|
||||
host: /pan\.quark\.cn/,
|
||||
input: ['.ant-input'],
|
||||
button: ['.ant-btn-primary'],
|
||||
name: '夸克网盘',
|
||||
storage: 'local',
|
||||
storagePwdName: 'tmp_quark_pwd'
|
||||
},
|
||||
'vdisk': {
|
||||
reg: /(?:https?:\/\/)?vdisk.weibo.com\/lc\/\w+/,
|
||||
host: /vdisk\.weibo\.com/,
|
||||
input: ['#keypass', "#access_code"],
|
||||
button: ['.search_btn_wrap a', "#linkcommon_btn"],
|
||||
name: '微盘',
|
||||
storage: 'hash',
|
||||
},
|
||||
'wenshushu': {
|
||||
reg: /((?:https?:\/\/)?(?:www\.wenshushu|ws28)\.cn\/(?:k|box|f)\/\w+)/,
|
||||
host: /www\.wenshushu\.cn/,
|
||||
input: ['.pwd-inp .ivu-input'],
|
||||
button: ['.pwd-inp .ivu-btn'],
|
||||
name: '文叔叔网盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'uc': {
|
||||
reg: /(?:https?:\/\/)?drive\.uc\.cn\/s\/[a-zA-Z\d]+/,
|
||||
host: /drive\.uc\.cn/,
|
||||
input: ["input[class*='ShareReceivePC--input']", '.input-wrap input'],
|
||||
button: ["button[class*='ShareReceivePC--submit-btn'", '.input-wrap button'],
|
||||
name: 'UC云盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'jianguoyun': {
|
||||
reg: /((?:https?:\/\/)?www\.jianguoyun\.com\/p\/[\w-]+)/,
|
||||
host: /www\.jianguoyun\.com/,
|
||||
input: ['input[type=password]'],
|
||||
button: ['.ok-button', '.confirm-button'],
|
||||
name: '坚果云',
|
||||
storage: 'hash'
|
||||
},
|
||||
'wo': {
|
||||
reg: /(?:https?:\/\/)?pan\.wo\.cn\/s\/[\w_]+/,
|
||||
host: /(pan\.wo\.cn|panservice\.mail\.wo\.cn)/,
|
||||
input: ['input.el-input__inner', ".van-field__control"],
|
||||
button: ['.s-button', ".share-code button"],
|
||||
name: '联通云盘',
|
||||
storage: (() => util.isMobile === true ? 'local' : 'hash')(),
|
||||
storagePwdName: 'tmp_wo_pwd'
|
||||
},
|
||||
'mega': {
|
||||
reg: /((?:https?:\/\/)?(?:mega\.nz|mega\.co\.nz)\/#F?![\w!-]+)/,
|
||||
host: /(?:mega\.nz|mega\.co\.nz)/,
|
||||
input: ['.dlkey-dialog input'],
|
||||
button: ['.dlkey-dialog .fm-dialog-new-folder-button'],
|
||||
name: 'Mega',
|
||||
storage: 'local'
|
||||
},
|
||||
'520vip': {
|
||||
reg: /((?:https?:\/\/)?www\.(?:520-vip|eos-53)\.com\/file-\d+\.html)/,
|
||||
host: /www\.520-vip\.com/,
|
||||
name: '520云盘',
|
||||
},
|
||||
'567pan': {
|
||||
reg: /((?:https?:\/\/)?www\.567(?:pan|yun|file|inc)\.(?:com|cn)\/file-\d+\.html)/,
|
||||
host: /www\.567inc\.cn/,
|
||||
name: '567盘',
|
||||
replaceHost: "www.567inc.com",
|
||||
},
|
||||
'ayunpan': {
|
||||
reg: /((?:https?:\/\/)?www\.ayunpan\.com\/file-\d+\.html)/,
|
||||
host: /www\.ayunpan\.com/,
|
||||
name: 'AYunPan',
|
||||
},
|
||||
'iycdn.com': {
|
||||
reg: /((?:https?:\/\/)?www\.iycdn\.com\/file-\d+\.html)/,
|
||||
host: /www\.iycdn\.com/,
|
||||
name: '爱优网盘',
|
||||
},
|
||||
'feimaoyun': {
|
||||
reg: /((?:https?:\/\/)?www\.feimaoyun\.com\/s\/[0-9a-zA-Z]+)/,
|
||||
host: /www\.feimaoyun\.com/,
|
||||
name: '飞猫盘',
|
||||
},
|
||||
'uyunp.com': {
|
||||
reg: /((?:https?:\/\/)?download\.uyunp\.com\/share\/s\/short\/\?surl=[0-9a-zA-Z]+)/,
|
||||
host: /download\.uyunp\.com/,
|
||||
name: '优云下载',
|
||||
},
|
||||
'dudujb': {
|
||||
reg: /(?:https?:\/\/)?www\.dudujb\.com\/file-\d+\.html/,
|
||||
host: /www\.dudujb\.com/,
|
||||
name: '贵族网盘',
|
||||
},
|
||||
'xunniu': {
|
||||
reg: /(?:https?:\/\/)?www\.xunniu(?:fxp|wp|fx)\.com\/file-\d+\.html/,
|
||||
host: /www\.xunniuwp\.com/,
|
||||
name: '迅牛网盘',
|
||||
},
|
||||
'xueqiupan': {
|
||||
reg: /(?:https?:\/\/)?www\.xueqiupan\.com\/file-\d+\.html/,
|
||||
host: /www\.xueqiupan\.com/,
|
||||
name: '雪球云盘',
|
||||
},
|
||||
'77file': {
|
||||
reg: /(?:https?:\/\/)?www\.77file\.com\/s\/[a-zA-Z\d]+/,
|
||||
host: /www\.77file\.com/,
|
||||
name: '77file',
|
||||
},
|
||||
'ownfile': {
|
||||
reg: /(?:https?:\/\/)?ownfile\.net\/files\/[a-zA-Z\d]+\.html/,
|
||||
host: /ownfile\.net/,
|
||||
name: 'OwnFile',
|
||||
},
|
||||
'feiyunfile': {
|
||||
reg: /(?:https?:\/\/)?www\.feiyunfile\.com\/file\/[\w=]+\.html/,
|
||||
host: /www\.feiyunfile\.com/,
|
||||
name: '飞云网盘',
|
||||
},
|
||||
'yifile': {
|
||||
reg: /(?:https?:\/\/)?www\.yifile\.com\/f\/\w+/,
|
||||
host: /www\.yifile\.com/,
|
||||
name: 'YiFile',
|
||||
},
|
||||
'dufile': {
|
||||
reg: /(?:https?:\/\/)?dufile\.com\/file\/\w+\.html/,
|
||||
host: /dufile\.com/,
|
||||
name: 'duFile',
|
||||
},
|
||||
'flowus': {
|
||||
reg: /((?:https?:\/\/)?flowus\.cn\/[\S ^\/]*\/?share\/[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12})/,
|
||||
host: /flowus\.cn/,
|
||||
name: 'FlowUs息流',
|
||||
storage: 'hash'
|
||||
},
|
||||
'chrome': {
|
||||
reg: /^https?:\/\/chrome.google.com\/webstore\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
|
||||
host: /chrome\.google\.com/,
|
||||
replaceHost: "chrome.crxsoso.com",
|
||||
name: 'Chrome商店',
|
||||
},
|
||||
'edge': {
|
||||
reg: /^https?:\/\/microsoftedge.microsoft.com\/addons\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
|
||||
host: /microsoftedge\.microsoft\.com/,
|
||||
replaceHost: "microsoftedge.crxsoso.com",
|
||||
name: 'Edge商店',
|
||||
},
|
||||
'firefox': {
|
||||
reg: /^https?:\/\/(reviewers\.)?(addons\.mozilla\.org|addons(?:-dev)?\.allizom\.org)\/.*?(?:addon|review)\/([^/<>"'?#]+)/,
|
||||
host: /addons\.mozilla\.org/,
|
||||
replaceHost: "addons.crxsoso.com",
|
||||
name: 'Firefox商店',
|
||||
},
|
||||
'microsoft': {
|
||||
reg: /^https?:\/\/(?:apps|www).microsoft.com\/(?:store|p)\/.+?\/([a-zA-Z\d]{10,})(?=[\/#?]|$)/,
|
||||
host: /(apps|www)\.microsoft\.com/,
|
||||
replaceHost: "apps.crxsoso.com",
|
||||
name: 'Windows商店',
|
||||
}
|
||||
};
|
||||
|
||||
let main = {
|
||||
lastText: "lorem&",
|
||||
|
||||
//初始化配置数据
|
||||
initValue() {
|
||||
let value = [{
|
||||
name: 'setting_success_times',
|
||||
value: 0
|
||||
}, {
|
||||
name: 'setting_auto_click_btn',
|
||||
value: true
|
||||
}, {
|
||||
name: 'setting_active_in_front',
|
||||
value: true
|
||||
}, {
|
||||
name: 'setting_timer_open',
|
||||
value: false
|
||||
}, {
|
||||
name: 'setting_timer',
|
||||
value: 5000
|
||||
}, {
|
||||
name: 'setting_hotkeys',
|
||||
value: 'F1'
|
||||
}];
|
||||
|
||||
value.forEach((v) => {
|
||||
if (util.getValue(v.name) === undefined) {
|
||||
util.setValue(v.name, v.value);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 监听选择事件
|
||||
addPageListener() {
|
||||
document.addEventListener("mouseup", this.smartIdentify.bind(this), true);
|
||||
document.addEventListener("keydown", this.pressKey.bind(this), true);
|
||||
},
|
||||
|
||||
// ⚠️可能会增加时间⚠️ 如果有需要可以增加选项
|
||||
// 获取选择内容的HTML和文本(增加兼容性) 或 DOM(节点遍历)
|
||||
getSelectionHTML(selection, isDOM = false) {
|
||||
const testDiv = document.createElement("div");
|
||||
if (!selection.isCollapsed) {
|
||||
// Range 转 DocumentFragment
|
||||
const docFragment = selection.getRangeAt(0).cloneContents();
|
||||
testDiv.appendChild(docFragment);
|
||||
}
|
||||
// 拼接选中文本,增加兼容
|
||||
return isDOM ? testDiv : selection.toString();
|
||||
},
|
||||
|
||||
smartIdentify(event, str = '') {
|
||||
let selection = window.getSelection();
|
||||
let text = str || this.getSelectionHTML(selection);
|
||||
if (text !== this.lastText && text !== '') { //选择相同文字或空不识别
|
||||
let start = performance.now();
|
||||
this.lastText = text;
|
||||
//util.clog(`当前选中文字:${text}`);
|
||||
let linkObj = this.parseLink(text);
|
||||
let link = linkObj.link;
|
||||
let name = linkObj.name;
|
||||
let pwd = this.parsePwd(text);
|
||||
if (!link) {
|
||||
linkObj = this.parseParentLink(selection);
|
||||
link = linkObj.link;
|
||||
name = linkObj.name;
|
||||
}
|
||||
if (link) {
|
||||
if (!/https?:\/\//.test(link)) {
|
||||
link = 'https://' + link;
|
||||
}
|
||||
let end = performance.now();
|
||||
let time = (end - start).toFixed(3);
|
||||
util.clog(`文本识别结果:${name} 链接:${link} 密码:${pwd} 耗时:${time}毫秒`);
|
||||
let option = {
|
||||
toast: true,
|
||||
showCancelButton: true,
|
||||
position: 'top',
|
||||
title: `发现<span style="color: #2778c4;margin: 0 5px;">${name}</span>链接`,
|
||||
html: `<span style="font-size: 0.8em;">${!!pwd ? '密码:' + pwd : '是否打开?'}</span>`,
|
||||
confirmButtonText: '打开',
|
||||
cancelButtonText: '关闭',
|
||||
customClass
|
||||
};
|
||||
if (util.getValue('setting_timer_open')) {
|
||||
option.timer = util.getValue('setting_timer');
|
||||
option.timerProgressBar = true;
|
||||
}
|
||||
util.setValue('setting_success_times', util.getValue('setting_success_times') + 1);
|
||||
|
||||
Swal.fire(option).then((res) => {
|
||||
this.lastText = 'lorem&';
|
||||
selection.empty();
|
||||
if (res.isConfirmed || res.dismiss === 'timer') {
|
||||
if (linkObj.storage == "local") {
|
||||
util.setValue(linkObj.storagePwdName, pwd);
|
||||
}
|
||||
let active = util.getValue('setting_active_in_front');
|
||||
if (pwd) {
|
||||
let extra = `${link}?pwd=${pwd}#${pwd}`;
|
||||
if (~link.indexOf('?')) {
|
||||
extra = `${link}&pwd=${pwd}#${pwd}`;
|
||||
}
|
||||
GM_openInTab(extra, {active});
|
||||
} else {
|
||||
GM_openInTab(`${link}`, {active});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
pressKey(event) {
|
||||
if (event.key === 'Enter') {
|
||||
let confirmBtn = document.querySelector('.panai-container .swal2-confirm');
|
||||
confirmBtn && confirmBtn.click();
|
||||
}
|
||||
if (event.key === 'Escape') {
|
||||
let cancelBtn = document.querySelector('.panai-container .swal2-cancel');
|
||||
cancelBtn && cancelBtn.click();
|
||||
}
|
||||
},
|
||||
|
||||
addHotKey() {
|
||||
//获取设置中的快捷键
|
||||
let hotkey = util.getValue('setting_hotkeys');
|
||||
hotkeys(hotkey, (event, handler) => {
|
||||
event.preventDefault();
|
||||
this.showIdentifyBox();
|
||||
});
|
||||
},
|
||||
|
||||
//正则解析网盘链接
|
||||
parseLink(text = '') {
|
||||
let obj = {name: '', link: '', storage: '', storagePwdName: ''};
|
||||
if (text) {
|
||||
try {
|
||||
text = decodeURIComponent(text);
|
||||
} catch {
|
||||
}
|
||||
text = text.replace(/[点點]/g, '.');
|
||||
text = text.replace(/[\u4e00-\u9fa5()(),\u200B,\uD83C-\uDBFF\uDC00-\uDFFF]/g, '');
|
||||
text = text.replace(/lanzous/g, 'lanzouw'); //修正lanzous打不开的问题
|
||||
for (let name in opt) {
|
||||
let val = opt[name];
|
||||
if (val.reg.test(text)) {
|
||||
let matches = text.match(val.reg);
|
||||
obj.name = val.name;
|
||||
obj.link = matches[0];
|
||||
obj.storage = val.storage;
|
||||
obj.storagePwdName = val.storagePwdName || null;
|
||||
if (val.replaceHost) {
|
||||
obj.link = obj.link.replace(val.host, val.replaceHost);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
//正则解析超链接类型网盘链接
|
||||
parseParentLink(selection) {
|
||||
const dom = this.getSelectionHTML(selection, true).querySelector('*[href]');
|
||||
return this.parseLink(dom ? dom.href : "");
|
||||
},
|
||||
|
||||
//正则解析提取码
|
||||
parsePwd(text) {
|
||||
text = text.replace(/\u200B/g, '').replace('%3A', ":");
|
||||
text = text.replace(/(?:本帖)?隐藏的?内容[::]?/, "");
|
||||
let reg = /wss:[a-zA-Z0-9]+|(?<=\s*(?:密|提取|访问|訪問|key|password|pwd|#|\?p=)\s*[码碼]?\s*[::=]?\s*)[a-zA-Z0-9]{3,8}/i;
|
||||
if (reg.test(text)) {
|
||||
let match = text.match(reg);
|
||||
return match[0];
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
//根据域名检测网盘类型
|
||||
panDetect() {
|
||||
let hostname = location.hostname;
|
||||
for (let name in opt) {
|
||||
let val = opt[name];
|
||||
if (val.host.test(hostname)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
//自动填写密码
|
||||
autoFillPassword() {
|
||||
let query = util.parseQuery('pwd|p');
|
||||
let hash = location.hash.slice(1).replace(/\W/g, "") //hash中可能存在密码,需要过滤掉非密码字符
|
||||
let pwd = query || hash;
|
||||
let panType = this.panDetect();
|
||||
for (let name in opt) {
|
||||
let val = opt[name];
|
||||
if (panType === name) {
|
||||
if (val.storage === 'local') {
|
||||
//当前local存储的密码不一定是当前链接的密码,用户可能通过url直接访问或者恢复页面,这样取出来的密码可能是其他链接的
|
||||
//如果能从url中获取到密码,则应该优先使用url中获取的密码
|
||||
//util.getValue查询不到key时,默认返回undefined,已经形成逻辑短路,此处赋空值无效也无需赋空值.详见https://github.com/syhyz1990/panAI/commit/efb6ff0c77972920b26617bb836a2e19dd14a749
|
||||
pwd = pwd || util.getValue(val.storagePwdName);
|
||||
pwd && this.doFillAction(val.input, val.button, pwd);
|
||||
}
|
||||
if (val.storage === 'hash') {
|
||||
if (!/^(?:wss:[a-zA-Z\d]+|[a-zA-Z0-9]{3,8})$/.test(pwd)) { //过滤掉不正常的Hash
|
||||
return;
|
||||
}
|
||||
pwd && this.doFillAction(val.input, val.button, pwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
doFillAction(inputSelector, buttonSelector, pwd) {
|
||||
let maxTime = 10;
|
||||
let ins = setInterval(async () => {
|
||||
maxTime--;
|
||||
let input = util.query(inputSelector);
|
||||
let button = util.query(buttonSelector);
|
||||
if (input && !util.isHidden(input)) {
|
||||
clearInterval(ins);
|
||||
Swal.fire({
|
||||
toast: true,
|
||||
position: 'top',
|
||||
showCancelButton: false,
|
||||
showConfirmButton: false,
|
||||
title: 'AI已识别到密码!正自动帮您填写',
|
||||
icon: 'success',
|
||||
timer: 2000,
|
||||
customClass
|
||||
});
|
||||
|
||||
let lastValue = input.value;
|
||||
input.value = pwd;
|
||||
//Vue & React 触发 input 事件
|
||||
let event = new Event('input', {bubbles: true});
|
||||
let tracker = input._valueTracker;
|
||||
if (tracker) {
|
||||
tracker.setValue(lastValue);
|
||||
}
|
||||
input.dispatchEvent(event);
|
||||
|
||||
if (util.getValue('setting_auto_click_btn')) {
|
||||
await util.sleep(1000); //1秒后点击按钮
|
||||
button.click();
|
||||
}
|
||||
} else {
|
||||
maxTime === 0 && clearInterval(ins);
|
||||
}
|
||||
}, 800);
|
||||
},
|
||||
|
||||
//重置识别次数
|
||||
clearIdentifyTimes() {
|
||||
let res = Swal.fire({
|
||||
showCancelButton: true,
|
||||
title: '确定要重置识别次数吗?',
|
||||
icon: 'warning',
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
customClass
|
||||
}).then(res => {
|
||||
this.lastText = 'lorem&';
|
||||
if (res.isConfirmed) {
|
||||
util.setValue('setting_success_times', 0);
|
||||
history.go(0);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//识别输入框中的内容
|
||||
showIdentifyBox() {
|
||||
Swal.fire({
|
||||
title: '识别剪切板中文字',
|
||||
input: 'textarea',
|
||||
inputPlaceholder: '若选方式一,请按 Ctrl+V 粘贴要识别的文字',
|
||||
html: `<div style="font-size: 12px;color: #999;margin-bottom: 8px;text-align: center;">提示:在任意网页按下 <span style="font-weight: 700;">${util.getValue("setting_hotkeys")}</span> 键可快速打开本窗口。</div><div style="font-size: 14px;line-height: 22px;padding: 10px 0 5px;text-align: left;"><div style="font-size: 16px;margin-bottom: 8px;font-weight: 700;">支持以下两种方式:</div><div><b>方式一:</b>直接粘贴文字到输入框,点击“识别方框内容”按钮。</div><div><b>方式二:</b>点击“读取剪切板”按钮。<span style="color: #d14529;font-size: 12px;">会弹出“授予网站读取剪切板”权限,同意后会自动识别剪切板中的文字。</span></div></div>`,
|
||||
showCloseButton: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: '识别方框内容',
|
||||
denyButtonText: '读取剪切板',
|
||||
customClass
|
||||
}).then(res => {
|
||||
if (res.isConfirmed) {
|
||||
this.smartIdentify(null, res.value);
|
||||
}
|
||||
if (res.isDenied) {
|
||||
navigator.clipboard.readText().then(text => {
|
||||
this.smartIdentify(null, text);
|
||||
}).catch(() => {
|
||||
toast.fire({title: '读取剪切板失败,请先授权或手动粘贴后识别!', icon: 'error'});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//显示设置
|
||||
showSettingBox() {
|
||||
let html = `<div style="font-size: 1em;">
|
||||
<label class="panai-setting-label">填写密码后自动提交<input type="checkbox" id="S-Auto" ${util.getValue('setting_auto_click_btn') ? 'checked' : ''} class="panai-setting-checkbox"></label>
|
||||
<label class="panai-setting-label">前台打开网盘标签页<input type="checkbox" id="S-Active" ${util.getValue('setting_active_in_front') ? 'checked' : ''}
|
||||
class="panai-setting-checkbox"></label>
|
||||
<label class="panai-setting-label">倒计时结束自动打开<input type="checkbox" id="S-Timer-Open" ${util.getValue('setting_timer_open') ? 'checked' : ''} class="panai-setting-checkbox"></label>
|
||||
<label class="panai-setting-label" id="Panai-Range-Wrapper" style="${util.getValue('setting_timer_open') ? '' : 'display: none'}"><span>倒计时 <span id="Timer-Value">(${util.getValue('setting_timer') / 1000}秒)</span></span><input type="range" id="S-Timer" min="0" max="10000" step="500" value="${util.getValue('setting_timer')}" style="width: 200px;"></label>
|
||||
<label class="panai-setting-label">快捷键设置<input type="text" id="S-hotkeys" value="${util.getValue('setting_hotkeys')}" style="width: 100px;"></label>
|
||||
</div>`;
|
||||
Swal.fire({
|
||||
title: '识别助手配置',
|
||||
html,
|
||||
icon: 'info',
|
||||
showCloseButton: true,
|
||||
confirmButtonText: '保存',
|
||||
footer: '<div style="text-align: center;font-size: 1em;">点击查看 <a href="https://www.youxiaohou.com/tool/install-panai.html" target="_blank">使用说明</a>,助手免费开源,Powered by <a href="https://www.youxiaohou.com">油小猴</a></div>',
|
||||
customClass
|
||||
}).then((res) => {
|
||||
res.isConfirmed && history.go(0);
|
||||
});
|
||||
|
||||
document.getElementById('S-Auto').addEventListener('change', (e) => {
|
||||
util.setValue('setting_auto_click_btn', e.target.checked);
|
||||
});
|
||||
document.getElementById('S-Active').addEventListener('change', (e) => {
|
||||
util.setValue('setting_active_in_front', e.target.checked);
|
||||
});
|
||||
document.getElementById('S-Timer-Open').addEventListener('change', (e) => {
|
||||
let rangeWrapper = document.getElementById('Panai-Range-Wrapper');
|
||||
e.target.checked ? rangeWrapper.style.display = 'flex' : rangeWrapper.style.display = 'none';
|
||||
util.setValue('setting_timer_open', e.target.checked);
|
||||
});
|
||||
document.getElementById('S-Timer').addEventListener('change', (e) => {
|
||||
util.setValue('setting_timer', e.target.value);
|
||||
document.getElementById('Timer-Value').innerText = `(${e.target.value / 1000}秒)`;
|
||||
});
|
||||
document.getElementById('S-hotkeys').addEventListener('change', (e) => {
|
||||
util.setValue('setting_hotkeys', e.target.value);
|
||||
});
|
||||
},
|
||||
|
||||
registerMenuCommand() {
|
||||
GM_registerMenuCommand('👀 已识别:' + util.getValue('setting_success_times') + '次', () => {
|
||||
this.clearIdentifyTimes();
|
||||
});
|
||||
GM_registerMenuCommand(`📋️ 识别剪切板中文字(快捷键 ${util.getValue('setting_hotkeys')})`, () => {
|
||||
this.showIdentifyBox();
|
||||
});
|
||||
GM_registerMenuCommand('⚙️ 设置', () => {
|
||||
this.showSettingBox();
|
||||
});
|
||||
},
|
||||
|
||||
addPluginStyle() {
|
||||
let style = `
|
||||
.panai-container { z-index: 99999!important }
|
||||
.panai-popup { font-size: 14px !important }
|
||||
.panai-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 20px; }
|
||||
.panai-setting-checkbox { width: 16px;height: 16px; }
|
||||
`;
|
||||
|
||||
if (document.head) {
|
||||
util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
|
||||
util.addStyle('panai-style', 'style', style);
|
||||
}
|
||||
|
||||
const headObserver = new MutationObserver(() => {
|
||||
util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
|
||||
util.addStyle('panai-style', 'style', style);
|
||||
});
|
||||
headObserver.observe(document.head, {childList: true, subtree: true});
|
||||
},
|
||||
|
||||
isTopWindow() {
|
||||
return window.self === window.top;
|
||||
},
|
||||
|
||||
init() {
|
||||
this.initValue();
|
||||
this.addPluginStyle();
|
||||
this.addHotKey();
|
||||
this.autoFillPassword();
|
||||
this.addPageListener();
|
||||
this.isTopWindow() && this.registerMenuCommand();
|
||||
},
|
||||
};
|
||||
|
||||
main.init();
|
||||
})();
|
||||
387
web-front/src/parserUrl1.js
Normal file
387
web-front/src/parserUrl1.js
Normal file
@@ -0,0 +1,387 @@
|
||||
// 修改自 https://github.com/syhyz1990/panAI
|
||||
|
||||
const util = {
|
||||
|
||||
isMobile: (() => !!navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone|HarmonyOS|MicroMessenger)/i))(),
|
||||
|
||||
}
|
||||
|
||||
let opt = {
|
||||
// 'baidu': {
|
||||
// reg: /((?:https?:\/\/)?(?:e?yun|pan)\.baidu\.com\/(doc\/|enterprise\/)?(?:s\/[\w~]*(((-)?\w*)*)?|share\/\S{4,}))/,
|
||||
// host: /(pan|e?yun)\.baidu\.com/,
|
||||
// input: ['#accessCode', '.share-access-code', '#wpdoc-share-page > .u-dialog__wrapper .u-input__inner'],
|
||||
// button: ['#submitBtn', '.share-access .g-button', '#wpdoc-share-page > .u-dialog__wrapper .u-btn--primary'],
|
||||
// name: '百度网盘',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'aliyun': {
|
||||
// reg: /((?:https?:\/\/)?(?:(?:www\.)?(?:aliyundrive|alipan)\.com\/s|alywp\.net)\/[a-zA-Z\d]+)/,
|
||||
// host: /www\.(aliyundrive|alipan)\.com|alywp\.net/,
|
||||
// input: ['form .ant-input', 'form input[type="text"]', 'input[name="pwd"]'],
|
||||
// button: ['form .button--fep7l', 'form button[type="submit"]'],
|
||||
// name: '阿里云盘',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'weiyun': {
|
||||
// reg: /((?:https?:\/\/)?share\.weiyun\.com\/[a-zA-Z\d]+)/,
|
||||
// host: /share\.weiyun\.com/,
|
||||
// input: ['.mod-card-s input[type=password]', 'input.pw-input'],
|
||||
// button: ['.mod-card-s .btn-main', ".pw-btn-wrap button.btn"],
|
||||
// name: '微云',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'tianyi': {
|
||||
// reg: /((?:https?:\/\/)?cloud\.189\.cn\/(?:t\/|web\/share\?code=)?[a-zA-Z\d]+)/,
|
||||
// host: /cloud\.189\.cn/,
|
||||
// input: ['.access-code-item #code_txt', "input.access-code-input"],
|
||||
// button: ['.access-code-item .visit', ".button"],
|
||||
// name: '天翼云盘',
|
||||
// storage: (() => util.isMobile === true ? 'local' : 'hash')(),
|
||||
// storagePwdName: 'tmp_tianyi_pwd'
|
||||
// },
|
||||
// 'caiyun': {
|
||||
// reg: /((?:https?:\/\/)?caiyun\.139\.com\/(?:m\/i|w\/i\/|web\/|front\/#\/detail)\??(?:linkID=)?[a-zA-Z\d]+)/,
|
||||
// host: /(?:cai)?yun\.139\.com/,
|
||||
// input: ['.token-form input[type=text]'],
|
||||
// button: ['.token-form .btn-token'],
|
||||
// name: '移动云盘',
|
||||
// storage: 'local',
|
||||
// storagePwdName: 'tmp_caiyun_pwd'
|
||||
// },
|
||||
// 'xunlei': {
|
||||
// reg: /((?:https?:\/\/)?pan\.xunlei\.com\/s\/[\w-]{10,})/,
|
||||
// host: /pan\.xunlei\.com/,
|
||||
// input: ['.pass-input-wrap .td-input__inner'],
|
||||
// button: ['.pass-input-wrap .td-button'],
|
||||
// name: '迅雷云盘',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// '360': {
|
||||
// reg: /((?:https?:\/\/)?(?:[a-zA-Z\d\-.]+)?(?:yunpan\.360\.cn|yunpan\.com)(\/lk)?\/surl_\w{6,})/,
|
||||
// host: /[\w.]+?yunpan\.com/,
|
||||
// input: ['.pwd-input'],
|
||||
// button: ['.submit-btn'],
|
||||
// name: '360云盘',
|
||||
// storage: 'local',
|
||||
// storagePwdName: 'tmp_360_pwd'
|
||||
// },
|
||||
// '115': {
|
||||
// reg: /((?:https?:\/\/)?115\.com\/s\/[a-zA-Z\d]+)/,
|
||||
// host: /115\.com/,
|
||||
// input: ['.form-decode input'],
|
||||
// button: ['.form-decode .submit a'],
|
||||
// name: '115网盘',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'quark': {
|
||||
// reg: /((?:https?:\/\/)?pan\.quark\.cn\/s\/[a-zA-Z\d-]+)/,
|
||||
// host: /pan\.quark\.cn/,
|
||||
// input: ['.ant-input'],
|
||||
// button: ['.ant-btn-primary'],
|
||||
// name: '夸克网盘',
|
||||
// storage: 'local',
|
||||
// storagePwdName: 'tmp_quark_pwd'
|
||||
// },
|
||||
// 'vdisk': {
|
||||
// reg: /(?:https?:\/\/)?vdisk.weibo.com\/lc\/\w+/,
|
||||
// host: /vdisk\.weibo\.com/,
|
||||
// input: ['#keypass', "#access_code"],
|
||||
// button: ['.search_btn_wrap a', "#linkcommon_btn"],
|
||||
// name: '微盘',
|
||||
// storage: 'hash',
|
||||
// },
|
||||
// 'uc': {
|
||||
// reg: /(?:https?:\/\/)?drive\.uc\.cn\/s\/[a-zA-Z\d]+/,
|
||||
// host: /drive\.uc\.cn/,
|
||||
// input: ["input[class*='ShareReceivePC--input']", '.input-wrap input'],
|
||||
// button: ["button[class*='ShareReceivePC--submit-btn'", '.input-wrap button'],
|
||||
// name: 'UC云盘',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'jianguoyun': {
|
||||
// reg: /((?:https?:\/\/)?www\.jianguoyun\.com\/p\/[\w-]+)/,
|
||||
// host: /www\.jianguoyun\.com/,
|
||||
// input: ['input[type=password]'],
|
||||
// button: ['.ok-button', '.confirm-button'],
|
||||
// name: '坚果云',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'wo': {
|
||||
// reg: /(?:https?:\/\/)?pan\.wo\.cn\/s\/[\w_]+/,
|
||||
// host: /(pan\.wo\.cn|panservice\.mail\.wo\.cn)/,
|
||||
// input: ['input.el-input__inner', ".van-field__control"],
|
||||
// button: ['.s-button', ".share-code button"],
|
||||
// name: '联通云盘',
|
||||
// storage: (() => util.isMobile === true ? 'local' : 'hash')(),
|
||||
// storagePwdName: 'tmp_wo_pwd'
|
||||
// },
|
||||
// 'mega': {
|
||||
// reg: /((?:https?:\/\/)?(?:mega\.nz|mega\.co\.nz)\/#F?![\w!-]+)/,
|
||||
// host: /(?:mega\.nz|mega\.co\.nz)/,
|
||||
// input: ['.dlkey-dialog input'],
|
||||
// button: ['.dlkey-dialog .fm-dialog-new-folder-button'],
|
||||
// name: 'Mega',
|
||||
// storage: 'local'
|
||||
// },
|
||||
// '520vip': {
|
||||
// reg: /((?:https?:\/\/)?www\.(?:520-vip|eos-53)\.com\/file-\d+\.html)/,
|
||||
// host: /www\.520-vip\.com/,
|
||||
// name: '520云盘',
|
||||
// },
|
||||
// '567pan': {
|
||||
// reg: /((?:https?:\/\/)?www\.567(?:pan|yun|file|inc)\.(?:com|cn)\/file-\d+\.html)/,
|
||||
// host: /www\.567inc\.cn/,
|
||||
// name: '567盘',
|
||||
// replaceHost: "www.567inc.com",
|
||||
// },
|
||||
// 'ayunpan': {
|
||||
// reg: /((?:https?:\/\/)?www\.ayunpan\.com\/file-\d+\.html)/,
|
||||
// host: /www\.ayunpan\.com/,
|
||||
// name: 'AYunPan',
|
||||
// },
|
||||
// 'iycdn.com': {
|
||||
// reg: /((?:https?:\/\/)?www\.iycdn\.com\/file-\d+\.html)/,
|
||||
// host: /www\.iycdn\.com/,
|
||||
// name: '爱优网盘',
|
||||
// },
|
||||
// 'feimaoyun': {
|
||||
// reg: /((?:https?:\/\/)?www\.feimaoyun\.com\/s\/[0-9a-zA-Z]+)/,
|
||||
// host: /www\.feimaoyun\.com/,
|
||||
// name: '飞猫盘',
|
||||
// },
|
||||
// 'uyunp.com': {
|
||||
// reg: /((?:https?:\/\/)?download\.uyunp\.com\/share\/s\/short\/\?surl=[0-9a-zA-Z]+)/,
|
||||
// host: /download\.uyunp\.com/,
|
||||
// name: '优云下载',
|
||||
// },
|
||||
// 'dudujb': {
|
||||
// reg: /(?:https?:\/\/)?www\.dudujb\.com\/file-\d+\.html/,
|
||||
// host: /www\.dudujb\.com/,
|
||||
// name: '贵族网盘',
|
||||
// },
|
||||
// 'xunniu': {
|
||||
// reg: /(?:https?:\/\/)?www\.xunniu(?:fxp|wp|fx)\.com\/file-\d+\.html/,
|
||||
// host: /www\.xunniuwp\.com/,
|
||||
// name: '迅牛网盘',
|
||||
// },
|
||||
// 'xueqiupan': {
|
||||
// reg: /(?:https?:\/\/)?www\.xueqiupan\.com\/file-\d+\.html/,
|
||||
// host: /www\.xueqiupan\.com/,
|
||||
// name: '雪球云盘',
|
||||
// },
|
||||
// '77file': {
|
||||
// reg: /(?:https?:\/\/)?www\.77file\.com\/s\/[a-zA-Z\d]+/,
|
||||
// host: /www\.77file\.com/,
|
||||
// name: '77file',
|
||||
// },
|
||||
// 'ownfile': {
|
||||
// reg: /(?:https?:\/\/)?ownfile\.net\/files\/[a-zA-Z\d]+\.html/,
|
||||
// host: /ownfile\.net/,
|
||||
// name: 'OwnFile',
|
||||
// },
|
||||
// 'feiyunfile': {
|
||||
// reg: /(?:https?:\/\/)?www\.feiyunfile\.com\/file\/[\w=]+\.html/,
|
||||
// host: /www\.feiyunfile\.com/,
|
||||
// name: '飞云网盘',
|
||||
// },
|
||||
// 'yifile': {
|
||||
// reg: /(?:https?:\/\/)?www\.yifile\.com\/f\/\w+/,
|
||||
// host: /www\.yifile\.com/,
|
||||
// name: 'YiFile',
|
||||
// },
|
||||
// 'dufile': {
|
||||
// reg: /(?:https?:\/\/)?dufile\.com\/file\/\w+\.html/,
|
||||
// host: /dufile\.com/,
|
||||
// name: 'duFile',
|
||||
// },
|
||||
// 'flowus': {
|
||||
// reg: /((?:https?:\/\/)?flowus\.cn\/[\S ^\/]*\/?share\/[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12})/,
|
||||
// host: /flowus\.cn/,
|
||||
// name: 'FlowUs息流',
|
||||
// storage: 'hash'
|
||||
// },
|
||||
// 'chrome': {
|
||||
// reg: /^https?:\/\/chrome.google.com\/webstore\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
|
||||
// host: /chrome\.google\.com/,
|
||||
// replaceHost: "chrome.crxsoso.com",
|
||||
// name: 'Chrome商店',
|
||||
// },
|
||||
// 'edge': {
|
||||
// reg: /^https?:\/\/microsoftedge.microsoft.com\/addons\/.+?\/([a-z]{32})(?=[\/#?]|$)/,
|
||||
// host: /microsoftedge\.microsoft\.com/,
|
||||
// replaceHost: "microsoftedge.crxsoso.com",
|
||||
// name: 'Edge商店',
|
||||
// },
|
||||
// 'firefox': {
|
||||
// reg: /^https?:\/\/(reviewers\.)?(addons\.mozilla\.org|addons(?:-dev)?\.allizom\.org)\/.*?(?:addon|review)\/([^/<>"'?#]+)/,
|
||||
// host: /addons\.mozilla\.org/,
|
||||
// replaceHost: "addons.crxsoso.com",
|
||||
// name: 'Firefox商店',
|
||||
// },
|
||||
// 'microsoft': {
|
||||
// reg: /^https?:\/\/(?:apps|www).microsoft.com\/(?:store|p)\/.+?\/([a-zA-Z\d]{10,})(?=[\/#?]|$)/,
|
||||
// host: /(apps|www)\.microsoft\.com/,
|
||||
// replaceHost: "apps.crxsoso.com",
|
||||
// name: 'Windows商店',
|
||||
// }
|
||||
|
||||
'lanzou': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?(?:lanzou[a-z]|lanzn)\.com\/[a-zA-Z\d_\-]+(?:\/[\w-]+)?)/,
|
||||
host: /(?:[a-zA-Z\d-.]+)?(?:lanzou[a-z]|lanzn)\.com/,
|
||||
input: ['#pwd'],
|
||||
button: ['.passwddiv-btn', '#sub'],
|
||||
name: '蓝奏云',
|
||||
storage: 'hash'
|
||||
},
|
||||
'cowtransfer': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?cowtransfer\.com\/s\/[a-zA-Z\d]+)/,
|
||||
host: /(?:[a-zA-Z\d-.]+)?cowtransfer\.com/,
|
||||
input: ['.receive-code-input input'],
|
||||
button: ['.open-button'],
|
||||
name: '奶牛快传',
|
||||
storage: 'hash'
|
||||
},
|
||||
'ctfile': {
|
||||
reg: /((?:https?:\/\/)?(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|ghpym|474b)\.com\/\w+\/[a-zA-Z\d-]+)/,
|
||||
host: /(?:[a-zA-Z\d-.]+)?(?:ctfile|545c|u062|474b)\.com/,
|
||||
input: ['#passcode'],
|
||||
button: ['.card-body button'],
|
||||
name: '城通网盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'123pan': {
|
||||
reg: /((?:https?:\/\/)?www\.(123pan|123865|123684)\.com\/s\/[\w-]{6,})/,
|
||||
host: /www\.123pan\.com/,
|
||||
input: ['.ca-fot input', ".appinput .appinput"],
|
||||
button: ['.ca-fot button', ".appinput button"],
|
||||
name: '123云盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
'wenshushu': {
|
||||
reg: /((?:https?:\/\/)?(?:www\.wenshushu|ws28)\.cn\/(?:k|box|f)\/\w+)/,
|
||||
host: /www\.wenshushu\.cn/,
|
||||
input: ['.pwd-inp .ivu-input'],
|
||||
button: ['.pwd-inp .ivu-btn'],
|
||||
name: '文叔叔网盘',
|
||||
storage: 'hash'
|
||||
},
|
||||
|
||||
// ---new---
|
||||
feijix: {
|
||||
reg: /https:\/\/(share\.feijipan\.com|www\.feijix\.com)\/s\/.+/,
|
||||
host: /feijix\.com|feijipan\.com/,
|
||||
name: '小飞机网盘'
|
||||
},
|
||||
lecloud: {
|
||||
reg: /https:\/\/lecloud\.lenovo\.com\/share\/.+/,
|
||||
host: /lenovo\.com/,
|
||||
name: '联想乐云'
|
||||
},
|
||||
fangcloud: {
|
||||
reg: /https:\/\/v2\.fangcloud\.(com|cn)\/(s|sharing)\/.+/,
|
||||
host: /fangcloud\.(com|cn)/,
|
||||
name: '亿方云'
|
||||
},
|
||||
ilanzou: {
|
||||
reg: /https:\/\/www\.ilanzou\.com\/s\/.+/,
|
||||
host: /ilanzou\.com/,
|
||||
name: '蓝奏云优享'
|
||||
},
|
||||
qqMailTransfer: {
|
||||
reg: /https:\/\/iwx\.mail\.qq\.com\/ftn\/download\?.+/,
|
||||
host: /mail\.qq\.com/,
|
||||
name: 'QQ邮箱中转站'
|
||||
},
|
||||
pan118: {
|
||||
reg: /https:\/\/(?:[a-zA-Z\d-]+\.)?118pan\.com\/b.+/,
|
||||
host: /118pan\.com/,
|
||||
name: '118网盘'
|
||||
},
|
||||
onedrive: {
|
||||
reg: /https:\/\/1drv\.ms\/[uw]\/s!.+/,
|
||||
host: /1drv\.ms/,
|
||||
name: 'OneDrive'
|
||||
},
|
||||
googleDrive: {
|
||||
reg: /https:\/\/drive\.google\.com\/file\/d\/.+\/view\?usp=(sharing|drive_link)?/,
|
||||
host: /drive\.google\.com/,
|
||||
name: 'GoogleDrive'
|
||||
},
|
||||
n163Music: {
|
||||
reg: /https:\/\/163cn\.tv\/.+/,
|
||||
host: /163cn\.tv/,
|
||||
name: '网易云音乐分享'
|
||||
},
|
||||
qqMusic: {
|
||||
reg: /https:\/\/y\.qq\.com\/n\/ryqq\/songDetail\/.+/,
|
||||
host: /y\.qq\.com/,
|
||||
name: 'QQ音乐歌曲详情'
|
||||
},
|
||||
kuwoMusic: {
|
||||
reg: /https:\/\/(m\.)?kuwo\.cn\/(newh5app\/)?play_detail\/.+/,
|
||||
host: /kuwo\.cn/,
|
||||
name: '酷我音乐分享'
|
||||
},
|
||||
miguMusic: {
|
||||
reg: /https:\/\/music\.migu\.cn\/v3\/music\/song\/.+/,
|
||||
host: /migu\.cn/,
|
||||
name: '咪咕音乐分享'
|
||||
},
|
||||
other: {
|
||||
reg: /https:\/\/([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,}\/s\/.+/,
|
||||
host: /.*/,
|
||||
name: '其他/Cloudreve/可道云'
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
let main = {
|
||||
//正则解析网盘链接
|
||||
parseLink(text = '') {
|
||||
let obj = {name: '', link: '', storage: '', storagePwdName: ''};
|
||||
if (text) {
|
||||
try {
|
||||
text = decodeURIComponent(text);
|
||||
} catch {
|
||||
}
|
||||
text = text.replace(/[点點]/g, '.');
|
||||
text = text.replace(/[\u4e00-\u9fa5()(),\u200B,\uD83C-\uDBFF\uDC00-\uDFFF]/g, '');
|
||||
text = text.replace(/lanzous/g, 'lanzouw'); //修正lanzous打不开的问题
|
||||
for (let name in opt) {
|
||||
let val = opt[name];
|
||||
if (val.reg.test(text)) {
|
||||
let matches = text.match(val.reg);
|
||||
obj.name = val.name;
|
||||
obj.link = matches[0];
|
||||
obj.storage = val.storage;
|
||||
obj.storagePwdName = val.storagePwdName || null;
|
||||
if (val.replaceHost) {
|
||||
obj.link = obj.link.replace(val.host, val.replaceHost);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
//正则解析提取码
|
||||
parsePwd(text = '') {
|
||||
text = text.replace(/\u200B/g, '').replace('%3A', ":");
|
||||
text = text.replace(/(?:本帖)?隐藏的?内容[::]?/, "");
|
||||
let reg = /wss:[a-zA-Z0-9]+|(?<=\s*(?:密|提取|访问|訪問|key|password|pwd|#|\?p=)\s*[码碼]?\s*[::=]?\s*)[a-zA-Z0-9]{3,8}/i;
|
||||
if (reg.test(text)) {
|
||||
let match = text.match(reg);
|
||||
return match[0];
|
||||
}
|
||||
return '';
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
parseLink: main.parseLink,
|
||||
parsePwd: main.parsePwd,
|
||||
opt: opt
|
||||
}
|
||||
@@ -17,7 +17,7 @@ module.exports = {
|
||||
proxy: {
|
||||
'/': {
|
||||
target: 'http://127.0.0.1:6400', // 请求本地
|
||||
ws: true
|
||||
ws: false
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5,10 +5,11 @@ import cn.qaiu.entity.ShareLinkInfo;
|
||||
import cn.qaiu.lz.common.cache.CacheManager;
|
||||
import cn.qaiu.lz.common.util.URLParamUtil;
|
||||
import cn.qaiu.lz.web.model.LinkInfoResp;
|
||||
import cn.qaiu.lz.web.model.StatisticsInfo;
|
||||
import cn.qaiu.lz.web.model.SysUser;
|
||||
import cn.qaiu.lz.web.service.DbService;
|
||||
import cn.qaiu.lz.web.service.UserService;
|
||||
import cn.qaiu.lz.web.model.StatisticsInfo;
|
||||
import cn.qaiu.parser.PanDomainTemplate;
|
||||
import cn.qaiu.parser.ParserCreate;
|
||||
import cn.qaiu.vx.core.annotaions.RouteHandler;
|
||||
import cn.qaiu.vx.core.annotaions.RouteMapping;
|
||||
@@ -21,6 +22,12 @@ import io.vertx.core.http.HttpServerRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RouteHandler(value = "/v2", order = 10)
|
||||
@Slf4j
|
||||
public class ParserApi {
|
||||
@@ -76,4 +83,17 @@ public class ParserApi {
|
||||
return linkPrefix + (isJson ? "/json/" : "/d/") + create.genPathSuffix();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的网盘列表
|
||||
* @return list-map: name: 网盘名, type: 网盘标识, url: 网盘域名地址
|
||||
*/
|
||||
@RouteMapping("/getPanList")
|
||||
public List<Map<String, String>> getPanList() {
|
||||
return Arrays.stream(PanDomainTemplate.values()).map(pan -> new TreeMap<String, String>() {{
|
||||
put("name", pan.getDisplayName());
|
||||
put("type", pan.name().toLowerCase());
|
||||
put("url", pan.getPanDomain());
|
||||
}}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,11 +10,12 @@ server:
|
||||
# 反向代理服务器配置路径(不用加后缀)
|
||||
proxyConf: server-proxy
|
||||
|
||||
# vertx线程配置, 为0表示eventLoopPoolSize将会采用默认配置(CPU核心*2) workerPoolSize将会采用默认20
|
||||
# vertx核心线程配置(一般无需改的), 为0表示eventLoopPoolSize将会采用默认配置(CPU核心*2) workerPoolSize将会采用默认20
|
||||
vertx:
|
||||
eventLoopPoolSize: 0
|
||||
workerPoolSize: 0
|
||||
|
||||
# vertx-service配置(一般无需改的)
|
||||
custom:
|
||||
# 异步服务线程数
|
||||
asyncServiceInstances: 4
|
||||
|
||||
@@ -157,3 +157,17 @@ https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!4699&authkey=!AO7jjiGDnJW
|
||||
|
||||
###
|
||||
https://api.onedrive.com/v1.0/drives/abfd0a26e47d3458/items/ABFD0A26E47D3458!4699?authkey=!AO7jjiGDnJWoNwo
|
||||
|
||||
### 谷歌云盘
|
||||
https://drive.google.com/file/d/1iofiAmFs2NaBHp4OyeIo7sbVX-jQ0imB/view?usp=sharing
|
||||
###
|
||||
https://drive.google.com/file/d/151bR-nk-tOBm9QAFaozJIVt2WYyCMkoz/view?usp=drive_link
|
||||
#302链
|
||||
#https://drive.usercontent.google.com/uc?id=1iofiAmFs2NaBHp4OyeIo7sbVX-jQ0imB&export=download
|
||||
#直链
|
||||
#https://drive.usercontent.google.com/download?id=1iofiAmFs2NaBHp4OyeIo7sbVX-jQ0imB&export=download
|
||||
|
||||
#https://drive.usercontent.google.com/download?id=151bR-nk-tOBm9QAFaozJIVt2WYyCMkoz&export=download&confirm=t&uuid=bb8870cb-debd-4ba0-b239-aca14b6a9782&at=AENtkXYr-p2Bv0EDgKyXyYcZwOwA%3A1730526150700
|
||||
#https://drive.usercontent.google.com/download?id=151bR-nk-tOBm9QAFaozJIVt2WYyCMkoz&export=download&confirm=t&uuid=c9bb0ec9-3858-47a5-8cc1-979145b9d866&at=AENtkXaWSisZ7HO9EqxoIdY_38tX%3A1730526571780
|
||||
#https://drive.usercontent.google.com/download?id=1_qu7GTFzIm9GpUtzSmn8F8SOn3fqaOOu&export=download&confirm=t&uuid=&at=AENtkXaWSisZ7HO9EqxoIdY_38tX%3A1730526571780
|
||||
|
||||
|
||||
@@ -172,6 +172,9 @@ GET http://127.0.0.1:6400/json/parser?url=https://iwx.mail.qq.com/ftn/download?f
|
||||
###
|
||||
GET http://127.0.0.1:6400/v2/statisticsInfo
|
||||
|
||||
###
|
||||
GET http://127.0.0.1:6400/v2/getPanList
|
||||
|
||||
###
|
||||
GET http://127.0.0.1:6400/v2/linkInfo?url=https://www.123865.com/s/iaKtVv-6OECd.html&pwd=DcGe
|
||||
###
|
||||
@@ -198,7 +201,7 @@ GET http://127.0.0.1:6401/json/parser?url=https://iwx.mail.qq.com/ftn/download?f
|
||||
|
||||
### PASS CT
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6401/parser?url=https://474b.com/file/4015376-131945810
|
||||
GET http://127.0.0.1:6401/parser?url=https://123123-asd.474b.com/file/4015376-131945810
|
||||
|
||||
|
||||
### PASS MNE
|
||||
@@ -231,7 +234,7 @@ GET http://127.0.0.1:6401/parser?url=https://www.kugou.com/mixsong/9q98o5b9.html
|
||||
|
||||
### PASS MQW 酷我
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6401/parser?url=https://kuwo.cn/play_detail/395500809
|
||||
GET http://127.0.0.1:6401/parser?url=https://kuwo.cn/play_detail/394906263
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
<p> -- vert.x反向代理服务器(version 4.1.2)</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user