258 lines
8.2 KiB
Python
258 lines
8.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
import json
|
|
import sys
|
|
import traceback
|
|
sys.path.append('..')
|
|
from base.spider import Spider
|
|
|
|
class Spider(Spider):
|
|
primary_host = 'http://api.hclyz.com:81/mf/'
|
|
backup_host = 'http://api.maiyoux.com:81/mf/'
|
|
host = primary_host
|
|
platforms = []
|
|
|
|
def init(self, extend=""):
|
|
if extend:
|
|
h = extend.strip()
|
|
if not h.endswith('/'):
|
|
h += '/'
|
|
self.host = h
|
|
else:
|
|
self.host = self.primary_host
|
|
|
|
content = None
|
|
for base in [self.host, self.backup_host]:
|
|
try:
|
|
txt = self.fetch(base + 'json.txt').text
|
|
data = None
|
|
try:
|
|
data = json.loads(txt)
|
|
except Exception:
|
|
data = None
|
|
|
|
if data is not None:
|
|
self.host = base
|
|
self.platforms = self._parse_catalog_json(data)
|
|
if self.platforms:
|
|
return
|
|
else:
|
|
plats = self._parse_catalog_text(txt)
|
|
if plats:
|
|
self.host = base
|
|
self.platforms = plats
|
|
return
|
|
except Exception:
|
|
continue
|
|
|
|
def _parse_catalog_json(self, data):
|
|
items = []
|
|
if isinstance(data, dict):
|
|
if 'pingtai' in data and isinstance(data['pingtai'], list):
|
|
items = data['pingtai']
|
|
else:
|
|
if all(isinstance(v, dict) for v in data.values()):
|
|
items = list(data.values())
|
|
elif isinstance(data, list):
|
|
items = data
|
|
|
|
platforms = []
|
|
for it in items:
|
|
name = it.get('mc') or it.get('title') or it.get('name') or ''
|
|
img = it.get('tp1') or it.get('xinimg') or it.get('img') or ''
|
|
file = it.get('dz') or it.get('address') or it.get('file') or ''
|
|
count = it.get('sl') or it.get('Number') or it.get('count') or 0
|
|
try:
|
|
count = int(count)
|
|
except Exception:
|
|
pass
|
|
if name and file:
|
|
if not file.endswith('.txt'):
|
|
file += '.txt'
|
|
if not file.startswith('json'):
|
|
file = 'json' + file
|
|
platforms.append({
|
|
'name': name,
|
|
'img': img,
|
|
'file': file,
|
|
'count': count
|
|
})
|
|
return platforms
|
|
|
|
def _parse_catalog_text(self, txt):
|
|
plats = []
|
|
block = txt.strip()
|
|
if not block:
|
|
return plats
|
|
if block.startswith('{') and block.endswith('}'):
|
|
block = block[1:-1]
|
|
chunks = [c for c in block.split('|') if c.strip()]
|
|
curr = {'mc': '', 'tp1': '', 'dz': '', 'sl': 0}
|
|
def flush():
|
|
if curr.get('mc') and curr.get('dz'):
|
|
try:
|
|
sl = int(curr.get('sl') or 0)
|
|
except Exception:
|
|
sl = curr.get('sl') or 0
|
|
fname = curr.get('dz')
|
|
if not fname.endswith('.txt'):
|
|
fname += '.txt'
|
|
if not fname.startswith('json'):
|
|
fname = 'json' + fname
|
|
plats.append({
|
|
'name': curr.get('mc'),
|
|
'img': curr.get('tp1'),
|
|
'file': fname,
|
|
'count': sl
|
|
})
|
|
for c in chunks:
|
|
s = c.strip()
|
|
if s.startswith('@mc'):
|
|
if curr.get('mc') or curr.get('dz'):
|
|
flush()
|
|
curr = {'mc': '', 'tp1': '', 'dz': '', 'sl': 0}
|
|
curr['mc'] = s.replace('@mc', '', 1)
|
|
elif s.startswith('@tp1'):
|
|
curr['tp1'] = s.replace('@tp1', '', 1)
|
|
elif s.startswith('@dz'):
|
|
curr['dz'] = s.replace('@dz', '', 1)
|
|
elif s.startswith('@sl'):
|
|
curr['sl'] = s.replace('@sl', '', 1)
|
|
if curr.get('mc') or curr.get('dz'):
|
|
flush()
|
|
return plats
|
|
|
|
def _load_platform_rooms(self, file_path, pg=1):
|
|
url_candidates = [
|
|
self.host + file_path,
|
|
]
|
|
alt_path = file_path.replace('json', '', 1)
|
|
if alt_path != file_path:
|
|
url_candidates.insert(0, self.host + alt_path)
|
|
|
|
data = None
|
|
raw = None
|
|
for u in url_candidates:
|
|
try:
|
|
raw = self.fetch(u).text
|
|
data = json.loads(raw)
|
|
break
|
|
except Exception:
|
|
data = None
|
|
continue
|
|
|
|
rooms = []
|
|
if isinstance(data, dict):
|
|
if 'zhubo' in data and isinstance(data['zhubo'], list):
|
|
rooms = data['zhubo']
|
|
elif 'list' in data and isinstance(data['list'], list):
|
|
rooms = data['list']
|
|
elif 'data' in data and isinstance(data['data'], list):
|
|
rooms = data['data']
|
|
elif 'rooms' in data and isinstance(data['rooms'], list):
|
|
rooms = data['rooms']
|
|
elif isinstance(data, list):
|
|
rooms = data
|
|
|
|
videos = []
|
|
for idx, r in enumerate(rooms or [], 1):
|
|
title = r.get('title') or r.get('name') or r.get('nickname') or f'主播{idx}'
|
|
address = r.get('address') or r.get('url') or r.get('stream') or ''
|
|
img = r.get('img') or r.get('pic') or r.get('avatar') or ''
|
|
remarks = r.get('Number') or r.get('online') or r.get('viewers') or ''
|
|
if title and address:
|
|
videos.append({
|
|
'vod_id': address,
|
|
'vod_name': title,
|
|
'vod_pic': img,
|
|
'vod_remarks': str(remarks)
|
|
})
|
|
total = len(videos)
|
|
if pg > 1:
|
|
start = (pg - 1) * 20
|
|
videos = videos[start:start + 20]
|
|
return videos, total
|
|
|
|
def isVideoFormat(self, url):
|
|
return False
|
|
|
|
def manualVideoCheck(self):
|
|
pass
|
|
|
|
def getName(self):
|
|
return 'Leospring直播'
|
|
|
|
def homeContent(self, filter):
|
|
classes = []
|
|
for p in self.platforms:
|
|
classes.append({
|
|
'type_id': p['file'],
|
|
'type_name': p['name'],
|
|
})
|
|
return {'class': classes}
|
|
|
|
def homeVideoContent(self):
|
|
return {'list': []}
|
|
|
|
def _find_platform(self, tid):
|
|
for p in self.platforms:
|
|
if p['file'] == tid or p['name'] == tid:
|
|
return p
|
|
return None
|
|
|
|
def categoryContent(self, tid, pg, filter, extend):
|
|
p = self._find_platform(tid)
|
|
if not p:
|
|
return {'list': [], 'page': pg, 'pagecount': 0, 'limit': 0, 'total': 0}
|
|
|
|
videos, total = self._load_platform_rooms(p['file'], int(pg))
|
|
pagecount = (total + 19) // 20
|
|
result = {
|
|
'list': videos,
|
|
'page': pg,
|
|
'pagecount': pagecount,
|
|
'limit': min(len(videos), 20),
|
|
'total': total
|
|
}
|
|
return result
|
|
|
|
def searchContent(self, key, quick, pg="1"):
|
|
key = (key or '').strip().lower()
|
|
out = []
|
|
if not key:
|
|
return {'list': out}
|
|
for p in self.platforms:
|
|
videos, _ = self._load_platform_rooms(p['file'])
|
|
for v in videos:
|
|
if key in v['vod_name'].lower():
|
|
out.append(v)
|
|
if len(out) >= 50:
|
|
break
|
|
return {'list': out[:50]}
|
|
|
|
def detailContent(self, ids):
|
|
try:
|
|
address = ids[0]
|
|
if not address:
|
|
return {'list': []}
|
|
|
|
vod = {
|
|
'vod_id': address,
|
|
'vod_name': '直播源',
|
|
'vod_play_from': '每日必修课',
|
|
'vod_play_url': address,
|
|
'vod_content': '多看少打卡',
|
|
}
|
|
return {'list': [vod]}
|
|
except Exception as e:
|
|
traceback.print_exc()
|
|
return {'list': []}
|
|
|
|
def playerContent(self, flag, id, vipFlags):
|
|
return {
|
|
'parse': 0,
|
|
'url': id
|
|
}
|
|
|
|
def localProxy(self, param):
|
|
pass
|