mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-17 04:43:02 +00:00
Compare commits
29 Commits
main-jdk11
...
0.1.8.bate
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
603afed2f2 | ||
|
|
c2a7c34496 | ||
|
|
edd40f48ba | ||
|
|
cca3d6b8b9 | ||
|
|
f004512903 | ||
|
|
6407bb6730 | ||
|
|
b914eeadec | ||
|
|
dcadc6783e | ||
|
|
bc9f43634f | ||
|
|
4778f0164c | ||
|
|
9904754a07 | ||
|
|
1b79077c9e | ||
|
|
c13afb05b3 | ||
|
|
03e320efb8 | ||
|
|
7846332476 | ||
|
|
2d5d3b86e0 | ||
|
|
7c9ba890af | ||
|
|
0d609daffa | ||
|
|
c12e56d402 | ||
|
|
c7b38c07d5 | ||
|
|
dc51066cea | ||
|
|
59d2fb3010 | ||
|
|
a0fe702c10 | ||
|
|
f886f7e366 | ||
|
|
1d475d88ed | ||
|
|
e64c901912 | ||
|
|
5fce02e623 | ||
|
|
13997bc543 | ||
|
|
3e05b0d6f9 |
28
.devcontainer/devcontainer.json
Normal file
28
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
|
// README at: https://github.com/devcontainers/templates/tree/main/src/java
|
||||||
|
{
|
||||||
|
"name": "Java",
|
||||||
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/java:0-17",
|
||||||
|
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/java:1": {
|
||||||
|
"version": "none",
|
||||||
|
"installMaven": "true",
|
||||||
|
"installGradle": "false"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers-contrib/features/ant-sdkman:2": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
// "postCreateCommand": "java -version",
|
||||||
|
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
// "customizations": {},
|
||||||
|
|
||||||
|
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||||
|
// "remoteUser": "root"
|
||||||
|
}
|
||||||
70
.vscode/launch.json
vendored
Normal file
70
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
// 使用 IntelliSense 了解相关属性。
|
||||||
|
// 悬停以查看现有属性的描述。
|
||||||
|
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "Current File",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "${file}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "StringCase",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.vx.core.util.StringCase",
|
||||||
|
"projectName": "core"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "FCURLParser",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.parser.FCURLParser",
|
||||||
|
"projectName": "parser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "QkTool",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.parser.impl.QkTool",
|
||||||
|
"projectName": "parser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "WebClientExample",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "qaiu.web.test.WebClientExample",
|
||||||
|
"projectName": "parser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "AppMain",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.lz.AppMain",
|
||||||
|
"projectName": "web-service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "TestJs",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.web.test.TestJs",
|
||||||
|
"projectName": "web-service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "TestOS",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.web.test.TestOS",
|
||||||
|
"projectName": "web-service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "WebProxyExamples",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "cn.qaiu.web.test.WebProxyExamples",
|
||||||
|
"projectName": "web-service"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"java.compile.nullAnalysis.mode": "automatic"
|
"java.compile.nullAnalysis.mode": "automatic",
|
||||||
|
"java.configuration.updateBuildConfiguration": "interactive"
|
||||||
}
|
}
|
||||||
86
README.md
86
README.md
@@ -1,5 +1,6 @@
|
|||||||
云盘解析服务 (nfd云解析)
|
云盘解析服务 (nfd云解析)
|
||||||
预览地址 https://lz.qaiu.top
|
预览地址 https://lz.qaiu.top
|
||||||
|
main分支依赖JDK17, 提供了JDK11分支[main-jdk11](https://github.com/qaiu/netdisk-fast-download/tree/main-jdk11)
|
||||||
**注意: 请不要过度依赖lz.qaiu.top预览地址服务,建议本地搭建或者云服务器自行搭建。
|
**注意: 请不要过度依赖lz.qaiu.top预览地址服务,建议本地搭建或者云服务器自行搭建。
|
||||||
解析次数过多IP会被部分网盘厂商限制,不推荐做公共解析。**
|
解析次数过多IP会被部分网盘厂商限制,不推荐做公共解析。**
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
网盘直链解析工具能把网盘分享下载链接转化为直链,已支持蓝奏云/蓝奏云优享/奶牛快传/移动云云空间/小飞机盘/亿方云/123云盘/Cloudreve等,支持加密分享。
|
网盘直链解析工具能把网盘分享下载链接转化为直链,已支持蓝奏云/蓝奏云优享/奶牛快传/移动云云空间/小飞机盘/亿方云/123云盘/Cloudreve等,支持加密分享。
|
||||||
|
|
||||||
|
|
||||||
*重要声明:本项目仅供学习参考;请不要将此项目用于任何商业用途,否则可能带来严重的后果。*
|
*重要声明:本项目仅供学习参考;请不要将此项目用于任何商业用途,否则可能带来严重的后果。转发/分享该项目请注明来源*
|
||||||
|
|
||||||
## 网盘支持情况:
|
## 网盘支持情况:
|
||||||
> 20230905 奶牛云直链做了防盗链,需加入请求头:Referer: https://cowtransfer.com/
|
> 20230905 奶牛云直链做了防盗链,需加入请求头:Referer: https://cowtransfer.com/
|
||||||
@@ -22,38 +23,17 @@
|
|||||||
`网盘名称(网盘标识):`
|
`网盘名称(网盘标识):`
|
||||||
|
|
||||||
- [蓝奏云 (lz)](https://pc.woozooo.com/)
|
- [蓝奏云 (lz)](https://pc.woozooo.com/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [蓝奏云优享 (iz)](https://www.ilanzou.com/)
|
- [蓝奏云优享 (iz)](https://www.ilanzou.com/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [奶牛快传 (cow)](https://cowtransfer.com/)
|
- [奶牛快传 (cow)](https://cowtransfer.com/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [移动云云空间 (ec)](https://www.ecpan.cn/web)
|
- [移动云云空间 (ec)](https://www.ecpan.cn/web)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [小飞机网盘 (fj)](https://www.feijipan.com/)
|
- [小飞机网盘 (fj)](https://www.feijipan.com/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [亿方云 (fc)](https://www.fangcloud.com/)
|
- [亿方云 (fc)](https://www.fangcloud.com/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [123云盘 (ye)](https://www.123pan.com/)
|
- [123云盘 (ye)](https://www.123pan.com/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析
|
|
||||||
- [文叔叔 (ws)](https://www.wenshushu.cn/)
|
- [文叔叔 (ws)](https://www.wenshushu.cn/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
- [联想乐云 (le)](https://lecloud.lenovo.com/)
|
||||||
- [X] 直链解析
|
- [QQ邮箱文件中转站 (qq)](https://mail.qq.com/)
|
||||||
- [Cloudreve自建网盘 (ce)](https://github.com/cloudreve/Cloudreve)
|
- [超星网盘-开发中 (cx)](https://passport2.chaoxing.com/login?newversion=true&refer=https%3A%2F%2Fpan-yz.chaoxing.com%2F)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
- [Cloudreve自建网盘--正在优化 (ce)](https://github.com/cloudreve/Cloudreve)
|
||||||
- [X] 直链解析
|
|
||||||
- [QQ邮箱 (qq) 暂不可用-存在cookie问题](https://wx.mail.qq.com/)
|
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
|
||||||
- [X] 直链解析(用户无法直接使用直链)
|
|
||||||
- [夸克网盘 (qk) 寄了](https://pan.quark.cn/)
|
|
||||||
- [UC网盘 (uc) 寄了](https://fast.uc.cn/)
|
|
||||||
|
|
||||||
**TODO:**
|
**TODO:**
|
||||||
- 登录接口, 文件上传/下载/分享后端接口
|
- 登录接口, 文件上传/下载/分享后端接口
|
||||||
- 短地址服务
|
- 短地址服务
|
||||||
@@ -61,49 +41,41 @@
|
|||||||
|
|
||||||
### API接口说明
|
### API接口说明
|
||||||
your_host指的是您的域名或者IP,实际使用时替换为实际域名或者IP,端口默认6400,可以使用nginx代理来做域名访问。
|
your_host指的是您的域名或者IP,实际使用时替换为实际域名或者IP,端口默认6400,可以使用nginx代理来做域名访问。
|
||||||
解析方式分为两种类型直接跳转下载链接和获取下载链接(JSON),每一种都提供了两种接口形式parser和网盘标志/分享key拼接的短地址(标志短链),所有规则参考示例。
|
解析方式分为两种类型直接跳转下载文件和获取下载链接,每一种都提供了两种接口形式parser和网盘标志/分享key拼接的短地址(标志短链),所有规则参考示例。
|
||||||
- 通用接口: `/parser?url=分享链接`,加密分享需要加上参数pwd=密码;
|
- 通用接口: `/parser?url=分享链接`,加密分享需要加上参数pwd=密码;
|
||||||
- 标志短链: `/网盘标识/分享key` 在分享Key后面加上@密码;
|
- 标志短链: `/网盘标识/分享key` 在分享Key后面加上@密码;
|
||||||
- 直链JSON: `通用接口`和`标志短链`前加上`/json` 加密分享的密码规则同上;
|
- 直链JSON: `通用接口`和`标志短链`前加上`/json` 加密分享的密码规则同上;
|
||||||
- 网盘标识参考上面网盘支持情况
|
- 网盘标识参考上面网盘支持情况
|
||||||
- 括号内是可选内容: 表示当带有分享密码时需要加上密码参数
|
- 当带有分享密码时需要加上密码参数(pwd)
|
||||||
- 移动云云空间,小飞机网盘的加密分享的密码可以忽略
|
- 移动云云空间,小飞机网盘的加密分享的密码可以忽略
|
||||||
- 移动云空间分享key取分享链接中的data参数,比如`&data=xxx`的参数就是xxx
|
- 移动云空间分享key取分享链接中的data参数,比如`&data=xxx`的参数就是xxx
|
||||||
|
|
||||||
规则示例:
|
API规则:
|
||||||
```
|
```
|
||||||
|
|
||||||
1. 解析并自动302跳转 :
|
1. 解析并自动302跳转 :
|
||||||
http://your_host/parser?url=分享链接(&pwd=xxx)
|
http://your_host/parser?url=分享链接&pwd=xxx
|
||||||
http://your_host/网盘标识/分享key(@分享密码)
|
http://your_host/网盘标识/分享key@分享密码
|
||||||
2. 获取解析后的直链--JSON格式
|
2. 获取解析后的直链--JSON格式
|
||||||
http://your_host/json/parser?url=分享链接(&pwd=xxx)
|
http://your_host/json/parser?url=分享链接&pwd=xxx
|
||||||
http://your_host/json/网盘标识/分享key(@分享密码)
|
http://your_host/json/网盘标识/分享key@分享密码
|
||||||
3. 需要特殊处理的网盘分享:
|
|
||||||
1. 移动云云空间(ec)使用parser?url= 解析时因为分享链接比较特殊(链接带有参数且含有#符号)所以要么对#进行转义%23要么直接去掉# 或者URL直接是主机名+'/'跟一个data参数
|
|
||||||
比如 http://your_host/parser?url=https://www.ecpan.cn/web//yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
|
||||||
http://your_host/parser?url=https://www.ecpan.cn/web/%23/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
|
||||||
http://your_host/parser?url=https://www.ecpan.cn/&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
|
||||||
|
|
||||||
2. Cloudreve自建网盘解析规则:
|
|
||||||
1. 标志短链: 根据网盘使用https和http选择 http://your_host/ce/https_网盘域名_s_wDz5TK 或 http://your_host/ce/http_网盘域名_s_wDz5TK
|
|
||||||
网盘域名指的是Cloudreve搭建网盘的主域名比如pan.huang1111.cn,如果存在子路径需要将/替换为_,是否存在子路径看分享链接格式是否是://网盘域名/子路径/s/xxx,一般不存在子路径:网盘域名/s/xxx,
|
|
||||||
比如: http://127.0.0.1:6400/ce/https_pan.huang1111.cn_s_wDz5TK
|
|
||||||
2. parser接口 -> http://your_host/parser?url=分享链接(&pwd=xxx)
|
|
||||||
比如: http://127.0.0.1:6400/parser?url=https://pan.huang1111.cn/s/wDz5TK
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
json返回数据格式示例:
|
json返回数据格式示例:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"code": 200,
|
"code": 200,
|
||||||
"msg": "success",
|
"msg": "success",
|
||||||
"success": true,
|
"success": true,
|
||||||
"count": 0,
|
"count": 0,
|
||||||
"data": "https://下载链接",
|
"data": {
|
||||||
"timestamp": 1690733953927
|
"shareKey": "lz:xxx",
|
||||||
|
"directLink": "下载直链",
|
||||||
|
"cacheHit": true,
|
||||||
|
"expires": "2024-09-18 01:48:02",
|
||||||
|
"expiration": 1726638482825
|
||||||
|
},
|
||||||
|
"timestamp": 1726637151902
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -179,7 +151,7 @@ mvn package
|
|||||||
> 注意: netdisk-fast-download.service中的ExecStart的路径改为实际路径
|
> 注意: netdisk-fast-download.service中的ExecStart的路径改为实际路径
|
||||||
```shell
|
```shell
|
||||||
cd ~
|
cd ~
|
||||||
wget -O netdisk-fast-download.zip https://github.com/qaiu/netdisk-fast-download/releases/download/0.1.7-release-fixed2/netdisk-fast-download-bin-fixed2.zip
|
wget -O netdisk-fast-download.zip https://github.com/qaiu/netdisk-fast-download/releases/download/0.1.8-release-fixed2/netdisk-fast-download-bin-fixed2.zip
|
||||||
unzip netdisk-fast-download-bin.zip
|
unzip netdisk-fast-download-bin.zip
|
||||||
cd netdisk-fast-download
|
cd netdisk-fast-download
|
||||||
bash service-install.sh
|
bash service-install.sh
|
||||||
@@ -213,9 +185,9 @@ bash service-install.sh
|
|||||||
|
|
||||||
## 0.1.8 开发计划
|
## 0.1.8 开发计划
|
||||||
- Docker部署
|
- Docker部署
|
||||||
- 联想乐云解析
|
- 联想乐云解析 √
|
||||||
- 直链缓存
|
- 直链缓存 √
|
||||||
- 日志优化
|
- 日志优化 √
|
||||||
|
|
||||||
|
|
||||||
**技术栈:**
|
**技术栈:**
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static cn.qaiu.vx.core.util.ConfigConstant.ROUTE_TIME_OUT;
|
import static cn.qaiu.vx.core.util.ConfigConstant.ROUTE_TIME_OUT;
|
||||||
import static io.vertx.core.http.HttpHeaders.*;
|
import static io.vertx.core.http.HttpHeaders.*;
|
||||||
|
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由映射, 参数绑定
|
* 路由映射, 参数绑定
|
||||||
@@ -87,6 +89,7 @@ public class RouterHandlerFactory implements BaseHttpApi {
|
|||||||
LOGGER.debug("The HTTP service request address information ===>path:{}, uri:{}, method:{}",
|
LOGGER.debug("The HTTP service request address information ===>path:{}, uri:{}, method:{}",
|
||||||
ctx.request().path(), ctx.request().absoluteURI(), ctx.request().method());
|
ctx.request().path(), ctx.request().absoluteURI(), ctx.request().method());
|
||||||
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||||
|
ctx.response().headers().add(DATE, LocalDateTime.now().format(ISO_LOCAL_DATE_TIME));
|
||||||
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, OPTIONS, PUT, DELETE, HEAD");
|
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, OPTIONS, PUT, DELETE, HEAD");
|
||||||
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_HEADERS, "X-PINGOTHER, Origin,Content-Type, Accept, " +
|
ctx.response().headers().add(ACCESS_CONTROL_ALLOW_HEADERS, "X-PINGOTHER, Origin,Content-Type, Accept, " +
|
||||||
"X-Requested-With, Dev, Authorization, Version, Token");
|
"X-Requested-With, Dev, Authorization, Version, Token");
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ public interface ConfigConstant {
|
|||||||
String EVENT_LOOP_POOL_SIZE = "eventLoopPoolSize";
|
String EVENT_LOOP_POOL_SIZE = "eventLoopPoolSize";
|
||||||
String LOCAL = "local";
|
String LOCAL = "local";
|
||||||
String SERVER = "server";
|
String SERVER = "server";
|
||||||
|
String CACHE = "cache";
|
||||||
String GLOBAL_CONFIG = "globalConfig";
|
String GLOBAL_CONFIG = "globalConfig";
|
||||||
String CUSTOM_CONFIG = "customConfig";
|
String CUSTOM_CONFIG = "customConfig";
|
||||||
String ASYNC_SERVICE_INSTANCES = "asyncServiceInstances";
|
String ASYNC_SERVICE_INSTANCES = "asyncServiceInstances";
|
||||||
|
|||||||
114
parser/src/main/java/cn/qaiu/entity/ShareLinkInfo.java
Normal file
114
parser/src/main/java/cn/qaiu/entity/ShareLinkInfo.java
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package cn.qaiu.entity;
|
||||||
|
|
||||||
|
public class ShareLinkInfo {
|
||||||
|
|
||||||
|
private String shareKey; // 分享键
|
||||||
|
private String type; // 分享类型
|
||||||
|
private String sharePassword; // 分享密码(如果存在)
|
||||||
|
private String shareUrl; // 原始分享链接
|
||||||
|
private String standardUrl; // 规范化的标准链接
|
||||||
|
|
||||||
|
private ShareLinkInfo(Builder builder) {
|
||||||
|
this.shareKey = builder.shareKey;
|
||||||
|
this.type = builder.type;
|
||||||
|
this.sharePassword = builder.sharePassword;
|
||||||
|
this.shareUrl = builder.shareUrl;
|
||||||
|
this.standardUrl = builder.standardUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter和Setter方法
|
||||||
|
|
||||||
|
public String getShareKey() {
|
||||||
|
return shareKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShareKey(String shareKey) {
|
||||||
|
this.shareKey = shareKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSharePassword() {
|
||||||
|
return sharePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSharePassword(String sharePassword) {
|
||||||
|
this.sharePassword = sharePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShareUrl() {
|
||||||
|
return shareUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShareUrl(String shareUrl) {
|
||||||
|
this.shareUrl = shareUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStandardUrl() {
|
||||||
|
return standardUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStandardUrl(String standardUrl) {
|
||||||
|
this.standardUrl = standardUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 静态方法创建建造者对象
|
||||||
|
public static ShareLinkInfo.Builder newBuilder() {
|
||||||
|
return new ShareLinkInfo.Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 建造者类
|
||||||
|
public static class Builder {
|
||||||
|
private String shareKey; // 分享键
|
||||||
|
private String type; // 分享类型 (网盘模板枚举的小写)
|
||||||
|
private String sharePassword = ""; // 分享密码(如果存在)
|
||||||
|
private String shareUrl; // 原始分享链接
|
||||||
|
private String standardUrl; // 规范化的标准链接
|
||||||
|
|
||||||
|
public Builder shareKey(String shareKey) {
|
||||||
|
this.shareKey = shareKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder type(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder sharePassword(String sharePassword) {
|
||||||
|
this.sharePassword = sharePassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder shareUrl(String shareUrl) {
|
||||||
|
this.shareUrl = shareUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder standardUrl(String standardUrl) {
|
||||||
|
this.standardUrl = standardUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShareLinkInfo build() {
|
||||||
|
return new ShareLinkInfo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ShareLinkInfo{" +
|
||||||
|
"shareKey='" + shareKey + '\'' +
|
||||||
|
", type='" + type + '\'' +
|
||||||
|
", sharePassword='" + sharePassword + '\'' +
|
||||||
|
", shareUrl='" + shareUrl + '\'' +
|
||||||
|
", standardUrl='" + standardUrl + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,62 +1,7 @@
|
|||||||
package cn.qaiu.parser;//package cn.qaiu.lz.common.parser;
|
package cn.qaiu.parser;//package cn.qaiu.lz.common.parser;
|
||||||
|
|
||||||
import cn.qaiu.parser.impl.*;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
|
|
||||||
public interface IPanTool {
|
public interface IPanTool {
|
||||||
Future<String> parse();
|
Future<String> parse();
|
||||||
|
|
||||||
static IPanTool typeMatching(String type, String key, String pwd) {
|
|
||||||
return switch (type) {
|
|
||||||
case "lz" -> new LzTool(key, pwd);
|
|
||||||
case "cow" -> new CowTool(key, pwd);
|
|
||||||
case "ec" -> new EcTool(key, pwd);
|
|
||||||
case "fc" -> new FcTool(key, pwd);
|
|
||||||
case "uc" -> new UcTool(key, pwd);
|
|
||||||
case "ye" -> new YeTool(key, pwd);
|
|
||||||
case "fj" -> new FjTool(key, pwd);
|
|
||||||
case "qk" -> new QkTool(key, pwd);
|
|
||||||
case "le" -> new LeTool(key, pwd);
|
|
||||||
case "ws" -> new WsTool(key, pwd);
|
|
||||||
case "qq" -> new QQTool(key, pwd);
|
|
||||||
case "iz" -> new IzTool(key, pwd);
|
|
||||||
case "ce" -> new CeTool(key, pwd);
|
|
||||||
default -> {
|
|
||||||
throw new UnsupportedOperationException("未知分享类型");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static IPanTool shareURLPrefixMatching(String url, String pwd) {
|
|
||||||
|
|
||||||
if (url.contains(CowTool.LINK_KEY)) {
|
|
||||||
return new CowTool(url, pwd);
|
|
||||||
} else if (url.startsWith(EcTool.SHARE_URL_PREFIX)) {
|
|
||||||
return new EcTool(url, pwd);
|
|
||||||
} else if (url.startsWith(FcTool.SHARE_URL_PREFIX0)) {
|
|
||||||
return new FcTool(url, pwd);
|
|
||||||
} else if (url.startsWith(UcTool.SHARE_URL_PREFIX)) {
|
|
||||||
return new UcTool(url, pwd);
|
|
||||||
} else if (url.startsWith(YeTool.SHARE_URL_PREFIX)) {
|
|
||||||
return new YeTool(url, pwd);
|
|
||||||
} else if (url.startsWith(FjTool.SHARE_URL_PREFIX) || url.startsWith(FjTool.SHARE_URL_PREFIX2)) {
|
|
||||||
return new FjTool(url, pwd);
|
|
||||||
} else if (url.startsWith(IzTool.SHARE_URL_PREFIX)) {
|
|
||||||
return new IzTool(url, pwd);
|
|
||||||
} else if (url.contains(LzTool.LINK_KEY)) {
|
|
||||||
return new LzTool(url, pwd);
|
|
||||||
} else if (url.startsWith(LeTool.SHARE_URL_PREFIX)) {
|
|
||||||
return new LeTool(url, pwd);
|
|
||||||
} else if (url.contains(WsTool.SHARE_URL_PREFIX) || url.contains(WsTool.SHARE_URL_PREFIX2)) {
|
|
||||||
return new WsTool(url, pwd);
|
|
||||||
} else if (url.contains(QQTool.SHARE_URL_PREFIX)) {
|
|
||||||
return new QQTool(url, pwd);
|
|
||||||
} else if (url.contains("/s/")) {
|
|
||||||
// Cloudreve 网盘通用解析
|
|
||||||
return new CeTool(url, pwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new UnsupportedOperationException("未知分享类型");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package cn.qaiu.parser;
|
package cn.qaiu.parser;
|
||||||
|
|
||||||
import cn.qaiu.WebClientVertxInit;
|
import cn.qaiu.WebClientVertxInit;
|
||||||
import cn.qaiu.util.CommonUtils;
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
import io.vertx.ext.web.client.WebClient;
|
||||||
@@ -35,16 +35,7 @@ public abstract class PanBase {
|
|||||||
protected WebClient clientNoRedirects = WebClient.create(WebClientVertxInit.get(),
|
protected WebClient clientNoRedirects = WebClient.create(WebClientVertxInit.get(),
|
||||||
new WebClientOptions().setFollowRedirects(false));
|
new WebClientOptions().setFollowRedirects(false));
|
||||||
|
|
||||||
/**
|
protected ShareLinkInfo shareLinkInfo;
|
||||||
* 分享key 可以是整个URL; 如果是URL实现该类时要
|
|
||||||
* 使用{@link CommonUtils#adaptShortPaths(String urlPrefix, String key)}获取真实的分享key
|
|
||||||
*/
|
|
||||||
protected String key;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分享密码
|
|
||||||
*/
|
|
||||||
protected String pwd;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 子类重写此构造方法不需要添加额外逻辑
|
* 子类重写此构造方法不需要添加额外逻辑
|
||||||
@@ -55,12 +46,9 @@ public abstract class PanBase {
|
|||||||
* }
|
* }
|
||||||
* </pre></blockquote>
|
* </pre></blockquote>
|
||||||
*
|
*
|
||||||
* @param key 分享key/url
|
|
||||||
* @param pwd 分享密码
|
|
||||||
*/
|
*/
|
||||||
protected PanBase(String key, String pwd) {
|
public PanBase(ShareLinkInfo shareLinkInfo) {
|
||||||
this.key = key;
|
this.shareLinkInfo = shareLinkInfo;
|
||||||
this.pwd = pwd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
116
parser/src/main/java/cn/qaiu/parser/PanDomainTemplate.java
Normal file
116
parser/src/main/java/cn/qaiu/parser/PanDomainTemplate.java
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package cn.qaiu.parser;
|
||||||
|
|
||||||
|
import cn.qaiu.parser.impl.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举类 PanDomainTemplate 定义了不同网盘服务的模板信息,包括:
|
||||||
|
* <ul>
|
||||||
|
* <li>displayName: 网盘服务的显示名称,用于用户界面展示。</li>
|
||||||
|
* <li>regexPattern: 用于匹配和解析分享链接的正则表达式。</li>
|
||||||
|
* <li>standardUrlTemplate: 网盘服务的标准URL模板,用于规范化分享链接。</li>
|
||||||
|
* <li>toolClass: 网盘解析工具实现类。</li>
|
||||||
|
* </ul>
|
||||||
|
* 请注意:增添网盘时,保证正则表达式最后一个捕捉组能匹配到分享key
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* at 2023/6/13 4:26
|
||||||
|
*/
|
||||||
|
public enum PanDomainTemplate {
|
||||||
|
|
||||||
|
// 网盘定义
|
||||||
|
LZ("蓝奏云",
|
||||||
|
"https://([a-z]+)?\\.?lanzou[a-z]\\.com/(.+/)?(.+)",
|
||||||
|
"https://lanzoux.com/{shareKey}",
|
||||||
|
LzTool.class),
|
||||||
|
|
||||||
|
// https://www.feijix.com/s/
|
||||||
|
// https://share.feijipan.com/s/
|
||||||
|
FJ("小飞机网盘",
|
||||||
|
"https://(share\\.feijipan\\.com|www\\.feijix\\.com)/s/(.+)",
|
||||||
|
"https://www.feijix.com/s/{shareKey}",
|
||||||
|
FjTool.class),
|
||||||
|
|
||||||
|
// https://lecloud.lenovo.com/share/
|
||||||
|
LE("联想乐云",
|
||||||
|
"https://lecloud?\\.lenovo\\.com/share/(.+)",
|
||||||
|
"https://lecloud.lenovo.com/share/{shareKey}",
|
||||||
|
LeTool.class),
|
||||||
|
|
||||||
|
// https://v2.fangcloud.com/s/
|
||||||
|
FC("亿方云",
|
||||||
|
"https://v2\\.fangcloud\\.(com|cn)/(s|sharing)/([^/]+)",
|
||||||
|
"https://v2.fangcloud.com/s/{shareKey}",
|
||||||
|
FcTool.class),
|
||||||
|
// https://www.ilanzou.com/s/
|
||||||
|
IZ("蓝奏云优享",
|
||||||
|
"https://www\\.ilanzou\\.com/s/(.+)",
|
||||||
|
"https://www.ilanzou.com/s/{shareKey}",
|
||||||
|
IzTool.class),
|
||||||
|
// https://wx.mail.qq.com/ftn/download?
|
||||||
|
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("文叔叔",
|
||||||
|
"https://(f\\.ws59\\.cn|www\\.wenshushu\\.cn)/f/(.+)",
|
||||||
|
"https://f.ws59.cn/f/{shareKey}",
|
||||||
|
WsTool.class),
|
||||||
|
// https://www.123pan.com/s/
|
||||||
|
YE("123网盘",
|
||||||
|
"https://www\\.123pan\\.com/s/(.+)",
|
||||||
|
"https://www.123pan.com/s/{shareKey}",
|
||||||
|
YeTool.class),
|
||||||
|
// https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data={code}&isShare=1
|
||||||
|
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("奶牛快传",
|
||||||
|
"https://(.*)cowtransfer\\.com/s/(.+)",
|
||||||
|
"https://cowtransfer.com/s/{shareKey}",
|
||||||
|
CowTool.class),
|
||||||
|
// https://pan.huang1111.cn/s/
|
||||||
|
CE("huang1111",
|
||||||
|
"https://pan\\.huang1111\\.cn/s/(.+)",
|
||||||
|
"https://pan.huang1111.cn/s/{shareKey}",
|
||||||
|
CeTool.class);
|
||||||
|
|
||||||
|
|
||||||
|
// 网盘的显示名称,用于用户界面显示
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
|
// 用于匹配和解析分享链接的正则表达式,保证最后一个捕捉组能匹配到分享key
|
||||||
|
private final String regexPattern;
|
||||||
|
|
||||||
|
// 网盘的标准链接模板,不含占位符,用于规范化分享链接
|
||||||
|
private final String standardUrlTemplate;
|
||||||
|
|
||||||
|
// 指向解析工具IPanTool实现类
|
||||||
|
private final Class<? extends IPanTool> toolClass;
|
||||||
|
|
||||||
|
PanDomainTemplate(String displayName, String regexPattern, String standardUrlTemplate,
|
||||||
|
Class<? extends IPanTool> toolClass) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.regexPattern = regexPattern;
|
||||||
|
this.standardUrlTemplate = standardUrlTemplate;
|
||||||
|
this.toolClass = toolClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRegexPattern() {
|
||||||
|
return regexPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStandardUrlTemplate() {
|
||||||
|
return standardUrlTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
@@ -7,9 +8,6 @@ import io.vertx.core.buffer.Buffer;
|
|||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.HttpRequest;
|
import io.vertx.ext.web.client.HttpRequest;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://github.com/cloudreve/Cloudreve">Cloudreve网盘解析</a> <br>
|
* <a href="https://github.com/cloudreve/Cloudreve">Cloudreve网盘解析</a> <br>
|
||||||
* <a href="https://pan.xiaomuxi.cn">暮希云盘</a> <br>
|
* <a href="https://pan.xiaomuxi.cn">暮希云盘</a> <br>
|
||||||
@@ -17,34 +15,40 @@ import java.net.URL;
|
|||||||
*/
|
*/
|
||||||
public class CeTool extends PanBase implements IPanTool {
|
public class CeTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
private static final String DOWNLOAD_API_PATH = "/api/v3/share/download/";
|
private static final String DOWNLOAD_API_PATH = "https://pan.huang1111.cn/api/v3/share/download/";
|
||||||
|
|
||||||
// api/v3/share/info/g31PcQ?password=qaiu
|
// api/v3/share/info/g31PcQ?password=qaiu
|
||||||
private static final String SHARE_API_PATH = "/api/v3/share/info/";
|
private static final String SHARE_API_PATH = "https://pan.huang1111.cn/api/v3/share/info/";
|
||||||
|
|
||||||
public CeTool(String key, String pwd) {
|
public CeTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
|
String key = shareLinkInfo.getShareKey();
|
||||||
|
String pwd = shareLinkInfo.getSharePassword();
|
||||||
// https://pan.huang1111.cn/s/wDz5TK
|
// https://pan.huang1111.cn/s/wDz5TK
|
||||||
// https://pan.huang1111.cn/s/y12bI6 -> https://pan.huang1111
|
// https://pan.huang1111.cn/s/y12bI6 -> https://pan.huang1111
|
||||||
// .cn/api/v3/share/download/y12bI6?path=undefined%2Fundefined;
|
// .cn/api/v3/share/download/y12bI6?path=undefined%2Fundefined;
|
||||||
// 类型解析 -> /ce/https_pan.huang1111.cn_s_wDz5TK
|
// 类型解析 -> /ce/https_pan.huang1111.cn_s_wDz5TK
|
||||||
// parser接口 -> /parser?url=https://pan.huang1111.cn/s/wDz5TK
|
// parser接口 -> /parser?url=https://pan.huang1111.cn/s/wDz5TK
|
||||||
try {
|
try {
|
||||||
if (key.startsWith("https_") || key.startsWith("http_")) {
|
// if (key.startsWith("https_") || key.startsWith("http_")) {
|
||||||
key = key.replace("https_", "https://")
|
// key = key.replace("https_", "https://")
|
||||||
.replace("http_", "http://")
|
// .replace("http_", "http://")
|
||||||
.replace("_", "/");
|
// .replace("_", "/");
|
||||||
}
|
// }
|
||||||
// 处理URL
|
// // 处理URL
|
||||||
URL url = new URL(key);
|
// URL url = new URL(key);
|
||||||
String path = url.getPath();
|
// String path = url.getPath();
|
||||||
String shareKey = path.substring(3);
|
// String shareKey = path.substring(3);
|
||||||
String downloadApiUrl = url.getProtocol() + "://" + url.getHost() + DOWNLOAD_API_PATH + shareKey + "?path" +
|
// String downloadApiUrl = url.getProtocol() + "://" + url.getHost() + DOWNLOAD_API_PATH + shareKey + "?path" +
|
||||||
"=undefined/undefined;";
|
// "=undefined/undefined;";
|
||||||
String shareApiUrl = url.getProtocol() + "://" + url.getHost() + SHARE_API_PATH + shareKey;
|
// String shareApiUrl = url.getProtocol() + "://" + url.getHost() + SHARE_API_PATH + shareKey;
|
||||||
|
|
||||||
|
var shareApiUrl = SHARE_API_PATH;
|
||||||
|
var downloadApiUrl = DOWNLOAD_API_PATH;
|
||||||
|
|
||||||
// 设置cookie
|
// 设置cookie
|
||||||
HttpRequest<Buffer> httpRequest = clientSession.getAbs(shareApiUrl);
|
HttpRequest<Buffer> httpRequest = clientSession.getAbs(shareApiUrl);
|
||||||
@@ -53,7 +57,7 @@ public class CeTool extends PanBase implements IPanTool {
|
|||||||
}
|
}
|
||||||
// 获取下载链接
|
// 获取下载链接
|
||||||
httpRequest.send().onSuccess(res -> getDownURL(downloadApiUrl)).onFailure(handleFail(shareApiUrl));
|
httpRequest.send().onSuccess(res -> getDownURL(downloadApiUrl)).onFailure(handleFail(shareApiUrl));
|
||||||
} catch (MalformedURLException e) {
|
} catch (Exception e) {
|
||||||
fail(e, "URL解析错误");
|
fail(e, "URL解析错误");
|
||||||
}
|
}
|
||||||
return promise.future();
|
return promise.future();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -16,16 +16,14 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
public class CowTool extends PanBase implements IPanTool {
|
public class CowTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
private static final String API_REQUEST_URL = "https://cowtransfer.com/core/api/transfer/share";
|
private static final String API_REQUEST_URL = "https://cowtransfer.com/core/api/transfer/share";
|
||||||
public static final String SHARE_URL_PREFIX = "https://cowtransfer.com/s/";
|
|
||||||
|
|
||||||
public static final String LINK_KEY = "cowtransfer.com/s/";
|
public CowTool(ShareLinkInfo shareLinkInfo) {
|
||||||
|
super(shareLinkInfo);
|
||||||
public CowTool(String key, String pwd) {
|
|
||||||
super(key, pwd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
key = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
final String key = shareLinkInfo.getShareKey();
|
||||||
String url = API_REQUEST_URL + "?uniqueUrl=" + key;
|
String url = API_REQUEST_URL + "?uniqueUrl=" + key;
|
||||||
client.getAbs(url).send().onSuccess(res -> {
|
client.getAbs(url).send().onSuccess(res -> {
|
||||||
JsonObject resJson = res.bodyAsJsonObject();
|
JsonObject resJson = res.bodyAsJsonObject();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
@@ -12,20 +12,22 @@ import io.vertx.uritemplate.UriTemplate;
|
|||||||
* 移动云空间解析
|
* 移动云空间解析
|
||||||
*/
|
*/
|
||||||
public class EcTool extends PanBase implements IPanTool {
|
public class EcTool extends PanBase implements IPanTool {
|
||||||
|
// https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=4b3d786755688b85c6eb0c04b9124f4dalzdaJpXHx&isShare=1
|
||||||
private static final String FIRST_REQUEST_URL = "https://www.ecpan.cn/drive/fileextoverrid" +
|
private static final String FIRST_REQUEST_URL = "https://www.ecpan.cn/drive/fileextoverrid" +
|
||||||
".do?extractionCode={extractionCode}&chainUrlTemplate=https:%2F%2Fwww.ecpan" +
|
".do?extractionCode={extractionCode}&chainUrlTemplate=https:%2F%2Fwww.ecpan" +
|
||||||
".cn%2Fweb%2F%23%2FyunpanProxy%3Fpath%3D%252F%2523%252Fdrive%252Foutside&parentId=-1&data={dataKey}";
|
".cn%2Fweb%2F%23%2FyunpanProxy%3Fpath%3D%252F%2523%252Fdrive%252Foutside&parentId=-1&data={dataKey}";
|
||||||
|
|
||||||
private static final String DOWNLOAD_REQUEST_URL = "https://www.ecpan.cn/drive/sharedownload.do";
|
private static final String DOWNLOAD_REQUEST_URL = "https://www.ecpan.cn/drive/sharedownload.do";
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "www.ecpan.cn/";
|
public EcTool(ShareLinkInfo shareLinkInfo) {
|
||||||
|
super(shareLinkInfo);
|
||||||
public EcTool(String key, String pwd) {
|
|
||||||
super(key, pwd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
final String dataKey = shareLinkInfo.getShareKey();
|
||||||
|
final String pwd = shareLinkInfo.getSharePassword();
|
||||||
|
|
||||||
// 第一次请求 获取文件信息
|
// 第一次请求 获取文件信息
|
||||||
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL))
|
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL))
|
||||||
.setTemplateParam("dataKey", dataKey)
|
.setTemplateParam("dataKey", dataKey)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.MultiMap;
|
import io.vertx.core.MultiMap;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
@@ -21,19 +21,19 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public class FcTool extends PanBase implements IPanTool {
|
public class FcTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX0 = "https://v2.fangcloud.com/s";
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://v2.fangcloud.com/sharing/";
|
public static final String SHARE_URL_PREFIX = "https://v2.fangcloud.com/sharing/";
|
||||||
public static final String SHARE_URL_PREFIX2 = "https://v2.fangcloud.cn/sharing/";
|
public static final String SHARE_URL_PREFIX2 = "https://v2.fangcloud.cn/sharing/";
|
||||||
private static final String DOWN_REQUEST_URL = "https://v2.fangcloud.cn/apps/files/download?file_id={fid}" +
|
private static final String DOWN_REQUEST_URL = "https://v2.fangcloud.cn/apps/files/download?file_id={fid}" +
|
||||||
"&scenario=share&unique_name={uname}";
|
"&scenario=share&unique_name={uname}";
|
||||||
|
|
||||||
public FcTool(String key, String pwd) {
|
public FcTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String data = key.replace("share","sharing");
|
final String dataKey = shareLinkInfo.getShareKey();
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
final String pwd = shareLinkInfo.getSharePassword();
|
||||||
WebClientSession sClient = WebClientSession.create(client);
|
WebClientSession sClient = WebClientSession.create(client);
|
||||||
// 第一次请求 自动重定向
|
// 第一次请求 自动重定向
|
||||||
sClient.getAbs(SHARE_URL_PREFIX + dataKey).send().onSuccess(res -> {
|
sClient.getAbs(SHARE_URL_PREFIX + dataKey).send().onSuccess(res -> {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.AESUtils;
|
import cn.qaiu.util.AESUtils;
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import cn.qaiu.util.UUIDUtil;
|
import cn.qaiu.util.UUIDUtil;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.MultiMap;
|
import io.vertx.core.MultiMap;
|
||||||
@@ -18,10 +18,7 @@ import io.vertx.uritemplate.UriTemplate;
|
|||||||
* @version V016_230609
|
* @version V016_230609
|
||||||
*/
|
*/
|
||||||
public class FjTool extends PanBase implements IPanTool {
|
public class FjTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://www.feijix.com/s/";
|
|
||||||
public static final String REFERER_URL = "https://share.feijipan.com/";
|
public static final String REFERER_URL = "https://share.feijipan.com/";
|
||||||
public static final String SHARE_URL_PREFIX2 = REFERER_URL + "s/";
|
|
||||||
private static final String API_URL_PREFIX = "https://api.feijipan.com/ws/";
|
private static final String API_URL_PREFIX = "https://api.feijipan.com/ws/";
|
||||||
|
|
||||||
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "recommend/list?devType=6&devModel=Chrome" +
|
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "recommend/list?devType=6&devModel=Chrome" +
|
||||||
@@ -38,19 +35,14 @@ public class FjTool extends PanBase implements IPanTool {
|
|||||||
"={uuid}&extra=2×tamp={ts}";
|
"={uuid}&extra=2×tamp={ts}";
|
||||||
// https://api.feijipan.com/ws/buy/vip/list?devType=6&devModel=Chrome&uuid=WQAl5yBy1naGudJEILBvE&extra=2×tamp=E2C53155F6D09417A27981561134CB73
|
// https://api.feijipan.com/ws/buy/vip/list?devType=6&devModel=Chrome&uuid=WQAl5yBy1naGudJEILBvE&extra=2×tamp=E2C53155F6D09417A27981561134CB73
|
||||||
|
|
||||||
public FjTool(String key, String pwd) {
|
public FjTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String dataKey;
|
final String dataKey = shareLinkInfo.getShareKey();
|
||||||
if (key.startsWith(SHARE_URL_PREFIX2)) {
|
|
||||||
dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX2, key);
|
|
||||||
} else {
|
|
||||||
dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 240530 此处shareId又改为了原始的shareId, nm玩呢?
|
// 240530 此处shareId又改为了原始的shareId
|
||||||
String shareId = dataKey; // String.valueOf(AESUtils.idEncrypt(dataKey));
|
String shareId = dataKey; // String.valueOf(AESUtils.idEncrypt(dataKey));
|
||||||
long nowTs = System.currentTimeMillis();
|
long nowTs = System.currentTimeMillis();
|
||||||
String tsEncode = AESUtils.encrypt2Hex(Long.toString(nowTs));
|
String tsEncode = AESUtils.encrypt2Hex(Long.toString(nowTs));
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.AESUtils;
|
import cn.qaiu.util.AESUtils;
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.MultiMap;
|
import io.vertx.core.MultiMap;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
@@ -26,12 +26,12 @@ public class IzTool extends PanBase implements IPanTool {
|
|||||||
private static final String SECOND_REQUEST_URL = API_URL_PREFIX + "file/redirect?downloadId={fidEncode}&enable=1" +
|
private static final String SECOND_REQUEST_URL = API_URL_PREFIX + "file/redirect?downloadId={fidEncode}&enable=1" +
|
||||||
"&devType=6&uuid={uuid}×tamp={ts}&auth={auth}";
|
"&devType=6&uuid={uuid}×tamp={ts}&auth={auth}";
|
||||||
|
|
||||||
public IzTool(String key, String pwd) {
|
public IzTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
String dataKey = shareLinkInfo.getShareKey();
|
||||||
|
|
||||||
// 24.5.12 ilanzou改规则无需计算shareId
|
// 24.5.12 ilanzou改规则无需计算shareId
|
||||||
// String shareId = String.valueOf(AESUtils.idEncryptIz(dataKey));
|
// String shareId = String.valueOf(AESUtils.idEncryptIz(dataKey));
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
@@ -13,16 +13,15 @@ import java.util.UUID;
|
|||||||
* <a href="https://lecloud.lenovo.com/">联想乐云</a>
|
* <a href="https://lecloud.lenovo.com/">联想乐云</a>
|
||||||
*/
|
*/
|
||||||
public class LeTool extends PanBase implements IPanTool {
|
public class LeTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://lecloud.lenovo.com/share/";
|
|
||||||
private static final String API_URL_PREFIX = "https://lecloud.lenovo.com/share/api/clouddiskapi/share/public/v1/";
|
private static final String API_URL_PREFIX = "https://lecloud.lenovo.com/share/api/clouddiskapi/share/public/v1/";
|
||||||
|
|
||||||
public LeTool(String key, String pwd) {
|
public LeTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
final String dataKey = shareLinkInfo.getShareKey();
|
||||||
|
final String pwd = shareLinkInfo.getSharePassword();
|
||||||
// {"shareId":"xxx","password":"xxx","directoryId":"-1"}
|
// {"shareId":"xxx","password":"xxx","directoryId":"-1"}
|
||||||
String apiUrl1 = API_URL_PREFIX + "shareInfo";
|
String apiUrl1 = API_URL_PREFIX + "shareInfo";
|
||||||
client.postAbs(apiUrl1)
|
client.postAbs(apiUrl1)
|
||||||
@@ -47,7 +46,7 @@ public class LeTool extends PanBase implements IPanTool {
|
|||||||
JsonObject fileInfoJson = files.getJsonObject(0);
|
JsonObject fileInfoJson = files.getJsonObject(0);
|
||||||
if (fileInfoJson != null) {
|
if (fileInfoJson != null) {
|
||||||
// TODO 文件大小fileSize和文件名fileName
|
// TODO 文件大小fileSize和文件名fileName
|
||||||
Long fileId = fileInfoJson.getLong("fileId");
|
String fileId = fileInfoJson.getString("fileId");
|
||||||
// 根据文件ID获取跳转链接
|
// 根据文件ID获取跳转链接
|
||||||
getDownURL(dataKey, fileId);
|
getDownURL(dataKey, fileId);
|
||||||
}
|
}
|
||||||
@@ -61,7 +60,7 @@ public class LeTool extends PanBase implements IPanTool {
|
|||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDownURL(String key, Long fileId) {
|
private void getDownURL(String key, String fileId) {
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
JsonArray fileIds = JsonArray.of(fileId);
|
JsonArray fileIds = JsonArray.of(fileId);
|
||||||
String apiUrl2 = API_URL_PREFIX + "packageDownloadWithFileIds";
|
String apiUrl2 = API_URL_PREFIX + "packageDownloadWithFileIds";
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.JsExecUtils;
|
import cn.qaiu.util.JsExecUtils;
|
||||||
@@ -23,15 +24,15 @@ public class LzTool extends PanBase implements IPanTool {
|
|||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://wwwa.lanzoux.com";
|
public static final String SHARE_URL_PREFIX = "https://wwwa.lanzoux.com";
|
||||||
|
|
||||||
public static final String LINK_KEY = "lanzou";
|
|
||||||
|
|
||||||
public LzTool(String key, String pwd) {
|
public LzTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String sUrl = key.startsWith("https://") ? key : SHARE_URL_PREFIX + "/" + key;
|
String sUrl = shareLinkInfo.getStandardUrl();
|
||||||
|
String pwd = shareLinkInfo.getSharePassword();
|
||||||
|
|
||||||
WebClient client = clientNoRedirects;
|
WebClient client = clientNoRedirects;
|
||||||
client.getAbs(sUrl).send().onSuccess(res -> {
|
client.getAbs(sUrl).send().onSuccess(res -> {
|
||||||
@@ -50,34 +51,37 @@ public class LzTool extends PanBase implements IPanTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsText = jsText.replace("document.getElementById('pwd').value", "\"" + pwd + "\"");
|
jsText = jsText.replace("document.getElementById('pwd').value", "\"" + pwd + "\"");
|
||||||
jsText = jsText.substring(0, jsText.indexOf("document.getElementById('rpt')"));
|
int i = jsText.indexOf("document.getElementById('rpt')");
|
||||||
|
if (i > 0) {
|
||||||
|
jsText = jsText.substring(0, i);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, "down_p");
|
ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, "down_p");
|
||||||
getDownURL(sUrl, client, (Map<String, String>) scriptObjectMirror.get("data"));
|
getDownURL(sUrl, client, (Map<String, String>) scriptObjectMirror.get("data"));
|
||||||
} catch (ScriptException | NoSuchMethodException e) {
|
} catch (ScriptException | NoSuchMethodException e) {
|
||||||
fail(e, "js引擎执行失败");
|
fail(e, "js引擎执行失败");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return;
|
} else {
|
||||||
}
|
// 没有密码
|
||||||
String iframePath = matcher.group(1);
|
String iframePath = matcher.group(1);
|
||||||
client.getAbs(SHARE_URL_PREFIX + iframePath).send().onSuccess(res2 -> {
|
client.getAbs(SHARE_URL_PREFIX + iframePath).send().onSuccess(res2 -> {
|
||||||
String html2 = res2.bodyAsString();
|
String html2 = res2.bodyAsString();
|
||||||
|
|
||||||
// 去TMD正则
|
// 去TMD正则
|
||||||
// Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'(\\w+)'").matcher(html2);
|
// Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'(\\w+)'").matcher(html2);
|
||||||
String jsText = getJsText(html2);
|
String jsText = getJsText(html2);
|
||||||
if (jsText == null) {
|
if (jsText == null) {
|
||||||
fail(SHARE_URL_PREFIX + iframePath + " -> " + sUrl + ": js脚本匹配失败, 可能分享已失效");
|
fail(SHARE_URL_PREFIX + iframePath + " -> " + sUrl + ": js脚本匹配失败, 可能分享已失效");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, null);
|
ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, null);
|
||||||
getDownURL(sUrl, client, (Map<String, String>) scriptObjectMirror.get("data"));
|
getDownURL(sUrl, client, (Map<String, String>) scriptObjectMirror.get("data"));
|
||||||
} catch (ScriptException | NoSuchMethodException e) {
|
} catch (ScriptException | NoSuchMethodException e) {
|
||||||
fail(e, "js引擎执行失败");
|
fail(e, "js引擎执行失败");
|
||||||
}
|
}
|
||||||
}).onFailure(handleFail(SHARE_URL_PREFIX));
|
}).onFailure(handleFail(SHARE_URL_PREFIX));
|
||||||
|
}
|
||||||
}).onFailure(handleFail(sUrl));
|
}).onFailure(handleFail(sUrl));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,48 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.util.StringUtils;
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
|
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
|
import cn.qaiu.util.StringUtils;
|
||||||
|
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.MultiMap;
|
import io.vertx.core.MultiMap;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://wx.mail.qq.com/">QQ邮箱</a>
|
* <a href="https://wx.mail.qq.com/">QQ邮箱</a>
|
||||||
*/
|
*/
|
||||||
public class QQTool extends PanBase implements IPanTool {
|
public class QQTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "wx.mail.qq.com/ftn/download?";
|
public static final String REDIRECT_URL_TEMP = "https://iwx.mail.qq.com/ftn/download?func=4&key={key}&code={code}";
|
||||||
|
|
||||||
public QQTool(String key, String pwd) {
|
public QQTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
|
// QQ mail 直接替换为302链接 无需请求
|
||||||
WebClient httpClient = this.client;
|
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(shareLinkInfo.getShareUrl(), StandardCharsets.UTF_8);
|
||||||
|
Map<String, List<String>> prms = queryStringDecoder.parameters();
|
||||||
// 补全链接
|
if (prms.containsKey("key") && prms.containsKey("code") && prms.containsKey("func")) {
|
||||||
if (!this.key.startsWith("https://" + SHARE_URL_PREFIX)) {
|
log.info(prms.get("func").get(0));
|
||||||
if (this.key.startsWith(SHARE_URL_PREFIX)) {
|
promise.complete(REDIRECT_URL_TEMP.replace("{key}",
|
||||||
this.key = "https://" + this.key;
|
prms.get("key").get(0)).replace("{code}", prms.get("code").get(0)));
|
||||||
} else if (this.key.startsWith("func=")) {
|
} else {
|
||||||
this.key = "https://" + SHARE_URL_PREFIX + this.key;
|
fail("key 不合法");
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("未知分享类型");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 通过请求URL获取文件信息和直链 暂时不需要
|
||||||
|
// getFileInfo(key);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getFileInfo(String key) {
|
||||||
// 设置基础HTTP头部
|
// 设置基础HTTP头部
|
||||||
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
||||||
"like " +
|
"like " +
|
||||||
@@ -50,7 +55,7 @@ public class QQTool extends PanBase implements IPanTool {
|
|||||||
headers.set("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
headers.set("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
||||||
|
|
||||||
// 获取下载中转站页面
|
// 获取下载中转站页面
|
||||||
httpClient.getAbs(this.key).putHeaders(headers).send().onSuccess(res -> {
|
client.getAbs(key).putHeaders(headers).send().onSuccess(res -> {
|
||||||
if (res.statusCode() == 200) {
|
if (res.statusCode() == 200) {
|
||||||
String html = res.bodyAsString();
|
String html = res.bodyAsString();
|
||||||
|
|
||||||
@@ -61,10 +66,10 @@ public class QQTool extends PanBase implements IPanTool {
|
|||||||
|
|
||||||
if (filename != null && filesize != null && fileurl != null) {
|
if (filename != null && filesize != null && fileurl != null) {
|
||||||
// 设置所需HTTP头部
|
// 设置所需HTTP头部
|
||||||
headers.set("Referer", "https://" + StringUtils.StringCutNot(this.key, "https://", "/") + "/");
|
headers.set("Referer", "https://" + StringUtils.StringCutNot(key, "https://", "/") + "/");
|
||||||
headers.set("Host", StringUtils.StringCutNot(fileurl, "https://", "/"));
|
headers.set("Host", StringUtils.StringCutNot(fileurl, "https://", "/"));
|
||||||
res.headers().forEach((k, v) -> {
|
res.headers().forEach((k, v) -> {
|
||||||
if (k.toLowerCase().equals("set-cookie")) {
|
if (k.equalsIgnoreCase("set-cookie")) {
|
||||||
headers.set("Cookie", "mail5k=" + StringUtils.StringCutNot(v, "mail5k=", ";") + ";");
|
headers.set("Cookie", "mail5k=" + StringUtils.StringCutNot(v, "mail5k=", ";") + ";");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -82,9 +87,7 @@ public class QQTool extends PanBase implements IPanTool {
|
|||||||
} else {
|
} else {
|
||||||
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
||||||
}
|
}
|
||||||
}).onFailure(this.handleFail(this.key));
|
}).onFailure(this.handleFail(key));
|
||||||
|
|
||||||
return promise.future();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
@@ -9,11 +10,14 @@ import java.util.stream.IntStream;
|
|||||||
|
|
||||||
public class QkTool extends PanBase implements IPanTool {
|
public class QkTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public QkTool(String key, String pwd) {
|
public QkTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
|
final String key = shareLinkInfo.getShareKey();
|
||||||
|
final String pwd = shareLinkInfo.getSharePassword();
|
||||||
|
|
||||||
promise.complete("https://lz.qaiu.top");
|
promise.complete("https://lz.qaiu.top");
|
||||||
IntStream.range(0, 1000).forEach(num -> {
|
IntStream.range(0, 1000).forEach(num -> {
|
||||||
clientNoRedirects.getAbs(key).send()
|
clientNoRedirects.getAbs(key).send()
|
||||||
@@ -33,14 +37,6 @@ public class QkTool extends PanBase implements IPanTool {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
new QkTool("https://pimapi.lenovomm.com/clouddiskapi/v1/shareRedirect?si=12298704&dk" +
|
|
||||||
"=19ab590770399d4438ea885446e27186cc668cdfa559f5fcc063a1ecf78008e5&pk" +
|
|
||||||
"=ef45aa4d25c1dcecb631b3394f51539d59cb35c6a40c3911df8ba431ba2a3244&pc=true&ot=ali&ob=sync-cloud-disk" +
|
|
||||||
"&ok=649593714557087744.dex&fn=classes" +
|
|
||||||
".dex&ds=8909208&dc=1&bi=asdddsad&ri=&ts=1701235051759&sn" +
|
|
||||||
"=13dc33749bd9cc108009fa505b3ecca9f358d70874352858475956ba4240e4c3", "")
|
|
||||||
.parse().onSuccess((res) -> {
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
package cn.qaiu.parser.impl;
|
|
||||||
|
|
||||||
import cn.qaiu.parser.IPanTool;
|
|
||||||
import cn.qaiu.parser.PanBase;
|
|
||||||
import cn.qaiu.util.CommonUtils;
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import io.vertx.core.json.JsonArray;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.uritemplate.UriTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UC网盘解析
|
|
||||||
*/
|
|
||||||
public class UcTool extends PanBase implements IPanTool {
|
|
||||||
private static final String API_URL_PREFIX = "https://pc-api.uc.cn/1/clouddrive/";
|
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://fast.uc.cn/s/";
|
|
||||||
|
|
||||||
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "share/sharepage/token?entry=ft&fr=pc&pr" +
|
|
||||||
"=UCBrowser";
|
|
||||||
|
|
||||||
private static final String SECOND_REQUEST_URL = API_URL_PREFIX + "transfer_share/detail?pwd_id={pwd_id}&passcode" +
|
|
||||||
"={passcode}&stoken={stoken}";
|
|
||||||
|
|
||||||
private static final String THIRD_REQUEST_URL = API_URL_PREFIX + "file/download?entry=ft&fr=pc&pr=UCBrowser";
|
|
||||||
|
|
||||||
public UcTool(String key, String pwd) {
|
|
||||||
super(key, pwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<String> parse() {
|
|
||||||
var dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
|
||||||
var passcode = (pwd == null) ? "" : pwd;
|
|
||||||
var jsonObject = JsonObject.of("share_for_transfer", true);
|
|
||||||
jsonObject.put("pwd_id", dataKey);
|
|
||||||
jsonObject.put("passcode", passcode);
|
|
||||||
// 第一次请求 获取文件信息
|
|
||||||
client.postAbs(FIRST_REQUEST_URL).sendJsonObject(jsonObject).onSuccess(res -> {
|
|
||||||
log.debug("第一阶段 {}", res.body());
|
|
||||||
var resJson = res.bodyAsJsonObject();
|
|
||||||
if (resJson.getInteger("code") != 0) {
|
|
||||||
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var stoken = resJson.getJsonObject("data").getString("stoken");
|
|
||||||
// 第二次请求
|
|
||||||
client.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
|
|
||||||
.setTemplateParam("pwd_id", dataKey)
|
|
||||||
.setTemplateParam("passcode", passcode)
|
|
||||||
.setTemplateParam("stoken", stoken)
|
|
||||||
.send().onSuccess(res2 -> {
|
|
||||||
log.debug("第二阶段 {}", res2.body());
|
|
||||||
JsonObject resJson2 = res2.bodyAsJsonObject();
|
|
||||||
if (resJson2.getInteger("code") != 0) {
|
|
||||||
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 文件信息
|
|
||||||
var info = resJson2.getJsonObject("data").getJsonArray("list").getJsonObject(0);
|
|
||||||
// 第二次请求
|
|
||||||
var bodyJson = JsonObject.of()
|
|
||||||
.put("fids", JsonArray.of(info.getString("fid")))
|
|
||||||
.put("pwd_id", dataKey)
|
|
||||||
.put("stoken", stoken)
|
|
||||||
.put("fids_token", JsonArray.of(info.getString("share_fid_token")));
|
|
||||||
client.postAbs(THIRD_REQUEST_URL).sendJsonObject(bodyJson)
|
|
||||||
.onSuccess(res3 -> {
|
|
||||||
log.debug("第三阶段 {}", res3.body());
|
|
||||||
var resJson3 = res3.bodyAsJsonObject();
|
|
||||||
if (resJson3.getInteger("code") != 0) {
|
|
||||||
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
promise.complete(resJson3.getJsonArray("data").getJsonObject(0).getString("download_url"));
|
|
||||||
}).onFailure(handleFail(THIRD_REQUEST_URL));
|
|
||||||
|
|
||||||
}).onFailure(handleFail(SECOND_REQUEST_URL));
|
|
||||||
}
|
|
||||||
).onFailure(handleFail(FIRST_REQUEST_URL));
|
|
||||||
return promise.future();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.util.StringUtils;
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
|
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
@@ -13,33 +9,27 @@ import io.vertx.core.json.DecodeException;
|
|||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
import io.vertx.ext.web.client.WebClient;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://www.wenshushu.cn/">文叔叔</a>
|
* <a href="https://www.wenshushu.cn/">文叔叔</a>
|
||||||
*/
|
*/
|
||||||
public class WsTool extends PanBase implements IPanTool {
|
public class WsTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "www.wenshushu.cn/f/";
|
public static final String SHARE_URL_PREFIX = "www.wenshushu.cn/f/";
|
||||||
public static final String SHARE_URL_PREFIX2 = "f.ws59.cn/f/";
|
|
||||||
public static final String SHARE_URL_API = "https://www.wenshushu.cn/ap/";
|
public static final String SHARE_URL_API = "https://www.wenshushu.cn/ap/";
|
||||||
|
|
||||||
public WsTool(String key, String pwd) {
|
public WsTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
|
|
||||||
WebClient httpClient = this.client;
|
WebClient httpClient = this.client;
|
||||||
|
final String key = shareLinkInfo.getShareKey();
|
||||||
|
final String pwd = shareLinkInfo.getSharePassword();
|
||||||
|
|
||||||
// 补全链接
|
|
||||||
if (!this.key.startsWith("https://" + SHARE_URL_PREFIX) && !this.key.startsWith("https://" + SHARE_URL_PREFIX2)) {
|
|
||||||
if (this.key.startsWith(SHARE_URL_PREFIX) || this.key.startsWith(SHARE_URL_PREFIX2)) {
|
|
||||||
this.key = "https://" + this.key;
|
|
||||||
} else if (this.key.matches("^[A-Za-z0-9]+$")) {
|
|
||||||
this.key = "https://" + SHARE_URL_PREFIX + this.key;
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("未知分享类型");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置基础HTTP头部
|
// 设置基础HTTP头部
|
||||||
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
||||||
@@ -66,8 +56,8 @@ public class WsTool extends PanBase implements IPanTool {
|
|||||||
// 获取文件夹信息
|
// 获取文件夹信息
|
||||||
httpClient.postAbs(SHARE_URL_API + "task/mgrtask").putHeaders(headers)
|
httpClient.postAbs(SHARE_URL_API + "task/mgrtask").putHeaders(headers)
|
||||||
.sendJsonObject(JsonObject.of(
|
.sendJsonObject(JsonObject.of(
|
||||||
"tid", StringUtils.StringCutNot(key, this.key.startsWith(SHARE_URL_PREFIX) ? SHARE_URL_PREFIX : SHARE_URL_PREFIX2),
|
"tid", key,
|
||||||
"password", ""
|
"password", pwd
|
||||||
)).onSuccess(res2 -> {
|
)).onSuccess(res2 -> {
|
||||||
|
|
||||||
if (res2.statusCode() == 200) {
|
if (res2.statusCode() == 200) {
|
||||||
@@ -128,16 +118,9 @@ public class WsTool extends PanBase implements IPanTool {
|
|||||||
// 调试输出文件直链
|
// 调试输出文件直链
|
||||||
System.out.println("文件直链: " + fileurl);
|
System.out.println("文件直链: " + fileurl);
|
||||||
|
|
||||||
if (!fileurl.equals(""))
|
if (!fileurl.equals("")) {
|
||||||
{
|
promise.complete(URLDecoder.decode(fileurl, StandardCharsets.UTF_8));
|
||||||
try {
|
} else {
|
||||||
promise.complete(URLDecoder.decode(fileurl, "UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
promise.complete(fileurl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.fail("文件已失效");
|
this.fail("文件已失效");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +149,7 @@ public class WsTool extends PanBase implements IPanTool {
|
|||||||
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
||||||
}
|
}
|
||||||
|
|
||||||
}).onFailure(this.handleFail(this.key));
|
}).onFailure(this.handleFail(key));
|
||||||
|
|
||||||
} catch (DecodeException | NullPointerException e) {
|
} catch (DecodeException | NullPointerException e) {
|
||||||
this.fail("token获取失败,可能是分享链接的方式已更新");
|
this.fail("token获取失败,可能是分享链接的方式已更新");
|
||||||
@@ -175,7 +158,7 @@ public class WsTool extends PanBase implements IPanTool {
|
|||||||
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
this.fail("HTTP状态不正确,可能是分享链接的方式已更新");
|
||||||
}
|
}
|
||||||
|
|
||||||
}).onFailure(this.handleFail(this.key));
|
}).onFailure(this.handleFail(key));
|
||||||
|
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.qaiu.parser.impl;
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.parser.IPanTool;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.CommonUtils;
|
import cn.qaiu.util.CommonUtils;
|
||||||
@@ -30,13 +31,14 @@ public class YeTool extends PanBase implements IPanTool {
|
|||||||
"&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event=homeListFile&operateType=1";
|
"&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event=homeListFile&operateType=1";
|
||||||
private static final String DOWNLOAD_API_URL = "https://www.123pan.com/a/api/share/download/info?{authK}={authV}";
|
private static final String DOWNLOAD_API_URL = "https://www.123pan.com/a/api/share/download/info?{authK}={authV}";
|
||||||
|
|
||||||
public YeTool(String key, String pwd) {
|
public YeTool(ShareLinkInfo shareLinkInfo) {
|
||||||
super(key, pwd);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
|
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
final String dataKey = shareLinkInfo.getShareKey();
|
||||||
|
final String pwd = shareLinkInfo.getSharePassword();
|
||||||
|
|
||||||
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("key", dataKey).send().onSuccess(res -> {
|
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("key", dataKey).send().onSuccess(res -> {
|
||||||
|
|
||||||
|
|||||||
37
parser/src/test/java/cn/qaiu/parser/FCURLParser.java
Normal file
37
parser/src/test/java/cn/qaiu/parser/FCURLParser.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package cn.qaiu.parser;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class FCURLParser {// 定义前缀
|
||||||
|
public static final String SHARE_URL_PREFIX0 = "https://v2.fangcloud.com/s";
|
||||||
|
public static final String SHARE_URL_PREFIX = "https://v2.fangcloud.com/sharing/";
|
||||||
|
public static final String SHARE_URL_PREFIX2 = "https://v2.fangcloud.cn/sharing/";
|
||||||
|
|
||||||
|
// 定义正则表达式,适用于所有前缀
|
||||||
|
private static final String SHARING_REGEX = "https://www\\.ecpan\\.cn/web(/%23|/#)?/yunpanProxy\\?path=.*&data=" +
|
||||||
|
"([^&]+)&isShare=1";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 测试 URL
|
||||||
|
String[] urls = {
|
||||||
|
"https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=4b3d786755688b85c6eb0c04b9124f4dalzdaJpXHx&isShare=1",
|
||||||
|
"https://www.ecpan.cn/web/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=4b3d786755688b85c6eb0c04b9124f4dalzdaJpXHx&isShare=1",
|
||||||
|
"https://v2.fangcloud.cn/sharing/xyz789"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编译正则表达式
|
||||||
|
Pattern pattern = Pattern.compile(SHARING_REGEX);
|
||||||
|
|
||||||
|
for (String url : urls) {
|
||||||
|
Matcher matcher = pattern.matcher(url);
|
||||||
|
if (matcher.find()) {
|
||||||
|
System.out.println(matcher.groupCount());
|
||||||
|
String shareKey = matcher.group(matcher.groupCount()); // 捕捉组 3
|
||||||
|
System.out.println("Captured part: " + shareKey);
|
||||||
|
} else {
|
||||||
|
System.out.println("No match found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package cn.qaiu.parser;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2024/8/8 2:39
|
||||||
|
*/
|
||||||
|
public class PanDomainTemplateTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalizeShareLink() {
|
||||||
|
// 准备测试数据
|
||||||
|
String testShareUrl = "https://test.lanzoux.com/s/someShareKey";
|
||||||
|
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromShareUrl(testShareUrl); // 假设使用LZ网盘模板
|
||||||
|
|
||||||
|
// 调用normalizeShareLink方法
|
||||||
|
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", parserCreate.getStandardUrlTemplate().replace("{shareKey}", "someShareKey"), result.getStandardUrl());
|
||||||
|
// 可以添加更多的断言来验证其他字段
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromShareUrl() throws InterruptedException {
|
||||||
|
// 准备测试数据
|
||||||
|
String lzUrl = "https://wwn.lanzouy.com/ihLkw1gezutg";
|
||||||
|
String cowUrl = "https://cowtransfer.com/s/9a644fe3e3a748";
|
||||||
|
String ceUrl = "https://pan.huang1111.cn/s/g31PcQ";
|
||||||
|
String wsUrl = "https://f.ws59.cn/f/f25625rv6p6";
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// ParserCreate.fromType("lz").shareKey("ihLkw1gezutg")
|
||||||
|
// .createTool().parse().onSuccess(System.out::println);
|
||||||
|
// ParserCreate.LZ.shareKey("ihLkw1gezutg")
|
||||||
|
// .createTool().parse().onSuccess(System.out::println);
|
||||||
|
|
||||||
|
|
||||||
|
// 调用fromShareUrl方法
|
||||||
|
// PanDomainTemplate resultTemplate = ParserCreate.fromShareUrl(testShareUrl);
|
||||||
|
// System.out.println(resultTemplate.normalizeShareLink(testShareUrl));
|
||||||
|
// System.out.println(resultTemplate.shareKey("xxx"));
|
||||||
|
// System.out.println(resultTemplate.createTool("xxx",null).parse()
|
||||||
|
// .onSuccess(System.out::println));
|
||||||
|
// System.out.println(resultTemplate.getDisplayName());
|
||||||
|
// System.out.println(resultTemplate.getStandardUrlTemplate());
|
||||||
|
// System.out.println(resultTemplate.getRegexPattern());
|
||||||
|
//
|
||||||
|
// // 断言结果是否符合预期
|
||||||
|
// assertNotNull("Result should not be null", resultTemplate);
|
||||||
|
// assertEquals("Should return the correct template", ParserCreate.LZ, resultTemplate);
|
||||||
|
// // 可以添加更多的断言来验证正则表达式匹配逻辑
|
||||||
|
// new Scanner(System.in).nextLine();
|
||||||
|
TimeUnit.SECONDS.sleep(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
pom.xml
4
pom.xml
@@ -17,7 +17,7 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>0.1.7</revision>
|
<revision>0.1.8</revision>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<slf4j.version>2.0.5</slf4j.version>
|
<slf4j.version>2.0.5</slf4j.version>
|
||||||
<vertx.version>4.5.6</vertx.version>
|
<vertx.version>4.5.6</vertx.version>
|
||||||
<org.reflections.version>0.10.2</org.reflections.version>
|
<org.reflections.version>0.10.2</org.reflections.version>
|
||||||
<lombok.version>1.18.12</lombok.version>
|
<lombok.version>1.18.30</lombok.version>
|
||||||
<slf4j.version>2.0.5</slf4j.version>
|
<slf4j.version>2.0.5</slf4j.version>
|
||||||
<commons-lang3.version>3.12.0</commons-lang3.version>
|
<commons-lang3.version>3.12.0</commons-lang3.version>
|
||||||
<commons-beanutils2.version>2.0.0</commons-beanutils2.version>
|
<commons-beanutils2.version>2.0.0</commons-beanutils2.version>
|
||||||
|
|||||||
426
web-front/package-lock.json
generated
426
web-front/package-lock.json
generated
@@ -8,7 +8,7 @@
|
|||||||
"name": "nfd-web",
|
"name": "nfd-web",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.7.4",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"element-ui": "^2.15.12",
|
"element-ui": "^2.15.12",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
@@ -1879,13 +1879,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.17",
|
"version": "0.3.25",
|
||||||
"resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||||
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
|
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "3.1.0",
|
"@jridgewell/resolve-uri": "^3.1.0",
|
||||||
"@jridgewell/sourcemap-codec": "1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@leichtgewicht/ip-codec": {
|
"node_modules/@leichtgewicht/ip-codec": {
|
||||||
@@ -2200,20 +2200,10 @@
|
|||||||
"@types/json-schema": "*"
|
"@types/json-schema": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/eslint-scope": {
|
|
||||||
"version": "3.7.4",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
|
|
||||||
"integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/eslint": "*",
|
|
||||||
"@types/estree": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||||
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
|
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/express": {
|
"node_modules/@types/express": {
|
||||||
@@ -2996,9 +2986,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/ast": {
|
"node_modules/@webassemblyjs/ast": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
|
||||||
"integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
|
"integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/helper-numbers": "1.11.6",
|
"@webassemblyjs/helper-numbers": "1.11.6",
|
||||||
@@ -3018,9 +3008,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/helper-buffer": {
|
"node_modules/@webassemblyjs/helper-buffer": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
|
||||||
"integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
|
"integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/helper-numbers": {
|
"node_modules/@webassemblyjs/helper-numbers": {
|
||||||
@@ -3041,15 +3031,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/helper-wasm-section": {
|
"node_modules/@webassemblyjs/helper-wasm-section": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
|
||||||
"integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
|
"integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/ast": "1.11.6",
|
"@webassemblyjs/ast": "1.12.1",
|
||||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
"@webassemblyjs/helper-buffer": "1.12.1",
|
||||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||||
"@webassemblyjs/wasm-gen": "1.11.6"
|
"@webassemblyjs/wasm-gen": "1.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/ieee754": {
|
"node_modules/@webassemblyjs/ieee754": {
|
||||||
@@ -3077,28 +3067,28 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/wasm-edit": {
|
"node_modules/@webassemblyjs/wasm-edit": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
|
||||||
"integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
|
"integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/ast": "1.11.6",
|
"@webassemblyjs/ast": "1.12.1",
|
||||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
"@webassemblyjs/helper-buffer": "1.12.1",
|
||||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||||
"@webassemblyjs/helper-wasm-section": "1.11.6",
|
"@webassemblyjs/helper-wasm-section": "1.12.1",
|
||||||
"@webassemblyjs/wasm-gen": "1.11.6",
|
"@webassemblyjs/wasm-gen": "1.12.1",
|
||||||
"@webassemblyjs/wasm-opt": "1.11.6",
|
"@webassemblyjs/wasm-opt": "1.12.1",
|
||||||
"@webassemblyjs/wasm-parser": "1.11.6",
|
"@webassemblyjs/wasm-parser": "1.12.1",
|
||||||
"@webassemblyjs/wast-printer": "1.11.6"
|
"@webassemblyjs/wast-printer": "1.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/wasm-gen": {
|
"node_modules/@webassemblyjs/wasm-gen": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
|
||||||
"integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
|
"integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/ast": "1.11.6",
|
"@webassemblyjs/ast": "1.12.1",
|
||||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||||
"@webassemblyjs/ieee754": "1.11.6",
|
"@webassemblyjs/ieee754": "1.11.6",
|
||||||
"@webassemblyjs/leb128": "1.11.6",
|
"@webassemblyjs/leb128": "1.11.6",
|
||||||
@@ -3106,24 +3096,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/wasm-opt": {
|
"node_modules/@webassemblyjs/wasm-opt": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
|
||||||
"integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
|
"integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/ast": "1.11.6",
|
"@webassemblyjs/ast": "1.12.1",
|
||||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
"@webassemblyjs/helper-buffer": "1.12.1",
|
||||||
"@webassemblyjs/wasm-gen": "1.11.6",
|
"@webassemblyjs/wasm-gen": "1.12.1",
|
||||||
"@webassemblyjs/wasm-parser": "1.11.6"
|
"@webassemblyjs/wasm-parser": "1.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/wasm-parser": {
|
"node_modules/@webassemblyjs/wasm-parser": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
|
||||||
"integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
|
"integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/ast": "1.11.6",
|
"@webassemblyjs/ast": "1.12.1",
|
||||||
"@webassemblyjs/helper-api-error": "1.11.6",
|
"@webassemblyjs/helper-api-error": "1.11.6",
|
||||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||||
"@webassemblyjs/ieee754": "1.11.6",
|
"@webassemblyjs/ieee754": "1.11.6",
|
||||||
@@ -3132,12 +3122,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@webassemblyjs/wast-printer": {
|
"node_modules/@webassemblyjs/wast-printer": {
|
||||||
"version": "1.11.6",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
|
||||||
"integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
|
"integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@webassemblyjs/ast": "1.11.6",
|
"@webassemblyjs/ast": "1.12.1",
|
||||||
"@xtuc/long": "4.2.2"
|
"@xtuc/long": "4.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3178,10 +3168,10 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn-import-assertions": {
|
"node_modules/acorn-import-attributes": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
|
||||||
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
|
"integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^8"
|
"acorn": "^8"
|
||||||
@@ -3522,11 +3512,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.6.0",
|
"version": "1.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
||||||
"integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==",
|
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
@@ -3692,9 +3682,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.2",
|
"version": "1.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||||
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
|
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "3.1.2",
|
"bytes": "3.1.2",
|
||||||
@@ -3705,7 +3695,7 @@
|
|||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
"iconv-lite": "0.4.24",
|
"iconv-lite": "0.4.24",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"qs": "6.11.0",
|
"qs": "6.13.0",
|
||||||
"raw-body": "2.5.2",
|
"raw-body": "2.5.2",
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
"unpipe": "1.0.0"
|
"unpipe": "1.0.0"
|
||||||
@@ -3780,15 +3770,29 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.21.4",
|
"version": "4.23.3",
|
||||||
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.4.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
|
||||||
"integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
|
"integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/browserslist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001400",
|
"caniuse-lite": "^1.0.30001646",
|
||||||
"electron-to-chromium": "^1.4.251",
|
"electron-to-chromium": "^1.5.4",
|
||||||
"node-releases": "^2.0.6",
|
"node-releases": "^2.0.18",
|
||||||
"update-browserslist-db": "^1.0.9"
|
"update-browserslist-db": "^1.1.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"browserslist": "cli.js"
|
"browserslist": "cli.js"
|
||||||
@@ -3950,10 +3954,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001442",
|
"version": "1.0.30001655",
|
||||||
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz",
|
||||||
"integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==",
|
"integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/browserslist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"node_modules/case-sensitive-paths-webpack-plugin": {
|
"node_modules/case-sensitive-paths-webpack-plugin": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
@@ -5106,7 +5124,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -5115,7 +5133,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/destroy": {
|
"node_modules/destroy": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -5262,14 +5280,14 @@
|
|||||||
},
|
},
|
||||||
"node_modules/ee-first": {
|
"node_modules/ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.284",
|
"version": "1.5.13",
|
||||||
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz",
|
||||||
"integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
|
"integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/element-ui": {
|
"node_modules/element-ui": {
|
||||||
@@ -5304,9 +5322,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
@@ -5322,9 +5340,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.15.0",
|
"version": "5.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||||
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
|
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.4",
|
"graceful-fs": "^4.2.4",
|
||||||
@@ -5398,9 +5416,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
|
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -6012,7 +6030,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/etag": {
|
"node_modules/etag": {
|
||||||
"version": "1.8.1",
|
"version": "1.8.1",
|
||||||
"resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -6062,37 +6080,37 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.19.2",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
||||||
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
|
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
"body-parser": "1.20.2",
|
"body-parser": "1.20.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.4",
|
||||||
"cookie": "0.6.0",
|
"cookie": "0.6.0",
|
||||||
"cookie-signature": "1.0.6",
|
"cookie-signature": "1.0.6",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
"encodeurl": "~1.0.2",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"etag": "~1.8.1",
|
"etag": "~1.8.1",
|
||||||
"finalhandler": "1.2.0",
|
"finalhandler": "1.3.1",
|
||||||
"fresh": "0.5.2",
|
"fresh": "0.5.2",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
"merge-descriptors": "1.0.1",
|
"merge-descriptors": "1.0.3",
|
||||||
"methods": "~1.1.2",
|
"methods": "~1.1.2",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"path-to-regexp": "0.1.7",
|
"path-to-regexp": "0.1.10",
|
||||||
"proxy-addr": "~2.0.7",
|
"proxy-addr": "~2.0.7",
|
||||||
"qs": "6.11.0",
|
"qs": "6.13.0",
|
||||||
"range-parser": "~1.2.1",
|
"range-parser": "~1.2.1",
|
||||||
"safe-buffer": "5.2.1",
|
"safe-buffer": "5.2.1",
|
||||||
"send": "0.18.0",
|
"send": "0.19.0",
|
||||||
"serve-static": "1.15.0",
|
"serve-static": "1.16.2",
|
||||||
"setprototypeof": "1.2.0",
|
"setprototypeof": "1.2.0",
|
||||||
"statuses": "2.0.1",
|
"statuses": "2.0.1",
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
@@ -6317,13 +6335,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.2.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||||
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"encodeurl": "~1.0.2",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
@@ -6336,7 +6354,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/finalhandler/node_modules/debug": {
|
"node_modules/finalhandler/node_modules/debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6345,7 +6363,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/finalhandler/node_modules/ms": {
|
"node_modules/finalhandler/node_modules/ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
@@ -6447,7 +6465,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/fresh": {
|
"node_modules/fresh": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -6608,7 +6626,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/glob-to-regexp": {
|
"node_modules/glob-to-regexp": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
|
||||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
|
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
@@ -6659,9 +6677,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/graceful-fs": {
|
"node_modules/graceful-fs": {
|
||||||
"version": "4.2.10",
|
"version": "4.2.11",
|
||||||
"resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
|
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/gzip-size": {
|
"node_modules/gzip-size": {
|
||||||
@@ -6895,7 +6913,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/http-errors": {
|
"node_modules/http-errors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -7892,10 +7910,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
|
||||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
|
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/merge-source-map": {
|
"node_modules/merge-source-map": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
@@ -7945,7 +7966,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/mime": {
|
"node_modules/mime": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -8275,9 +8296,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.8",
|
"version": "2.0.18",
|
||||||
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
|
||||||
"integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==",
|
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/normalize-package-data": {
|
"node_modules/normalize-package-data": {
|
||||||
@@ -8364,10 +8385,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.1",
|
"version": "1.13.2",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
|
||||||
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
|
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
@@ -8404,7 +8428,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/on-finished": {
|
"node_modules/on-finished": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8746,9 +8770,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.10",
|
||||||
"resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
|
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/path-type": {
|
"node_modules/path-type": {
|
||||||
@@ -8761,9 +8785,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
@@ -9479,12 +9503,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.11.0",
|
"version": "6.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"side-channel": "^1.0.4"
|
"side-channel": "^1.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
@@ -9907,9 +9931,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "0.18.0",
|
"version": "0.19.0",
|
||||||
"resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
||||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
@@ -9932,7 +9956,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/send/node_modules/debug": {
|
"node_modules/send/node_modules/debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -9941,13 +9965,22 @@
|
|||||||
},
|
},
|
||||||
"node_modules/send/node_modules/debug/node_modules/ms": {
|
"node_modules/send/node_modules/debug/node_modules/ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/send/node_modules/encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/send/node_modules/ms": {
|
"node_modules/send/node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
@@ -10039,15 +10072,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/serve-static": {
|
"node_modules/serve-static": {
|
||||||
"version": "1.15.0",
|
"version": "1.16.2",
|
||||||
"resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||||
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"encodeurl": "~1.0.2",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"send": "0.18.0"
|
"send": "0.19.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
@@ -10072,7 +10105,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/setprototypeof": {
|
"node_modules/setprototypeof": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
@@ -10344,7 +10377,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -10599,9 +10632,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.19.2",
|
"version": "5.31.6",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz",
|
||||||
"integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
|
"integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
@@ -10617,16 +10650,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/terser-webpack-plugin": {
|
"node_modules/terser-webpack-plugin": {
|
||||||
"version": "5.3.9",
|
"version": "5.3.10",
|
||||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
|
||||||
"integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
|
"integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/trace-mapping": "^0.3.17",
|
"@jridgewell/trace-mapping": "^0.3.20",
|
||||||
"jest-worker": "^27.4.5",
|
"jest-worker": "^27.4.5",
|
||||||
"schema-utils": "^3.1.1",
|
"schema-utils": "^3.1.1",
|
||||||
"serialize-javascript": "^6.0.1",
|
"serialize-javascript": "^6.0.1",
|
||||||
"terser": "^5.16.8"
|
"terser": "^5.26.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.13.0"
|
"node": ">= 10.13.0"
|
||||||
@@ -10786,7 +10819,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -10917,7 +10950,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -10925,16 +10958,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.0.10",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
|
||||||
"integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
|
"integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/browserslist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.2",
|
||||||
"picocolors": "^1.0.0"
|
"picocolors": "^1.0.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"browserslist-lint": "cli.js"
|
"update-browserslist-db": "cli.js"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"browserslist": ">= 4.21.0"
|
"browserslist": ">= 4.21.0"
|
||||||
@@ -11270,9 +11317,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
|
||||||
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
|
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
@@ -11307,34 +11354,33 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.88.2",
|
"version": "5.94.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
|
||||||
"integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
|
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
"@types/estree": "^1.0.5",
|
||||||
"@types/estree": "^1.0.0",
|
"@webassemblyjs/ast": "^1.12.1",
|
||||||
"@webassemblyjs/ast": "^1.11.5",
|
"@webassemblyjs/wasm-edit": "^1.12.1",
|
||||||
"@webassemblyjs/wasm-edit": "^1.11.5",
|
"@webassemblyjs/wasm-parser": "^1.12.1",
|
||||||
"@webassemblyjs/wasm-parser": "^1.11.5",
|
|
||||||
"acorn": "^8.7.1",
|
"acorn": "^8.7.1",
|
||||||
"acorn-import-assertions": "^1.9.0",
|
"acorn-import-attributes": "^1.9.5",
|
||||||
"browserslist": "^4.14.5",
|
"browserslist": "^4.21.10",
|
||||||
"chrome-trace-event": "^1.0.2",
|
"chrome-trace-event": "^1.0.2",
|
||||||
"enhanced-resolve": "^5.15.0",
|
"enhanced-resolve": "^5.17.1",
|
||||||
"es-module-lexer": "^1.2.1",
|
"es-module-lexer": "^1.2.1",
|
||||||
"eslint-scope": "5.1.1",
|
"eslint-scope": "5.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"graceful-fs": "^4.2.9",
|
"graceful-fs": "^4.2.11",
|
||||||
"json-parse-even-better-errors": "^2.3.1",
|
"json-parse-even-better-errors": "^2.3.1",
|
||||||
"loader-runner": "^4.2.0",
|
"loader-runner": "^4.2.0",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"neo-async": "^2.6.2",
|
"neo-async": "^2.6.2",
|
||||||
"schema-utils": "^3.2.0",
|
"schema-utils": "^3.2.0",
|
||||||
"tapable": "^2.1.1",
|
"tapable": "^2.1.1",
|
||||||
"terser-webpack-plugin": "^5.3.7",
|
"terser-webpack-plugin": "^5.3.10",
|
||||||
"watchpack": "^2.4.0",
|
"watchpack": "^2.4.1",
|
||||||
"webpack-sources": "^3.2.3"
|
"webpack-sources": "^3.2.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.7.4",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"element-ui": "^2.15.12",
|
"element-ui": "^2.15.12",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
content="Netdisk fast download 网盘直链解析工具">
|
content="Netdisk fast download 网盘直链解析工具">
|
||||||
<script charset="UTF-8" id="LA_COLLECT" src="//sdk.51.la/js-sdk-pro.min.js"></script>
|
<script charset="UTF-8" id="LA_COLLECT" src="//sdk.51.la/js-sdk-pro.min.js"></script>
|
||||||
<script>LA.init({id:"K8zkCkZMgFA6ShZK",ck:"K8zkCkZMgFA6ShZK"})</script>
|
<script>LA.init({id:"K8zkCkZMgFA6ShZK",ck:"K8zkCkZMgFA6ShZK"})</script>
|
||||||
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9851170484804006"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
<style>
|
<style>
|
||||||
.page-loading-wrap {
|
.page-loading-wrap {
|
||||||
padding: 120px;
|
padding: 120px;
|
||||||
|
|||||||
@@ -7,19 +7,17 @@
|
|||||||
<el-avatar :size="150" :src="avatar"></el-avatar>
|
<el-avatar :size="150" :src="avatar"></el-avatar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3 style="text-align: center;">NFD网盘直链解析(API演示)</h3>
|
<h3 style="text-align: center;">NFD网盘直链解析0.1.8_bate(API演示)</h3>
|
||||||
<div class="typo">
|
<div class="typo">
|
||||||
<p><strong>项目GitHub </strong><a href="https://github.com/qaiu/netdisk-fast-download" target="_blank"
|
<p><strong>项目GitHub </strong><a href="https://github.com/qaiu/netdisk-fast-download" target="_blank"
|
||||||
rel="nofollow"><u>netdisk-fast-download</u></a></p>
|
rel="nofollow"><u>netdisk-fast-download</u></a></p>
|
||||||
<p><strong>当前页面修改自开源项目</strong><a href="https://github.com/HurryBy/CloudDiskAnalysis"
|
<p><strong>目前支持 </strong>蓝奏云/蓝奏云优享/小飞机盘/123云盘/奶牛快传/移动云云空间/亿方云/文叔叔/QQ邮箱文件中转站</p>
|
||||||
target="_blank"
|
<p>已加入缓存机制, 如果遇到解析出的下载链接失效的情况请及时到项目GitHub反馈</p>
|
||||||
rel="nofollow"><u>CloudDiskAnalysis</u></a></p>
|
|
||||||
<p><strong>目前支持 </strong>已支持蓝奏云/奶牛快传/移动云云空间/UC网盘(暂时失效)/小飞机盘/亿方云/123云盘</p>
|
|
||||||
<p>
|
<p>
|
||||||
<el-button><strong @click="getInfo">刷新API调用统计</strong></el-button>
|
<el-button><strong @click="getInfo">刷新API调用统计</strong></el-button>
|
||||||
</p>
|
</p>
|
||||||
<p>节点1: 成功:{{ node1Info.success }},失败:{{ node1Info.fail }},总数:{{ node1Info.total }}</p>
|
<p>节点1: 回源请求数:{{ node1Info.parserTotal }}, 缓存请求数:{{ node1Info.cacheTotal }}, 总数:{{ node1Info.total }}</p>
|
||||||
<p>节点2: 成功:{{ node2Info.success }},失败:{{ node2Info.fail }},总数:{{ node2Info.total }}</p>
|
<!-- <p>节点2: 成功:{{ node2Info.success }},失败:{{ node2Info.fail }},总数:{{ node2Info.total }}</p>-->
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="main" v-loading="isLoading">
|
<div class="main" v-loading="isLoading">
|
||||||
@@ -149,10 +147,11 @@ export default {
|
|||||||
message: response.data.msg,
|
message: response.data.msg,
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
this.downUrl = response.data.data
|
this.downUrl = response.data.data.directLink
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(response.data.msg)
|
this.$message.error(response.data.msg)
|
||||||
}
|
}
|
||||||
|
this.getInfo()
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
@@ -174,12 +173,12 @@ export default {
|
|||||||
this.node1Info = response.data.data
|
this.node1Info = response.data.data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
axios.get('/n2/statisticsInfo').then(
|
// axios.get('/n2/statisticsInfo').then(
|
||||||
response => {
|
// response => {
|
||||||
if (response.data.success) {
|
// if (response.data.success) {
|
||||||
this.node2Info = response.data.data
|
// this.node2Info = response.data.data
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -40,17 +40,17 @@ module.exports = {
|
|||||||
test: /\.js$|\.html$|\.css/, // 匹配文件
|
test: /\.js$|\.html$|\.css/, // 匹配文件
|
||||||
threshold: 10240 // 对超过10k文件压缩
|
threshold: 10240 // 对超过10k文件压缩
|
||||||
}),
|
}),
|
||||||
new FileManagerPlugin({ //初始化 filemanager-webpack-plugin 插件实例
|
// new FileManagerPlugin({ //初始化 filemanager-webpack-plugin 插件实例
|
||||||
onEnd: {
|
// onEnd: {
|
||||||
mkdir: ['./nfd-front'],
|
// mkdir: ['./nfd-front'],
|
||||||
delete: [ //首先需要删除项目根目录下的dist.zip
|
// delete: [ //首先需要删除项目根目录下的dist.zip
|
||||||
'./nfd-front.zip',
|
// './nfd-front.zip',
|
||||||
],
|
// ],
|
||||||
archive: [ //然后我们选择dist文件夹将之打包成dist.zip并放在根目录
|
// archive: [ //然后我们选择dist文件夹将之打包成dist.zip并放在根目录
|
||||||
{source: './nfd-front', destination: './nfd-front.zip'},
|
// {source: './nfd-front', destination: './nfd-front.zip'},
|
||||||
]
|
// ]
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
6771
web-front/yarn.lock
Normal file
6771
web-front/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.26</version>
|
<version>${lombok.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--logback日志实现-->
|
<!--logback日志实现-->
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package cn.qaiu.lz;
|
|||||||
|
|
||||||
import cn.qaiu.WebClientVertxInit;
|
import cn.qaiu.WebClientVertxInit;
|
||||||
import cn.qaiu.db.pool.JDBCPoolInit;
|
import cn.qaiu.db.pool.JDBCPoolInit;
|
||||||
|
import cn.qaiu.lz.common.cache.CacheConfigLoader;
|
||||||
import cn.qaiu.vx.core.Deploy;
|
import cn.qaiu.vx.core.Deploy;
|
||||||
import cn.qaiu.vx.core.util.ConfigConstant;
|
import cn.qaiu.vx.core.util.ConfigConstant;
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
import cn.qaiu.vx.core.util.VertxHolder;
|
||||||
@@ -23,17 +24,20 @@ public class AppMain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化数据库
|
* 初始化数据库/缓存等
|
||||||
*
|
*
|
||||||
* @param jsonObject 配置
|
* @param jsonObject 配置
|
||||||
*/
|
*/
|
||||||
private static void exec(JsonObject jsonObject) {
|
private static void exec(JsonObject jsonObject) {
|
||||||
WebClientVertxInit.init(VertxHolder.getVertxInstance());
|
WebClientVertxInit.init(VertxHolder.getVertxInstance());
|
||||||
DatabindCodec.mapper().registerModule(new JavaTimeModule());
|
DatabindCodec.mapper().registerModule(new JavaTimeModule());
|
||||||
|
// 数据库
|
||||||
if (jsonObject.getJsonObject(ConfigConstant.SERVER).getBoolean("enableDatabase")) {
|
if (jsonObject.getJsonObject(ConfigConstant.SERVER).getBoolean("enableDatabase")) {
|
||||||
JDBCPoolInit.builder().config(jsonObject.getJsonObject("dataSource")).build().initPool();
|
JDBCPoolInit.builder().config(jsonObject.getJsonObject("dataSource")).build().initPool();
|
||||||
}
|
}
|
||||||
|
// 缓存
|
||||||
|
if (jsonObject.containsKey(ConfigConstant.CACHE)) {
|
||||||
|
CacheConfigLoader.init(jsonObject.getJsonObject(ConfigConstant.CACHE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
37
web-service/src/main/java/cn/qaiu/lz/common/cache/CacheConfigLoader.java
vendored
Normal file
37
web-service/src/main/java/cn/qaiu/lz/common/cache/CacheConfigLoader.java
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package cn.qaiu.lz.common.cache;
|
||||||
|
|
||||||
|
import cn.qaiu.parser.PanDomainTemplate;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2024/9/12 7:38
|
||||||
|
*/
|
||||||
|
public class CacheConfigLoader {
|
||||||
|
private static final Map<String, Integer> CONFIGS = new HashMap<>();
|
||||||
|
public static String TYPE;
|
||||||
|
public static Integer DEFAULT_DURATION;
|
||||||
|
|
||||||
|
public static void init(JsonObject config) {
|
||||||
|
TYPE = config.getString("type");
|
||||||
|
Integer defaultDuration = config.getInteger("defaultDuration");
|
||||||
|
DEFAULT_DURATION = defaultDuration == null ? 60 : defaultDuration;
|
||||||
|
config.getJsonObject("duration").getMap().forEach((k,v) -> {
|
||||||
|
if (v == null) {
|
||||||
|
CONFIGS.put(k, DEFAULT_DURATION);
|
||||||
|
} else {
|
||||||
|
CONFIGS.put(k, (Integer) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer getDuration(PanDomainTemplate pdt) {
|
||||||
|
return CONFIGS.get(pdt.name().toLowerCase());
|
||||||
|
}
|
||||||
|
public static Integer getDuration(String type) {
|
||||||
|
return CONFIGS.get(type.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
129
web-service/src/main/java/cn/qaiu/lz/common/cache/CacheManager.java
vendored
Normal file
129
web-service/src/main/java/cn/qaiu/lz/common/cache/CacheManager.java
vendored
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
package cn.qaiu.lz.common.cache;
|
||||||
|
|
||||||
|
import cn.qaiu.db.pool.JDBCPoolInit;
|
||||||
|
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.jdbcclient.JDBCPool;
|
||||||
|
import io.vertx.sqlclient.Row;
|
||||||
|
import io.vertx.sqlclient.templates.SqlTemplate;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CacheManager {
|
||||||
|
private final JDBCPool jdbcPool = JDBCPoolInit.instance().getPool();
|
||||||
|
|
||||||
|
|
||||||
|
public Future<CacheLinkInfo> get(String cacheKey) {
|
||||||
|
String sql = "SELECT share_key as shareKey, direct_link as directLink, expiration FROM cache_link_info WHERE share_key = #{share_key}";
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("share_key", cacheKey);
|
||||||
|
Promise<CacheLinkInfo> promise = Promise.promise();
|
||||||
|
SqlTemplate.forQuery(jdbcPool, sql)
|
||||||
|
.mapTo(CacheLinkInfo.class)
|
||||||
|
.execute(params)
|
||||||
|
.onSuccess(rows->{
|
||||||
|
CacheLinkInfo cacheHit;
|
||||||
|
if (rows.size() > 0) {
|
||||||
|
cacheHit = rows.iterator().next();
|
||||||
|
cacheHit.setCacheHit(true);
|
||||||
|
} else {
|
||||||
|
cacheHit = new CacheLinkInfo(JsonObject.of("cacheHit", false, "shareKey", cacheKey));
|
||||||
|
}
|
||||||
|
promise.complete(cacheHit);
|
||||||
|
}).onFailure(Throwable::printStackTrace);
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 插入或更新缓存数据
|
||||||
|
public Future<Void> cacheShareLink(CacheLinkInfo cacheLinkInfo) {
|
||||||
|
String sql = "MERGE INTO cache_link_info (share_key, direct_link, expiration) " +
|
||||||
|
"KEY (share_key) " +
|
||||||
|
"VALUES (#{shareKey}, #{directLink}, #{expiration})";
|
||||||
|
|
||||||
|
// 直接传递 CacheLinkInfo 实体类
|
||||||
|
return SqlTemplate.forUpdate(jdbcPool, sql)
|
||||||
|
.mapFrom(CacheLinkInfo.class) // 将实体类映射为 Tuple 参数
|
||||||
|
.execute(cacheLinkInfo)
|
||||||
|
.mapEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计网盘厂商API解析次数
|
||||||
|
public Future<Integer> updateTotalByCached(String shareKey) {
|
||||||
|
Promise<Integer> promise = Promise.promise();
|
||||||
|
String sql = """
|
||||||
|
MERGE INTO `api_statistics_info` (`pan_type`, `share_key`, `cache_hit_total`, `update_ts`)
|
||||||
|
KEY (`share_key`)
|
||||||
|
VALUES (#{panType}, #{shareKey}, #{total}, #{ts})
|
||||||
|
""";
|
||||||
|
|
||||||
|
getShareKeyTotal(shareKey, "cache_hit_total").onSuccess(total -> {
|
||||||
|
Integer newTotal = (total == null ? 0 : total) + 1;
|
||||||
|
SqlTemplate.forUpdate(jdbcPool, sql)
|
||||||
|
.execute(new HashMap<>() {{
|
||||||
|
put("panType", getShareType(shareKey));
|
||||||
|
put("shareKey", shareKey);
|
||||||
|
put("total", newTotal);
|
||||||
|
put("ts", System.currentTimeMillis());
|
||||||
|
}})
|
||||||
|
.onSuccess(res -> promise.complete(res.rowCount()))
|
||||||
|
.onFailure(Throwable::printStackTrace);
|
||||||
|
});
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getShareType(String fullShareKey) {
|
||||||
|
// 将type和shareKey组合成一个字符串作为缓存key
|
||||||
|
return fullShareKey.split(":")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计网盘厂商API解析次数
|
||||||
|
public Future<Integer> updateTotalByParser(String shareKey) {
|
||||||
|
Promise<Integer> promise = Promise.promise();
|
||||||
|
String sql = """
|
||||||
|
MERGE INTO `api_statistics_info` (`pan_type`, `share_key`, `api_parser_total`, `update_ts`)
|
||||||
|
KEY (`share_key`)
|
||||||
|
VALUES (#{panType}, #{shareKey}, #{total}, #{ts})
|
||||||
|
""";
|
||||||
|
|
||||||
|
getShareKeyTotal(shareKey, "api_parser_total").onSuccess(total -> {
|
||||||
|
Integer newTotal = (total == null ? 0 : total) + 1;
|
||||||
|
SqlTemplate.forUpdate(jdbcPool, sql)
|
||||||
|
.execute(new HashMap<>() {{
|
||||||
|
put("panType", getShareType(shareKey));
|
||||||
|
put("shareKey", shareKey);
|
||||||
|
put("total", newTotal);
|
||||||
|
put("ts", System.currentTimeMillis());
|
||||||
|
}})
|
||||||
|
.onSuccess(res -> promise.complete(res.rowCount()))
|
||||||
|
.onFailure(Throwable::printStackTrace);
|
||||||
|
});
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<Integer> getShareKeyTotal(String shareKey, String name) {
|
||||||
|
String sql = """
|
||||||
|
select `share_key`, sum({total_name}) sum_num
|
||||||
|
from `api_statistics_info`
|
||||||
|
group by `share_key` having `share_key` = #{shareKey};
|
||||||
|
""".replace("{total_name}", name);
|
||||||
|
Promise<Integer> promise = Promise.promise();
|
||||||
|
Map<String, Object> paramMap = new HashMap<>();
|
||||||
|
paramMap.put("shareKey", shareKey);
|
||||||
|
SqlTemplate.forQuery(jdbcPool, sql)
|
||||||
|
.mapTo(Row::toJson)
|
||||||
|
.execute(paramMap)
|
||||||
|
.onSuccess(res -> {
|
||||||
|
Integer total = res.iterator().hasNext() ?
|
||||||
|
res.iterator().next().getInteger("sum_num") : null;
|
||||||
|
promise.complete(total);
|
||||||
|
});
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ public class DefaultInterceptor implements BeforeInterceptor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
System.out.println("进入前置拦截器1->" + ctx.request().path());
|
// System.out.println("进入前置拦截器1->" + ctx.request().path());
|
||||||
doNext(ctx);
|
doNext(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import cn.qaiu.db.pool.JDBCPoolInit;
|
|||||||
import cn.qaiu.lz.common.model.ParserLogInfo;
|
import cn.qaiu.lz.common.model.ParserLogInfo;
|
||||||
import cn.qaiu.vx.core.annotaions.HandleSortFilter;
|
import cn.qaiu.vx.core.annotaions.HandleSortFilter;
|
||||||
import cn.qaiu.vx.core.interceptor.AfterInterceptor;
|
import cn.qaiu.vx.core.interceptor.AfterInterceptor;
|
||||||
import cn.qaiu.vx.core.model.JsonResult;
|
|
||||||
import cn.qaiu.vx.core.util.CommonUtil;
|
import cn.qaiu.vx.core.util.CommonUtil;
|
||||||
import cn.qaiu.vx.core.util.SharedDataUtil;
|
import cn.qaiu.vx.core.util.SharedDataUtil;
|
||||||
import io.vertx.core.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
@@ -36,23 +35,9 @@ public class LogStatistics implements AfterInterceptor {
|
|||||||
|
|
||||||
ParserLogInfo parserLogInfo = new ParserLogInfo();
|
ParserLogInfo parserLogInfo = new ParserLogInfo();
|
||||||
parserLogInfo.setPath(ctx.request().uri());
|
parserLogInfo.setPath(ctx.request().uri());
|
||||||
if (responseData == null) {
|
if (responseData == null) return;
|
||||||
String location = ctx.response().headers().get("location");
|
if (responseData.containsKey("code") && responseData.getInteger("code") == 500) {
|
||||||
if (location != null) {
|
log.error("code 500: {} {}", ctx.request().path(), responseData.getString("msg"));
|
||||||
parserLogInfo.setCode(200);
|
|
||||||
parserLogInfo.setData(location);
|
|
||||||
} else {
|
|
||||||
log.error("location不存在且responseData为空, path={}", ctx.request().path());
|
|
||||||
}
|
|
||||||
insert(parserLogInfo);
|
|
||||||
|
|
||||||
} else if (responseData.containsKey("code")) {
|
|
||||||
JsonResult<?> result = JsonResult.toJsonResult(responseData);
|
|
||||||
parserLogInfo.setCode(result.getCode());
|
|
||||||
parserLogInfo.setData(result.getCode() == 500 ? result.getMsg() : result.getData().toString());
|
|
||||||
insert(parserLogInfo);
|
|
||||||
} else {
|
|
||||||
log.error("未知json日志: {}, path: {}", responseData.encode(), ctx.request().path());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public class ParserLogInfo {
|
|||||||
String id = SnowflakeIdWorker.getStringId();
|
String id = SnowflakeIdWorker.getStringId();
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS", timezone = "GMT+8")
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS", timezone = "GMT+8")
|
||||||
Date logTime = new Date();
|
Date logTime = new Date();
|
||||||
|
|
||||||
|
@Length(varcharSize = 4096)
|
||||||
String path;
|
String path;
|
||||||
Integer code;
|
Integer code;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package cn.qaiu.lz.common.util;
|
||||||
|
|
||||||
|
import io.vertx.core.MultiMap;
|
||||||
|
import io.vertx.core.http.HttpServerRequest;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理URL截断问题,拼接被截断的参数,特殊处理pwd参数。
|
||||||
|
*
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2024/9/13
|
||||||
|
*/
|
||||||
|
public class URLParamUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析并处理截断的URL参数
|
||||||
|
*
|
||||||
|
* @param request HttpServerRequest对象
|
||||||
|
* @return 完整的URL字符串
|
||||||
|
*/
|
||||||
|
public static String parserParams(HttpServerRequest request) {
|
||||||
|
|
||||||
|
String url = request.absoluteURI();
|
||||||
|
MultiMap params = request.params();
|
||||||
|
// 处理URL截断的情况,例如: url='https://...&key=...&code=...'
|
||||||
|
if (params.contains("url")) {
|
||||||
|
String encodedUrl = params.get("url");
|
||||||
|
url = handleTruncatedUrl(encodedUrl, params);
|
||||||
|
if (url.endsWith(".html")) {
|
||||||
|
// 123云盘的后缀处理
|
||||||
|
url = url.replace(".html", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理被截断的URL,拼接所有参数,特殊处理pwd参数。
|
||||||
|
*
|
||||||
|
* @param encodedUrl 被截断的url参数
|
||||||
|
* @param params 请求的其他参数
|
||||||
|
* @return 重新拼接后的完整URL
|
||||||
|
*/
|
||||||
|
private static String handleTruncatedUrl(String encodedUrl, MultiMap params) {
|
||||||
|
// 对URL进行解码,以便获取完整的URL
|
||||||
|
String decodedUrl = URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
// 如果URL已经包含查询参数,不需要额外拼接
|
||||||
|
if (params.contains("pwd")) {
|
||||||
|
if (params.size() == 2) {
|
||||||
|
return decodedUrl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (params.size() == 1) {
|
||||||
|
return decodedUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接被截断的URL参数,忽略pwd参数
|
||||||
|
StringBuilder urlBuilder = new StringBuilder(decodedUrl);
|
||||||
|
boolean firstParam = !decodedUrl.contains("?");
|
||||||
|
|
||||||
|
for (String paramName : params.names()) {
|
||||||
|
if (!paramName.equals("url") && !paramName.equals("pwd")) { // 忽略 "url" 和 "pwd" 参数
|
||||||
|
if (firstParam) {
|
||||||
|
urlBuilder.append("?");
|
||||||
|
firstParam = false;
|
||||||
|
} else {
|
||||||
|
urlBuilder.append("&");
|
||||||
|
}
|
||||||
|
urlBuilder.append(paramName).append("=").append(params.get(paramName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package cn.qaiu.lz.web.http;
|
package cn.qaiu.lz.web.http;
|
||||||
|
|
||||||
import cn.qaiu.parser.IPanTool;
|
import cn.qaiu.lz.common.util.URLParamUtil;
|
||||||
import cn.qaiu.parser.impl.EcTool;
|
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||||
import cn.qaiu.parser.impl.QQTool;
|
import cn.qaiu.lz.web.service.CacheService;
|
||||||
import cn.qaiu.vx.core.annotaions.RouteHandler;
|
import cn.qaiu.vx.core.annotaions.RouteHandler;
|
||||||
import cn.qaiu.vx.core.annotaions.RouteMapping;
|
import cn.qaiu.vx.core.annotaions.RouteMapping;
|
||||||
import cn.qaiu.vx.core.enums.RouteMethod;
|
import cn.qaiu.vx.core.enums.RouteMethod;
|
||||||
|
import cn.qaiu.vx.core.util.AsyncServiceUtil;
|
||||||
import cn.qaiu.vx.core.util.ResponseUtil;
|
import cn.qaiu.vx.core.util.ResponseUtil;
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.http.HttpServerRequest;
|
import io.vertx.core.http.HttpServerRequest;
|
||||||
@@ -24,58 +24,53 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@RouteHandler("/")
|
@RouteHandler("/")
|
||||||
public class ServerApi {
|
public class ServerApi {
|
||||||
|
|
||||||
@RouteMapping(value = "/parser", method = RouteMethod.GET, order = 4)
|
private final CacheService cacheService = AsyncServiceUtil.getAsyncServiceInstance(CacheService.class);
|
||||||
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
|
|
||||||
|
|
||||||
|
@RouteMapping(value = "/parser", method = RouteMethod.GET, order = 4)
|
||||||
|
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String pwd) {
|
||||||
Promise<Void> promise = Promise.promise();
|
Promise<Void> promise = Promise.promise();
|
||||||
if (url.contains(EcTool.SHARE_URL_PREFIX)) {
|
String url = URLParamUtil.parserParams(request);
|
||||||
// 默认读取Url参数会被截断手动获取一下其他参数
|
|
||||||
url = EcTool.SHARE_URL_PREFIX + request.getParam("data");
|
cacheService.getCachedByShareUrlAndPwd(url, pwd)
|
||||||
}
|
.onSuccess(res -> ResponseUtil.redirect(
|
||||||
if (url.contains(QQTool.SHARE_URL_PREFIX)) {
|
response.putHeader("nfd-cache-hit", res.getCacheHit().toString())
|
||||||
// 默认读取Url参数会被截断手动获取一下其他参数
|
.putHeader("nfd-cache-expires", res.getExpires()),
|
||||||
url = url + "&key=" + request.getParam("key") +
|
res.getDirectLink(), promise))
|
||||||
"&code=" + request.getParam("code") + "&k=" + request.getParam("k") +
|
|
||||||
"&fweb=" + request.getParam("fweb") + "&cl=" + request.getParam("cl");
|
|
||||||
}
|
|
||||||
IPanTool.shareURLPrefixMatching(url, pwd).parse()
|
|
||||||
.onSuccess(resUrl -> ResponseUtil.redirect(response, resUrl, promise))
|
|
||||||
.onFailure(t -> promise.fail(t.fillInStackTrace()));
|
.onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RouteMapping(value = "/json/parser", method = RouteMethod.GET, order = 3)
|
@RouteMapping(value = "/json/parser", method = RouteMethod.GET, order = 3)
|
||||||
public Future<String> parseJson(HttpServerRequest request, String url, String pwd) {
|
public Future<CacheLinkInfo> parseJson(HttpServerRequest request, String pwd) {
|
||||||
if (url.contains(EcTool.SHARE_URL_PREFIX)) {
|
String url = URLParamUtil.parserParams(request);
|
||||||
// 默认读取Url参数会被截断手动获取一下其他参数
|
return cacheService.getCachedByShareUrlAndPwd(url, pwd);
|
||||||
url = EcTool.SHARE_URL_PREFIX + request.getParam("data");
|
|
||||||
}
|
|
||||||
return IPanTool.shareURLPrefixMatching(url, pwd).parse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET, order = 2)
|
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET, order = 2)
|
||||||
public Future<String> parseKeyJson(String type, String key) {
|
public Future<CacheLinkInfo> parseKeyJson(String type, String key) {
|
||||||
String code = "";
|
String pwd = "";
|
||||||
if (key.contains("@")) {
|
if (key.contains("@")) {
|
||||||
String[] keys = key.split("@");
|
String[] keys = key.split("@");
|
||||||
key = keys[0];
|
key = keys[0];
|
||||||
code = keys[1];
|
pwd = keys[1];
|
||||||
}
|
}
|
||||||
return IPanTool.typeMatching(type, key, code).parse();
|
return cacheService.getCachedByShareKeyAndPwd(type, key, pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET, order = 1)
|
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET, order = 1)
|
||||||
public Future<Void> parseKey(HttpServerResponse response, String type, String key) {
|
public Future<Void> parseKey(HttpServerResponse response, String type, String key) {
|
||||||
Promise<Void> promise = Promise.promise();
|
Promise<Void> promise = Promise.promise();
|
||||||
String code = "";
|
String pwd = "";
|
||||||
if (key.contains("@")) {
|
if (key.contains("@")) {
|
||||||
String[] keys = key.split("@");
|
String[] keys = key.split("@");
|
||||||
key = keys[0];
|
key = keys[0];
|
||||||
code = keys[1];
|
pwd = keys[1];
|
||||||
}
|
}
|
||||||
|
cacheService.getCachedByShareKeyAndPwd(type, key, pwd)
|
||||||
IPanTool.typeMatching(type, key, code).parse()
|
.onSuccess(res -> ResponseUtil.redirect(
|
||||||
.onSuccess(resUrl -> ResponseUtil.redirect(response, resUrl, promise))
|
response.putHeader("nfd-cache-hit", res.getCacheHit().toString())
|
||||||
|
.putHeader("nfd-cache-expires", res.getExpires()),
|
||||||
|
res.getDirectLink(), promise))
|
||||||
.onFailure(t -> promise.fail(t.fillInStackTrace()));
|
.onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package cn.qaiu.lz.web.model;
|
||||||
|
|
||||||
|
import cn.qaiu.db.ddl.Length;
|
||||||
|
import cn.qaiu.db.ddl.Table;
|
||||||
|
import cn.qaiu.lz.common.ToJson;
|
||||||
|
import io.vertx.codegen.annotations.DataObject;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2024/9/11 16:06
|
||||||
|
*/
|
||||||
|
@Table(value = "api_statistics_info", keyFields = "share_key")
|
||||||
|
@Data
|
||||||
|
@DataObject
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ApiStatisticsInfo implements ToJson {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pan type 单独拿出来便于统计.
|
||||||
|
*/
|
||||||
|
@Length(varcharSize = 4)
|
||||||
|
private String panType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分享key type:key
|
||||||
|
*/
|
||||||
|
@Length(varcharSize = 4096)
|
||||||
|
private String shareKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命中缓存次数
|
||||||
|
*/
|
||||||
|
private Integer cacheHitTotal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api解析次数
|
||||||
|
*/
|
||||||
|
private Integer apiParserTotal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间戳
|
||||||
|
*/
|
||||||
|
private Long updateTs;
|
||||||
|
|
||||||
|
// 使用 JsonObject 构造
|
||||||
|
public ApiStatisticsInfo(JsonObject json) {
|
||||||
|
if (json.containsKey("panType")) {
|
||||||
|
this.setPanType(json.getString("panType"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("shareKey")) {
|
||||||
|
this.setShareKey(json.getString("shareKey"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("cacheHitTotal")) {
|
||||||
|
this.setCacheHitTotal(json.getInteger("cacheHitTotal"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("apiParserTotal")) {
|
||||||
|
this.setApiParserTotal(json.getInteger("apiParserTotal"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("updateTs")) {
|
||||||
|
this.setUpdateTs(json.getLong("updateTs"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package cn.qaiu.lz.web.model;
|
||||||
|
|
||||||
|
import cn.qaiu.db.ddl.Length;
|
||||||
|
import cn.qaiu.db.ddl.Table;
|
||||||
|
import cn.qaiu.db.ddl.TableGenIgnore;
|
||||||
|
import cn.qaiu.lz.common.ToJson;
|
||||||
|
import io.vertx.codegen.annotations.DataObject;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2024/9/11 16:06
|
||||||
|
*/
|
||||||
|
@Table(value = "cache_link_info", keyFields = "share_key")
|
||||||
|
@Data
|
||||||
|
@DataObject
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class CacheLinkInfo implements ToJson {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存key: type:ShareKey; e.g. lz:xxxx
|
||||||
|
*/
|
||||||
|
@Length(varcharSize = 4096)
|
||||||
|
private String shareKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析后的直链
|
||||||
|
*/
|
||||||
|
@Length(varcharSize = 4096)
|
||||||
|
private String directLink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否命中缓存
|
||||||
|
*/
|
||||||
|
@TableGenIgnore
|
||||||
|
private Boolean cacheHit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 到期时间 yyyy-MM-dd hh:mm:ss
|
||||||
|
*/
|
||||||
|
@TableGenIgnore
|
||||||
|
private String expires;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有效期
|
||||||
|
*/
|
||||||
|
private Long expiration;
|
||||||
|
|
||||||
|
|
||||||
|
// 使用 JsonObject 构造
|
||||||
|
public CacheLinkInfo(JsonObject json) {
|
||||||
|
if (json.containsKey("shareKey")) {
|
||||||
|
this.setShareKey(json.getString("shareKey"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("directLink")) {
|
||||||
|
this.setDirectLink(json.getString("directLink"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("expires")) {
|
||||||
|
this.setExpires(json.getString("expires"));
|
||||||
|
}
|
||||||
|
if (json.containsKey("expiration")) {
|
||||||
|
this.setExpiration(json.getLong("expiration"));
|
||||||
|
}
|
||||||
|
this.setCacheHit(json.getBoolean("cacheHit", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,14 +10,14 @@ import lombok.NoArgsConstructor;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@DataObject
|
@DataObject
|
||||||
public class StatisticsInfo implements ToJson {
|
public class StatisticsInfo implements ToJson {
|
||||||
Integer fail;
|
Integer parserTotal;
|
||||||
Integer success;
|
Integer cacheTotal;
|
||||||
Integer total;
|
Integer total;
|
||||||
|
|
||||||
|
|
||||||
public StatisticsInfo(JsonObject jsonObject) {
|
public StatisticsInfo(JsonObject jsonObject) {
|
||||||
this.fail = jsonObject.getInteger("fail");
|
this.parserTotal = jsonObject.getInteger("parserTotal");
|
||||||
this.success = jsonObject.getInteger("success");
|
this.cacheTotal = jsonObject.getInteger("cacheTotal");
|
||||||
this.total = jsonObject.getInteger("total");
|
this.total = jsonObject.getInteger("total");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package cn.qaiu.lz.web.service;
|
||||||
|
|
||||||
|
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||||
|
import cn.qaiu.vx.core.base.BaseAsyncService;
|
||||||
|
import io.vertx.codegen.annotations.ProxyGen;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2024/9/12 8:26
|
||||||
|
*/
|
||||||
|
@ProxyGen
|
||||||
|
public interface CacheService extends BaseAsyncService {
|
||||||
|
|
||||||
|
Future<CacheLinkInfo> getCachedByShareKeyAndPwd(String type, String shareKey, String pwd);
|
||||||
|
|
||||||
|
Future<CacheLinkInfo> getCachedByShareUrlAndPwd(String shareUrl, String pwd);
|
||||||
|
}
|
||||||
@@ -19,4 +19,5 @@ public interface DbService extends BaseAsyncService {
|
|||||||
Future<JsonObject> sayOk2(String data, UserInfo holder);
|
Future<JsonObject> sayOk2(String data, UserInfo holder);
|
||||||
|
|
||||||
Future<StatisticsInfo> getStatisticsInfo();
|
Future<StatisticsInfo> getStatisticsInfo();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package cn.qaiu.lz.web.service;
|
|
||||||
|
|
||||||
import cn.qaiu.vx.core.util.CastUtil;
|
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDK代理类工厂
|
|
||||||
*/
|
|
||||||
public class JdkProxyFactory {
|
|
||||||
public static <T> T getProxy(T target) {
|
|
||||||
return CastUtil.cast(Proxy.newProxyInstance(
|
|
||||||
target.getClass().getClassLoader(),
|
|
||||||
target.getClass().getInterfaces(),
|
|
||||||
new ServiceJdkProxy<>(target))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package cn.qaiu.lz.web.service.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
import cn.qaiu.lz.common.cache.CacheConfigLoader;
|
||||||
|
import cn.qaiu.lz.common.cache.CacheManager;
|
||||||
|
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
||||||
|
import cn.qaiu.lz.web.service.CacheService;
|
||||||
|
import cn.qaiu.parser.ParserCreate;
|
||||||
|
import cn.qaiu.vx.core.annotaions.Service;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CacheServiceImpl implements CacheService {
|
||||||
|
|
||||||
|
private final CacheManager cacheManager = new CacheManager();
|
||||||
|
|
||||||
|
private Future<CacheLinkInfo> getAndSaveCachedShareLink(ParserCreate parserCreate) {
|
||||||
|
Promise<CacheLinkInfo> promise = Promise.promise();
|
||||||
|
// 构建组合的缓存key
|
||||||
|
ShareLinkInfo shareLinkInfo = parserCreate.getShareLinkInfo();
|
||||||
|
String cacheKey = generateCacheKey(shareLinkInfo.getType(), shareLinkInfo.getShareKey());
|
||||||
|
// 尝试从缓存中获取
|
||||||
|
cacheManager.get(cacheKey).onSuccess(result -> {
|
||||||
|
// 判断是否已过期
|
||||||
|
// 未命中或者过期
|
||||||
|
if (!result.getCacheHit() || result.getExpiration() < System.currentTimeMillis()) {
|
||||||
|
// parse
|
||||||
|
result.setCacheHit(false);
|
||||||
|
result.setExpiration(0L);
|
||||||
|
parserCreate.createTool().parse().onSuccess(redirectUrl -> {
|
||||||
|
long expires = System.currentTimeMillis() +
|
||||||
|
CacheConfigLoader.getDuration(shareLinkInfo.getType()) * 60 * 1000L;
|
||||||
|
result.setDirectLink(redirectUrl);
|
||||||
|
// result.setExpires(generateDate(expires));
|
||||||
|
promise.complete(result);
|
||||||
|
// 更新缓存
|
||||||
|
// 将直链存储到缓存
|
||||||
|
CacheLinkInfo cacheLinkInfo = new CacheLinkInfo(JsonObject.of(
|
||||||
|
"directLink", redirectUrl,
|
||||||
|
"expiration", expires,
|
||||||
|
"shareKey", cacheKey
|
||||||
|
));
|
||||||
|
cacheManager.cacheShareLink(cacheLinkInfo).onFailure(Throwable::printStackTrace);
|
||||||
|
cacheManager.updateTotalByParser(cacheKey).onFailure(Throwable::printStackTrace);
|
||||||
|
}).onFailure(promise::fail);
|
||||||
|
} else {
|
||||||
|
result.setExpires(generateDate(result.getExpiration()));
|
||||||
|
promise.complete(result);
|
||||||
|
cacheManager.updateTotalByCached(cacheKey).onFailure(Throwable::printStackTrace);
|
||||||
|
}
|
||||||
|
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateCacheKey(String type, String shareKey) {
|
||||||
|
// 将type和shareKey组合成一个字符串作为缓存key
|
||||||
|
return type + ":" + shareKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateDate(Long ts) {
|
||||||
|
return DateFormatUtils.format(new Date(ts), "yyyy-MM-dd HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<CacheLinkInfo> getCachedByShareKeyAndPwd(String type, String shareKey, String pwd) {
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromType(type).shareKey(shareKey).setShareLinkInfoPwd(pwd);
|
||||||
|
return getAndSaveCachedShareLink(parserCreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<CacheLinkInfo> getCachedByShareUrlAndPwd(String shareUrl, String pwd) {
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromShareUrl(shareUrl).setShareLinkInfoPwd(pwd);
|
||||||
|
return getAndSaveCachedShareLink(parserCreate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,10 +48,9 @@ public class DbServiceImpl implements DbService {
|
|||||||
JDBCPool client = JDBCPoolInit.instance().getPool();
|
JDBCPool client = JDBCPoolInit.instance().getPool();
|
||||||
Promise<StatisticsInfo> promise = Promise.promise();
|
Promise<StatisticsInfo> promise = Promise.promise();
|
||||||
String sql = """
|
String sql = """
|
||||||
select COUNT(CASE "code" WHEN 500 THEN "code" END ) "fail",
|
select sum(api_parser_total) parserTotal,sum("cache_hit_total") cacheTotal,
|
||||||
COUNT(CASE "code" WHEN 200 THEN "code" END ) "success",
|
sum(api_parser_total) + sum("cache_hit_total") total
|
||||||
count(1) "total"
|
from "api_statistics_info";
|
||||||
from "t_parser_log_info"
|
|
||||||
""";
|
""";
|
||||||
SqlTemplate.forQuery(client, sql).mapTo(StatisticsInfo.class).execute(new HashMap<>()).onSuccess(row -> {
|
SqlTemplate.forQuery(client, sql).mapTo(StatisticsInfo.class).execute(new HashMap<>()).onSuccess(row -> {
|
||||||
StatisticsInfo info;
|
StatisticsInfo info;
|
||||||
|
|||||||
@@ -39,3 +39,23 @@ dataSource:
|
|||||||
driverClassName: org.h2.Driver
|
driverClassName: org.h2.Driver
|
||||||
username: root
|
username: root
|
||||||
password: '123456'
|
password: '123456'
|
||||||
|
|
||||||
|
# 缓存配置
|
||||||
|
cache:
|
||||||
|
type: h2db
|
||||||
|
# 默认时长: 单位分钟, 实际有效期分钟-1
|
||||||
|
defaultDuration: 59
|
||||||
|
duration:
|
||||||
|
ce:
|
||||||
|
cow:
|
||||||
|
ec:
|
||||||
|
fc:
|
||||||
|
fj:
|
||||||
|
iz:
|
||||||
|
le: 2879
|
||||||
|
lz:
|
||||||
|
qq: 999999
|
||||||
|
ws:
|
||||||
|
ye:
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 要激活的配置: dev--连接本地数据库; prod连接线上数据库
|
# 要激活的配置: dev--连接本地数据库; prod连接线上数据库
|
||||||
active: dev
|
active: dev
|
||||||
# 版本号
|
# 版本号
|
||||||
version_app: 0.1.7
|
version_app: 0.1.8
|
||||||
# 公司名称 -> LOGO版权文字
|
# 公司名称 -> LOGO版权文字
|
||||||
copyright: QAIU
|
copyright: QAIU
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
10
web-service/src/main/resources/http-tools/pan-cx.http
Normal file
10
web-service/src/main/resources/http-tools/pan-cx.http
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
###超星
|
||||||
|
|
||||||
|
### 直链 Referer
|
||||||
|
https://d0.ananas.chaoxing.com/download/8e8c9baca640d24680d974331390a158?at_=1717958244333&ak_=783925f9ba6eb2d0c711977b777a13e0&ad_=58ffecd38be494bea68f0cda68b18c0a&fn=testgles.c
|
||||||
|
Referer: https://pan-yz.chaoxing.com/external/m/file/1006748113111711744
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
@@ -59,3 +59,10 @@ Origin:https://www.feijipan.com
|
|||||||
Referer:https://www.feijipan.com/
|
Referer:https://www.feijipan.com/
|
||||||
|
|
||||||
{"loginName":"","loginPwd":""}
|
{"loginName":"","loginPwd":""}
|
||||||
|
|
||||||
|
|
||||||
|
### 240530 规则修改
|
||||||
|
### https://share.feijipan.com/s/nMtCOXL
|
||||||
|
POST https://api.feijipan.com/ws/recommend/list?devType=6&devModel=Chrome&uuid=WQAl5yBy1naGudJEILBvE&extra=2×tamp=A8ECC3C7C50191ACEB9CB8444FD37624&shareId=nMtCOXL&type=0&offset=1&limit=60
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
### 蓝奏云
|
### PASS 蓝奏云
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://lanzoux.com/ia2cntg
|
GET http://127.0.0.1:6400/parser?url=https://www.lanzoux.com/ia2cntg
|
||||||
|
|
||||||
### 蓝奏云
|
### 蓝奏云
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
@@ -8,19 +8,19 @@ GET http://127.0.0.1:6400/json/parser?url=https://wwsd.lanzoue.com/iLany1e9bbbi
|
|||||||
|
|
||||||
### 蓝奏云
|
### 蓝奏云
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/lz/i6SqHmp1yfc
|
GET http://127.0.0.1:6400/json/lz/i6SqHmp1yfc
|
||||||
### 蓝奏云https://acgtools.lanzoui.com/iUr7Qnu3sxc https://wwn.lanzouy.com/tp/ihLkw1gezutg https://wwn.lanzouy.com/ihLkw1gezutg
|
### 蓝奏云https://acgtools.lanzoui.com/iUr7Qnu3sxc https://wwn.lanzouy.com/tp/ihLkw1gezutg https://wwn.lanzouy.com/ihLkw1gezutg
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/lz/ihLkw1gezutg
|
GET http://127.0.0.1:6400/lz/ihLkw1gezutg
|
||||||
|
|
||||||
### 蓝奏云
|
### 蓝奏云
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/lz/icBp6qqj82b@QAIU
|
GET http://127.0.0.1:6400/json/lz/icBp6qqj82b@QAIU
|
||||||
|
|
||||||
### 蓝奏云
|
### 蓝奏云
|
||||||
GET http://127.0.0.1:6400/json/lz/ia2cntg
|
GET http://127.0.0.1:6400/json/lz/ia2cntg
|
||||||
|
|
||||||
### 蓝奏云优享
|
### PASS 蓝奏云优享
|
||||||
GET http://127.0.0.1:6400/json/iz/lGFndCM
|
GET http://127.0.0.1:6400/json/iz/lGFndCM
|
||||||
|
|
||||||
###
|
###
|
||||||
@@ -34,7 +34,7 @@ GET http://127.0.0.1:6400/json/parser?url=https://www.ilanzou.com/s/zHkna1S
|
|||||||
GET http://127.0.0.1:6400/json/cow/9a644fe3e3a748
|
GET http://127.0.0.1:6400/json/cow/9a644fe3e3a748
|
||||||
Referer: https://cowtransfer.com/
|
Referer: https://cowtransfer.com/
|
||||||
|
|
||||||
### 奶牛
|
### PASS 奶牛
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/cow/e4f41b51b5da4f
|
GET http://127.0.0.1:6400/cow/e4f41b51b5da4f
|
||||||
|
|
||||||
@@ -47,9 +47,9 @@ GET http://127.0.0.1:6400/parser?url=https://cowtransfer.com/s/9a644fe3e3a748
|
|||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://goldrepo.cowtransfer.com/s/026a638795634b
|
GET http://127.0.0.1:6400/parser?url=https://goldrepo.cowtransfer.com/s/026a638795634b
|
||||||
|
|
||||||
### 移动云空间 https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
### 移动云空间 PASS https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://www.ecpan.cn/web//yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
GET http://127.0.0.1:6400/parser?url=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
||||||
|
|
||||||
### 移动云空间 https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=aa0cae0164d8885e6d35826b5b2901eckbWJBalM&parentId=-1
|
### 移动云空间 https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=aa0cae0164d8885e6d35826b5b2901eckbWJBalM&parentId=-1
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
@@ -62,21 +62,7 @@ GET http://127.0.0.1:6400/json/ec/4b3d786755688b85c6eb0c04b9124f4dalzdaJpXHx@T6O
|
|||||||
#@no-redirect
|
#@no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=4b3d786755688b85c6eb0c04b9124f4dalzdaJpXHx&isShare=1&pwd=T6O1RC
|
GET http://127.0.0.1:6400/parser?url=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=4b3d786755688b85c6eb0c04b9124f4dalzdaJpXHx&isShare=1&pwd=T6O1RC
|
||||||
|
|
||||||
|
### 小飞机盘 PASS https://share.feijipan.com/s/nMtCOXL
|
||||||
|
|
||||||
### UC网盘
|
|
||||||
# @no-redirect
|
|
||||||
GET http://127.0.0.1:6400/uc/33197dd53ace4
|
|
||||||
|
|
||||||
### UC网盘
|
|
||||||
GET http://127.0.0.1:6400/json/uc/33197dd53ace4
|
|
||||||
|
|
||||||
### UC网盘
|
|
||||||
# @no-redirect
|
|
||||||
GET http://127.0.0.1:6400/parser?url=https://fast.uc.cn/s/33197dd53ace4
|
|
||||||
|
|
||||||
|
|
||||||
### 小飞机盘https://share.feijipan.com/s/nMtCOXL
|
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://share.feijipan.com/s/nMtCOXL
|
GET http://127.0.0.1:6400/parser?url=https://share.feijipan.com/s/nMtCOXL
|
||||||
|
|
||||||
@@ -98,7 +84,7 @@ GET http://127.0.0.1:6400/parser?url=https://v2.fangcloud.com/sharing/fb54bdf03c
|
|||||||
### 360亿方云
|
### 360亿方云
|
||||||
GET http://127.0.0.1:6400/json/fc/fb54bdf03c66c04334fe3687a3
|
GET http://127.0.0.1:6400/json/fc/fb54bdf03c66c04334fe3687a3
|
||||||
|
|
||||||
### 360亿方云
|
### 360亿方云 PASS
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/fc/e5079007dc31226096628870c7@QAIU
|
GET http://127.0.0.1:6400/fc/e5079007dc31226096628870c7@QAIU
|
||||||
|
|
||||||
@@ -113,7 +99,7 @@ GET http://127.0.0.1:6400/json/ye/iaKtVv-6OECd@DcGe
|
|||||||
### 123
|
### 123
|
||||||
GET https://lz.qaiu.top/json/ye/iaKtVv-6OECd@DcGe
|
GET https://lz.qaiu.top/json/ye/iaKtVv-6OECd@DcGe
|
||||||
|
|
||||||
### 123
|
### 123 PASS
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/ye/iaKtVv-qOECd
|
GET http://127.0.0.1:6400/ye/iaKtVv-qOECd
|
||||||
|
|
||||||
@@ -121,7 +107,7 @@ GET http://127.0.0.1:6400/ye/iaKtVv-qOECd
|
|||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/ye/Ev1lVv-t3SY3
|
GET http://127.0.0.1:6400/ye/Ev1lVv-t3SY3
|
||||||
|
|
||||||
### 123 https://www.123pan.com/s/iaKtVv-6OECd.html
|
### 123 PASS https://www.123pan.com/s/iaKtVv-6OECd.html
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/json/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&pwd=DcGe
|
GET http://127.0.0.1:6400/json/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&pwd=DcGe
|
||||||
|
|
||||||
@@ -131,29 +117,37 @@ GET http://127.0.0.1:6400/json/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.
|
|||||||
GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/zF07Vv-WkHWd.html&pwd=bios
|
GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/zF07Vv-WkHWd.html&pwd=bios
|
||||||
|
|
||||||
|
|
||||||
### 联想乐云
|
### 联想乐云 PASS
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://lecloud.lenovo.com/share/4DANWdRQsHHyiFB4a
|
GET http://127.0.0.1:6400/parser?url=https://lecloud.lenovo.com/share/4DANWdRQsHHyiFB4a
|
||||||
|
|
||||||
### 联想乐云
|
### 联想乐云 PASS
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/le/4DANWdRQsHHyiFB4a
|
GET http://127.0.0.1:6400/le/4DANWdRQsHHyiFB4a
|
||||||
|
|
||||||
### 联想乐云
|
### 联想乐云 PASS
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/le/2RkKbLP9BrppS9b43@ex2b
|
GET http://127.0.0.1:6400/le/2RkKbLP9BrppS9b43@ex2b
|
||||||
|
|
||||||
### 联想乐云
|
### 联想乐云 PASS
|
||||||
GET http://127.0.0.1:6400/json/le/2RkKbLP9BrppS9b43@ex2b
|
GET http://127.0.0.1:6400/json/le/2RkKbLP9BrppS9b43@ex2b
|
||||||
|
|
||||||
### 文叔叔
|
### PASS 文叔叔
|
||||||
GET http://127.0.0.1:6400/json/parser?url=https://f.ws59.cn/f/e3peohu6192
|
GET http://127.0.0.1:6400/parser?url=https://f.ws59.cn/f/f25625rv6p6
|
||||||
|
###
|
||||||
|
https://f.wss.cc/f/f25625rv6p6
|
||||||
|
|
||||||
### Cloudreve
|
### TODO Cloudreve
|
||||||
GET http://127.0.0.1:6400/json/ce/https_pan.huang1111.cn_s_wDz5TK
|
GET http://127.0.0.1:6400/json/ce/https_pan.huang1111.cn_s_wDz5TK
|
||||||
|
|
||||||
### Cloudreve https://pan.huang1111.cn/s/g31PcQ
|
### Cloudreve https://pan.huang1111.cn/s/g31PcQ
|
||||||
GET http://127.0.0.1:6400/json/parser?url=https://pan.huang1111.cn/s/g31PcQ&pwd=qaiu
|
GET http://127.0.0.1:6400/parser?url=https://pan.huang1111.cn/s/g31PcQ&pwd=qaiu
|
||||||
|
|
||||||
|
### PASS QQ
|
||||||
|
# @no-redirect
|
||||||
|
GET http://127.0.0.1:6400/json/parser?url=https://iwx.mail.qq.com/ftn/download?func=3&key=qweqe&code=8c02cf57&k=asdad
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
GET http://127.0.0.1:6400/v2/statisticsInfo
|
GET http://127.0.0.1:6400/v2/statisticsInfo
|
||||||
|
|||||||
Reference in New Issue
Block a user