Merge branch 'dev' into release

pull/137/head
FongMi 4 years ago
commit 7c3915f4c3
  1. 19
      app/build.gradle
  2. 9
      app/proguard-rules.pro
  3. 2
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java
  4. 2
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java
  5. 2
      app/src/leanback/res/layout/adapter_config.xml
  6. 4
      app/src/leanback/res/layout/dialog_config.xml
  7. 2
      app/src/leanback/res/values-zh-rCN/strings.xml
  8. 2
      app/src/leanback/res/values-zh-rTW/strings.xml
  9. 39
      app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java
  10. 50
      app/src/main/java/com/fongmi/android/tv/api/PyLoader.java
  11. 18
      app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java
  12. 2
      app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java
  13. 2
      app/src/main/java/com/fongmi/android/tv/ui/custom/ProgressLayout.java
  14. 4
      app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java
  15. 2
      app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java
  16. 7
      app/src/main/java/com/fongmi/android/tv/utils/Updater.java
  17. 9
      app/src/main/java/com/fongmi/android/tv/utils/Utils.java
  18. 2
      app/src/main/res/values/strings.xml
  19. 1
      build.gradle
  20. 1
      pyramid/.gitignore
  21. 35
      pyramid/build.gradle
  22. 2
      pyramid/src/main/AndroidManifest.xml
  23. 26
      pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java
  24. 58
      pyramid/src/main/java/com/undcover/freedom/pyramid/PySpider.java
  25. 144
      pyramid/src/main/python/app.py
  26. 109
      pyramid/src/main/python/base/spider.py
  27. 39
      pyramid/src/main/python/runner.py
  28. 36
      pyramid/src/main/python/trigger.py
  29. 3
      settings.gradle

@ -4,24 +4,30 @@ plugins {
android {
compileSdk 33
flavorDimensions "default"
flavorDimensions "mode", "api"
defaultConfig {
applicationId "com.fongmi.android.tv"
minSdk 21
targetSdk 33
versionCode 37
versionName "1.3.7"
versionCode 38
versionName "1.3.8"
resValue "string", "url", ""
ndk { abiFilters "armeabi-v7a" }
}
productFlavors {
leanback {
dimension "default"
dimension "mode"
}
mobile {
dimension "default"
dimension "mode"
}
java {
dimension = "api"
}
python {
dimension = "api"
}
}
@ -45,13 +51,14 @@ android {
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
outputFileName = "${variant.productFlavors[0].name}.apk"
outputFileName = "${variant.productFlavors[0].name}-${variant.productFlavors[1].name}.apk"
}
}
}
dependencies {
implementation project(':catvod')
pythonImplementation project(':pyramid')
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.core:core-splashscreen:1.0.0'
implementation 'androidx.preference:preference:1.2.0'

@ -22,9 +22,12 @@
-keepclassmembers,allowobfuscation class * { @org.simpleframework.xml.Path <fields>; }
-keepclassmembers,allowobfuscation class * { @org.simpleframework.xml.ElementList <fields>; }
# CatVod
-keep class com.github.catvod.crawler.** { *; }
# OkHttp
-dontwarn okhttp3.**
-keep class okhttp3.** { *; }
# CatVod
-keep class com.github.catvod.crawler.** { *; }
# Pyramid
-keep class com.undcover.freedom.pyramid.** { *; }

@ -57,7 +57,7 @@ public class ConfigDialog implements DialogInterface.OnDismissListener {
String address = Server.get().getAddress(false);
binding.text.setText(Prefers.getUrl());
binding.text.setSelection(binding.text.getText().length());
binding.code.setImageBitmap(QRCode.getBitmap(address, 180, 0));
binding.code.setImageBitmap(QRCode.getBitmap(address, 200, 0));
binding.info.setText(ResUtil.getString(R.string.push_info, address).replace(",", "\n"));
}

@ -47,7 +47,7 @@ public class SiteDialog implements SitePresenter.OnClickListener {
private void setDialog() {
WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.width = (int) (ResUtil.getScreenWidthPx() * 0.4f);
params.height = (int) (ResUtil.getScreenHeightPx() * 0.64f);
params.height = (int) (ResUtil.getScreenHeightPx() * 0.74f);
dialog.getWindow().setAttributes(params);
dialog.getWindow().setDimAmount(0);
dialog.show();

@ -11,7 +11,7 @@
android:layout_height="40dp"
android:layout_weight="1"
android:background="@drawable/selector_text"
android:ellipsize="marquee"
android:ellipsize="middle"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"

@ -9,13 +9,13 @@
android:id="@+id/code"
android:layout_width="180dp"
android:layout_height="180dp"
android:scaleType="fitXY" />
android:scaleType="centerCrop" />
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginStart="12dp"
android:layout_toEndOf="@+id/code"
android:lineSpacingExtra="4dp"
android:paddingStart="4dp"

@ -20,6 +20,6 @@
<string name="collect_result"><xliff:g name="name">%s</xliff:g>”的搜索结果</string>
<!-- Push -->
<string name="push_info">请用手机扫描二维码,或于浏览器中访问地址\n<xliff:g name="name">%s</xliff:g></string>
<string name="push_info">使用手机扫描二维码,或于浏览器访问地址\n<xliff:g name="name">%s</xliff:g></string>
</resources>

@ -20,6 +20,6 @@
<string name="collect_result"><xliff:g name="name">%s</xliff:g>」的搜尋結果</string>
<!-- Push -->
<string name="push_info">請用手機掃描 QR Code,或於瀏覽器中輸入網址\n<xliff:g name="name">%s</xliff:g></string>
<string name="push_info">使用手機掃描 QR Code,或於瀏覽器輸入網址\n<xliff:g name="name">%s</xliff:g></string>
</resources>

@ -15,6 +15,7 @@ import com.fongmi.android.tv.utils.Json;
import com.fongmi.android.tv.utils.Prefers;
import com.fongmi.android.tv.utils.Utils;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderNull;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@ -36,7 +37,8 @@ public class ApiConfig {
private List<Parse> parses;
private List<Live> lives;
private List<Site> sites;
private JarLoader loader;
private JarLoader jLoader;
private PyLoader pLoader;
private Handler handler;
private Parse parse;
private Site home;
@ -72,7 +74,8 @@ public class ApiConfig {
this.lives = new ArrayList<>();
this.flags = new ArrayList<>();
this.parses = new ArrayList<>();
this.loader = new JarLoader();
this.jLoader = new JarLoader();
this.pLoader = new PyLoader();
this.handler = new Handler(Looper.getMainLooper());
return this;
}
@ -88,25 +91,26 @@ public class ApiConfig {
}).start();
}
private void loadCache(String url, Callback callback) {
String json = Config.find(url).getJson();
if (!TextUtils.isEmpty(json)) parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback);
else handler.post(() -> callback.error(R.string.error_config_get));
}
private void loadConfig(String url, Callback callback) {
try {
parseConfig(new Gson().fromJson(Decoder.getJson(url), JsonObject.class), callback);
} catch (Exception e) {
if (url.isEmpty()) handler.post(() -> callback.error(0));
else loadCache(url, callback);
e.printStackTrace();
loadCache(url, callback);
}
}
private void loadCache(String url, Callback callback) {
String json = Config.find(url).getJson();
if (!TextUtils.isEmpty(json)) parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback);
else handler.post(() -> callback.error(R.string.error_config_get));
}
private void parseConfig(JsonObject object, Callback callback) {
try {
parseJson(object);
loader.parseJar("", Json.safeString(object, "spider", ""));
jLoader.parseJar("", Json.safeString(object, "spider", ""));
handler.post(() -> callback.success(object.toString()));
} catch (Exception e) {
e.printStackTrace();
@ -141,19 +145,23 @@ public class ApiConfig {
}
public Spider getCSP(Site site) {
return loader.getSpider(site.getKey(), site.getApi(), site.getExt(), site.getJar());
boolean py = site.getApi().startsWith("py_");
boolean csp = site.getApi().startsWith("csp_");
if (py) return pLoader.getSpider(site.getKey(), site.getApi(), site.getExt());
else if (csp) return jLoader.getSpider(site.getKey(), site.getApi(), site.getExt(), site.getJar());
else return new SpiderNull();
}
public Object[] proxyLocal(Map<?, ?> param) {
return loader.proxyInvoke(param);
return jLoader.proxyInvoke(param);
}
public JSONObject jsonExt(String key, LinkedHashMap<String, String> jxs, String url) {
return loader.jsonExt(key, jxs, url);
return jLoader.jsonExt(key, jxs, url);
}
public JSONObject jsonExtMix(String flag, String key, String name, LinkedHashMap<String, HashMap<String, String>> jxs, String url) {
return loader.jsonExtMix(flag, key, name, jxs, url);
return jLoader.jsonExtMix(flag, key, name, jxs, url);
}
public Site getSite(String key) {
@ -214,7 +222,8 @@ public class ApiConfig {
this.lives.clear();
this.flags.clear();
this.parses.clear();
this.loader.clear();
this.jLoader.clear();
this.pLoader.clear();
this.home = null;
return this;
}

@ -0,0 +1,50 @@
package com.fongmi.android.tv.api;
import android.content.Context;
import android.net.Uri;
import com.fongmi.android.tv.App;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderNull;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
public class PyLoader {
private final ConcurrentHashMap<String, Spider> spiders;
private Object loader;
public PyLoader() {
spiders = new ConcurrentHashMap<>();
init();
}
public void clear() {
this.spiders.clear();
}
private void init() {
try {
loader = Class.forName("com.undcover.freedom.pyramid.Loader").newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public Spider getSpider(String key, String api, String ext) {
try {
if (spiders.containsKey(key)) return spiders.get(key);
String extend = Uri.parse(ext).getQueryParameter("extend");
Method method = loader.getClass().getMethod("spider", Context.class, String.class);
Spider spider = (Spider) method.invoke(loader, App.get(), ext);
extend = extend == null ? "" : extend;
spider.init(App.get(), extend);
spiders.put(key, spider);
return spider;
} catch (Exception e) {
e.printStackTrace();
return new SpiderNull();
}
}
}

@ -2,12 +2,9 @@ package com.fongmi.android.tv.db;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.bean.Config;
@ -33,7 +30,7 @@ public abstract class AppDatabase extends RoomDatabase {
}
private static AppDatabase create(Context context) {
return Room.databaseBuilder(context, AppDatabase.class, "tv").addMigrations(MIGRATION_8_9).addMigrations(MIGRATION_9_11).allowMainThreadQueries().fallbackToDestructiveMigration().build();
return Room.databaseBuilder(context, AppDatabase.class, "tv").allowMainThreadQueries().fallbackToDestructiveMigration().build();
}
public abstract KeepDao getKeepDao();
@ -43,17 +40,4 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract ConfigDao getConfigDao();
public abstract HistoryDao getHistoryDao();
static final Migration MIGRATION_8_9 = new Migration(8, 9) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `Keep` (`key` TEXT NOT NULL, `siteName` TEXT, `vodName` TEXT, `vodPic` TEXT, `createTime` INTEGER NOT NULL, `cid` INTEGER NOT NULL, PRIMARY KEY(`key`))");
}
};
static final Migration MIGRATION_9_11 = new Migration(9, 11) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
}
};
}

@ -114,7 +114,7 @@ public class CustomWebView extends WebView {
handler.removeCallbacks(mTimer);
handler.post(() -> {
if (callback != null) callback.onParseSuccess(news, url, "");
SpiderDebug.log(url);
SpiderDebug.log(url + "," + headers);
stop(false);
});
}

@ -114,9 +114,7 @@ public class ProgressLayout extends RelativeLayout {
}
private void showView(View view) {
view.setAlpha(0f);
view.setVisibility(VISIBLE);
view.animate().alpha(1f).setDuration(250).setListener(null);
}
private void hideView(View view) {

@ -70,9 +70,9 @@ public class FileUtil {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getLocal(path))));
StringBuilder sb = new StringBuilder();
String text;
while ((text = br.readLine()) != null) sb.append(text);
while ((text = br.readLine()) != null) sb.append(text).append("\n");
br.close();
return sb.toString();
return Utils.substring(sb.toString());
} catch (Exception e) {
return "";
}

@ -8,8 +8,6 @@ public class Sniffer {
"http((?!http).){12,}?\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg)\\?.*|" +
"http((?!http).){12,}\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg)|" +
"http((?!http).)*?xg.php\\?id=|" +
"http((?!http).)*?cdn-tos|" +
"http((?!http).)*?obj/tos|" +
"http((?!http).)*?video/tos*"
);
}

@ -22,7 +22,9 @@ import java.util.concurrent.Executors;
public class Updater implements View.OnClickListener {
private static final String URL = "https://raw.githubusercontent.com/FongMi/TV/release/release/leanback.json";
private static final String DEF = "https://raw.githubusercontent.com/FongMi/TV/release/release/";
private static final String URL = DEF + BuildConfig.FLAVOR_mode + ".json";
private static final String APK = DEF + BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + ".apk";
private static final String PROXY = "https://ghproxy.com/";
private final ExecutorService executor;
@ -62,9 +64,8 @@ public class Updater implements View.OnClickListener {
JSONObject object = new JSONObject(OKHttp.newCall(target).execute().body().string());
String name = object.optString("name");
String desc = object.optString("desc");
String url = object.optString("url");
int code = object.optInt("code");
if (retry > 0) url = PROXY + url;
String url = retry > 0 ? PROXY + APK : APK;
if (code <= BuildConfig.VERSION_CODE) FileUtil.clearDir(getApk());
else FileUtil.write(getApk(), OKHttp.newCall(url).execute().body().bytes());
if (getApk().exists() && Prefers.getUpdate()) handler.post(() -> checkActivity(name, desc));

@ -101,6 +101,15 @@ public class Utils {
return Base64.encodeToString(ext.getBytes(), Base64.DEFAULT | Base64.NO_WRAP);
}
public static String substring(String text) {
return substring(text, 1);
}
public static String substring(String text, int num) {
if (text != null && text.length() > num) return text.substring(0, text.length() - num);
return text;
}
public static int getDigit(String text) {
try {
if (text.startsWith("上") || text.startsWith("下")) return -1;

@ -36,7 +36,7 @@
<string name="play_reset">Reset</string>
<string name="play_tracks">Tracks</string>
<string name="play_op">OP</string>
<string name="play_ed">OP</string>
<string name="play_ed">ED</string>
<string name="play_reverse">Reverse</string>
<string name="play_forward"></string>
<string name="play_backward"></string>

@ -1,6 +1,7 @@
plugins {
id 'com.android.application' version '7.2.2' apply false
id 'com.android.library' version '7.2.2' apply false
id 'com.chaquo.python' version '12.0.1' apply false
}
task clean(type: Delete) {

@ -0,0 +1 @@
/build

@ -0,0 +1,35 @@
plugins {
id 'com.android.library'
id 'com.chaquo.python'
}
android {
compileSdk 33
defaultConfig {
minSdk 21
targetSdk 33
ndk { abiFilters "armeabi-v7a" }
python {
buildPython "C:/Users/FongMi.DIREK/Anaconda3/python.exe"
pip {
install "lxml"
install "requests==2.27.1"
install 'pycryptodome'
install 'beautifulsoup4'
}
}
}
sourceSets {
main {
python.srcDirs = ["src/main/python"]
}
}
}
dependencies {
implementation project(':catvod')
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.google.code.gson:gson:2.9.1'
}

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.undcover.freedom.pyramid" />

@ -0,0 +1,26 @@
package com.undcover.freedom.pyramid;
import android.content.Context;
import com.chaquo.python.PyObject;
import com.chaquo.python.Python;
import com.chaquo.python.android.AndroidPlatform;
import com.github.catvod.crawler.Spider;
public class Loader {
private PyObject app;
private String cache;
private void init(Context context) {
if (!Python.isStarted()) Python.start(new AndroidPlatform(context));
cache = context.getCacheDir().getAbsolutePath();
app = Python.getInstance().getModule("app");
}
public Spider spider(Context context, String ext) {
if (app == null) init(context);
String path = app.callAttr("downloadPlugin", cache, ext).toString();
return new PySpider(app, app.callAttr("loadFromDisk", path));
}
}

@ -0,0 +1,58 @@
package com.undcover.freedom.pyramid;
import android.content.Context;
import com.chaquo.python.PyObject;
import com.github.catvod.crawler.Spider;
import com.google.gson.Gson;
import java.util.HashMap;
import java.util.List;
public class PySpider extends Spider {
private final PyObject app;
private final PyObject obj;
private final Gson gson;
public PySpider(PyObject app, PyObject obj) {
this.gson = new Gson();
this.app = app;
this.obj = obj;
}
@Override
public void init(Context context, String extend) {
app.callAttr("init", obj, extend);
}
@Override
public String homeContent(boolean filter) {
return app.callAttr("homeContent", obj, filter).toString();
}
@Override
public String homeVideoContent() {
return app.callAttr("homeVideoContent", obj).toString();
}
@Override
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
return app.callAttr("categoryContent", obj, tid, pg, filter, gson.toJson(extend)).toString();
}
@Override
public String detailContent(List<String> ids) {
return app.callAttr("detailContent", obj, gson.toJson(ids)).toString();
}
@Override
public String searchContent(String key, boolean quick) {
return app.callAttr("searchContent", obj, key, quick).toString();
}
@Override
public String playerContent(String flag, String id, List<String> vipFlags) {
return app.callAttr("playerContent", obj, flag, id, gson.toJson(vipFlags)).toString();
}
}

@ -0,0 +1,144 @@
import os
import requests
from importlib.machinery import SourceFileLoader
from urllib import parse
import json
def createFile(file_path):
if os.path.exists(file_path) is False:
os.makedirs(file_path)
def redirectResponse(tUrl):
rsp = requests.get(tUrl, allow_redirects=False, verify=False)
if 'Location' in rsp.headers:
return redirectResponse(rsp.headers['Location'])
else:
return rsp
def downloadFile(name, url):
try:
rsp = redirectResponse(url)
with open(name, 'wb') as f:
f.write(rsp.content)
print(url)
except:
print(name + ' =======================================> error')
print(url)
def downloadPlugin(basePath, url):
createFile(basePath)
name = url.split('/')[-1].split('.')[0]
if url.startswith('file://'):
pyName = url.replace('file://', '')
else:
pyName = basePath + name + '.py'
downloadFile(pyName, url)
sPath = gParam['SpiderPath']
sPath[name] = pyName
sParam = gParam['SpiderParam']
paramList = parse.parse_qs(parse.urlparse(url).query).get('extend')
if paramList == None:
paramList = ['']
sParam[name] = paramList[0]
return pyName
def loadFromDisk(fileName):
name = fileName.split('/')[-1].split('.')[0]
spList = gParam['SpiderList']
if name not in spList:
sp = SourceFileLoader(name, fileName).load_module().Spider()
spList[name] = sp
return spList[name]
def str2json(content):
return json.loads(content)
gParam = {
"SpiderList": {},
"SpiderPath": {},
"SpiderParam": {}
}
def getDependence(ru):
result = ru.getDependence()
return result
def getName(ru):
result = ru.getName()
return result
def init(ru, extend):
spoList = []
spList = gParam['SpiderList']
sPath = gParam['SpiderPath']
sParam = gParam['SpiderParam']
for key in ru.getDependence():
sp = None
if key in spList.keys():
sp = spList[key]
elif key in sPath.keys():
sp = loadFromDisk(sPath[key])
if sp != None:
sp.setExtendInfo(sParam[key])
spoList.append(sp)
ru.setExtendInfo(extend)
ru.init(spoList)
def homeContent(ru, filter):
result = ru.homeContent(filter)
formatJo = json.dumps(result, ensure_ascii=False)
return formatJo
def homeVideoContent(ru):
result = ru.homeVideoContent()
formatJo = json.dumps(result, ensure_ascii=False)
return formatJo
def categoryContent(ru, tid, pg, filter, extend):
result = ru.categoryContent(tid, pg, filter, str2json(extend))
formatJo = json.dumps(result, ensure_ascii=False)
return formatJo
def detailContent(ru, array):
result = ru.detailContent(str2json(array))
formatJo = json.dumps(result, ensure_ascii=False)
return formatJo
def playerContent(ru, flag, id, vipFlags):
result = ru.playerContent(flag, id, str2json(vipFlags))
formatJo = json.dumps(result, ensure_ascii=False)
return formatJo
def searchContent(ru, key, quick):
result = ru.searchContent(key, quick)
formatJo = json.dumps(result, ensure_ascii=False)
return formatJo
def localProxy(ru, param):
result = ru.localProxy(str2json(param))
return result
def run():
pass
if __name__ == '__main__':
run()

@ -0,0 +1,109 @@
import re
import json
import requests
from lxml import etree
from abc import abstractmethod, ABCMeta
from importlib.machinery import SourceFileLoader
class Spider(metaclass=ABCMeta):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance:
return cls._instance
else:
cls._instance = super().__new__(cls)
return cls._instance
@abstractmethod
def init(self, extend=""):
pass
@abstractmethod
def homeContent(self, filter):
pass
@abstractmethod
def homeVideoContent(self):
pass
@abstractmethod
def categoryContent(self, tid, pg, filter, extend):
pass
@abstractmethod
def detailContent(self, ids):
pass
@abstractmethod
def searchContent(self, key, quick):
pass
@abstractmethod
def playerContent(self, flag, id, vipFlags):
pass
@abstractmethod
def localProxy(self, param):
pass
@abstractmethod
def isVideoFormat(self, url):
pass
@abstractmethod
def manualVideoCheck(self):
pass
@abstractmethod
def getName(self):
pass
def getDependence(self):
return []
def setExtendInfo(self, extend):
self.extend = extend
def regStr(self, src, reg, group=1):
m = re.search(reg, src)
src = ''
if m:
src = m.group(group)
return src
def str2json(self, str):
return json.loads(str)
def cleanText(self, src):
clean = re.sub('[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F1E0-\U0001F1FF]', '', src)
return clean
def fetch(self, url, headers={}, cookies=""):
rsp = requests.get(url, headers=headers, cookies=cookies)
rsp.encoding = 'utf-8'
return rsp
def post(self, url, data, headers={}, cookies={}):
rsp = requests.post(url, data=data, headers=headers, cookies=cookies)
rsp.encoding = 'utf-8'
return rsp
def postJson(self, url, json, headers={}, cookies={}):
rsp = requests.post(url, json=json, headers=headers, cookies=cookies)
rsp.encoding = 'utf-8'
return rsp
def html(self, content):
return etree.HTML(content)
def xpText(self, root, expr):
ele = root.xpath(expr)
if len(ele) == 0:
return ''
else:
return ele[0]
def loadModule(self, name, fileName):
return SourceFileLoader(name, fileName).load_module()

@ -0,0 +1,39 @@
class Runner():
def __init__(self, spider):
self.spider = spider
def getDependence(self):
return self.spider.getDependence()
def getName(self):
return self.spider.getName()
def init(self, extend=""):
self.spider.init(extend)
def homeContent(self, filter):
return self.spider.homeContent(filter)
def homeVideoContent(self):
return self.spider.homeVideoContent()
def categoryContent(self, tid, pg, filter, extend):
return self.spider.categoryContent(tid, pg, filter, extend)
def detailContent(self, ids):
return self.spider.detailContent(ids)
def searchContent(self, key, quick):
return self.spider.searchContent(key, quick)
def playerContent(self, flag, id, vipFlags):
return self.spider.playerContent(flag, id, vipFlags)
def localProxy(self, param):
return self.spider.localProxy(param)
def isVideoFormat(self, url):
return self.spider.isVideoFormat(url)
def manualVideoCheck(self):
return self.spider.manualVideoCheck()

@ -0,0 +1,36 @@
class Trigger():
@staticmethod
def init(sp_obj, extend=""):
sp_obj.init(extend)
@staticmethod
def homeContent(sp_obj, filter):
return sp_obj.homeContent(filter)
@staticmethod
def homeVideoContent(sp_obj):
return sp_obj.homeVideoContent()
@staticmethod
def categoryContent(sp_obj, tid, pg, filter, extend):
return sp_obj.categoryContent(tid, pg, filter, extend)
@staticmethod
def detailContent(sp_obj, ids):
return sp_obj.detailContent(ids)
@staticmethod
def searchContent(sp_obj, key, quick):
return sp_obj.searchContent(key, quick)
@staticmethod
def playerContent(sp_obj, flag, id, vipFlags):
return sp_obj.playerContent(flag, id, vipFlags)
@staticmethod
def isVideoFormat(sp_obj, url):
return sp_obj.isVideoFormat(url)
@staticmethod
def manualVideoCheck(sp_obj):
return sp_obj.manualVideoCheck()

@ -16,4 +16,5 @@ dependencyResolutionManagement {
}
include ':app'
include ':catvod'
rootProject.name = "TV"
include ':pyramid'
rootProject.name = "TV"

Loading…
Cancel
Save