From 3c32be4d7e03b40abec2526b07eaacbec23fc1cb Mon Sep 17 00:00:00 2001 From: FongMi Date: Mon, 10 Jul 2023 18:37:53 +0800 Subject: [PATCH] Support python localProxy --- .../com/fongmi/android/tv/api/ApiConfig.java | 22 +++++--- .../com/fongmi/android/tv/api/JarLoader.java | 3 ++ .../com/fongmi/android/tv/api/JsLoader.java | 9 ++-- .../com/fongmi/android/tv/api/PyLoader.java | 18 +++++++ .../com/github/catvod/crawler/Spider.java | 8 +++ .../java/com/github/catvod/net/OkHttp.java | 4 ++ .../java/com/github/catvod/spider/Proxy.java | 30 +++++++++++ drpy/src/main/java/com/hiker/drpy/Spider.java | 39 +++++++------- .../java/com/hiker/drpy/method/Global.java | 8 ++- .../com/undcover/freedom/pyramid/Spider.java | 53 +++++++++++++++++++ pyramid/src/main/python/app.py | 5 ++ 11 files changed, 167 insertions(+), 32 deletions(-) create mode 100644 catvod/src/main/java/com/github/catvod/spider/Proxy.java diff --git a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java index 1103de9aa..4c163a9a7 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java @@ -22,6 +22,8 @@ import com.google.gson.JsonParser; import org.json.JSONObject; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -232,23 +234,29 @@ public class ApiConfig { boolean py = site.getApi().startsWith("py_"); boolean csp = site.getApi().startsWith("csp_"); if (js) return jsLoader.getSpider(site.getKey(), site.getApi(), site.getExt()); - if (py) return pyLoader.getSpider(site.getKey(), site.getApi(), site.getExt()); - if (csp) return jarLoader.getSpider(site.getKey(), site.getApi(), site.getExt(), site.getJar()); + else if (py) return pyLoader.getSpider(site.getKey(), site.getApi(), site.getExt()); + else if (csp) return jarLoader.getSpider(site.getKey(), site.getApi(), site.getExt(), site.getJar()); else return new SpiderNull(); } public void setRecent(Site site) { boolean js = site.getApi().contains(".js"); + boolean py = site.getApi().startsWith("py_"); boolean csp = site.getApi().startsWith("csp_"); if (js) jsLoader.setRecent(site.getKey()); - if (csp) jarLoader.setRecent(site.getJar()); + else if (py) pyLoader.setRecent(site.getJar()); + else if (csp) jarLoader.setRecent(site.getJar()); } - public Object[] proxyLocal(Map param) { - if (param.containsKey("do") && param.get("do").equals("js")) { - return jsLoader.proxyInvoke(param); + public Object[] proxyLocal(Map params) { + if (params.containsKey("do") && params.get("do").equals("port")) { + return new Object[]{200, "text/plain; charset=utf-8", new ByteArrayInputStream("ok".getBytes(StandardCharsets.UTF_8))}; + } else if (params.containsKey("do") && params.get("do").equals("js")) { + return jsLoader.proxyInvoke(params); + } else if (params.containsKey("do") && params.get("do").equals("py")) { + return pyLoader.proxyInvoke(params); } else { - return jarLoader.proxyInvoke(param); + return jarLoader.proxyInvoke(params); } } diff --git a/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java b/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java index 8a1a78cbc..e5ca5bdae 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java @@ -34,6 +34,7 @@ public class JarLoader { } public void clear() { + for (Spider spider : spiders.values()) spider.destroy(); this.loaders.clear(); this.methods.clear(); this.spiders.clear(); @@ -116,6 +117,8 @@ public class JarLoader { public Object[] proxyInvoke(Map params) { try { + Spider spider = spiders.get(recent); + if (spider != null) return spider.proxyLocal(params); Method method = methods.get(Utils.getMd5(recent)); if (method != null) return (Object[]) method.invoke(null, params); else return null; diff --git a/app/src/main/java/com/fongmi/android/tv/api/JsLoader.java b/app/src/main/java/com/fongmi/android/tv/api/JsLoader.java index 6ba0deacb..c57f2f349 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/JsLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/JsLoader.java @@ -1,8 +1,9 @@ package com.fongmi.android.tv.api; import com.fongmi.android.tv.App; +import com.github.catvod.crawler.Spider; +import com.github.catvod.crawler.SpiderNull; import com.hiker.drpy.Loader; -import com.hiker.drpy.Spider; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -37,20 +38,20 @@ public class JsLoader { public Spider getSpider(String key, String api, String ext) { try { if (spiders.containsKey(key)) return spiders.get(key); - Spider spider = new Spider(api); + Spider spider = new com.hiker.drpy.Spider(api); spider.init(App.get(), ext); spiders.put(key, spider); return spider; } catch (Throwable e) { e.printStackTrace(); - return new Spider(); + return new SpiderNull(); } } public Object[] proxyInvoke(Map params) { try { Spider spider = spiders.get(recent); - if (spider != null) return spider.doProxy(params); + if (spider != null) return spider.proxyLocal(params); else return null; } catch (Exception e) { e.printStackTrace(); diff --git a/app/src/main/java/com/fongmi/android/tv/api/PyLoader.java b/app/src/main/java/com/fongmi/android/tv/api/PyLoader.java index cb5df611d..0f86d11d9 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/PyLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/PyLoader.java @@ -7,12 +7,14 @@ import com.github.catvod.crawler.Spider; import com.github.catvod.crawler.SpiderNull; import java.lang.reflect.Method; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class PyLoader { private final ConcurrentHashMap spiders; private Object loader; + private String recent; public PyLoader() { spiders = new ConcurrentHashMap<>(); @@ -20,9 +22,14 @@ public class PyLoader { } public void clear() { + for (Spider spider : spiders.values()) spider.destroy(); this.spiders.clear(); } + public void setRecent(String recent) { + this.recent = recent; + } + private void init() { try { loader = Class.forName("com.undcover.freedom.pyramid.Loader").newInstance(); @@ -43,4 +50,15 @@ public class PyLoader { return new SpiderNull(); } } + + public Object[] proxyInvoke(Map params) { + try { + Spider spider = spiders.get(recent); + if (spider != null) return spider.proxyLocal(params); + else return null; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } } diff --git a/catvod/src/main/java/com/github/catvod/crawler/Spider.java b/catvod/src/main/java/com/github/catvod/crawler/Spider.java index 7c872428c..24dcc68f6 100644 --- a/catvod/src/main/java/com/github/catvod/crawler/Spider.java +++ b/catvod/src/main/java/com/github/catvod/crawler/Spider.java @@ -6,6 +6,7 @@ import com.github.catvod.net.OkHttp; import java.util.HashMap; import java.util.List; +import java.util.Map; import okhttp3.Dns; @@ -54,6 +55,13 @@ public abstract class Spider { return false; } + public Object[] proxyLocal(Map params) throws Exception { + return null; + } + + public void destroy() { + } + public static Dns safeDns() { return OkHttp.dns(); } diff --git a/catvod/src/main/java/com/github/catvod/net/OkHttp.java b/catvod/src/main/java/com/github/catvod/net/OkHttp.java index 097d1c642..a6aba4a45 100644 --- a/catvod/src/main/java/com/github/catvod/net/OkHttp.java +++ b/catvod/src/main/java/com/github/catvod/net/OkHttp.java @@ -78,6 +78,10 @@ public class OkHttp { return client().newCall(new Request.Builder().url(buildUrl(url, params)).build()); } + public static Call newCall(String url, ArrayMap params, Headers headers) { + return client().newCall(new Request.Builder().url(buildUrl(url, params)).headers(headers).build()); + } + public static Call newCall(OkHttpClient client, String url, RequestBody body) { return client.newCall(new Request.Builder().url(url).post(body).build()); } diff --git a/catvod/src/main/java/com/github/catvod/spider/Proxy.java b/catvod/src/main/java/com/github/catvod/spider/Proxy.java new file mode 100644 index 000000000..b03e35022 --- /dev/null +++ b/catvod/src/main/java/com/github/catvod/spider/Proxy.java @@ -0,0 +1,30 @@ +package com.github.catvod.spider; + +import com.github.catvod.net.OkHttp; + +public class Proxy { + + private static int port; + + static void adjustPort() throws Exception { + if (port > 0) return; + int port = 9978; + while (port < 10000) { + String resp = OkHttp.newCall("http://127.0.0.1:" + port + "/proxy?do=port").execute().body().string(); + if (resp.equals("ok")) { + Proxy.port = port; + break; + } + port++; + } + } + + public static String getUrl(String type) { + try { + adjustPort(); + return "http://127.0.0.1:" + port + "/proxy?do=" + type; + } catch (Exception e) { + return "http://127.0.0.1:9978/proxy?do=" + type; + } + } +} diff --git a/drpy/src/main/java/com/hiker/drpy/Spider.java b/drpy/src/main/java/com/hiker/drpy/Spider.java index 673d62b29..4d696c8a8 100644 --- a/drpy/src/main/java/com/hiker/drpy/Spider.java +++ b/drpy/src/main/java/com/hiker/drpy/Spider.java @@ -24,14 +24,11 @@ import java.util.concurrent.Future; public class Spider extends com.github.catvod.crawler.Spider { - private ExecutorService executor; + private final ExecutorService executor; private QuickJSContext ctx; private JSObject jsObject; - private String key; - private String api; - - public Spider() { - } + private final String key; + private final String api; public Spider(String api) { this.key = "__" + UUID.randomUUID().toString().replace("-", "") + "__"; @@ -89,34 +86,36 @@ public class Spider extends com.github.catvod.crawler.Spider { return post("play", flag, id, array); } - public void destroy() { - submit(() -> { - executor.shutdownNow(); - ctx.destroy(); - }); - } - - public Object[] doProxy(Map params) throws Exception { + @Override + public Object[] proxyLocal(Map params) throws Exception { return submit(() -> { JSObject obj = ctx.createNewJSObject(); for (Object key : params.keySet()) obj.setProperty((String) key, (String) params.get(key)); JSONArray array = new JSONArray(((JSArray) jsObject.getJSFunction("proxy").call(obj)).stringify()); - Object[] objects = new Object[3]; - objects[0] = array.get(0); - objects[1] = array.opt(1); + Object[] result = new Object[3]; + result[0] = array.get(0); + result[1] = array.opt(1); Object o = array.opt(2); if (o instanceof JSONArray) { JSONArray a = (JSONArray) o; byte[] bytes = new byte[a.length()]; for (int i = 0; i < a.length(); i++) bytes[i] = (byte) a.optInt(i); - objects[2] = new ByteArrayInputStream(bytes); + result[2] = new ByteArrayInputStream(bytes); } else { - objects[2] = new ByteArrayInputStream(o.toString().getBytes()); + result[2] = new ByteArrayInputStream(o.toString().getBytes()); } - return objects; + return result; }).get(); } + @Override + public void destroy() { + submit(() -> { + executor.shutdownNow(); + ctx.destroy(); + }); + } + private void initJS(Context context, String extend) { if (ctx == null) createCtx(); ctx.evaluateModule(getContent(context), api); diff --git a/drpy/src/main/java/com/hiker/drpy/method/Global.java b/drpy/src/main/java/com/hiker/drpy/method/Global.java index 405bf7f61..e1f925a7d 100644 --- a/drpy/src/main/java/com/hiker/drpy/method/Global.java +++ b/drpy/src/main/java/com/hiker/drpy/method/Global.java @@ -2,11 +2,11 @@ package com.hiker.drpy.method; import android.text.TextUtils; import android.util.Base64; -import android.util.Log; import androidx.annotation.Keep; import com.github.catvod.net.OkHttp; +import com.github.catvod.spider.Proxy; import com.google.gson.Gson; import com.hiker.drpy.Parser; import com.whl.quickjs.wrapper.JSArray; @@ -66,6 +66,12 @@ public class Global { } } + @Keep + @JSMethod + public String getProxy(boolean local) { + return Proxy.getUrl("js"); + } + @Keep @JSMethod public Object setTimeout(JSFunction func, int delay) { diff --git a/pyramid/src/main/java/com/undcover/freedom/pyramid/Spider.java b/pyramid/src/main/java/com/undcover/freedom/pyramid/Spider.java index 4f09afdc2..7680562a3 100644 --- a/pyramid/src/main/java/com/undcover/freedom/pyramid/Spider.java +++ b/pyramid/src/main/java/com/undcover/freedom/pyramid/Spider.java @@ -1,12 +1,22 @@ package com.undcover.freedom.pyramid; import android.content.Context; +import android.util.ArrayMap; import com.chaquo.python.PyObject; +import com.github.catvod.net.OkHttp; +import com.github.catvod.spider.Proxy; import com.google.gson.Gson; +import org.json.JSONObject; + +import java.io.ByteArrayInputStream; import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; + +import okhttp3.Headers; public class Spider extends com.github.catvod.crawler.Spider { @@ -59,4 +69,47 @@ public class Spider extends com.github.catvod.crawler.Spider { public String playerContent(String flag, String id, List vipFlags) { return app.callAttr("playerContent", obj, flag, id, gson.toJson(vipFlags)).toString(); } + + @Override + public Object[] proxyLocal(Map params) throws Exception { + List list = app.callAttr("localProxy", params).asList(); + int code = list.get(0).toInt(); + String type = list.get(1).toString(); + String action = list.get(2).toString(); + String content = list.get(3).toString(); + JSONObject object = new JSONObject(action); + String url = object.optString("url"); + Headers header = getHeader(object.getJSONObject("header")); + ArrayMap param = getParam(object.getJSONObject("param")); + if (object.optString("type").equals("stream")) { + return new Object[]{code, type, OkHttp.newCall(url, param, header).execute().body().byteStream()}; + } else { + content = replaceUrl(content.isEmpty() ? OkHttp.newCall(url, header).execute().body().string() : content); + return new Object[]{code, type, new ByteArrayInputStream(content.getBytes())}; + } + } + + private Headers getHeader(JSONObject object) { + Headers.Builder builder = new Headers.Builder(); + if (object == null) return builder.build(); + for (Iterator iterator = object.keys(); iterator.hasNext(); ) { + String key = iterator.next(); + builder.add(key, object.optString(key)); + } + return builder.build(); + } + + private ArrayMap getParam(JSONObject object) { + ArrayMap params = new ArrayMap<>(); + if (object == null) return params; + for (Iterator iterator = object.keys(); iterator.hasNext(); ) { + String key = iterator.next(); + params.put(key, object.optString(key)); + } + return params; + } + + private String replaceUrl(String content) { + return content.replace("http://127.0.0.1:UndCover/proxy", Proxy.getUrl("py")); + } } diff --git a/pyramid/src/main/python/app.py b/pyramid/src/main/python/app.py index 7fa85ac13..132d7b89a 100644 --- a/pyramid/src/main/python/app.py +++ b/pyramid/src/main/python/app.py @@ -80,6 +80,11 @@ def searchContent(ru, key, quick): return formatJo +def localProxy(ru, param): + result = ru.localProxy(str2json(param)) + return result + + def run(): pass