Files
tvbox_collect/jaychouqq/yingshi/py8/alist.py
T
2026-06-29 03:41:14 +00:00

169 lines
5.9 KiB
Python

# coding=utf-8
# !/usr/bin/python
import sys
sys.path.append('..')
from base.spider import Spider
import json
import re
import urllib.request
import urllib.parse
class Spider(Spider):
def getName(self):
return "Alist_DeepDir_Fix"
def init(self, extend=""):
self.ua = "Mozilla/5.0 (Linux; Android 16; ELI-AN00 Build/HONORELI-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.7499.192 Mobile Safari/537.36"
def homeContent(self, filter):
result = {}
cateManual = {
"🌊七米蓝": "https://al.chirmyram.com",
"🐝组织云盘": "https://w2.apachecn.org/",
"📽️网呢": "https://pan.clun.top",
"✨亿苯正经": "https://pan.lm379.cn",
"🐉神族九帝":"https://alist.shenzjd.com",
"🍓趣盘":"https://pan.mediy.cn/"
}
classes = []
for k in cateManual:
classes.append({'type_name': k, "type_flag": "1", 'type_id': cateManual[k]})
result['class'] = classes
return result
def rawPost(self, url, data, headers):
try:
params = json.dumps(data).encode('utf-8')
req = urllib.request.Request(url, data=params, headers=headers, method='POST')
with urllib.request.urlopen(req, timeout=10) as response:
return response.read().decode('utf-8')
except Exception as e:
return json.dumps({"code": 500, "message": str(e)})
def categoryContent(self, tid, pg, filter, extend):
result = {}
# 1. 精准提取 Host
host_match = re.findall(r"(https?://[^/]+)", tid)
if not host_match: return {"list": [], "total": 0}
host = host_match[0]
# 2. 核心修复:精准提取相对路径 path
# 无论 tid 是域名还是多级目录,确保 path 是以 / 开头的标准路径
path = tid.replace(host, "").strip()
if not path.startswith('/'):
path = '/' + path
# 去掉末尾重复斜杠,保持 API 请求整洁
if len(path) > 1:
path = path.rstrip('/')
# 3. 构造 Headers
hd = {
"User-Agent": self.ua,
"Content-Type": "application/json",
"Referer": host + "/",
"Origin": host,
"Accept": "application/json"
}
# 4. 构造参数
params = {
"path": path,
"password": "",
"page": int(pg),
"per_page": 50
}
videos = []
try:
api_url = host.rstrip('/') + "/api/fs/list"
res_text = self.rawPost(api_url, params, hd)
jo = json.loads(res_text)
data_obj = jo.get('data')
if jo.get('code') == 200 and data_obj:
data_list = data_obj.get('content') if isinstance(data_obj, dict) else data_obj
if data_list is None: data_list = []
for item in data_list:
if not item: continue
name = item.get('name', '未知')
if name.startswith('.'): continue
is_dir = item.get('type') == 1
# 5. 核心修复:多级目录拼接逻辑
# 确保 new_path 不会出现 // 且完整保留层级
if path == "/":
new_path = "/" + name
else:
new_path = path + "/" + name
new_tid = host + new_path
videos.append({
"vod_id": new_tid,
"vod_name": name,
"vod_tag": "folder" if is_dir else "file",
"vod_remarks": "文件夹" if is_dir else self.getSize(item.get('size', 0))
})
except:
pass
result['list'] = videos
result['total'] = len(videos)
return result
def detailContent(self, array):
id = array[0]
name = id.split('/')[-1]
name = urllib.parse.unquote(name)
return {'list': [{"vod_id": id, "vod_name": name, "vod_play_from": "Alist", "vod_play_url": f"{name}${id}"}]}
def playerContent(self, flag, id, vipFlags):
result = {}
host_match = re.findall(r"(https?://[^/]+)", id)
if not host_match: return {"parse": 0, "url": id}
host = host_match[0]
path = id.replace(host, "").strip()
if not path.startswith('/'): path = '/' + path
hd = {"User-Agent": self.ua, "Content-Type": "application/json", "Referer": host + "/"}
params = {"path": path, "password": ""}
try:
api_url = host.rstrip('/') + "/api/fs/get"
res_text = self.rawPost(api_url, params, hd)
jo = json.loads(res_text)
data = jo.get('data')
if jo.get('code') == 200 and data:
url = data.get('raw_url', '')
if url.startswith('/'): url = host.rstrip('/') + url
result["url"] = url
provider = data.get('provider', '')
if 'Baidu' in provider:
result["header"] = {"User-Agent": "pan.baidu.com"}
else:
result["header"] = {"User-Agent": self.ua}
else:
result["url"] = id
except:
result["url"] = id
result["parse"] = 0
return result
def getSize(self, size):
if size is None: return "0B"
try:
size = float(size)
units = ['B', 'KB', 'MB', 'GB', 'TB']
n = 0
while size >= 1024 and n < len(units) - 1:
size /= 1024
n += 1
return f"{round(size, 2)}{units[n]}"
except:
return "未知"
def searchContent(self, key, quick):
return {'list': []}