mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 20:33:03 +00:00
pod update
This commit is contained in:
@@ -7,6 +7,8 @@ public interface ConfigConstant {
|
|||||||
String LOCAL = "local";
|
String LOCAL = "local";
|
||||||
String SERVER = "server";
|
String SERVER = "server";
|
||||||
String CACHE = "cache";
|
String CACHE = "cache";
|
||||||
|
|
||||||
|
String PROXY = "proxy";
|
||||||
String GLOBAL_CONFIG = "globalConfig";
|
String GLOBAL_CONFIG = "globalConfig";
|
||||||
String CUSTOM_CONFIG = "customConfig";
|
String CUSTOM_CONFIG = "customConfig";
|
||||||
String ASYNC_SERVICE_INSTANCES = "asyncServiceInstances";
|
String ASYNC_SERVICE_INSTANCES = "asyncServiceInstances";
|
||||||
|
|||||||
@@ -6,16 +6,22 @@ import io.vertx.core.Future;
|
|||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.json.DecodeException;
|
import io.vertx.core.json.DecodeException;
|
||||||
|
import io.vertx.core.json.Json;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.core.net.ProxyOptions;
|
||||||
|
import io.vertx.core.net.ProxyType;
|
||||||
|
import io.vertx.core.net.impl.VertxHandler;
|
||||||
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.WebClient;
|
||||||
import io.vertx.ext.web.client.WebClientOptions;
|
import io.vertx.ext.web.client.WebClientOptions;
|
||||||
import io.vertx.ext.web.client.WebClientSession;
|
import io.vertx.ext.web.client.WebClientSession;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析器抽象类包含promise, HTTP Client, 默认失败方法等;
|
* 解析器抽象类包含promise, HTTP Client, 默认失败方法等;
|
||||||
@@ -61,6 +67,29 @@ public abstract class PanBase implements IPanTool {
|
|||||||
*/
|
*/
|
||||||
public PanBase(ShareLinkInfo shareLinkInfo) {
|
public PanBase(ShareLinkInfo shareLinkInfo) {
|
||||||
this.shareLinkInfo = shareLinkInfo;
|
this.shareLinkInfo = shareLinkInfo;
|
||||||
|
if (shareLinkInfo.getOtherParam().containsKey("proxy")) {
|
||||||
|
JsonObject proxy = (JsonObject) shareLinkInfo.getOtherParam().get("proxy");
|
||||||
|
ProxyOptions proxyOptions = new ProxyOptions()
|
||||||
|
.setType(ProxyType.valueOf(proxy.getString("type").toUpperCase()))
|
||||||
|
.setHost(proxy.getString("host"))
|
||||||
|
.setPort(proxy.getInteger("port"));
|
||||||
|
if (StringUtils.isNotEmpty(proxy.getString("username"))) {
|
||||||
|
proxyOptions.setUsername(proxy.getString("username"));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(proxy.getString("password"))) {
|
||||||
|
proxyOptions.setUsername(proxy.getString("password"));
|
||||||
|
}
|
||||||
|
this.client = WebClient.create(WebClientVertxInit.get(),
|
||||||
|
new WebClientOptions()
|
||||||
|
.setUserAgentEnabled(false)
|
||||||
|
.setProxyOptions(proxyOptions));
|
||||||
|
|
||||||
|
this.clientSession = WebClientSession.create(client);
|
||||||
|
this.clientNoRedirects = WebClient.create(WebClientVertxInit.get(),
|
||||||
|
new WebClientOptions().setFollowRedirects(false)
|
||||||
|
.setUserAgentEnabled(false)
|
||||||
|
.setProxyOptions(proxyOptions));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PanBase() {
|
protected PanBase() {
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ public enum PanDomainTemplate {
|
|||||||
compile("https://www\\.icloud\\.com\\.cn/iclouddrive/(?<KEY>[a-z_A-Z\\d-=]+)(#(.+))?"),
|
compile("https://www\\.icloud\\.com\\.cn/iclouddrive/(?<KEY>[a-z_A-Z\\d-=]+)(#(.+))?"),
|
||||||
"https://www.icloud.com.cn/iclouddrive/{shareKey}",
|
"https://www.icloud.com.cn/iclouddrive/{shareKey}",
|
||||||
PicTool.class),
|
PicTool.class),
|
||||||
|
// https://www.dropbox.com/scl/fi/cwnbms1yn8u6rcatzyta7/emqx-5.0.26-el7-amd64.tar.gz?rlkey=3uoi4bxz5mv93jmlaws0nlol1&e=8&st=fe0lclc2&dl=0
|
||||||
|
PDB("dropbox",
|
||||||
|
compile("https://www.dropbox.com/scl/fi/(?<KEY>\\w+)/.+?rlkey=(?<PWD>\\w+).*"),
|
||||||
|
"https://www.dropbox.com/scl/fi/{shareKey}/?rlkey={pwd}&dl=0",
|
||||||
|
PdbTool.class),
|
||||||
|
|
||||||
// =====================音乐类解析 分享链接标志->MxxS (单歌曲/普通音质)==========================
|
// =====================音乐类解析 分享链接标志->MxxS (单歌曲/普通音质)==========================
|
||||||
// http://163cn.tv/xxx
|
// http://163cn.tv/xxx
|
||||||
@@ -183,6 +188,8 @@ public enum PanDomainTemplate {
|
|||||||
|
|
||||||
public static final String KEY = "KEY";
|
public static final String KEY = "KEY";
|
||||||
|
|
||||||
|
public static final String PWD = "PWD";
|
||||||
|
|
||||||
// 网盘的显示名称,用于用户界面显示
|
// 网盘的显示名称,用于用户界面显示
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import static cn.qaiu.parser.PanDomainTemplate.KEY;
|
import static cn.qaiu.parser.PanDomainTemplate.KEY;
|
||||||
|
import static cn.qaiu.parser.PanDomainTemplate.PWD;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,8 +39,16 @@ public class ParserCreate {
|
|||||||
Matcher matcher = this.panDomainTemplate.getPattern().matcher(shareUrl);
|
Matcher matcher = this.panDomainTemplate.getPattern().matcher(shareUrl);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
String shareKey = matcher.group(KEY);
|
String shareKey = matcher.group(KEY);
|
||||||
|
|
||||||
// 返回规范化的标准链接
|
// 返回规范化的标准链接
|
||||||
String standardUrl = getStandardUrlTemplate().replace("{shareKey}", shareKey);
|
String standardUrl = getStandardUrlTemplate()
|
||||||
|
.replace("{shareKey}", shareKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String pwd = matcher.group(PWD);
|
||||||
|
standardUrl = standardUrl .replace("{pwd}", pwd);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
shareLinkInfo.setShareUrl(shareUrl);
|
shareLinkInfo.setShareUrl(shareUrl);
|
||||||
shareLinkInfo.setShareKey(shareKey);
|
shareLinkInfo.setShareKey(shareKey);
|
||||||
if (!(panDomainTemplate.ordinal() >= PanDomainTemplate.CE.ordinal())) {
|
if (!(panDomainTemplate.ordinal() >= PanDomainTemplate.CE.ordinal())) {
|
||||||
|
|||||||
95
parser/src/main/java/cn/qaiu/parser/impl/PdbTool.java
Normal file
95
parser/src/main/java/cn/qaiu/parser/impl/PdbTool.java
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
import cn.qaiu.parser.IPanTool;
|
||||||
|
import cn.qaiu.parser.PanBase;
|
||||||
|
import cn.qaiu.util.URLUtil;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.core.MultiMap;
|
||||||
|
import io.vertx.core.buffer.Buffer;
|
||||||
|
import io.vertx.core.net.ProxyOptions;
|
||||||
|
import io.vertx.ext.web.client.HttpRequest;
|
||||||
|
import io.vertx.ext.web.client.HttpResponse;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="https://www.dropbox.com/">dropbox</a>
|
||||||
|
* Dropbox网盘--不支持大陆地区
|
||||||
|
*/
|
||||||
|
public class PdbTool extends PanBase implements IPanTool {
|
||||||
|
|
||||||
|
private static final String API_URL =
|
||||||
|
"https://www.dropbox.com/sharing/fetch_user_content_link";
|
||||||
|
static final String COOKIE_KEY = "__Host-js_csrf=";
|
||||||
|
|
||||||
|
public PdbTool(ShareLinkInfo shareLinkInfo) {
|
||||||
|
super(shareLinkInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<String> parse() {
|
||||||
|
// https://www.dropbox.com/scl/fi/cwnbms1yn8u6rcatzyta7/emqx-5.0.26-el7-amd64.tar.gz?rlkey=3uoi4bxz5mv93jmlaws0nlol1&e=8&st=fe0lclc2&dl=0
|
||||||
|
// https://www.dropbox.com/scl/fi/()/Get-Started-with-Dropbox.pdf?rlkey=yrddd6s9gxsq967pmbgtzvfl3&st=2trcc1f3&dl=0
|
||||||
|
//
|
||||||
|
clientSession.getAbs(shareLinkInfo.getShareUrl())
|
||||||
|
.send()
|
||||||
|
.onSuccess(res->{
|
||||||
|
List<String> collect =
|
||||||
|
res.cookies().stream().filter(key -> key.contains(COOKIE_KEY)).toList();
|
||||||
|
if (collect.isEmpty()) {
|
||||||
|
fail("cookie未找到");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Matcher matcher = Pattern.compile(COOKIE_KEY + "([\\w-]+);").matcher(collect.get(0));
|
||||||
|
String _t;
|
||||||
|
if (matcher.find()) {
|
||||||
|
_t = matcher.group(1);
|
||||||
|
} else {
|
||||||
|
fail("cookie未找到");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
|
||||||
|
headers.set("accept", "*/*");
|
||||||
|
headers.set("accept-language", "zh-CN,zh;q=0.9");
|
||||||
|
headers.set("cache-control", "no-cache");
|
||||||
|
headers.set("dnt", "1");
|
||||||
|
headers.set("origin", "https://www.dropbox.com");
|
||||||
|
headers.set("pragma", "no-cache");
|
||||||
|
headers.set("priority", "u=1, i");
|
||||||
|
headers.set("referer", shareLinkInfo.getShareUrl());
|
||||||
|
headers.set("sec-ch-ua", "\"Chromium\";v=\"130\", \"Microsoft Edge\";v=\"130\", \"Not?A_Brand\";v=\"99\"");
|
||||||
|
headers.set("sec-ch-ua-mobile", "?0");
|
||||||
|
headers.set("sec-ch-ua-platform", "\"Windows\"");
|
||||||
|
headers.set("sec-fetch-dest", "empty");
|
||||||
|
headers.set("sec-fetch-mode", "cors");
|
||||||
|
headers.set("sec-fetch-site", "same-origin");
|
||||||
|
headers.set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0");
|
||||||
|
headers.set("x-dropbox-client-yaps-attribution", "edison_atlasservlet.file_viewer-edison:prod");
|
||||||
|
headers.set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
try {
|
||||||
|
URL url = new URL(shareLinkInfo.getShareUrl());
|
||||||
|
// https://www.dropbox.com/scl/fi/cwnbms1yn8u6rcatzyta7/xxx?rlkey=xx&dl=0
|
||||||
|
String u0 = URLEncoder.encode((url.getProtocol() + "://" + url.getHost() + url.getPath() + "?rlkey=%s&dl=0")
|
||||||
|
.formatted(URLUtil.from(shareLinkInfo.getShareUrl()).getParam("rlkey")), StandardCharsets.UTF_8);
|
||||||
|
clientSession.postAbs(API_URL)
|
||||||
|
.sendBuffer(Buffer.buffer("is_xhr=true&t=%s&url=%s&origin=PREVIEW_PAGE".formatted(_t, u0)))
|
||||||
|
.onSuccess(res2 -> {
|
||||||
|
complete(res2.bodyAsString());
|
||||||
|
})
|
||||||
|
.onFailure(handleFail());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.onFailure(handleFail("请求下载链接失败"));
|
||||||
|
return future();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,17 +31,11 @@ public class PgdTool extends PanBase implements IPanTool {
|
|||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
downloadUrl = DOWN_URL_TEMPLATE + "?id=" + shareLinkInfo.getShareKey() + "&export=download";
|
downloadUrl = DOWN_URL_TEMPLATE + "?id=" + shareLinkInfo.getShareKey() + "&export=download";
|
||||||
|
|
||||||
if (true) {
|
if (shareLinkInfo.getOtherParam().containsKey("proxy")) {
|
||||||
// if (shareLinkInfo.getOtherParam().containsKey("bypassCheck")
|
// if (shareLinkInfo.getOtherParam().containsKey("bypassCheck")
|
||||||
// && "true".equalsIgnoreCase(shareLinkInfo.getOtherParam().get("bypassCheck").toString())) {
|
// && "true".equalsIgnoreCase(shareLinkInfo.getOtherParam().get("bypassCheck").toString())) {
|
||||||
// 发起请求但不真正下载文件, 只检查响应头
|
// 发起请求但不真正下载文件, 只检查响应头
|
||||||
HttpRequest<Buffer> clientAbs = client.headAbs(downloadUrl);
|
client.headAbs(downloadUrl).send()
|
||||||
// TODO 判断是否需要代理
|
|
||||||
if (true) {
|
|
||||||
clientAbs.proxy(new ProxyOptions().setHost("127.0.0.1").setPort(7890));
|
|
||||||
}
|
|
||||||
clientAbs
|
|
||||||
.send()
|
|
||||||
.onSuccess(this::handleResponse)
|
.onSuccess(this::handleResponse)
|
||||||
.onFailure(handleFail("请求下载链接失败"));
|
.onFailure(handleFail("请求下载链接失败"));
|
||||||
return future();
|
return future();
|
||||||
@@ -59,12 +53,7 @@ public class PgdTool extends PanBase implements IPanTool {
|
|||||||
complete(downloadUrl);
|
complete(downloadUrl);
|
||||||
} else {
|
} else {
|
||||||
// 如果不是文件流类型,从 HTML 中解析出真实下载链接
|
// 如果不是文件流类型,从 HTML 中解析出真实下载链接
|
||||||
HttpRequest<Buffer> clientAbs = client.getAbs(downloadUrl);
|
client.getAbs(downloadUrl)
|
||||||
// TODO 判断是否需要代理
|
|
||||||
if (true) {
|
|
||||||
clientAbs.proxy(new ProxyOptions().setHost("127.0.0.1").setPort(7890));
|
|
||||||
}
|
|
||||||
clientAbs
|
|
||||||
.send()
|
.send()
|
||||||
.onSuccess(res0 -> {
|
.onSuccess(res0 -> {
|
||||||
parseHtmlForRealLink(res0.bodyAsString());
|
parseHtmlForRealLink(res0.bodyAsString());
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public class PodTool extends PanBase {
|
|||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!4699&e=OggA4s&migratedtospo=true&redeem=aHR0cHM6Ly8xZHJ2Lm1zL3UvcyFBbGcwZmVRbUN2MnJwRnZ1NDQ0aGc1eVZxRGNLP2U9T2dnQTRz
|
||||||
// public static void main(String[] args) {
|
// public static void main(String[] args) {
|
||||||
// Matcher matcher = redirectUrlRegex.matcher("https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!4698" +
|
// Matcher matcher = redirectUrlRegex.matcher("https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!4698" +
|
||||||
// "&authkey=!ACpvXghP5xhG_cg&e=hV98W1");
|
// "&authkey=!ACpvXghP5xhG_cg&e=hV98W1");
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
|
"@vueuse/core": "^11.2.0",
|
||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
@@ -27,8 +28,7 @@
|
|||||||
"compression-webpack-plugin": "^11.1.0",
|
"compression-webpack-plugin": "^11.1.0",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-plugin-vue": "^9.30.0",
|
"eslint-plugin-vue": "^9.30.0",
|
||||||
"filemanager-webpack-plugin": "8.0.0",
|
"filemanager-webpack-plugin": "8.0.0"
|
||||||
"typescript": "^5.6.3"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-card class="box-card">
|
<el-card class="box-card">
|
||||||
|
|
||||||
|
<div style="text-align: right"><DarkMode/></div>
|
||||||
<div class="demo-basic--circle">
|
<div class="demo-basic--circle">
|
||||||
<div class="block" style="text-align: center;">
|
<div class="block" style="text-align: center;">
|
||||||
<img :height="150" src="../public/images/lanzou111.png" alt="lz"></img>
|
<img :height="150" src="../public/images/lanzou111.png" alt="lz"></img>
|
||||||
@@ -40,7 +43,7 @@
|
|||||||
active-text="自动识别剪切板"
|
active-text="自动识别剪切板"
|
||||||
></el-switch>
|
></el-switch>
|
||||||
|
|
||||||
<el-input placeholder="请粘贴分享链接" v-model="link" id="url">
|
<el-input placeholder="请粘贴分享链接(http://或https://)" v-model="link" id="url">
|
||||||
<template #prepend>分享链接</template>
|
<template #prepend>分享链接</template>
|
||||||
<template #append v-if="!autoReadClipboard">
|
<template #append v-if="!autoReadClipboard">
|
||||||
<el-button @click="() => getPaste(1)">读取剪切板</el-button>
|
<el-button @click="() => getPaste(1)">读取剪切板</el-button>
|
||||||
@@ -49,14 +52,14 @@
|
|||||||
<el-input placeholder="请输入密码" v-model="password" id="url">
|
<el-input placeholder="请输入密码" v-model="password" id="url">
|
||||||
<template #prepend>分享密码</template>
|
<template #prepend>分享密码</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-input v-show="getLink2" placeholder="解析地址" :value="getLink2" id="url">
|
<el-input v-show="getLink2" :value="getLink2" id="url">
|
||||||
<template #prepend>智能直链</template>
|
<template #prepend>智能直链</template>
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button :icon="Search" circle
|
<el-button v-clipboard:copy="getLink2"
|
||||||
v-clipboard:copy="getLink2"
|
v-clipboard:success="onCopy"
|
||||||
v-clipboard:success="onCopy"
|
v-clipboard:error="onError">
|
||||||
v-clipboard:error="onError">复制
|
<el-icon><CopyDocument/></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
|
||||||
@@ -80,20 +83,19 @@
|
|||||||
<a :href="downUrl" v-show="downUrl">点击下载</a>
|
<a :href="downUrl" v-show="downUrl">点击下载</a>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="mdText" style="text-align: center">
|
<div v-if="mdText" style="text-align: center">
|
||||||
<el-input
|
<el-input :value="mdText" readonly>
|
||||||
type="textarea"
|
<template #append>
|
||||||
:autosize="{ minRows: 1, maxRows: 8}"
|
<el-button v-clipboard:copy="mdText"
|
||||||
v-model="mdText">
|
v-clipboard:success="onCopy"
|
||||||
|
v-clipboard:error="onError">
|
||||||
|
<el-icon><CopyDocument/></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-button style="width: 100%" v-clipboard:copy="mdText"
|
|
||||||
v-clipboard:success="onCopy"
|
|
||||||
v-clipboard:error="onError">复制
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: center" v-show="showQrc">
|
<div style="text-align: center" v-show="showQrc">
|
||||||
<div style="text-align: center"><el-link target="_blank" :href="codeUrl">{{ codeUrl }}</el-link></div>
|
|
||||||
<canvas ref="qrcodeCanvas"></canvas>
|
<canvas ref="qrcodeCanvas"></canvas>
|
||||||
<div style="text-align: center"> 扫码下载 </div>
|
<div style="text-align: center"><el-link target="_blank" :href="codeUrl">{{ codeUrl }}</el-link></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="tjData.shareLinkInfo">
|
<div v-if="tjData.shareLinkInfo">
|
||||||
<el-descriptions class="margin-top" title="分享详情" :column="1" border>
|
<el-descriptions class="margin-top" title="分享详情" :column="1" border>
|
||||||
@@ -121,12 +123,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import QRCode from 'qrcode'
|
import QRCode from 'qrcode'
|
||||||
import '@element-plus/icons-vue'
|
import DarkMode from '@/components/DarkMode'
|
||||||
|
|
||||||
import parserUrl from './parserUrl1'
|
import parserUrl from './parserUrl1'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
components: {DarkMode},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// baseAPI: `${location.protocol}//${location.hostname}:6400`,
|
// baseAPI: `${location.protocol}//${location.hostname}:6400`,
|
||||||
@@ -182,6 +185,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// toggleDark() {
|
||||||
|
// toggleDark()
|
||||||
|
// },
|
||||||
check() {
|
check() {
|
||||||
this.mdText = ''
|
this.mdText = ''
|
||||||
this.showQrc = false
|
this.showQrc = false
|
||||||
@@ -269,9 +275,7 @@ export default {
|
|||||||
const options = { // 设置二维码的参数,例如大小、边距等
|
const options = { // 设置二维码的参数,例如大小、边距等
|
||||||
width: 150,
|
width: 150,
|
||||||
height: 150,
|
height: 150,
|
||||||
margin: 2,
|
margin: 2
|
||||||
colorDark : "#8e0fb7",
|
|
||||||
colorLight : "#fff2ad",
|
|
||||||
};
|
};
|
||||||
axios.get(this.getLinkInfo, {params: {url: this.link, pwd: this.password}}).then(
|
axios.get(this.getLinkInfo, {params: {url: this.link, pwd: this.password}}).then(
|
||||||
response => {
|
response => {
|
||||||
@@ -343,13 +347,10 @@ export default {
|
|||||||
}
|
}
|
||||||
// 当文档获得焦点时触发
|
// 当文档获得焦点时触发
|
||||||
window.addEventListener('focus', () => {
|
window.addEventListener('focus', () => {
|
||||||
console.log('文档获得了焦点');
|
|
||||||
if (this.autoReadClipboard) {
|
if (this.autoReadClipboard) {
|
||||||
this.getPaste()
|
this.getPaste()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// this.getPaste()
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
autoReadClipboard(val) {
|
autoReadClipboard(val) {
|
||||||
@@ -371,9 +372,6 @@ export default {
|
|||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection {
|
|
||||||
background: rgba(0, 149, 255, .1);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:before {
|
body:before {
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -382,7 +380,6 @@ body:before {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
opacity: .3;
|
opacity: .3;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
28
web-front/src/components/DarkMode.vue
Normal file
28
web-front/src/components/DarkMode.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<el-switch
|
||||||
|
v-model="darkMode"
|
||||||
|
size="large"
|
||||||
|
style="--el-switch-on-color: #4882f8; --el-switch-off-color: #ff8000"
|
||||||
|
inline-prompt
|
||||||
|
:active-icon="Moon"
|
||||||
|
:inactive-icon="Sunny"
|
||||||
|
@change="toggleDark"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useDark, useToggle } from '@vueuse/core'
|
||||||
|
/** 引入Element-Plus图标 */
|
||||||
|
import { Sunny, Moon } from '@element-plus/icons-vue'
|
||||||
|
defineOptions({
|
||||||
|
name: 'DarkMode'
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 切换模式 */
|
||||||
|
const isDark = useDark({})
|
||||||
|
|
||||||
|
const toggleDark = useToggle(isDark)
|
||||||
|
/** 是否切换为暗黑模式 */
|
||||||
|
const darkMode = ref(false)
|
||||||
|
</script>
|
||||||
@@ -6,7 +6,9 @@ import DirectiveExtensions from './directive'
|
|||||||
import JsonViewer from 'vue3-json-viewer'
|
import JsonViewer from 'vue3-json-viewer'
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
|
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||||
import "vue3-json-viewer/dist/index.css";
|
import "vue3-json-viewer/dist/index.css";
|
||||||
|
import './styles/dark/css-vars.css'
|
||||||
|
|
||||||
window.$vueApp = Vue.createApp(App)
|
window.$vueApp = Vue.createApp(App)
|
||||||
|
|
||||||
|
|||||||
5
web-front/src/styles/dark/css-vars.css
Normal file
5
web-front/src/styles/dark/css-vars.css
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
html.dark {
|
||||||
|
/* 自定义深色背景颜色 */
|
||||||
|
--el-bg-color: #424242;
|
||||||
|
--el-bg-color-overlay: #424242;
|
||||||
|
}
|
||||||
0
web-front/src/styles/index.css
Normal file
0
web-front/src/styles/index.css
Normal file
@@ -5,7 +5,7 @@ function resolve(dir) {
|
|||||||
return path.join(__dirname, dir)
|
return path.join(__dirname, dir)
|
||||||
}
|
}
|
||||||
const CompressionPlugin = require('compression-webpack-plugin');
|
const CompressionPlugin = require('compression-webpack-plugin');
|
||||||
const FileManagerPlugin = require('filemanager-webpack-plugin')
|
// const FileManagerPlugin = require('filemanager-webpack-plugin')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
transpileDependencies: true,
|
transpileDependencies: true,
|
||||||
@@ -21,6 +21,9 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
productionSourceMap: false, // 是否在构建生产包时生成sourceMap文件,false将提高构建速度
|
||||||
|
},
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
// provide the app's title in webpack's name field, so that
|
// provide the app's title in webpack's name field, so that
|
||||||
// it can be accessed in index.html to inject the correct title.
|
// it can be accessed in index.html to inject the correct title.
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ import cn.qaiu.vx.core.Deploy;
|
|||||||
import cn.qaiu.vx.core.util.ConfigConstant;
|
import cn.qaiu.vx.core.util.ConfigConstant;
|
||||||
import cn.qaiu.vx.core.util.VertxHolder;
|
import cn.qaiu.vx.core.util.VertxHolder;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.core.json.jackson.DatabindCodec;
|
import io.vertx.core.json.jackson.DatabindCodec;
|
||||||
|
import io.vertx.core.shareddata.LocalMap;
|
||||||
|
|
||||||
|
import static cn.qaiu.vx.core.util.ConfigConstant.LOCAL;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,5 +43,23 @@ public class AppMain {
|
|||||||
if (jsonObject.containsKey(ConfigConstant.CACHE)) {
|
if (jsonObject.containsKey(ConfigConstant.CACHE)) {
|
||||||
CacheConfigLoader.init(jsonObject.getJsonObject(ConfigConstant.CACHE));
|
CacheConfigLoader.init(jsonObject.getJsonObject(ConfigConstant.CACHE));
|
||||||
}
|
}
|
||||||
|
// 代理
|
||||||
|
if (jsonObject.containsKey(ConfigConstant.PROXY)) {
|
||||||
|
LocalMap<Object, Object> localMap = VertxHolder.getVertxInstance().sharedData().getLocalMap(LOCAL);
|
||||||
|
JsonArray proxyJsonArray = jsonObject.getJsonArray(ConfigConstant.PROXY);
|
||||||
|
|
||||||
|
proxyJsonArray.forEach(proxyJson -> {
|
||||||
|
String panTypes = ((JsonObject)proxyJson).getString("panTypes");
|
||||||
|
|
||||||
|
if (!panTypes.isEmpty()) {
|
||||||
|
JsonObject jsonObject1 = new JsonObject();
|
||||||
|
for (String s : panTypes.split(",")) {
|
||||||
|
jsonObject1.put(s, proxyJson);
|
||||||
|
}
|
||||||
|
localMap.put("proxy", jsonObject1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,12 @@ import cn.qaiu.lz.web.model.CacheLinkInfo;
|
|||||||
import cn.qaiu.lz.web.service.CacheService;
|
import cn.qaiu.lz.web.service.CacheService;
|
||||||
import cn.qaiu.parser.ParserCreate;
|
import cn.qaiu.parser.ParserCreate;
|
||||||
import cn.qaiu.vx.core.annotaions.Service;
|
import cn.qaiu.vx.core.annotaions.Service;
|
||||||
|
import cn.qaiu.vx.core.util.ConfigConstant;
|
||||||
|
import cn.qaiu.vx.core.util.VertxHolder;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.core.shareddata.LocalMap;
|
||||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -21,6 +24,16 @@ public class CacheServiceImpl implements CacheService {
|
|||||||
private final CacheManager cacheManager = new CacheManager();
|
private final CacheManager cacheManager = new CacheManager();
|
||||||
|
|
||||||
private Future<CacheLinkInfo> getAndSaveCachedShareLink(ParserCreate parserCreate) {
|
private Future<CacheLinkInfo> getAndSaveCachedShareLink(ParserCreate parserCreate) {
|
||||||
|
LocalMap<Object, Object> localMap = VertxHolder.getVertxInstance().sharedData()
|
||||||
|
.getLocalMap(ConfigConstant.LOCAL);
|
||||||
|
if (localMap.containsKey(ConfigConstant.PROXY)) {
|
||||||
|
JsonObject proxy = (JsonObject) localMap.get(ConfigConstant.PROXY);
|
||||||
|
String type = parserCreate.getShareLinkInfo().getType();
|
||||||
|
if (proxy.containsKey(type)) {
|
||||||
|
parserCreate.getShareLinkInfo().getOtherParam().put(ConfigConstant.PROXY, proxy.getJsonObject(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Promise<CacheLinkInfo> promise = Promise.promise();
|
Promise<CacheLinkInfo> promise = Promise.promise();
|
||||||
// 构建组合的缓存key
|
// 构建组合的缓存key
|
||||||
ShareLinkInfo shareLinkInfo = parserCreate.getShareLinkInfo();
|
ShareLinkInfo shareLinkInfo = parserCreate.getShareLinkInfo();
|
||||||
|
|||||||
@@ -64,4 +64,16 @@ cache:
|
|||||||
mqq: 30
|
mqq: 30
|
||||||
mkg: 30
|
mkg: 30
|
||||||
|
|
||||||
|
# httpClient静态代理服务器配置(外网代理)
|
||||||
|
proxy:
|
||||||
|
- panTypes: pgd,pdb
|
||||||
|
type: http # 支持http/socks4/socks5
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 7890
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
|
||||||
|
|
||||||
|
# 代理池配置
|
||||||
|
#ip-pool:
|
||||||
|
# api-url:
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ https://api.onedrive.com/v1.0/drives/abfd0a26e47d3458/items/ABFD0A26E47D3458!469
|
|||||||
|
|
||||||
|
|
||||||
### https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!3729&authkey=!AF3rQNA6Yxr46H8&ithint=file%2cdocx&e=buaRtp
|
### https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!3729&authkey=!AF3rQNA6Yxr46H8&ithint=file%2cdocx&e=buaRtp
|
||||||
|
### https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!3729&ithint=file%2cdocx&e=buaRtp&migratedtospo=true&redeem=aHR0cHM6Ly8xZHJ2Lm1zL3cvcyFBbGcwZmVRbUN2MnJuUkZkNjBEUU9tTWEtT2hfP2U9YnVhUnRw
|
||||||
#@no-redirect
|
#@no-redirect
|
||||||
https://1drv.ms/w/s!Alg0feQmCv2rnRFd60DQOmMa-Oh_?e=buaRtp
|
https://1drv.ms/w/s!Alg0feQmCv2rnRFd60DQOmMa-Oh_?e=buaRtp
|
||||||
|
|
||||||
@@ -153,6 +154,7 @@ https://api.onedrive.com/v1.0/drives/abfd0a26e47d3458/items/ABFD0A26E47D3458!372
|
|||||||
https://1drv.ms/u/s!Alg0feQmCv2rpFvu444hg5yVqDcK?e=OggA4s
|
https://1drv.ms/u/s!Alg0feQmCv2rpFvu444hg5yVqDcK?e=OggA4s
|
||||||
|
|
||||||
###
|
###
|
||||||
|
#@no-redirect
|
||||||
https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!4699&authkey=!AO7jjiGDnJWoNwo&e=OggA4s
|
https://onedrive.live.com/redir?resid=ABFD0A26E47D3458!4699&authkey=!AO7jjiGDnJWoNwo&e=OggA4s
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|||||||
@@ -259,3 +259,7 @@ GET http://127.0.0.1:6400/parser?url=https://1drv.ms/u/s!Alg0feQmCv2rpFvu444hg5y
|
|||||||
### pic PASS
|
### pic PASS
|
||||||
# @no-redirect
|
# @no-redirect
|
||||||
GET http://127.0.0.1:6400/parser?url=https://www.icloud.com.cn/iclouddrive/0d8lBC0qp01v1uNThurAGQf1A#fonts
|
GET http://127.0.0.1:6400/parser?url=https://www.icloud.com.cn/iclouddrive/0d8lBC0qp01v1uNThurAGQf1A#fonts
|
||||||
|
|
||||||
|
### pdb PASS
|
||||||
|
# @no-redirect
|
||||||
|
GET http://127.0.0.1:6400/parser?url=https://www.dropbox.com/scl/fi/cwnbms1yn8u6rcatzyta7/1?rlkey=3uoi4bxz5mv93jmlaws0nlol1&e=2&dl=0
|
||||||
|
|||||||
Reference in New Issue
Block a user