mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-02-03 11:56:18 +00:00
Compare commits
3 Commits
v0.1.9b20a
...
v019b21b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9fa83e57c | ||
|
|
ba4666c32a | ||
|
|
d6d37e8204 |
@@ -4,13 +4,15 @@ import cn.qaiu.entity.FileInfo;
|
|||||||
import cn.qaiu.entity.ShareLinkInfo;
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
import cn.qaiu.parser.PanBase;
|
import cn.qaiu.parser.PanBase;
|
||||||
import cn.qaiu.util.AESUtils;
|
import cn.qaiu.util.AESUtils;
|
||||||
|
import cn.qaiu.util.AcwScV2Generator;
|
||||||
import cn.qaiu.util.FileSizeConverter;
|
import cn.qaiu.util.FileSizeConverter;
|
||||||
import cn.qaiu.util.UUIDUtil;
|
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.MultiMap;
|
import io.vertx.core.MultiMap;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.ext.web.client.WebClientSession;
|
||||||
import io.vertx.uritemplate.UriTemplate;
|
import io.vertx.uritemplate.UriTemplate;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@@ -18,10 +20,12 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 蓝奏云优享
|
* 蓝奏云优享
|
||||||
*
|
* v019b22
|
||||||
*/
|
*/
|
||||||
public class IzTool extends PanBase {
|
public class IzTool extends PanBase {
|
||||||
|
|
||||||
|
WebClientSession webClientSession = WebClientSession.create(clientNoRedirects);
|
||||||
|
|
||||||
private static final String API_URL_PREFIX = "https://api.ilanzou.com/unproved/";
|
private static final String API_URL_PREFIX = "https://api.ilanzou.com/unproved/";
|
||||||
|
|
||||||
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "recommend/list?devType=6&devModel=Chrome" +
|
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "recommend/list?devType=6&devModel=Chrome" +
|
||||||
@@ -70,6 +74,19 @@ public class IzTool extends PanBase {
|
|||||||
super(shareLinkInfo);
|
super(shareLinkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setCookie(String html) {
|
||||||
|
int beginIndex = html.indexOf("arg1='") + 6;
|
||||||
|
String arg1 = html.substring(beginIndex, html.indexOf("';", beginIndex));
|
||||||
|
String acw_sc__v2 = AcwScV2Generator.acwScV2Simple(arg1);
|
||||||
|
// 创建一个 Cookie 并放入 CookieStore
|
||||||
|
DefaultCookie nettyCookie = new DefaultCookie("acw_sc__v2", acw_sc__v2);
|
||||||
|
nettyCookie.setDomain(".ilanzou.com"); // 设置域名
|
||||||
|
nettyCookie.setPath("/"); // 设置路径
|
||||||
|
nettyCookie.setSecure(false);
|
||||||
|
nettyCookie.setHttpOnly(false);
|
||||||
|
webClientSession.cookieStore().put(nettyCookie);
|
||||||
|
}
|
||||||
|
|
||||||
public Future<String> parse() {
|
public Future<String> parse() {
|
||||||
String shareId = shareLinkInfo.getShareKey();
|
String shareId = shareLinkInfo.getShareKey();
|
||||||
|
|
||||||
@@ -80,19 +97,52 @@ public class IzTool extends PanBase {
|
|||||||
// POST https://api.ilanzou.com/ws/recommend/list?devType=6&devModel=Chrome&extra=2&shareId=146731&type=0&offset=1&limit=60
|
// POST https://api.ilanzou.com/ws/recommend/list?devType=6&devModel=Chrome&extra=2&shareId=146731&type=0&offset=1&limit=60
|
||||||
String url = StringUtils.isBlank(shareLinkInfo.getSharePassword()) ? FIRST_REQUEST_URL
|
String url = StringUtils.isBlank(shareLinkInfo.getSharePassword()) ? FIRST_REQUEST_URL
|
||||||
: (FIRST_REQUEST_URL + "&code=" + shareLinkInfo.getSharePassword());
|
: (FIRST_REQUEST_URL + "&code=" + shareLinkInfo.getSharePassword());
|
||||||
client.postAbs(UriTemplate.of(VIP_REQUEST_URL))
|
webClientSession.postAbs(UriTemplate.of(VIP_REQUEST_URL))
|
||||||
.setTemplateParam("uuid", uuid)
|
.setTemplateParam("uuid", uuid)
|
||||||
.setTemplateParam("ts", tsEncode)
|
.setTemplateParam("ts", tsEncode)
|
||||||
.send().onSuccess(r0 -> { // 忽略res
|
.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
|
// 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(url))
|
webClientSession.postAbs(UriTemplate.of(url))
|
||||||
.putHeaders(header)
|
.putHeaders(header)
|
||||||
.setTemplateParam("shareId", shareId)
|
.setTemplateParam("shareId", shareId)
|
||||||
.setTemplateParam("uuid", uuid)
|
.setTemplateParam("uuid", uuid)
|
||||||
.setTemplateParam("ts", tsEncode)
|
.setTemplateParam("ts", tsEncode)
|
||||||
.send().onSuccess(res -> {
|
.send().onSuccess(res -> {
|
||||||
JsonObject resJson = asJson(res);
|
String resBody = asText(res);
|
||||||
|
// 检查是否包含 cookie 验证
|
||||||
|
if (resBody.contains("var arg1='")) {
|
||||||
|
webClientSession = WebClientSession.create(clientNoRedirects);
|
||||||
|
setCookie(resBody);
|
||||||
|
// 重新请求
|
||||||
|
webClientSession.postAbs(UriTemplate.of(url))
|
||||||
|
.putHeaders(header)
|
||||||
|
.setTemplateParam("shareId", shareId)
|
||||||
|
.setTemplateParam("uuid", uuid)
|
||||||
|
.setTemplateParam("ts", tsEncode)
|
||||||
|
.send().onSuccess(res2 -> {
|
||||||
|
handleParseResponse(asText(res2), shareId);
|
||||||
|
}).onFailure(handleFail(FIRST_REQUEST_URL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleParseResponse(resBody, shareId);
|
||||||
|
}).onFailure(handleFail(FIRST_REQUEST_URL));
|
||||||
|
});
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleParseResponse(String resBody, String shareId) {
|
||||||
|
JsonObject resJson;
|
||||||
|
try {
|
||||||
|
resJson = new JsonObject(resBody);
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(FIRST_REQUEST_URL + " 解析JSON失败: " + resBody);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resJson.isEmpty()) {
|
||||||
|
fail(FIRST_REQUEST_URL + " 返回内容为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (resJson.getInteger("code") != 200) {
|
if (resJson.getInteger("code") != 200) {
|
||||||
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
|
||||||
return;
|
return;
|
||||||
@@ -125,7 +175,7 @@ public class IzTool extends PanBase {
|
|||||||
String fidEncode = AESUtils.encrypt2HexIz(fileId + "|" + userId);
|
String fidEncode = AESUtils.encrypt2HexIz(fileId + "|" + userId);
|
||||||
String auth = AESUtils.encrypt2HexIz(fileId + "|" + nowTs);
|
String auth = AESUtils.encrypt2HexIz(fileId + "|" + nowTs);
|
||||||
// 第二次请求
|
// 第二次请求
|
||||||
clientNoRedirects.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
|
webClientSession.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
|
||||||
.setTemplateParam("fidEncode", fidEncode)
|
.setTemplateParam("fidEncode", fidEncode)
|
||||||
.setTemplateParam("uuid", uuid)
|
.setTemplateParam("uuid", uuid)
|
||||||
.setTemplateParam("ts", tsEncode)
|
.setTemplateParam("ts", tsEncode)
|
||||||
@@ -139,9 +189,6 @@ public class IzTool extends PanBase {
|
|||||||
}
|
}
|
||||||
promise.complete(headers.get("Location"));
|
promise.complete(headers.get("Location"));
|
||||||
}).onFailure(handleFail(SECOND_REQUEST_URL));
|
}).onFailure(handleFail(SECOND_REQUEST_URL));
|
||||||
}).onFailure(handleFail(FIRST_REQUEST_URL));
|
|
||||||
});
|
|
||||||
return promise.future();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,7 +221,7 @@ public class IzTool extends PanBase {
|
|||||||
log.debug("开始解析目录: {}, shareId: {}, uuid: {}, ts: {}", id, shareId, uuid, tsEncode);
|
log.debug("开始解析目录: {}, shareId: {}, uuid: {}, ts: {}", id, shareId, uuid, tsEncode);
|
||||||
// 开始解析目录: 164312216, shareId: bPMsbg5K, uuid: 0fmVWTx2Ea4zFwkpd7KXf, ts: 20865d7b7f00828279f437cd1f097860
|
// 开始解析目录: 164312216, shareId: bPMsbg5K, uuid: 0fmVWTx2Ea4zFwkpd7KXf, ts: 20865d7b7f00828279f437cd1f097860
|
||||||
// 拿到目录ID
|
// 拿到目录ID
|
||||||
client.postAbs(UriTemplate.of(FILE_LIST_URL))
|
webClientSession.postAbs(UriTemplate.of(FILE_LIST_URL))
|
||||||
.putHeaders(header)
|
.putHeaders(header)
|
||||||
.setTemplateParam("shareId", shareId)
|
.setTemplateParam("shareId", shareId)
|
||||||
.setTemplateParam("uuid", uuid)
|
.setTemplateParam("uuid", uuid)
|
||||||
@@ -264,7 +311,7 @@ public class IzTool extends PanBase {
|
|||||||
public Future<String> parseById() {
|
public Future<String> parseById() {
|
||||||
// 第二次请求
|
// 第二次请求
|
||||||
JsonObject paramJson = (JsonObject)shareLinkInfo.getOtherParam().get("paramJson");
|
JsonObject paramJson = (JsonObject)shareLinkInfo.getOtherParam().get("paramJson");
|
||||||
clientNoRedirects.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
|
webClientSession.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
|
||||||
.setTemplateParam("fidEncode", paramJson.getString("fidEncode"))
|
.setTemplateParam("fidEncode", paramJson.getString("fidEncode"))
|
||||||
.setTemplateParam("uuid", paramJson.getString("uuid"))
|
.setTemplateParam("uuid", paramJson.getString("uuid"))
|
||||||
.setTemplateParam("ts", paramJson.getString("ts"))
|
.setTemplateParam("ts", paramJson.getString("ts"))
|
||||||
|
|||||||
@@ -294,9 +294,24 @@ public class LzTool extends PanBase {
|
|||||||
String sUrl = shareLinkInfo.getShareUrl();
|
String sUrl = shareLinkInfo.getShareUrl();
|
||||||
String pwd = shareLinkInfo.getSharePassword();
|
String pwd = shareLinkInfo.getSharePassword();
|
||||||
|
|
||||||
WebClient client = clientNoRedirects;
|
webClientSession.getAbs(sUrl).send().onSuccess(res -> {
|
||||||
client.getAbs(sUrl).send().onSuccess(res -> {
|
|
||||||
String html = res.bodyAsString();
|
String html = res.bodyAsString();
|
||||||
|
// 检查是否需要 cookie 验证
|
||||||
|
if (html.contains("var arg1='")) {
|
||||||
|
webClientSession = WebClientSession.create(clientNoRedirects);
|
||||||
|
setCookie(html);
|
||||||
|
// 重新请求
|
||||||
|
webClientSession.getAbs(sUrl).send().onSuccess(res2 -> {
|
||||||
|
handleFileListParse(res2.bodyAsString(), pwd, sUrl, promise);
|
||||||
|
}).onFailure(err -> promise.fail(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleFileListParse(html, pwd, sUrl, promise);
|
||||||
|
}).onFailure(err -> promise.fail(err));
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleFileListParse(String html, String pwd, String sUrl, Promise<List<FileInfo>> promise) {
|
||||||
try {
|
try {
|
||||||
String jsText = getJsByPwd(pwd, html, "var urls =window.location.href");
|
String jsText = getJsByPwd(pwd, html, "var urls =window.location.href");
|
||||||
ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, "file");
|
ScriptObjectMirror scriptObjectMirror = JsExecUtils.executeDynamicJs(jsText, "file");
|
||||||
@@ -307,8 +322,27 @@ public class LzTool extends PanBase {
|
|||||||
MultiMap headers = getHeaders(sUrl);
|
MultiMap headers = getHeaders(sUrl);
|
||||||
|
|
||||||
String url = SHARE_URL_PREFIX + "/filemoreajax.php?file=" + data.get("fid");
|
String url = SHARE_URL_PREFIX + "/filemoreajax.php?file=" + data.get("fid");
|
||||||
client.postAbs(url).putHeaders(headers).sendForm(map).onSuccess(res2 -> {
|
webClientSession.postAbs(url).putHeaders(headers).sendForm(map).onSuccess(res2 -> {
|
||||||
JsonObject fileListJson = asJson(res2);
|
String resBody = asText(res2);
|
||||||
|
// 再次检查是否需要 cookie 验证
|
||||||
|
if (resBody.contains("var arg1='")) {
|
||||||
|
setCookie(resBody);
|
||||||
|
// 重新请求
|
||||||
|
webClientSession.postAbs(url).putHeaders(headers).sendForm(map).onSuccess(res3 -> {
|
||||||
|
handleFileListResponse(asText(res3), promise);
|
||||||
|
}).onFailure(err -> promise.fail(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleFileListResponse(resBody, promise);
|
||||||
|
}).onFailure(err -> promise.fail(err));
|
||||||
|
} catch (ScriptException | NoSuchMethodException e) {
|
||||||
|
promise.fail(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleFileListResponse(String responseBody, Promise<List<FileInfo>> promise) {
|
||||||
|
try {
|
||||||
|
JsonObject fileListJson = new JsonObject(responseBody);
|
||||||
if (fileListJson.getInteger("zt") != 1) {
|
if (fileListJson.getInteger("zt") != 1) {
|
||||||
promise.fail(baseMsg() + fileListJson.getString("info"));
|
promise.fail(baseMsg() + fileListJson.getString("info"));
|
||||||
return;
|
return;
|
||||||
@@ -347,12 +381,9 @@ public class LzTool extends PanBase {
|
|||||||
list.add(fileInfo);
|
list.add(fileInfo);
|
||||||
});
|
});
|
||||||
promise.complete(list);
|
promise.complete(list);
|
||||||
});
|
} catch (Exception e) {
|
||||||
} catch (ScriptException | NoSuchMethodException e) {
|
|
||||||
promise.fail(e);
|
promise.fail(e);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return promise.future();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFileInfo(String html, ShareLinkInfo shareLinkInfo) {
|
void setFileInfo(String html, ShareLinkInfo shareLinkInfo) {
|
||||||
|
|||||||
Reference in New Issue
Block a user