From b78a8300c677ba76aa478ff20d4322de050c8a9a Mon Sep 17 00:00:00 2001 From: QAIU <736226400@qq.com> Date: Fri, 4 Aug 2023 17:49:30 +0800 Subject: [PATCH] 0 --- .../cn/qaiu/lz/common/parser/IPanTool.java | 10 +-- .../cn/qaiu/lz/common/parser/PanBase.java | 37 +++++++++++ .../cn/qaiu/lz/common/parser/impl/YeTool.java | 65 +++++++++---------- .../cn/qaiu/lz/common/util/JsExecUtils.java | 27 +++++--- .../src/main/resources/http-tools/test.http | 2 +- 5 files changed, 89 insertions(+), 52 deletions(-) create mode 100644 web-service/src/main/java/cn/qaiu/lz/common/parser/PanBase.java diff --git a/web-service/src/main/java/cn/qaiu/lz/common/parser/IPanTool.java b/web-service/src/main/java/cn/qaiu/lz/common/parser/IPanTool.java index 39d1c16..f2f5bb3 100644 --- a/web-service/src/main/java/cn/qaiu/lz/common/parser/IPanTool.java +++ b/web-service/src/main/java/cn/qaiu/lz/common/parser/IPanTool.java @@ -4,16 +4,16 @@ import cn.qaiu.lz.common.parser.impl.*; import io.vertx.core.Future; public interface IPanTool { - Future parse(String data, String code); + Future parse(); - static IPanTool typeMatching(String type) { + static IPanTool typeMatching(String type, String key, String pwd) { return switch (type) { case "lz" -> new LzTool(); case "cow" -> new CowTool(); case "ec" -> new EcTool(); case "fc" -> new FcTool(); case "uc" -> new UcTool(); - case "ye" -> new YeTool(); + case "ye" -> new YeTool(key, pwd); case "fj" -> new FjTool(); default -> { throw new IllegalArgumentException("未知分享类型"); @@ -21,7 +21,7 @@ public interface IPanTool { }; } - static IPanTool shareURLPrefixMatching(String url) { + static IPanTool shareURLPrefixMatching(String url, String pwd) { if (url.startsWith(CowTool.SHARE_URL_PREFIX)) { return new CowTool(); @@ -32,7 +32,7 @@ public interface IPanTool { } else if (url.startsWith(UcTool.SHARE_URL_PREFIX)) { return new UcTool(); } else if (url.startsWith(YeTool.SHARE_URL_PREFIX)) { - return new YeTool(); + return new YeTool(url, pwd); } else if (url.startsWith(FjTool.SHARE_URL_PREFIX)) { return new FjTool(); } else if (url.contains("lanzou")) { diff --git a/web-service/src/main/java/cn/qaiu/lz/common/parser/PanBase.java b/web-service/src/main/java/cn/qaiu/lz/common/parser/PanBase.java new file mode 100644 index 0000000..18fde70 --- /dev/null +++ b/web-service/src/main/java/cn/qaiu/lz/common/parser/PanBase.java @@ -0,0 +1,37 @@ +package cn.qaiu.lz.common.parser; + +import io.vertx.core.Handler; +import io.vertx.core.Promise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class PanBase { + + protected Promise promise = Promise.promise(); + protected Logger log = LoggerFactory.getLogger(this.getClass()); + + 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) { + String s = String.format(errorMsg.replaceAll("\\{}", "%s"), args); + log.error("解析异常: " + s, t.fillInStackTrace()); + promise.fail(this.getClass().getSimpleName() + ": 解析异常: " + s + " -> " + t); + } + + protected void fail(String errorMsg, Object... args) { + String s = String.format(errorMsg.replaceAll("\\{}", "%s"), args); + log.error("解析异常: " + s); + promise.fail(this.getClass().getSimpleName() + " - 解析异常: " + s); + } + + protected Handler handleFail(String errorMsg) { + return t -> fail(this.getClass().getSimpleName() + " - 请求异常 {}: -> {}", errorMsg, t.fillInStackTrace()); + } + +} diff --git a/web-service/src/main/java/cn/qaiu/lz/common/parser/impl/YeTool.java b/web-service/src/main/java/cn/qaiu/lz/common/parser/impl/YeTool.java index ded013d..6650573 100644 --- a/web-service/src/main/java/cn/qaiu/lz/common/parser/impl/YeTool.java +++ b/web-service/src/main/java/cn/qaiu/lz/common/parser/impl/YeTool.java @@ -1,22 +1,18 @@ package cn.qaiu.lz.common.parser.impl; 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.JsExecUtils; import cn.qaiu.lz.common.util.PanExceptionUtils; import cn.qaiu.vx.core.util.VertxHolder; import io.vertx.core.Future; -import io.vertx.core.Promise; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.client.WebClient; import io.vertx.uritemplate.UriTemplate; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.openjdk.nashorn.api.scripting.ScriptObjectMirror; -import javax.script.ScriptException; -import java.io.IOException; import java.net.MalformedURLException; import java.util.Base64; import java.util.Map; @@ -26,8 +22,8 @@ import java.util.regex.Pattern; /** * 123网盘 */ -@Slf4j -public class YeTool implements IPanTool { +public class YeTool extends PanBase implements IPanTool { + public static final String SHARE_URL_PREFIX = "https://www.123pan.com/s/"; public static final String FIRST_REQUEST_URL = SHARE_URL_PREFIX + "{key}.html"; /* @@ -45,10 +41,13 @@ public class YeTool implements IPanTool { "&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event=homeListFile&operateType=1"; private static final String DOWNLOAD_API_URL = "https://www.123pan.com/b/api/share/download/info?{authK}={authV}"; - public Future parse(String data, String code) { + public YeTool(String key, String pwd) { + super(key, pwd); + } - String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data); - Promise promise = Promise.promise(); + public Future parse() { + + String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, key); WebClient client = WebClient.create(VertxHolder.getVertxInstance()); client.getAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("key", dataKey).send().onSuccess(res -> { @@ -58,7 +57,7 @@ public class YeTool implements IPanTool { Matcher matcher = compile.matcher(html); if (!matcher.find()) { - promise.fail(html + "\n Ye: " + dataKey + " 正则匹配失败"); + fail(html + "\n Ye: " + dataKey + " 正则匹配失败"); return; } String fileInfoString = matcher.group(1); @@ -67,45 +66,45 @@ public class YeTool implements IPanTool { JsonObject resListJson = fileInfoJson.getJsonObject("reslist"); if (resJson == null || resJson.getInteger("code") != 0) { - promise.fail(dataKey + " 解析到异常JSON: " + resJson); + fail(dataKey + " 解析到异常JSON: " + resJson); return; } String shareKey = resJson.getJsonObject("data").getString("ShareKey"); if (resListJson == null || resListJson.getInteger("code") != 0) { // 加密分享 - if (StringUtils.isNotEmpty(code)) { + if (StringUtils.isNotEmpty(pwd)) { client.getAbs(UriTemplate.of(GET_FILE_INFO_URL)) .setTemplateParam("shareKey", shareKey) - .setTemplateParam("pwd", code) + .setTemplateParam("pwd", pwd) // .setTemplateParam("authKey", AESUtils.getAuthKey("/b/api/share/get")) .putHeader("Platform", "web") .putHeader("App-Version", "3") .send().onSuccess(res2 -> { JsonObject infoJson = res2.bodyAsJsonObject(); if (infoJson.getInteger("code") != 0) { - promise.fail("Ye: " + dataKey + " 状态码异常" + infoJson); + fail("{} 状态码异常 {}", dataKey, infoJson); return; } JsonObject getFileInfoJson = infoJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0); getFileInfoJson.put("ShareKey", shareKey); - getDownUrl(promise, client, getFileInfoJson); - }).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", dataKey, t))); + getDownUrl(client, getFileInfoJson); + }).onFailure(this.handleFail("获取文件信息失败")); } else { - promise.fail(dataKey + " 该分享需要密码"); + fail(dataKey + " 该分享需要密码"); } return; } JsonObject reqBodyJson = resListJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0); reqBodyJson.put("ShareKey", shareKey); - getDownUrl(promise, client, reqBodyJson); - }).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", dataKey, t))); + getDownUrl(client, reqBodyJson); + }).onFailure(this.handleFail("")); return promise.future(); } - private static void getDownUrl(Promise promise, WebClient client, JsonObject reqBodyJson) { + private void getDownUrl(WebClient client, JsonObject reqBodyJson) { log.info(reqBodyJson.encodePrettily()); JsonObject jsonObject = new JsonObject(); // {"ShareKey":"iaKtVv-6OECd","FileID":2193732,"S3keyFlag":"1811834632-0","Size":4203111, @@ -120,12 +119,8 @@ public class YeTool implements IPanTool { ScriptObjectMirror getSign; try { getSign = JsExecUtils.executeJs("getSign", "/b/api/share/download/info"); - } catch (ScriptException | IOException | NoSuchMethodException e) { - promise.fail(e); - return; - } - if (getSign == null) { - promise.fail(ArrayUtils.toString(getSign)); + } catch (Exception e) { + fail(e, "JS函数执行异常"); return; } log.info("ye getSign: {}={}", getSign.get("0").toString(), getSign.get("1").toString()); @@ -140,11 +135,11 @@ public class YeTool implements IPanTool { try { if (downURLJson.getInteger("code") != 0) { - promise.fail("Ye: downURLJson返回值异常->" + downURLJson); + fail("Ye: downURLJson返回值异常->" + downURLJson); return; } } catch (Exception ignored) { - promise.fail("Ye: downURLJson格式异常->" + downURLJson); + fail("Ye: downURLJson格式异常->" + downURLJson); return; } String downURL = downURLJson.getJsonObject("data").getString("DownloadURL"); @@ -159,23 +154,21 @@ public class YeTool implements IPanTool { JsonObject res3Json = res3.bodyAsJsonObject(); try { if (res3Json.getInteger("code") != 0) { - promise.fail("Ye: downUrl2返回值异常->" + res3Json); + fail("Ye: downUrl2返回值异常->" + res3Json); return; } } catch (Exception ignored) { - promise.fail("Ye: downUrl2格式异常->" + downURLJson); + fail("Ye: downUrl2格式异常->" + downURLJson); return; } promise.complete(res3Json.getJsonObject("data").getString("redirect_url")); - }).onFailure(t -> promise.fail(PanExceptionUtils.fillRunTimeException("Ye", - reqBodyJson.encodePrettily(), t))); + }).onFailure(this.handleFail("获取直链失败")); } 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); } } diff --git a/web-service/src/main/java/cn/qaiu/lz/common/util/JsExecUtils.java b/web-service/src/main/java/cn/qaiu/lz/common/util/JsExecUtils.java index cbcc3a3..501598e 100644 --- a/web-service/src/main/java/cn/qaiu/lz/common/util/JsExecUtils.java +++ b/web-service/src/main/java/cn/qaiu/lz/common/util/JsExecUtils.java @@ -6,6 +6,7 @@ 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; @@ -17,26 +18,32 @@ import java.net.URL; */ public class JsExecUtils { private static final String JS_PATH = "/js/ye123.js"; + private static Invocable inv; - /** - * 调用js文件 - */ - public static ScriptObjectMirror executeJs(String functionName, Object... args) throws ScriptException, - IOException, NoSuchMethodException { + // 初始化脚本引擎 + static { ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎 //获取文件所在的相对路径 URL resource = JsExecUtils.class.getResource("/"); if (resource == null) { - throw new ScriptException("js resource path is null"); + throw new RuntimeException("js resource path is null"); } String path = resource.getPath(); String reader = path + JS_PATH; - FileReader fReader = new FileReader(reader); - engine.eval(fReader); - fReader.close(); + try (FileReader fReader = new FileReader(reader)){ + engine.eval(fReader); + fReader.close(); + inv = (Invocable) engine; + } catch (IOException | ScriptException e) { + throw new RuntimeException(e); + } + } - Invocable inv = (Invocable) engine; + /** + * 调用js文件 + */ + public static ScriptObjectMirror executeJs(String functionName, Object... args) throws ScriptException, NoSuchMethodException { //调用js中的方法 return (ScriptObjectMirror) inv.invokeFunction(functionName, args); } diff --git a/web-service/src/main/resources/http-tools/test.http b/web-service/src/main/resources/http-tools/test.http index ad85cdf..087be62 100644 --- a/web-service/src/main/resources/http-tools/test.http +++ b/web-service/src/main/resources/http-tools/test.http @@ -91,7 +91,7 @@ GET http://127.0.0.1:6400/ye/iaKtVv-qOECd ### 123 # @no-redirect -GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&pwd=DcGe +GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&pwd=DcGeasd ### POST http://127.0.0.1:6400/login1