UNPKG

rsshub

Version:
128 lines (122 loc) 5.93 kB
import { t as rofetch } from "./ofetch-W1aeTHCo.mjs"; import { load } from "cheerio"; //#region lib/routes/touhougarakuta/json2html.ts const href = (text, url, language) => `<a href="${url.replace(/\/\/edit/, () => `//${language === "ja" ? "" : language}`)}">${text}</a>`; const authors = (data) => data?.map((author) => `<p>${author.role}${author.name}</p>`).join(""); const freeEntry = (data) => data ? data.map((fe) => `<br/><h2>${fe.subject}</h2><p>${fe.contents}</p>`).join("") : ""; const ogpImage = (article) => `<img src="${article.ogpSettings.ogp.image.sourceUrl}" alt="${article.ogpSettings.ogp.image.altText}">`; const linkToIndex = (article, language) => { if (Object.hasOwn(article, "linkToIndex") && article.linkToIndex.linktoindex !== null) { const index = article.linkToIndex.linktoindex; return `<p>Index:${href(index.title, index.url, language)}</p>`; } return ""; }; const index = (article, language) => article.index.item.map((item) => `<hr/><p><b>${item.num}</b></p>` + (item.link ? href(item.title, item.link.url, language) : `<p>${item.title}</p>`) + `<p style="text-align: right;">${item.date}</p>`).join(""); const indexInterview = (article, language) => Object.hasOwn(article, "index") ? ogpImage(article) + article.ogpSettings.ogp.description + index(article, language) : ogpImage(article); const indexComic = (article, language) => ogpImage(article) + article.index.about + authors(article.index.authors) + `<img src="${article.indexCover.cover.sourceUrl}">` + index(article, language); const indexNovel = indexComic; const removeSrcset = (html) => { const $ = load(html, null, false); $("img").removeAttr("srcset"); return $.html(); }; const interview = (article, language) => { if (Object.hasOwn(article, "interviewContents")) { const leading = article.interviewContents.leading; return ogpImage(article) + linkToIndex(article, language) + "<hr/>" + (leading ? removeSrcset(leading) : "") + article.interviewContents.block.map((block) => `<h2 style="text-align: center;">${block.head}</h2>` + removeSrcset(block.content)).join(""); } return ogpImage(article) + linkToIndex(article, language); }; const novel = (article, language) => ogpImage(article) + linkToIndex(article, language) + `<hr/><img src="${article.novelContent.cover.sourceUrl}">` + authors(article.novelContent.authors) + freeEntry(article.novelContent.freeentry) + removeSrcset(article.novelContent.contents); const comic = (article, language) => { const viewerurl = article.comicContents.viewerurl; const niconicourl = article.comicContents.niconicourl; return ogpImage(article) + linkToIndex(article, language) + `<hr/><img src="${article.comicContents.cover.sourceUrl}">` + authors(article.comicContents.authors) + (viewerurl ? `<p>Viewer: <a href="${viewerurl}">${viewerurl}</a></p>` : "") + (niconicourl ? `<p>niconico: <a href="${niconicourl}">${niconicourl}</a></p>` : "") + freeEntry(article.comicContents.freeentry) + article.comicContents.pages.map((page) => `<img src="${page.page.sourceUrl}">`).join(""); }; const uncategorized = (article, language) => ogpImage(article) + linkToIndex(article, language) + "<hr/>" + removeSrcset(article.contents.texts); //#endregion //#region lib/routes/touhougarakuta/index.ts const route = { path: "/:language/:type", categories: ["anime"], example: "/touhougarakuta/ja/news", parameters: { language: "language", type: "article type" }, name: "Articles", maintainers: ["ttyfly"], description: `Languages: | Chinese | English | Japanese | Korean | | ------- | ------- | -------- | ------ | | cn | en | ja | ko | Article types: | Index | Series | Interviews | Novels | Comics | News | | ----- | ------ | ---------- | ------ | ------ | ---- | | index | series | interviews | novels | comics | news | | Music review | Game review | Book review | Where are you | | ------------- | ------------ | ------------ | --------------- | | music\\_review | game\\_review | book\\_review | where\\_are\\_you | **Note:** The index type includes all types of articles. Think twice before using it.`, handler }; const languageCodes = { cn: "zh-cn", en: "en", ko: "ko", ja: "ja" }; async function handler(ctx) { const { language, type } = ctx.req.param(); if (!Object.keys(languageCodes).includes(language)) throw new Error("Invalid language"); const baseUrl = language === "ja" ? "https://touhougarakuta.com" : `https://${language}.touhougarakuta.com`; const response = await rofetch(`${baseUrl}/page-data/${type === "interviews" ? "tags/interviews" : type}/page-data.json`); return { title: `東方我楽多叢誌 - ${type}`, link: `${baseUrl}/${type === "index" ? "" : type}`, description: `東方我楽多叢誌 〜strange article of the outer world〜 - ${type}`, language: languageCodes[language], allowEmpty: true, item: response.result.pageContext.articles.map((article, i) => { let description; try { switch (article.type) { case "index_interview": case "column": description = indexInterview(article, language); break; case "index_comic": description = indexComic(article, language); break; case "index_novel": description = indexNovel(article, language); break; case "interview": case "report": description = interview(article, language); break; case "novel": description = novel(article, language); break; case "comic": description = comic(article, language); break; default: description = uncategorized(article, language); } } catch (error) { error.message += `(at article ${i}: ${article.title})`; throw error; } return { title: article.title, pubDate: article.date, link: `${baseUrl}/${article.type}/${article.slug}`, description, category: article.tags.nodes.map((tag) => tag.name) }; }) }; } //#endregion export { route };