mirror of https://github.com/FongMi/TV.git
commit
7c3915f4c3
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
@ -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() |
||||
Loading…
Reference in new issue