feat(route): add slashdot (#20942)

* feat(route): add slashdot

* chore: apply changes
This commit is contained in:
Tony 2026-01-22 07:02:53 +08:00 committed by GitHub
parent aa55379145
commit 02826c6d9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 94 additions and 0 deletions

View File

@ -0,0 +1,87 @@
import { load } from 'cheerio';
import { InvalidParameterError } from '@/errors/types/invalid-parameter';
import type { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import { isValidHost } from '@/utils/valid-host';
export const route: Route = {
path: '/:section?',
categories: ['new-media'],
example: '/slashdot',
parameters: { section: 'Section name, can be found in the URL host, leave empty for the main page' },
radar: [
{
source: ['slashdot.org'],
},
{
source: ['devices.slashdot.org'],
target: '/devices',
},
{
source: ['build.slashdot.org'],
target: '/build',
},
{
source: ['entertainment.slashdot.org'],
target: '/entertainment',
},
{
source: ['technology.slashdot.org'],
target: '/technology',
},
{
source: ['science.slashdot.org'],
target: '/science',
},
{
source: ['yro.slashdot.org'],
target: '/yro',
},
],
name: 'News',
maintainers: ['TonyRL'],
handler,
};
async function handler(ctx) {
const { section } = ctx.req.param();
if (section && !isValidHost(section)) {
throw new InvalidParameterError('Invalid section name');
}
const link = section ? `https://${section}.slashdot.org` : 'https://slashdot.org';
const response = await ofetch(link);
const $ = load(response);
const list = $('.article')
.toArray()
.map((item) => {
const $item = $(item);
const a = $item.find('.story-title a').first();
const details = $item.find('.details');
return {
title: a.text(),
link: a.attr('href'),
description: $item.find('.body').html(),
pubDate: parseDate(
details
.find('time')
.attr('datetime')
?.replace(/on\s\w+?day\s/, '')
?.replace('@', '')
?.replace(/(\d{2}:\d{2})(\w{2})$/, '$1 $2')
),
};
});
return {
title: $('head title').text(),
description: $('meta[name="description"]').attr('content'),
link,
item: list,
};
}

View File

@ -0,0 +1,7 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: 'Slashdot',
url: 'slashdot.org',
lang: 'en',
};