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,
+ };
+}