ddys_open.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import { Crypto, load, _ } from 'assets://js/lib/cat.js';
  2. const key = 'ddys';
  3. let DOMAIN = 'ddys.pro';
  4. let HOST = 'https://' + DOMAIN;
  5. let PLAY_HOST = 'https://v.' + DOMAIN;
  6. const FROM_DIRECT = '直连';
  7. const FROM_PARSE = '解析';
  8. let siteKey = '';
  9. let siteType = 0;
  10. const UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 Mobile Safari/537.36';
  11. async function request(reqUrl) {
  12. const res = await req(reqUrl, {
  13. method: 'get',
  14. headers: {
  15. 'Host': HOST.match(/.*\:\/\/(.*)/)[1],
  16. 'User-Agent': UA,
  17. 'Referer': HOST,
  18. 'Accept-Encoding': 'gzip',
  19. },
  20. });
  21. return res.content;
  22. }
  23. // cfg = {skey: siteKey, ext: extend}
  24. async function init(cfg) {
  25. siteKey = cfg.skey;
  26. siteType = cfg.stype;
  27. if (cfg.hasOwnProperty('ext')) {
  28. if (cfg.ext.hasOwnProperty('domain')) {
  29. DOMAIN = cfg.ext.domain;
  30. HOST = 'https://' + DOMAIN;
  31. PLAY_HOST = 'https://v.' + DOMAIN;
  32. }
  33. }
  34. }
  35. async function home(filter) {
  36. const classes = [{'type_id':'class','type_name':'类型'},{'type_id':'movie','type_name':'电影'},{'type_id':'airing','type_name':'热映中'},{'type_id':'drama','type_name':'剧集'},{'type_id':'anime','type_name':'动画'},{'type_id':'documentary','type_name':'纪录片'},{'type_id':'variety','type_name':'综艺'}];
  37. const filterObj = {
  38. 'class':[{'key':'tag','name':'标签','init':'recommend','value':[{'n':'站长推荐','v':'recommend'},{'n':'动作','v':'action'},{'n':'喜剧','v':'comedy'},{'n':'爱情','v':'romance'},{'n':'科幻','v':'sci-fi'},{'n':'犯罪','v':'crime'},{'n':'悬疑','v':'mystery'},{'n':'恐怖','v':'horror'}]}],
  39. 'movie':[{'key':'type','name':'分类','init':'','value':[{'n':'全部','v':''},{'n':'欧美电影','v':'western-movie'},{'n':'日韩电影','v':'asian-movie'},{'n':'华语电影','v':'chinese-movie'}]}],
  40. 'drama':[{'key':'type','name':'分类','init':'','value':[{'n':'全部','v':''},{'n':'欧美剧','v':'western-drama'},{'n':'日剧','v':'jp-drama'},{'n':'韩剧','v':'kr-drama'},{'n':'华语剧','v':'cn-drama'},{'n':'其他地区','v':'other'}]}],
  41. 'anime':[{'key':'type','name':'分类','init':'','value':[{'n':'全部','v':''},{'n':'本季新番','v':'new-bangumi'}]}]
  42. };
  43. return JSON.stringify({
  44. class: classes,
  45. filters: filterObj,
  46. });
  47. }
  48. async function homeVod() {}
  49. async function category(tid, pg, filter, extend) {
  50. if (pg <= 0) pg = 1;
  51. let path = '';
  52. if (extend.tag) {
  53. path = '/tag/' + extend.tag;
  54. } else {
  55. path = '/category/' + tid;
  56. if (!_.isEmpty(extend.type)) {
  57. path += '/' + extend.type;
  58. }
  59. }
  60. let page = '';
  61. if (pg > 1) {
  62. page = 'page/' + pg + '/';
  63. }
  64. const link = HOST + path + '/' + page;
  65. const html = await request(link);
  66. const $ = load(html);
  67. const items = $('.post-box-list article');
  68. const videos = _.map(items, (item) => {
  69. const $item = $(item);
  70. const title = $item.find('.post-box-title a');
  71. const name = title.text();
  72. const url = title.attr('href');
  73. const image = $item.find('.post-box-image').attr('style').replace(/.*url\((.*)\);/g, '$1');
  74. const remarks = $item.find('.post-box-meta').text();
  75. return {
  76. vod_id: url.replace(/.*\/\/.*\/(.*)\//g, '$1'),
  77. vod_name: name,
  78. vod_pic: image,
  79. vod_remarks: remarks || '',
  80. };
  81. });
  82. const limit = 28;
  83. const hasMore = $('nav.navigation a.next').length > 0;
  84. const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
  85. return JSON.stringify({
  86. page: parseInt(pg),
  87. pagecount: pgCount,
  88. limit: limit,
  89. total: limit * pgCount,
  90. list: videos,
  91. });
  92. }
  93. async function detail(id) {
  94. const html = await request(HOST + '/' + id + '/');
  95. const $ = load(html);
  96. const abstract = $('div.abstract')[0].children;
  97. const vod = {
  98. vod_id: id,
  99. vod_name: $('h1.post-title').text(),
  100. vod_type: findAbstractText(abstract, '类型:'),
  101. vod_year: findAbstractText(abstract, '年份:'),
  102. vod_area: findAbstractText(abstract, '制片国家/地区:'),
  103. vod_director: findAbstractText(abstract, '导演:'),
  104. vod_actor: findAbstractText(abstract, '演员:'),
  105. vod_pic: $('div.post img:first').attr('data-cfsrc'),
  106. vod_remarks : $('span.cat-links').text().trim(),
  107. vod_content: findAbstractText(abstract, '简介:'),
  108. };
  109. const playMap = {};
  110. parseAndUpdateUrls($, playMap);
  111. const links = $('div.page-links a');
  112. if (!_.isEmpty(links)) {
  113. const promiseList = _.map(links, (link) => {
  114. const url = $(link).attr('href');
  115. return request(url);
  116. });
  117. const respList = await Promise.all(promiseList);
  118. _.each(respList, (resp) => {
  119. try {
  120. const $ = load(resp);
  121. parseAndUpdateUrls($, playMap);
  122. } catch(e) {
  123. }
  124. });
  125. }
  126. vod.vod_play_from = _.keys(playMap).join('$$$');
  127. const urls = _.values(playMap);
  128. const vod_play_url = _.map(urls, (urlist) => {
  129. return urlist.join('#');
  130. });
  131. vod.vod_play_url = vod_play_url.join('$$$');
  132. return JSON.stringify({
  133. list: [vod],
  134. });
  135. }
  136. function findAbstractText(children, keyword) {
  137. for (const item of children) {
  138. if (item.type == 'text' && item.data && item.data.startsWith(keyword)) {
  139. return item.data.substring(keyword.length).trim();
  140. }
  141. }
  142. return '';
  143. }
  144. function parseAndUpdateUrls($, playMap) {
  145. const trackText = $('script.wp-playlist-script').text();
  146. const tracks = JSON.parse(trackText).tracks;
  147. _.each(tracks, (track) => {
  148. const title = track.caption;
  149. const directUrl = track.src0;
  150. if (!playMap.hasOwnProperty(FROM_DIRECT)) {
  151. playMap[FROM_DIRECT] = [];
  152. }
  153. playMap[FROM_DIRECT].push(title + '$' + directUrl);
  154. if (!_.isEmpty(track.src1)) {
  155. if (!playMap.hasOwnProperty(FROM_PARSE)) {
  156. playMap[FROM_PARSE] = [];
  157. }
  158. playMap[FROM_PARSE].push(title + '$' + track.src1);
  159. }
  160. });
  161. }
  162. async function play(flag, id, flags) {
  163. let playUrl;
  164. if (flag == FROM_PARSE) {
  165. const resp = await request(HOST + '/getvddr2/video?id=' + id + '&type=json');
  166. playUrl = JSON.parse(resp).url;
  167. } else {
  168. playUrl = PLAY_HOST + id;
  169. }
  170. const headers = {
  171. 'User-Agent': UA,
  172. 'Referer': HOST,
  173. 'Icy-MetaData': '1',
  174. 'Sec-Fetch-Site': 'same-site',
  175. 'Sec-Fetch-Mode': 'cors',
  176. 'Sec-Fetch-Dest': 'video',
  177. };
  178. return JSON.stringify({
  179. parse: 0,
  180. url: playUrl,
  181. header: headers,
  182. });
  183. }
  184. async function search(wd, quick, pg) {
  185. let page = '';
  186. if (pg > 1) {
  187. page = '/page/' + pg;
  188. }
  189. const html = await request(HOST + page + '/?s=' + wd + '&post_type=post');
  190. const $ = load(html);
  191. const list = $('div.post-content');
  192. const videos = _.map(list, (item) => {
  193. const $item = $(item);
  194. const title = $item.find('.post-title a');
  195. const name = title.text();
  196. const url = title.attr('href');
  197. const remarks = $item.find('.cat-links').text();
  198. return {
  199. vod_id: url.replace(/.*\/\/.*\/(.*)\//g, '$1'),
  200. vod_name: name,
  201. vod_pic: HOST + '/android-chrome-512x512.png',
  202. vod_remarks: remarks,
  203. };
  204. });
  205. const limit = 100;
  206. const hasMore = $('nav.navigation a.next').length > 0;
  207. const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
  208. return JSON.stringify({
  209. page: parseInt(pg),
  210. pagecount: pgCount,
  211. limit: limit,
  212. total: limit * pgCount,
  213. list: videos,
  214. });
  215. }
  216. export function __jsEvalReturn() {
  217. return {
  218. init: init,
  219. home: home,
  220. homeVod: homeVod,
  221. category: category,
  222. detail: detail,
  223. play: play,
  224. search: search,
  225. };
  226. }