From 5364464831421fc3c298ef2531f08438a8f11263 Mon Sep 17 00:00:00 2001 From: SrakhiuMeow <59913171+SrakhiuMeow@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:19:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(route):=20=E6=B7=BB=E5=8A=A0Lofter?= =?UTF-8?q?=E7=9A=84=E5=90=88=E9=9B=86=E8=8E=B7=E5=8F=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20(#16732)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加获取Lofter合集内容的功能 * 添加获取Lofter合集内容的功能 * bug fix * 将抓取行为由仅抓取前50条改为抓取全部合集内容 * 代码规范 * eslint warning fixed * bugfix * 更新 collection.ts * removed page turn * fix: fallback title --------- --- lib/routes/lofter/collection.ts | 87 +++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 lib/routes/lofter/collection.ts diff --git a/lib/routes/lofter/collection.ts b/lib/routes/lofter/collection.ts new file mode 100644 index 00000000000000..7ec2784d807e43 --- /dev/null +++ b/lib/routes/lofter/collection.ts @@ -0,0 +1,87 @@ +import { Route } from '@/types'; +import got from '@/utils/got'; +import cache from '@/utils/cache'; +import { config } from '@/config'; +import { parseDate } from '@/utils/parse-date'; + +export const route: Route = { + path: '/collection/:collectionID', + categories: ['social-media'], + example: '/lofter/collection/552041', + parameters: { collectionID: 'Lofter collection ID, can be found in the share URL' }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + name: 'Collection', + maintainers: ['SrakhiuMeow'], + handler, +}; + +async function fetchCollection(collectionID, limit, offset = 0) { + const response = await got({ + method: 'post', + url: 'https://api.lofter.com/v1.1/postCollection.api?product=lofter-android-7.6.12', + body: new URLSearchParams({ + collectionid: collectionID, + limit: limit.toString(), + method: 'getCollectionDetail', + offset: offset.toString(), + order: '0', + }), + }); + + if (!response.data.response) { + throw new Error('Collection Not Found'); + } + + const data = response.data.response; + + return { + title: data.collection.name || 'Lofter Collection', + link: data.blogInfo.homePageUrl || 'https://www.lofter.com/', + description: data.collection.description || 'No description provided.', + items: data.items, + } as object; +} + +async function handler(ctx) { + const collectionID = ctx.req.param('collectionID'); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : '50'; + + const response = await cache.tryGet(collectionID, () => fetchCollection(collectionID, Number(limit)), config.cache.routeExpire, false); + + const { title, link, description, items } = response; + + const itemsArray = items.map((item) => ({ + title: item.post.title || item.post.noticeLinkTitle, + link: item.post.blogPageUrl, + description: + JSON.parse(item.post.photoLinks || `[]`) + .map((photo) => { + if (photo.raw?.match(/\/\/nos\.netease\.com\//)) { + photo.raw = `https://${photo.raw.match(/(imglf\d)/)[0]}.lf127.net${photo.raw.match(/\/\/nos\.netease\.com\/imglf\d(.*)/)[1]}`; + } + return ``; + }) + .join('') + + JSON.parse(item.post.embed ? `[${item.post.embed}]` : `[]`) + .map((video) => ``) + .join('') + + item.post.content, + pubDate: parseDate(item.post.publishTime), + author: item.post.blogInfo.blogNickName, + category: item.post.tag.split(','), + })); + + return { + title, + link, + item: itemsArray, + description, + }; +}