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")