mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-17 21:03:03 +00:00
1. add 网易云音乐解析
This commit is contained in:
@@ -35,6 +35,7 @@ main分支依赖JDK17, 提供了JDK11分支[main-jdk11](https://github.com/qaiu/
|
|||||||
- [QQ邮箱文件中转站 (qq)](https://mail.qq.com/)
|
- [QQ邮箱文件中转站 (qq)](https://mail.qq.com/)
|
||||||
- [超星网盘-开发中 (cx)](https://passport2.chaoxing.com/login?newversion=true&refer=https%3A%2F%2Fpan-yz.chaoxing.com%2F)
|
- [超星网盘-开发中 (cx)](https://passport2.chaoxing.com/login?newversion=true&refer=https%3A%2F%2Fpan-yz.chaoxing.com%2F)
|
||||||
- [城通网盘(ct)](https://www.ctfile.com)
|
- [城通网盘(ct)](https://www.ctfile.com)
|
||||||
|
- [网易云音乐(mne)](https://music.163.com)
|
||||||
- [Cloudreve自建网盘(ce)](https://github.com/cloudreve/Cloudreve)
|
- [Cloudreve自建网盘(ce)](https://github.com/cloudreve/Cloudreve)
|
||||||
|
|
||||||
**TODO:**
|
**TODO:**
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public final class Deploy {
|
|||||||
private DeploymentOptions getWorkDeploymentOptions(String name, int ins) {
|
private DeploymentOptions getWorkDeploymentOptions(String name, int ins) {
|
||||||
return new DeploymentOptions()
|
return new DeploymentOptions()
|
||||||
.setWorkerPoolName(name)
|
.setWorkerPoolName(name)
|
||||||
.setWorker(true)
|
.setThreadingModel(ThreadingModel.WORKER)
|
||||||
.setInstances(ins);
|
.setInstances(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ public class ReverseProxyVerticle extends AbstractVerticle {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Promise<Void> startPromise) throws Exception {
|
public void start(Promise<Void> startPromise) {
|
||||||
CONFIG.onSuccess(this::handleProxyConfList);
|
CONFIG.onSuccess(this::handleProxyConfList);
|
||||||
|
// createFileListener
|
||||||
startPromise.complete();
|
startPromise.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,9 +117,7 @@ public class ReverseProxyVerticle extends AbstractVerticle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send page404 page
|
// Send page404 page
|
||||||
proxyRouter.errorHandler(404, ctx -> {
|
proxyRouter.errorHandler(404, ctx -> ctx.response().sendFile(proxyConf.getString("page404")));
|
||||||
ctx.response().sendFile(proxyConf.getString("page404"));
|
|
||||||
});
|
|
||||||
|
|
||||||
HttpServer server = getHttpsServer(proxyConf);
|
HttpServer server = getHttpsServer(proxyConf);
|
||||||
server.requestHandler(proxyRouter);
|
server.requestHandler(proxyRouter);
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ public enum PanDomainTemplate {
|
|||||||
"https://474b\\.com/file/(.+)",
|
"https://474b\\.com/file/(.+)",
|
||||||
"https://474b.com/file/{shareKey}",
|
"https://474b.com/file/{shareKey}",
|
||||||
CtTool.class),
|
CtTool.class),
|
||||||
|
// http://163cn.tv/xxx
|
||||||
|
MNE("网易云音乐",
|
||||||
|
"http(s)?://163cn\\.tv/(.+)",
|
||||||
|
"http://163cn.tv/{shareKey}",
|
||||||
|
MneTool.class),
|
||||||
// https://pan.huang1111.cn/s/xxx
|
// https://pan.huang1111.cn/s/xxx
|
||||||
// 通用域名([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}
|
// 通用域名([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}
|
||||||
CE("Cloudreve",
|
CE("Cloudreve",
|
||||||
|
|||||||
35
parser/src/main/java/cn/qaiu/parser/impl/MneTool.java
Normal file
35
parser/src/main/java/cn/qaiu/parser/impl/MneTool.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
import cn.qaiu.parser.PanBase;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.uritemplate.UriTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网易云音乐, 单歌曲直链解析
|
||||||
|
* <a href="http://163cn.tv/ykLZJJT">示例分享</a>
|
||||||
|
*/
|
||||||
|
public class MneTool extends PanBase {
|
||||||
|
|
||||||
|
|
||||||
|
public static final String API_URL = "https://music.163.com/song/media/outer/url?id={id}";
|
||||||
|
|
||||||
|
|
||||||
|
public MneTool(ShareLinkInfo shareLinkInfo) {
|
||||||
|
super(shareLinkInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<String> parse() {
|
||||||
|
String shareUrl = shareLinkInfo.getStandardUrl();
|
||||||
|
clientNoRedirects.getAbs(shareUrl).send().onSuccess(res -> {
|
||||||
|
String locationURL = res.headers().get("Location");
|
||||||
|
String substring = locationURL.substring(locationURL.indexOf("id="));
|
||||||
|
String id = substring.substring("id=".length(), substring.indexOf('&'));
|
||||||
|
clientNoRedirects.getAbs(UriTemplate.of(API_URL)).setTemplateParam("id", id).send()
|
||||||
|
.onSuccess(res2 -> {
|
||||||
|
promise.complete(res2.headers().get("Location"));
|
||||||
|
}).onFailure(handleFail(API_URL.replace("{id}", id)));
|
||||||
|
}).onFailure(handleFail(shareUrl));
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -193,7 +193,7 @@ export default {
|
|||||||
this.showQrc = false
|
this.showQrc = false
|
||||||
this.respData = {}
|
this.respData = {}
|
||||||
this.tjData = {}
|
this.tjData = {}
|
||||||
if (!this.link.startsWith("https://")) {
|
if (!this.link.startsWith("https://") && !this.link.startsWith("http://")) {
|
||||||
this.$message.error("请输入有效链接!")
|
this.$message.error("请输入有效链接!")
|
||||||
throw new Error('请输入有效链接')
|
throw new Error('请输入有效链接')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,15 +52,16 @@ public class CacheManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 写入网盘厂商API解析次数
|
// 写入网盘厂商API解析次数
|
||||||
public Future<Integer> updateTotalByCached(String shareKey) {
|
public Future<Integer> updateTotalByField(String shareKey, CacheTotalField field) {
|
||||||
Promise<Integer> promise = Promise.promise();
|
Promise<Integer> promise = Promise.promise();
|
||||||
|
String fieldLower = field.name().toLowerCase();
|
||||||
String sql = """
|
String sql = """
|
||||||
MERGE INTO `api_statistics_info` (`pan_type`, `share_key`, `cache_hit_total`, `update_ts`)
|
MERGE INTO `api_statistics_info` (`pan_type`, `share_key`, `{field}`, `update_ts`)
|
||||||
KEY (`share_key`)
|
KEY (`share_key`)
|
||||||
VALUES (#{panType}, #{shareKey}, #{total}, #{ts})
|
VALUES (#{panType}, #{shareKey}, #{total}, #{ts})
|
||||||
""";
|
""".replace("field", fieldLower);
|
||||||
|
|
||||||
getShareKeyTotal(shareKey, "cache_hit_total").onSuccess(total -> {
|
getShareKeyTotal(shareKey, fieldLower).onSuccess(total -> {
|
||||||
Integer newTotal = (total == null ? 0 : total) + 1;
|
Integer newTotal = (total == null ? 0 : total) + 1;
|
||||||
SqlTemplate.forUpdate(jdbcPool, sql)
|
SqlTemplate.forUpdate(jdbcPool, sql)
|
||||||
.execute(new HashMap<>() {{
|
.execute(new HashMap<>() {{
|
||||||
@@ -81,30 +82,6 @@ public class CacheManager {
|
|||||||
return fullShareKey.split(":")[0];
|
return fullShareKey.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 写入网盘厂商API解析次数
|
|
||||||
public Future<Integer> updateTotalByParser(String shareKey) {
|
|
||||||
Promise<Integer> promise = Promise.promise();
|
|
||||||
String sql = """
|
|
||||||
MERGE INTO `api_statistics_info` (`pan_type`, `share_key`, `api_parser_total`, `update_ts`)
|
|
||||||
KEY (`share_key`)
|
|
||||||
VALUES (#{panType}, #{shareKey}, #{total}, #{ts})
|
|
||||||
""";
|
|
||||||
|
|
||||||
getShareKeyTotal(shareKey, "api_parser_total").onSuccess(total -> {
|
|
||||||
Integer newTotal = (total == null ? 0 : total) + 1;
|
|
||||||
SqlTemplate.forUpdate(jdbcPool, sql)
|
|
||||||
.execute(new HashMap<>() {{
|
|
||||||
put("panType", getShareType(shareKey));
|
|
||||||
put("shareKey", shareKey);
|
|
||||||
put("total", newTotal);
|
|
||||||
put("ts", System.currentTimeMillis());
|
|
||||||
}})
|
|
||||||
.onSuccess(res -> promise.complete(res.rowCount()))
|
|
||||||
.onFailure(Throwable::printStackTrace);
|
|
||||||
});
|
|
||||||
return promise.future();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<Integer> getShareKeyTotal(String shareKey, String name) {
|
public Future<Integer> getShareKeyTotal(String shareKey, String name) {
|
||||||
String sql = """
|
String sql = """
|
||||||
select `share_key`, sum({total_name}) sum_num
|
select `share_key`, sum({total_name}) sum_num
|
||||||
|
|||||||
10
web-service/src/main/java/cn/qaiu/lz/common/cache/CacheTotalField.java
vendored
Normal file
10
web-service/src/main/java/cn/qaiu/lz/common/cache/CacheTotalField.java
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package cn.qaiu.lz.common.cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存字段
|
||||||
|
*/
|
||||||
|
public enum CacheTotalField {
|
||||||
|
API_PARSER_TOTAL, // 解析次数
|
||||||
|
CACHE_HIT_TOTAL, // 缓存次数
|
||||||
|
FAILED_TOTAL // 解析失败次数
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package cn.qaiu.lz.web.service.impl;
|
|||||||
import cn.qaiu.entity.ShareLinkInfo;
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.lz.common.cache.CacheConfigLoader;
|
import cn.qaiu.lz.common.cache.CacheConfigLoader;
|
||||||
import cn.qaiu.lz.common.cache.CacheManager;
|
import cn.qaiu.lz.common.cache.CacheManager;
|
||||||
|
import cn.qaiu.lz.common.cache.CacheTotalField;
|
||||||
import cn.qaiu.lz.web.model.CacheLinkInfo;
|
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;
|
||||||
@@ -46,12 +47,12 @@ public class CacheServiceImpl implements CacheService {
|
|||||||
"shareKey", cacheKey
|
"shareKey", cacheKey
|
||||||
));
|
));
|
||||||
cacheManager.cacheShareLink(cacheLinkInfo).onFailure(Throwable::printStackTrace);
|
cacheManager.cacheShareLink(cacheLinkInfo).onFailure(Throwable::printStackTrace);
|
||||||
cacheManager.updateTotalByParser(cacheKey).onFailure(Throwable::printStackTrace);
|
cacheManager.updateTotalByField(cacheKey, CacheTotalField.API_PARSER_TOTAL).onFailure(Throwable::printStackTrace);
|
||||||
}).onFailure(promise::fail);
|
}).onFailure(promise::fail);
|
||||||
} else {
|
} else {
|
||||||
result.setExpires(generateDate(result.getExpiration()));
|
result.setExpires(generateDate(result.getExpiration()));
|
||||||
promise.complete(result);
|
promise.complete(result);
|
||||||
cacheManager.updateTotalByCached(cacheKey).onFailure(Throwable::printStackTrace);
|
cacheManager.updateTotalByField(cacheKey, CacheTotalField.CACHE_HIT_TOTAL).onFailure(Throwable::printStackTrace);
|
||||||
}
|
}
|
||||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||||
return promise.future();
|
return promise.future();
|
||||||
|
|||||||
@@ -54,8 +54,9 @@ cache:
|
|||||||
iz: 20
|
iz: 20
|
||||||
le: 2879
|
le: 2879
|
||||||
lz: 20
|
lz: 20
|
||||||
qq: 999999
|
qq: 9999999
|
||||||
ws:
|
ws:
|
||||||
ye:
|
ye:
|
||||||
|
mne: 30
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
11
web-service/src/main/resources/http-tools/pan-mne.http
Normal file
11
web-service/src/main/resources/http-tools/pan-mne.http
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#@no-redirect
|
||||||
|
# https://y.music.163.com/m/song?id=472194327&uct2=qzCghKR6RWwXkHGVOZeRrg%3D%3D&fx-wechatnew=t1&fx-wxqd=c&fx-wordtest=&fx-listentest=t3&H5_DownloadVIPGift=&playerUIModeId=76001&PlayerStyles_SynchronousSharing=t3&dlt=0846&app_version=9.1.78&sc=wm&tn=
|
||||||
|
http://163cn.tv/ykLZJJT
|
||||||
|
|
||||||
|
###
|
||||||
|
#@no-redirect
|
||||||
|
https://music.163.com/song?id=233334
|
||||||
|
|
||||||
|
###
|
||||||
|
#@no-redirect
|
||||||
|
https://music.163.com/song/media/outer/url?id=233334
|
||||||
@@ -195,6 +195,11 @@ GET http://127.0.0.1:6401/json/parser?url=https://iwx.mail.qq.com/ftn/download?f
|
|||||||
GET http://127.0.0.1:6401/parser?url=https://474b.com/file/4015376-131945810
|
GET http://127.0.0.1:6401/parser?url=https://474b.com/file/4015376-131945810
|
||||||
|
|
||||||
|
|
||||||
|
### PASS MNE
|
||||||
|
# @no-redirect
|
||||||
|
GET http://127.0.0.1:6401/parser?url=http://163cn.tv/ykLZJJT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### n1
|
### n1
|
||||||
http://127.0.0.1:6401/n1/statisticsInfo
|
http://127.0.0.1:6401/n1/statisticsInfo
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ proxy:
|
|||||||
# 1.origin代理地址端口后有目录(包括 / ),转发后地址:代理地址+访问URL目录部分去除location匹配目录
|
# 1.origin代理地址端口后有目录(包括 / ),转发后地址:代理地址+访问URL目录部分去除location匹配目录
|
||||||
# 2.origin代理地址端口后无任何,转发后地址:代理地址+访问URL目录部
|
# 2.origin代理地址端口后无任何,转发后地址:代理地址+访问URL目录部
|
||||||
location:
|
location:
|
||||||
- path: ~^/(json/|v2/|parser|ye/|lz/|cow/|ec/|fj/|fc/|le/|qq/|ws/|iz/|ce/).*
|
- path: ~^/(json/|v2/|parser|ye/|lz/|cow/|ec/|fj/|fc/|le/|qq/|ws/|iz/|ce|mne/).*
|
||||||
origin: 127.0.0.1:6400
|
origin: 127.0.0.1:6400
|
||||||
|
|
||||||
# json/parser -> xxx/parser
|
# json/parser -> xxx/parser
|
||||||
|
|||||||
Reference in New Issue
Block a user