UNPKG

rsshub

Version:
228 lines (213 loc) 8.17 kB
import { Route, ViewType } from '@/types'; // 导入所需模组 import got from '@/utils/got'; // 自订的 got import { parseDate } from '@/utils/parse-date'; import dayjs from 'dayjs'; import path from 'node:path'; import { art } from '@/utils/render'; // 分类 const categoryMap = [ { keywords: 'video-motiongraphic', category: 'portfolio.category.trevorbenitez', }, { keywords: 'graphic-design', category: 'portfolio.category.lynnrogers', }, { keywords: 'branding-editorial', category: 'portfolio.category.katiethompson', }, { keywords: 'UI-UX', category: 'portfolio.category.brittneyhall', }, { keywords: 'illustration', category: 'portfolio.category.margaretbullock', }, { keywords: 'digital-art', category: 'portfolio.category.amandahoward', }, { keywords: 'character-design', category: 'portfolio.category.rachelsharp', }, { keywords: 'product-package-design', category: 'portfolio.category.vanessacohen', }, { keywords: 'photography', category: 'portfolio.category.johnmurray', }, { keywords: 'typography', category: 'portfolio.category.timothysmith', }, { keywords: 'crafts', category: 'portfolio.category.jessicaking', }, { keywords: 'fine-art', category: 'portfolio.category.johnmedina', }, ]; /** * @param category 分类 * @param order 排序 [like, pick, published] * @param time 时间范围 ['one-day', 'week', 'month', 'three-month'] * @param query 搜索词 * @query limit 分页,默认20 */ export const route: Route = { path: '/search/:category?/:order?/:time?/:query?', categories: ['design'], view: ViewType.Pictures, example: '/notefolio/search/1/pick/all/life', parameters: { category: { description: 'Category, see below', options: [ { value: 'all', label: 'All (전체)' }, { value: '1', label: 'Video / Motion Graphics (영상/모션그래픽)' }, { value: '2', label: 'Graphic Design (그래픽 디자인)' }, { value: '3', label: 'Branding / Editing (브랜딩/편집)' }, { value: '4', label: 'UI/UX (UI/UX)' }, { value: '5', label: 'Illustration (일러스트레이션)' }, { value: '6', label: 'Digital Art (디지털 아트)' }, { value: '7', label: 'Character Design (캐릭터 디자인)' }, { value: '8', label: 'Product Package Design (제품/패키지 디자인)' }, { value: '9', label: 'Photography (포토그래피)' }, { value: '10', label: 'Typography (타이포그래피)' }, { value: '11', label: 'Crafts (공예)' }, { value: '12', label: 'Fine Art (파인아트)' }, ], default: 'all', }, order: { description: 'Order, `pick` as Notefolio Pick, `published` as Newest, `like` as like, `pick` by default', options: [ { value: 'pick', label: 'Notefolio Pick' }, { value: 'published', label: 'Newest' }, { value: 'like', label: 'Like' }, ], default: 'pick', }, time: { description: 'Time', options: [ { value: 'all', label: 'All the time' }, { value: 'one-day', label: 'Latest 24 hours' }, { value: 'week', label: 'Latest week' }, { value: 'month', label: 'Latest month' }, { value: 'three-month', label: 'Latest 3 months' }, ], default: 'all', }, query: 'Keyword, empty by default', }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, }, radar: [ { source: ['notefolio.net/search'], }, ], name: 'Works', maintainers: ['BianTan'], handler, url: 'notefolio.net/search', description: `| Category | Name in Korean | Name in English | | -------- | ------------------ | ----------------------- | | all | 전체 | All | | 1 | 영상/모션그래픽 | Video / Motion Graphics | | 2 | 그래픽 디자인 | Graphic Design | | 3 | 브랜딩/편집 | Branding / Editing | | 4 | UI/UX | UI/UX | | 5 | 일러스트레이션 | Illustration | | 6 | 디지털 아트 | Digital Art | | 7 | 캐릭터 디자인 | Character Design | | 8 | 제품/패키지 디자인 | Product Package Design | | 9 | 포토그래피 | Photography | | 10 | 타이포그래피 | Typography | | 11 | 공예 | Crafts | | 12 | 파인아트 | Fine Art |`, }; async function handler(ctx) { // 分类、排序、时间范围、搜索词 const { category = 'all', order = 'pick', time = 'all', query = '' } = ctx.req.param(); // 分页 const { limit } = ctx.req.query(); // 请求链接 let searchUrl = `https://api.stunning.kr/api/v1/dantats/portfolio?state=Public&limit=${limit ? Number.parseInt(limit, 10) : 20}&search=${query}&orderBy=${order}`; // 分类 const index = (Number(category) || 0) - 1; if (index >= 0 && categoryMap[index]) { searchUrl += `&category=${categoryMap[index].category}`; } // 时间范围 if (time !== 'all' && ['one-day', 'week', 'month', 'three-month'].includes(time)) { let startTime = ''; const endTime = dayjs().endOf('d').format('YYYY-MM-DDTHH:mm:ss.SSS'); // 过去24小时-day 最近一周-week 最近一个月-month 最近三个月three-month switch (time) { case 'one-day': startTime = dayjs().subtract(1, 'd').format('YYYY-MM-DDTHH:mm:ss.SSS'); break; case 'week': startTime = dayjs().subtract(7, 'd').startOf('d').format('YYYY-MM-DDTHH:mm:ss.SSS'); break; case 'month': startTime = dayjs().subtract(30, 'd').startOf('d').format('YYYY-MM-DDTHH:mm:ss.SSS'); break; case 'three-month': startTime = dayjs().subtract(90, 'd').startOf('d').format('YYYY-MM-DDTHH:mm:ss.SSS'); break; } searchUrl += `&publishedAt=${startTime}Z&publishedAt=${endTime}Z`; } // 发送 HTTP GET 请求到 API 并解构返回的数据对象 const { data } = await got(searchUrl, { headers: { Origin: 'https://notefolio.net', }, }); // 从 API 响应中提取相关数据 const items = data?.resultData.map((item) => { const { id, title, user, createdAt, categories = [], contents = [] } = item; const description = contents.map((item) => art(path.join(__dirname, './templates/search.art'), { item })).join(' '); return { // 文章标题 title, // 文章链接 link: `https://notefolio.net/${user.url}/${id}`, // 文章正文 description, // 文章发布日期 pubDate: parseDate(createdAt), // 如果有的话,文章作者 author: user.nick, // 如果有的话,文章分类 category: categories.map((label) => label.replace('portfolio.category.', '')), }; }) || []; return { // 源标题 title: `${category}/${order}/${time}/${query} search`, // 源链接 // link: '', // 源文章 item: items, }; }