pan99_open.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import { Crypto, load, _ } from 'assets://js/lib/cat.js';
  2. import { log } from './lib/utils.js';
  3. import { initAli, detailContentVodPlayFrom, detailContentVodPlayUrl, playContent } from './lib/ali.js';
  4. let siteKey = 'pan99';
  5. let siteType = 0;
  6. const siteUrl = 'https://pan99.xyz';
  7. const UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1';
  8. async function request(reqUrl) {
  9. const res = await req(reqUrl, {
  10. method: 'get',
  11. headers: {
  12. 'User-Agent': UA,
  13. 'Referer': siteUrl,
  14. },
  15. });
  16. return res.content;
  17. }
  18. // cfg = {skey: siteKey, ext: extend}
  19. async function init(cfg) {
  20. try {
  21. siteKey = cfg.skey;
  22. siteType = cfg.stype;
  23. await initAli(cfg.ext);
  24. } catch (e) {
  25. await log('init:' + e.message + ' line:' + e.lineNumber);
  26. }
  27. }
  28. async function home(filter) {
  29. const classes = [{'type_id':'dy','type_name':'电影'},{'type_id':'tv','type_name':'完结剧集'},{'type_id':'tv/geng','type_name':'追更剧集'},{'type_id':'tv/netflix','type_name':'Netflix'}];
  30. const filterObj = {};
  31. return JSON.stringify({
  32. class: classes,
  33. filters: filterObj,
  34. });
  35. }
  36. async function homeVod() {}
  37. async function category(tid, pg, filter, extend) {
  38. let page = '';
  39. if (pg > 1) {
  40. page = 'page/' + pg + '/';
  41. }
  42. const cateUrl = siteUrl + '/category/' + tid + '/' + page;
  43. const html = await request(cateUrl);
  44. const $ = load(html);
  45. const list = $('.post-item');
  46. const jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  47. const videos = _.map(list, (vid) => {
  48. const $vid = $(vid);
  49. const $link = $vid.find('.media-img');
  50. const $entry = $vid.find('.entry-cat-dot');
  51. return {
  52. vod_id: decodeURIComponent($link.attr('href').replace(/.*\/\/.*\/(.*\/.*)\//g, '$1')),
  53. vod_name: $link.attr('title'),
  54. vod_pic: jsBase + base64Encode($link.attr("data-bg")),
  55. vod_remarks: $entry.text().trim(),
  56. };
  57. });
  58. const limit = 50;
  59. const curPage = parseInt(pg);
  60. const hasMore = videos.length == limit;
  61. const pgCount = hasMore ? curPage + 1 : curPage;
  62. return JSON.stringify({
  63. page: curPage,
  64. pagecount: pgCount,
  65. limit: limit,
  66. total: limit * pgCount,
  67. list: videos,
  68. });
  69. }
  70. async function detail(id) {
  71. const detailUrl = siteUrl + '/' + id;
  72. const html = await request(detailUrl);
  73. const $ = load(html);
  74. const $cards = $('.card p a:not([href*=quark])');
  75. const shareLinks = _.map($cards, (card) => {
  76. return $(card).attr('href').trim();
  77. });
  78. const content = $('.post-content').text();
  79. const jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  80. const vod = {
  81. vod_id: id,
  82. vod_name: $('.post-title.mb-2.mb-lg-3').text().trim(),
  83. vod_director: matchDetailContent(content, /◎导  演([\w\W]*?)◎/),
  84. vod_actor: matchDetailContent(content, /◎演  员([\w\W]*?)◎/),
  85. vod_year: matchDetailContent(content, /◎年  代(.*)/),
  86. vod_area: matchDetailContent(content, /◎产  地(.*)/),
  87. vod_type: matchDetailContent(content, /◎类  别(.*)/),
  88. vod_pic: jsBase + base64Encode($('img.alignnone.size-medium').attr('src')),
  89. vod_content: matchDetailContent(content, /◎简  介([\w\W]*)资源失效/),
  90. vod_remarks: $('.meta-cat-dot').text().trim(),
  91. };
  92. try {
  93. vod.vod_play_from = detailContentVodPlayFrom(shareLinks);
  94. vod.vod_play_url = await detailContentVodPlayUrl(shareLinks);
  95. } catch (e) {
  96. await log('detail:' + e.message + ' line:' + e.lineNumber);
  97. }
  98. return JSON.stringify({
  99. list: [vod],
  100. });
  101. }
  102. function matchDetailContent(contentText, regex) {
  103. const matches = contentText.match(regex);
  104. if (!_.isEmpty(matches)) {
  105. const index = matches.length - 1;
  106. return matches[index].trim();
  107. }
  108. return '';
  109. }
  110. function base64Encode(text) {
  111. return Crypto.enc.Base64.stringify(Crypto.enc.Utf8.parse(text));
  112. }
  113. function base64Decode(text) {
  114. return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
  115. }
  116. async function proxy(segments, headers) {
  117. const what = segments[0];
  118. const url = base64Decode(segments[1]);
  119. if (what == 'img') {
  120. const resp = await req(url, {
  121. buffer: 2,
  122. headers: {
  123. 'Referer': 'https://api.douban.com/',
  124. 'User-Agent': UA,
  125. },
  126. });
  127. return JSON.stringify({
  128. code: resp.code,
  129. buffer: 2,
  130. content: resp.content,
  131. headers: resp.headers,
  132. });
  133. }
  134. return JSON.stringify({
  135. code: 500,
  136. content: '',
  137. });
  138. }
  139. async function play(flag, id, flags) {
  140. try {
  141. return await playContent(flag, id, flags);
  142. } catch (e) {
  143. await log('play:' + e.message + ' line:' + e.lineNumber);
  144. }
  145. }
  146. async function search(wd, quick, pg) {
  147. let page = '';
  148. if (pg > 1) {
  149. page = 'page/' + pg + '/';
  150. }
  151. const searchUrl = siteUrl + '/' + page + '?cat=&s=' + encodeURIComponent(wd);
  152. const html = await request(searchUrl);
  153. const $ = load(html);
  154. const list = $('.post-item');
  155. const jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  156. const videos = _.map(list, (vid) => {
  157. const $vid = $(vid);
  158. const $link = $vid.find('.media-img');
  159. const $entry = $vid.find('.entry-cat-dot');
  160. return {
  161. vod_id: decodeURIComponent($link.attr('href').replace(/.*\/\/.*\/(.*\/.*)\//g, '$1')),
  162. vod_name: $link.attr('title'),
  163. vod_pic: jsBase + base64Encode($link.attr("data-bg")),
  164. vod_remarks: $entry.text().trim(),
  165. };
  166. });
  167. const limit = 50;
  168. const curPage = parseInt(pg);
  169. const hasMore = videos.length == limit;
  170. const pgCount = hasMore ? curPage + 1 : curPage;
  171. return JSON.stringify({
  172. page: curPage,
  173. pagecount: pgCount,
  174. limit: limit,
  175. total: limit * pgCount,
  176. list: videos,
  177. });
  178. }
  179. export function __jsEvalReturn() {
  180. return {
  181. init: init,
  182. home: home,
  183. homeVod: homeVod,
  184. category: category,
  185. detail: detail,
  186. play: play,
  187. proxy: proxy,
  188. search: search,
  189. };
  190. }