mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 12:23:03 +00:00
Compare commits
38 Commits
0.1.6-rele
...
0.1.6-rele
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8441954075 | ||
|
|
5e0568fa0e | ||
|
|
594e9af71d | ||
|
|
9bc7e9aa26 | ||
|
|
5805edf0a9 | ||
|
|
9614a36fc2 | ||
|
|
f45031c3f1 | ||
|
|
28e0542c8e | ||
|
|
b78a8300c6 | ||
|
|
ca06d5ae98 | ||
|
|
0c5e53b86e | ||
|
|
f45e6f3468 | ||
|
|
08ffec524e | ||
|
|
62dea67d69 | ||
|
|
8108a4dd3f | ||
|
|
56334fa4a2 | ||
|
|
093b337396 | ||
|
|
4bedf4486b | ||
|
|
b700493a6c | ||
|
|
44b1168bb5 | ||
|
|
a351364faf | ||
|
|
6bd075e17c | ||
|
|
1e77b20e44 | ||
|
|
0c2165dbf3 | ||
|
|
7595345e7b | ||
|
|
d13fe1fc21 | ||
|
|
f0269b1687 | ||
|
|
257147dd75 | ||
|
|
6fe824e705 | ||
|
|
f482982a25 | ||
|
|
e3ec81bd9b | ||
|
|
4771a5b5ce | ||
|
|
1292440f95 | ||
|
|
c2052ddbd8 | ||
|
|
f65dfacf4b | ||
|
|
27c2c1ab29 | ||
|
|
b4471dd9c3 | ||
|
|
69d8b645a4 |
29
README.md
29
README.md
@@ -1,4 +1,5 @@
|
|||||||
# netdisk-fast-download
|
# netdisk-fast-download
|
||||||
|
预览地址 https://lz.qaiu.top
|
||||||
|
|
||||||
[](https://github.com/qaiu/netdisk-fast-download/actions/workflows/maven.yml)
|
[](https://github.com/qaiu/netdisk-fast-download/actions/workflows/maven.yml)
|
||||||
[](https://www.oracle.com/cn/java/technologies/downloads/)
|
[](https://www.oracle.com/cn/java/technologies/downloads/)
|
||||||
@@ -6,6 +7,9 @@
|
|||||||
[](https://github.com/qaiu/netdisk-fast-download/releases/tag/0.1.6-releases)
|
[](https://github.com/qaiu/netdisk-fast-download/releases/tag/0.1.6-releases)
|
||||||
|
|
||||||
## 网盘支持情况:
|
## 网盘支持情况:
|
||||||
|
> 20230722 UC网盘解析失效,需要登录
|
||||||
|
|
||||||
|
|
||||||
`网盘名称(网盘标识):`
|
`网盘名称(网盘标识):`
|
||||||
|
|
||||||
- [蓝奏云 (lz)](https://pc.woozooo.com/)
|
- [蓝奏云 (lz)](https://pc.woozooo.com/)
|
||||||
@@ -17,7 +21,7 @@
|
|||||||
- [移动云空间 (ec)](https://www.ecpan.cn/web)
|
- [移动云空间 (ec)](https://www.ecpan.cn/web)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
- [ ] 登录, 上传, 下载, 分享
|
||||||
- [X] 直链解析
|
- [X] 直链解析
|
||||||
- [UC网盘 (uc)](https://fast.uc.cn/)
|
- [UC网盘 (uc)似乎已经失效,需要登录](https://fast.uc.cn/)
|
||||||
- [ ] 登录, 上传, 下载, 分享
|
- [ ] 登录, 上传, 下载, 分享
|
||||||
- [X] 直链解析
|
- [X] 直链解析
|
||||||
- [小飞机网盘 (fj)](https://www.feijipan.com/)
|
- [小飞机网盘 (fj)](https://www.feijipan.com/)
|
||||||
@@ -35,7 +39,7 @@
|
|||||||
**TODO:**
|
**TODO:**
|
||||||
- 登录接口, 文件上传/下载/分享后端接口
|
- 登录接口, 文件上传/下载/分享后端接口
|
||||||
- 短地址服务
|
- 短地址服务
|
||||||
- 前端界面(正则规划)
|
- 前端界面(建设中...)
|
||||||
|
|
||||||
**技术栈:**
|
**技术栈:**
|
||||||
Jdk17+Vert.x4.4.1
|
Jdk17+Vert.x4.4.1
|
||||||
@@ -52,6 +56,7 @@ parser接口可以直接解析分享链接: 加密分享需要加上参数pwd=
|
|||||||
http(s)://your_host/parser?url=分享链接(&pwd=xxx)
|
http(s)://your_host/parser?url=分享链接(&pwd=xxx)
|
||||||
http(s)://your_host/网盘标识/分享key(@分享密码)
|
http(s)://your_host/网盘标识/分享key(@分享密码)
|
||||||
2. 获取解析后的直链--JSON格式
|
2. 获取解析后的直链--JSON格式
|
||||||
|
http(s)://your_host/json/parser?url=分享链接(&pwd=xxx)
|
||||||
http(s)://your_host/json/网盘标识/分享key(@分享密码)
|
http(s)://your_host/json/网盘标识/分享key(@分享密码)
|
||||||
3. 特别注意的地方:
|
3. 特别注意的地方:
|
||||||
- 有些网盘的加密分享的密码可以忽略: 如移动云空间,小飞机网盘
|
- 有些网盘的加密分享的密码可以忽略: 如移动云空间,小飞机网盘
|
||||||
@@ -60,6 +65,17 @@ parser接口可以直接解析分享链接: 加密分享需要加上参数pwd=
|
|||||||
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/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
|
http://your_host/parser?url=https://www.ecpan.cn/&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
|
||||||
```
|
```
|
||||||
|
json返回数据格式示例:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"success": true,
|
||||||
|
"count": 0,
|
||||||
|
"data": "https://下载链接",
|
||||||
|
"timestamp": 1690733953927
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
IDEA HttpClient示例:
|
IDEA HttpClient示例:
|
||||||
|
|
||||||
@@ -105,7 +121,7 @@ GET http://127.0.0.1:6400/json/fc/e5079007dc31226096628870c7@QAIU
|
|||||||
| 蓝奏云 | √ | √ | 不限空间 | 100M | TODO |
|
| 蓝奏云 | √ | √ | 不限空间 | 100M | TODO |
|
||||||
| 奶牛快传 | √ | X | 10G | 不限大小 | TODO |
|
| 奶牛快传 | √ | X | 10G | 不限大小 | TODO |
|
||||||
| 移动云空间 | √ | √(密码可忽略) | 5G(个人) | 不限大小 | TODO |
|
| 移动云空间 | √ | √(密码可忽略) | 5G(个人) | 不限大小 | TODO |
|
||||||
| UC网盘 | √ | √ | 10G | 不限大小 | TODO |
|
| UC网盘 | 需要登录 | √ | 10G | 不限大小 | TODO |
|
||||||
| 小飞机网盘 | √ | √(密码可忽略) | 10G | 不限大小 | TODO |
|
| 小飞机网盘 | √ | √(密码可忽略) | 10G | 不限大小 | TODO |
|
||||||
| 360亿方云 | √(试用账号有时间限制企业版需要599续费) | √(密码可忽略) | 100G(须实名) | 不限大小 | TODO |
|
| 360亿方云 | √(试用账号有时间限制企业版需要599续费) | √(密码可忽略) | 100G(须实名) | 不限大小 | TODO |
|
||||||
| 123云盘 | √ | √ | 2T | 100G | TODO |
|
| 123云盘 | √ | √ | 2T | 100G | TODO |
|
||||||
@@ -114,6 +130,12 @@ GET http://127.0.0.1:6400/json/fc/e5079007dc31226096628870c7@QAIU
|
|||||||
|
|
||||||
# 打包部署
|
# 打包部署
|
||||||
|
|
||||||
|
## JDK下载(lz.qaiu.top提供直链云解析服务)
|
||||||
|
- [阿里jdk17(Dragonwell17-windows-x86)](https://lz.qaiu.top/ye/iaKtVv-hbECd)
|
||||||
|
- [阿里jdk17(Dragonwell17-linux-x86)](https://lz.qaiu.top/ye/iaKtVv-AbECd)
|
||||||
|
- [阿里jdk17(Dragonwell17-linux-aarch64)](https://lz.qaiu.top/ye/iaKtVv-HbECd)
|
||||||
|
- [123云盘解析有效性测试用-阿里jdk17(Dragonwell17-linux-aarch64)](https://lz.qaiu.top/json/ye/iaKtVv-HbECd)
|
||||||
|
|
||||||
## 开发和打包
|
## 开发和打包
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -158,5 +180,6 @@ systemctl disable netdisk-fast-download.servic
|
|||||||
3. 使用管理员权限运行nfd-service-install.bat
|
3. 使用管理员权限运行nfd-service-install.bat
|
||||||
如果不想使用服务运行可以直接运行run.bat
|
如果不想使用服务运行可以直接运行run.bat
|
||||||
> 注意: 如果jdk环境变量的java版本不是17请修改nfd-service-template.xml中的java命令的路径改为实际路径
|
> 注意: 如果jdk环境变量的java版本不是17请修改nfd-service-template.xml中的java命令的路径改为实际路径
|
||||||
|
|
||||||
## Docker部署
|
## Docker部署
|
||||||
TODO
|
TODO
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import cn.qaiu.vx.core.verticle.ReverseProxyVerticle;
|
|||||||
import cn.qaiu.vx.core.verticle.RouterVerticle;
|
import cn.qaiu.vx.core.verticle.RouterVerticle;
|
||||||
import cn.qaiu.vx.core.verticle.ServiceVerticle;
|
import cn.qaiu.vx.core.verticle.ServiceVerticle;
|
||||||
import io.vertx.core.*;
|
import io.vertx.core.*;
|
||||||
|
import io.vertx.core.impl.launcher.commands.VersionCommand;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.core.shareddata.LocalMap;
|
import io.vertx.core.shareddata.LocalMap;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -95,7 +96,7 @@ public final class Deploy {
|
|||||||
|
|
||||||
System.out.printf(logoTemplete,
|
System.out.printf(logoTemplete,
|
||||||
conf.getString("version_app"),
|
conf.getString("version_app"),
|
||||||
conf.getString("version_vertx"),
|
VersionCommand.getVersion(),
|
||||||
conf.getString("copyright"),
|
conf.getString("copyright"),
|
||||||
year
|
year
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ import io.vertx.ext.web.RoutingContext;
|
|||||||
public interface Interceptor {
|
public interface Interceptor {
|
||||||
|
|
||||||
default Handler<RoutingContext> doHandle() {
|
default Handler<RoutingContext> doHandle() {
|
||||||
return this::handle;
|
return this::beforeHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle(RoutingContext context);
|
void beforeHandle(RoutingContext context);
|
||||||
|
|
||||||
|
void afterHandle(RoutingContext context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,11 +70,11 @@ public final class ReflectionUtil {
|
|||||||
// 发现注解api层 没有继承父类时 这里反射一直有问题(Scanner SubTypesScanner was not configured)
|
// 发现注解api层 没有继承父类时 这里反射一直有问题(Scanner SubTypesScanner was not configured)
|
||||||
// 因此这里需要手动配置各种Scanner扫描器 -- https://blog.csdn.net/qq_29499107/article/details/106889781
|
// 因此这里需要手动配置各种Scanner扫描器 -- https://blog.csdn.net/qq_29499107/article/details/106889781
|
||||||
configurationBuilder.setScanners(
|
configurationBuilder.setScanners(
|
||||||
new SubTypesScanner(false), //允许getAllTypes获取所有Object的子类, 不设置为false则 getAllTypes 会报错.默认为true.
|
Scanners.SubTypes.filterResultsBy(s -> true), //允许getAllTypes获取所有Object的子类, 不设置为false则 getAllTypes 会报错.默认为true.
|
||||||
new MethodParameterNamesScanner(), //设置方法参数名称 扫描器,否则调用getConstructorParamNames 会报错
|
new MethodParameterNamesScanner(), //设置方法参数名称 扫描器,否则调用getConstructorParamNames 会报错
|
||||||
new MethodAnnotationsScanner(), //设置方法注解 扫描器, 否则getConstructorsAnnotatedWith,getMethodsAnnotatedWith 会报错
|
Scanners.MethodsAnnotated, //设置方法注解 扫描器, 否则getConstructorsAnnotatedWith,getMethodsAnnotatedWith 会报错
|
||||||
new MemberUsageScanner(), //设置 member 扫描器,否则 getMethodUsage 会报错, 不推荐使用,有可能会报错 Caused by: java.lang.ClassCastException: javassist.bytecode.InterfaceMethodrefInfo cannot be cast to javassist.bytecode.MethodrefInfo
|
new MemberUsageScanner(), //设置 member 扫描器,否则 getMethodUsage 会报错, 不推荐使用,有可能会报错 Caused by: java.lang.ClassCastException: javassist.bytecode.InterfaceMethodrefInfo cannot be cast to javassist.bytecode.MethodrefInfo
|
||||||
new TypeAnnotationsScanner() //设置类注解 扫描器 ,否则 getTypesAnnotatedWith 会报错
|
Scanners.TypesAnnotated //设置类注解 扫描器 ,否则 getTypesAnnotatedWith 会报错
|
||||||
);
|
);
|
||||||
|
|
||||||
configurationBuilder.filterInputsBy(filterBuilder);
|
configurationBuilder.filterInputsBy(filterBuilder);
|
||||||
|
|||||||
25
web-front/.gitignore
vendored
Normal file
25
web-front/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
dist.zip
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
/nfd-front.zip
|
||||||
|
/nfd-front
|
||||||
26
web-front/README.md
Normal file
26
web-front/README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# nfd-web
|
||||||
|
当前页面修改自开源项目 https://github.com/HurryBy/CloudDiskAnalysis
|
||||||
|
|
||||||
|

|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
5
web-front/babel.config.js
Normal file
5
web-front/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
19
web-front/jsconfig.json
Normal file
19
web-front/jsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "esnext",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
13855
web-front/package-lock.json
generated
Normal file
13855
web-front/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
50
web-front/package.json
Normal file
50
web-front/package.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"name": "nfd-web",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.2.2",
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"element-ui": "^2.15.12",
|
||||||
|
"vue": "^2.6.14",
|
||||||
|
"vue-clipboard2": "^0.3.3",
|
||||||
|
"vue-json-viewer": "^2.2.22"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.16",
|
||||||
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
|
"@vue/cli-service": "~5.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
|
"vue-template-compiler": "^2.6.14",
|
||||||
|
|
||||||
|
"compression-webpack-plugin": "^6.1.1",
|
||||||
|
"filemanager-webpack-plugin": "2.0.5"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "@babel/eslint-parser"
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
web-front/public/avator.png
Normal file
BIN
web-front/public/avator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
web-front/public/favicon.ico
Normal file
BIN
web-front/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
168
web-front/public/index.html
Normal file
168
web-front/public/index.html
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cn">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<title>Netdisk fast download</title>
|
||||||
|
<meta name="keywords"
|
||||||
|
content="Netdisk fast download,网盘直链解析工具">
|
||||||
|
<meta name="description"
|
||||||
|
content="Netdisk fast download 网盘直链解析工具">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.page-loading-wrap {
|
||||||
|
padding: 120px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer,
|
||||||
|
.la-timer>div {
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer {
|
||||||
|
display: block;
|
||||||
|
font-size: 0;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer.la-dark {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer>div {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
background-color: currentColor;
|
||||||
|
border: 0 solid currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer>div {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
background: transparent;
|
||||||
|
border-width: 2px;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer>div:before,
|
||||||
|
.la-timer>div:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 14px;
|
||||||
|
left: 14px;
|
||||||
|
display: block;
|
||||||
|
width: 2px;
|
||||||
|
margin-top: -1px;
|
||||||
|
margin-left: -1px;
|
||||||
|
content: "";
|
||||||
|
background: currentColor;
|
||||||
|
border-radius: 2px;
|
||||||
|
-webkit-transform-origin: 1px 1px 0;
|
||||||
|
-moz-transform-origin: 1px 1px 0;
|
||||||
|
-ms-transform-origin: 1px 1px 0;
|
||||||
|
-o-transform-origin: 1px 1px 0;
|
||||||
|
transform-origin: 1px 1px 0;
|
||||||
|
-webkit-animation: timer-loader 1250ms infinite linear;
|
||||||
|
-moz-animation: timer-loader 1250ms infinite linear;
|
||||||
|
-o-animation: timer-loader 1250ms infinite linear;
|
||||||
|
animation: timer-loader 1250ms infinite linear;
|
||||||
|
-webkit-animation-delay: -625ms;
|
||||||
|
-moz-animation-delay: -625ms;
|
||||||
|
-o-animation-delay: -625ms;
|
||||||
|
animation-delay: -625ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer>div:before {
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-timer>div:after {
|
||||||
|
height: 8px;
|
||||||
|
-webkit-animation-duration: 15s;
|
||||||
|
-moz-animation-duration: 15s;
|
||||||
|
-o-animation-duration: 15s;
|
||||||
|
animation-duration: 15s;
|
||||||
|
-webkit-animation-delay: -7.5s;
|
||||||
|
-moz-animation-delay: -7.5s;
|
||||||
|
-o-animation-delay: -7.5s;
|
||||||
|
animation-delay: -7.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes timer-loader {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes timer-loader {
|
||||||
|
0% {
|
||||||
|
-moz-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-moz-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-o-keyframes timer-loader {
|
||||||
|
0% {
|
||||||
|
-o-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-o-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes timer-loader {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
-moz-transform: rotate(0deg);
|
||||||
|
-o-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
-moz-transform: rotate(360deg);
|
||||||
|
-o-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<div class="page-loading-wrap">
|
||||||
|
<div style="color: #4e9ff5" class="la-timer">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<h4 style="margin-top:20px;font-size:14px;font-weight:400;color: #515a6e;">正在加载资源...</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
242
web-front/src/App.vue
Normal file
242
web-front/src/App.vue
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-card class="box-card">
|
||||||
|
<div class="demo-basic--circle">
|
||||||
|
<div class="block" style="text-align: center;">
|
||||||
|
<el-avatar :size="150" :src="avatar"></el-avatar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 style="text-align: center;">NFD网盘直链解析(API演示)</h3>
|
||||||
|
<div class="typo">
|
||||||
|
<p><strong>项目GitHub </strong><a href="https://github.com/qaiu/netdisk-fast-download" target="_blank"
|
||||||
|
rel="nofollow"><u>netdisk-fast-download</u></a></p>
|
||||||
|
<p><strong>当前页面修改自开源项目</strong><a href="https://github.com/HurryBy/CloudDiskAnalysis" target="_blank"
|
||||||
|
rel="nofollow"><u>CloudDiskAnalysis</u></a></p>
|
||||||
|
<p><strong>目前支持 </strong>已支持蓝奏云/奶牛快传/移动云云空间/UC网盘(暂时失效)/小飞机盘/亿方云/123云盘</p>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="main" v-loading="isLoading">
|
||||||
|
<div class="grid-content">
|
||||||
|
<el-input placeholder="请粘贴分享链接" v-model="link" id="url" lass="input-with-select">
|
||||||
|
<strong slot="prepend">分享链接</strong>
|
||||||
|
<el-button slot="append" @click="onSubmit">解析</el-button>
|
||||||
|
</el-input>
|
||||||
|
<el-input placeholder="请输入密码" v-model="password" id="url" lass="input-with-select"></el-input>
|
||||||
|
<el-input v-show="respData.data" placeholder="解析地址" :value="getLink2" id="url" lass="input-with-select">
|
||||||
|
<el-button slot="append" v-clipboard:copy="getLink2"
|
||||||
|
v-clipboard:success="onCopy"
|
||||||
|
v-clipboard:error="onError">点我复制</el-button>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<div v-show="respData.code" style="margin-top: 10px">
|
||||||
|
<strong>解析结果: </strong>
|
||||||
|
<json-viewer
|
||||||
|
:value="respData"
|
||||||
|
:expand-depth=5
|
||||||
|
copyable
|
||||||
|
boxed
|
||||||
|
sort
|
||||||
|
/>
|
||||||
|
<a :href="downUrl" v-show="downUrl">点击下载</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios'
|
||||||
|
/*
|
||||||
|
蓝奏云 (lz)
|
||||||
|
登录, 上传, 下载, 分享
|
||||||
|
直链解析
|
||||||
|
奶牛快传 (cow)
|
||||||
|
登录, 上传, 下载, 分享
|
||||||
|
直链解析
|
||||||
|
移动云空间 (ec)
|
||||||
|
登录, 上传, 下载, 分享
|
||||||
|
直链解析
|
||||||
|
UC网盘 (uc)似乎已经失效,需要登录
|
||||||
|
登录, 上传, 下载, 分享
|
||||||
|
直链解析
|
||||||
|
小飞机网盘 (fj)
|
||||||
|
登录, 上传, 下载, 分享
|
||||||
|
直链解析
|
||||||
|
亿方云 (fc)
|
||||||
|
登录, 上传, 下载, 分享
|
||||||
|
直链解析
|
||||||
|
123云盘 (ye)
|
||||||
|
登录, 上传, 下载,, 分享
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
link: "",
|
||||||
|
password: "",
|
||||||
|
isLoading: false,
|
||||||
|
downUrl: null,
|
||||||
|
avatar: "https://q2.qlogo.cn/headimg_dl?dst_uin=736226400&spec=640",
|
||||||
|
select: "lz",
|
||||||
|
respData: {},
|
||||||
|
panList: [
|
||||||
|
{
|
||||||
|
name: "蓝奏云",
|
||||||
|
value: 'lz'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "奶牛快传",
|
||||||
|
value: 'cow'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "移动云空间",
|
||||||
|
value: 'ec'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "UC网盘",
|
||||||
|
value: 'uc',
|
||||||
|
disabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "小飞机网盘",
|
||||||
|
value: 'fj'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "360亿方云",
|
||||||
|
value: 'fc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "123云盘",
|
||||||
|
value: 'ye'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
getLink: '',
|
||||||
|
getLink2: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onSubmit() {
|
||||||
|
if (!this.link.startsWith("https://")) {
|
||||||
|
this.$message.error("请输入有效链接!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.isLoading = true
|
||||||
|
this.downUrl = ''
|
||||||
|
this.respData = {}
|
||||||
|
this.getLink2 = `${location.protocol}//${location.host}/parser?url=${this.link}`
|
||||||
|
// this.getLink = `${location.protocol}//${location.host}/api/json/parser?url=${this.link}`
|
||||||
|
this.getLink = `${location.protocol}//${location.host}/json/parser?url=${this.link}`
|
||||||
|
if (this.password) {
|
||||||
|
this.getLink += `&pwd=${this.password}`
|
||||||
|
}
|
||||||
|
axios.get(this.getLink).then(
|
||||||
|
response => {
|
||||||
|
this.isLoading = false
|
||||||
|
this.respData = response.data
|
||||||
|
if (response.data.code === 200) {
|
||||||
|
this.$message({
|
||||||
|
message: response.data.msg,
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
this.downUrl = response.data.data
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.data.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.isLoading = false
|
||||||
|
this.$message.error(error.message)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onCopy(){
|
||||||
|
this.$message.success('复制成功')
|
||||||
|
},
|
||||||
|
onError(){
|
||||||
|
this.$message.error('复制失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin: auto;
|
||||||
|
padding: 1em;
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: rgba(0, 149, 255, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
body:before {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
opacity: .3;
|
||||||
|
z-index: -1;
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-content {
|
||||||
|
margin-top: 1em;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select .el-input {
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-with-select .el-input-group__prepend {
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-card {
|
||||||
|
margin-top: 4em !important;
|
||||||
|
margin-bottom: 4em !important;
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px) {
|
||||||
|
.box-card {
|
||||||
|
margin-top: 1em !important;
|
||||||
|
margin-bottom: 1em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.download h3 {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download button {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typo {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typo a {
|
||||||
|
color: #2c3e50;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: 10px;
|
||||||
|
margin-bottom: .8em;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
19
web-front/src/main.js
Normal file
19
web-front/src/main.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import ElementUI from 'element-ui'
|
||||||
|
import 'element-ui/lib/theme-chalk/index.css'
|
||||||
|
import VueClipboard from 'vue-clipboard2'
|
||||||
|
import JsonViewer from 'vue-json-viewer'
|
||||||
|
|
||||||
|
// Import JsonViewer as a Vue.js plugin
|
||||||
|
Vue.use(JsonViewer)
|
||||||
|
|
||||||
|
// or
|
||||||
|
// components: {JsonViewer}
|
||||||
|
|
||||||
|
Vue.use(VueClipboard)
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
Vue.use(ElementUI)
|
||||||
|
new Vue({
|
||||||
|
render: h => h(App),
|
||||||
|
}).$mount('#app')
|
||||||
57
web-front/vue.config.js
Normal file
57
web-front/vue.config.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
function resolve(dir) {
|
||||||
|
return path.join(__dirname, dir)
|
||||||
|
}
|
||||||
|
const CompressionPlugin = require('compression-webpack-plugin');
|
||||||
|
const FileManagerPlugin = require('filemanager-webpack-plugin')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
transpileDependencies: true,
|
||||||
|
lintOnSave: false,
|
||||||
|
outputDir: 'nfd-front',
|
||||||
|
devServer: {
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: 6444,
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://127.0.0.1:6400', // 请求本地
|
||||||
|
changeOrigin: true,
|
||||||
|
pathRewrite: {
|
||||||
|
'^/api': '/' //本身的接口地址没有 '/api' 这种通用前缀,所以要rewrite,如果本身有则去掉
|
||||||
|
},
|
||||||
|
ws: true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
configureWebpack: {
|
||||||
|
// provide the app's title in webpack's name field, so that
|
||||||
|
// it can be accessed in index.html to inject the correct title.
|
||||||
|
name: 'Netdisk fast download',
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': resolve('src')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
new CompressionPlugin({
|
||||||
|
test: /\.js$|\.html$|\.css/, // 匹配文件
|
||||||
|
threshold: 10240 // 对超过10k文件压缩
|
||||||
|
}),
|
||||||
|
new FileManagerPlugin({ //初始化 filemanager-webpack-plugin 插件实例
|
||||||
|
onEnd: {
|
||||||
|
mkdir: ['./nfd-front'],
|
||||||
|
delete: [ //首先需要删除项目根目录下的dist.zip
|
||||||
|
'./nfd-front.zip',
|
||||||
|
],
|
||||||
|
archive: [ //然后我们选择dist文件夹将之打包成dist.zip并放在根目录
|
||||||
|
{source: './nfd-front', destination: './nfd-front.zip'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
@@ -60,7 +60,12 @@
|
|||||||
<artifactId>core-database</artifactId>
|
<artifactId>core-database</artifactId>
|
||||||
<version>0.1.6</version>
|
<version>0.1.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.openjdk.nashorn/nashorn-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.nashorn</groupId>
|
||||||
|
<artifactId>nashorn-core</artifactId>
|
||||||
|
<version>15.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,10 @@ package cn.qaiu.lz.common.interceptorImpl;
|
|||||||
|
|
||||||
import cn.qaiu.vx.core.base.BaseHttpApi;
|
import cn.qaiu.vx.core.base.BaseHttpApi;
|
||||||
import cn.qaiu.vx.core.interceptor.Interceptor;
|
import cn.qaiu.vx.core.interceptor.Interceptor;
|
||||||
import cn.qaiu.vx.core.model.JsonResult;
|
|
||||||
import cn.qaiu.vx.core.util.CommonUtil;
|
|
||||||
import cn.qaiu.vx.core.util.SharedDataUtil;
|
import cn.qaiu.vx.core.util.SharedDataUtil;
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
|
||||||
import io.vertx.core.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.shareddata.LocalMap;
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import lombok.val;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认拦截器实现
|
* 默认拦截器实现
|
||||||
@@ -23,7 +18,12 @@ public class DefaultInterceptor implements Interceptor, BaseHttpApi {
|
|||||||
private final JsonArray ignores = SharedDataUtil.getJsonArrayForCustomConfig("ignoresReg");
|
private final JsonArray ignores = SharedDataUtil.getJsonArrayForCustomConfig("ignoresReg");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(RoutingContext ctx) {
|
public void beforeHandle(RoutingContext ctx) {
|
||||||
ctx.next();
|
ctx.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterHandle(RoutingContext context) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,42 +4,42 @@ import cn.qaiu.lz.common.parser.impl.*;
|
|||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
|
|
||||||
public interface IPanTool {
|
public interface IPanTool {
|
||||||
Future<String> parse(String data, String code);
|
Future<String> parse();
|
||||||
|
|
||||||
static IPanTool typeMatching(String type) {
|
static IPanTool typeMatching(String type, String key, String pwd) {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case "lz" -> new LzTool();
|
case "lz" -> new LzTool(key, pwd);
|
||||||
case "cow" -> new CowTool();
|
case "cow" -> new CowTool(key, pwd);
|
||||||
case "ec" -> new EcTool();
|
case "ec" -> new EcTool(key, pwd);
|
||||||
case "fc" -> new FcTool();
|
case "fc" -> new FcTool(key, pwd);
|
||||||
case "uc" -> new UcTool();
|
case "uc" -> new UcTool(key, pwd);
|
||||||
case "ye" -> new YeTool();
|
case "ye" -> new YeTool(key, pwd);
|
||||||
case "fj" -> new FjTool();
|
case "fj" -> new FjTool(key, pwd);
|
||||||
default -> {
|
default -> {
|
||||||
throw new IllegalArgumentException("未知分享类型");
|
throw new UnsupportedOperationException("未知分享类型");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPanTool shareURLPrefixMatching(String url) {
|
static IPanTool shareURLPrefixMatching(String url, String pwd) {
|
||||||
|
|
||||||
if (url.startsWith(CowTool.SHARE_URL_PREFIX)) {
|
if (url.startsWith(CowTool.SHARE_URL_PREFIX)) {
|
||||||
return new CowTool();
|
return new CowTool(url, pwd);
|
||||||
} else if (url.startsWith(EcTool.SHARE_URL_PREFIX)) {
|
} else if (url.startsWith(EcTool.SHARE_URL_PREFIX)) {
|
||||||
return new EcTool();
|
return new EcTool(url, pwd);
|
||||||
} else if (url.startsWith(FcTool.SHARE_URL_PREFIX)) {
|
} else if (url.startsWith(FcTool.SHARE_URL_PREFIX0)) {
|
||||||
return new FcTool();
|
return new FcTool(url, pwd);
|
||||||
} else if (url.startsWith(UcTool.SHARE_URL_PREFIX)) {
|
} else if (url.startsWith(UcTool.SHARE_URL_PREFIX)) {
|
||||||
return new UcTool();
|
return new UcTool(url, pwd);
|
||||||
} else if (url.startsWith(YeTool.SHARE_URL_PREFIX)) {
|
} else if (url.startsWith(YeTool.SHARE_URL_PREFIX)) {
|
||||||
return new YeTool();
|
return new YeTool(url, pwd);
|
||||||
} else if (url.startsWith(FjTool.SHARE_URL_PREFIX)) {
|
} else if (url.startsWith(FjTool.SHARE_URL_PREFIX)) {
|
||||||
return new FjTool();
|
return new FjTool(url, pwd);
|
||||||
} else if (url.contains("lanzou")) {
|
} else if (url.contains("lanzou")) {
|
||||||
return new LzTool();
|
return new LzTool(url, pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("未知分享类型");
|
throw new UnsupportedOperationException("未知分享类型");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package cn.qaiu.lz.common.parser;
|
||||||
|
|
||||||
|
import cn.qaiu.vx.core.util.VertxHolder;
|
||||||
|
import io.vertx.core.Handler;
|
||||||
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.ext.web.client.WebClient;
|
||||||
|
import io.vertx.ext.web.client.WebClientOptions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public abstract class PanBase {
|
||||||
|
protected Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
protected Promise<String> promise = Promise.promise();
|
||||||
|
|
||||||
|
protected WebClient client = WebClient.create(VertxHolder.getVertxInstance());
|
||||||
|
protected WebClient clientNoRedirects = WebClient.create(VertxHolder.getVertxInstance(), OPTIONS);
|
||||||
|
private static final WebClientOptions OPTIONS = new WebClientOptions().setFollowRedirects(false);
|
||||||
|
|
||||||
|
|
||||||
|
protected String key;
|
||||||
|
protected String pwd;
|
||||||
|
|
||||||
|
protected PanBase(String key, String pwd) {
|
||||||
|
this.key = key;
|
||||||
|
this.pwd = pwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fail(Throwable t, String errorMsg, Object... args) {
|
||||||
|
try {
|
||||||
|
String s = String.format(errorMsg.replaceAll("\\{}", "%s"), args);
|
||||||
|
log.error("解析异常: " + s, t.fillInStackTrace());
|
||||||
|
promise.fail(this.getClass().getSimpleName() + ": 解析异常: " + s + " -> " + t);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("ErrorMsg format fail. The parameter has been discarded", e);
|
||||||
|
log.error("解析异常: " + errorMsg, t.fillInStackTrace());
|
||||||
|
promise.fail(this.getClass().getSimpleName() + ": 解析异常: " + errorMsg + " -> " + t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fail(String errorMsg, Object... args) {
|
||||||
|
try {
|
||||||
|
String s = String.format(errorMsg.replaceAll("\\{}", "%s"), args);
|
||||||
|
log.error("解析异常: " + s);
|
||||||
|
promise.fail(this.getClass().getSimpleName() + " - 解析异常: " + s);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("ErrorMsg format fail. The parameter has been discarded", e);
|
||||||
|
log.error("解析异常: " + errorMsg);
|
||||||
|
promise.fail(this.getClass().getSimpleName() + " - 解析异常: " + errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Handler<Throwable> handleFail(String errorMsg) {
|
||||||
|
return t -> fail(this.getClass().getSimpleName() + " - 请求异常 {}: -> {}", errorMsg, t.fillInStackTrace());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.lz.common.util.CommonUtils;
|
import cn.qaiu.lz.common.util.CommonUtils;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
|
||||||
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.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,17 +13,19 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
* @author <a href="https://qaiu.top">QAIU</a>
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
* @date 2023/4/21 21:19
|
* @date 2023/4/21 21:19
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
public class CowTool extends PanBase implements IPanTool {
|
||||||
public class CowTool 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 SHARE_URL_PREFIX = "https://cowtransfer.com/s/";
|
||||||
|
|
||||||
public Future<String> parse(String data, String code) {
|
public CowTool(String key, String pwd) {
|
||||||
Promise<String> promise = Promise.promise();
|
super(key, pwd);
|
||||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance());
|
}
|
||||||
String key = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
|
||||||
client.getAbs(API_REQUEST_URL + "?uniqueUrl=" + key).send().onSuccess(res -> {
|
public Future<String> parse() {
|
||||||
|
key = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
||||||
|
String url = API_REQUEST_URL + "?uniqueUrl=" + key;
|
||||||
|
client.getAbs(url).send().onSuccess(res -> {
|
||||||
JsonObject resJson = res.bodyAsJsonObject();
|
JsonObject resJson = res.bodyAsJsonObject();
|
||||||
if ("success".equals(resJson.getString("message")) && resJson.containsKey("data")) {
|
if ("success".equals(resJson.getString("message")) && resJson.containsKey("data")) {
|
||||||
JsonObject dataJson = resJson.getJsonObject("data");
|
JsonObject dataJson = resJson.getJsonObject("data");
|
||||||
@@ -44,19 +42,15 @@ public class CowTool implements IPanTool {
|
|||||||
promise.complete(downloadUrl);
|
promise.complete(downloadUrl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
fail("cow parse fail: {}; downloadUrl is empty", url2);
|
||||||
log.error("cow parse fail: {}; downloadUrl is empty", url2);
|
|
||||||
promise.fail("cow parse fail: " + url2 + "; downloadUrl is empty");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.error("cow parse fail: {}; json: {}", url2, res2Json);
|
fail("cow parse fail: {}; json: {}", url2, res2Json);
|
||||||
promise.fail("cow parse fail: " + url2 + "; json:" + res2Json);
|
}).onFailure(handleFail(url2));
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.error("cow parse fail: {}; json: {}", key, resJson);
|
fail("cow parse fail: {}; json: {}", key, resJson);
|
||||||
promise.fail("cow parse fail: " + key + "; json:" + resJson);
|
}).onFailure(handleFail(url));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Cow", key, t)));
|
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.lz.common.util.CommonUtils;
|
import cn.qaiu.lz.common.util.CommonUtils;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
|
||||||
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.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
|
||||||
import io.vertx.uritemplate.UriTemplate;
|
import io.vertx.uritemplate.UriTemplate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 移动云空间解析
|
* 移动云空间解析
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
public class EcTool extends PanBase implements IPanTool {
|
||||||
public class EcTool implements IPanTool {
|
|
||||||
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?chainUrlTemplate=https:%2F%2Fwww.ecpan" +
|
".do?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}";
|
||||||
@@ -25,10 +20,12 @@ public class EcTool implements IPanTool {
|
|||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "www.ecpan.cn/";
|
public static final String SHARE_URL_PREFIX = "www.ecpan.cn/";
|
||||||
|
|
||||||
public Future<String> parse(String data, String code) {
|
public EcTool(String key, String pwd) {
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
super(key, pwd);
|
||||||
Promise<String> promise = Promise.promise();
|
}
|
||||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance());
|
|
||||||
|
public Future<String> parse() {
|
||||||
|
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
||||||
// 第一次请求 获取文件信息
|
// 第一次请求 获取文件信息
|
||||||
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("dataKey", dataKey).send().onSuccess(res -> {
|
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("dataKey", dataKey).send().onSuccess(res -> {
|
||||||
JsonObject jsonObject = res.bodyAsJsonObject();
|
JsonObject jsonObject = res.bodyAsJsonObject();
|
||||||
@@ -37,8 +34,7 @@ public class EcTool implements IPanTool {
|
|||||||
.getJsonObject("var")
|
.getJsonObject("var")
|
||||||
.getJsonObject("chainFileInfo");
|
.getJsonObject("chainFileInfo");
|
||||||
if (fileInfo.containsKey("errMesg")) {
|
if (fileInfo.containsKey("errMesg")) {
|
||||||
promise.fail(new RuntimeException(DOWNLOAD_REQUEST_URL + " 解析失败: "
|
fail("{} 解析失败:{} key = {}", FIRST_REQUEST_URL, fileInfo.getString("errMesg"), dataKey);
|
||||||
+ fileInfo.getString("errMesg")) + " key = " + dataKey);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JsonObject cloudpFile = fileInfo.getJsonObject("cloudpFile");
|
JsonObject cloudpFile = fileInfo.getJsonObject("cloudpFile");
|
||||||
@@ -55,9 +51,9 @@ public class EcTool implements IPanTool {
|
|||||||
JsonObject jsonRes = res2.bodyAsJsonObject();
|
JsonObject jsonRes = res2.bodyAsJsonObject();
|
||||||
log.debug("ecPan get download url -> {}", res2.body().toString());
|
log.debug("ecPan get download url -> {}", res2.body().toString());
|
||||||
promise.complete(jsonRes.getJsonObject("var").getString("downloadUrl"));
|
promise.complete(jsonRes.getJsonObject("var").getString("downloadUrl"));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ec", dataKey, t)));
|
}).onFailure(handleFail(""));
|
||||||
}
|
}
|
||||||
).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ec", dataKey, t)));;
|
).onFailure(handleFail(FIRST_REQUEST_URL));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.lz.common.util.CommonUtils;
|
import cn.qaiu.lz.common.util.CommonUtils;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
|
||||||
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;
|
||||||
import io.vertx.core.Vertx;
|
|
||||||
import io.vertx.core.buffer.Buffer;
|
import io.vertx.core.buffer.Buffer;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.HttpResponse;
|
import io.vertx.ext.web.client.HttpResponse;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
|
||||||
import io.vertx.ext.web.client.WebClientOptions;
|
|
||||||
import io.vertx.ext.web.client.WebClientSession;
|
import io.vertx.ext.web.client.WebClientSession;
|
||||||
import io.vertx.uritemplate.UriTemplate;
|
import io.vertx.uritemplate.UriTemplate;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -23,51 +19,52 @@ import java.util.regex.Pattern;
|
|||||||
/**
|
/**
|
||||||
* 360亿方云
|
* 360亿方云
|
||||||
*/
|
*/
|
||||||
public class FcTool 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 Future<String> parse(String data, String code) {
|
public FcTool(String key, String pwd) {
|
||||||
|
super(key, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<String> parse() {
|
||||||
|
String data = key.replace("share","sharing");
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
||||||
|
|
||||||
Promise<String> promise = Promise.promise();
|
|
||||||
|
|
||||||
Vertx vertx = VertxHolder.getVertxInstance();
|
|
||||||
WebClient client = WebClient.create(vertx);
|
|
||||||
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 -> {
|
||||||
|
|
||||||
// 判断是否是加密分享
|
// 判断是否是加密分享
|
||||||
if (StringUtils.isNotEmpty(code)) {
|
if (StringUtils.isNotEmpty(pwd)) {
|
||||||
// 获取requesttoken
|
// 获取requesttoken
|
||||||
String html = res.bodyAsString();
|
String html = res.bodyAsString();
|
||||||
Pattern compile = Pattern.compile("name=\"requesttoken\"\\s+value=\"([a-zA-Z0-9_+=]+)\"");
|
Pattern compile = Pattern.compile("name=\"requesttoken\"\\s+value=\"([a-zA-Z0-9_+=]+)\"");
|
||||||
Matcher matcher = compile.matcher(html);
|
Matcher matcher = compile.matcher(html);
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
promise.fail(SHARE_URL_PREFIX + " 未匹配到加密分享的密码输入页面的requesttoken: \n" + html);
|
fail(SHARE_URL_PREFIX + " 未匹配到加密分享的密码输入页面的requesttoken");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String token = matcher.group(1);
|
String token = matcher.group(1);
|
||||||
|
|
||||||
sClient.postAbs(SHARE_URL_PREFIX2 + dataKey).sendForm(MultiMap.caseInsensitiveMultiMap()
|
sClient.postAbs(SHARE_URL_PREFIX2 + dataKey).sendForm(MultiMap.caseInsensitiveMultiMap()
|
||||||
.set("requesttoken", token)
|
.set("requesttoken", token)
|
||||||
.set("password", code)).onSuccess(res2 -> {
|
.set("password", pwd)).onSuccess(res2 -> {
|
||||||
if (res2.statusCode() == 302) {
|
if (res2.statusCode() == 302) {
|
||||||
sClient.getAbs(res2.getHeader("Location")).send().onSuccess(res3 ->
|
sClient.getAbs(res2.getHeader("Location")).send()
|
||||||
getDownURL(dataKey, promise, res3, sClient))
|
.onSuccess(res3 -> getDownURL(dataKey, promise, res3, sClient))
|
||||||
.onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
|
.onFailure(handleFail(res2.getHeader("Location")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
promise.fail(SHARE_URL_PREFIX + " 密码跳转后获取重定向失败 \n" + html);
|
fail(SHARE_URL_PREFIX + " 密码跳转后获取重定向失败");
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
|
}).onFailure(handleFail(SHARE_URL_PREFIX2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getDownURL(dataKey, promise, res, sClient);
|
getDownURL(dataKey, promise, res, sClient);
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
|
}).onFailure(handleFail(SHARE_URL_PREFIX + dataKey));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,14 +75,12 @@ public class FcTool implements IPanTool {
|
|||||||
Pattern compile = Pattern.compile("id=\"typed_id\"\\s+value=\"file_(\\d+)\"");
|
Pattern compile = Pattern.compile("id=\"typed_id\"\\s+value=\"file_(\\d+)\"");
|
||||||
Matcher matcher = compile.matcher(html);
|
Matcher matcher = compile.matcher(html);
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
promise.fail(SHARE_URL_PREFIX + " 未匹配到文件id(typed_id): \n" + html);
|
fail(SHARE_URL_PREFIX + " 未匹配到文件id(typed_id)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String fid = matcher.group(1);
|
String fid = matcher.group(1);
|
||||||
|
|
||||||
// 创建一个不自动重定向的WebClientSession
|
// 创建一个不自动重定向的WebClientSession
|
||||||
WebClient clientNoRedirects = WebClient.create(VertxHolder.getVertxInstance(),
|
|
||||||
new WebClientOptions().setFollowRedirects(false));
|
|
||||||
WebClientSession sClientNoRedirects = WebClientSession.create(clientNoRedirects, sClient.cookieStore());
|
WebClientSession sClientNoRedirects = WebClientSession.create(clientNoRedirects, sClient.cookieStore());
|
||||||
// 第二次请求
|
// 第二次请求
|
||||||
sClientNoRedirects.getAbs(UriTemplate.of(DOWN_REQUEST_URL))
|
sClientNoRedirects.getAbs(UriTemplate.of(DOWN_REQUEST_URL))
|
||||||
@@ -95,14 +90,14 @@ public class FcTool implements IPanTool {
|
|||||||
try {
|
try {
|
||||||
resJson = res2.bodyAsJsonObject();
|
resJson = res2.bodyAsJsonObject();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
promise.fail(DOWN_REQUEST_URL + " 第二次请求没有返回JSON, 可能下载受限: " + res2.bodyAsString());
|
fail(e, DOWN_REQUEST_URL + " 第二次请求没有返回JSON, 可能下载受限");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!resJson.getBoolean("success")) {
|
if (!resJson.getBoolean("success")) {
|
||||||
promise.fail(DOWN_REQUEST_URL + " 第二次请求未得到正确相应: " + resJson);
|
fail(DOWN_REQUEST_URL + " 第二次请求未得到正确相应: " + resJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
promise.complete(resJson.getString("download_url"));
|
promise.complete(resJson.getString("download_url"));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fc", dataKey, t)));
|
}).onFailure(handleFail(DOWN_REQUEST_URL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.lz.common.util.AESUtils;
|
import cn.qaiu.lz.common.util.AESUtils;
|
||||||
import cn.qaiu.lz.common.util.CommonUtils;
|
import cn.qaiu.lz.common.util.CommonUtils;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
import cn.qaiu.vx.core.util.VertxHolder;
|
||||||
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.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
import io.vertx.ext.web.client.WebClient;
|
||||||
import io.vertx.ext.web.client.WebClientOptions;
|
import io.vertx.ext.web.client.WebClientOptions;
|
||||||
@@ -20,7 +19,7 @@ import java.util.UUID;
|
|||||||
*
|
*
|
||||||
* @version V016_230609
|
* @version V016_230609
|
||||||
*/
|
*/
|
||||||
public class FjTool 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 SHARE_URL_PREFIX = "https://www.feijix.com/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/";
|
||||||
@@ -31,10 +30,13 @@ public class FjTool 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 Future<String> parse(String data, String code) {
|
public FjTool(String key, String pwd) {
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
super(key, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<String> parse() {
|
||||||
|
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
||||||
|
|
||||||
Promise<String> promise = Promise.promise();
|
|
||||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance(),
|
WebClient client = WebClient.create(VertxHolder.getVertxInstance(),
|
||||||
new WebClientOptions().setFollowRedirects(false));
|
new WebClientOptions().setFollowRedirects(false));
|
||||||
String shareId = String.valueOf(AESUtils.idEncrypt(dataKey));
|
String shareId = String.valueOf(AESUtils.idEncrypt(dataKey));
|
||||||
@@ -44,11 +46,11 @@ public class FjTool implements IPanTool {
|
|||||||
client.postAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("shareId", shareId).send().onSuccess(res -> {
|
client.postAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("shareId", shareId).send().onSuccess(res -> {
|
||||||
JsonObject resJson = res.bodyAsJsonObject();
|
JsonObject resJson = res.bodyAsJsonObject();
|
||||||
if (resJson.getInteger("code") != 200) {
|
if (resJson.getInteger("code") != 200) {
|
||||||
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (resJson.getJsonArray("list").size() == 0) {
|
if (resJson.getJsonArray("list").size() == 0) {
|
||||||
promise.fail(FIRST_REQUEST_URL + " 解析文件列表为空: " + resJson);
|
fail(FIRST_REQUEST_URL + " 解析文件列表为空: " + resJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 文件Id
|
// 文件Id
|
||||||
@@ -67,12 +69,12 @@ public class FjTool implements IPanTool {
|
|||||||
.setTemplateParam("auth", auth).send().onSuccess(res2 -> {
|
.setTemplateParam("auth", auth).send().onSuccess(res2 -> {
|
||||||
MultiMap headers = res2.headers();
|
MultiMap headers = res2.headers();
|
||||||
if (!headers.contains("Location")) {
|
if (!headers.contains("Location")) {
|
||||||
promise.fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + res.headers());
|
fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + res.headers());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
promise.complete(headers.get("Location"));
|
promise.complete(headers.get("Location"));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fj", dataKey, t)));
|
}).onFailure(handleFail(SECOND_REQUEST_URL));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Fj", dataKey, t)));
|
}).onFailure(handleFail(FIRST_REQUEST_URL));
|
||||||
|
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
import cn.qaiu.vx.core.util.VertxHolder;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.MultiMap;
|
import io.vertx.core.MultiMap;
|
||||||
@@ -19,17 +19,20 @@ import java.util.regex.Pattern;
|
|||||||
* @author QAIU
|
* @author QAIU
|
||||||
* @version 1.0 update 2021/5/16 10:39
|
* @version 1.0 update 2021/5/16 10:39
|
||||||
*/
|
*/
|
||||||
public class LzTool implements IPanTool {
|
public class LzTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://wwwa.lanzoui.com";
|
public static final String SHARE_URL_PREFIX = "https://wwwa.lanzoui.com";
|
||||||
|
|
||||||
public Future<String> parse(String data, String code) {
|
public LzTool(String key, String pwd) {
|
||||||
Promise<String> promise = Promise.promise();
|
super(key, pwd);
|
||||||
String key = data.indexOf('/') > 0 ? data : SHARE_URL_PREFIX + "/" + data;
|
}
|
||||||
|
|
||||||
|
public Future<String> parse() {
|
||||||
|
String sUrl = key.startsWith("https://") ? key : SHARE_URL_PREFIX + "/" + key;
|
||||||
|
|
||||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance(),
|
WebClient client = WebClient.create(VertxHolder.getVertxInstance(),
|
||||||
new WebClientOptions().setFollowRedirects(false));
|
new WebClientOptions().setFollowRedirects(false));
|
||||||
client.getAbs(key).send().onSuccess(res -> {
|
client.getAbs(sUrl).send().onSuccess(res -> {
|
||||||
String html = res.bodyAsString();
|
String html = res.bodyAsString();
|
||||||
// 匹配iframe
|
// 匹配iframe
|
||||||
Pattern compile = Pattern.compile("src=\"(/fn\\?[a-zA-Z\\d_+/=]{16,})\"");
|
Pattern compile = Pattern.compile("src=\"(/fn\\?[a-zA-Z\\d_+/=]{16,})\"");
|
||||||
@@ -39,11 +42,11 @@ public class LzTool implements IPanTool {
|
|||||||
Pattern compile2 = Pattern.compile("sign=(\\w{16,})");
|
Pattern compile2 = Pattern.compile("sign=(\\w{16,})");
|
||||||
Matcher matcher2 = compile2.matcher(html);
|
Matcher matcher2 = compile2.matcher(html);
|
||||||
if (!matcher2.find()) {
|
if (!matcher2.find()) {
|
||||||
promise.fail(key + ": sign正则匹配失败, 可能分享已失效: " + html);
|
fail(sUrl + ": sign正则匹配失败, 可能分享已失效");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String sign = matcher2.group(1);
|
String sign = matcher2.group(1);
|
||||||
getDownURL(promise, code, key, client, sign);
|
getDownURL(promise, sUrl, client, sign);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String iframePath = matcher.group(1);
|
String iframePath = matcher.group(1);
|
||||||
@@ -52,17 +55,17 @@ public class LzTool implements IPanTool {
|
|||||||
System.out.println(html);
|
System.out.println(html);
|
||||||
Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'(\\w+)'").matcher(html2);
|
Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'(\\w+)'").matcher(html2);
|
||||||
if (!matcher2.find()) {
|
if (!matcher2.find()) {
|
||||||
promise.fail(SHARE_URL_PREFIX + iframePath + " -> " + key + ": sign正则匹配失败, 可能分享已失效: " + html2);
|
fail(SHARE_URL_PREFIX + iframePath + " -> " + sUrl + ": sign正则匹配失败, 可能分享已失效");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String sign = matcher2.group(1);
|
String sign = matcher2.group(1);
|
||||||
getDownURL(promise, code, key, client, sign);
|
getDownURL(promise, sUrl, client, sign);
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
|
}).onFailure(handleFail(SHARE_URL_PREFIX));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
|
}).onFailure(handleFail(sUrl));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDownURL(Promise<String> promise, String code, String key, WebClient client, String sign) {
|
private void getDownURL(Promise<String> promise, String key, WebClient client, String sign) {
|
||||||
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
|
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
|
||||||
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 " +
|
||||||
@@ -73,19 +76,20 @@ public class LzTool implements IPanTool {
|
|||||||
headers.set("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
headers.set("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||||
headers.set("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
headers.set("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
||||||
|
|
||||||
client.postAbs(SHARE_URL_PREFIX + "/ajaxm.php").putHeaders(headers).sendForm(MultiMap
|
String url = SHARE_URL_PREFIX + "/ajaxm.php";
|
||||||
|
client.postAbs(url).putHeaders(headers).sendForm(MultiMap
|
||||||
.caseInsensitiveMultiMap()
|
.caseInsensitiveMultiMap()
|
||||||
.set("action", "downprocess")
|
.set("action", "downprocess")
|
||||||
.set("sign", sign).set("p", code)).onSuccess(res2 -> {
|
.set("sign", sign).set("p", pwd)).onSuccess(res2 -> {
|
||||||
JsonObject urlJson = res2.bodyAsJsonObject();
|
JsonObject urlJson = res2.bodyAsJsonObject();
|
||||||
if (urlJson.getInteger("zt") != 1) {
|
if (urlJson.getInteger("zt") != 1) {
|
||||||
promise.fail(urlJson.getString("inf"));
|
fail(urlJson.getString("inf"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String downUrl = urlJson.getString("dom") + "/file/" + urlJson.getString("url");
|
String downUrl = urlJson.getString("dom") + "/file/" + urlJson.getString("url");
|
||||||
client.getAbs(downUrl).putHeaders(headers).send()
|
client.getAbs(downUrl).putHeaders(headers).send()
|
||||||
.onSuccess(res3 -> promise.complete(res3.headers().get("Location")))
|
.onSuccess(res3 -> promise.complete(res3.headers().get("Location")))
|
||||||
.onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
|
.onFailure(handleFail(downUrl));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Lz", key, t)));
|
}).onFailure(handleFail(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import io.vertx.core.Future;
|
|||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
|
|
||||||
public class QkTool {
|
public class QkTool {
|
||||||
public static Future<String> parse(String data, String code) {
|
public static Future<String> parse() {
|
||||||
Promise<String> promise = Promise.promise();
|
Promise<String> promise = Promise.promise();
|
||||||
|
|
||||||
return promise.future();
|
return promise.future();
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.lz.common.util.CommonUtils;
|
import cn.qaiu.lz.common.util.CommonUtils;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
|
||||||
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.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
|
||||||
import io.vertx.uritemplate.UriTemplate;
|
import io.vertx.uritemplate.UriTemplate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UC网盘解析
|
* UC网盘解析
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
public class UcTool extends PanBase implements IPanTool {
|
||||||
public class UcTool implements IPanTool {
|
|
||||||
private static final String API_URL_PREFIX = "https://pc-api.uc.cn/1/clouddrive/";
|
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/";
|
public static final String SHARE_URL_PREFIX = "https://fast.uc.cn/s/";
|
||||||
@@ -29,11 +24,13 @@ public class UcTool implements IPanTool {
|
|||||||
|
|
||||||
private static final String THIRD_REQUEST_URL = API_URL_PREFIX + "file/download?entry=ft&fr=pc&pr=UCBrowser";
|
private static final String THIRD_REQUEST_URL = API_URL_PREFIX + "file/download?entry=ft&fr=pc&pr=UCBrowser";
|
||||||
|
|
||||||
public Future<String> parse(String data, String code) {
|
public UcTool(String key, String pwd) {
|
||||||
var dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
super(key, pwd);
|
||||||
var passcode = (code == null) ? "" : code;
|
}
|
||||||
Promise<String> promise = Promise.promise();
|
|
||||||
var client = WebClient.create(VertxHolder.getVertxInstance());
|
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);
|
var jsonObject = JsonObject.of("share_for_transfer", true);
|
||||||
jsonObject.put("pwd_id", dataKey);
|
jsonObject.put("pwd_id", dataKey);
|
||||||
jsonObject.put("passcode", passcode);
|
jsonObject.put("passcode", passcode);
|
||||||
@@ -42,7 +39,7 @@ public class UcTool implements IPanTool {
|
|||||||
log.debug("第一阶段 {}", res.body());
|
log.debug("第一阶段 {}", res.body());
|
||||||
var resJson = res.bodyAsJsonObject();
|
var resJson = res.bodyAsJsonObject();
|
||||||
if (resJson.getInteger("code") != 0) {
|
if (resJson.getInteger("code") != 0) {
|
||||||
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var stoken = resJson.getJsonObject("data").getString("stoken");
|
var stoken = resJson.getJsonObject("data").getString("stoken");
|
||||||
@@ -55,7 +52,7 @@ public class UcTool implements IPanTool {
|
|||||||
log.debug("第二阶段 {}", res2.body());
|
log.debug("第二阶段 {}", res2.body());
|
||||||
JsonObject resJson2 = res2.bodyAsJsonObject();
|
JsonObject resJson2 = res2.bodyAsJsonObject();
|
||||||
if (resJson2.getInteger("code") != 0) {
|
if (resJson2.getInteger("code") != 0) {
|
||||||
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
|
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 文件信息
|
// 文件信息
|
||||||
@@ -71,15 +68,15 @@ public class UcTool implements IPanTool {
|
|||||||
log.debug("第三阶段 {}", res3.body());
|
log.debug("第三阶段 {}", res3.body());
|
||||||
var resJson3 = res3.bodyAsJsonObject();
|
var resJson3 = res3.bodyAsJsonObject();
|
||||||
if (resJson3.getInteger("code") != 0) {
|
if (resJson3.getInteger("code") != 0) {
|
||||||
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
|
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
promise.complete(resJson3.getJsonArray("data").getJsonObject(0).getString("download_url"));
|
promise.complete(resJson3.getJsonArray("data").getJsonObject(0).getString("download_url"));
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Uc", dataKey, t)));
|
}).onFailure(handleFail(THIRD_REQUEST_URL));
|
||||||
|
|
||||||
}).onFailure(t -> promise.fail(new RuntimeException("解析异常: ", t.fillInStackTrace())));
|
}).onFailure(handleFail(SECOND_REQUEST_URL));
|
||||||
}
|
}
|
||||||
).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Uc", dataKey, t)));
|
).onFailure(handleFail(FIRST_REQUEST_URL));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
package cn.qaiu.lz.common.parser.impl;
|
package cn.qaiu.lz.common.parser.impl;
|
||||||
|
|
||||||
import cn.qaiu.lz.common.parser.IPanTool;
|
import cn.qaiu.lz.common.parser.IPanTool;
|
||||||
import cn.qaiu.lz.common.util.AESUtils;
|
import cn.qaiu.lz.common.parser.PanBase;
|
||||||
import cn.qaiu.lz.common.util.CommonUtils;
|
import cn.qaiu.lz.common.util.CommonUtils;
|
||||||
import cn.qaiu.lz.common.util.PanExceptionUtils;
|
import cn.qaiu.lz.common.util.JsExecUtils;
|
||||||
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.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
import io.vertx.ext.web.client.WebClient;
|
||||||
import io.vertx.uritemplate.UriTemplate;
|
import io.vertx.uritemplate.UriTemplate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openjdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
@@ -22,21 +20,23 @@ import java.util.regex.Pattern;
|
|||||||
/**
|
/**
|
||||||
* 123网盘
|
* 123网盘
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
public class YeTool extends PanBase implements IPanTool {
|
||||||
public class YeTool implements IPanTool {
|
|
||||||
public static final String SHARE_URL_PREFIX = "https://www.123pan.com/s/";
|
public static final String SHARE_URL_PREFIX = "https://www.123pan.com/s/";
|
||||||
public static final String FIRST_REQUEST_URL = SHARE_URL_PREFIX + "{key}.html";
|
public static final String FIRST_REQUEST_URL = SHARE_URL_PREFIX + "{key}.html";
|
||||||
|
|
||||||
private static final String GET_FILE_INFO_URL = "https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy" +
|
private static final String GET_FILE_INFO_URL = "https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy" +
|
||||||
"=file_name&orderDirection=asc&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event" +
|
"=file_name&orderDirection=asc" +
|
||||||
"=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/b/api/share/download/info?auth-key={authKey}";
|
public YeTool(String key, String pwd) {
|
||||||
|
super(key, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
public Future<String> parse(String data, String code) {
|
public Future<String> parse() {
|
||||||
|
|
||||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key);
|
||||||
Promise<String> promise = Promise.promise();
|
|
||||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance());
|
|
||||||
|
|
||||||
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 -> {
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public class YeTool implements IPanTool {
|
|||||||
Matcher matcher = compile.matcher(html);
|
Matcher matcher = compile.matcher(html);
|
||||||
|
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
promise.fail(html + "\n Ye: " + dataKey + " 正则匹配失败");
|
fail(html + "\n Ye: " + dataKey + " 正则匹配失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String fileInfoString = matcher.group(1);
|
String fileInfoString = matcher.group(1);
|
||||||
@@ -54,52 +54,80 @@ public class YeTool implements IPanTool {
|
|||||||
JsonObject resListJson = fileInfoJson.getJsonObject("reslist");
|
JsonObject resListJson = fileInfoJson.getJsonObject("reslist");
|
||||||
|
|
||||||
if (resJson == null || resJson.getInteger("code") != 0) {
|
if (resJson == null || resJson.getInteger("code") != 0) {
|
||||||
promise.fail(dataKey + " 解析到异常JSON: " + resJson);
|
fail(dataKey + " 解析到异常JSON: " + resJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String shareKey = resJson.getJsonObject("data").getString("ShareKey");
|
String shareKey = resJson.getJsonObject("data").getString("ShareKey");
|
||||||
if (resListJson == null || resListJson.getInteger("code") != 0) {
|
if (resListJson == null || resListJson.getInteger("code") != 0) {
|
||||||
// 加密分享
|
// 加密分享
|
||||||
if (StringUtils.isNotEmpty(code)) {
|
if (StringUtils.isNotEmpty(pwd)) {
|
||||||
client.getAbs(UriTemplate.of(GET_FILE_INFO_URL))
|
client.getAbs(UriTemplate.of(GET_FILE_INFO_URL))
|
||||||
.setTemplateParam("shareKey", shareKey)
|
.setTemplateParam("shareKey", shareKey)
|
||||||
.setTemplateParam("pwd", code)
|
.setTemplateParam("pwd", pwd)
|
||||||
|
// .setTemplateParam("authKey", AESUtils.getAuthKey("/a/api/share/get"))
|
||||||
|
.putHeader("Platform", "web")
|
||||||
|
.putHeader("App-Version", "3")
|
||||||
.send().onSuccess(res2 -> {
|
.send().onSuccess(res2 -> {
|
||||||
JsonObject infoJson = res2.bodyAsJsonObject();
|
JsonObject infoJson = res2.bodyAsJsonObject();
|
||||||
if (infoJson.getInteger("code") != 0) {
|
if (infoJson.getInteger("code") != 0) {
|
||||||
promise.fail("Ye: " + dataKey + " 状态码异常" + infoJson);
|
fail("{} 状态码异常 {}", dataKey, infoJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JsonObject getFileInfoJson =
|
JsonObject getFileInfoJson =
|
||||||
infoJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
|
infoJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
|
||||||
getFileInfoJson.put("ShareKey", shareKey);
|
getFileInfoJson.put("ShareKey", shareKey);
|
||||||
getDownUrl(promise, client, getFileInfoJson);
|
getDownUrl(client, getFileInfoJson);
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", dataKey, t)));
|
}).onFailure(this.handleFail(GET_FILE_INFO_URL));
|
||||||
} else {
|
} else {
|
||||||
promise.fail(dataKey + " 该分享需要密码");
|
fail("该分享[{}]需要密码",dataKey);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject reqBodyJson = resListJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
|
JsonObject reqBodyJson = resListJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
|
||||||
reqBodyJson.put("ShareKey", shareKey);
|
reqBodyJson.put("ShareKey", shareKey);
|
||||||
getDownUrl(promise, client, reqBodyJson);
|
getDownUrl(client, reqBodyJson);
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", dataKey, t)));
|
}).onFailure(this.handleFail(FIRST_REQUEST_URL));
|
||||||
|
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getDownUrl(Promise<String> promise, WebClient client, JsonObject reqBodyJson) {
|
private void getDownUrl(WebClient client, JsonObject reqBodyJson) {
|
||||||
log.info(reqBodyJson.encodePrettily());
|
log.info(reqBodyJson.encodePrettily());
|
||||||
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
// {"ShareKey":"iaKtVv-6OECd","FileID":2193732,"S3keyFlag":"1811834632-0","Size":4203111,
|
||||||
|
// "Etag":"69c94adbc0b9190cf23c4e958d8c7c53"}
|
||||||
|
jsonObject.put("ShareKey", reqBodyJson.getString("ShareKey"));
|
||||||
|
jsonObject.put("FileID", reqBodyJson.getInteger("FileId"));
|
||||||
|
jsonObject.put("S3keyFlag", reqBodyJson.getString("S3KeyFlag"));
|
||||||
|
jsonObject.put("Size", reqBodyJson.getInteger("Size"));
|
||||||
|
jsonObject.put("Etag", reqBodyJson.getString("Etag"));
|
||||||
|
|
||||||
|
// 调用JS文件获取签名
|
||||||
|
ScriptObjectMirror getSign;
|
||||||
|
try {
|
||||||
|
getSign = JsExecUtils.executeJs("getSign", "/a/api/share/download/info");
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(e, "JS函数执行异常");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info("ye getSign: {}={}", getSign.get("0").toString(), getSign.get("1").toString());
|
||||||
|
|
||||||
client.postAbs(UriTemplate.of(DOWNLOAD_API_URL))
|
client.postAbs(UriTemplate.of(DOWNLOAD_API_URL))
|
||||||
.setTemplateParam("authKey", AESUtils.getAuthKey())
|
.setTemplateParam("authK", getSign.get("0").toString())
|
||||||
|
.setTemplateParam("authV", getSign.get("1").toString())
|
||||||
.putHeader("Platform", "web")
|
.putHeader("Platform", "web")
|
||||||
.putHeader("App-Version", "3")
|
.putHeader("App-Version", "3")
|
||||||
.sendJsonObject(reqBodyJson).onSuccess(res2 -> {
|
.sendJsonObject(jsonObject).onSuccess(res2 -> {
|
||||||
JsonObject downURLJson = res2.bodyAsJsonObject();
|
JsonObject downURLJson = res2.bodyAsJsonObject();
|
||||||
|
|
||||||
if (downURLJson.getInteger("code") != 0) {
|
try {
|
||||||
promise.fail("Ye: downURLJson返回值异常->" + downURLJson);
|
if (downURLJson.getInteger("code") != 0) {
|
||||||
|
fail("Ye: downURLJson返回值异常->" + downURLJson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
fail("Ye: downURLJson格式异常->" + downURLJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String downURL = downURLJson.getJsonObject("data").getString("DownloadURL");
|
String downURL = downURLJson.getJsonObject("data").getString("DownloadURL");
|
||||||
@@ -112,18 +140,23 @@ public class YeTool implements IPanTool {
|
|||||||
// 获取直链
|
// 获取直链
|
||||||
client.getAbs(downUrl2).send().onSuccess(res3 -> {
|
client.getAbs(downUrl2).send().onSuccess(res3 -> {
|
||||||
JsonObject res3Json = res3.bodyAsJsonObject();
|
JsonObject res3Json = res3.bodyAsJsonObject();
|
||||||
if (res3Json.getInteger("code") != 0) {
|
try {
|
||||||
promise.fail("Ye: downUrl2返回值异常->" + res3Json);
|
if (res3Json.getInteger("code") != 0) {
|
||||||
|
fail("Ye: downUrl2返回值异常->" + res3Json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
fail("Ye: downUrl2格式异常->" + downURLJson);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.complete(res3Json.getJsonObject("data").getString("redirect_url"));
|
promise.complete(res3Json.getJsonObject("data").getString("redirect_url"));
|
||||||
|
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye",
|
}).onFailure(this.handleFail("获取直链失败"));
|
||||||
reqBodyJson.encodePrettily(), t)));
|
|
||||||
|
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
promise.fail("urlParams解析异常" + e.getMessage());
|
fail("urlParams解析异常" + e.getMessage());
|
||||||
}
|
}
|
||||||
}).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", reqBodyJson.encodePrettily(), t)));
|
}).onFailure(this.handleFail(DOWNLOAD_API_URL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,8 +274,7 @@ public class AESUtils {
|
|||||||
return new BigInteger(1, digest).toString(16);
|
return new BigInteger(1, digest).toString(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getAuthKey() {
|
public static String getAuthKey(String _0x2207af) {
|
||||||
String _0x2207af = "/b/api/share/download/info";
|
|
||||||
String _0x467baa = "web";
|
String _0x467baa = "web";
|
||||||
int _0x4965f1 = 3;
|
int _0x4965f1 = 3;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package cn.qaiu.lz.common.util;
|
||||||
|
|
||||||
|
import org.openjdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||||
|
|
||||||
|
import javax.script.Invocable;
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行Js脚本
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2023/7/29 17:35
|
||||||
|
*/
|
||||||
|
public class JsExecUtils {
|
||||||
|
private static final String JS_PATH = "/js/ye123.js";
|
||||||
|
private static Invocable inv;
|
||||||
|
|
||||||
|
// 初始化脚本引擎
|
||||||
|
static {
|
||||||
|
ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||||
|
ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎
|
||||||
|
//获取文件所在的相对路径
|
||||||
|
URL resource = JsExecUtils.class.getResource("/");
|
||||||
|
if (resource == null) {
|
||||||
|
throw new RuntimeException("js resource path is null");
|
||||||
|
}
|
||||||
|
String path = resource.getPath();
|
||||||
|
String reader = path + JS_PATH;
|
||||||
|
try (FileReader fReader = new FileReader(reader)){
|
||||||
|
engine.eval(fReader);
|
||||||
|
fReader.close();
|
||||||
|
inv = (Invocable) engine;
|
||||||
|
} catch (IOException | ScriptException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用js文件
|
||||||
|
*/
|
||||||
|
public static ScriptObjectMirror executeJs(String functionName, Object... args) throws ScriptException, NoSuchMethodException {
|
||||||
|
//调用js中的方法
|
||||||
|
return (ScriptObjectMirror) inv.invokeFunction(functionName, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ public class ServerApi {
|
|||||||
return userService.login(user);
|
return userService.login(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RouteMapping(value = "/parser", method = RouteMethod.GET)
|
@RouteMapping(value = "/parser", method = RouteMethod.GET, order = 4)
|
||||||
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
|
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
|
||||||
|
|
||||||
Promise<Void> promise = Promise.promise();
|
Promise<Void> promise = Promise.promise();
|
||||||
@@ -43,7 +43,7 @@ public class ServerApi {
|
|||||||
url = EcTool.SHARE_URL_PREFIX + request.getParam("data");
|
url = EcTool.SHARE_URL_PREFIX + request.getParam("data");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
IPanTool.shareURLPrefixMatching(url).parse(url, pwd).onSuccess(resUrl -> {
|
IPanTool.shareURLPrefixMatching(url, pwd).parse().onSuccess(resUrl -> {
|
||||||
response.putHeader("location", resUrl).setStatusCode(302).end();
|
response.putHeader("location", resUrl).setStatusCode(302).end();
|
||||||
promise.complete();
|
promise.complete();
|
||||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||||
@@ -53,8 +53,17 @@ public class ServerApi {
|
|||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RouteMapping(value = "/json/parser", method = RouteMethod.GET, order = 3)
|
||||||
|
public Future<String> parseJson(HttpServerRequest request, String url, String pwd) {
|
||||||
|
if (url.contains(EcTool.SHARE_URL_PREFIX)) {
|
||||||
|
// 默认读取Url参数会被截断手动获取一下其他参数
|
||||||
|
url = EcTool.SHARE_URL_PREFIX + request.getParam("data");
|
||||||
|
}
|
||||||
|
return IPanTool.shareURLPrefixMatching(url, pwd).parse();
|
||||||
|
}
|
||||||
|
|
||||||
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET)
|
|
||||||
|
@RouteMapping(value = "/:type/:key", method = RouteMethod.GET, order = 1)
|
||||||
public void parseKey(HttpServerResponse response, String type, String key) {
|
public void parseKey(HttpServerResponse response, String type, String key) {
|
||||||
String code = "";
|
String code = "";
|
||||||
if (key.contains("@")) {
|
if (key.contains("@")) {
|
||||||
@@ -63,21 +72,21 @@ public class ServerApi {
|
|||||||
code = keys[1];
|
code = keys[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
IPanTool.typeMatching(type).parse(key, code).onSuccess(resUrl -> response.putHeader("location", resUrl)
|
IPanTool.typeMatching(type, key, code).parse().onSuccess(resUrl -> response.putHeader("location", resUrl)
|
||||||
.setStatusCode(302).end()).onFailure(t -> {
|
.setStatusCode(302).end()).onFailure(t -> {
|
||||||
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
|
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
|
||||||
response.end(t.getMessage());
|
response.end(t.getMessage());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET)
|
@RouteMapping(value = "/json/:type/:key", method = RouteMethod.GET, order = 2)
|
||||||
public Future<String> parseKeyJson(HttpServerResponse response, String type, String key) {
|
public Future<String> parseKeyJson(String type, String key) {
|
||||||
String code = "";
|
String code = "";
|
||||||
if (key.contains("@")) {
|
if (key.contains("@")) {
|
||||||
String[] keys = key.split("@");
|
String[] keys = key.split("@");
|
||||||
key = keys[0];
|
key = keys[0];
|
||||||
code = keys[1];
|
code = keys[1];
|
||||||
}
|
}
|
||||||
return IPanTool.typeMatching(type).parse(key, code);
|
return IPanTool.typeMatching(type, key, code).parse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# 要激活的配置: dev--连接本地数据库; prod连接线上数据库
|
# 要激活的配置: dev--连接本地数据库; prod连接线上数据库
|
||||||
active: dev
|
active: dev
|
||||||
# 框架版本号 和主版本号
|
# 版本号
|
||||||
version_vertx: 4.4.1
|
|
||||||
version_app: 0.1.6
|
version_app: 0.1.6
|
||||||
# 公司名称 -> LOGO版权文字
|
# 公司名称 -> LOGO版权文字
|
||||||
copyright: QAIU
|
copyright: QAIU
|
||||||
|
|||||||
@@ -10,20 +10,44 @@ content-type: application/json
|
|||||||
{"pwd_id":"33197dd53ace4","passcode":"","share_for_transfer":true}
|
{"pwd_id":"33197dd53ace4","passcode":"","share_for_transfer":true}
|
||||||
|
|
||||||
### UCpan 第二步 获取fid,share_fid_token GET传参pwd_id,passcode,stoken
|
### UCpan 第二步 获取fid,share_fid_token GET传参pwd_id,passcode,stoken
|
||||||
https://pc-api.uc.cn/1/clouddrive/transfer_share/detail?pwd_id=33197dd53ace4&passcode=&stoken=oPz47hsgQXQdDYimsP4kBMi8aLv40X378IZOiBsnfLU%3D
|
https://pc-api.uc.cn/1/clouddrive/transfer_share/detail?pwd_id=33197dd53ace4&passcode=&stoken=4lXGIeQ6rdqjuOPW1MHJpqrQR3RWGFKSAAjpTibsR%2B8%3D
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
|
||||||
### UCpan 第二步获取下载链接 POST json传入fids(fid),pwd_id,stoken,fids_token(share_fid_token)
|
### UCpan 第二步获取下载链接 POST json传入fids(fid),pwd_id,stoken,fids_token(share_fid_token)
|
||||||
|
|
||||||
POST https://pc-api.uc.cn/1/clouddrive/file/download?entry=ft&fr=pc&pr=UCBrowser
|
POST https://pc-api.uc.cn/1/clouddrive/file/download?entry=ft&fr=pc&pr=UCBrowser
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
#Cookie: __pus=7576a6d3a511ad7b4c5649a1d89c29ffAAQ06zBxHWghrwEbKRdqBrhXssuYiMIwLLVzi1f2K6qnSL95A79GIxXDEPlYS3NaPjDWOcWVuvbQ3HqTfvqRKr29
|
||||||
|
|
||||||
{
|
{
|
||||||
"fids": [
|
"fids": [
|
||||||
"54c3cd90ed3e45119bb96ed99a562d40"
|
"54c3cd90ed3e45119bb96ed99a562d40"
|
||||||
],
|
],
|
||||||
"pwd_id": "33197dd53ace4",
|
"pwd_id": "33197dd53ace4",
|
||||||
"stoken": "oPz47hsgQXQdDYimsP4kBMi8aLv40X378IZOiBsnfLU=",
|
"stoken": "7P02U9tWJEkkMgbXaIJxAQyBiqcfPdkbDZ6XoiYsBiA=",
|
||||||
"fids_token": [
|
"fids_token": [
|
||||||
"ff9f5b5c94df9d08c8dd3b7948fc5e20"
|
"e8a52adcda41d9e218e732b5de549d2a"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
# @no-redirect
|
||||||
|
https://dl-uf-zb.pds.uc.cn/l3PNAKfz/64623447/646b0de6e9f13000c9b14ba182b805312795a82a/646b0de6717e1bfa5bb44dd2a456f103c5177850?Expires=1691488145&OSSAccessKeyId=LTAIyYfxTqY7YZsg&Signature=MvUiIWszmMncqDrsLV%2BlL1HpuYw%3D&x-oss-traffic-limit=503316480&response-content-disposition=attachment%3B%20filename%3DC%23%20Shell%20%28C%23%20Offline%20Compiler%29_2.5.16.apks&callback-var=eyJ4OmF1IjoiLSIsIng6c3AiOiIxOTkiLCJ4OnRva2VuIjoiMi1iYzBhNTgxNTUwOGE0NmQwYmE4YzUxYjAyZGEwNjA5Yi01LTctNjE0NDAtZGFjYjM2NjViYmFhNGY1ZTlkMzc4MDBlYzY0MDMxNjAtNGZhNTliY2RkNzhlYTE0MDg0Mjc5OGVlNDMxZWFlMDciLCJ4OnR0bCI6IjEwODAwIn0%3D&callback=eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrU3RhZ2UiOiJiZWZvcmUtZXhlY3V0ZSIsImNhbGxiYWNrRmFpbHVyZUFjdGlvbiI6Imlnbm9yZSIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9hdXRoLWNkbi51Yy5jbi9vdXRlci9vc3MvY2hlY2twbGF5IiwiY2FsbGJhY2tCb2R5Ijoie1wiaG9zdFwiOiR7aHR0cEhlYWRlci5ob3N0fSxcInNpemVcIjoke3NpemV9LFwicmFuZ2VcIjoke2h0dHBIZWFkZXIucmFuZ2V9LFwicmVmZXJlclwiOiR7aHR0cEhlYWRlci5yZWZlcmVyfSxcImNvb2tpZVwiOiR7aHR0cEhlYWRlci5jb29raWV9LFwibWV0aG9kXCI6JHtodHRwSGVhZGVyLm1ldGhvZH0sXCJpcFwiOiR7Y2xpZW50SXB9LFwicG9ydFwiOiR7Y2xpZW50UG9ydH0sXCJvYmplY3RcIjoke29iamVjdH0sXCJzcFwiOiR7eDpzcH0sXCJ0b2tlblwiOiR7eDp0b2tlbn0sXCJhdVwiOiR7eDphdX0sXCJ0dGxcIjoke3g6dHRsfSxcImNsaWVudF90b2tlblwiOiR7cXVlcnlTdHJpbmcuY2xpZW50X3Rva2VufX0ifQ%3D%3D&ud=4-N-5-0-6-N-3-ft-0-2
|
||||||
|
#Cookie: __pus=7576a6d3a511ad7b4c5649a1d89c29ffAAQ06zBxHWghrwEbKRdqBrhXssuYiMIwLLVzi1f2K6qnSL95A79GIxXDEPlYS3NaPjDWOcWVuvbQ3HqTfvqRKr29
|
||||||
|
|
||||||
|
###
|
||||||
|
https://dl-uf-zb.pds.uc.cn/l3PNAKfz/64623447/646b0de6e9f13000c9b14ba182b805312795a82a/646b0de6717e1bfa5bb44dd2a456f103c5177850?Expires=1691488387&OSSAccessKeyId=LTAIyYfxTqY7YZsg&Signature=WIy4UGCwd9eNdUnSexRVFUCFZcM%3D&x-oss-traffic-limit=503316480&response-content-disposition=attachment%3B%20filename%3DC%23%20Shell%20%28C%23%20Offline%20Compiler%29_2.5.16.apks&callback-var=eyJ4OmF1IjoiLSIsIng6c3AiOiIxOTkiLCJ4OnRva2VuIjoiMi0wNDBjYjFjMDNjNzU1YWY1NDc0NjkxNjNmOTYzYWY2NC0yLTctNjE0NDAtZGFjYjM2NjViYmFhNGY1ZTlkMzc4MDBlYzY0MDMxNjAtYTU2MGJiMmU1MzhlNzY0OTFkMDY1MjA2OGRiNmEzMzEiLCJ4OnR0bCI6IjEwODAwIn0%3D&callback=eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrU3RhZ2UiOiJiZWZvcmUtZXhlY3V0ZSIsImNhbGxiYWNrRmFpbHVyZUFjdGlvbiI6Imlnbm9yZSIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9hdXRoLWNkbi51Yy5jbi9vdXRlci9vc3MvY2hlY2twbGF5IiwiY2FsbGJhY2tCb2R5Ijoie1wiaG9zdFwiOiR7aHR0cEhlYWRlci5ob3N0fSxcInNpemVcIjoke3NpemV9LFwicmFuZ2VcIjoke2h0dHBIZWFkZXIucmFuZ2V9LFwicmVmZXJlclwiOiR7aHR0cEhlYWRlci5yZWZlcmVyfSxcImNvb2tpZVwiOiR7aHR0cEhlYWRlci5jb29raWV9LFwibWV0aG9kXCI6JHtodHRwSGVhZGVyLm1ldGhvZH0sXCJpcFwiOiR7Y2xpZW50SXB9LFwicG9ydFwiOiR7Y2xpZW50UG9ydH0sXCJvYmplY3RcIjoke29iamVjdH0sXCJzcFwiOiR7eDpzcH0sXCJ0b2tlblwiOiR7eDp0b2tlbn0sXCJhdVwiOiR7eDphdX0sXCJ0dGxcIjoke3g6dHRsfSxcImNsaWVudF90b2tlblwiOiR7cXVlcnlTdHJpbmcuY2xpZW50X3Rva2VufX0ifQ%3D%3D&ud=4-0-5-0-6-N-3-ft-0-2
|
||||||
|
|
||||||
|
###
|
||||||
|
#@no-cookie-jar
|
||||||
|
https://dl-uf-zb.pds.uc.cn/l3PNAKfz/64623447/646b0de6e9f13000c9b14ba182b805312795a82a/646b0de6717e1bfa5bb44dd2a456f103c5177850?Expires=1691488539&OSSAccessKeyId=LTAIyYfxTqY7YZsg&Signature=rhD0OQTq2CuMUvp0ZphStKiyyw8%3D&x-oss-traffic-limit=503316480&response-content-disposition=attachment%3B%20filename%3DC%23%20Shell%20%28C%23%20Offline%20Compiler%29_2.5.16.apks&callback-var=eyJ4OmF1IjoiLSIsIng6c3AiOiIxOTkiLCJ4OnRva2VuIjoiMi02YTU3OGNkNjYyMTQzZWI4ODFjZTE0ZGYyNjk5OTQ4OS01LTctNjE0NDAtZGFjYjM2NjViYmFhNGY1ZTlkMzc4MDBlYzY0MDMxNjAtYzlhYWI1YjA5ZDNhYTA5MWU4NTJjNTJlNGRjYWJkZDYiLCJ4OnR0bCI6IjEwODAwIn0%3D&callback=eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrU3RhZ2UiOiJiZWZvcmUtZXhlY3V0ZSIsImNhbGxiYWNrRmFpbHVyZUFjdGlvbiI6Imlnbm9yZSIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9hdXRoLWNkbi51Yy5jbi9vdXRlci9vc3MvY2hlY2twbGF5IiwiY2FsbGJhY2tCb2R5Ijoie1wiaG9zdFwiOiR7aHR0cEhlYWRlci5ob3N0fSxcInNpemVcIjoke3NpemV9LFwicmFuZ2VcIjoke2h0dHBIZWFkZXIucmFuZ2V9LFwicmVmZXJlclwiOiR7aHR0cEhlYWRlci5yZWZlcmVyfSxcImNvb2tpZVwiOiR7aHR0cEhlYWRlci5jb29raWV9LFwibWV0aG9kXCI6JHtodHRwSGVhZGVyLm1ldGhvZH0sXCJpcFwiOiR7Y2xpZW50SXB9LFwicG9ydFwiOiR7Y2xpZW50UG9ydH0sXCJvYmplY3RcIjoke29iamVjdH0sXCJzcFwiOiR7eDpzcH0sXCJ0b2tlblwiOiR7eDp0b2tlbn0sXCJhdVwiOiR7eDphdX0sXCJ0dGxcIjoke3g6dHRsfSxcImNsaWVudF90b2tlblwiOiR7cXVlcnlTdHJpbmcuY2xpZW50X3Rva2VufX0ifQ%3D%3D&ud=4-N-5-0-6-N-3-ft-0-2
|
||||||
|
Cookie: __pugs=efc5f3f9c041af5dc62eea4481901cbbAAT912628i+uT/WMwOFWBjJ1TjbKGC1j6cyGHSLVzwuPQP74d+rZXO4xJgdG93MC5DUDdgRJcg5y93waA/KPWDSeDY8LPgjB2Ha2tQ3sQ/MXMoRUi/LRdY3psAyC3YOlUDeFwLtkLAXABRgJhKTw6W0v
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
#@no-cookie-jar
|
||||||
|
|
||||||
|
https://dl-uf-zb.pds.uc.cn/l3PNAKfz/64623447/646b0de6e9f13000c9b14ba182b805312795a82a/646b0de6717e1bfa5bb44dd2a456f103c5177850?Expires=1691489999&OSSAccessKeyId=LTAIyYfxTqY7YZsg&Signature=NbQLAEUCkvJxmSsRoIynZ%2BuPMvY%3D&x-oss-traffic-limit=503316480&response-content-disposition=attachment%3B%20filename%3DC%23%20Shell%20%28C%23%20Offline%20Compiler%29_2.5.16.apks&callback-var=eyJ4OmF1IjoiLSIsIng6c3AiOiIxOTkiLCJ4OnRva2VuIjoiMi0wNDBjYjFjMDNjNzU1YWY1NDc0NjkxNjNmOTYzYWY2NC0yLTctNjE0NDAtZGFjYjM2NjViYmFhNGY1ZTlkMzc4MDBlYzY0MDMxNjAtYTU2MGJiMmU1MzhlNzY0OTFkMDY1MjA2OGRiNmEzMzEiLCJ4OnR0bCI6IjEwODAwIn0%3D&callback=eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrU3RhZ2UiOiJiZWZvcmUtZXhlY3V0ZSIsImNhbGxiYWNrRmFpbHVyZUFjdGlvbiI6Imlnbm9yZSIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9hdXRoLWNkbi51Yy5jbi9vdXRlci9vc3MvY2hlY2twbGF5IiwiY2FsbGJhY2tCb2R5Ijoie1wiaG9zdFwiOiR7aHR0cEhlYWRlci5ob3N0fSxcInNpemVcIjoke3NpemV9LFwicmFuZ2VcIjoke2h0dHBIZWFkZXIucmFuZ2V9LFwicmVmZXJlclwiOiR7aHR0cEhlYWRlci5yZWZlcmVyfSxcImNvb2tpZVwiOiR7aHR0cEhlYWRlci5jb29raWV9LFwibWV0aG9kXCI6JHtodHRwSGVhZGVyLm1ldGhvZH0sXCJpcFwiOiR7Y2xpZW50SXB9LFwicG9ydFwiOiR7Y2xpZW50UG9ydH0sXCJvYmplY3RcIjoke29iamVjdH0sXCJzcFwiOiR7eDpzcH0sXCJ0b2tlblwiOiR7eDp0b2tlbn0sXCJhdVwiOiR7eDphdX0sXCJ0dGxcIjoke3g6dHRsfSxcImNsaWVudF90b2tlblwiOiR7cXVlcnlTdHJpbmcuY2xpZW50X3Rva2VufX0ifQ%3D%3D&ud=4-0-5-0-6-N-3-ft-0-2
|
||||||
|
Cookie: __puus=dc48cb12577eb3df6fe84fdea250ad6fAAOF0LBv/M4HTtkYfuUNdcVLXHZl1x2mw8NQSdxo5abymS+irugphlPNv5kwQZkDI+pXaeOD22v/whNQT5AwUULF0q1nSNXmHqxr20AJjXlEhvbIZNgUfwmw8aOCyarrLi7o7w6w0Rod4DLCSeYGwlTF3P9jMcqCM+WqWHnxKY6i8gaXZkHLObatSHkwivB7Xpc=
|
||||||
|
Referer: https://fast.uc.cn/
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ Accept: application/json, text/plain, */*
|
|||||||
### 获取下载文件URL
|
### 获取下载文件URL
|
||||||
POST https://www.wenshushu.cn/ap/dl/sign
|
POST https://www.wenshushu.cn/ap/dl/sign
|
||||||
Accept: application/json, text/plain, */*
|
Accept: application/json, text/plain, */*
|
||||||
X-Token:wss:bekzdwsfwwf
|
X-Token:wss:br57uq0qg03
|
||||||
|
|
||||||
{"ufileid":"bekoe5n508z","consumeCode":0,"type":1}
|
{"ufileid":"br4t1rst6xb","consumeCode":0,"type":1}
|
||||||
|
|
||||||
###
|
###
|
||||||
# {
|
# {
|
||||||
@@ -49,5 +49,14 @@ X-Token:wss:bekzdwsfwwf
|
|||||||
# "url": "https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1686211254-31-0-6edd2e228a030be23210158daeb2c4a1&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql",
|
# "url": "https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1686211254-31-0-6edd2e228a030be23210158daeb2c4a1&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql",
|
||||||
|
|
||||||
### 直接下载
|
### 直接下载
|
||||||
https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1686211254-31-0-6edd2e228a030be23210158daeb2c4a1&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql
|
https://down.wss.show/zkrk4th/9/yj/9yjvzkrk4th?cdn_sign=1690012643-63-0-f7761ba9a500a0b300a3b5573693f9ce&exp=4800&response-content-disposition=attachment%3B%20filename%3D%22supervision.sql%22%3B%20filename%2A%3Dutf-8%27%27supervision.sql
|
||||||
|
|
||||||
|
### https://115.com/s/sw6tqra3zti?password=vc30#boost.files
|
||||||
|
https://webapi.115.com/share/downurl?user_id=101200613&share_code=sw6tqra3zti&file_id=2643992364552551890&receive_code=vc30
|
||||||
|
Cookie: UID=101200613_A1_1690425668; CID=29ac00cab116eeda63fce2296179b5ad; SEID=8f0385cd8a10f4bb8db7b064ff55ae8f53f8c7e7c6f61a3f6b1eee234d31f08bf00ac9dc68c6ff38005788e0b8444751a6b35a3f9654b07d3e4d7a67
|
||||||
|
|
||||||
|
###
|
||||||
|
https://cdnfhnfile.115.com/64722de2d26c69c339bd4c1322a0a7714717d15f/boost.files?t=1690427063&u=101200613&s=1048576&d=1894289998--0&c=0&f=3&k=53d82265b751466ee0581d1638327605&us=52428800&uc=10&v=1
|
||||||
|
|
||||||
|
###
|
||||||
|
https://webapi.115.com/share/snap?share_code=sw6tqra3zti&offset=0&limit=20&receive_code=vc30
|
||||||
|
|||||||
@@ -104,4 +104,18 @@ Platform:web
|
|||||||
https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy=file_name&orderDirection=asc&shareKey=iaKtVv-6OECd&SharePwd=DcGe&ParentFileId=0&Page=1&event=homeListFile&operateType=1
|
https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy=file_name&orderDirection=asc&shareKey=iaKtVv-6OECd&SharePwd=DcGe&ParentFileId=0&Page=1&event=homeListFile&operateType=1
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
POST https://www.123pan.com/b/api/share/download/info?1091802552=1690430466-4809035-157589386
|
||||||
|
App-Version:3
|
||||||
|
Platform:web
|
||||||
|
|
||||||
|
{"ShareKey":"iaKtVv-6OECd","FileID":2193732,"S3keyFlag":"1811834632-0","Size":4203111,"Etag":"69c94adbc0b9190cf23c4e958d8c7c53"}
|
||||||
|
|
||||||
|
###
|
||||||
|
POST https://www.123pan.com/b/api/share/statistics?1091802552=1690430466-4809035-157589386
|
||||||
|
App-Version:3
|
||||||
|
Platform:web
|
||||||
|
|
||||||
|
{"ShareKey":"iaKtVv-6OECd","behavior":1}
|
||||||
|
|
||||||
|
### eaefamemdead
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ GET http://127.0.0.1:6400/fj/tIfhRqH
|
|||||||
|
|
||||||
### 360亿方云
|
### 360亿方云
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://v2.fangcloud.com/sharing/e5079007dc31226096628870c7&pwd=QAIU
|
GET http://127.0.0.1:6400/parser?url=https://v2.fangcloud.com/sharing/fb54bdf03c66c04334fe3687a3
|
||||||
|
|
||||||
### 360亿方云
|
### 360亿方云
|
||||||
GET http://127.0.0.1:6400/json/fc/30646fefc8bf936a4766ab8a5e
|
GET http://127.0.0.1:6400/json/fc/fb54bdf03c66c04334fe3687a3
|
||||||
|
|
||||||
### 360亿方云
|
### 360亿方云
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
@@ -80,6 +80,10 @@ GET http://127.0.0.1:6400/fc/e5079007dc31226096628870c7@QAIU
|
|||||||
# https://www.123pan.com/s/iaKtVv-ICECd.html
|
# https://www.123pan.com/s/iaKtVv-ICECd.html
|
||||||
### 123
|
### 123
|
||||||
GET http://127.0.0.1:6400/json/ye/iaKtVv-ICECd
|
GET http://127.0.0.1:6400/json/ye/iaKtVv-ICECd
|
||||||
|
### 123
|
||||||
|
GET http://127.0.0.1:6400/json/ye/iaKtVv-6OECd@DcGe
|
||||||
|
### 123
|
||||||
|
GET https://lz.qaiu.top/json/ye/iaKtVv-6OECd@DcGe
|
||||||
|
|
||||||
### 123
|
### 123
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
@@ -91,3 +95,5 @@ GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&
|
|||||||
|
|
||||||
###
|
###
|
||||||
POST http://127.0.0.1:6400/login1
|
POST http://127.0.0.1:6400/login1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
95
web-service/src/main/resources/js/ye123.js
Normal file
95
web-service/src/main/resources/js/ye123.js
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
https://statics.123pan.com/share-static/dist/umi.fb72555e.js
|
||||||
|
eaefamemdead
|
||||||
|
eaefameidldy
|
||||||
|
_0x4f141a(1690439821|5790548|/b/api/share/download/info|web|3|1946841013) = 秘钥
|
||||||
|
|
||||||
|
_0x1e2592 1690439821 时间戳
|
||||||
|
_0x48562f 5790548 随机码
|
||||||
|
_0x1e37d5 /b/api/share/download/info
|
||||||
|
_0x4e2d74 web
|
||||||
|
_0x56f040 3
|
||||||
|
_0x43bdc6 1946841013 加密时间HASH戳
|
||||||
|
|
||||||
|
>>>>
|
||||||
|
_0x43bdc6=''['concat'](_0x1e2592, '-')['concat'](_0x48562f, '-')['concat'](_0x406c4e)
|
||||||
|
加密时间HASH戳 = 时间戳-随机码-秘钥
|
||||||
|
*/
|
||||||
|
|
||||||
|
function _0x1b5d95(_0x278d1a) {
|
||||||
|
var _0x839b57,
|
||||||
|
_0x4ed4dc = arguments['length'] > 0x2 && void 0x0 !== arguments[0x2] ? arguments[0x2] : 0x8;
|
||||||
|
if (0x0 === arguments['length'])
|
||||||
|
return null;
|
||||||
|
'object' === typeof _0x278d1a ? _0x839b57 = _0x278d1a : (0xa === ('' + _0x278d1a)['length'] && (_0x278d1a = 0x3e8 * parseInt(_0x278d1a)),
|
||||||
|
_0x839b57 = new Date(_0x278d1a));
|
||||||
|
var _0xc5c54a = _0x278d1a + 0xea60 * new Date(_0x278d1a)['getTimezoneOffset']()
|
||||||
|
, _0x3732dc = _0xc5c54a + 0x36ee80 * _0x4ed4dc;
|
||||||
|
return _0x839b57 = new Date(_0x3732dc),
|
||||||
|
{
|
||||||
|
'y': _0x839b57['getFullYear'](),
|
||||||
|
'm': _0x839b57['getMonth']() + 0x1 < 0xa ? '0' + (_0x839b57['getMonth']() + 0x1) : _0x839b57['getMonth']() + 0x1,
|
||||||
|
'd': _0x839b57['getDate']() < 0xa ? '0' + _0x839b57['getDate']() : _0x839b57['getDate'](),
|
||||||
|
'h': _0x839b57['getHours']() < 0xa ? '0' + _0x839b57['getHours']() : _0x839b57['getHours'](),
|
||||||
|
'f': _0x839b57['getMinutes']() < 0xa ? '0' + _0x839b57['getMinutes']() : _0x839b57['getMinutes']()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function _0x4f141a(_0x4075b1) {
|
||||||
|
|
||||||
|
for (var _0x4eddcb = arguments['length'] > 0x1 && void 0x0 !== arguments[0x1] ? arguments[0x1] : 0xa,
|
||||||
|
_0x2fc680 = function() {
|
||||||
|
for (var _0x515c63, _0x361314 = [], _0x4cbdba = 0x0; _0x4cbdba < 0x100; _0x4cbdba++) {
|
||||||
|
_0x515c63 = _0x4cbdba;
|
||||||
|
for (var _0x460960 = 0x0; _0x460960 < 0x8; _0x460960++)
|
||||||
|
_0x515c63 = 0x1 & _0x515c63 ? 0xedb88320 ^ _0x515c63 >>> 0x1 : _0x515c63 >>> 0x1;
|
||||||
|
_0x361314[_0x4cbdba] = _0x515c63;
|
||||||
|
}
|
||||||
|
return _0x361314;
|
||||||
|
},
|
||||||
|
_0x4aed86 = _0x2fc680(),
|
||||||
|
_0x5880f0 = _0x4075b1,
|
||||||
|
_0x492393 = -0x1, _0x25d82c = 0x0;
|
||||||
|
_0x25d82c < _0x5880f0['length'];
|
||||||
|
_0x25d82c++)
|
||||||
|
|
||||||
|
_0x492393 = _0x492393 >>> 0x8 ^ _0x4aed86[0xff & (_0x492393 ^ _0x5880f0.charCodeAt(_0x25d82c))];
|
||||||
|
return _0x492393 = (-0x1 ^ _0x492393) >>> 0x0,
|
||||||
|
_0x492393.toString(_0x4eddcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getSign(_0x1e37d5) {
|
||||||
|
var _0x4e2d74 = 'web';
|
||||||
|
var _0x56f040 = 3;
|
||||||
|
var _0x1e2592 = Math.round((new Date().getTime() + 0x3c * new Date().getTimezoneOffset() * 0x3e8 + 28800000) / 0x3e8).toString();
|
||||||
|
var key = 'a,d,e,f,g,h,l,m,y,i,j,n,o,p,k,q,r,s,t,u,b,c,v,w,s,z';
|
||||||
|
var _0x48562f = Math['round'](0x989680 * Math['random']());
|
||||||
|
|
||||||
|
var _0x2f7dfc;
|
||||||
|
var _0x35a889;
|
||||||
|
var _0x36f983;
|
||||||
|
var _0x3b043d;
|
||||||
|
var _0x5bc73b;
|
||||||
|
var _0x4b30b2;
|
||||||
|
var _0x32399e;
|
||||||
|
var _0x25d94e;
|
||||||
|
var _0x373490;
|
||||||
|
for (var _0x1c540f in (_0x2f7dfc = key.split(','),
|
||||||
|
_0x35a889 = _0x1b5d95(_0x1e2592),
|
||||||
|
_0x36f983 = _0x35a889['y'],
|
||||||
|
_0x3b043d = _0x35a889['m'],
|
||||||
|
_0x5bc73b = _0x35a889['d'],
|
||||||
|
_0x4b30b2 = _0x35a889['h'],
|
||||||
|
_0x32399e = _0x35a889['f'],
|
||||||
|
_0x25d94e = [_0x36f983, _0x3b043d, _0x5bc73b, _0x4b30b2, _0x32399e].join(''),
|
||||||
|
_0x373490 = [],
|
||||||
|
_0x25d94e))
|
||||||
|
_0x373490['push'](_0x2f7dfc[Number(_0x25d94e[_0x1c540f])]);
|
||||||
|
var _0x43bdc6;
|
||||||
|
var _0x406c4e;
|
||||||
|
return _0x43bdc6 = _0x4f141a(_0x373490['join']('')),
|
||||||
|
_0x406c4e = _0x4f141a(''['concat'](_0x1e2592, '|')['concat'](_0x48562f, '|')['concat'](_0x1e37d5, '|')['concat'](_0x4e2d74, '|')['concat'](_0x56f040, '|')['concat'](_0x43bdc6)),
|
||||||
|
[_0x43bdc6, ''['concat'](_0x1e2592, '-')['concat'](_0x48562f, '-')['concat'](_0x406c4e)];
|
||||||
|
}
|
||||||
@@ -65,9 +65,9 @@ public class TestAESUtil {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testKeyAuth(){
|
public void testKeyAuth(){
|
||||||
System.out.println(AESUtils.getAuthKey());
|
System.out.println(AESUtils.getAuthKey("/a/api/share/download/info"));
|
||||||
System.out.println(AESUtils.getAuthKey());
|
System.out.println(AESUtils.getAuthKey("/a/api/share/download/info"));
|
||||||
System.out.println(AESUtils.getAuthKey());
|
System.out.println(AESUtils.getAuthKey("/b/api/share/get"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
47
web-service/src/test/java/cn/qaiu/web/test/TestJs.java
Normal file
47
web-service/src/test/java/cn/qaiu/web/test/TestJs.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package cn.qaiu.web.test;
|
||||||
|
|
||||||
|
import javax.script.Invocable;
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://qaiu.top">QAIU</a>
|
||||||
|
* @date 2023/7/29 17:15
|
||||||
|
*/
|
||||||
|
public class TestJs {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用js文件获取url
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static String excuteJs() throws ScriptException,
|
||||||
|
IOException, NoSuchMethodException {
|
||||||
|
ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||||
|
ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎
|
||||||
|
String reader = null;
|
||||||
|
//获取文件所在的相对路径
|
||||||
|
//String text = System.getProperty("user.dir");
|
||||||
|
//reader = text + "\\src\\main\\resources\\test.js";
|
||||||
|
|
||||||
|
String path = TestJs.class.getResource("/").getPath();
|
||||||
|
System.out.println(path);
|
||||||
|
reader = path + "/test.js";
|
||||||
|
FileReader fReader = new FileReader(reader);
|
||||||
|
engine.eval(fReader);
|
||||||
|
|
||||||
|
Invocable inv = (Invocable) engine;
|
||||||
|
//调用js中的方法
|
||||||
|
Object test2 = inv.invokeFunction("add", 1, 2);
|
||||||
|
String url = test2.toString();
|
||||||
|
fReader.close();
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws ScriptException, IOException, NoSuchMethodException {
|
||||||
|
String s = excuteJs();
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
web-service/src/test/resources/test.js
Normal file
3
web-service/src/test/resources/test.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
function add(a, b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user