-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Expand file tree
/
Copy pathindex.ts
More file actions
133 lines (111 loc) · 4.59 KB
/
index.ts
File metadata and controls
133 lines (111 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { load } from 'cheerio';
import type { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate, parseRelativeDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
/**
* Convert an array into a dictionary object.
* The keys of the dictionary object are the `id` properties of the elements in the array,
* and the values are the remaining properties of each element.
* @param {Array} arr - The array to be converted.
* @returns {Object} - The converted dictionary object.
*/
const arrayToDictionary = (arr) =>
Object.fromEntries(
arr.map(({ id, ...rest }) => [
id,
{
...rest,
},
])
);
export const route: Route = {
path: '/:proma?',
categories: ['new-media'],
example: '/latepost',
parameters: { proma: '栏目 id,见下表,默认为最新报道' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
name: '报道',
maintainers: ['nczitzk'],
handler,
description: `| 最新报道 | 晚点独家 | 人物访谈 | 晚点早知道 | 长报道 |
| -------- | -------- | -------- | ---------- | ------ |
| | 1 | 2 | 3 | 4 |`,
};
async function handler(ctx) {
const proma = ctx.req.param('proma');
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 5;
const title = '晚点';
const defaultTitle = '最新报道';
const exclusiveCategory = '晚点独家';
const rootUrl = 'https://www.latepost.com';
const currentUrl = new URL(proma ? `news/index?proma=${proma}` : '', rootUrl).href;
const apiColumnUrl = new URL('site/get-column', rootUrl).href;
const apiCommentUrl = new URL('news/get-comment', rootUrl).href;
const apiUrl = new URL(proma ? 'news/get-news-data' : 'site/index', rootUrl).href;
const { data: columnResponse } = await got(apiColumnUrl);
const columns = arrayToDictionary(columnResponse?.data ?? []);
const { data: response } = await got.post(apiUrl, {
form: {
page: 1,
limit,
programa: Number.parseInt(proma, 10),
},
});
let items = response.data.slice(0, limit).map((item) => ({
title: item.title,
link: new URL(item.detail_url, rootUrl).href,
category: [item.is_dj ? exclusiveCategory : undefined, item.programa ? columns[item.programa]?.title : undefined, ...item.label.map((c) => c.label)],
guid: item.id,
pubDate: parseDate(item.release_time, ['MM月DD日', 'YYYY年MM月DD日']),
}));
items = await Promise.all(
items.map((item) =>
cache.tryGet(item.link, async () => {
const { data: detailResponse } = await got(item.link);
const { data: commentResponse } = await got.post(apiCommentUrl, {
news_id: item.guid,
page: 1,
limit: Infinity,
sort: 1,
delete_num: 0,
});
const content = load(detailResponse);
item.title = item.title ?? content('div.article-header-title').text();
item.description = content('#select-main').html().replaceAll('<p><br></p>', '');
item.author = content('div.article-header-author div.author-link a.label').first().text();
item.category = item.category.filter(Boolean);
item.guid = `latepost-${item.guid}`;
const pubDate = content('div.article-header-date').text();
if (pubDate) {
item.pubDate = /\d+月\d+日/.test(pubDate) ? parseDate(pubDate, ['YYYY年MM月DD日 HH:mm', 'MM月DD日 HH:mm']) : parseRelativeDate(pubDate);
}
item.pubDate = timezone(item.pubDate, +8);
item.comments = commentResponse.data?.length() ?? 0;
return item;
})
)
);
const icon = new URL('favicon.ico', rootUrl).href;
const { data: currentResponse } = await got(currentUrl);
const $ = load(currentResponse);
return {
item: items,
title: `${title} - ${proma ? columns[proma].title : defaultTitle}`,
link: currentUrl,
description: $('div.logo-txt').first().text(),
language: 'zh-cn',
image: new URL($('div.logo-txt img').prop('src'), rootUrl).href,
icon,
logo: icon,
author: title,
};
}