From d62c520667478642c00364866dee2809a090d1e1 Mon Sep 17 00:00:00 2001 From: FongMi Date: Wed, 12 Oct 2022 01:22:25 +0800 Subject: [PATCH 1/6] init py --- build.gradle | 1 + pyramid/.gitignore | 1 + pyramid/build.gradle | 34 ++++++ pyramid/src/main/AndroidManifest.xml | 2 + pyramid/src/main/python/app.py | 144 +++++++++++++++++++++++++ pyramid/src/main/python/base/spider.py | 109 +++++++++++++++++++ pyramid/src/main/python/runner.py | 39 +++++++ pyramid/src/main/python/trigger.py | 36 +++++++ settings.gradle | 3 +- 9 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 pyramid/.gitignore create mode 100644 pyramid/build.gradle create mode 100644 pyramid/src/main/AndroidManifest.xml create mode 100644 pyramid/src/main/python/app.py create mode 100644 pyramid/src/main/python/base/spider.py create mode 100644 pyramid/src/main/python/runner.py create mode 100644 pyramid/src/main/python/trigger.py diff --git a/build.gradle b/build.gradle index 53a4e6ec0..fab0d5e68 100644 --- a/build.gradle +++ b/build.gradle @@ -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) { diff --git a/pyramid/.gitignore b/pyramid/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/pyramid/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/pyramid/build.gradle b/pyramid/build.gradle new file mode 100644 index 000000000..fb7152202 --- /dev/null +++ b/pyramid/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'com.android.library' + id 'com.chaquo.python' +} + +android { + compileSdk 33 + + defaultConfig { + minSdk 21 + targetSdk 33 + ndk { abiFilters "armeabi-v7a" } + python { + buildPython "D:/python/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' +} \ No newline at end of file diff --git a/pyramid/src/main/AndroidManifest.xml b/pyramid/src/main/AndroidManifest.xml new file mode 100644 index 000000000..c406568a6 --- /dev/null +++ b/pyramid/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/pyramid/src/main/python/app.py b/pyramid/src/main/python/app.py new file mode 100644 index 000000000..adbb45dd2 --- /dev/null +++ b/pyramid/src/main/python/app.py @@ -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() diff --git a/pyramid/src/main/python/base/spider.py b/pyramid/src/main/python/base/spider.py new file mode 100644 index 000000000..2dc949799 --- /dev/null +++ b/pyramid/src/main/python/base/spider.py @@ -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() diff --git a/pyramid/src/main/python/runner.py b/pyramid/src/main/python/runner.py new file mode 100644 index 000000000..203462740 --- /dev/null +++ b/pyramid/src/main/python/runner.py @@ -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() diff --git a/pyramid/src/main/python/trigger.py b/pyramid/src/main/python/trigger.py new file mode 100644 index 000000000..8524930eb --- /dev/null +++ b/pyramid/src/main/python/trigger.py @@ -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() diff --git a/settings.gradle b/settings.gradle index 244507fc6..9c5b6eb6f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,6 +16,7 @@ dependencyResolutionManagement { } include ':app' include ':catvod' +include ':pyramid' rootProject.name = "TV" gradle.ext.exoplayerModulePrefix = 'exoplayer-' -apply from: file("/exo/core_settings.gradle") \ No newline at end of file +apply from: file("/exo/core_settings.gradle") From 939b04c0f3f9bbd18abeefcbf0d474d3bf14a614 Mon Sep 17 00:00:00 2001 From: FongMi Date: Wed, 12 Oct 2022 14:16:29 +0800 Subject: [PATCH 2/6] Fix some bug --- .../com/fongmi/android/tv/api/ApiConfig.java | 15 ++++++++------- .../com/fongmi/android/tv/db/AppDatabase.java | 18 +----------------- .../android/tv/ui/custom/CustomWebView.java | 2 +- .../com/fongmi/android/tv/utils/FileUtil.java | 4 ++-- .../com/fongmi/android/tv/utils/Sniffer.java | 2 -- .../com/fongmi/android/tv/utils/Utils.java | 9 +++++++++ 6 files changed, 21 insertions(+), 29 deletions(-) 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 4b866e8c4..7f72e24dd 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 @@ -88,21 +88,22 @@ 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); diff --git a/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java b/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java index 2114f73fa..a5c790af7 100644 --- a/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java +++ b/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java @@ -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) { - } - }; } diff --git a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java index 165b497dd..6226d1ead 100644 --- a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java +++ b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java @@ -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); }); } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java index b5e59eea6..930c8260d 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java @@ -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 ""; } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java b/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java index 537cbb10a..dcd360309 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java @@ -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*" ); } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Utils.java b/app/src/main/java/com/fongmi/android/tv/utils/Utils.java index 4d5a5ed21..311549da8 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Utils.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Utils.java @@ -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; From 83954bffbdc6648664bd7538378e5241501e52c2 Mon Sep 17 00:00:00 2001 From: FongMi Date: Wed, 12 Oct 2022 15:53:05 +0800 Subject: [PATCH 3/6] Adjust dialog --- .../com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java | 2 +- .../com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java | 2 +- app/src/leanback/res/layout/adapter_config.xml | 2 +- app/src/leanback/res/layout/dialog_config.xml | 4 ++-- app/src/leanback/res/values-zh-rCN/strings.xml | 2 +- app/src/leanback/res/values-zh-rTW/strings.xml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java index 52c99f47d..d94f825d3 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java @@ -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")); } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java index 87d5806f1..005d06de6 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java @@ -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(); diff --git a/app/src/leanback/res/layout/adapter_config.xml b/app/src/leanback/res/layout/adapter_config.xml index 215387ba1..4c53705b3 100644 --- a/app/src/leanback/res/layout/adapter_config.xml +++ b/app/src/leanback/res/layout/adapter_config.xml @@ -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" diff --git a/app/src/leanback/res/layout/dialog_config.xml b/app/src/leanback/res/layout/dialog_config.xml index bb76a8b79..79fff57d6 100644 --- a/app/src/leanback/res/layout/dialog_config.xml +++ b/app/src/leanback/res/layout/dialog_config.xml @@ -9,13 +9,13 @@ android:id="@+id/code" android:layout_width="180dp" android:layout_height="180dp" - android:scaleType="fitXY" /> + android:scaleType="centerCrop" /> %s”的搜索结果 - 请用手机扫描二维码,或于浏览器中访问地址\n%s + 使用手机扫描二维码,或于浏览器访问地址\n%s \ No newline at end of file diff --git a/app/src/leanback/res/values-zh-rTW/strings.xml b/app/src/leanback/res/values-zh-rTW/strings.xml index 3eca402e6..b6b9f6efe 100644 --- a/app/src/leanback/res/values-zh-rTW/strings.xml +++ b/app/src/leanback/res/values-zh-rTW/strings.xml @@ -20,6 +20,6 @@ %s」的搜尋結果 - 請用手機掃描 QR Code,或於瀏覽器中輸入網址\n%s + 使用手機掃描 QR Code,或於瀏覽器輸入網址\n%s \ No newline at end of file From 05a7fb3c2691a8641252adcdacba762c8b18d22c Mon Sep 17 00:00:00 2001 From: FongMi Date: Thu, 13 Oct 2022 01:37:11 +0800 Subject: [PATCH 4/6] Add py --- .../com/fongmi/android/tv/api/ApiConfig.java | 24 +++++--- .../com/fongmi/android/tv/api/PyLoader.java | 52 +++++++++++++++++ .../android/tv/ui/custom/ProgressLayout.java | 2 - pyramid/build.gradle | 3 +- .../com/undcover/freedom/pyramid/Loader.java | 34 +++++++++++ .../undcover/freedom/pyramid/PySpider.java | 58 +++++++++++++++++++ 6 files changed, 162 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/fongmi/android/tv/api/PyLoader.java create mode 100644 pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java create mode 100644 pyramid/src/main/java/com/undcover/freedom/pyramid/PySpider.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 7f72e24dd..cb23048c8 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 @@ -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 parses; private List lives; private List 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; } @@ -107,7 +110,7 @@ public class ApiConfig { 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(); @@ -142,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 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> jxs, String url) { - return loader.jsonExtMix(flag, key, name, jxs, url); + return jLoader.jsonExtMix(flag, key, name, jxs, url); } public Site getSite(String key) { @@ -215,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; } 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 new file mode 100644 index 000000000..d1f939308 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/api/PyLoader.java @@ -0,0 +1,52 @@ +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 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(); + Method method = loader.getClass().getMethod("init", Context.class); + method.invoke(loader, App.get()); + } 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", String.class); + Spider spider = (Spider) method.invoke(loader, ext); + extend = extend == null ? "" : extend; + spider.init(App.get(), extend); + spiders.put(key, spider); + return spider; + } catch (Exception e) { + e.printStackTrace(); + return new SpiderNull(); + } + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/ui/custom/ProgressLayout.java b/app/src/main/java/com/fongmi/android/tv/ui/custom/ProgressLayout.java index d99a1e7b0..ab6f38bf5 100644 --- a/app/src/main/java/com/fongmi/android/tv/ui/custom/ProgressLayout.java +++ b/app/src/main/java/com/fongmi/android/tv/ui/custom/ProgressLayout.java @@ -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) { diff --git a/pyramid/build.gradle b/pyramid/build.gradle index fb7152202..793222c2b 100644 --- a/pyramid/build.gradle +++ b/pyramid/build.gradle @@ -11,7 +11,7 @@ android { targetSdk 33 ndk { abiFilters "armeabi-v7a" } python { - buildPython "D:/python/python.exe" + buildPython "C:/Users/FongMi.DIREK/Anaconda3/python.exe" pip { install "lxml" install "requests==2.27.1" @@ -31,4 +31,5 @@ android { dependencies { implementation project(':catvod') implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'com.google.code.gson:gson:2.9.1' } \ No newline at end of file diff --git a/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java b/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java new file mode 100644 index 000000000..b53b6855b --- /dev/null +++ b/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java @@ -0,0 +1,34 @@ +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; + +import java.util.List; + +public class Loader { + + private PyObject app; + private String cache; + + public void init(Context context) { + new Thread(() -> { + if (!Python.isStarted()) Python.start(new AndroidPlatform(context)); + cache = context.getCacheDir().getAbsolutePath(); + app = Python.getInstance().getModule("app"); + }).start(); + } + + public Spider spider(String ext) { + String path = app.callAttr("downloadPlugin", cache, ext).toString(); + PyObject pySpider = app.callAttr("loadFromDisk", path); + List dependencies = app.callAttr("getDependence", pySpider).asList(); + for (PyObject dependence : dependencies) { + String api = dependence.toString(); + } + return new PySpider(app, pySpider); + } +} diff --git a/pyramid/src/main/java/com/undcover/freedom/pyramid/PySpider.java b/pyramid/src/main/java/com/undcover/freedom/pyramid/PySpider.java new file mode 100644 index 000000000..8907357cb --- /dev/null +++ b/pyramid/src/main/java/com/undcover/freedom/pyramid/PySpider.java @@ -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 extend) { + return app.callAttr("categoryContent", obj, tid, pg, filter, gson.toJson(extend)).toString(); + } + + @Override + public String detailContent(List 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 vipFlags) { + return app.callAttr("playerContent", obj, flag, id, gson.toJson(vipFlags)).toString(); + } +} From 3670d41af5c07a5afced1e381da6fd8170acb949 Mon Sep 17 00:00:00 2001 From: FongMi Date: Thu, 13 Oct 2022 01:44:13 +0800 Subject: [PATCH 5/6] Optimize py init --- .../java/com/fongmi/android/tv/api/PyLoader.java | 6 ++---- .../java/com/undcover/freedom/pyramid/Loader.java | 13 ++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) 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 d1f939308..4b89a638f 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 @@ -27,8 +27,6 @@ public class PyLoader { private void init() { try { loader = Class.forName("com.undcover.freedom.pyramid.Loader").newInstance(); - Method method = loader.getClass().getMethod("init", Context.class); - method.invoke(loader, App.get()); } catch (Exception e) { e.printStackTrace(); } @@ -38,8 +36,8 @@ public class PyLoader { try { if (spiders.containsKey(key)) return spiders.get(key); String extend = Uri.parse(ext).getQueryParameter("extend"); - Method method = loader.getClass().getMethod("spider", String.class); - Spider spider = (Spider) method.invoke(loader, ext); + 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); diff --git a/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java b/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java index b53b6855b..347b886f5 100644 --- a/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java +++ b/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java @@ -14,15 +14,14 @@ public class Loader { private PyObject app; private String cache; - public void init(Context context) { - new Thread(() -> { - if (!Python.isStarted()) Python.start(new AndroidPlatform(context)); - cache = context.getCacheDir().getAbsolutePath(); - app = Python.getInstance().getModule("app"); - }).start(); + 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(String ext) { + public Spider spider(Context context, String ext) { + if (app == null) init(context); String path = app.callAttr("downloadPlugin", cache, ext).toString(); PyObject pySpider = app.callAttr("loadFromDisk", path); List dependencies = app.callAttr("getDependence", pySpider).asList(); From ef727a525827650f7998b1861d4caed95ba2f744 Mon Sep 17 00:00:00 2001 From: FongMi Date: Thu, 13 Oct 2022 11:16:11 +0800 Subject: [PATCH 6/6] Update config --- app/build.gradle | 19 +++++++++++++------ app/proguard-rules.pro | 9 ++++++--- .../com/fongmi/android/tv/utils/Updater.java | 7 ++++--- app/src/main/res/values/strings.xml | 2 +- .../com/undcover/freedom/pyramid/Loader.java | 9 +-------- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1414eefed..49185f3b5 100644 --- a/app/build.gradle +++ b/app/build.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 project(':exoplayer-library') implementation project(':exoplayer-extension-rtmp') implementation project(':exoplayer-extension-ffmpeg') diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 911c21c2f..a54d0a71f 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -22,9 +22,12 @@ -keepclassmembers,allowobfuscation class * { @org.simpleframework.xml.Path ; } -keepclassmembers,allowobfuscation class * { @org.simpleframework.xml.ElementList ; } -# 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.** { *; } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Updater.java b/app/src/main/java/com/fongmi/android/tv/utils/Updater.java index 8aa506aa1..b0adfa347 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Updater.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Updater.java @@ -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)); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 12939b973..bc03133ec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,7 +36,7 @@ Reset Tracks OP - OP + ED Reverse diff --git a/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java b/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java index 347b886f5..842564b59 100644 --- a/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java +++ b/pyramid/src/main/java/com/undcover/freedom/pyramid/Loader.java @@ -7,8 +7,6 @@ import com.chaquo.python.Python; import com.chaquo.python.android.AndroidPlatform; import com.github.catvod.crawler.Spider; -import java.util.List; - public class Loader { private PyObject app; @@ -23,11 +21,6 @@ public class Loader { public Spider spider(Context context, String ext) { if (app == null) init(context); String path = app.callAttr("downloadPlugin", cache, ext).toString(); - PyObject pySpider = app.callAttr("loadFromDisk", path); - List dependencies = app.callAttr("getDependence", pySpider).asList(); - for (PyObject dependence : dependencies) { - String api = dependence.toString(); - } - return new PySpider(app, pySpider); + return new PySpider(app, app.callAttr("loadFromDisk", path)); } }