com3d2_world.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { INewsItem, IAggregator } from "./aggregator";
  2. import { getRepository } from "typeorm";
  3. import { AggroNewsItem } from "@shared/db/entity/AggroNewsItem";
  4. import cheerio from "cheerio";
  5. import { logger } from "src/logging";
  6. import got from "got";
  7. const kissDiaryRoot = "https://com3d2.world/r18/notices.php";
  8. const FEED_NAME = "com3d2-world-notices";
  9. function isTag<T>(o: T): o is (T & {attribs: { [attr: string]: string };}) {
  10. return typeof(o) === "object" && Object.keys(o).includes("tagName");
  11. }
  12. async function aggregate() {
  13. const repo = getRepository(AggroNewsItem);
  14. let lastPost = await repo.findOne({
  15. select: [ "newsId" ],
  16. where: { feedName: FEED_NAME },
  17. order: { newsId: "DESC" }
  18. });
  19. if(!lastPost)
  20. lastPost = repo.create({
  21. newsId: 0
  22. });
  23. try {
  24. const mainPageRes = await got.get(kissDiaryRoot);
  25. if(mainPageRes.statusCode != 200) {
  26. logger.error("[COM3D2 WORLD BLOG] Failed to load page. Got response code: %s", mainPageRes.statusCode);
  27. return [];
  28. }
  29. const rootNode = cheerio.load(mainPageRes.body);
  30. const diaryEntries = rootNode("div.frame a");
  31. if(!diaryEntries) {
  32. logger.error("[COM3D2 WORLD BLOG] Failed to find listing!");
  33. return [];
  34. }
  35. const result : INewsItem[] = [];
  36. let latestEntry = lastPost.newsId;
  37. for(const a of diaryEntries.toArray()) {
  38. if (!isTag(a)) {
  39. continue;
  40. }
  41. const idAttrVal = a.attribs.id;
  42. if(!idAttrVal)
  43. continue;
  44. const id = +idAttrVal;
  45. if(id <= lastPost.newsId)
  46. continue;
  47. if(id > latestEntry)
  48. latestEntry = id;
  49. const diaryLink = `${kissDiaryRoot}?no=${id}`;
  50. const res = await got.get(diaryLink);
  51. if(res.statusCode != 200)
  52. continue;
  53. const node = cheerio.load(res.body);
  54. const title = node("div.frame div.notice_title th");
  55. const contents = node("div.frame div").get(1);
  56. result.push({
  57. newsId: id,
  58. feedId: FEED_NAME,
  59. link: diaryLink,
  60. title: title.text(),
  61. author: "com3d2.world",
  62. contents: cheerio.html(contents),
  63. embedColor: 0xa39869
  64. });
  65. }
  66. return result;
  67. } catch(err) {
  68. logger.error("Failed to process com3d2.world news: %s", err);
  69. return [];
  70. }
  71. }
  72. export default {
  73. aggregate: aggregate
  74. } as IAggregator;