Support drpy - part 3

pull/123/head
FongMi 3 years ago
parent 0365d9b361
commit 3bfa6559cb
  1. 6
      app/src/main/java/com/fongmi/android/tv/api/JsLoader.java
  2. 111
      drpy/src/main/java/com/hiker/drpy/Loader.java
  3. 29
      drpy/src/main/java/com/hiker/drpy/Module.java
  4. 72
      drpy/src/main/java/com/hiker/drpy/Spider.java
  5. 31
      drpy/src/main/java/com/hiker/drpy/Worker.java
  6. 15
      drpy/src/main/java/com/hiker/drpy/method/Console.java
  7. 126
      drpy/src/main/java/com/hiker/drpy/method/Global.java
  8. 26
      drpy/src/main/java/com/hiker/drpy/method/Local.java
  9. 9
      drpy/src/main/java/com/hiker/drpy/net/OkHttp.java

@ -1,7 +1,5 @@
package com.fongmi.android.tv.api;
import android.content.Context;
import com.fongmi.android.tv.App;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderNull;
@ -34,8 +32,8 @@ public class JsLoader {
public Spider getSpider(String key, String api, String ext) {
try {
if (spiders.containsKey(key)) return spiders.get(key);
Method method = loader.getClass().getMethod("spider", Context.class, String.class, String.class);
Spider spider = (Spider) method.invoke(loader, App.get(), api, ext);
Method method = loader.getClass().getMethod("spider", String.class, String.class);
Spider spider = (Spider) method.invoke(loader, api, ext);
spider.init(App.get(), ext);
spiders.put(key, spider);
return spider;

@ -1,107 +1,34 @@
package com.hiker.drpy;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;
import android.util.Log;
import com.hiker.drpy.net.OkHttp;
import com.whl.quickjs.wrapper.JSArray;
import com.whl.quickjs.wrapper.JSObject;
import com.whl.quickjs.wrapper.QuickJSContext;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Response;
import com.github.tvbox.quickjs.JSModule;
import com.github.tvbox.quickjs.QuickJSContext;
import com.hiker.drpy.method.Console;
import com.hiker.drpy.method.Global;
import com.hiker.drpy.method.Local;
public class Loader {
private final String TAG = Loader.class.getSimpleName();
private QuickJSContext jsContext;
private Context context;
private void init(Context context) {
System.loadLibrary("quickjs-android-wrapper");
this.jsContext = QuickJSContext.create();
this.context = context;
initConsole();
initLocal();
initReq();
}
public Spider spider(Context context, String name, String ext) {
if (jsContext == null) init(context);
return new Spider();
}
private void initConsole() {
jsContext.evaluate("var console = {};");
JSObject console = (JSObject) jsContext.getGlobalObject().getProperty("console");
console.setProperty("log", args -> {
StringBuilder b = new StringBuilder();
for (Object o : args) b.append(o == null ? "null" : o.toString());
Log.e(TAG, b.toString());
return null;
});
}
private QuickJSContext ctx;
private void initLocal() {
jsContext.evaluate("var local = {};");
JSObject local = (JSObject) jsContext.getGlobalObject().getProperty("local");
local.setProperty("get", args -> {
SharedPreferences pref = context.getSharedPreferences("js_engine_" + args[0].toString(), Context.MODE_PRIVATE);
return pref.getString(args[1].toString(), "");
});
local.setProperty("set", args -> {
SharedPreferences pref = context.getSharedPreferences("js_engine_" + args[0].toString(), Context.MODE_PRIVATE);
pref.edit().putString(args[1].toString(), args[2].toString()).apply();
return null;
});
local.setProperty("delete", args -> {
SharedPreferences pref = context.getSharedPreferences("js_engine_" + args[0].toString(), Context.MODE_PRIVATE);
pref.edit().remove(args[1].toString()).apply();
return null;
});
static {
System.loadLibrary("quickjs");
}
private void initReq() {
jsContext.getGlobalObject().setProperty("req", args -> {
JSObject jsObject = jsContext.createNewJSObject();
JSObject jsHeader = jsContext.createNewJSObject();
setReqObject(jsObject, jsHeader, args);
return jsObject;
public Loader() {
Worker.submit(() -> {
JSModule.setModuleLoader(name -> Module.get().load(name));
initCtx();
});
}
private void setReqObject(JSObject jsObject, JSObject jsHeader, Object... args) {
try {
JSONObject obj = new JSONObject(jsContext.stringify((JSObject) args[1]));
Response response = OkHttp.get().newCall(args[0].toString(), obj).execute();
for (String name : response.headers().names()) jsHeader.setProperty(name, response.header(name));
jsObject.setProperty("headers", jsHeader);
setReqContent(jsObject, obj, response);
} catch (Throwable e) {
jsObject.setProperty("headers", jsHeader);
jsObject.setProperty("content", "");
}
private void initCtx() {
ctx = QuickJSContext.create();
ctx.getGlobalObject().setProperty("console", Console.class);
ctx.getGlobalObject().setProperty("local", Local.class);
Global.create(ctx).setProperty();
}
private void setReqContent(JSObject jsObject, JSONObject obj, Response response) throws IOException {
switch (obj.optInt("buffer")) {
case 1:
byte[] bytes = response.body().bytes();
JSArray array = jsContext.createNewJSArray();
for (int i = 0; i < bytes.length; i++) array.set(bytes[i], i);
jsObject.setProperty("content", array);
break;
case 2:
jsObject.setProperty("content", Base64.encodeToString(response.body().bytes(), Base64.DEFAULT));
break;
default:
jsObject.setProperty("content", response.body().string());
break;
}
public Spider spider(String api, String ext) {
return new Spider(ctx, api, ext);
}
}

@ -0,0 +1,29 @@
package com.hiker.drpy;
import com.hiker.drpy.net.OkHttp;
import java.util.concurrent.ConcurrentHashMap;
public class Module {
private final ConcurrentHashMap<String, String> cache;
private static class Loader {
static volatile Module INSTANCE = new Module();
}
public static Module get() {
return Loader.INSTANCE;
}
public Module() {
this.cache = new ConcurrentHashMap<>();
}
public String load(String name) {
if (cache.contains(name)) return cache.get(name);
String content = OkHttp.get().module(name);
cache.put(name, content);
return content;
}
}

@ -1,6 +1,78 @@
package com.hiker.drpy;
import android.content.Context;
import com.github.tvbox.quickjs.JSObject;
import com.github.tvbox.quickjs.QuickJSContext;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class Spider extends com.github.catvod.crawler.Spider {
private QuickJSContext ctx;
private JSObject jsObject;
private String api;
private String ext;
private String key;
public Spider(QuickJSContext ctx, String api, String ext) {
this.key = "__" + UUID.randomUUID().toString().replace("-", "") + "__";
this.ctx = ctx;
this.api = api;
this.ext = ext;
}
private String getContent() {
return Module.get().load(api)
.replace("export default{", "globalThis." + key + " ={")
.replace("export default {", "globalThis." + key + " ={")
.replace("__JS_SPIDER__", "globalThis." + key);
}
@Override
public void init(Context context, String extend) throws Exception {
super.init(context, extend);
Worker.submit(() -> {
ctx.evaluateModule(getContent(), api);
jsObject = (JSObject) ctx.getProperty(ctx.getGlobalObject(), key);
jsObject.getJSFunction("init").call(ext);
});
}
private String post(String func, Object... args) throws ExecutionException, InterruptedException {
return (String) Worker.submit(() -> (String) jsObject.getJSFunction(func).call(args)).get();
}
@Override
public String homeContent(boolean filter) throws Exception {
return post("home", filter);
}
@Override
public String homeVideoContent() throws Exception {
return post("homeVod");
}
@Override
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
return post("category", tid, pg, filter, null);
}
@Override
public String detailContent(List<String> ids) throws Exception {
return post("detail", ids.get(0));
}
@Override
public String searchContent(String key, boolean quick) throws Exception {
return post("search", key, quick);
}
@Override
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
return post("play", flag, id, null);
}
}

@ -0,0 +1,31 @@
package com.hiker.drpy;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Worker {
private final ExecutorService executor;
private static class Loader {
static volatile Worker INSTANCE = new Worker();
}
private static Worker get() {
return Loader.INSTANCE;
}
public Worker() {
executor = Executors.newSingleThreadExecutor();
}
public static void submit(Runnable runnable) {
get().executor.submit(runnable);
}
public static Future<?> submit(Callable<String> callable) {
return get().executor.submit(callable);
}
}

@ -0,0 +1,15 @@
package com.hiker.drpy.method;
import android.util.Log;
import com.github.tvbox.quickjs.JSMethod;
public class Console {
private final String TAG = Console.class.getSimpleName();
@JSMethod
public void log(String msg) {
Log.d(TAG, msg);
}
}

@ -0,0 +1,126 @@
package com.hiker.drpy.method;
import android.text.TextUtils;
import android.util.Base64;
import com.github.tvbox.quickjs.JSArray;
import com.github.tvbox.quickjs.JSMethod;
import com.github.tvbox.quickjs.JSObject;
import com.github.tvbox.quickjs.QuickJSContext;
import com.google.gson.Gson;
import com.hiker.drpy.Parser;
import com.hiker.drpy.net.OkHttp;
import org.json.JSONObject;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import okhttp3.Response;
public class Global {
private final QuickJSContext ctx;
public static Global create(QuickJSContext jsContext) {
return new Global(jsContext);
}
private Global(QuickJSContext ctx) {
this.ctx = ctx;
}
public void setProperty() {
for (Method method : getClass().getMethods()) {
if (!method.isAnnotationPresent(JSMethod.class)) continue;
ctx.getGlobalObject().setProperty(method.getName(), args -> {
try {
return method.invoke(this, args);
} catch (IllegalAccessException | InvocationTargetException e) {
return null;
}
});
}
}
@JSMethod
public JSObject req(String url, JSObject object) {
try {
JSObject jsObject = ctx.createNewJSObject();
JSObject jsHeader = ctx.createNewJSObject();
JSONObject obj = new JSONObject(ctx.stringify(object));
Response response = OkHttp.get().newCall(url, obj).execute();
for (String name : response.headers().names()) jsHeader.setProperty(name, response.header(name));
jsObject.setProperty("headers", jsHeader);
setReqContent(jsObject, obj, response);
return jsObject;
} catch (Throwable e) {
return null;
}
}
@JSMethod
public String pd(String html, String rule, String urlKey) {
try {
return Parser.parseDomForUrl(html, rule, urlKey);
} catch (Throwable e) {
e.printStackTrace();
return "";
}
}
@JSMethod
public JSObject pdfa(String html, String rule) {
try {
return ctx.parseJSON(new Gson().toJson(Parser.parseDomForList(html, rule)));
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
@JSMethod
public String pdfh(String html, String rule) {
try {
return Parser.parseDomForUrl(html, rule, "");
} catch (Throwable e) {
e.printStackTrace();
return "";
}
}
@JSMethod
public JSObject pdfl(String html, String p1, String list_text, String list_url, String urlKey) {
return null;
}
@JSMethod
public String joinUrl(String parent, String child) {
try {
if (TextUtils.isEmpty(parent)) return child;
return new URL(new URL(parent), child).toString();
} catch (Throwable e) {
e.printStackTrace();
return "";
}
}
private void setReqContent(JSObject jsObject, JSONObject obj, Response response) throws IOException {
switch (obj.optInt("buffer")) {
case 1:
byte[] bytes = response.body().bytes();
JSArray array = ctx.createNewJSArray();
for (int i = 0; i < bytes.length; i++) array.set(bytes[i], i);
jsObject.setProperty("content", array);
break;
case 2:
jsObject.setProperty("content", Base64.encodeToString(response.body().bytes(), Base64.DEFAULT));
break;
default:
jsObject.setProperty("content", response.body().string());
break;
}
}
}

@ -0,0 +1,26 @@
package com.hiker.drpy.method;
import com.github.tvbox.quickjs.JSMethod;
import java.util.HashMap;
import java.util.Map;
public class Local {
private final Map<String, String> maps = new HashMap<>();
@JSMethod
public String get(String R_KEY, String k) {
return maps.get("js_engine_" + R_KEY + "_" + k);
}
@JSMethod
public void set(String R_KEY, String k, String v) {
maps.put("js_engine_" + R_KEY + "_" + k, v);
}
@JSMethod
public void delete(String R_KEY, String k) {
maps.remove("js_engine_" + R_KEY + "_" + k);
}
}

@ -42,6 +42,15 @@ public class OkHttp {
return noRedirect;
}
public String module(String url) {
try {
return client().newCall(new Request.Builder().url(url).header("User-Agent", "Mozilla/5.0").build()).execute().body().string();
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
public Call newCall(String url, JSONObject object) {
int redirect = object.optInt("redirect", 1);
int timeout = object.optInt("timeout", 10000);

Loading…
Cancel
Save