rsshub
Version:
Make RSS Great Again!
113 lines (111 loc) • 4.66 kB
JavaScript
import "./esm-shims-CzJ_djXG.mjs";
import { t as config } from "./config-C37vj7VH.mjs";
import "./dist-BInvbO1W.mjs";
import "./logger-Czu8UMNd.mjs";
import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs";
import { t as parseDate } from "./parse-date-BrP7mxXf.mjs";
import { t as cache_default } from "./cache-Bo__VnGm.mjs";
import { t as invalid_parameter_default } from "./invalid-parameter-rr4AgGpp.mjs";
import { t as config_not_found_default } from "./config-not-found-Dyp3RlZZ.mjs";
import { load } from "cheerio";
import iconv from "iconv-lite";
//#region lib/routes/discuz/discuz.ts
function fixUrl(itemLink, baseUrl) {
if (itemLink) {
if (baseUrl && !/^https?:\/\//.test(baseUrl)) baseUrl = /^\/\//.test(baseUrl) ? "http:" + baseUrl : "http://" + baseUrl;
itemLink = new URL(itemLink, baseUrl).href;
}
return itemLink;
}
async function loadContent(itemLink, charset, header) {
const response = await ofetch_default.raw(itemLink, {
method: "get",
responseType: "arrayBuffer",
headers: header
});
const responseData = iconv.decode(Buffer.from(response._data), charset ?? "utf-8");
if (!responseData) return { description: "获取详细内容失败" };
const $ = load(responseData);
const post = $("div#postlist div[id^=post] td[id^=postmessage]").first();
post.find("img").each((_, img) => {
img = $(img);
if (img.attr("src")?.endsWith("none.gif") && img.attr("file")) {
img.attr("src", img.attr("file") || img.attr("zoomfile"));
img.removeAttr("file");
img.removeAttr("zoomfile");
}
});
return { description: post.html() };
}
const route = {
path: [
"/:ver{[7x]}/:cid{[0-9]{2}}/:link{.+}",
"/:ver{[7x]}/:link{.+}",
"/:link{.+}"
],
name: "Unknown",
maintainers: [],
handler
};
async function handler(ctx) {
let link = ctx.req.param("link");
const ver = ctx.req.param("ver") ? ctx.req.param("ver").toUpperCase() : void 0;
const cid = ctx.req.param("cid");
link = link.replace(/:\/\//, ":/").replace(/:\//, "://");
const cookie = cid === void 0 ? "" : config.discuz.cookies[cid];
if (cookie === void 0) throw new config_not_found_default("缺少对应论坛的cookie.");
const header = { Cookie: cookie };
const response = await ofetch_default.raw(link, {
method: "get",
responseType: "arrayBuffer",
headers: header
});
const responseData = Buffer.from(response._data);
const contentType = response.headers["content-type"] || "";
let $ = load(iconv.decode(responseData, "utf-8"));
const charset = contentType.match(/charset=([^;]*)/)?.[1] ?? $("meta[charset]").attr("charset") ?? $("meta[http-equiv=\"Content-Type\"]").attr("content")?.split("charset=")?.[1];
if (charset?.toLowerCase() !== "utf-8") $ = load(iconv.decode(responseData, charset ?? "utf-8"));
const version = ver ? `DISCUZ! ${ver}` : $("head > meta[name=generator]").attr("content");
let items;
if (version.toUpperCase().startsWith("DISCUZ! 7")) {
const list = $("tbody[id^=\"normalthread\"] > tr").slice(0, ctx.req.query("limit") ? Number.parseInt(ctx.req.query("limit"), 10) : 5).toArray().map((item) => {
item = $(item);
const a = item.find("span[id^=thread] a");
return {
title: a.text().trim(),
link: fixUrl(a.attr("href"), link),
pubDate: item.find("td.author em").length ? parseDate(item.find("td.author em").text().trim()) : void 0,
author: item.find("td.author cite a").text().trim()
};
});
items = await Promise.all(list.map((item) => cache_default.tryGet(item.link, async () => {
const { description } = await loadContent(item.link, charset, header);
item.description = description;
return item;
})));
} else if (version.toUpperCase().startsWith("DISCUZ! X")) {
const list = $("tbody[id^=\"normalthread\"] > tr").slice(0, ctx.req.query("limit") ? Number.parseInt(ctx.req.query("limit"), 10) : 5).toArray().map((item) => {
item = $(item);
const a = item.find("a.xst");
return {
title: a.text(),
link: fixUrl(a.attr("href"), link),
pubDate: item.find("td.by:nth-child(3) em span").last().length ? parseDate(item.find("td.by:nth-child(3) em span").last().text().trim()) : void 0,
author: item.find("td.by:nth-child(3) cite a").text().trim()
};
});
items = await Promise.all(list.map((item) => cache_default.tryGet(item.link, async () => {
const { description } = await loadContent(item.link, charset, header);
item.description = description;
return item;
})));
} else throw new invalid_parameter_default("不支持当前Discuz版本.");
return {
title: $("head > title").text(),
description: $("head > meta[name=description]").attr("content"),
link,
item: items
};
}
//#endregion
export { route };