kiss_diary.ts 2.8 KB

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