Skip to content

Commit

Permalink
fix(route/keylol): 改进有阅读权限的帖子 (#16285)
Browse files Browse the repository at this point in the history
* fix(route/keylol): 改进有阅读权限的帖子

未登录或权限不足时
pubDate author 会使用列表页的数据
description 会显示错误讯息

* change type

* 设置 KEYLOL_COOKIE 登录账户

* Update doc for KEYLOL_COOKIE
  • Loading branch information
kennyfong19931 authored Jul 29, 2024
1 parent acd64df commit 12b45b2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 11 deletions.
6 changes: 6 additions & 0 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ export type Config = {
javdb: {
session?: string;
};
keylol: {
cookie?: string;
};
lastfm: {
api_key?: string;
};
Expand Down Expand Up @@ -534,6 +537,9 @@ const calculateValue = () => {
javdb: {
session: envs.JAVDB_SESSION,
},
keylol: {
cookie: envs.KEYLOL_COOKIE,
},
lastfm: {
api_key: envs.LASTFM_API_KEY,
},
Expand Down
56 changes: 45 additions & 11 deletions lib/routes/keylol/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import { config } from '@/config';
import got from '@/utils/got';
import { load } from 'cheerio';
import timezone from '@/utils/timezone';
import { parseDate } from '@/utils/parse-date';
import { parseDate, parseRelativeDate } from '@/utils/parse-date';
import parser from '@/utils/rss-parser';
import queryString from 'query-string';

const threadIdRegex = /(\d+)-\d+-\d+/;
const header = {
Cookie: config.keylol.cookie ?? undefined,
};

export const route: Route = {
path: '/:path',
name: '论坛',
parameters: { path: '路径,默认为热点聚焦' },
categories: ['game'],
example: '/keylol/f161-1',
features: {
requireConfig: [
{
name: 'KEYLOL_COOKIE',
optional: true,
description: `配置后可抓取具有阅读权限的帖子內容`,
},
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['keylol.com/:path'],
Expand Down Expand Up @@ -58,31 +76,41 @@ async function handler(ctx) {
const rootUrl = 'https://keylol.com';
const currentUrl = queryString.stringifyUrl({ url: `${rootUrl}/forum.php`, query: queryParams });

const { data: response } = await got(currentUrl);
const { data: response } = await got({
method: 'get',
url: currentUrl,
headers: header,
});

const $ = load(response);

let items = $('tbody[id^="normalthread_"] a.xst')
let items = $('tbody[id^="normalthread_"]')
.slice(0, limit)
.toArray()
.map((item) => {
item = $(item);

return {
title: item.text(),
link: new URL(item.prop('href').split('&extra=')[0], rootUrl).href,
title: item.find('a.xst').text(),
link: new URL(item.find(' a.xst').prop('href').split('&extra=')[0], rootUrl).href,
author: item.find('td.by-author cite').text(),
pubDate: parseRelativeDate(item.find('td.by-author em').text().replaceAll(' 发表', '')),
};
});

items = await Promise.all(
items.map((item) =>
cache.tryGet(item.link, async () => {
const threadId = threadIdRegex.test(item.link) ? item.link.match(threadIdRegex)[1] : queryString.parseUrl(item.link).query.tid;
const { data: detailResponse } = await got(item.link);
const { data: detailResponse } = await got({
method: 'get',
url: item.link,
headers: header,
});

const content = load(detailResponse);

let descriptionList: any[] = [];
let descriptionList: string[] = [];
const indexDiv = content('div#threadindex');
if (indexDiv.length > 0) {
// post with page
Expand Down Expand Up @@ -110,8 +138,10 @@ async function handler(ctx) {
}

item.description = descriptionList.join('<br/>');
const authorName = authorNameMap.find((a) => a.threadId === threadId);
item.author = authorName && authorName.length > 0 ? authorName[0].author : content('a.xw1').first().text();
const realAuthorName = authorNameMap.find((a) => a.threadId === threadId);
if (realAuthorName) {
item.author = realAuthorName.author;
}
item.category = content('#keyloL_thread_tags a')
.toArray()
.map((c) => content(c).text());
Expand Down Expand Up @@ -156,11 +186,15 @@ async function handler(ctx) {
function getDescription($) {
const descriptionEl = $('td.t_f');
descriptionEl.find('div.rnd_ai_pr').remove(); // remove ad image
return descriptionEl.html();
return descriptionEl.length > 0 ? descriptionEl.html() : $('div.alert_info').html();
}

async function getPage(url, pageTitle) {
const { data: detailResponse } = await got(url);
const { data: detailResponse } = await got({
method: 'get',
url,
headers: header,
});

const $ = load(detailResponse, { xmlMode: true });
const content = $('root').text();
Expand Down

0 comments on commit 12b45b2

Please sign in to comment.