From 23db0563ac94c322a7c45a65c4d2e53885de6582 Mon Sep 17 00:00:00 2001 From: QAIU <736226400@qq.com> Date: Fri, 7 Feb 2025 19:27:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E4=BB=B6=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E8=A7=A3=E6=9E=90=E6=8E=A5=E5=8F=A3/v2/getFileList=3F?= =?UTF-8?q?url=3D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/qaiu/entity/FileInfo.java | 61 ++++++-- .../main/java/cn/qaiu/parser/IPanTool.java | 24 ++++ .../main/java/cn/qaiu/parser/impl/FjTool.java | 94 ++++++++++++- .../main/java/cn/qaiu/parser/impl/IzTool.java | 72 +++++++++- .../main/java/cn/qaiu/parser/impl/LzTool.java | 133 ++++++++++++++---- .../src/main/java/cn/qaiu/util/CastUtil.java | 18 +++ .../java/cn/qaiu/util/FileSizeConverter.java | 35 +++++ .../src/main/java/cn/qaiu/util/JsContent.java | 15 +- .../cn/qaiu/lz/web/controller/ParserApi.java | 9 +- .../lz/web/service/impl/UserServiceImpl.java | 10 +- web-service/src/main/resources/app-dev.yml | 32 ++--- 11 files changed, 428 insertions(+), 75 deletions(-) create mode 100644 parser/src/main/java/cn/qaiu/util/CastUtil.java create mode 100644 parser/src/main/java/cn/qaiu/util/FileSizeConverter.java diff --git a/parser/src/main/java/cn/qaiu/entity/FileInfo.java b/parser/src/main/java/cn/qaiu/entity/FileInfo.java index 33a7bf5..b226020 100644 --- a/parser/src/main/java/cn/qaiu/entity/FileInfo.java +++ b/parser/src/main/java/cn/qaiu/entity/FileInfo.java @@ -7,57 +7,61 @@ public class FileInfo { /** * 文件名 */ - String fileName; + private String fileName; /** * 文件ID */ - String fileId; + private String fileId; + + private String fileIcon; /** * 文件大小(byte) */ - Long size; + private Long size; + + private String sizeStr; /** * 类型 */ - String fileType; + private String fileType; /** * 文件路径 */ - String filePath; + private String filePath; /** * 创建(上传)时间 yyyy-MM-dd HH:mm:ss格式 */ - String createTime; + private String createTime; /** * 上次修改时间 */ - String updateTime; + private String updateTime; /** * 创建者 */ - String createBy; + private String createBy; /** * 文件描述 */ - String description; + private String description; /** * 下载次数 */ - Integer downloadCount; + private Integer downloadCount; /** * 扩展参数 */ - Map extParameters; + private Map extParameters;; public String getFileName() { return fileName; @@ -86,6 +90,15 @@ public class FileInfo { return this; } + public String getSizeStr() { + return sizeStr; + } + + public FileInfo setSizeStr(String sizeStr) { + this.sizeStr = sizeStr; + return this; + } + public String getFileType() { return fileType; } @@ -157,4 +170,30 @@ public class FileInfo { this.extParameters = extParameters; return this; } + + public String getFileIcon() { + return fileIcon; + } + + public FileInfo setFileIcon(String fileIcon) { + this.fileIcon = fileIcon; + return this; + } + + @Override + public String toString() { + return "FileInfo{" + + "fileName='" + fileName + '\'' + + ", fileId='" + fileId + '\'' + + ", size=" + size + + ", fileType='" + fileType + '\'' + + ", filePath='" + filePath + '\'' + + ", createTime='" + createTime + '\'' + + ", updateTime='" + updateTime + '\'' + + ", createBy='" + createBy + '\'' + + ", description='" + description + '\'' + + ", downloadCount=" + downloadCount + + ", extParameters=" + extParameters + + '}'; + } } diff --git a/parser/src/main/java/cn/qaiu/parser/IPanTool.java b/parser/src/main/java/cn/qaiu/parser/IPanTool.java index 63ec362..1fefa93 100644 --- a/parser/src/main/java/cn/qaiu/parser/IPanTool.java +++ b/parser/src/main/java/cn/qaiu/parser/IPanTool.java @@ -1,6 +1,10 @@ package cn.qaiu.parser;//package cn.qaiu.lz.common.parser; +import cn.qaiu.entity.FileInfo; import io.vertx.core.Future; +import io.vertx.core.Promise; + +import java.util.List; public interface IPanTool { Future parse(); @@ -8,4 +12,24 @@ public interface IPanTool { default String parseSync() { return parse().toCompletionStage().toCompletableFuture().join(); } + + /** + * 解析文件列表 + * @return List + */ + default Future> parseFileList() { + Promise> promise = Promise.promise(); + promise.complete(); + return promise.future(); + } + + /** + * 根据文件ID获取下载链接 + * @return url + */ + default Future parseById(String id) { + Promise promise = Promise.promise(); + promise.complete(); + return promise.future(); + } } diff --git a/parser/src/main/java/cn/qaiu/parser/impl/FjTool.java b/parser/src/main/java/cn/qaiu/parser/impl/FjTool.java index b67a862..5f67ad4 100644 --- a/parser/src/main/java/cn/qaiu/parser/impl/FjTool.java +++ b/parser/src/main/java/cn/qaiu/parser/impl/FjTool.java @@ -1,12 +1,16 @@ package cn.qaiu.parser.impl; +import cn.qaiu.entity.FileInfo; import cn.qaiu.entity.ShareLinkInfo; import cn.qaiu.parser.PanBase; import cn.qaiu.util.AESUtils; +import cn.qaiu.util.FileSizeConverter; import cn.qaiu.util.UUIDUtil; import io.vertx.core.Future; import io.vertx.core.MultiMap; +import io.vertx.core.Promise; import io.vertx.core.buffer.Buffer; +import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.client.HttpRequest; import io.vertx.uritemplate.UriTemplate; @@ -16,6 +20,8 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import java.util.zip.GZIPInputStream; /** @@ -42,8 +48,19 @@ public class FjTool extends PanBase { "={uuid}&extra=2×tamp={ts}"; // https://api.feijipan.com/ws/buy/vip/list?devType=6&devModel=Chrome&uuid=WQAl5yBy1naGudJEILBvE&extra=2×tamp=E2C53155F6D09417A27981561134CB73 + // https://api.feijipan.com/ws/share/list?devType=6&devModel=Chrome&uuid=pwRWqwbk1J-KMTlRZowrn&extra=2×tamp=C5F8A68C53121AB21FA35BA3529E8758&shareId=fmAuOh3m&folderId=28986333&offset=1&limit=60 + + private static final String FILE_LIST_URL = API_URL_PREFIX + "/share/list?devType=6&devModel=Chrome&uuid" + + "={uuid}&extra=2×tamp={ts}&shareId={shareId}&folderId" + + "={folderId}&offset=1&limit=60"; + private static final MultiMap header; + + long nowTs = System.currentTimeMillis(); + String tsEncode = AESUtils.encrypt2Hex(Long.toString(nowTs)); + String uuid = UUIDUtil.fjUuid(); // 也可以使用 UUID.randomUUID().toString() + static { header = MultiMap.caseInsensitiveMultiMap(); header.set("Accept", "application/json, text/plain, */*"); @@ -71,13 +88,10 @@ public class FjTool extends PanBase { } public Future parse() { - final String dataKey = shareLinkInfo.getShareKey(); // 240530 此处shareId又改为了原始的shareId - String shareId = dataKey; // String.valueOf(AESUtils.idEncrypt(dataKey)); - long nowTs = System.currentTimeMillis(); - String tsEncode = AESUtils.encrypt2Hex(Long.toString(nowTs)); - String uuid = UUIDUtil.fjUuid(); // 也可以使用 UUID.randomUUID().toString() + // String.valueOf(AESUtils.idEncrypt(dataKey)); + final String shareId = shareLinkInfo.getShareKey(); // 24.5.12 飞机盘 规则修改 需要固定UUID先请求会员接口, 再请求后续接口 client.postAbs(UriTemplate.of(VIP_REQUEST_URL)) @@ -132,6 +146,13 @@ public class FjTool extends PanBase { } // 文件Id JsonObject fileInfo = resJson.getJsonArray("list").getJsonObject(0); + // 如果是目录返回目录ID + JsonObject fileList = fileInfo.getJsonArray("fileList").getJsonObject(0); + if (fileList.getInteger("fileType") == 2) { + promise.complete(fileList.getInteger("folderId").toString()); + return; + } + String fileId = fileInfo.getString("fileIds"); String userId = fileInfo.getString("userId"); // 其他参数 @@ -148,7 +169,7 @@ public class FjTool extends PanBase { .setTemplateParam("uuid", uuid) .setTemplateParam("ts", tsEncode2) .setTemplateParam("auth", auth) - .setTemplateParam("dataKey", dataKey); + .setTemplateParam("dataKey", shareId); System.out.println(httpRequest.toString()); httpRequest.send().onSuccess(res2 -> { MultiMap headers = res2.headers(); @@ -164,4 +185,65 @@ public class FjTool extends PanBase { return promise.future(); } + + @Override + public Future> parseFileList() { + Promise> promise = Promise.promise(); + + String shareId = shareLinkInfo.getShareKey(); // String.valueOf(AESUtils.idEncrypt(dataKey)); + parse().onSuccess(id -> { + // 拿到目录ID + client.postAbs(UriTemplate.of(FILE_LIST_URL)) + .putHeaders(header) + .setTemplateParam("shareId", shareId) + .setTemplateParam("uuid", uuid) + .setTemplateParam("ts", tsEncode) + .setTemplateParam("folderId", id) + .send().onSuccess(res -> { + JsonObject jsonObject = asJson(res); + System.out.println(jsonObject.encodePrettily()); + /* + { + "iconId" : 13, + "fileName" : "酷我音乐车机版 6.4.2.20.apk", + "fileSaves" : 52, + "fileStars" : 5.0, + "type" : 1, + "userId" : 1392902, + "fileComments" : 0, + "fileSize" : 68854, + "fileIcon" : "https://d.feijix.com/storage/files/icon/2024/06/08/7/8146637/6534494874910391.gz?t=67a5ea7c&rlimit=20&us=nMfuftjBN5&sign=f72be03007a301217f90dcc20333bd9a", + "updTime" : "2024-06-10 17:26:53", + "sortId" : 1487918143, + "name" : "酷我音乐车机版 6.4.2.20.apk", + "fileDownloads" : 109, + "fileUrl" : null, + "fileLikes" : 0, + "fileType" : 1, + "fileId" : 1487918143 + } + */ + JsonArray list = jsonObject.getJsonArray("list"); + ArrayList result = new ArrayList<>(); + list.forEach(item->{ + JsonObject fileJson = (JsonObject) item; + FileInfo fileInfo = new FileInfo(); + // 映射已知字段 + 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"))) + .setCreateBy(fileJson.getLong("userId").toString()) + .setDownloadCount(fileJson.getInteger("fileDownloads")) + .setCreateTime(fileJson.getString("updTime")) + .setFileIcon(fileJson.getString("fileIcon")); + result.add(fileInfo); + }); + promise.complete(result); + }); + }); + return promise.future(); + } } diff --git a/parser/src/main/java/cn/qaiu/parser/impl/IzTool.java b/parser/src/main/java/cn/qaiu/parser/impl/IzTool.java index d69148a..e409d10 100644 --- a/parser/src/main/java/cn/qaiu/parser/impl/IzTool.java +++ b/parser/src/main/java/cn/qaiu/parser/impl/IzTool.java @@ -1,13 +1,20 @@ package cn.qaiu.parser.impl; +import cn.qaiu.entity.FileInfo; import cn.qaiu.entity.ShareLinkInfo; import cn.qaiu.parser.PanBase; import cn.qaiu.util.AESUtils; +import cn.qaiu.util.FileSizeConverter; +import cn.qaiu.util.UUIDUtil; import io.vertx.core.Future; import io.vertx.core.MultiMap; +import io.vertx.core.Promise; +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; /** @@ -27,6 +34,15 @@ public class IzTool extends PanBase { private static final String VIP_REQUEST_URL = API_URL_PREFIX + "/buy/vip/list?devType=6&devModel=Chrome&uuid" + "={uuid}&extra=2×tamp={ts}"; + + private static final String FILE_LIST_URL = API_URL_PREFIX + "/share/list?devType=6&devModel=Chrome&uuid" + + "={uuid}&extra=2×tamp={ts}&shareId={shareId}&folderId" + + "={folderId}&offset=1&limit=60"; + + long nowTs = System.currentTimeMillis(); + String tsEncode = AESUtils.encrypt2HexIz(Long.toString(nowTs)); + String uuid = UUID.randomUUID().toString(); + private static final MultiMap header; static { @@ -57,9 +73,6 @@ public class IzTool extends PanBase { public Future parse() { String shareId = shareLinkInfo.getShareKey(); - long nowTs = System.currentTimeMillis(); - String tsEncode = AESUtils.encrypt2HexIz(Long.toString(nowTs)); - String uuid = UUID.randomUUID().toString(); // 24.5.12 ilanzou改规则无需计算shareId // String shareId = String.valueOf(AESUtils.idEncryptIz(dataKey)); @@ -73,7 +86,10 @@ public class IzTool extends PanBase { .send().onSuccess(r0 -> { // 忽略res // 第一次请求 获取文件信息 // 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)) + client.postAbs(UriTemplate.of( + shareLinkInfo.getSharePassword() == null ? + FIRST_REQUEST_URL : (FIRST_REQUEST_URL + "&code=" + shareLinkInfo.getSharePassword())) + ) .putHeaders(header) .setTemplateParam("shareId", shareId) .setTemplateParam("uuid", uuid) @@ -90,6 +106,14 @@ public class IzTool extends PanBase { } // 文件Id JsonObject fileInfo = resJson.getJsonArray("list").getJsonObject(0); + + // 如果是目录返回目录ID + JsonObject fileList = fileInfo.getJsonArray("fileList").getJsonObject(0); + if (fileList.getInteger("fileType") == 2) { + promise.complete(fileList.getInteger("folderId").toString()); + return; + } + String fileId = fileInfo.getString("fileIds"); String userId = fileInfo.getString("userId"); // 其他参数 @@ -115,4 +139,44 @@ public class IzTool extends PanBase { }); return promise.future(); } + + @Override + public Future> parseFileList() { + Promise> promise = Promise.promise(); + + String shareId = shareLinkInfo.getShareKey(); // String.valueOf(AESUtils.idEncrypt(dataKey)); + parse().onSuccess(id -> { + // 拿到目录ID + client.postAbs(UriTemplate.of(FILE_LIST_URL)) + .putHeaders(header) + .setTemplateParam("shareId", shareId) + .setTemplateParam("uuid", uuid) + .setTemplateParam("ts", tsEncode) + .setTemplateParam("folderId", id) + .send().onSuccess(res -> { + JsonObject jsonObject = asJson(res); + System.out.println(jsonObject.encodePrettily()); + JsonArray list = jsonObject.getJsonArray("list"); + ArrayList result = new ArrayList<>(); + list.forEach(item->{ + JsonObject fileJson = (JsonObject) item; + FileInfo fileInfo = new FileInfo(); + // 映射已知字段 + 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"))) + .setCreateBy(fileJson.getLong("userId").toString()) + .setDownloadCount(fileJson.getInteger("fileDownloads")) + .setCreateTime(fileJson.getString("updTime")) + .setFileIcon(fileJson.getString("fileIcon")); + result.add(fileInfo); + }); + promise.complete(result); + }); + }); + return promise.future(); + } } diff --git a/parser/src/main/java/cn/qaiu/parser/impl/LzTool.java b/parser/src/main/java/cn/qaiu/parser/impl/LzTool.java index f90a5dc..bd84431 100644 --- a/parser/src/main/java/cn/qaiu/parser/impl/LzTool.java +++ b/parser/src/main/java/cn/qaiu/parser/impl/LzTool.java @@ -1,15 +1,21 @@ package cn.qaiu.parser.impl; -import cn.qaiu.entity.ShareLinkInfo; +import cn.qaiu.entity.FileInfo; +import cn.qaiu.entity.ShareLinkInfo; import cn.qaiu.parser.PanBase; +import cn.qaiu.util.CastUtil; +import cn.qaiu.util.FileSizeConverter; import cn.qaiu.util.JsExecUtils; import io.vertx.core.Future; import io.vertx.core.MultiMap; +import io.vertx.core.Promise; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.client.WebClient; import org.openjdk.nashorn.api.scripting.ScriptObjectMirror; import javax.script.ScriptException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -28,7 +34,6 @@ public class LzTool extends PanBase { super(shareLinkInfo); } - @SuppressWarnings("unchecked") public Future parse() { String sUrl = shareLinkInfo.getStandardUrl(); String pwd = shareLinkInfo.getSharePassword(); @@ -41,22 +46,10 @@ public class LzTool extends PanBase { Matcher matcher = compile.matcher(html); // 没有Iframe说明是加密分享, 匹配sign通过密码请求下载页面 if (!matcher.find()) { - // 处理一下JS - String jsText = getJsText(html); - - if (jsText == null) { - fail(SHARE_URL_PREFIX + " -> " + sUrl + ": js脚本匹配失败, 可能分享已失效"); - return; - } - - jsText = jsText.replace("document.getElementById('pwd').value", "\"" + pwd + "\""); - int i = jsText.indexOf("document.getElementById('rpt')"); - if (i > 0) { - jsText = jsText.substring(0, i); - } try { + String jsText = getJsByPwd(pwd, html, "document.getElementById('rpt')"); ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, "down_p"); - getDownURL(sUrl, client, (Map) scriptObjectMirror.get("data")); + getDownURL(sUrl, client, CastUtil.cast(scriptObjectMirror.get("data"))); } catch (ScriptException | NoSuchMethodException e) { fail(e, "js引擎执行失败"); } @@ -75,7 +68,7 @@ public class LzTool extends PanBase { } try { ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, null); - getDownURL(sUrl, client, (Map) scriptObjectMirror.get("data")); + getDownURL(sUrl, client, CastUtil.cast(scriptObjectMirror.get("data"))); } catch (ScriptException | NoSuchMethodException e) { fail(e, "js引擎执行失败"); } @@ -85,6 +78,20 @@ public class LzTool extends PanBase { return promise.future(); } + private String getJsByPwd(String pwd, String html, String subText) { + String jsText = getJsText(html); + + if (jsText == null) { + throw new RuntimeException("js脚本匹配失败, 可能分享已失效"); + } + jsText = jsText.replace("document.getElementById('pwd').value", "\"" + pwd + "\""); + int i = jsText.indexOf(subText); + if (i > 0) { + jsText = jsText.substring(0, i); + } + return jsText; + } + private String getJsText(String html) { String jsTagStart = ""; @@ -94,23 +101,15 @@ public class LzTool extends PanBase { } int startPos = index + jsTagStart.length(); int endPos = html.indexOf(jsTagEnd, startPos); - return html.substring(startPos, endPos); + return html.substring(startPos, endPos).replaceAll("",""); } - private void getDownURL(String key, WebClient client, Map signMap) { + private void getDownURL(String key, WebClient client, Map signMap) { MultiMap map = MultiMap.caseInsensitiveMultiMap(); signMap.forEach((k, v) -> { map.set(k, v.toString()); }); - MultiMap headers = MultiMap.caseInsensitiveMultiMap(); - var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " + - "like " + - "Gecko) Chrome/111.0.0.0 Mobile Safari/537.36"; - headers.set("User-Agent", userAgent2); - headers.set("referer", key); - headers.set("sec-ch-ua-platform", "Android"); - 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"); + MultiMap headers = getHeaders(key); String url = SHARE_URL_PREFIX + "/ajaxm.php"; client.postAbs(url).putHeaders(headers).sendForm(map).onSuccess(res2 -> { @@ -125,4 +124,82 @@ public class LzTool extends PanBase { .onFailure(handleFail(downUrl)); }).onFailure(handleFail(url)); } + + private static MultiMap getHeaders(String key) { + MultiMap headers = MultiMap.caseInsensitiveMultiMap(); + var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " + + "like " + + "Gecko) Chrome/111.0.0.0 Mobile Safari/537.36"; + headers.set("User-Agent", userAgent2); + headers.set("referer", key); + headers.set("sec-ch-ua-platform", "Android"); + 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"); + return headers; + } + + + @Override + public Future> parseFileList() { + Promise> promise = Promise.promise(); + + String sUrl = shareLinkInfo.getShareUrl(); + String pwd = shareLinkInfo.getSharePassword(); + + WebClient client = clientNoRedirects; + client.getAbs(sUrl).send().onSuccess(res -> { + String html = res.bodyAsString(); + try { + String jsText = getJsByPwd(pwd, html, "var urls =window.location.href"); + ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, "file"); + Map data = CastUtil.cast(scriptObjectMirror.get("data")); + System.out.println(data); + MultiMap map = MultiMap.caseInsensitiveMultiMap(); + data.forEach((k, v) -> { + map.set(k, v.toString()); + }); + MultiMap headers = getHeaders(sUrl); + + String url = SHARE_URL_PREFIX + "/filemoreajax.php?file=" + data.get("fid"); + client.postAbs(url).putHeaders(headers).sendForm(map).onSuccess(res2 -> { + JsonObject fileListJson = asJson(res2); + if (fileListJson.getInteger("zt") != 1) { + fail(fileListJson.getString("inf")); + return; + } + List list = new ArrayList<>(); + fileListJson.getJsonArray("text").forEach(item -> { + /* + { + "icon": "apk", + "t": 0, + "id": "iULV2n4361c", + "name_all": "xx.apk", + "size": "49.8 M", + "time": "2021-03-19", + "duan": "in4361", + "p_ico": 0 + } + */ + JsonObject fileJson = (JsonObject) item; + FileInfo fileInfo = new FileInfo(); + String size = fileJson.getString("size"); + Long sizeNum = FileSizeConverter.convertToBytes(size); + fileInfo.setFileName(fileJson.getString("name_all")) + .setFileId(fileJson.getString("id")) + .setCreateTime(fileJson.getString("time")) + .setFileType(fileJson.getString("icon")) + .setSizeStr(fileJson.getString("size")) + .setSize(sizeNum); + System.out.println(fileInfo); + list.add(fileInfo); + }); + promise.complete(list); + }); + } catch (ScriptException | NoSuchMethodException e) { + promise.fail(e); + } + }); + return promise.future(); + } } diff --git a/parser/src/main/java/cn/qaiu/util/CastUtil.java b/parser/src/main/java/cn/qaiu/util/CastUtil.java new file mode 100644 index 0000000..b06efd2 --- /dev/null +++ b/parser/src/main/java/cn/qaiu/util/CastUtil.java @@ -0,0 +1,18 @@ +package cn.qaiu.util; + +/** + * 转换为任意类型 旨在消除泛型转换时的异常 + */ +public interface CastUtil { + + /** + * 泛型转换 + * @param object 要转换的object + * @param T + * @return T + */ + @SuppressWarnings("unchecked") + static T cast(Object object) { + return (T) object; + } +} diff --git a/parser/src/main/java/cn/qaiu/util/FileSizeConverter.java b/parser/src/main/java/cn/qaiu/util/FileSizeConverter.java new file mode 100644 index 0000000..48ab30c --- /dev/null +++ b/parser/src/main/java/cn/qaiu/util/FileSizeConverter.java @@ -0,0 +1,35 @@ +package cn.qaiu.util; + +public class FileSizeConverter { + + public static long convertToBytes(String sizeStr) { + if (sizeStr == null || sizeStr.isEmpty()) { + throw new IllegalArgumentException("Invalid file size string"); + } + + sizeStr = sizeStr.trim().toUpperCase(); + char unit = sizeStr.charAt(sizeStr.length() - 1); + double size = Double.parseDouble(sizeStr.substring(0, sizeStr.length() - 1)); + + return switch (unit) { + case 'B' -> (long) size; + case 'K' -> (long) (size * 1024); + case 'M' -> (long) (size * 1024 * 1024); + case 'G' -> (long) (size * 1024 * 1024 * 1024); + default -> throw new IllegalArgumentException("Unknown file size unit: " + unit); + }; + } + + public static String convertToReadableSize(long bytes) { + if (bytes < 1024) { + return bytes + " B"; + } else if (bytes < 1024 * 1024) { + return String.format("%.1f K", bytes / 1024.0); + } else if (bytes < 1024 * 1024 * 1024) { + return String.format("%.1f M", bytes / (1024.0 * 1024)); + } else { + return String.format("%.1f G", bytes / (1024.0 * 1024 * 1024)); + } + } + +} diff --git a/parser/src/main/java/cn/qaiu/util/JsContent.java b/parser/src/main/java/cn/qaiu/util/JsContent.java index 3169ea4..42c84a4 100644 --- a/parser/src/main/java/cn/qaiu/util/JsContent.java +++ b/parser/src/main/java/cn/qaiu/util/JsContent.java @@ -124,7 +124,10 @@ public interface JsContent { }, ajax: function (obj) { signObj = obj - } + }, + val: function(a) { + + }, } }, @@ -134,7 +137,6 @@ public interface JsContent { jQuery.fn.init.prototype = jQuery.fn; - // 伪装jquery.ajax函数获取关键数据 $.ajax = function (obj) { signObj = obj } @@ -142,11 +144,16 @@ public interface JsContent { var document = { getElementById: function (v) { return { - value: 'v' + value: 'v', + style: { + display: '' + }, + addEventListener: function() {} } }, } - + + var window = {location: {}} """; String kwSignString = """ diff --git a/web-service/src/main/java/cn/qaiu/lz/web/controller/ParserApi.java b/web-service/src/main/java/cn/qaiu/lz/web/controller/ParserApi.java index beb6166..20a2a09 100644 --- a/web-service/src/main/java/cn/qaiu/lz/web/controller/ParserApi.java +++ b/web-service/src/main/java/cn/qaiu/lz/web/controller/ParserApi.java @@ -1,6 +1,7 @@ package cn.qaiu.lz.web.controller; +import cn.qaiu.entity.FileInfo; import cn.qaiu.entity.ShareLinkInfo; import cn.qaiu.lz.common.cache.CacheManager; import cn.qaiu.lz.common.util.URLParamUtil; @@ -35,7 +36,7 @@ public class ParserApi { private final UserService userService = AsyncServiceUtil.getAsyncServiceInstance(UserService.class); private final DbService dbService = AsyncServiceUtil.getAsyncServiceInstance(DbService.class); - @RouteMapping(value = "/login", method = RouteMethod.POST) + @RouteMapping(value = "/login", method = RouteMethod.GET) public Future login(SysUser user) { log.info("<------- login: {}", user.getUsername()); return userService.login(user); @@ -98,4 +99,10 @@ public class ParserApi { }}).collect(Collectors.toList()); } + @RouteMapping("/getFileList") + public Future> getFileList(HttpServerRequest request, String pwd) { + String url = URLParamUtil.parserParams(request); + ParserCreate parserCreate = ParserCreate.fromShareUrl(url).setShareLinkInfoPwd(pwd); + return parserCreate.createTool().parseFileList(); + } } diff --git a/web-service/src/main/java/cn/qaiu/lz/web/service/impl/UserServiceImpl.java b/web-service/src/main/java/cn/qaiu/lz/web/service/impl/UserServiceImpl.java index 45de354..8c492e1 100644 --- a/web-service/src/main/java/cn/qaiu/lz/web/service/impl/UserServiceImpl.java +++ b/web-service/src/main/java/cn/qaiu/lz/web/service/impl/UserServiceImpl.java @@ -19,11 +19,11 @@ public class UserServiceImpl implements UserService { @Override public Future login(SysUser user) { - try { - TimeUnit.SECONDS.sleep(2); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } +// try { +// TimeUnit.SECONDS.sleep(2); +// } catch (InterruptedException e) { +// throw new RuntimeException(e); +// } return Future.succeededFuture(user); } } diff --git a/web-service/src/main/resources/app-dev.yml b/web-service/src/main/resources/app-dev.yml index 16a6588..dbc11a9 100644 --- a/web-service/src/main/resources/app-dev.yml +++ b/web-service/src/main/resources/app-dev.yml @@ -36,7 +36,7 @@ custom: # 数据源配置 dataSource: #jdbcUrl: jdbc:mysql://127.0.0.1:3306/nfddata?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false - jdbcUrl: jdbc:h2:file:./db/nfdData;MODE=MySQL;DATABASE_TO_UPPER=FALSE + jdbcUrl: jdbc:h2:file:./db/nfdData1;MODE=MySQL;DATABASE_TO_UPPER=FALSE username: root password: '123456' @@ -48,21 +48,21 @@ cache: defaultDuration: 59 # 具体网盘的缓存配置,如果不加配置则不缓存,每次请求都会请求网盘API,格式:网盘标识: 时长 duration: - ce: 5 - cow: - ec: 5 - fc: - fj: 20 - iz: 20 - le: 2879 - lz: 20 - qq: 9999999 - ws: 10 - ye: -1 - mne: 30 - mqq: 30 - mkg: 30 - p115: 5 +# ce: 5 +# cow: +# ec: 5 +# fc: +# fj: 20 +# iz: 20 +# le: 2879 +# lz: 20 +# qq: 9999999 +# ws: 10 +# ye: -1 +# mne: 30 +# mqq: 30 +# mkg: 30 +# p115: 5 # httpClient静态代理服务器配置(外网代理) proxy: