fix(route): ABC News (#13482)
* fix(route): ABC News * delete original file * fix typo
This commit is contained in:
parent
4d764ef13e
commit
ba4fa14a53
|
|
@ -2033,7 +2033,7 @@ router.get('/icity/:id', lazyloadRouteHandler('./routes/icity/index'));
|
|||
router.get('/anki/changes', lazyloadRouteHandler('./routes/anki/changes'));
|
||||
|
||||
// ABC News
|
||||
router.get('/abc/:id?', lazyloadRouteHandler('./routes/abc'));
|
||||
// router.get('/abc/:id?', lazyloadRouteHandler('./routes/abc'));
|
||||
|
||||
// 台湾中央通讯社
|
||||
// router.get('/cna/:id?', lazyloadRouteHandler('./routes/cna/index'));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
7272
lib/routes/abc/id.js
7272
lib/routes/abc/id.js
File diff suppressed because it is too large
Load Diff
|
|
@ -1,74 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const ids = require('./id');
|
||||
const documentIds = require('./documentId');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id ?? 'justin';
|
||||
|
||||
const isChannel = ids.hasOwnProperty(id) ? !/topic\//.test(ids[id].link) : documentIds.hasOwnProperty(id) ? !/topic\//.test(documentIds[id].link) : isNaN(id) ? undefined : true;
|
||||
|
||||
if (isChannel === undefined) {
|
||||
throw Error('Bad id. See <a href="https://docs.rsshub.app/routes/traditional-media#abc-news-channel-topic">docs</a>');
|
||||
}
|
||||
|
||||
const rootUrl = 'https://www.abc.net.au';
|
||||
const currentUrl = `${rootUrl}/news/${ids.hasOwnProperty(id) ? ids[id].link : documentIds.hasOwnProperty(id) ? documentIds[id].link : id}`;
|
||||
const apiUrl = `${rootUrl}/news-web/api/loader/${id === 'justin' ? 'justinstories?' : `${isChannel ? `channelrefetch` : `topicstories`}?name=PaginationArticles&documentId=${!isNaN(id) ? id : ids[id].documentId}&`}size=100`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: apiUrl,
|
||||
});
|
||||
|
||||
const list = response.data.collection.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 50).map((item) => ({
|
||||
title: item.title.children,
|
||||
link: `${rootUrl}${item.link.to}`,
|
||||
pubDate: parseDate(item.timestamp.dates.firstPublished.labelDate),
|
||||
}));
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
content('div[data-component="ZendeskForm"]').remove();
|
||||
content('aside[data-component="RelatedCard"]').remove();
|
||||
|
||||
item.description = '';
|
||||
|
||||
const cover = content('div[data-component="FeatureMedia"]');
|
||||
const coverImage = cover.find('img');
|
||||
coverImage.attr('src', coverImage.attr('data-src'));
|
||||
|
||||
item.description += coverImage.toString() + cover.find('figcaption').toString();
|
||||
|
||||
content('.ZN39J')
|
||||
.find('noscript')
|
||||
.each(function () {
|
||||
content(this).parent().parent().html(content(this).text());
|
||||
});
|
||||
|
||||
item.description += content('.ZN39J').html();
|
||||
item.category = content('meta[property="article:tag"]')
|
||||
.toArray()
|
||||
.map((tag) => content(tag).attr('content'));
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${ids.hasOwnProperty(id) ? ids[id].title : documentIds.hasOwnProperty(id) ? documentIds[id].title : id} - ABC`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { category = 'news/justin' } = ctx.params;
|
||||
const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30;
|
||||
|
||||
const rootUrl = 'https://www.abc.net.au';
|
||||
const apiUrl = new URL('news-web/api/loader/channelrefetch', rootUrl).href;
|
||||
|
||||
let currentUrl = '';
|
||||
let documentId = undefined;
|
||||
|
||||
if (!isNaN(category)) {
|
||||
documentId = category;
|
||||
const feedUrl = new URL(`news/feed/${documentId}/rss.xml`, rootUrl).href;
|
||||
|
||||
const { data: feedResponse } = await got(feedUrl);
|
||||
currentUrl = feedResponse.match(/<link>([\w-.:/?]+)<\/link>/)[1];
|
||||
} else {
|
||||
currentUrl = new URL(category, rootUrl).href;
|
||||
}
|
||||
|
||||
const { data: currentResponse } = await got(currentUrl);
|
||||
|
||||
const $ = cheerio.load(currentResponse);
|
||||
|
||||
documentId = documentId ?? $('div[data-uri^="coremedia://collection/"]').first().prop('data-uri').split(/\//).pop();
|
||||
|
||||
const { data: response } = await got(apiUrl, {
|
||||
searchParams: {
|
||||
name: 'PaginationArticles',
|
||||
documentId,
|
||||
size: limit,
|
||||
},
|
||||
});
|
||||
|
||||
let items = response.collection.slice(0, limit).map((i) => {
|
||||
const item = {
|
||||
title: i.title.children ?? i.title,
|
||||
link: new URL(i.link.to, rootUrl).href,
|
||||
description: art(path.join(__dirname, 'templates/description.art'), {
|
||||
image: i.image
|
||||
? {
|
||||
src: i.image.imgSrc.split(/\?/)[0],
|
||||
alt: i.image.alt,
|
||||
}
|
||||
: undefined,
|
||||
}),
|
||||
author: i.newsBylineProps?.authors?.map((a) => a.name).join('/') ?? undefined,
|
||||
guid: `abc-${i.id}`,
|
||||
pubDate: parseDate(i.timestamp.dates.firstPublished),
|
||||
updated: i.timestamp.dates.lastUpdated ? parseDate(i.timestamp.dates.lastUpdated) : undefined,
|
||||
};
|
||||
|
||||
if (i.mediaIndicator) {
|
||||
item.enclosure_type = 'audio/mpeg';
|
||||
item.itunes_item_image = i.image?.imgSrc.split(/\?/)[0] ?? undefined;
|
||||
item.itunes_duration = i.mediaIndicator.duration;
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
try {
|
||||
const { data: detailResponse } = await got(item.link);
|
||||
|
||||
const content = cheerio.load(detailResponse);
|
||||
|
||||
content('aside, header, [data-print="inline-media"], [data-component="EmbedBlock"]').remove();
|
||||
|
||||
content('#body *, div[data-component="FeatureMedia"]')
|
||||
.children()
|
||||
.each(function () {
|
||||
const element = content(this);
|
||||
if (element.prop('tagName').toLowerCase() === 'figure') {
|
||||
element.replaceWith(
|
||||
art(path.join(__dirname, 'templates/description.art'), {
|
||||
image: {
|
||||
src: element.find('img').prop('src').split(/\?/)[0],
|
||||
alt: element.find('figcaption').text().trim(),
|
||||
},
|
||||
})
|
||||
);
|
||||
} else {
|
||||
element.removeAttr('id class role data-component data-uri');
|
||||
}
|
||||
});
|
||||
|
||||
item.title = content('meta[property="og:title"]').prop('content');
|
||||
item.description = '';
|
||||
|
||||
const enclosurePattern = '"(?:MIME|content)?Type":"([\\w]+/[\\w]+)".*?"(?:fileS|s)?ize":(\\d+),.*?"url":"([\\w-.:/?]+)"';
|
||||
|
||||
const enclosureMatches = detailResponse.match(new RegExp(enclosurePattern, 'g'));
|
||||
|
||||
if (enclosureMatches) {
|
||||
const enclosureMatch = enclosureMatches
|
||||
.map((e) => e.match(new RegExp(enclosurePattern)))
|
||||
.sort((a, b) => parseInt(a[2], 10) - parseInt(b[2], 10))
|
||||
.pop();
|
||||
|
||||
item.enclosure_url = enclosureMatch[3];
|
||||
item.enclosure_length = enclosureMatch[2];
|
||||
item.enclosure_type = enclosureMatch[1];
|
||||
|
||||
item.description = art(path.join(__dirname, 'templates/description.art'), {
|
||||
enclosure: {
|
||||
src: item.enclosure_url,
|
||||
type: item.enclosure_type,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
item.description =
|
||||
art(path.join(__dirname, 'templates/description.art'), {
|
||||
description: (content('div[data-component="FeatureMedia"]').html() || '') + (content('#body div[data-component="LayoutContainer"] div').first().html() || ''),
|
||||
}) + item.description;
|
||||
|
||||
item.category = content('meta[property="article:tag"]')
|
||||
.toArray()
|
||||
.map((c) =>
|
||||
content(c)
|
||||
.prop('content')
|
||||
.split(/,/)
|
||||
.map((c) => c.trim())
|
||||
)
|
||||
.flat();
|
||||
item.guid = `abc-${content('meta[name="ContentId"]').prop('content')}`;
|
||||
item.pubDate = parseDate(content('meta[property="article:published_time"]').prop('content'));
|
||||
item.updated = parseDate(content('meta[property="article:modified_time"]').prop('content'));
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line
|
||||
}
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const icon = new URL($('link[rel="apple-touch-icon"]').prop('href'), rootUrl).href;
|
||||
|
||||
ctx.state.data = {
|
||||
item: items,
|
||||
title: $('title').first().text(),
|
||||
link: currentUrl,
|
||||
description: $('meta[property="og:description"]').prop('content'),
|
||||
language: $('html').prop('lang'),
|
||||
image: $('meta[property="og:image"]').prop('content').split('?')[0],
|
||||
icon,
|
||||
logo: icon,
|
||||
subtitle: $('meta[property="og:title"]').prop('content'),
|
||||
author: $('meta[name="generator"]').prop('content'),
|
||||
allowEmpty: true,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
'/:category?': ['nczitzk'],
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
'abc.net.au': {
|
||||
_name: 'ABC News',
|
||||
'.': [
|
||||
{
|
||||
title: 'Channel & Topic',
|
||||
docs: 'https://docs.rsshub.app/routes/traditional-media#abc-news',
|
||||
source: ['/:category*'],
|
||||
target: '/abc/:category',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = (router) => {
|
||||
router.get('/:category*', require('./'));
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{{ if image }}
|
||||
<figure>
|
||||
<img src="{{ image.src }}" alt="{{ image.alt }}">
|
||||
<figcaption>{{ image.alt }}</figcaption>
|
||||
</figure>
|
||||
{{ /if }}
|
||||
|
||||
{{ if enclosure }}
|
||||
<{{ enclosure.type.split(/\//)[0] }} controls>
|
||||
<source
|
||||
src="{{ enclosure.src }}"
|
||||
type="{{ enclosure.type }}">
|
||||
<object data="{{ enclosure.src }}">
|
||||
<embed src="{{ enclosure.src }}">
|
||||
</object>
|
||||
</{{ enclosure.type.split(/\//)[0] }}>
|
||||
{{ /if }}
|
||||
|
||||
{{ if description }}
|
||||
{{@ description }}
|
||||
{{ /if }}
|
||||
|
|
@ -10,52 +10,18 @@
|
|||
|
||||
### Channel & Topic {#abc-news-channel-topic}
|
||||
|
||||
<Route author="nczitzk" example="/abc" path="/abc/:id?" paramsDesc={['id, can be found in the Channel or Topic page, can also be filled in the `documentId` in the source code of the page, see below, Just In by default']}>
|
||||
<Route author="nczitzk" example="/abc" path="/abc/:category?" paramsDesc={['Category, can be found in the URL, can also be filled in with the `documentId` in the source code of the page, `news/justin` as **Just In** by default']}>
|
||||
|
||||
:::tip
|
||||
|
||||
All Topics in [Topic Library](https://abc.net.au/news/topics) are supported, you can fill in the field after `topic` in its URL, or fill in the `documentId`.
|
||||
|
||||
For example, the URL for [Computers and Technology](https://www.abc.net.au/news/topic/computers-and-technology) is <https://www.abc.net.au/news/topic/computers-and-technology>, the field after `topic` is `computers-and-technology`, and the `documentId` of the Topic is `2302`, so the route is [/abc/computers-and-technology](https://rsshub.app/abc/computers-and-technology) and [/abc/2302](https://rsshub.app/abc/2302).
|
||||
For example, the URL for [Computer Science](https://www.abc.net.au/news/topic/computer-science) is <https://www.abc.net.au/news/topic/computer-science>, the `category` is `news/topic/computer-science`, and the `documentId` of the Topic is `2302`, so the route is [/abc/news/topic/computer-science](https://rsshub.app/abc/news/topic/computer-science) and [/abc/2302](https://rsshub.app/abc/2302).
|
||||
|
||||
The supported channels are all listed in the table below. For other channels, please find the `documentId` in the source code of the channel page and fill it in as above.
|
||||
|
||||
:::
|
||||
|
||||
The following are some of the supported Channel and Topic ids.
|
||||
|
||||
| Just In | Coronavirus | Politics | World |
|
||||
| ------- | ----------- | -------- | ----- |
|
||||
| justin | coronavirus | politics | world |
|
||||
|
||||
| Asia Pacific | Business | Analysis & Opinion | Sport |
|
||||
| ------------ | -------- | -------------------- | ----- |
|
||||
| asia-pacific | business | analysis-and-opinion | sport |
|
||||
|
||||
| AFL | Rugby League | Rugby Union | Football |
|
||||
| --- | ------------ | ----------- | -------- |
|
||||
| afl | rugbyleague | rugbyunion | football |
|
||||
|
||||
| Cricket | Science | Astronomy (Space) | Computers and Technology |
|
||||
| ------- | ------- | ----------------- | ------------------------ |
|
||||
| cricket | science | astronomy-space | computers-and-technology |
|
||||
|
||||
| Environment | Archaeology | Health | Exercise and Fitness |
|
||||
| ----------- | ----------- | ------ | -------------------- |
|
||||
| environment | archaeology | health | exercise-and-fitness |
|
||||
|
||||
| Pharmaceuticals | Mental Health | Diet and Nutrition | Arts & Culture |
|
||||
| --------------- | ------------- | ------------------ | -------------- |
|
||||
| pharmaceuticals | mental-health | diet-and-nutrition | arts-culture |
|
||||
|
||||
| Fact Check | ABC 中文 | 澳洲时政 | 聚焦中港台 |
|
||||
| ---------- | -------- | ------------------ | -------------- |
|
||||
| factcheck | chinese | australia-politics | focus-on-china |
|
||||
|
||||
| 观点与分析 | 澳洲华人 | 解读澳洲 | Berita dalam Bahasa Indonesia | Tok Pisin |
|
||||
| ----------------------- | -------------------- | ----------------- | ----------------------------- | --------- |
|
||||
| analysis-and-opinion-zh | chinese-in-australia | curious-australia | indonesian | tok-pisin |
|
||||
|
||||
</Route>
|
||||
|
||||
## Aljazeera 半岛电视台 {#aljazeera-ban-dao-dian-shi-tai}
|
||||
|
|
|
|||
Loading…
Reference in New Issue