import { INewsItem, IAggregator } from "./aggregator"; import { getRepository } from "typeorm"; import { AggroNewsItem } from "@shared/db/entity/AggroNewsItem"; import cheerio from "cheerio"; import { logger } from "src/logging"; import got from "got"; const kissDiaryRoot = "https://com3d2.world/r18/notices.php"; const FEED_NAME = "com3d2-world-notices"; function isTag(o: T): o is (T & {attribs: { [attr: string]: string };}) { return typeof(o) === "object" && Object.keys(o).includes("tagName"); } async function aggregate() { const repo = getRepository(AggroNewsItem); let lastPost = await repo.findOne({ select: [ "newsId" ], where: { feedName: FEED_NAME }, order: { newsId: "DESC" } }); if(!lastPost) lastPost = repo.create({ newsId: 0 }); try { const mainPageRes = await got.get(kissDiaryRoot); if(mainPageRes.statusCode != 200) { logger.error("[COM3D2 WORLD BLOG] Failed to load page. Got response code: %s", mainPageRes.statusCode); return []; } const rootNode = cheerio.load(mainPageRes.body); const diaryEntries = rootNode("div.frame a"); if(!diaryEntries) { logger.error("[COM3D2 WORLD BLOG] Failed to find listing!"); return []; } const result : INewsItem[] = []; let latestEntry = lastPost.newsId; for(const a of diaryEntries.toArray()) { if (!isTag(a)) { continue; } const idAttrVal = a.attribs.id; if(!idAttrVal) continue; const id = +idAttrVal; if(id <= lastPost.newsId) continue; if(id > latestEntry) latestEntry = id; const diaryLink = `${kissDiaryRoot}?no=${id}`; const res = await got.get(diaryLink); if(res.statusCode != 200) continue; const node = cheerio.load(res.body); const title = node("div.frame div.notice_title th"); const contents = node("div.frame div").get(1); result.push({ newsId: id, feedId: FEED_NAME, link: diaryLink, title: title.text(), author: "com3d2.world", contents: cheerio.html(contents), embedColor: 0xa39869 }); } return result; } catch(err) { logger.error("Failed to process com3d2.world news: %s", err); return []; } } export default { aggregate: aggregate } as IAggregator;