rsshub
Version:
Make RSS Great Again!
94 lines (91 loc) • 5.22 kB
JavaScript
import "./esm-shims-CzJ_djXG.mjs";
import { t as config } from "./config-C37vj7VH.mjs";
import { t as ViewType } from "./types-D84BRIt4.mjs";
import "./dist-BInvbO1W.mjs";
import "./logger-Czu8UMNd.mjs";
import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs";
import { t as cache_default } from "./cache-Bo__VnGm.mjs";
import "./helpers-DxBp0Pty.mjs";
import "./render-BQo6B4tL.mjs";
import { t as got_default } from "./got-KxxWdaxq.mjs";
import { t as parseArticle } from "./utils-VgvwyvBB.mjs";
import crypto from "node:crypto";
import { KJUR, hextob64 } from "jsrsasign";
//#region lib/routes/caixin/utils-fulltext.ts
const rsaPrivateKey = "-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCLci8q2u3NGFyFlMUwjCP91PsvGjHdRAq9fmqZLxvue+n+RhzNxnKKYOv35pLgFKWXsGq2TV+5Xrv6xZgNx36IUkqbmrO+eCa8NFmti04wvMfG3DCNdKA7Lue880daNiK3BOhlQlZPykUXt1NftMNS/z+e70W+Vpv1ZxCx5BipqZkdoceM3uin0vUQmqmHqjxi5qKUuov90dXLaMxypCA0TDsIDnX8RPvPtqKff1p2TMW2a0XYe7CPYhRggaQMpmo0TcFutgrM1Vywyr2TPxYR+H/tpuuWRET7tUIQykBYoO1WKfL2dX6cxarjAJfnYnod3sMzppHouyp8Pt7gHVG7AgMBAAECggEAEFshSy6IrADKgWSUyH/3jMNZfwnchW6Ar/9O847CAPQJ2yhQIpa/Qpnhs58Y5S2myqcHrUBgFPcWp3BbyGn43naAh8XahWHEcVjWl/N6BV9vM1UKYN0oGikDR3dljCBDbCIoPBBO3WcFOaXoIpaqPmbwCG1aSdwQyPUA0UzG08eDbuHK6L5jvbe3xv5kLpWTVddrocW+SakbZRAX1Ykp7IujOce235nM7GOfoq4b8jmK5CLg6VIZGQV20wnn9YxuFOndRSjneFberzfzBMhVLpPsQ16M2xDLpZaDTggZnq2L6nZygds8Hda++ga3WbD3TcgjJNYuENu1S88IowYhSQKBgQDFqRA+38mo6KsxVDCNWcuEk2hSq8NEUzRHJpS7/QjZmEIYpFzDXgSGwhZJ0WNsQtaxJeBbc7B/OOqh8TL1reLl5AdTimS1OLHWVf/MUsLVS7Y82hx/hpYWxZnRSq41oI3P8FO/53FiQMYo2wbwqF6uQjB1y8h58aqL3OYpTH/5xQKBgQC0mobALJ+bU4nCPzkVDZuD6RyNWPwS1aE3+925wDSN2rJ0iLIb4N5czWZmHb66VlAtfGbp2q+amsCV4r6UR19A/y8k9SFB0mdtxix6mjEfaGhVJm4B1mkvsn0OHMAanKkohUvCjROQc3sziyp2gqSEQ98G7//VMPx/3dhgyQpVfwKBgQCycsqu6N0n+D6t/0MCKiJaI7bYhCd7JN8aqVM4UN5PjG2Hz8PLwbK2cr0qkbaAA+vN7NMb3Vtn0FvMLnUCZqVlRTP0EQqQrYmoZuXUcpdhd8QkNgnqe/g+wND4qcKTucquA1uo8mtj9/Su5+bhGDC6hBk6D+uDZFHDiX/loyIavQKBgQCXF6AcLjjpDZ52b8Yloti0JtXIOuXILAlQeNoqiG5vLsOVUrcPM7VUFlLQo5no8kTpiOXgRyAaS9VKkAO4sW0zR0n9tUY5dvkokV6sw0rNZ9/BPQFTcDlXug99OvhMSzwJtlqHTNdNRg+QM6E2vF0+ejmf6DEz/mN/5e0cK5UFqQKBgCR2hVfbRtDz9Cm/P8chPqaWFkH5ulUxBpc704Igc6bVH5DrEoWo6akbeJixV2obAZO3sFyeJqBUqaCvqG17Xei6jn3Hc3WMz9nLrAJEI9BTCfwvuxCOyY0IxqAAYT28xYv42I4+ADT/PpCq2Dj5u43X0dapAjZBZDfVVis7q1Bw-----END PRIVATE KEY-----";
async function getFulltext(url) {
if (!config.caixin.cookie) return;
if (!/(\d+)\.html/.test(url)) return;
const articleID = url.match(/(\d+)\.html/)[1];
const nonce = crypto.randomUUID().replaceAll("-", "").toUpperCase();
const rawString = `id=${articleID}&uid=${config.caixin.cookie.split(";").find((e) => e.includes("SA_USER_UID"))?.split("=")[1]}&${nonce}=nonce`;
const sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(rsaPrivateKey);
sig.updateString(rawString);
const sigValueHex = hextob64(sig.sign());
const res = await ofetch_default(`https://gateway.caixin.com/api/newauth/checkAuthByIdJsonp`, {
query: {
type: 1,
page: url.includes("weekly") ? 0 : 1,
rand: Math.random(),
id: articleID
},
headers: {
"X-Sign": encodeURIComponent(sigValueHex),
"X-Nonce": encodeURIComponent(nonce),
Cookie: config.caixin.cookie
}
});
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("") : "");
}
//#endregion
//#region lib/routes/caixin/latest.ts
const route = {
path: "/latest",
categories: ["traditional-media"],
view: ViewType.Articles,
example: "/caixin/latest",
parameters: {},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false
},
radar: [{ source: ["caixin.com/"] }],
name: "最新文章",
maintainers: ["tpnonthealps"],
handler,
url: "caixin.com/",
description: `说明:此 RSS feed 会自动抓取财新网的最新文章,但不包含 FM 及视频内容。订阅用户可根据文档设置环境变量后,在url传入\`fulltext=\`以解锁全文。`
};
async function handler(ctx) {
const { data } = await got_default("https://gateway.caixin.com/api/dataplatform/scroll/index");
const list = data.data.articleList.map((e) => ({
title: e.title,
link: e.url,
pubDate: e.time,
category: e.channelObject.name
})).filter((item) => !item.link.startsWith("https://fm.caixin.com/") && !item.link.startsWith("https://video.caixin.com/") && !item.link.startsWith("https://datanews.caixin.com/"));
return {
title: "财新网 - 最新文章",
link: "https://www.caixin.com/",
item: await Promise.all(list.map((item) => cache_default.tryGet(`caixin:latest:${item.link}`, async () => {
const desc = await parseArticle(item);
if (ctx.req.query("fulltext") === "true") {
const authorizedFullText = await getFulltext(item.link);
item.description = authorizedFullText === "" ? desc.description : authorizedFullText;
} else item.description = desc.description;
item.guid = `caixin:latest:${item.link}`;
return {
...desc,
...item
};
})))
};
}
//#endregion
export { route };