diff --git a/app/build.gradle b/app/build.gradle index 7f312713..0ca22fc6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { defaultConfig { applicationId "com.github.catvod.demo" - minSdk 17 + minSdk 18 targetSdk 29 ndk { abiFilters "armeabi-v7a" } } @@ -41,5 +41,6 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.6' implementation 'cn.wanghaomiao:JsoupXpath:2.5.1' implementation 'com.google.zxing:core:3.3.0' + implementation 'com.alibaba:fastjson:1.2.31' implementation 'org.jsoup:jsoup:1.15.3' } \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/Ali.java b/app/src/main/java/com/github/catvod/spider/Ali.java deleted file mode 100644 index 5d954339..00000000 --- a/app/src/main/java/com/github/catvod/spider/Ali.java +++ /dev/null @@ -1,346 +0,0 @@ -package com.github.catvod.spider; - -import android.os.SystemClock; -import android.text.TextUtils; -import android.view.Gravity; -import android.widget.FrameLayout; -import android.widget.ImageView; - -import com.github.catvod.bean.Result; -import com.github.catvod.bean.Sub; -import com.github.catvod.bean.Vod; -import com.github.catvod.bean.ali.Auth; -import com.github.catvod.bean.ali.Data; -import com.github.catvod.bean.ali.Item; -import com.github.catvod.net.OkHttp; -import com.github.catvod.utils.Misc; -import com.github.catvod.utils.Prefers; -import com.github.catvod.utils.QRCode; -import com.github.catvod.utils.Trans; -import com.google.gson.JsonObject; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.ByteArrayInputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author ColaMint & Adam & FongMi - */ -public class Ali { - - private final Pattern pattern = Pattern.compile("www.aliyundrive.com/s/([^/]+)(/folder/([^/]+))?"); - private ScheduledExecutorService service; - private final Auth auth; - - private static class Loader { - static volatile Ali INSTANCE = new Ali(); - } - - public static Ali get() { - return Loader.INSTANCE; - } - - public Ali() { - this.auth = new Auth(); - } - - public Ali init(String token) { - auth.setRefreshToken(Prefers.getString("token", token)); - return this; - } - - private HashMap getHeaders() { - HashMap headers = new HashMap<>(); - headers.put("User-Agent", Misc.CHROME); - headers.put("Referer", "https://www.aliyundrive.com/"); - return headers; - } - - private HashMap getAuthHeader() { - HashMap headers = getHeaders(); - headers.put("authorization", auth.getAccessToken()); - headers.put("x-share-token", auth.getShareToken()); - return headers; - } - - private String post(String url, JSONObject body) { - url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url; - return OkHttp.postJson(url, body.toString(), getHeaders()); - } - - private String postAuth(String url, JSONObject body) { - url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url; - String result = OkHttp.postJson(url, body.toString(), getAuthHeader()); - if (check401(result)) return postAuth(url, body); - return result; - } - - private boolean check401(String result) { - if (result.contains("AccessTokenInvalid")) return refreshAccessToken(); - if (result.contains("ShareLinkTokenInvalid")) return refreshShareToken(); - if (result.contains("InvalidParameterNotMatch")) return refreshShareToken(); - return false; - } - - public String detailContent(List ids) throws Exception { - String url = ids.get(0).trim(); - Matcher matcher = pattern.matcher(url); - if (!matcher.find()) return ""; - String shareId = matcher.group(1); - String fileId = matcher.groupCount() == 3 ? matcher.group(3) : ""; - auth.setShareId(shareId); refreshShareToken(); - return Result.string(getVod(url, fileId)); - } - - public String playerContent(String flag, String id) { - String[] ids = id.split("\\+"); - if (auth.isEmpty()) refreshAccessToken(); - if (flag.equals("原畫")) { - return Result.get().url(getDownloadUrl(ids[0])).subs(getSub(ids)).header(getHeaders()).string(); - } else { - return Result.get().url(getPreviewUrl(ids[0])).subs(getSub(ids)).header(getHeaders()).string(); - } - } - - private Vod getVod(String url, String fileId) throws Exception { - JSONObject body = new JSONObject(); - body.put("share_id", auth.getShareId()); - String json = post("adrive/v3/share_link/get_share_by_anonymous", body); - JSONObject object = new JSONObject(json); - List files = new ArrayList<>(); - LinkedHashMap> subMap = new LinkedHashMap<>(); - listFiles(new Item(getParentFileId(fileId, object)), files, subMap); - List playUrls = new ArrayList<>(); - for (Item file : files) playUrls.add(Trans.get(file.getDisplayName()) + "$" + file.getFileId() + findSubs(file.getName(), subMap)); - List sourceUrls = new ArrayList<>(); - sourceUrls.add(TextUtils.join("#", playUrls)); - sourceUrls.add(TextUtils.join("#", playUrls)); - Vod vod = new Vod(); - vod.setVodId(url); - vod.setVodContent(url); - vod.setVodPic(object.getString("avatar")); - vod.setVodName(object.getString("share_name")); - vod.setVodPlayUrl(TextUtils.join("$$$", sourceUrls)); - vod.setVodPlayFrom("原畫$$$普畫"); - vod.setTypeName("阿里雲盤"); - return vod; - } - - private void listFiles(Item folder, List files, LinkedHashMap> subMap) throws Exception { - listFiles(folder, files, subMap, ""); - } - - private void listFiles(Item parent, List files, LinkedHashMap> subMap, String marker) throws Exception { - JSONObject body = new JSONObject(); - List folders = new ArrayList<>(); - body.put("limit", 200); - body.put("share_id", auth.getShareId()); - body.put("parent_file_id", parent.getFileId()); - body.put("order_by", "name"); - body.put("order_direction", "ASC"); - if (marker.length() > 0) body.put("marker", marker); - Item item = Item.objectFrom(postAuth("adrive/v3/file/list", body)); - for (Item file : item.getItems()) { - if (file.getType().equals("folder")) { - folders.add(file); - } else if (file.getCategory().equals("video") || file.getCategory().equals("audio")) { - files.add(file.parent(parent.getName())); - } else if (Misc.isSub(file.getExt())) { - String key = file.removeExt(); - if (!subMap.containsKey(key)) subMap.put(key, new ArrayList<>()); - subMap.get(key).add(key + "@@@" + file.getExt() + "@@@" + file.getFileId()); - } - } - if (item.getNextMarker().length() > 0) { - listFiles(parent, files, subMap, item.getNextMarker()); - } - for (Item folder : folders) { - listFiles(folder, files, subMap); - } - } - - private String getParentFileId(String fileId, JSONObject shareInfo) throws Exception { - JSONArray array = shareInfo.getJSONArray("file_infos"); - if (!TextUtils.isEmpty(fileId)) return fileId; - if (array.length() == 0) return ""; - JSONObject fileInfo = array.getJSONObject(0); - if (fileInfo.getString("type").equals("folder")) return fileInfo.getString("file_id"); - if (fileInfo.getString("type").equals("file") && fileInfo.getString("category").equals("video")) return "root"; - return ""; - } - - private boolean refreshAccessToken() { - try { - JSONObject body = new JSONObject(); - String token = auth.getRefreshToken(); - if (token.startsWith("http")) token = OkHttp.string(token).replaceAll("[^A-Za-z0-9]", ""); - body.put("refresh_token", token); - body.put("grant_type", "refresh_token"); - JSONObject object = new JSONObject(post("https://auth.aliyundrive.com/v2/account/token", body)); - auth.setAccessToken(object.getString("token_type") + " " + object.getString("access_token")); - auth.setRefreshToken(object.getString("refresh_token")); - return true; - } catch (Exception e) { - checkService(); - auth.clean(); - getQRCode(); - return true; - } finally { - while (auth.isEmpty()) SystemClock.sleep(250); - } - } - - private boolean refreshShareToken() { - try { - JSONObject body = new JSONObject(); - body.put("share_id", auth.getShareId()); - body.put("share_pwd", ""); - JSONObject object = new JSONObject(post("v2/share_link/get_share_token", body)); - auth.setShareToken(object.getString("share_token")); - return true; - } catch (Exception e) { - Init.show("來晚啦,該分享已失效。"); - e.printStackTrace(); - return false; - } - } - - private String findSubs(String name, Map> subMap) { - name = name.substring(0, name.lastIndexOf(".")); - List subs = subMap.get(name); - if (subs != null && subs.size() > 0) return combineSubs(subs); - StringBuilder sb = new StringBuilder(); - for (Map.Entry> entry : subMap.entrySet()) sb.append(combineSubs(entry.getValue())); - return sb.toString(); - } - - private String combineSubs(List subs) { - StringBuilder sb = new StringBuilder(); - for (String sub : subs) sb.append("+").append(sub); - return sb.toString(); - } - - private List getSub(String[] ids) { - List sub = new ArrayList<>(); - for (String text : ids) { - if (!text.contains("@@@")) continue; - String[] split = text.split("@@@"); - String name = split[0]; - String ext = split[1]; - String url = Proxy.getUrl() + "?do=ali&type=sub" + "&file_id=" + split[2]; - sub.add(Sub.create().name(name).ext(ext).url(url)); - } - return sub; - } - - private String getPreviewQuality(JSONArray taskList) throws Exception { - for (String templateId : Arrays.asList("FHD", "HD", "SD", "LD")) { - for (int i = 0; i < taskList.length(); ++i) { - JSONObject task = taskList.getJSONObject(i); - if (task.getString("template_id").equals(templateId)) { - return task.getString("url"); - } - } - } - return taskList.getJSONObject(0).getString("url"); - } - - private String getPreviewUrl(String fileId) { - try { - JSONObject body = new JSONObject(); - body.put("file_id", fileId); - body.put("share_id", auth.getShareId()); - body.put("template_id", ""); - body.put("category", "live_transcoding"); - String json = postAuth("v2/file/get_share_link_video_preview_play_info", body); - JSONArray taskList = new JSONObject(json).getJSONObject("video_preview_play_info").getJSONArray("live_transcoding_task_list"); - Map> respHeaders = new HashMap<>(); - OkHttp.stringNoRedirect(getPreviewQuality(taskList), getHeaders(), respHeaders); - return OkHttp.getRedirectLocation(respHeaders); - } catch (Exception e) { - e.printStackTrace(); - return ""; - } - } - - private String getDownloadUrl(String fileId) { - try { - JSONObject body = new JSONObject(); - body.put("file_id", fileId); - body.put("share_id", auth.getShareId()); - body.put("expire_sec", 600); - String json = postAuth("v2/file/get_share_link_download_url", body); - String url = new JSONObject(json).optString("download_url"); - Map> respHeaders = new HashMap<>(); - OkHttp.stringNoRedirect(url, getHeaders(), respHeaders); - return OkHttp.getRedirectLocation(respHeaders); - } catch (Exception e) { - e.printStackTrace(); - return ""; - } - } - - public Object[] vod(Map params) { - String fileId = params.get("file_id"); - String text = OkHttp.string(getDownloadUrl(fileId), getAuthHeader()); - Object[] result = new Object[3]; - result[0] = 200; - result[1] = "application/octet-stream"; - result[2] = new ByteArrayInputStream(text.getBytes()); - return result; - } - - private void checkService() { - if (service != null) service.shutdownNow(); - if (auth.getView() != null) Init.run(() -> Misc.removeView(auth.getView())); - } - - private void getQRCode() { - HashMap headers = new HashMap<>(); - headers.put("User-Agent", Misc.CHROME); - Data data = Data.objectFrom(OkHttp.string("https://easy-token.cooluc.com/qr", headers)); - if (data != null) Init.run(() -> showCode(data)); - service = Executors.newScheduledThreadPool(1); - if (data != null) service.scheduleAtFixedRate(() -> { - JsonObject params = new JsonObject(); - params.addProperty("t", data.getData().getT()); - params.addProperty("ck", data.getData().getCk()); - Data result = Data.objectFrom(OkHttp.postJson("https://easy-token.cooluc.com/ck", params.toString(), headers)); - if (result.hasToken()) setToken(result.getData().getRefreshToken()); - }, 1, 1, TimeUnit.SECONDS); - } - - private void setToken(String value) { - Prefers.put("token", value); - Init.show("請重新進入播放頁"); - auth.setRefreshToken(value); - checkService(); - } - - private void showCode(Data data) { - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); - params.gravity = Gravity.CENTER; - Misc.addView(create(data.getData().getCodeContent()), params); - Init.show("請使用阿里雲盤 App 掃描二維碼"); - } - - private ImageView create(String value) { - ImageView view = new ImageView(Init.context()); - view.setScaleType(ImageView.ScaleType.CENTER_CROP); - view.setImageBitmap(QRCode.getBitmap(value, 250, 2)); - auth.setView(view); - return view; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/Bili.java b/app/src/main/java/com/github/catvod/spider/Bili.java deleted file mode 100644 index 74b0f70a..00000000 --- a/app/src/main/java/com/github/catvod/spider/Bili.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.github.catvod.spider; - -import android.content.Context; -import android.text.TextUtils; - -import com.github.catvod.bean.Class; -import com.github.catvod.bean.Result; -import com.github.catvod.bean.Vod; -import com.github.catvod.crawler.Spider; -import com.github.catvod.net.OkHttp; -import com.github.catvod.utils.Misc; -import com.github.catvod.utils.Trans; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.jsoup.Jsoup; - -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * @author ColaMint & FongMi - */ -public class Bili extends Spider { - - private static final String url = "https://www.bilibili.com"; - private HashMap header; - private JSONObject ext; - private String extend; - - private String getCookie(String cookie) { - if (TextUtils.isEmpty(cookie)) return "buvid3=84B0395D-C9F2-C490-E92E-A09AB48FE26E71636infoc"; - if (cookie.startsWith("http")) return OkHttp.string(cookie).replace("\n", ""); - return cookie; - } - - private void setHeader() throws Exception { - header.put("cookie", getCookie(ext.getString("cookie"))); - header.put("User-Agent", Misc.CHROME); - header.put("Referer", url); - } - - private void fetchExt() { - String result = OkHttp.string(extend); - if (!TextUtils.isEmpty(result)) extend = result; - } - - private void fetchRule() throws Exception { - if (header.containsKey("cookie") && header.get("cookie").length() > 0) return; - if (extend.startsWith("http")) fetchExt(); - ext = new JSONObject(extend); - setHeader(); - } - - @Override - public void init(Context context, String extend) { - try { - this.extend = extend; - this.header = new HashMap<>(); - fetchRule(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public String homeContent(boolean filter) throws Exception { - fetchRule(); - return Result.string(Class.arrayFrom(ext.getJSONArray("classes").toString()), ext.getJSONObject("filter")); - } - - @Override - public String homeVideoContent() throws Exception { - fetchRule(); - return categoryContent("窗 白噪音", "1", true, new HashMap<>()); - } - - @Override - public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { - String duration = extend.containsKey("duration") ? extend.get("duration") : "0"; - if (extend.containsKey("tid")) tid = tid + " " + extend.get("tid"); - String url = "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=" + URLEncoder.encode(tid) + "&duration=" + duration + "&page=" + pg; - JSONObject resp = new JSONObject(OkHttp.string(url, header)); - JSONArray result = resp.getJSONObject("data").getJSONArray("result"); - List list = new ArrayList<>(); - for (int i = 0; i < result.length(); ++i) { - JSONObject object = result.getJSONObject(i); - String pic = object.getString("pic"); - Vod vod = new Vod(); - vod.setVodId(object.getString("bvid")); - vod.setVodName(Jsoup.parse(object.getString("title")).text()); - vod.setVodRemarks(object.getString("duration").split(":")[0] + "分鐘"); - vod.setVodPic(pic.startsWith("//") ? "https:" + pic : pic); - list.add(vod); - } - return Result.string(list); - } - - @Override - public String detailContent(List ids) throws Exception { - String bvid = ids.get(0); - String bvid2aidUrl = "https://api.bilibili.com/x/web-interface/archive/stat?bvid=" + bvid; - JSONObject bvid2aidResp = new JSONObject(OkHttp.string(bvid2aidUrl, header)); - String aid = bvid2aidResp.getJSONObject("data").getLong("aid") + ""; - String detailUrl = "https://api.bilibili.com/x/web-interface/view?aid=" + aid; - JSONObject detailResp = new JSONObject(OkHttp.string(detailUrl, header)); - JSONObject detailData = detailResp.getJSONObject("data"); - List playlist = new ArrayList<>(); - JSONArray pages = detailData.getJSONArray("pages"); - for (int i = 0; i < pages.length(); ++i) { - JSONObject page = pages.getJSONObject(i); - String title = page.getString("part").replace("$", "_").replace("#", "_"); - playlist.add(Trans.get(title) + "$" + aid + "+" + page.getLong("cid")); - } - Vod vod = new Vod(); - vod.setVodId(bvid); - vod.setVodName(detailData.getString("title")); - vod.setVodPic(detailData.getString("pic")); - vod.setTypeName(detailData.getString("tname")); - vod.setVodRemarks(detailData.getLong("duration") / 60 + "分鐘"); - vod.setVodContent(detailData.getString("desc")); - vod.setVodPlayFrom("B站"); - vod.setVodPlayUrl(TextUtils.join("#", playlist)); - return Result.string(vod); - } - - @Override - public String searchContent(String key, boolean quick) throws Exception { - return categoryContent(key, "1", true, new HashMap<>()); - } - - @Override - public String playerContent(String flag, String id, List vipFlags) throws Exception { - String[] ids = id.split("\\+"); - String aid = ids[0]; - String cid = ids[1]; - String url = "https://api.bilibili.com/x/player/playurl?avid=" + aid + "&cid=" + cid + "&qn=120&fourk=1"; - JSONObject resp = new JSONObject(OkHttp.string(url, header)); - url = resp.getJSONObject("data").getJSONArray("durl").getJSONObject(0).getString("url"); - return Result.get().url(url).header(header).string(); - } -} diff --git a/app/src/main/java/com/github/catvod/spider/YiSo.java b/app/src/main/java/com/github/catvod/spider/YiSo.java index eaf6d57d..64ba8dd8 100644 --- a/app/src/main/java/com/github/catvod/spider/YiSo.java +++ b/app/src/main/java/com/github/catvod/spider/YiSo.java @@ -39,7 +39,7 @@ public class YiSo extends Spider { public String searchContent(String key, boolean quick) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return ""; - String url = "https://yiso.fun/api/search?name=" + URLEncoder.encode(key) + "&from=ali"; + String url = "https://yiso.fun/api/search?name=4k " + URLEncoder.encode(key) + "&from=ali"; Map result = new HashMap<>(); Misc.loadWebView(url, getWebViewClient(result)); while (!result.containsKey("json")) SystemClock.sleep(50); diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 109c2ad0..b0e01555 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index dd7c88d3..da14f3c3 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -a84fef826cb82da525469e8acf1e7d9a +0a5952d9789ee1a8398598bea20ce488