Skip to content

Commit

Permalink
Merge pull request #1346 from DIYgod/master
Browse files Browse the repository at this point in the history
[pull] master from diygod:master
  • Loading branch information
pull[bot] authored Apr 10, 2024
2 parents 3e1f79c + 8f451ab commit 20041fb
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 268 deletions.
13 changes: 2 additions & 11 deletions lib/routes/500px/tribe-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Route } from '@/types';
import { getCurrentPath } from '@/utils/helpers';
const __dirname = getCurrentPath(import.meta.url);

import cache from '@/utils/cache';
import { parseDate } from '@/utils/parse-date';
import { art } from '@/utils/render';
import path from 'node:path';
Expand All @@ -14,14 +13,6 @@ export const route: Route = {
categories: ['picture'],
example: '/500px/tribe/set/f5de0b8aa6d54ec486f5e79616418001',
parameters: { id: '部落 ID' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
name: '部落影集',
maintainers: ['TonyRL'],
handler,
Expand All @@ -31,8 +22,8 @@ async function handler(ctx) {
const id = ctx.req.param('id');
const limit = Number.parseInt(ctx.req.query('limit')) || 100;

const { tribe } = await getTribeDetail(id, cache.tryGet);
const tribeSets = await getTribeSets(id, limit, cache.tryGet);
const { tribe } = await getTribeDetail(id);
const tribeSets = await getTribeSets(id, limit);

const items = tribeSets.map((item) => ({
title: item.title,
Expand Down
60 changes: 0 additions & 60 deletions lib/routes/500px/user.ts

This file was deleted.

45 changes: 23 additions & 22 deletions lib/routes/500px/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import got from '@/utils/got';
import ofetch from '@/utils/ofetch';
import cache from '@/utils/cache';
import { load } from 'cheerio';
import { config } from '@/config';

Expand All @@ -24,39 +25,39 @@ const headers = {
'X-Tingyun-Id': `Fm3hXcTiLT8;r=${Date.now() % 1e8}`,
};

const getUserInfoFromUsername = (username, tryGet) =>
tryGet(`500px:user:${username}`, async () => {
const { data } = await got(`${baseUrl}/${username}`);
const getUserInfoFromUsername = (username) =>
cache.tryGet(`500px:user:${username}`, async () => {
const data = await ofetch(`${baseUrl}/${username}`);
const $ = load(data);
return JSON.parse(
$('script[type="text/javascript"]')
.text()
.match(/var cur_user = new Object\((.*?)\);/)[1]
.match(/var cur_user = new Object\((.*?)\);/)?.[1] || '{}'
);
});

const getUserInfoFromId = (id, tryGet) =>
tryGet(`500px:user:indexInfo:${id}`, async () => {
const { data } = await got(`${baseUrl}/community/v2/user/indexInfo`, {
const getUserInfoFromId = (id) =>
cache.tryGet(`500px:user:indexInfo:${id}`, async () => {
const data = await ofetch(`${baseUrl}/community/v2/user/indexInfo`, {
headers: {
...headers,
},
searchParams: {
query: {
queriedUserId: id,
},
});
return data.data;
});

const getUserWorks = (id, limit, tryGet) =>
tryGet(
const getUserWorks = (id, limit) =>
cache.tryGet(
`500px:user:profile:${id}`,
async () => {
const { data } = await got(`${baseUrl}/community/v2/user/profile`, {
const data = await ofetch(`${baseUrl}/community/v2/user/profile`, {
headers: {
...headers,
},
searchParams: {
query: {
resourceType: '0,2,4',
imgsize: 'p1,p2,p3,p4',
queriedUserId: id,
Expand All @@ -66,21 +67,21 @@ const getUserWorks = (id, limit, tryGet) =>
type: 'json',
},
});
return data.data;
return data;
},
config.cache.routeExpire,
false
);

const getTribeDetail = (id, tryGet) =>
tryGet(
const getTribeDetail = (id) =>
cache.tryGet(
`500px:tribeDetail:${id}`,
async () => {
const { data } = await got(`${baseUrl}/community/tribe/tribeDetail`, {
const data = await ofetch(`${baseUrl}/community/tribe/tribeDetail`, {
headers: {
...headers,
},
searchParams: {
query: {
tribeId: id,
},
});
Expand All @@ -90,15 +91,15 @@ const getTribeDetail = (id, tryGet) =>
false
);

const getTribeSets = (id, limit, tryGet) =>
tryGet(
const getTribeSets = (id, limit) =>
cache.tryGet(
`500px:tribeSets:${id}`,
async () => {
const { data } = await got(`${baseUrl}/community/tribe/getTribeSetsV2`, {
const data = await ofetch(`${baseUrl}/community/tribe/getTribeSetsV2`, {
headers: {
...headers,
},
searchParams: {
query: {
tribeId: id,
privacy: 1,
page: 1,
Expand Down
8 changes: 4 additions & 4 deletions lib/routes/discourse/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import { getConfig } from './utils';
import got from '@/utils/got';
import ofetch from '@/utils/ofetch';

export const route: Route = {
path: '/:configId/notifications/:fulltext?',
Expand Down Expand Up @@ -32,7 +32,7 @@ If you opt to enable \`fulltext\` feature, consider adding \`limit\` parameter t
async function handler(ctx) {
const { link, key } = getConfig(ctx);

const response = await got(`${link}/notifications.json`, { headers: { 'User-Api-Key': key } }).json();
const response = await ofetch(`${link}/notifications.json`, { headers: { 'User-Api-Key': key } });
let items = response.notifications.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10).map((e) => ({
title: e.fancy_title ?? e.data.badge_name,
link: `${link}/${Object.hasOwn(e.data, 'badge_id') ? `badges/${e.data.badge_id}/${e.data.badge_slug}?username=${e.data.username}` : `t/topic/${e.topic_id}/${e.post_number}`}`,
Expand All @@ -48,7 +48,7 @@ async function handler(ctx) {
if (e.original_post_id) {
const post_link = `${link}/posts/${e.original_post_id}.json`;
return cache.tryGet(post_link, async () => {
const { cooked } = await got(post_link, { headers: { 'User-Api-Key': key } }).json();
const { cooked } = await ofetch(post_link, { headers: { 'User-Api-Key': key } });
return { ...e, description: cooked };
});
} else {
Expand All @@ -58,7 +58,7 @@ async function handler(ctx) {
);
}

const { about } = await got(`${link}/about.json`, { headers: { 'User-Api-Key': key } }).json();
const { about } = await ofetch(`${link}/about.json`, { headers: { 'User-Api-Key': key } });
return {
title: `${about.title} - Notifications`,
description: about.description,
Expand Down
6 changes: 6 additions & 0 deletions lib/routes/hitcon/namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Namespace } from '@/types';

export const namespace: Namespace = {
name: 'HITCON',
url: 'hitcon.org',
};
8 changes: 8 additions & 0 deletions lib/routes/hitcon/templates/zeroday.art
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<ul>
<li>{{ vender }}</li>
<li>ZDID: {{ code }}</li>
<li>風險: {{ risk }}</li>
<li>處理狀態: {{ status }}</li>
<li>通報者: {{ reporter }}</li>
<li>通報日期: {{ date }}</li>
</ul>
109 changes: 109 additions & 0 deletions lib/routes/hitcon/zeroday.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type { Data, DataItem, Route } from '@/types';
import type { Context } from 'hono';
import { load } from 'cheerio';
import puppeteer from '@/utils/puppeteer';
import logger from '@/utils/logger';
import { art } from '@/utils/render';
import path from 'node:path';
import { parseDate } from '@/utils/parse-date';
import { getCurrentPath } from '@/utils/helpers';

const __dirname = getCurrentPath(import.meta.url);

export const route: Route = {
name: '漏洞',
categories: ['programming'],
path: '/zeroday/vulnerability/:status?',
example: '/hitcon/zeroday/vulnerability',
parameters: {
status: '漏洞状态,见下表',
},
maintainers: ['KarasuShin'],
radar: [
{
source: ['zeroday.hitcon.org/vulnerability/:status?'],
},
],
features: {
requirePuppeteer: true,
},
handler,
description: `| 缺省 | all | closed | disclosed | patching |
| ------ | ---- | ------ | --------- | -------- |
| 活動中 | 全部 | 關閉 | 公開 | 修補中 |`,
};

const baseUrl = 'https://zeroday.hitcon.org/vulnerability';

const titleMap = {
all: '全部',
closed: '關閉',
disclosed: '公開',
patching: '修補中',
};

async function handler(ctx: Context): Promise<Data> {
let url = baseUrl;
const status = ctx.req.param('status');
if (status) {
url += `/${status}`;
}

const browser = await puppeteer();
const page = await browser.newPage();
await page.setRequestInterception(true);

page.on('request', (request) => {
request.resourceType() === 'document' ? request.continue() : request.abort();
});

logger.http(`Requesting ${url}`);
await page.goto(url, {
waitUntil: 'domcontentloaded',
});

const response = await page.evaluate(() => document.documentElement.innerHTML);
browser.close();

const $ = load(response);
const items: DataItem[] = $('.zdui-strip-list>li')
.toArray()
.map((el) => {
const title = $(el).find('.title a');
const vulData = $(el).find('.vul-data');
const code = vulData
.find('.code')
.contents()
.filter(function () {
return this.nodeType === 3;
})
.text();
const risk = vulData.find('.risk span').eq(1).text();
const vender = vulData.find('.vender').find('.v-name-full').text();
const status = vulData.find('.status').text().replace('Status:', '').trim();
const date = vulData.find('.date').text().replace('Date:', '').trim();
const reporter = vulData.find('.zdui-author-badge').find('a>span').text();
const description = art(path.join(__dirname, 'templates/zeroday.art'), {
code,
risk,
vender,
status,
date,
reporter,
});

return {
title: title.text(),
link: title.attr('href'),
description,
pubDate: parseDate(date),
};
});

return {
title: status ? titleMap[status] ?? 'ZeroDay' : '活動中',
link: url,
item: items,
image: 'https://zeroday.hitcon.org/images/favicon/favicon.png',
};
}
Loading

0 comments on commit 20041fb

Please sign in to comment.