UNPKG

rsshub

Version:
257 lines (253 loc) 8.16 kB
import "./esm-shims-CzJ_djXG.mjs"; import "./config-C37vj7VH.mjs"; import "./dist-BInvbO1W.mjs"; import "./logger-Czu8UMNd.mjs"; import "./ofetch-BIyrKU3Y.mjs"; import { t as parseDate } from "./parse-date-BrP7mxXf.mjs"; import "./helpers-DxBp0Pty.mjs"; import { t as got_default } from "./got-KxxWdaxq.mjs"; import bbobHTML from "@bbob/html"; import presetHTML5 from "@bbob/preset-html5"; import { getUniqAttr } from "@bbob/plugin-helper"; //#region lib/routes/steam/news.ts const route = { path: "/news/:appid/:language?", name: "News", url: "steamcommunity.com", maintainers: ["keocheung"], handler, example: "/news/958260/english", parameters: { appid: "Game App ID, all digits, can be found in the URL", language: "Language, english by default, see below for more languages" }, description: ` <details> <summary>More languages</summary> | 语言代码 | 语言名称 | | ------------------------------------------------- | ---------- | | English | english | | Español - España (Spanish - Spain) | spanish | | Français (French) | french | | Italiano (Italian) | italian | | Deutsch (German) | german | | Ελληνικά (Greek) | greek | | 한국어 (Korean) | koreana | | 简体中文 (Simplified Chinese) | schinese | | 繁體中文 (Traditional Chinese) | tchinese | | Русский (Russian) | russian | | ไทย (Thai) | thai | | 日本語 (Japanese) | japanese | | Português (Portuguese) | portuguese | | Português - Brasil (Portuguese - Brazil) | brazilian | | Polski (Polish) | polish | | Dansk (Danish) | danish | | Nederlands (Dutch) | dutch | | Suomi (Finnish) | finnish | | Norsk (Norwegian) | norwegian | | Svenska (Swedish) | swedish | | Čeština (Czech) | czech | | Magyar (Hungarian) | hungarian | | Română (Romanian) | romanian | | Български (Bulgarian) | bulgarian | | Türkçe (Turkish) | turkish | | Українська (Ukrainian) | ukrainian | | Tiếng Việt (Vietnamese) | vietnamese | | Español - Latinoamérica (Spanish - Latin America) | latam | </details> `, categories: ["game"], features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportRadar: true, supportBT: false, supportPodcast: false, supportScihub: false }, radar: [{ title: "News", source: [ "steamcommunity.com/app/:appid", "steamcommunity.com/app/:appid/allnews", "steamcommunity.com/app/:appid/announcements", "steamcommunity.com/app/:appid/news" ], target: "/news/:appid" }] }; const langMap = { english: "en", german: "de", french: "fr", italian: "it", korean: "ko", spanish: "es", schinese: "zh-Hans", tchinese: "zh-Hant", japanese: "ja", portuguese: "pt-PT", brazilian: "pt-BR", russian: "ru", polish: "pl", danish: "da", dutch: "nl", finnish: "fi", norwegian: "no", swedish: "sv", czech: "cs", hungarian: "hu", turkish: "tr", thai: "th", ukrainian: "uk", vietnamese: "vi", romanian: "ro", greek: "el", arabic: "ar", latam: "es-419", bulgarian: "bg" }; async function handler(ctx) { const { appid = "958260", language = "english" } = ctx.req.param(); const limitQuery = ctx.req.query("limit"); const limit = limitQuery ? Number.parseInt(limitQuery, 10) : 100; const rootUrl = "https://steamcommunity.com"; const apiRootUrl = "https://store.steampowered.com"; const clanRootUrl = "https://clan.fastly.steamstatic.com"; const sharedRootUrl = "https://shared.fastly.steamstatic.com"; const apiUrl = new URL("events/ajaxgetpartnereventspageable/", apiRootUrl).href; const { data: response } = await got_default(apiUrl, { searchParams: { clan_accountid: 0, appid, offset: 0, count: limit, l: language } }); const items = response.events.slice(0, limit).map((item) => { const title = item.event_name; const description = `<div lang="${langMap[language] || ""}">${bbobHTML(item.announcement_body.body.replaceAll("{STEAM_CLAN_IMAGE}", `${clanRootUrl}/images`).replaceAll("[olist]", "[list=1]").replaceAll("[/olist]", "[/list]").replaceAll(/(\[\/h\d\])\n/g, "$1").replaceAll(/(\[list(?:=.*?)?\])\n/g, "$1"), [ customPreset(), linebreakRenderer, plainUrlRenderer ])}</div>`; const jsondata = JSON.parse(item.jsondata); const titleImage = jsondata.localized_title_image?.[0]; const capsuleImage = jsondata.localized_capsule_image?.[0]; return { title, description, pubDate: parseDate(item.announcement_body.posttime, "X"), link: new URL(`games/${appid}/announcements/detail/${item.announcement_body.gid}`, rootUrl).href, category: item.announcement_body.tags, content: { html: description, text: item.announcement_body.body }, updated: parseDate(item.announcement_body.updatetime, "X"), image: capsuleImage ? new URL(`images/${item.announcement_body.clanid}/${capsuleImage}`, clanRootUrl).href : void 0, banner: titleImage ? new URL(`images/${item.announcement_body.clanid}/${titleImage}`, clanRootUrl).href : void 0 }; }); return { title: `App ${appid} News`, link: new URL(`app/${appid}/allnews/`, rootUrl).href, image: new URL(`store_item_assets/steam/apps/${appid}/hero_capsule.jpg`, sharedRootUrl).href, item: items, language: langMap[language] || null }; } const linebreakRenderer = (tree) => tree.walk((node) => { if (typeof node === "string" && node === "\n") return { tag: "br", content: null }; return node; }); const plainUrlRenderer = (tree) => tree.walk((node) => { if (typeof node === "string" && /https?:\/\/[^\s]+/.test(node)) { let lastIndex = 0; let match; const content = []; const urlRe = /https?:\/\/[^\s]+/g; while ((match = urlRe.exec(node)) !== null) { if (match.index > lastIndex) content.push(node.slice(lastIndex, match.index)); content.push({ tag: "a", attrs: { href: match[0], rel: "noopener", target: "_blank" }, content: match[0] }); lastIndex = match.index + match[0].length; } if (lastIndex < node.length) content.push(node.slice(lastIndex)); if (content.length === 0) return node; if (content.length === 1) return content[0]; return { tag: "span", content }; } return node; }); const customPreset = presetHTML5.extend((tags) => ({ ...tags, b: (node) => ({ tag: "b", content: node.content }), i: (node) => ({ tag: "i", content: node.content }), u: (node) => ({ tag: "u", content: node.content }), s: (node) => ({ tag: "s", content: node.content }), url: (node) => ({ tag: "a", attrs: { href: Object.keys(node.attrs)[0], rel: "noopener", target: "_blank" }, content: node.content }), previewyoutube: (node) => ({ tag: "iframe", attrs: { src: `https://www.youtube-nocookie.com/embed/${getUniqAttr(node.attrs).match(/[A-Za-z0-9_-]+/)?.[0]}`, title: "YouTube video player", frameborder: "0", allowFullScreen: "1", refererpolicy: "strict-origin-when-cross-origin" } }), video: (node, { render }) => ({ tag: "video", attrs: { controls: "", preload: "metadata", poster: node.attrs?.poster }, content: render(Object.entries({ webm: "video/webm", mp4: "video/mp4" }).map(([key, type]) => ({ tag: "source", attrs: { src: node.attrs?.[key], type } }))) }) })); //#endregion export { route };