更新源
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
|
||||
def load_json(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def find_index_by_key(sites, key):
|
||||
for i, item in enumerate(sites):
|
||||
if isinstance(item, dict) and item.get("key") == key:
|
||||
return i
|
||||
return -1
|
||||
|
||||
|
||||
def extract_local_paths(value):
|
||||
"""提取字符串中的本地路径(支持 ./ 和 ../),忽略 URL"""
|
||||
if not isinstance(value, str):
|
||||
return []
|
||||
paths = []
|
||||
# 先按 ? 切分,保留路径及查询参数里的路径
|
||||
parts = value.split("?")
|
||||
for part in parts:
|
||||
# 再按常见分隔符切
|
||||
for token in part.replace("&", " ").replace("$", " ").split():
|
||||
token = token.strip()
|
||||
if token.startswith("./") or token.startswith("../"):
|
||||
# 去掉可能的尾部参数
|
||||
token = token.split("&", 1)[0]
|
||||
token = token.split("$", 1)[0]
|
||||
paths.append(token)
|
||||
return paths
|
||||
|
||||
|
||||
def iter_paths_between(sites, start_key, end_key):
|
||||
start_idx = find_index_by_key(sites, start_key)
|
||||
end_idx = find_index_by_key(sites, end_key)
|
||||
if start_idx == -1 or end_idx == -1 or start_idx >= end_idx:
|
||||
return []
|
||||
subset = sites[start_idx + 1 : end_idx]
|
||||
all_paths = []
|
||||
for item in subset:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
# api 仅拷贝 .py
|
||||
api_val = item.get("api")
|
||||
if isinstance(api_val, str):
|
||||
for p in extract_local_paths(api_val):
|
||||
if p.endswith(".py"):
|
||||
all_paths.append(p)
|
||||
# ext 拷贝所有本地路径
|
||||
ext_val = item.get("ext")
|
||||
if isinstance(ext_val, str):
|
||||
all_paths.extend(extract_local_paths(ext_val))
|
||||
# 去重,保留顺序
|
||||
seen = set()
|
||||
deduped = []
|
||||
for p in all_paths:
|
||||
if p not in seen:
|
||||
seen.add(p)
|
||||
deduped.append(p)
|
||||
return deduped
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("用法: python copy_xbpq.py <json路径>")
|
||||
print("示例: python copy_xbpq.py jsm_with_app_sites.json")
|
||||
sys.exit(1)
|
||||
|
||||
json_path = sys.argv[1]
|
||||
data = load_json(json_path)
|
||||
sites = data.get("sites", [])
|
||||
|
||||
paths = iter_paths_between(sites, "cbh", "push_agent")
|
||||
if not paths:
|
||||
print("⚠️ 未找到 cbh 到 push_agent 之间的 ./XBPQ/ 路径")
|
||||
return
|
||||
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
src_base = os.path.normpath(os.path.join(base_dir, "..", "xiaosa"))
|
||||
dst_base = os.path.normpath(os.path.join(base_dir, ".."))
|
||||
|
||||
copied = 0
|
||||
missing = 0
|
||||
for path in paths:
|
||||
rel_path = path.replace("./", "", 1)
|
||||
rel_path = rel_path.replace("../", "", 1)
|
||||
src = os.path.join(src_base, rel_path)
|
||||
dst = os.path.join(dst_base, rel_path)
|
||||
if not os.path.exists(src):
|
||||
print(f"⚠️ 源文件不存在: {src}")
|
||||
missing += 1
|
||||
continue
|
||||
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||
shutil.copy2(src, dst)
|
||||
print(f"✅ 已覆盖: {dst}")
|
||||
copied += 1
|
||||
|
||||
print(f"完成: 复制 {copied} 个,缺失 {missing} 个")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"spider":"./jar/fan.txt;md5;8432d174d72d5b608ae1bcd16d966847",
|
||||
"spider":"./jar/spider.jar;md5;8432d174d72d5b608ae1bcd16d966847",
|
||||
"lives":[
|
||||
{"name":"live","boot": false,"type":0,"url":"./tv.txt","playerType":2,"ua":"okhttp/3.8.1","timeout":20,"epg":"https://epg.112114.xyz/?ch={name}&date={date}","logo":"https://logo.wyfc.qzz.io/{name}.png"}
|
||||
],
|
||||
@@ -7,10 +7,10 @@
|
||||
"sites":[
|
||||
{"key":"drpy_js_豆瓣","name":"搜索 | 豆瓣[js]","type":3,"api":"./lib/drpy2.min.js","ext":"./js/drpy.js","searchable":1,"quickSearch":0,"changeable":0},
|
||||
{"key":"drpy_js_TVB云播","name":"影视 | TVB云播[js]","type":3,"api":"./lib/drpy2.min.js","ext":"./js/TVB云播.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"新闪雷","name":"新闪雷┃MP4","type":3,"api":"./FTY/drpy2.min.js","ext":"./js/新闪雷.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"闪雷","name":"闪雷┃MP4","type":3,"api":"./FTY/drpy2.min.js","ext":"./js/678.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"fyyy","name":"飞宇影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"http://ntfeiyu.com/nt/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"},"jar": "./jar/sx.jar;md5;6186f490eadf878ba5de21a7fa29e594"},
|
||||
{"key":"cbh","name":"茶杯狐","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"https://www.cupfox7.com/cupfox/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$fenlei1#电视剧$fenlei2#综艺$fenlei3#动漫$fenlei4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"},"jar": "./jar/sx.jar;md5;6186f490eadf878ba5de21a7fa29e594"},
|
||||
{"key":"新闪雷","name":"新闪雷┃MP4","type":3,"api":"./lib/drpy2.min.js","ext":"./js/新闪雷.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"闪雷","name":"闪雷┃MP4","type":3,"api":"./lib/drpy2.min.js","ext":"./js/678.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"fyyy","name":"飞宇影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"http://ntfeiyu.com/nt/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"cbh","name":"茶杯狐","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"https://www.cupfox7.com/cupfox/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$fenlei1#电视剧$fenlei2#综艺$fenlei3#动漫$fenlei4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
|
||||
{"key":"奇优","name":"影视 | ️奇优[直连]","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"ext":"./json/奇优.json","jar": "./jar/Yoursmile.jar;md5;97796a79a781055669f2d5442439dc5f"},
|
||||
{"key": "电影天堂","name": "影视 | 电影天堂","type": 1,"api": "http://caiji.dyttzyapi.com/api.php/provide/vod","searchable": 1,"quickSearch": 1,"filterable": 1,"changeable": 1,"playerType":2},
|
||||
|
||||
+22
-9
@@ -2,6 +2,7 @@ import requests
|
||||
import re
|
||||
import demjson3 as demjson
|
||||
import json
|
||||
import hashlib
|
||||
|
||||
# 创建全局 session 并设置浏览器 UA
|
||||
session = requests.Session()
|
||||
@@ -31,6 +32,14 @@ def extract_and_save_spider(json_text):
|
||||
f.write(resp.content)
|
||||
print("✅ 已保存为 fan.txt")
|
||||
|
||||
# 计算本地文件 MD5
|
||||
def get_md5(filepath):
|
||||
md5 = hashlib.md5()
|
||||
with open(filepath, "rb") as f:
|
||||
while chunk := f.read(8192):
|
||||
md5.update(chunk)
|
||||
return md5.hexdigest()
|
||||
|
||||
# 删除不需要的 sites 项 + 替换链接
|
||||
def clean_data(raw_text):
|
||||
# 统一把各种 GitHub 代理壳替换掉
|
||||
@@ -42,18 +51,18 @@ def clean_data(raw_text):
|
||||
|
||||
data = demjson.decode(raw_text)
|
||||
|
||||
keywords = [
|
||||
"豆", "饭太硬", "广告", "PanSso", "YpanSo", "xzso", "米搜", "夸搜", "Aliso", "YiSo"
|
||||
]
|
||||
# keywords = [
|
||||
# "豆", "饭太硬", "广告", "PanSso", "YpanSo", "xzso", "米搜", "夸搜", "Aliso", "YiSo"
|
||||
# ]
|
||||
|
||||
original_count = len(data.get("sites", []))
|
||||
# original_count = len(data.get("sites", []))
|
||||
|
||||
data["sites"] = [
|
||||
s for s in data["sites"]
|
||||
if not any(kw in s.get("key", "") or kw in s.get("name", "") for kw in keywords)
|
||||
]
|
||||
# data["sites"] = [
|
||||
# s for s in data["sites"]
|
||||
# if not any(kw in s.get("key", "") or kw in s.get("name", "") for kw in keywords)
|
||||
# ]
|
||||
|
||||
print(f"🧹 清理 {original_count - len(data['sites'])} 条 sites")
|
||||
# print(f"🧹 清理 {data - len(data['sites'])} 条 sites")
|
||||
return data
|
||||
|
||||
# 格式美化保存
|
||||
@@ -85,6 +94,10 @@ if __name__ == "__main__":
|
||||
raw_text = fetch_raw_json()
|
||||
extract_and_save_spider(raw_text)
|
||||
data = clean_data(raw_text)
|
||||
# 更新 spider 为本地 fan.txt + 最新 MD5
|
||||
md5_value = get_md5("fan.txt")
|
||||
data["spider"] = f"./jar/fan.txt;md5;{md5_value}"
|
||||
print(f"🔄 spider 已更新为: {data['spider']}")
|
||||
save_json(data)
|
||||
except Exception as e:
|
||||
print(f"❌ 错误: {e}")
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"spider":"./jar/fan.txt;md5;8432d174d72d5b608ae1bcd16d966847",
|
||||
"spider":"./jar/spider.jar;md5;8432d174d72d5b608ae1bcd16d966847",
|
||||
"lives":[
|
||||
{"name":"migu","type":0,"url":"https://develop202.github.io/migu_video/interface.txt","playerType":1,"ua":"okhttp/3.8.1","timeout":20,"epg":"https://epg.112114.xyz/?ch={name}&date={date}","logo":"https://epg.112114.xyz/logo/{name}.png"},
|
||||
{"name":"live","type":0,"url":"https://epg.pw/test_channels.m3u","playerType":1,"ua":"okhttp/3.8.1","timeout":20,"epg":"https://epg.112114.xyz/?ch={name}&date={date}","logo":"https://epg.112114.xyz/logo/{name}.png"},
|
||||
@@ -9,9 +9,9 @@
|
||||
"sites":[
|
||||
{"key":"drpy_js_豆瓣","name":"搜索 | 豆瓣[js]","type":3,"api":"./lib/drpy2.min.js","ext":"./js/drpy.js","searchable":1,"quickSearch":0,"changeable":0},
|
||||
{"key":"drpy_js_TVB云播","name":"影视 | TVB云播[js]","type":3,"api":"./lib/drpy2.min.js","ext":"./js/TVB云播.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"新闪雷","name":"新闪雷┃MP4","type":3,"api":"./FTY/drpy2.min.js","ext":"./js/新闪雷.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"fyyy","name":"飞宇影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"http://ntfeiyu.com/nt/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"},"jar": "./jar/sx.jar;md5;6186f490eadf878ba5de21a7fa29e594"},
|
||||
{"key":"cbh","name":"茶杯狐","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"www.cupfox7.com/cupfox/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$fenlei1#电视剧$fenlei2#综艺$fenlei3#动漫$fenlei4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"},"jar": "./jar/sx.jar;md5;6186f490eadf878ba5de21a7fa29e594"},
|
||||
{"key":"新闪雷","name":"新闪雷┃MP4","type":3,"api":"./lib/drpy2.min.js","ext":"./js/新闪雷.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"fyyy","name":"飞宇影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"http://ntfeiyu.com/nt/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
{"key":"cbh","name":"茶杯狐","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"www.cupfox7.com/cupfox/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$fenlei1#电视剧$fenlei2#综艺$fenlei3#动漫$fenlei4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}},
|
||||
|
||||
{"key":"奇优","name":"影视 | ️奇优[直连]","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"ext":"./json/奇优.json","jar": "./jar/Yoursmile.jar;md5;97796a79a781055669f2d5442439dc5f"},
|
||||
{"key": "电影天堂","name": "影视 | 电影天堂","type": 1,"api": "http://caiji.dyttzyapi.com/api.php/provide/vod","searchable": 1,"quickSearch": 1,"filterable": 1,"changeable": 1,"playerType":2},
|
||||
|
||||
+49
-48
@@ -1,15 +1,14 @@
|
||||
import json
|
||||
import requests
|
||||
import sys
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
# 默认 jar 路径和下载 URL(如需下载)
|
||||
default_jar = "./xiaosa/spider.jar"
|
||||
default_jar_url = "../xiaosa/spider.jar"
|
||||
# jar 路径(用于计算 md5)
|
||||
primary_jar_path = "jar/spider.jar"
|
||||
fallback_jar_path = "../xiaosa/spider.jar"
|
||||
|
||||
# 需要删除的站点 key
|
||||
remove_keys = {"巴士动漫"} # 可以加多个,例如 {"巴士动漫", "电影牛"}
|
||||
# 需要删除的站点 key(在此填写即可删除)
|
||||
remove_keys = {"版本信息","腾讯视频","优酷视频","芒果视频","爱奇艺","三六零","豆瓣"} # 可以加多个,例如 {"巴士动漫", "电影牛"}
|
||||
|
||||
# 保存 JSON 文件(折叠字典数组为单行,空数组和基础数组一行)
|
||||
class CompactJSONEncoder(json.JSONEncoder):
|
||||
@@ -38,12 +37,7 @@ def fetch_json(path_or_url):
|
||||
if os.path.exists(path_or_url):
|
||||
with open(path_or_url, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
elif path_or_url.startswith("http://") or path_or_url.startswith("https://"):
|
||||
resp = requests.get(path_or_url)
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
else:
|
||||
raise ValueError(f"无效路径或 URL:{path_or_url}")
|
||||
raise ValueError(f"无效路径或 URL:{path_or_url}")
|
||||
|
||||
|
||||
def get_md5(filepath):
|
||||
@@ -53,35 +47,22 @@ def get_md5(filepath):
|
||||
md5.update(chunk)
|
||||
return md5.hexdigest()
|
||||
|
||||
|
||||
def ensure_jar_with_md5(site):
|
||||
def replace_drpy_path(site):
|
||||
"""将 ./js/drpy2.min.js 替换为 ./lib/drpy2.min.js"""
|
||||
if not isinstance(site, dict):
|
||||
return
|
||||
jar_val = site.get("jar")
|
||||
if jar_val and ";md5;" in jar_val:
|
||||
return # 已包含 md5
|
||||
if not os.path.exists(default_jar_url):
|
||||
print(f"⚠️ 找不到本地 jar 文件:{default_jar_url}")
|
||||
return
|
||||
md5_val = get_md5(default_jar_url)
|
||||
site["jar"] = f"{default_jar};md5;{md5_val}"
|
||||
for field in ("api", "ext"):
|
||||
val = site.get(field)
|
||||
if isinstance(val, str) and val == "./js/drpy2.min.js":
|
||||
site[field] = "./lib/drpy2.min.js"
|
||||
|
||||
|
||||
def ensure_xyqhiker_ext_and_jar(site):
|
||||
"""修正所有 csp_XYQHiker 站点的 ext 路径,并加上 jar md5"""
|
||||
if not isinstance(site, dict):
|
||||
return
|
||||
if site.get("api") == "csp_XYQHiker":
|
||||
ext_val = site.get("ext", "")
|
||||
if ext_val.startswith("./XYQHiker/"):
|
||||
site["ext"] = ext_val.replace("./XYQHiker/", "./xiaosa/XYQHiker/")
|
||||
ensure_jar_with_md5(site)
|
||||
|
||||
|
||||
def insert_sites_at_key(base_sites, insert_sites, key_marker):
|
||||
for i, item in enumerate(base_sites):
|
||||
if item.get("key") == key_marker:
|
||||
return base_sites[:i] + insert_sites + base_sites[i:]
|
||||
return base_sites[:i + 1] + insert_sites + base_sites[i + 1:]
|
||||
print(f"⚠️ 未找到 key 为 {key_marker} 的插入点,追加到末尾")
|
||||
return base_sites + insert_sites
|
||||
|
||||
@@ -91,10 +72,16 @@ def remove_sites(sites, keys_to_remove):
|
||||
return [s for s in sites if s.get("key") not in keys_to_remove]
|
||||
|
||||
|
||||
def dedupe_by_name(base_sites, insert_sites):
|
||||
"""按 name 去重:若重名,优先保留 base_sites 中的条目"""
|
||||
base_names = {s.get("name") for s in base_sites if isinstance(s, dict)}
|
||||
return [s for s in insert_sites if s.get("name") not in base_names]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print("用法: python script.py <远程json_url> <本地dianshi.json路径>")
|
||||
print("示例: python script.py https://raw.githubusercontent.com/qist/tvbox/master/xiaosa/api.json dianshi.json")
|
||||
print("用法: python xiao.py <本地api.json路径> <本地dianshi.json路径>")
|
||||
print("示例: python xiao.py ../xiaosa/api.json dianshi.json")
|
||||
sys.exit(1)
|
||||
|
||||
remote_url = sys.argv[1]
|
||||
@@ -103,28 +90,33 @@ if __name__ == "__main__":
|
||||
# 1. 下载远程 JSON
|
||||
data = fetch_json(remote_url)
|
||||
|
||||
# 2. 筛选 sites,只保留 name 含 APP
|
||||
# 2. 读取 sites(不再筛选)
|
||||
sites = data.get("sites", [])
|
||||
filtered_sites = [s for s in sites if isinstance(s, dict) and "name" in s and "APP" in s["name"]]
|
||||
filtered_sites = [s for s in sites if isinstance(s, dict)]
|
||||
|
||||
# 3. 为每个 APP site 添加 jar 字段和 md5
|
||||
# 3. 不再单独追加 XYQHiker(已包含在 sites 中)
|
||||
|
||||
# 3.1 不删除站点,仅移除每个站点的 jar 字段
|
||||
before_count = len(filtered_sites)
|
||||
removed_sites = []
|
||||
for site in filtered_sites:
|
||||
ensure_jar_with_md5(site)
|
||||
|
||||
# 3.1 处理所有 csp_XYQHiker
|
||||
for site in sites:
|
||||
if isinstance(site, dict) and site.get("api") == "csp_XYQHiker":
|
||||
ensure_xyqhiker_ext_and_jar(site)
|
||||
filtered_sites.append(site)
|
||||
print(f"✅ 筛选并更新 {len(filtered_sites)} 个站点(APP + XYQHiker,含 jar+md5)")
|
||||
replace_drpy_path(site)
|
||||
if isinstance(site, dict) and "jar" in site:
|
||||
site.pop("jar", None)
|
||||
removed_count = before_count - len(filtered_sites)
|
||||
print(f"✅ 更新 {len(filtered_sites)} 个站点")
|
||||
|
||||
# 4. 读取本地文件
|
||||
with open(local_file, "r", encoding="utf-8") as f:
|
||||
dianshi = json.load(f)
|
||||
|
||||
# 5. 插入到 key="玩偶" 处
|
||||
# 5. 插入到 key="cbh" 之后(按 name 去重,保留本地)
|
||||
dianshi_sites = dianshi.get("sites", [])
|
||||
dianshi["sites"] = insert_sites_at_key(dianshi_sites, filtered_sites, "玩偶")
|
||||
# 先按 key 删除来源站点
|
||||
if remove_keys:
|
||||
filtered_sites = [s for s in filtered_sites if s.get("key") not in remove_keys]
|
||||
filtered_sites = dedupe_by_name(dianshi_sites, filtered_sites)
|
||||
dianshi["sites"] = insert_sites_at_key(dianshi_sites, filtered_sites, "cbh")
|
||||
|
||||
# 6. 删除指定的站点
|
||||
before_count = len(dianshi["sites"])
|
||||
@@ -132,7 +124,16 @@ if __name__ == "__main__":
|
||||
after_count = len(dianshi["sites"])
|
||||
print(f"✅ 删除了 {before_count - after_count} 个指定站点: {', '.join(remove_keys)}")
|
||||
|
||||
# 7. 保存合并结果
|
||||
# 7. 设置 spider 为 jar+md5(统一在输出文件中)
|
||||
jar_path = primary_jar_path if os.path.exists(primary_jar_path) else fallback_jar_path
|
||||
if os.path.exists(jar_path):
|
||||
md5_val = get_md5(jar_path)
|
||||
dianshi["spider"] = f"./jar/spider.jar;md5;{md5_val}"
|
||||
print(f"🔄 spider 已更新为: {dianshi['spider']}")
|
||||
else:
|
||||
print(f"⚠️ 找不到 jar 文件,未更新 spider:{primary_jar_path} / {fallback_jar_path}")
|
||||
|
||||
# 8. 保存合并结果(新文件)
|
||||
output_file = f"{local_file.rsplit('.',1)[0]}_with_app_sites.json"
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
json.dump(dianshi, f, ensure_ascii=False, indent=2, cls=CompactJSONEncoder)
|
||||
|
||||
Reference in New Issue
Block a user