From 19a7f6779691b05dd67152ac5da1f5fba0b1fefd Mon Sep 17 00:00:00 2001 From: Hualiang <78242797+hualiong@users.noreply.github.com> Date: Tue, 25 Jun 2024 02:18:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(route):=20=E6=96=B0=E5=A2=9E=E9=AD=94?= =?UTF-8?q?=E9=83=BD=E8=B5=84=E6=BA=90=E7=BD=91=20(#15974)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(route): 新增魔都资源网 * fix dirname * fix --- lib/routes/moduzy/index.ts | 84 +++++++++++++++++++++++++ lib/routes/moduzy/namespace.ts | 17 ++++++ lib/routes/moduzy/templates/vod.art | 12 ++++ lib/routes/moduzy/type.ts | 95 +++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 lib/routes/moduzy/index.ts create mode 100644 lib/routes/moduzy/namespace.ts create mode 100644 lib/routes/moduzy/templates/vod.art create mode 100644 lib/routes/moduzy/type.ts diff --git a/lib/routes/moduzy/index.ts b/lib/routes/moduzy/index.ts new file mode 100644 index 000000000..12e228857 --- /dev/null +++ b/lib/routes/moduzy/index.ts @@ -0,0 +1,84 @@ +import { Result, Vod } from '@/routes/moduzy/type'; +import { DataItem, Route } from '@/types'; +import ofetch from '@/utils/ofetch'; +import path from 'node:path'; +import { parseDate } from '@/utils/parse-date'; +import { art } from '@/utils/render'; +import timezone from '@/utils/timezone'; +import { getCurrentPath } from '@/utils/helpers'; + +const render = (vod: Vod, link: string) => art(path.join(getCurrentPath(import.meta.url), 'templates', 'vod.art'), { vod, link }); + +export const route: Route = { + path: '/:type/:hours?', + categories: ['multimedia'], + example: '/moduzy/2', + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + parameters: { + type: '类别ID,具体见下表,为 0 代表全部类别', + hours: '获取截止到几小时前的数据,默认不限', + }, + radar: [ + { + source: ['moduzy.cc', 'moduzy.net', 'moduzy.com', 'moduzy1.com', 'moduzy2.com', 'moduzy3.com', 'moduzy4.com', 'moduzy5.com', 'moduzy6.com', 'moduzy7.com', 'moduzy8.com', 'moduzy9.com', 'moduzy10.com'], + }, + ], + name: '最新资源', + maintainers: ['hualiong'], + url: 'moduzy.net', + description: ` +:::warning +不建议订阅\`全部类别\`和\`国产动漫\`,因为该类型每天的更新量会大幅超过单次抓取的最大上限20条而被截断 +**温馨提醒**:该资源网以**动漫资源**为主,部分影视类别可能会没有资源 +::: + +| 类别 | ID | 类别 | ID | 类别 | ID | +| ---- | ---- | ---- | ---- | ---- | ---- | +| 国产动漫 | 1 | 日韩动漫 | 2 | 欧美动漫 | 3 | +| 港台动漫 | 4 | 动漫电影 | 5 | 里番动漫 | 6 | +| 动作片 | 10 | 喜剧片 | 11 | 爱情片 | 12 | +| 科幻片 | 13 | 恐怖片 | 14 | 剧情片 | 15 | +| 战争片 | 16 | 惊悚片 | 17 | 家庭片 | 18 | +| 古装片 | 19 | 历史片 | 20 | 悬疑片 | 21 | +| 犯罪片 | 22 | 灾难片 | 23 | 记录片 | 24 | +| 短片 | 25 | 国产剧 | 26 | 香港剧 | 27 | +| 韩国剧 | 28 | 欧美剧 | 29 | 台湾剧 | 30 | +| 日本剧 | 31 | 海外剧 | 32 | 泰国剧 | 33 | +| 大陆综艺 | 34 | 港台综艺 | 35 | 日韩综艺 | 36 | +| 欧美综艺 | 37 | 全部类别 | 0 | | |`, + handler: async (ctx) => { + const { type, hours = '' } = ctx.req.param(); + const query = async (pg: number) => + await ofetch('https://moduzy.net/api.php/provide/vod', { + parseResponse: JSON.parse, + query: { ac: 'detail', t: type || '', h: hours, pg }, + }); + + const res = await query(1); + + const items: DataItem[] = res.list.map((each) => ({ + title: each.vod_name, + image: each.vod_pic, + link: `https://moduzy.net/vod/${each.vod_id}/`, + guid: each.vod_play_url.match(/https:\/\/.+?\.m3u8/g)?.slice(-1)[0], + pubDate: timezone(parseDate(each.vod_time, 'YYYY-MM-DD HH:mm:ss'), +8), + category: [each.type_name, ...each.vod_class.split(',')], + description: render(each, `https://moduzy.net/vod/${each.vod_id}/`) + each.vod_content, + })); + + return { + title: `最新${type && items.length ? items[0].category![0] : '资源'} - 魔都资源网`, + link: 'https://moduzy.net', + allowEmpty: true, + language: 'zh-cn', + item: items, + }; + }, +}; diff --git a/lib/routes/moduzy/namespace.ts b/lib/routes/moduzy/namespace.ts new file mode 100644 index 000000000..839fc57d4 --- /dev/null +++ b/lib/routes/moduzy/namespace.ts @@ -0,0 +1,17 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '魔都资源网', + url: 'www.moduzy.com', + description: ` +:::tip +哔嘀影视有多个备用域名,路由默认使用域名 \`moduzy.net\` 确保在中国大陆内的实例也能访问。如果你想直接访问源站可以通过以下域名: + +- moduzy.com(主域名,大陆内无法访问) +- moduzy.cc +- moduzy.net +- moduzy1.com - moduzy10.com(均可访问) + +官方的导航页:[moduzy.vip](https://www.moduzy.vip) +:::`, +}; diff --git a/lib/routes/moduzy/templates/vod.art b/lib/routes/moduzy/templates/vod.art new file mode 100644 index 000000000..cea9457f9 --- /dev/null +++ b/lib/routes/moduzy/templates/vod.art @@ -0,0 +1,12 @@ +{{ vod.vod_name }} +

{{ vod.vod_name }} {{ vod.vod_remarks }}

+

别名:{{ vod.vod_sub }}

+

导演:{{ vod.vod_director }}

+

主演:{{ vod.vod_actor }}

+

类型:{{ vod.vod_class }}

+

年份:{{ vod.vod_year }}

+

地区:{{ vod.vod_area }}

+

开播时间:{{ vod.vod_pubdate }}

+

更新时间:{{ vod.vod_time }}

+

资源主页:{{ link }}

+

剧情介绍

\ No newline at end of file diff --git a/lib/routes/moduzy/type.ts b/lib/routes/moduzy/type.ts new file mode 100644 index 000000000..0b671ef13 --- /dev/null +++ b/lib/routes/moduzy/type.ts @@ -0,0 +1,95 @@ +export type Result = { + code: number; + msg: string; + page: string; + pagecount: number; + limit: string; + total: number; + list: Array; +}; + +export type Vod = { + vod_id: number; + type_id: number; + type_id_1: number; + group_id: number; + vod_name: string; + vod_sub: string; + vod_en: string; + vod_status: number; + vod_letter: string; + vod_color: string; + vod_tag: string; + vod_class: string; + vod_pic: string; + vod_pic_thumb: string; + vod_pic_slide: string; + vod_pic_screenshot: string; + vod_actor: string; + vod_director: string; + vod_writer: string; + vod_behind: string; + vod_blurb: string; + vod_remarks: string; + vod_pubdate: string; + vod_total: number; + vod_serial: string; + vod_tv: string; + vod_weekday: string; + vod_area: string; + vod_lang: string; + vod_year: string; + vod_version: string; + vod_state: string; + vod_author: string; + vod_jumpurl: string; + vod_tpl: string; + vod_tpl_play: string; + vod_tpl_down: string; + vod_isend: number; + vod_lock: number; + vod_level: number; + vod_copyright: number; + vod_points: number; + vod_points_play: number; + vod_points_down: number; + vod_hits: number; + vod_hits_day: number; + vod_hits_week: number; + vod_hits_month: number; + vod_duration: string; + vod_up: number; + vod_down: number; + vod_score: string; + vod_score_all: number; + vod_score_num: number; + vod_time: string; + vod_time_add: number; + vod_time_hits: number; + vod_time_make: number; + vod_trysee: number; + vod_douban_id: number; + vod_douban_score: string; + vod_reurl: string; + vod_rel_vod: string; + vod_rel_art: string; + vod_pwd: string; + vod_pwd_url: string; + vod_pwd_play: string; + vod_pwd_play_url: string; + vod_pwd_down: string; + vod_pwd_down_url: string; + vod_content: string; + vod_play_from: string; + vod_play_server: string; + vod_play_note: string; + vod_play_url: string; + vod_down_from: string; + vod_down_server: string; + vod_down_note: string; + vod_down_url: string; + vod_plot: number; + vod_plot_name: string; + vod_plot_detail: string; + type_name: string; +};