diff --git a/open/zhishi_juhe.js b/open/zhishi_juhe.js new file mode 100644 index 0000000..eae470d --- /dev/null +++ b/open/zhishi_juhe.js @@ -0,0 +1,287 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '聚合知识[知]', + lang: 'cat' +}) +*/ + +let siteName = '聚合知识', siteKey = '', siteType = 0; + +const platformList = [ + { name: '古诗鉴赏', id: 'gushi' }, + { name: '博看听书', id: 'bokan' }, + { name: '科学辟谣', id: 'kepu' } +]; + +const headers = { + 'User-Agent': 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36' +}; + +const rule = { + gushi: { host: 'http://dbfm.taikeji.com', cateApi: '/v1/poemcate', poemApi: '/v1/poem' }, + bokan: { host: 'https://api.bookan.com.cn', bookList: '/voice/book/list', albumUnits: '/voice/album/units', searchApi: 'https://es.bookan.com.cn/api/v3/voice/book' }, + kepu: { host: 'https://piyao.kepuchina.cn', mediaList: '/h5/ajaxGetMediaList', videoDetail: '/h5/videodetail' } +}; + +const filterOptions = { + gushi: [{ key: "area", name: "分类", value: [{ "n": "分类", "v": "543" }, { "n": "诗人", "v": "552" }, { "n": "朝代", "v": "547" }] }], + bokan: [{ key: "area", name: "分类", value: [{ "n": "少年读物", "v": "1305" }, { "n": "儿童文学", "v": "1304" }, { "n": "国学经典", "v": "1320" }, { "n": "文艺少年", "v": "1306" }, { "n": "育儿心经", "v": "1309" }, { "n": "心理哲学", "v": "1310" }, { "n": "青春励志", "v": "1307" }, { "n": "历史小说", "v": "1312" }, { "n": "故事会", "v": "1303" }, { "n": "音乐戏剧", "v": "1317" }, { "n": "相声评书", "v": "1319" }] }], + kepu: [{ key: "area", name: "分类", value: [{ "n": "科学辟谣", "v": "2" }] }] +}; + +const ruleFilterDef = { + gushi: { area: '543' }, + bokan: { area: '1309' }, + kepu: { area: '2' } +}; + +function init(cfg) { + siteName = cfg.skey?.split('_')[1] || cfg.skey || '聚合知识'; + siteKey = cfg.skey; + siteType = cfg.stype; +} + +function safeJSONParse(str, defaultValue = {}) { + if (!str || typeof str === 'object') return str || defaultValue; + try { + return JSON.parse(str); + } catch { + return defaultValue; + } +} + +async function request(url, options = {}) { + const reqHeaders = { ...headers, ...options.headers }; + let postType = reqHeaders['Content-Type']?.includes('json') ? 'json' : + reqHeaders['Content-Type']?.includes('form') ? 'form' : ''; + + try { + const response = await req(url, { + method: options.method || 'GET', + headers: reqHeaders, + data: options.data, + postType: postType, + timeout: options.timeout || 15000 + }); + return response?.content || response?.data || response; + } catch { + return null; + } +} + +function getDate(time) { + let date = new Date(parseInt(time) * 1000); + let y = date.getFullYear(); + let MM = date.getMonth() + 1; + MM = MM < 10 ? ('0' + MM) : MM; + let d = date.getDate(); + d = d < 10 ? ('0' + d) : d; + let h = date.getHours(); + h = h < 10 ? ('0' + h) : h; + let m = date.getMinutes(); + m = m < 10 ? ('0' + m) : m; + let s = date.getSeconds(); + s = s < 10 ? ('0' + s) : s; + return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s; +} + +function getPlatList() { return platformList; } + +async function getGushiList(typeId, page) { + let videos = []; + try { + const cateHtml = await request(rule.gushi.host + rule.gushi.cateApi + '?channel=znds&deviceid=d652f03ce6c89719886dc199c0724b19&model=V1990A&packagename=com.monster.tvfm&random=1727208873340&sdkinfo=10&sdkint=29&vcode=2&vname=1.0.1'); + const cateData = safeJSONParse(cateHtml).data; + for (const a of cateData) { + if (a.id == typeId) { + const items = a.items[0]?.items || []; + videos = items.map(b => ({ vod_id: `gushi@${typeId},${a.items[0].id},${b.id}`, vod_name: b.title || '未知古诗', vod_pic: b.pic || '', vod_remarks: '古诗鉴赏', vod_content: '' })); + break; + } + } + } catch (e) {} + return videos; +} + +async function getBokanList(typeId, page) { + let videos = []; + try { + const url = `${rule.bokan.host}${rule.bokan.bookList}?instance_id=25304&page=${page}&category_id=${typeId}&num=24`; + const html = await request(url); + const data = safeJSONParse(html).data; + const books = data.list || []; + videos = books.map(book => ({ vod_id: `bokan@${book.id}`, vod_name: book.name || '未知书籍', vod_pic: book.cover || '', vod_remarks: `博看 | ${book.extra?.author || ''}`, vod_content: book.extra?.description || '' })); + } catch (e) {} + return videos; +} + +async function getKepuList(typeId, page) { + let videos = []; + try { + const url = `${rule.kepu.host}${rule.kepu.mediaList}?page=${page}&page_type=${typeId}&title=`; + const html = await request(url); + const data = safeJSONParse(html).data; + const list = data.list || []; + videos = list.map(it => { + const keywords = it.keywords?.map(i => i.keyword).join('、') || ''; + return { vod_id: `kepu@${it.id}&${getDate(it.discern_time)}&${keywords}&${it.audit_info}&${it.title_pre}&${it.origin}`, vod_name: it.title || '未知视频', vod_pic: it.cover || '', vod_remarks: `科学辟谣 | ${getDate(it.discern_time)}`, vod_content: it.title_pre || '' }; + }); + } catch (e) {} + return videos; +} + +async function getGushiDetail(id) { + let vod = {}; + try { + const url = `${rule.gushi.host}${rule.gushi.poemApi}?cateid=${id}&limit=100&page=1`; + const html = await request(url); + const data = safeJSONParse(html).data.list || []; + const playUrls = data.map(it => `${it.title}-${it.dynasty}-${it.author}$${it.source}`).join('#'); + vod = { vod_id: id, vod_name: '古诗选集', vod_pic: '', vod_content: `共${data.length}首古诗`, vod_remarks: '古诗鉴赏', vod_play_from: "古诗鉴赏", vod_play_url: playUrls }; + } catch (e) {} + return vod; +} + +async function getBokanDetail(id) { + let vod = {}; + try { + const url = `${rule.bokan.host}${rule.bokan.albumUnits}?album_id=${id}&page=1&num=200&order=1`; + const html = await request(url); + const data = safeJSONParse(html).data; + const list = data.list || []; + const playUrls = list.map(b => { const name = b.title.trim().replace(/<|>|《|》/g, '').replace(/\$|#/g, ' ').trim(); return `${name}$${b.file}`; }).join('#'); + vod = { vod_id: id, vod_name: '', vod_pic: '', vod_content: '', vod_remarks: `共${list.length}集`, vod_play_from: "博看听书", vod_play_url: playUrls, audio: 1 }; + } catch (e) {} + return vod; +} + +async function getKepuDetail(id) { + let vod = {}; + try { + const parts = id.split('&'); + const vodId = parts[0]; + const date = parts[1]; + const keywords = parts[2]; + const actor = parts[3]; + const content = parts[4]; + const origin = parts[5]; + vod = { vod_id: id, vod_name: '科学辟谣视频', vod_pic: '', vod_content: content || '', vod_actor: actor || '', vod_year: date || '', vod_type: origin || '', vod_remarks: `关键词:${keywords || ''}`, vod_play_from: "科学辟谣", vod_play_url: `点击播放$${vodId}` }; + } catch (e) {} + return vod; +} + +async function searchBokan(wd, page) { + const results = []; + try { + const url = `${rule.bokan.searchApi}?instanceId=25304&keyword=${encodeURIComponent(wd)}&pageNum=${page}&limitNum=20`; + const html = await request(url); + const data = safeJSONParse(html).data; + const books = data.list || []; + results.push(...books.map(book => ({ vod_id: `bokan@${book.id}`, vod_name: book.name || '未知书籍', vod_pic: book.cover || '', vod_remarks: `博看 | ${book.extra?.author || ''}`, vod_content: book.extra?.description || '' }))); + } catch (e) {} + return results; +} + +async function searchKepu(wd, page) { + const results = []; + try { + const url = `${rule.kepu.host}${rule.kepu.mediaList}?page=${page}&page_type=2&title=${encodeURIComponent(wd)}`; + const html = await request(url); + const data = safeJSONParse(html).data; + const list = data.list || []; + results.push(...list.map(it => { const keywords = it.keywords?.map(i => i.keyword).join('、') || ''; return { vod_id: `kepu@${it.id}&${getDate(it.discern_time)}&${keywords}&${it.audit_info}&${it.title_pre}&${it.origin}`, vod_name: it.title || '未知视频', vod_pic: it.cover || '', vod_remarks: `科学辟谣 | ${getDate(it.discern_time)}`, vod_content: it.title_pre || '' }; })); + } catch (e) {} + return results; +} + +async function home(filter) { + const platForms = getPlatList(); + const classes = platForms.map(item => ({ type_name: item.name, type_id: item.id, type_flag: '[CFS][SUBSITE2][FILTERBAR]' })); + const filters = {}; + platForms.forEach(item => { if (filterOptions[item.id]) filters[item.id] = filterOptions[item.id]; }); + return JSON.stringify({ class: classes, filters: filters }); +} + +async function homeVod() { + const platForms = getPlatList(); + const randomPlat = platForms[Math.floor(Math.random() * platForms.length)]; + const randomArea = ruleFilterDef[randomPlat.id]?.area || ''; + const categoryResult = await category(randomPlat.id, 1, { area: randomArea }, {}); + const categoryList = safeJSONParse(categoryResult).list || []; + return JSON.stringify({ list: categoryList }); +} + +async function category(tid, pg, filter, extend) { + const page = pg || 1; + extend = extend || {}; + const platformItem = platformList.find(p => p.id === tid); + if (!platformItem) return JSON.stringify({ list: [], page, pagecount: 1, limit: 0, total: 0 }); + const searchKeyword = extend?.custom; + if (searchKeyword) return await cfs(tid, searchKeyword, pg); + const area = filter?.area || extend?.area || ruleFilterDef[tid]?.area || ''; + const videos = []; + switch (tid) { + case 'gushi': videos.push(...await getGushiList(area, page)); break; + case 'bokan': videos.push(...await getBokanList(area, page)); break; + case 'kepu': videos.push(...await getKepuList(area, page)); break; + } + return JSON.stringify({ list: videos, page: page, pagecount: page + 1, limit: videos.length, total: videos.length * (page + 1) }); +} + +async function detail(id) { + const parts = id.split('@'); + const platform = parts[0]; + const did = parts.slice(1).join('@'); + let vod = {}; + if (platform === 'gushi') vod = await getGushiDetail(did); + else if (platform === 'bokan') vod = await getBokanDetail(did); + else if (platform === 'kepu') vod = await getKepuDetail(did); + return JSON.stringify({ list: [vod] }); +} + +async function play(flag, id, flags) { + if (flag.includes('古诗')) return JSON.stringify({ parse: 0, url: id }); + if (flag.includes('博看')) return JSON.stringify({ parse: 0, url: id }); + if (flag.includes('科学辟谣')) { + try { + const detailUrl = `${rule.kepu.host}${rule.kepu.videoDetail}?id=${id}`; + const html = await request(detailUrl); + let videoUrl = ''; + const srcMatch = html.match(/src="([^"]+\.mp4[^"]*)"/); + if (srcMatch) videoUrl = srcMatch[1]; + if (!videoUrl) { + const sourceMatch = html.match(/]*src=["']([^"']+)["']/); + if (sourceMatch) videoUrl = sourceMatch[1]; + } + return JSON.stringify({ parse: 0, url: videoUrl || '', header: headers }); + } catch (e) { + return JSON.stringify({ parse: 0, url: id }); + } + } + return JSON.stringify({ parse: 0, url: id }); +} + +async function cfs(siteId, wd, pg) { + const page = pg || 1; + let results = []; + if (siteId === 'gushi') results = []; + else if (siteId === 'bokan') results = await searchBokan(wd, page); + else if (siteId === 'kepu') results = await searchKepu(wd, page); + return JSON.stringify({ list: results, page: page, pagecount: page + 1, limit: results.length, total: results.length * (page + 1) }); +} + +async function search(wd, quick, pg) { + const videos = []; + const page = pg || 1; + const bokanResults = await searchBokan(wd, page); + const kepuResults = await searchKepu(wd, page); + videos.push(...bokanResults, ...kepuResults); + return JSON.stringify({ list: videos, page: page, pagecount: page + 1, limit: videos.length, total: videos.length * (page + 1) }); +} + +export function __jsEvalReturn() { + return { init, home, homeVod, category, detail, play, search }; +} \ No newline at end of file