Merge branch 'main' of https://github.com/FongMi/CatVodSpider
This commit is contained in:
commit
ac199497b3
|
|
@ -17,6 +17,7 @@ import com.github.catvod.BuildConfig;
|
|||
import com.github.catvod.bean.Result;
|
||||
import com.github.catvod.bean.Sub;
|
||||
import com.github.catvod.bean.Vod;
|
||||
import com.github.catvod.bean.ali.Cache;
|
||||
import com.github.catvod.bean.ali.Code;
|
||||
import com.github.catvod.bean.ali.Data;
|
||||
import com.github.catvod.bean.ali.Download;
|
||||
|
|
@ -60,9 +61,7 @@ public class AliYun {
|
|||
private AlertDialog dialog;
|
||||
private String refreshToken;
|
||||
private Share share;
|
||||
private OAuth oauth;
|
||||
private Drive drive;
|
||||
private User user;
|
||||
private Cache cache;
|
||||
|
||||
private static class Loader {
|
||||
static volatile AliYun INSTANCE = new AliYun();
|
||||
|
|
@ -72,23 +71,14 @@ public class AliYun {
|
|||
return Loader.INSTANCE;
|
||||
}
|
||||
|
||||
public File getUserCache() {
|
||||
return Path.cache("aliyundrive_user");
|
||||
}
|
||||
|
||||
public File getOAuthCache() {
|
||||
return Path.cache("aliyundrive_oauth");
|
||||
}
|
||||
|
||||
public File getDriveCache() {
|
||||
return Path.cache("aliyundrive_drive");
|
||||
public File getCache() {
|
||||
return Path.tv("aliyun");
|
||||
}
|
||||
|
||||
private AliYun() {
|
||||
Init.checkPermission();
|
||||
tempIds = new ArrayList<>();
|
||||
user = User.objectFrom(Path.read(getUserCache()));
|
||||
oauth = OAuth.objectFrom(Path.read(getOAuthCache()));
|
||||
drive = Drive.objectFrom(Path.read(getDriveCache()));
|
||||
cache = Cache.objectFrom(Path.read(getCache()));
|
||||
}
|
||||
|
||||
public void setRefreshToken(String token) {
|
||||
|
|
@ -99,7 +89,7 @@ public class AliYun {
|
|||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = "text/plain";
|
||||
result[2] = new ByteArrayInputStream(user.getRefreshToken().getBytes());
|
||||
result[2] = new ByteArrayInputStream(cache.getUser().getRefreshToken().getBytes());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -114,13 +104,13 @@ public class AliYun {
|
|||
HashMap<String, String> headers = getHeader();
|
||||
headers.put("x-share-token", share.getShareToken());
|
||||
headers.put("X-Canary", "client=Android,app=adrive,version=v4.3.1");
|
||||
if (user.isAuthed()) headers.put("authorization", user.getAuthorization());
|
||||
if (cache.getUser().isAuthed()) headers.put("authorization", cache.getUser().getAuthorization());
|
||||
return headers;
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaderOpen() {
|
||||
HashMap<String, String> headers = getHeader();
|
||||
headers.put("authorization", oauth.getAuthorization());
|
||||
headers.put("authorization", cache.getOAuth().getAuthorization());
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +119,7 @@ public class AliYun {
|
|||
OkResult result = OkHttp.post(api, param.toString(), getHeader());
|
||||
SpiderDebug.log(result.getCode() + "," + api + "," + result.getBody());
|
||||
if (isManyRequest(result.getBody())) return false;
|
||||
oauth = OAuth.objectFrom(result.getBody()).save();
|
||||
cache.setOAuth(OAuth.objectFrom(result.getBody()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +150,7 @@ public class AliYun {
|
|||
private boolean isManyRequest(String result) {
|
||||
if (!result.contains("Too Many Requests")) return false;
|
||||
Utils.notify("洗洗睡吧,Too Many Requests。");
|
||||
oauth.clean().save();
|
||||
cache.getOAuth().clean();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -184,31 +174,31 @@ public class AliYun {
|
|||
try {
|
||||
SpiderDebug.log("refreshAccessToken...");
|
||||
JsonObject param = new JsonObject();
|
||||
String token = user.getRefreshToken();
|
||||
String token = cache.getUser().getRefreshToken();
|
||||
if (token.isEmpty()) token = refreshToken;
|
||||
if (token != null && token.startsWith("http")) token = OkHttp.string(token).trim();
|
||||
param.addProperty("refresh_token", token);
|
||||
param.addProperty("grant_type", "refresh_token");
|
||||
String json = post("https://auth.aliyundrive.com/v2/account/token", param);
|
||||
user = User.objectFrom(json).save();
|
||||
if (user.getAccessToken().isEmpty()) throw new Exception(json);
|
||||
cache.setUser(User.objectFrom(json));
|
||||
if (cache.getUser().getAccessToken().isEmpty()) throw new Exception(json);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
if (e instanceof TimeoutException) return onTimeout();
|
||||
cache.getUser().clean();
|
||||
e.printStackTrace();
|
||||
user.clean().save();
|
||||
stopService();
|
||||
startFlow();
|
||||
return true;
|
||||
} finally {
|
||||
while (user.getAccessToken().isEmpty()) SystemClock.sleep(250);
|
||||
while (cache.getUser().getAccessToken().isEmpty()) SystemClock.sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
private void getDriveId() {
|
||||
SpiderDebug.log("Get Drive Id...");
|
||||
String json = auth("https://user.aliyundrive.com/v2/user/get", "{}", true);
|
||||
drive = Drive.objectFrom(json).save();
|
||||
cache.setDrive(Drive.objectFrom(json));
|
||||
}
|
||||
|
||||
private boolean oauthRequest() {
|
||||
|
|
@ -230,11 +220,11 @@ public class AliYun {
|
|||
}
|
||||
|
||||
private boolean refreshOpenToken() {
|
||||
if (oauth.getRefreshToken().isEmpty()) return oauthRequest();
|
||||
if (cache.getOAuth().getRefreshToken().isEmpty()) return oauthRequest();
|
||||
SpiderDebug.log("refreshOpenToken...");
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("grant_type", "refresh_token");
|
||||
param.addProperty("refresh_token", oauth.getRefreshToken());
|
||||
param.addProperty("refresh_token", cache.getOAuth().getRefreshToken());
|
||||
return alist("token", param);
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +237,7 @@ public class AliYun {
|
|||
List<Item> subs = new ArrayList<>();
|
||||
listFiles(shareId, new Item(getParentFileId(fileId, share)), files, subs);
|
||||
Collections.sort(files);
|
||||
List<String> playFrom = Arrays.asList("原畫", "普畫");
|
||||
List<String> playFrom = Arrays.asList("原畫", "普畫", "極速");
|
||||
List<String> episode = new ArrayList<>();
|
||||
List<String> playUrl = new ArrayList<>();
|
||||
for (Item file : files) episode.add(file.getDisplayName() + "$" + shareId + "+" + file.getFileId() + findSubs(file.getName(), subs));
|
||||
|
|
@ -337,7 +327,7 @@ public class AliYun {
|
|||
tempIds.add(0, copy(shareId, fileId));
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", tempIds.get(0));
|
||||
param.addProperty("drive_id", drive.getDriveId());
|
||||
param.addProperty("drive_id", cache.getDrive().getDriveId());
|
||||
String json = oauth("openFile/getDownloadUrl", param.toString(), true);
|
||||
return Download.objectFrom(json).getUrl();
|
||||
} catch (Exception e) {
|
||||
|
|
@ -355,7 +345,7 @@ public class AliYun {
|
|||
tempIds.add(0, copy(shareId, fileId));
|
||||
JsonObject param = new JsonObject();
|
||||
param.addProperty("file_id", tempIds.get(0));
|
||||
param.addProperty("drive_id", drive.getDriveId());
|
||||
param.addProperty("drive_id", cache.getDrive().getDriveId());
|
||||
param.addProperty("category", "live_transcoding");
|
||||
param.addProperty("url_expire_sec", "14400");
|
||||
String json = oauth("openFile/getVideoPreviewPlayInfo", param.toString(), true);
|
||||
|
|
@ -368,9 +358,16 @@ public class AliYun {
|
|||
}
|
||||
}
|
||||
|
||||
public String playerContent(String[] ids, boolean original) {
|
||||
if (original) return Result.get().url(getMultiThreadedDownloadUrl(ids[0], ids[1])).octet().subs(getSubs(ids)).header(getHeader()).string();
|
||||
else return getPreviewContent(ids);
|
||||
public String playerContent(String[] ids, String flag) {
|
||||
if (flag.split("#")[0].equals("普畫")) {
|
||||
return getPreviewContent(ids);
|
||||
} else if (flag.split("#")[0].equals("原畫")) {
|
||||
return Result.get().url(getDownloadUrl(ids[0], ids[1])).octet().subs(getSubs(ids)).header(getHeader()).string();
|
||||
} else if (flag.split("#")[0].equals("極速")) {
|
||||
return Result.get().url(MultiThread.url(getDownloadUrl(ids[0], ids[1]), 4)).octet().subs(getSubs(ids)).header(getHeader()).string();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getPreviewContent(String[] ids) {
|
||||
|
|
@ -398,10 +395,10 @@ public class AliYun {
|
|||
}
|
||||
|
||||
private String copy(String shareId, String fileId) {
|
||||
if (drive.getDriveId().isEmpty()) getDriveId();
|
||||
if (cache.getDrive().getDriveId().isEmpty()) getDriveId();
|
||||
SpiderDebug.log("Copy..." + fileId);
|
||||
String json = "{\"requests\":[{\"body\":{\"file_id\":\"%s\",\"share_id\":\"%s\",\"auto_rename\":true,\"to_parent_file_id\":\"root\",\"to_drive_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"0\",\"method\":\"POST\",\"url\":\"/file/copy\"}],\"resource\":\"file\"}";
|
||||
json = String.format(json, fileId, shareId, drive.getDriveId());
|
||||
json = String.format(json, fileId, shareId, cache.getDrive().getDriveId());
|
||||
Resp resp = Resp.objectFrom(auth("adrive/v2/batch", json, true));
|
||||
return resp.getResponse().getBody().getFileId();
|
||||
}
|
||||
|
|
@ -417,17 +414,11 @@ public class AliYun {
|
|||
private boolean delete(String fileId) {
|
||||
SpiderDebug.log("Delete..." + fileId);
|
||||
String json = "{\"requests\":[{\"body\":{\"drive_id\":\"%s\",\"file_id\":\"%s\"},\"headers\":{\"Content-Type\":\"application/json\"},\"id\":\"%s\",\"method\":\"POST\",\"url\":\"/file/delete\"}],\"resource\":\"file\"}";
|
||||
json = String.format(json, drive.getDriveId(), fileId, fileId);
|
||||
json = String.format(json, cache.getDrive().getDriveId(), fileId, fileId);
|
||||
Resp resp = Resp.objectFrom(auth("adrive/v2/batch", json, true));
|
||||
return resp.getResponse().getStatus() == 404;
|
||||
}
|
||||
|
||||
public String getMultiThreadedDownloadUrl(String shareId, String fileId) {
|
||||
String url = getDownloadUrl(shareId, fileId);
|
||||
url = MultiThread.proxyUrl(url, 20);
|
||||
return url;
|
||||
}
|
||||
|
||||
public Object[] proxySub(Map<String, String> params) throws Exception {
|
||||
String fileId = params.get("fileId");
|
||||
String shareId = params.get("shareId");
|
||||
|
|
@ -515,9 +506,9 @@ public class AliYun {
|
|||
}
|
||||
|
||||
private void setToken(String value) {
|
||||
cache.getUser().setRefreshToken(value);
|
||||
SpiderDebug.log("Token:" + value);
|
||||
Utils.notify("Token:" + value);
|
||||
user.setRefreshToken(value);
|
||||
refreshAccessToken();
|
||||
stopService();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
package com.github.catvod.bean.ali;
|
||||
|
||||
import com.github.catvod.api.AliYun;
|
||||
import com.github.catvod.spider.Init;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Cache {
|
||||
|
||||
@SerializedName("user")
|
||||
private User user;
|
||||
@SerializedName("oauth")
|
||||
private OAuth oauth;
|
||||
@SerializedName("drive")
|
||||
private Drive drive;
|
||||
|
||||
public static Cache objectFrom(String str) {
|
||||
Cache item = new Gson().fromJson(str, Cache.class);
|
||||
return item == null ? new Cache() : item;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user == null ? new User() : user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public OAuth getOAuth() {
|
||||
return oauth == null ? new OAuth() : oauth;
|
||||
}
|
||||
|
||||
public void setOAuth(OAuth oauth) {
|
||||
this.oauth = oauth;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public Drive getDrive() {
|
||||
return drive == null ? new Drive() : drive;
|
||||
}
|
||||
|
||||
public void setDrive(Drive drive) {
|
||||
this.drive = drive;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
Init.execute(() -> Path.write(AliYun.get().getCache(), toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,6 @@ package com.github.catvod.bean.ali;
|
|||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.api.AliYun;
|
||||
import com.github.catvod.utils.FileUtil;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
|
@ -31,20 +28,4 @@ public class Drive {
|
|||
public String getDriveId() {
|
||||
return getResourceDriveId().isEmpty() ? getDefaultDriveId() : getResourceDriveId();
|
||||
}
|
||||
|
||||
public Drive clean() {
|
||||
this.defaultDriveId = "";
|
||||
this.resourceDriveId = "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public Drive save() {
|
||||
Path.write(AliYun.get().getDriveCache(), toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@ package com.github.catvod.bean.ali;
|
|||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.api.AliYun;
|
||||
import com.github.catvod.utils.FileUtil;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
|
@ -38,19 +35,8 @@ public class OAuth {
|
|||
return getTokenType() + " " + getAccessToken();
|
||||
}
|
||||
|
||||
public OAuth clean() {
|
||||
public void clean() {
|
||||
this.refreshToken = "";
|
||||
this.accessToken = "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth save() {
|
||||
Path.write(AliYun.get().getOAuthCache(), toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,11 @@ package com.github.catvod.bean.ali;
|
|||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.api.AliYun;
|
||||
import com.github.catvod.utils.FileUtil;
|
||||
import com.github.catvod.utils.Path;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class User {
|
||||
|
||||
@SerializedName("default_drive_id")
|
||||
private String driveId;
|
||||
@SerializedName("user_id")
|
||||
private String userId;
|
||||
@SerializedName("token_type")
|
||||
private String tokenType;
|
||||
@SerializedName("access_token")
|
||||
|
|
@ -26,14 +19,6 @@ public class User {
|
|||
return item == null ? new User() : item;
|
||||
}
|
||||
|
||||
public String getDriveId() {
|
||||
return TextUtils.isEmpty(driveId) ? "" : driveId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return TextUtils.isEmpty(userId) ? "" : userId;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return TextUtils.isEmpty(tokenType) ? "" : tokenType;
|
||||
}
|
||||
|
|
@ -58,19 +43,8 @@ public class User {
|
|||
return getTokenType().length() > 0 && getAccessToken().length() > 0;
|
||||
}
|
||||
|
||||
public User clean() {
|
||||
public void clean() {
|
||||
this.refreshToken = "";
|
||||
this.accessToken = "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public User save() {
|
||||
Path.write(AliYun.get().getUserCache(), toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Gson().toJson(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class OkRequest {
|
|||
}
|
||||
|
||||
private RequestBody getRequestBody() {
|
||||
if (!TextUtils.isEmpty(json)) return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
|
||||
if (!TextUtils.isEmpty(json)) return RequestBody.create(MediaType.get("application/json; charset=utf-8"), json);
|
||||
FormBody.Builder formBody = new FormBody.Builder();
|
||||
if (params != null) for (String key : params.keySet()) formBody.add(key, params.get(key));
|
||||
return formBody.build();
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class Ali extends Spider {
|
|||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
return AliYun.get().playerContent(id.split("\\+"), flag.split("#")[0].equals("原畫"));
|
||||
return AliYun.get().playerContent(id.split("\\+"), flag);
|
||||
}
|
||||
|
||||
private Vod parseVod(Matcher matcher, String id) {
|
||||
|
|
@ -54,10 +54,11 @@ public class Ali extends Spider {
|
|||
*/
|
||||
public String detailContentVodPlayFrom(List<String> ids) {
|
||||
List<String> playFrom = new ArrayList<>();
|
||||
if (ids.size() < 2) return TextUtils.join("$$$", Arrays.asList("原畫", "普畫"));
|
||||
if (ids.size() < 2) return TextUtils.join("$$$", Arrays.asList("原畫", "普畫", "極速"));
|
||||
for (int i = 1; i <= ids.size(); i++) {
|
||||
playFrom.add(String.format(Locale.getDefault(), "原畫#%02d", i));
|
||||
playFrom.add(String.format(Locale.getDefault(), "普畫#%02d", i));
|
||||
playFrom.add(String.format(Locale.getDefault(), "極速#%02d", i));
|
||||
}
|
||||
return TextUtils.join("$$$", playFrom);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class Bili extends Spider {
|
|||
private void setCookie() {
|
||||
cookie = extend.get("cookie").getAsString();
|
||||
if (cookie.startsWith("http")) cookie = OkHttp.string(cookie).trim();
|
||||
if (TextUtils.isEmpty(cookie)) cookie = Path.read(getUserCache());
|
||||
if (TextUtils.isEmpty(cookie)) cookie = Path.read(getCache());
|
||||
if (TextUtils.isEmpty(cookie)) cookie = COOKIE;
|
||||
}
|
||||
|
||||
|
|
@ -77,8 +77,8 @@ public class Bili extends Spider {
|
|||
return items;
|
||||
}
|
||||
|
||||
private File getUserCache() {
|
||||
return Path.cache("bilibili_user");
|
||||
private File getCache() {
|
||||
return Path.tv("bilibili");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.github.catvod.spider;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
|
|
@ -53,6 +55,16 @@ public class Init {
|
|||
get().handler.postDelayed(runnable, delay);
|
||||
}
|
||||
|
||||
public static void checkPermission() {
|
||||
try {
|
||||
Activity activity = Init.getActivity();
|
||||
if (activity == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
|
||||
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 9999);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Activity getActivity() throws Exception {
|
||||
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
|
||||
Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
package com.github.catvod.spider;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
||||
import com.github.catvod.bean.Class;
|
||||
import com.github.catvod.bean.Result;
|
||||
|
|
@ -46,7 +44,7 @@ public class Market extends Spider {
|
|||
public void init(Context context, String extend) throws Exception {
|
||||
if (extend.startsWith("http")) extend = OkHttp.string(extend);
|
||||
datas = Data.arrayFrom(extend);
|
||||
checkPermission();
|
||||
Init.checkPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -72,15 +70,6 @@ public class Market extends Spider {
|
|||
return Result.string(vod);
|
||||
}
|
||||
|
||||
private void checkPermission() {
|
||||
try {
|
||||
Activity activity = Init.getActivity();
|
||||
if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 9999);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void finish() {
|
||||
try {
|
||||
Activity activity = Init.getActivity();
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ import java.util.zip.ZipFile;
|
|||
|
||||
public class FileUtil {
|
||||
|
||||
public static File getWall(int index) {
|
||||
return Path.files("wallpaper_" + index);
|
||||
}
|
||||
|
||||
public static void openFile(File file) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.github.catvod.utils;
|
||||
|
||||
import com.github.catvod.downloader.MultiThreadedMemoryDownloader;
|
||||
import com.github.catvod.spider.Proxy;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
|
@ -11,27 +10,20 @@ import fi.iki.elonen.NanoHTTPD;
|
|||
|
||||
public class MultiThread {
|
||||
|
||||
public static String proxyUrl(String url, int thread) {
|
||||
public static String url(String url, int thread) {
|
||||
return String.format(Proxy.getUrl() + "?do=multi&url=%s&thread=%d", URLEncoder.encode(url), thread);
|
||||
}
|
||||
|
||||
public static Object[] proxy(Map<String, String> params) throws Exception {
|
||||
String url = params.get("url");
|
||||
int threadNum = Integer.parseInt(params.get("thread"));
|
||||
int thread = Integer.parseInt(params.get("thread"));
|
||||
Map<String, String> reqHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
if (entry.getKey() != null) {
|
||||
reqHeaders.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
for (String key : params.keySet()) reqHeaders.put(key, params.get(key));
|
||||
if (reqHeaders.containsKey("do")) reqHeaders.remove("do");
|
||||
if (reqHeaders.containsKey("url")) reqHeaders.remove("url");
|
||||
if (reqHeaders.containsKey("thread")) reqHeaders.remove("thread");
|
||||
MultiThreadedMemoryDownloader downloader = new MultiThreadedMemoryDownloader(url, reqHeaders, threadNum);
|
||||
MultiThreadedDownloader downloader = new MultiThreadedDownloader(url, reqHeaders, thread);
|
||||
NanoHTTPD.Response response = downloader.start();
|
||||
Object[] result = new Object[1];
|
||||
result[0] = response;
|
||||
return result;
|
||||
return new Object[]{response};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.github.catvod.downloader;
|
||||
package com.github.catvod.utils;
|
||||
|
||||
import static java.lang.Thread.sleep;
|
||||
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
|
||||
|
|
@ -21,7 +21,8 @@ import fi.iki.elonen.NanoHTTPD;
|
|||
import okhttp3.Response;
|
||||
|
||||
// 多线程内存下载器
|
||||
public class MultiThreadedMemoryDownloader {
|
||||
public class MultiThreadedDownloader {
|
||||
|
||||
private String url; // 资源URL
|
||||
private Map<String, String> headers; // HTTP Headers. 主要关注`Range-Bytes`这个字段.
|
||||
private int chunkSize = 1024 * 128; // 每个线程每轮下载的字节数.
|
||||
|
|
@ -36,7 +37,7 @@ public class MultiThreadedMemoryDownloader {
|
|||
private BlockingQueue<Chunk> readyChunkQueue = new LinkedBlockingQueue<>(); // 已开始下载的chunk队列(有序).
|
||||
private Lock lock = new ReentrantLock(); // 锁.
|
||||
|
||||
public MultiThreadedMemoryDownloader(String url, Map<String, String> headers, int numThreads) {
|
||||
public MultiThreadedDownloader(String url, Map<String, String> headers, int numThreads) {
|
||||
this.url = url;
|
||||
this.headers = headers;
|
||||
this.numThreads = numThreads;
|
||||
|
|
@ -115,7 +116,7 @@ public class MultiThreadedMemoryDownloader {
|
|||
if (hContentLength == null) {
|
||||
throw new Exception("missing response header: Content-Length");
|
||||
}
|
||||
Long contentLength = Long.parseLong(hContentLength);
|
||||
long contentLength = Long.parseLong(hContentLength);
|
||||
|
||||
// 尝试从Content-Range获取下载结束的偏移量
|
||||
if (this.endOffset <= 0) {
|
||||
|
|
@ -142,9 +143,7 @@ public class MultiThreadedMemoryDownloader {
|
|||
// 开启多线程下载
|
||||
this.running = true;
|
||||
for (int i = 0; i < this.numThreads; ++i) {
|
||||
new Thread(() -> {
|
||||
MultiThreadedMemoryDownloader.this.worker();
|
||||
}).start();
|
||||
new Thread(MultiThreadedDownloader.this::worker).start();
|
||||
}
|
||||
|
||||
// 构造response
|
||||
|
|
@ -153,7 +152,7 @@ public class MultiThreadedMemoryDownloader {
|
|||
NanoHTTPD.Response mResponse = newFixedLengthResponse(status, contentType, input, contentLength);
|
||||
for (String key : response.headers().names()) {
|
||||
String value = response.headers().get(key);
|
||||
if (key != null && !key.equalsIgnoreCase("Content-Type") && !key.equalsIgnoreCase("Content-Length")) {
|
||||
if (!key.equalsIgnoreCase("Content-Type") && !key.equalsIgnoreCase("Content-Length")) {
|
||||
mResponse.addHeader(key, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -296,11 +295,8 @@ public class MultiThreadedMemoryDownloader {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean shouldFilterRequestHeaderKey(String key) {
|
||||
if (key == null) {
|
||||
return true;
|
||||
}
|
||||
if (key == null) return true;
|
||||
key = key.toLowerCase();
|
||||
return key.equals("host") || key.equals("http-client-ip") || key.equals("remote-addr");
|
||||
}
|
||||
|
|
@ -309,9 +305,10 @@ public class MultiThreadedMemoryDownloader {
|
|||
this.running = false;
|
||||
}
|
||||
|
||||
private class Chunk {
|
||||
private long startOffset;
|
||||
private long endOffset;
|
||||
private static class Chunk {
|
||||
|
||||
private final long startOffset;
|
||||
private final long endOffset;
|
||||
private byte[] buffer;
|
||||
|
||||
public Chunk(long startOffset, long endOffset) {
|
||||
|
|
@ -3,8 +3,6 @@ package com.github.catvod.utils;
|
|||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.catvod.spider.Init;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
|
@ -24,52 +22,21 @@ public class Path {
|
|||
return file;
|
||||
}
|
||||
|
||||
public static boolean exists(String path) {
|
||||
return new File(path.replace("file://", "")).exists();
|
||||
public static File download() {
|
||||
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
public static File root() {
|
||||
return Environment.getExternalStorageDirectory();
|
||||
}
|
||||
|
||||
public static File cache() {
|
||||
return Init.context().getCacheDir();
|
||||
public static File tv() {
|
||||
return check(new File(root() + File.separator + "TV"));
|
||||
}
|
||||
|
||||
public static File files() {
|
||||
return Init.context().getFilesDir();
|
||||
}
|
||||
|
||||
public static File download() {
|
||||
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
public static String rootPath() {
|
||||
return root().getAbsolutePath();
|
||||
}
|
||||
|
||||
public static File root(String name) {
|
||||
return new File(root(), name);
|
||||
}
|
||||
|
||||
public static File root(String child, String name) {
|
||||
return new File(check(new File(root(), child)), name);
|
||||
}
|
||||
|
||||
public static File cache(String name) {
|
||||
return new File(cache(), name);
|
||||
}
|
||||
|
||||
public static File files(String name) {
|
||||
return new File(files(), name);
|
||||
}
|
||||
|
||||
public static String asset(String fileName) {
|
||||
try {
|
||||
return read(Init.context().getAssets().open(fileName));
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
public static File tv(String name) {
|
||||
if (!name.startsWith(".")) name = "." + name;
|
||||
return new File(tv(), name);
|
||||
}
|
||||
|
||||
public static String read(File file) {
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
a71b8fa729618f6a1f11fb1b96b5278f
|
||||
41ef471afad9198e7273a12f9912578a
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;a71b8fa729618f6a1f11fb1b96b5278f",
|
||||
"spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;41ef471afad9198e7273a12f9912578a",
|
||||
"wallpaper": "https://gao.chuqiuyu.tk",
|
||||
"sites": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;a71b8fa729618f6a1f11fb1b96b5278f",
|
||||
"spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;41ef471afad9198e7273a12f9912578a",
|
||||
"wallpaper": "http://饭太硬.top/深色壁纸/api.php",
|
||||
"sites": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -276,10 +276,9 @@
|
|||
},
|
||||
{
|
||||
"name": "香雅情",
|
||||
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/zip/XYQTVBox_本地包.zip",
|
||||
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/xyq254245/xyqtvbox/main/XYQTVBox_本地包.zip",
|
||||
"icon": "https://i.imgs.ovh/2023/10/20/2IO0D.jpeg",
|
||||
"copy": "file://Download/XYQTVBox/XYQTVBox.json",
|
||||
"version": "11/16"
|
||||
"copy": "file://Download/XYQTVBox/XYQTVBox.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue