kiss_diary.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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 urlPattern = /diary\.php\?no=(\d+)/i;
  8. const kissDiaryRoot = "http://www.kisskiss.tv/kiss";
  9. const FEED_NAME = "kisskisstv-diary";
  10. async function aggregate() {
  11. const repo = getRepository(AggroNewsItem);
  12. let lastPost = await repo.findOne({
  13. select: [ "newsId" ],
  14. where: { feedName: FEED_NAME },
  15. order: { newsId: "DESC" }
  16. });
  17. if(!lastPost)
  18. lastPost = repo.create({
  19. newsId: 0
  20. });
  21. try {
  22. const mainPageRes = await got.get(`${kissDiaryRoot}/diary.php`);
  23. if(mainPageRes.statusCode != 200) {
  24. logger.error("[KISS DIARY] Failed to load page. Got response code: %s", mainPageRes.statusCode);
  25. return [];
  26. }
  27. const rootNode = cheerio.load(mainPageRes.body);
  28. const diaryEntryNames = rootNode("table.blog_frame_top");
  29. if(diaryEntryNames.length == 0) {
  30. logger.error("[KISS DIARY] Failed to find listing!");
  31. return [];
  32. }
  33. const diaryTexts = rootNode("div.blog_frame_middle");
  34. const items = diaryEntryNames.toArray().map((e, i) => ({ table: e, content: diaryTexts[i]}));
  35. const result : INewsItem[] = [];
  36. let latestEntry = lastPost.newsId;
  37. for(const {table, content} of items) {
  38. const a = cheerio(table).find("a");
  39. const link = a.attr("href");
  40. const matches = link ? urlPattern.exec(link) : false;
  41. if(!matches)
  42. continue;
  43. const id = +matches[1];
  44. if(id <= lastPost.newsId)
  45. continue;
  46. if(id > latestEntry)
  47. latestEntry = id;
  48. const diaryLink = `${kissDiaryRoot}/${link}`;
  49. const contentCh = cheerio(content);
  50. const title = a.text();
  51. const bottomFrame = contentCh.find("div.blog_data");
  52. bottomFrame.remove();
  53. result.push({
  54. newsId: id,
  55. feedId: FEED_NAME,
  56. link: diaryLink,
  57. title: title,
  58. author: "KISS BLOG",
  59. contents: contentCh.html() ?? "",
  60. embedColor: 0xf4c100,
  61. needsTranslation: true
  62. });
  63. }
  64. return result;
  65. } catch(err) {
  66. logger.error("Failed to parse KISS Diary news: %s", err);
  67. return [];
  68. }
  69. }
  70. export default {
  71. aggregate: aggregate
  72. } as IAggregator;