py_alist.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. # coding=utf-8
  2. # !/usr/bin/python
  3. import sys
  4. import json
  5. import time
  6. from os.path import splitext
  7. sys.path.append('..')
  8. from base.spider import Spider
  9. class Spider(Spider): # 元类 默认的元类 type
  10. alisttoken = ''
  11. def getName(self):
  12. return "Alist"
  13. def init(self, extend):
  14. try:
  15. self.ext = extend
  16. except:
  17. self.ext = ''
  18. def isVideoFormat(self, url):
  19. pass
  20. def manualVideoCheck(self):
  21. pass
  22. def homeContent(self, filter):
  23. result = {}
  24. if self.ext.startswith('http'):
  25. url = self.ext
  26. drivers = self.fetch(url, headers=self.header, timeout=5).json()['drives']
  27. else:
  28. drivers = json.loads(self.ext)['drives']
  29. classes = []
  30. for driver in drivers:
  31. if 'hidden' in driver and driver['hidden']:
  32. continue
  33. tid = driver['server']
  34. if 'login' in driver:
  35. tid = tid + '&&&login' + json.dumps(driver['login'], ensure_ascii=False)
  36. if 'params' in driver:
  37. tid = tid + '&&&params' + json.dumps(driver['params'], ensure_ascii=False)
  38. classes.append({
  39. 'type_name': driver['name'],
  40. 'type_id': tid
  41. })
  42. result['class'] = classes
  43. return result
  44. def homeVideoContent(self):
  45. result = {}
  46. return result
  47. def categoryContent(self, cid, page, filter, ext):
  48. result = {}
  49. login = {}
  50. params = []
  51. password = ''
  52. if '&&&' in cid:
  53. cidList = cid.split('&&&')
  54. url = cidList[0]
  55. for cL in cidList:
  56. if cL.startswith('login'):
  57. login = json.loads(cL.replace('login', ''))
  58. elif cL.startswith('params'):
  59. params = json.loads(cL.replace('params', ''))
  60. else:
  61. url = cid
  62. if url.count('/') == 2:
  63. url = url + '/'
  64. header = self.header.copy()
  65. baseUrl = self.getCache('baseUrl')
  66. if not baseUrl:
  67. baseUrl = self.regStr(reg="(http.*://.*?/)", src=url)
  68. header['Referer'] = baseUrl
  69. token = self.getCache('token')
  70. if token:
  71. token = token['token']
  72. else:
  73. data = self.postJson(baseUrl + 'api/auth/login', json=login, headers=header).json()
  74. if data['code'] == 200:
  75. token = data['data']['token']
  76. self.setCache('token', {'token': token, 'expiresAt': int(time.time()) + 86400})
  77. header['Authorization'] = token
  78. path = '/' + url.replace(baseUrl, "")
  79. for param in params:
  80. if param['path'].startswith(path) and 'pass' in param:
  81. password = param['pass']
  82. break
  83. param = {
  84. "path": path,
  85. 'password': password
  86. }
  87. data = self.postJson(baseUrl + 'api/fs/list', json=param, headers=header).json()
  88. vodList = data['data']['content']
  89. videos = []
  90. subtList = []
  91. playList = []
  92. for vod in vodList:
  93. if len(vod['thumb']) == 0:
  94. img = "https://api-lmteam.koyeb.app/files/alist.png"
  95. elif vod['thumb'].startswith('http'):
  96. img = vod['thumb']
  97. else:
  98. img = baseUrl.strip('/') + vod['thumb']
  99. if path != '/':
  100. aid = path.strip('/') + '/'
  101. else:
  102. aid = path.strip('/')
  103. if vod['type'] == 1:
  104. tag = "folder"
  105. remark = "文件夹"
  106. cid = baseUrl + aid + vod['name']
  107. else:
  108. if splitext(vod['name'])[1] in ['.mp4', '.mpg', '.mkv', '.ts', '.TS', '.avi', '.flv', '.rmvb', '.mp3', '.flac', '.wav', '.wma', '.dff']:
  109. size = self.getSize(vod['size'])
  110. tag = "file"
  111. remark = size
  112. cid = baseUrl + aid + vod['name']
  113. playList.append(vod['name'])
  114. elif splitext(vod['name'])[1] in ['.ass', '.ssa', '.srt']:
  115. cid = baseUrl + aid + vod['name']
  116. subtList.append(vod['name'])
  117. continue
  118. else:
  119. continue
  120. if login != {}:
  121. cid = cid + '&&&login' + json.dumps(login, ensure_ascii=False)
  122. elif params != []:
  123. cid = cid + '&&&params' + json.dumps(params, ensure_ascii=False)
  124. videos.append({
  125. "vod_id": cid,
  126. "vod_name": vod['name'],
  127. "vod_pic": img,
  128. "vod_tag": tag,
  129. "vod_remarks": remark
  130. })
  131. if playList != []:
  132. cid = baseUrl + aid
  133. for pL in playList:
  134. cid = cid + '!!!' + pL
  135. if login != {}:
  136. cid = cid + '&&&login' + json.dumps(login, ensure_ascii=False)
  137. elif params != []:
  138. cid = cid + '&&&params' + json.dumps(params, ensure_ascii=False)
  139. videos.insert(0, {
  140. "vod_id": cid,
  141. "vod_name": '播放列表',
  142. "vod_pic": "https://avatars.githubusercontent.com/u/97389433?s=200&v=4",
  143. "vod_tag": 'file',
  144. "vod_remarks": path
  145. })
  146. if subtList != []:
  147. self.setCache(f"subtList_{cid[:cid.rfind('/')]}", {'subtList': subtList, 'expiresAt': int(time.time()) + 86400})
  148. result['list'] = videos
  149. result['page'] = 1
  150. result['pagecount'] = 1
  151. result['limit'] = len(videos)
  152. result['total'] = len(videos)
  153. return result
  154. def detailContent(self, did):
  155. did = did[0]
  156. if '&&&' in did:
  157. pos = did.index('&&&')
  158. url = did[:pos]
  159. append = did[pos:]
  160. else:
  161. url = did
  162. append = ''
  163. name = url[url.strip('/').rfind('/') + 1:].strip('/')
  164. if '!!!' in url:
  165. urls = url.split('!!!')
  166. fileList = urls[1:]
  167. url = urls[0]
  168. playUrl = ''
  169. for file in fileList:
  170. playUrl += file + '$' + url + file + append + '#'
  171. else:
  172. playUrl = name + '$' + did
  173. name = did[did.rfind('/') + 1:]
  174. if '&&&' in name:
  175. name = name.split('&&&')[0]
  176. vod = {
  177. "vod_id": did,
  178. "vod_name": name,
  179. "vod_play_from": "Alist网盘",
  180. "vod_play_url": playUrl.strip('#')
  181. }
  182. result = {
  183. 'list': [
  184. vod
  185. ]
  186. }
  187. return result
  188. def searchContent(self, key, quick):
  189. return self.searchContentPage(key, quick, '1')
  190. def searchContentPage(self, key, quick, page):
  191. result = {'list': []}
  192. return result
  193. def playerContent(self, flag, pid, vipFlags):
  194. result = {}
  195. purl = self.getDownloadUrl(pid)
  196. if '&&&' in pid:
  197. append = pid[pid.index('&&&'):]
  198. else:
  199. append = ''
  200. url = pid[:pid.rfind('/')]
  201. data = self.getCache(f'subtList_{url}')
  202. subs = []
  203. if data:
  204. subList = data['subtList']
  205. for sub in subList:
  206. subformat = os.path.splitext(sub)[1]
  207. if subformat == '.srt':
  208. sformat = 'application/x-subrip'
  209. elif subformat == '.ass':
  210. sformat = 'application/x-subtitle-ass'
  211. elif subformat == '.ssa':
  212. sformat = 'text/x-ssa'
  213. else:
  214. sformat = 'text/plain'
  215. surl = url + '/' + sub
  216. subs.append(f'http://127.0.0.1:UndCover/proxy?do=py&type=sub&url={surl}&sformat={sformat}')
  217. result["parse"] = 0
  218. result["playUrl"] = ''
  219. result["url"] = purl
  220. result["header"] = ''
  221. result["subs"] = subs
  222. return result
  223. def getSize(self, size):
  224. if size > 1024 * 1024 * 1024 * 1024.0:
  225. fs = "TB"
  226. sz = round(size / (1024 * 1024 * 1024 * 1024.0), 2)
  227. elif size > 1024 * 1024 * 1024.0:
  228. fs = "GB"
  229. sz = round(size / (1024 * 1024 * 1024.0), 2)
  230. elif size > 1024 * 1024.0:
  231. fs = "MB"
  232. sz = round(size / (1024 * 1024.0), 2)
  233. elif size > 1024.0:
  234. fs = "KB"
  235. sz = round(size / (1024.0), 2)
  236. else:
  237. fs = "KB"
  238. sz = round(size / (1024.0), 2)
  239. return str(sz) + fs
  240. def localProxy(self, params):
  241. url = self.getDownloadUrl(params['url'])
  242. baseUrl = self.getCache('baseUrl')
  243. if not baseUrl:
  244. baseUrl = self.regStr(reg="(http.*://.*?/)", src=params['url'])
  245. header = self.header.copy()
  246. header['Referer'] = baseUrl
  247. content = self.fetch(url, headers=header).content.decode()
  248. contentTyep = params['sformat']
  249. action = {'url': '', 'header': header, 'param': '', 'type': 'string'}
  250. return [200, contentTyep, action, content]
  251. def getDownloadUrl(self, url):
  252. params = []
  253. password = ''
  254. if '&&&' in url:
  255. urlList = url.split('&&&')
  256. url = urlList[0]
  257. for uL in urlList:
  258. if uL.startswith('login'):
  259. login = json.loads(uL.replace('login', ''))
  260. elif uL.startswith('params'):
  261. params = json.loads(uL.replace('params', ''))
  262. if url.count('/') == 2:
  263. url = url + '/'
  264. header = self.header.copy()
  265. baseUrl = self.getCache('baseUrl')
  266. if not baseUrl:
  267. baseUrl = self.regStr(reg="(http.*://.*?/)", src=url)
  268. header['Referer'] = baseUrl
  269. token = self.getCache('token')
  270. if token:
  271. token = token['token']
  272. else:
  273. data = self.postJson(baseUrl + 'api/auth/