新增文件列表解析接口/redirectUrl/:type/:param

This commit is contained in:
QAIU
2025-02-10 14:19:18 +08:00
parent 0637bcfd8e
commit e07ce15228
7 changed files with 209 additions and 38 deletions

View File

@@ -58,10 +58,21 @@ public class FileInfo {
*/
private Integer downloadCount;
/**
* 网盘标识
*/
private String panType;
/**
* nfd下载链接(可能获取不到)
* note: 不是下载直链
*/
private String parserUrl;
/**
* 扩展参数
*/
private Map<String, Object> extParameters;;
private Map<String, Object> extParameters;
public String getFileName() {
return fileName;
@@ -81,6 +92,15 @@ public class FileInfo {
return this;
}
public String getFileIcon() {
return fileIcon;
}
public FileInfo setFileIcon(String fileIcon) {
this.fileIcon = fileIcon;
return this;
}
public Long getSize() {
return size;
}
@@ -162,6 +182,24 @@ public class FileInfo {
return this;
}
public String getPanType() {
return panType;
}
public FileInfo setPanType(String panType) {
this.panType = panType;
return this;
}
public String getParserUrl() {
return parserUrl;
}
public FileInfo setParserUrl(String parserUrl) {
this.parserUrl = parserUrl;
return this;
}
public Map<String, Object> getExtParameters() {
return extParameters;
}
@@ -171,15 +209,6 @@ public class FileInfo {
return this;
}
public String getFileIcon() {
return fileIcon;
}
public FileInfo setFileIcon(String fileIcon) {
this.fileIcon = fileIcon;
return this;
}
@Override
public String toString() {
return "FileInfo{" +

View File

@@ -27,7 +27,7 @@ public interface IPanTool {
* 根据文件ID获取下载链接
* @return url
*/
default Future<String> parseById(String id) {
default Future<String> parseById() {
Promise<String> promise = Promise.promise();
promise.complete();
return promise.future();

View File

@@ -233,4 +233,8 @@ public abstract class PanBase implements IPanTool {
}
}
protected String getDomainName(){
return shareLinkInfo.getOtherParam().getOrDefault("domainName", "").toString();
}
}

View File

@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.zip.GZIPInputStream;
@@ -99,8 +100,6 @@ public class FjTool extends PanBase {
.setTemplateParam("ts", tsEncode)
.send().onSuccess(r0 -> { // 忽略res
// long nowTs0 = System.currentTimeMillis();
String tsEncode0 = AESUtils.encrypt2Hex(Long.toString(nowTs));
// 第一次请求 获取文件信息
// POST https://api.feijipan.com/ws/recommend/list?devType=6&devModel=Chrome&extra=2&shareId=146731&type=0&offset=1&limit=60
client.postAbs(UriTemplate.of(FIRST_REQUEST_URL))
@@ -228,17 +227,46 @@ public class FjTool extends PanBase {
list.forEach(item->{
JsonObject fileJson = (JsonObject) item;
FileInfo fileInfo = new FileInfo();
// 映射已知字段
// 映射已知字段fileInfo
String fileId = fileJson.getString("fileId");
String userId = fileJson.getString("userId");
// 其他参数
long nowTs2 = System.currentTimeMillis();
String tsEncode2 = AESUtils.encrypt2Hex(Long.toString(nowTs2));
String fidEncode = AESUtils.encrypt2Hex(fileId + "|" + userId);
String auth = AESUtils.encrypt2Hex(fileId + "|" + nowTs2);
// 回传用到的参数
//"fidEncode", paramJson.getString("fidEncode"))
//"uuid", paramJson.getString("uuid"))
//"ts", paramJson.getString("ts"))
//"auth", paramJson.getString("auth"))
//"shareId", paramJson.getString("shareId"))
JsonObject entries = JsonObject.of(
"fidEncode", fidEncode,
"uuid", uuid,
"ts", tsEncode2,
"auth", auth,
"shareId", shareId);
byte[] encode = Base64.getEncoder().encode(entries.encode().getBytes());
String param = new String(encode);
long fileSize = fileJson.getLong("fileSize") * 1024;
fileInfo.setFileName(fileJson.getString("fileName"))
.setFileId(fileJson.getString("fileId"))
.setCreateTime(fileJson.getString("createTime"))
.setFileType(fileJson.getString("fileType"))
.setSize(fileJson.getLong("fileSize"))
.setSizeStr(FileSizeConverter.convertToReadableSize(fileJson.getLong("fileSize")))
.setSize(fileSize)
.setSizeStr(FileSizeConverter.convertToReadableSize(fileSize))
.setCreateBy(fileJson.getLong("userId").toString())
.setDownloadCount(fileJson.getInteger("fileDownloads"))
.setCreateTime(fileJson.getString("updTime"))
.setFileIcon(fileJson.getString("fileIcon"));
.setFileIcon(fileJson.getString("fileIcon"))
.setPanType(shareLinkInfo.getType())
.setParserUrl(String.format("%s/v2/redirectUrl/%s/%s", getDomainName(),
shareLinkInfo.getType(), param));
result.add(fileInfo);
});
promise.complete(result);
@@ -246,4 +274,34 @@ public class FjTool extends PanBase {
});
return promise.future();
}
@Override
public Future<String> parseById() {
// 第二次请求
JsonObject paramJson = (JsonObject)shareLinkInfo.getOtherParam().get("paramJson");
// clientNoRedirects.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
// .putHeaders(header)
// .setTemplateParam("fidEncode", fidEncode)
// .setTemplateParam("uuid", uuid)
// .setTemplateParam("ts", tsEncode2)
// .setTemplateParam("auth", auth)
// .setTemplateParam("dataKey", shareId)
clientNoRedirects.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
.setTemplateParam("fidEncode", paramJson.getString("fidEncode"))
.setTemplateParam("uuid", paramJson.getString("uuid"))
.setTemplateParam("ts", paramJson.getString("ts"))
.setTemplateParam("auth", paramJson.getString("auth"))
.setTemplateParam("dataKey", paramJson.getString("shareId"))
.putHeaders(header).send().onSuccess(res2 -> {
MultiMap headers = res2.headers();
if (!headers.contains("Location")) {
fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + res2.headers());
return;
}
promise.complete(headers.get("Location"));
}).onFailure(handleFail(SECOND_REQUEST_URL));
return promise.future();
}
}

View File

@@ -13,9 +13,7 @@ import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.uritemplate.UriTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
/**
* 蓝奏云优享
@@ -130,7 +128,7 @@ public class IzTool extends PanBase {
.putHeaders(header).send().onSuccess(res2 -> {
MultiMap headers = res2.headers();
if (!headers.contains("Location")) {
fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + res.headers());
fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + headers);
return;
}
promise.complete(headers.get("Location"));
@@ -161,17 +159,43 @@ public class IzTool extends PanBase {
list.forEach(item->{
JsonObject fileJson = (JsonObject) item;
FileInfo fileInfo = new FileInfo();
// 映射已知字段
String fileId = fileJson.getString("fileId");
String userId = fileJson.getString("userId");
// 回传用到的参数
//"fidEncode", paramJson.getString("fidEncode"))
//"uuid", paramJson.getString("uuid"))
//"ts", paramJson.getString("ts"))
//"auth", paramJson.getString("auth"))
//"shareId", paramJson.getString("shareId"))
String fidEncode = AESUtils.encrypt2HexIz(fileId + "|" + userId);
String auth = AESUtils.encrypt2HexIz(fileId + "|" + nowTs);
JsonObject entries = JsonObject.of(
"fidEncode", fidEncode,
"uuid", uuid,
"ts", tsEncode,
"auth", auth,
"shareId", shareId);
byte[] encode = Base64.getEncoder().encode(entries.encode().getBytes());
String param = new String(encode);
long fileSize = fileJson.getLong("fileSize") * 1024;
fileInfo.setFileName(fileJson.getString("fileName"))
.setFileId(fileJson.getString("fileId"))
.setFileId(fileId)
.setCreateTime(fileJson.getString("createTime"))
.setFileType(fileJson.getString("fileType"))
.setSize(fileJson.getLong("fileSize"))
.setSizeStr(FileSizeConverter.convertToReadableSize(fileJson.getLong("fileSize")))
.setSize(fileSize)
.setSizeStr(FileSizeConverter.convertToReadableSize(fileSize))
.setCreateBy(fileJson.getLong("userId").toString())
.setDownloadCount(fileJson.getInteger("fileDownloads"))
.setCreateTime(fileJson.getString("updTime"))
.setFileIcon(fileJson.getString("fileIcon"));
.setFileIcon(fileJson.getString("fileIcon"))
.setPanType(shareLinkInfo.getType())
.setParserUrl(String.format("%s/v2/redirectUrl/%s/%s", getDomainName(),
shareLinkInfo.getType(), param));
result.add(fileInfo);
});
promise.complete(result);
@@ -179,4 +203,25 @@ public class IzTool extends PanBase {
});
return promise.future();
}
@Override
public Future<String> parseById() {
// 第二次请求
JsonObject paramJson = (JsonObject)shareLinkInfo.getOtherParam().get("paramJson");
clientNoRedirects.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
.setTemplateParam("fidEncode", paramJson.getString("fidEncode"))
.setTemplateParam("uuid", paramJson.getString("uuid"))
.setTemplateParam("ts", paramJson.getString("ts"))
.setTemplateParam("auth", paramJson.getString("auth"))
.setTemplateParam("shareId", paramJson.getString("shareId"))
.putHeaders(header).send().onSuccess(res2 -> {
MultiMap headers = res2.headers();
if (!headers.contains("Location")) {
fail(SECOND_REQUEST_URL + " 未找到重定向URL: \n" + res2.headers());
return;
}
promise.complete(headers.get("Location"));
}).onFailure(handleFail(SECOND_REQUEST_URL));
return promise.future();
}
}

View File

@@ -101,14 +101,12 @@ public class LzTool extends PanBase {
}
int startPos = index + jsTagStart.length();
int endPos = html.indexOf(jsTagEnd, startPos);
return html.substring(startPos, endPos).replaceAll("<!--.*-->","");
return html.substring(startPos, endPos).replaceAll("<!--.*-->", "");
}
private void getDownURL(String key, WebClient client, Map<String, Object> signMap) {
MultiMap map = MultiMap.caseInsensitiveMultiMap();
signMap.forEach((k, v) -> {
map.set(k, v.toString());
});
signMap.forEach((k, v) -> map.set(k, v.toString()));
MultiMap headers = getHeaders(key);
String url = SHARE_URL_PREFIX + "/ajaxm.php";
@@ -155,9 +153,7 @@ public class LzTool extends PanBase {
Map<String, Object> data = CastUtil.cast(scriptObjectMirror.get("data"));
System.out.println(data);
MultiMap map = MultiMap.caseInsensitiveMultiMap();
data.forEach((k, v) -> {
map.set(k, v.toString());
});
data.forEach((k, v) -> map.set(k, v.toString()));
MultiMap headers = getHeaders(sUrl);
String url = SHARE_URL_PREFIX + "/filemoreajax.php?file=" + data.get("fid");
@@ -185,12 +181,16 @@ public class LzTool extends PanBase {
FileInfo fileInfo = new FileInfo();
String size = fileJson.getString("size");
Long sizeNum = FileSizeConverter.convertToBytes(size);
String panType = shareLinkInfo.getType();
String id = fileJson.getString("id");
fileInfo.setFileName(fileJson.getString("name_all"))
.setFileId(fileJson.getString("id"))
.setFileId(id)
.setCreateTime(fileJson.getString("time"))
.setFileType(fileJson.getString("icon"))
.setSizeStr(fileJson.getString("size"))
.setSize(sizeNum);
.setSize(sizeNum)
.setPanType(panType)
.setParserUrl(getDomainName() + "/d/" + panType + "/" + id);
System.out.println(fileInfo);
list.add(fileInfo);
});

View File

@@ -16,17 +16,17 @@ import cn.qaiu.vx.core.annotaions.RouteHandler;
import cn.qaiu.vx.core.annotaions.RouteMapping;
import cn.qaiu.vx.core.enums.RouteMethod;
import cn.qaiu.vx.core.util.AsyncServiceUtil;
import cn.qaiu.vx.core.util.ResponseUtil;
import cn.qaiu.vx.core.util.SharedDataUtil;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.*;
import java.util.stream.Collectors;
@RouteHandler(value = "/v2", order = 10)
@@ -103,6 +103,41 @@ public class ParserApi {
public Future<List<FileInfo>> getFileList(HttpServerRequest request, String pwd) {
String url = URLParamUtil.parserParams(request);
ParserCreate parserCreate = ParserCreate.fromShareUrl(url).setShareLinkInfoPwd(pwd);
String linkPrefix = SharedDataUtil.getJsonConfig("server").getString("domainName");
parserCreate.getShareLinkInfo().getOtherParam().put("domainName", linkPrefix);
return parserCreate.createTool().parseFileList();
}
// 目录解析下载文件
// @RouteMapping("/getFileDownUrl/:type/:param")
public Future<String> getFileDownUrl(String type, String param) {
ParserCreate parserCreate = ParserCreate.fromType(type).shareKey("-") // shareKey not null
.setShareLinkInfoPwd("-");
if (param.isEmpty()) {
Promise<String> promise = Promise.promise();
promise.fail("下载参数为空");
return promise.future();
}
String paramStr = new String(Base64.getDecoder().decode(param));
ShareLinkInfo shareLinkInfo = parserCreate.getShareLinkInfo();
shareLinkInfo.getOtherParam().put("paramJson", new JsonObject(paramStr));
// domainName
String linkPrefix = SharedDataUtil.getJsonConfig("server").getString("domainName");
shareLinkInfo.getOtherParam().put("domainName", linkPrefix);
return parserCreate.createTool().parseById();
}
@RouteMapping("/redirectUrl/:type/:param")
public Future<Void> redirectUrl(HttpServerResponse response, String type, String param) {
Promise<Void> promise = Promise.promise();
getFileDownUrl(type, param)
.onSuccess(res -> ResponseUtil.redirect(response, res))
.onFailure(t -> promise.fail(t.fillInStackTrace()));
return promise.future();
}
}