Skip to content

Commit

Permalink
Merge branch 'DIYgod:master' into my-feature
Browse files Browse the repository at this point in the history
  • Loading branch information
findwei authored Nov 14, 2024
2 parents 5bdd2bb + 8550150 commit 632f963
Show file tree
Hide file tree
Showing 31 changed files with 446 additions and 124 deletions.
6 changes: 6 additions & 0 deletions lib/middleware/template.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,10 @@ describe('template', () => {
expect(parsed.items[0].enclosure?.length).toBe('3661');
expect(parsed.items[0].itunes.duration).toBe('10:10:10');
});

it(`redirect`, async () => {
const response = await app.request('/test/redirect');
expect(response.status).toBe(301);
expect(response.headers.get('location')).toBe('/test/1');
});
});
4 changes: 3 additions & 1 deletion lib/middleware/template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
return ctx.json(result);
}

if (ctx.get('no-content')) {
if (ctx.get('redirect')) {
return ctx.redirect(ctx.get('redirect'), 301);
} else if (ctx.get('no-content')) {
return ctx.body(null);
} else {
// retain .ums for backward compatibility
Expand Down
2 changes: 1 addition & 1 deletion lib/routes/141jav/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async function handler(ctx) {
const $ = load(response.data);

if (getSubPath(ctx) === '/') {
ctx.redirect(`/141jav${$('.overview').first().attr('href')}`);
ctx.set('redirect', `/141jav${$('.overview').first().attr('href')}`);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/routes/141ppv/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async function handler(ctx) {
const $ = load(response.data);

if (getSubPath(ctx) === '/') {
ctx.redirect(`/141ppv${$('.overview').first().attr('href')}`);
ctx.set('redirect', `/141ppv${$('.overview').first().attr('href')}`);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/routes/aqara/region.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ function handler(ctx) {

const { region = 'en', type = 'news' } = ctx.req.param();
const redirectTo = `/aqara/${region}/category/${types[type]}`;
ctx.redirect(redirectTo);
ctx.set('redirect', redirectTo);
}
20 changes: 19 additions & 1 deletion lib/routes/bilibili/ranking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const ridTypeList = [
];

export const route: Route = {
path: '/ranking/:rid_index?/:embed?',
path: '/ranking/:rid_index?/:embed?/:redirect1?/:redirect2?',
name: '排行榜',
maintainers: ['DIYgod', 'hyoban'],
categories: ['social-media', 'popular'],
Expand All @@ -130,10 +130,20 @@ export const route: Route = {
})).filter((_, i) => !ridTypeList[i].startsWith('pgc/')),
},
embed: '默认为开启内嵌视频, 任意值为关闭',
redirect1: '留空,用于兼容之前的路由',
redirect2: '留空,用于兼容之前的路由',
},
handler,
};

function getRidIndexByRid(rid: string): number {
const index = ridNumberList.indexOf(rid);
if (index === -1) {
throw new Error('Invalid rid');
}
return index;
}

function getAPI(ridIndex: number) {
if (ridIndex < 0 || ridIndex >= ridNumberList.length) {
throw new Error('Invalid rid index');
Expand Down Expand Up @@ -172,6 +182,14 @@ function getAPI(ridIndex: number) {
}

async function handler(ctx) {
const args = ctx.req.param();
if (args.redirect1 || args.redirect2) {
// redirect old routes like /bilibili/ranking/0/3/1 or /bilibili/ranking/0/3/1/xxx
const embedArg = args.redirect2 ? '/' + args.redirect2 : '';
ctx.set('redirect', `/bilibili/ranking/${getRidIndexByRid(args.rid_index)}${embedArg}`);
return;
}

const ridIndex = ctx.req.param('rid_index') || '0';
const embed = !ctx.req.param('embed');

Expand Down
7 changes: 6 additions & 1 deletion lib/routes/caixin/latest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ async function handler(ctx) {
// desc
const desc = await parseArticle(item);

item.description = ctx.req.query('fulltext') === 'true' ? ((await getFulltext(item.link)) ?? desc.description) : desc.description;
if (ctx.req.query('fulltext') === 'true') {
const authorizedFullText = await getFulltext(item.link);
item.description = authorizedFullText === '' ? desc.description : authorizedFullText;
} else {
item.description = desc.description;
}
// prevent cache coliision with /caixin/article and /caixin/:column/:category
// since those have podcasts
item.guid = `caixin:latest:${item.link}`;
Expand Down
4 changes: 2 additions & 2 deletions lib/routes/caixin/utils-fulltext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ export async function getFulltext(url: string) {
},
});

const { content } = JSON.parse(res.data.match(/resetContentInfo\((.*)\)/)[1]);
return content;
const { content = '', pictureList } = JSON.parse(res.data.match(/resetContentInfo\((.*)\)/)[1]);
return content + (pictureList ? pictureList.map((e) => `<img src="${e.url}" id="picture_${e.id}" alt="${e.desc}"><dl><dt>${e.desc}</dt></dl>`).join('') : '');
}
2 changes: 1 addition & 1 deletion lib/routes/cs/zzkx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ function handler(ctx) {
// https://www.cs.com.cn/sylm/jsbd/

const redirectTo = '/cs/sylm/jsbd';
ctx.redirect(redirectTo);
ctx.set('redirect', redirectTo);
}
2 changes: 1 addition & 1 deletion lib/routes/dongqiudi/daily.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export const route: Route = {
};

function handler(ctx) {
ctx.redirect('/dongqiudi/special/48');
ctx.set('redirect', '/dongqiudi/special/48');
}
3 changes: 3 additions & 0 deletions lib/routes/hellogithub/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const md = MarkdownIt({
import { load } from 'cheerio';
import cache from '@/utils/cache';
import { config } from '@/config';
import { parseDate } from '@/utils/parse-date';

art.defaults.imports.render = function (string) {
return md.render(string);
Expand Down Expand Up @@ -39,6 +40,7 @@ async function handler(ctx) {
const items = await Promise.all(
volumes.map(async (volume) => {
const current = volume.num;
const lastmod = volume.lastmod;
const currentUrl = `${rootUrl}/periodical/volume/${current}`;
const key = `hellogithub:${currentUrl}`;
return await cache.tryGet(
Expand All @@ -61,6 +63,7 @@ async function handler(ctx) {
description: art(path.join(__dirname, 'templates/volume.art'), {
data: data.pageProps.volume.data,
}),
pubDate: parseDate(lastmod),
};
},
config.cache.routeExpire,
Expand Down
2 changes: 1 addition & 1 deletion lib/routes/hostmonit/cloudflareyesv6.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export const route: Route = {
};

function handler(ctx) {
ctx.redirect('/hostmonit/cloudflareyes/v6');
ctx.set('redirect', '/hostmonit/cloudflareyes/v6');
}
80 changes: 80 additions & 0 deletions lib/routes/hrbeu/sec/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
const rootUrl = 'http://sec.hrbeu.edu.cn';

export const route: Route = {
path: '/sec/:id',
categories: ['university'],
example: '/hrbeu/sec/xshd',
parameters: { id: '栏目编号,由 `URL` 中获取。' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['sec.hrbeu.edu.cn/:id/list.htm'],
},
],
name: '船舶工程学院',
maintainers: ['Chi-hong22'],
handler,
description: `| 学院要闻 | 学术活动 | 通知公告 | 学科方向 |
| :------: | :------: |:------: | :------: |
| xyyw | xshd | 229 | xkfx |`,
};

async function handler(ctx) {
const id = ctx.req.param('id');
const response = await got(`${rootUrl}/${id}/list.htm`, {
headers: {
Referer: rootUrl,
},
});

const $ = load(response.data);

const bigTitle = $('div [class=lanmuInnerMiddleBigClass_right]').find('div [portletmode=simpleColumnAttri]').text().replaceAll(/[\s·]/g, '').trim();

const list = $('li.list_item')
.toArray()
.map((item) => {
let link = $(item).find('a').attr('href');
if (link && link.includes('page.htm')) {
link = `${rootUrl}${link}`;
}
return {
title: $(item).find('a').attr('title'),
pubDate: parseDate($(item).find('span.Article_PublishDate').text()),
link,
};
});

const items = await Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
if (item.link.includes('page.htm')) {
const detailResponse = await got(item.link);
const content = load(detailResponse.data);
item.description = content('div.wp_articlecontent').html();
} else {
item.description = '本文需跳转,请点击标题后阅读';
}
return item;
})
)
);

return {
title: '船舶工程学院 - ' + bigTitle,
link: rootUrl.concat('/', id, '/list.htm'),
item: items,
};
}
10 changes: 9 additions & 1 deletion lib/routes/inspirehep/author.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ export const route: Route = {
handler,
};

export const getAuthorById = (id: string) => cache.tryGet(`inspirehep:author:${id}`, () => ofetch<AuthorResponse>(`${baseUrl}/api/authors/${id}`));
export const getAuthorById = (id: string) =>
cache.tryGet(`inspirehep:author:${id}`, () =>
ofetch<AuthorResponse>(`${baseUrl}/api/authors/${id}`, {
headers: {
accept: 'application/vnd+inspire.record.ui+json',
},
parseResponse: JSON.parse,
})
);

async function handler(ctx) {
const id = ctx.req.param('id');
Expand Down
11 changes: 11 additions & 0 deletions lib/routes/isct/namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Namespace } from '@/types';

export const namespace: Namespace = {
name: 'Institute of Science Tokyo',
url: 'isct.ac.jp',
lang: 'ja',

ja: {
name: '東京科学大学',
},
};
66 changes: 66 additions & 0 deletions lib/routes/isct/news.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import { decode } from 'entities';

interface NewsItem {
ID: string;
TITLE: string;
PUBLISH_DATE: string;
META_DESCRIPTION: string;
MEDIA_CD: string;
}

export const route: Route = {
path: '/news/:lang',
categories: ['university'],
example: '/isct/news/ja',
parameters: { lang: 'language, could be ja or en' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['www.isct.ac.jp/:lang/news'],
target: '/news/:lang',
},
],
name: 'News',
maintainers: ['catyyy'],
handler: async (ctx) => {
const { lang = 'ja' } = ctx.req.param();
const response = await ofetch(`https://www.isct.ac.jp/expansion/get_media_list_json.php?lang_cd=${lang}`);

const decodedResponse = decode(response);
const data = JSON.parse(decodedResponse);
const itemsArray: NewsItem[] = Object.values(data);

const items = itemsArray.map((item) => ({
// 文章标题
title: item.TITLE,
// 文章链接
link: 'news/' + item.MEDIA_CD,
// 文章正文
description: item.META_DESCRIPTION,
// 文章发布日期
pubDate: parseDate(item.PUBLISH_DATE),
// 如果有的话,文章作者
// author: item.user.login,
// 如果有的话,文章分类
// category: item.labels.map((label) => label.name),
}));
return {
// 源标题
title: `ISCT News - ${lang}`,
// 源链接
link: `https://www.isct.ac.jp/${lang}/news`,
// 源文章
item: items,
};
},
};
2 changes: 1 addition & 1 deletion lib/routes/jiemian/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ function handler(ctx) {
const id = ctx.req.param('id');

const redirectTo = `/jiemian${id ? `/lists/${id}` : ''}`;
ctx.redirect(redirectTo);
ctx.set('redirect', redirectTo);
}
2 changes: 1 addition & 1 deletion lib/routes/liulinblog/itnews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export const route: Route = {
function handler(ctx) {
const { channel } = ctx.req.param();
const redirectTo = `/liulinblog/${channel}`;
ctx.redirect(redirectTo);
ctx.set('redirect', redirectTo);
}
20 changes: 19 additions & 1 deletion lib/routes/misskey/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,25 @@ const parseNotes = (data: MisskeyNote[], site: string) =>
title = `${author}: "${noteToUse.text ?? ''}"`;
}

const link = `https://${host}/notes/${noteToUse.id}`;
/**
* For renotes from non-Misskey instances (e.g. Mastodon, Pleroma),
* we can't use noteToUse.id to link to the original note since:
* 1. The URL format differs from Misskey's /notes/{id} pattern
* 2. Direct access to the original note may not be possible
* Therefore, we link to the renote itself in such cases
*/
let noteId = noteToUse.id;

if (isRenote) {
const renoteHost = item.user.host ?? site;
const noteHost = noteToUse.user.host ?? site;

// Use renote's ID if the note is from a different host or not in allowSiteList
if (renoteHost !== noteHost || !allowSiteList.includes(noteHost)) {
noteId = item.id;
}
}
const link = `https://${host}/notes/${noteId}`;
const pubDate = parseDate(noteToUse.createdAt);

return {
Expand Down
4 changes: 2 additions & 2 deletions lib/routes/mittrchina/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function handler(ctx) {
const { type = 'index' } = ctx.req.param();
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 10;

const link = `https://apii.mittrchina.com${typeMap[type].apiPath}`;
const link = `https://apii.web.mittrchina.com${typeMap[type].apiPath}`;
const { data: response } =
type === 'breaking'
? await got.post(link, {
Expand Down Expand Up @@ -95,7 +95,7 @@ async function handler(ctx) {
cache.tryGet(item.link, async () => {
const {
data: { data: details },
} = await got(`https://apii.mittrchina.com/information/details?id=${item.id}`);
} = await got(`https://apii.web.mittrchina.com/information/details?id=${item.id}`);

item.description = details.content;

Expand Down
Loading

0 comments on commit 632f963

Please sign in to comment.