Skip to content

Commit

Permalink
Merge pull request #625 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 Nov 22, 2024
2 parents 4e98e38 + 14d49ee commit 780d2cb
Show file tree
Hide file tree
Showing 33 changed files with 1,760 additions and 157 deletions.
11 changes: 11 additions & 0 deletions lib/routes/ajcass/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: '社科期刊网',
url: 'ajcass.com',
description: '中国社会科学院学术期刊方阵',
lang: 'zh-CN',
zh: {
name: '社科期刊网',
},
};
73 changes: 73 additions & 0 deletions lib/routes/ajcass/shxyj.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Route } from '@/types';
import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';

export const route: Route = {
path: '/shxyj/:year?/:issue?',
categories: ['journal'],
example: '/ajcass/shxyj/2024/1',
parameters: { year: 'Year of the issue, `null` for the lastest', issue: 'Issue number, `null` for the lastest' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
name: '社会学研究',
maintainers: ['CNYoki'],
handler,
};

async function handler(ctx) {
let { year, issue } = ctx.req.param();

if (!year) {
const response = await got('https://shxyj.ajcass.com/');
const $ = load(response.body);
const latestIssueText = $('p.hod.pop').first().text();

const match = latestIssueText.match(/(\d{4}) Vol\.(\d+):/);
if (match) {
year = match[1];
issue = match[2];
} else {
throw new Error('无法获取最新的 year 和 issue');
}
}

const url = `https://shxyj.ajcass.com/Magazine/?Year=${year}&Issue=${issue}`;
const response = await got(url);
const $ = load(response.body);

const items = $('#tab tr')
.toArray()
.map((item) => {
const $item = $(item);
const articleTitle = $item.find('a').first().text().trim();
const articleLink = $item.find('a').first().attr('href');
const summary = $item.find('li').eq(1).text().replace('[摘要]', '').trim();
const authors = $item.find('li').eq(2).text().replace('作者:', '').trim();
const pubDate = parseDate(`${year}-${Number.parseInt(issue) * 2}`);

if (articleTitle && articleLink) {
return {
title: articleTitle,
link: `https://shxyj.ajcass.com${articleLink}`,
description: summary,
author: authors,
pubDate,
};
}
return null;
})
.filter((item) => item !== null);

return {
title: `社会学研究 ${year}年第${issue}期`,
link: url,
item: items,
};
}
7 changes: 7 additions & 0 deletions lib/routes/cybersecurityventures/namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Namespace } from '@/types';

export const namespace: Namespace = {
name: 'Cybercrime Magazine',
url: 'cybersecurityventures.com',
lang: 'en',
};
121 changes: 121 additions & 0 deletions lib/routes/cybersecurityventures/news.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { type Data, type DataItem, type Route, ViewType } from '@/types';
import ofetch from '@/utils/ofetch';
import type { Context } from 'hono';
import { parseDate } from '@/utils/parse-date';
import { load } from 'cheerio';
import InvalidParameterError from '@/errors/types/invalid-parameter';
import type { RawRecord } from './types';

const categories: Record<
string,
{
label: string;
scene: number;
view: number;
}
> = {
today: {
label: "Today's News",
scene: 12,
view: 14,
},
'intrusion-daily-cyber-threat-alert': {
label: 'Cyberattacks',
scene: 13,
view: 15,
},
'ransomware-minute': {
label: 'Ransomware',
scene: 16,
view: 18,
},
cryptocrime: {
label: 'Cryptocrime',
scene: 18,
view: 20,
},
'hack-blotter': {
label: 'Hack Blotter',
scene: 19,
view: 21,
},
'cybersecurity-venture-capital-vc-deals': {
label: 'VC Deal Flow',
scene: 3,
view: 3,
},
'mergers-and-acquisitions-report': {
label: 'M&A Tracker',
scene: 11,
view: 13,
},
};

export const route: Route = {
name: 'News',
categories: ['programming'],
path: '/news/:category?',
example: '/cybersecurityventures/news',
radar: Object.keys(categories).map((key) => ({
source: [`cybersecurityventures.com/${key}`],
target: `/news/${key}`,
title: categories[key].label,
})),
parameters: {
category: {
description: 'news category',
default: 'today',
options: Object.keys(categories).map((key) => ({
value: key,
label: categories[key].label,
})),
},
},
handler,
maintainers: ['KarasuShin'],
features: {
supportRadar: true,
},
view: ViewType.Articles,
};

async function handler(ctx: Context): Promise<Data> {
const rootUrl = 'https://cybersecurityventures.com/';
const apiUrl = 'https://us-east-1-renderer-read.knack.com/v1';
const category = ctx.req.param('category') ?? 'today';
const limit = ctx.req.query('limit') ?? 20;

if (!(category in categories)) {
throw new InvalidParameterError('Invalid category');
}

const { scene, view, label } = categories[category];

const data = await ofetch<{
records: RawRecord[];
}>(`${apiUrl}/scenes/scene_${scene}/views/view_${view}/records?format=raw&page=1&rows_per_page=${limit}&sort_field=field_2&sort_order=desc`, {
headers: {
'X-Knack-Application-Id': '6013171b60be8f001cb27363',
'X-Knack-Rest-Api-Key': 'renderer',
},
});

return {
title: `${label} - Cybercrime Magazine`,
link: `${rootUrl}/${category}`,
item: data.records.map((item) => {
const $ = load(item.field_3, null, false);
const link = $('a').attr('href');
const source = item.field_4;
const description = `<p>${source}</p><br>${$.html()}`;

return {
title: item.field_5,
description,
pubDate: parseDate(item.field_2.iso_timestamp),
link,
guid: `cybersecurityventures:${item.id}`,
} as DataItem;
}),
};
}
17 changes: 17 additions & 0 deletions lib/routes/cybersecurityventures/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface RawRecord {
id: string;
field_2: {
date: string;
date_formatted: string;
hours: string;
minutes: string;
am_pm: string;
unix_timestamp: number;
iso_timestamp: string;
timestamp: string;
time: number;
};
field_3: string;
field_4: string;
field_5: string;
}
Loading

0 comments on commit 780d2cb

Please sign in to comment.