Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

newsfeedfetcher.js 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* Magic Mirror
  2. * Node Helper: Newsfeed - NewsfeedFetcher
  3. *
  4. * By Michael Teeuw https://michaelteeuw.nl
  5. * MIT Licensed.
  6. */
  7. const Log = require("logger");
  8. const FeedMe = require("feedme");
  9. const NodeHelper = require("node_helper");
  10. const fetch = require("node-fetch");
  11. const iconv = require("iconv-lite");
  12. /**
  13. * Responsible for requesting an update on the set interval and broadcasting the data.
  14. *
  15. * @param {string} url URL of the news feed.
  16. * @param {number} reloadInterval Reload interval in milliseconds.
  17. * @param {string} encoding Encoding of the feed.
  18. * @param {boolean} logFeedWarnings If true log warnings when there is an error parsing a news article.
  19. * @class
  20. */
  21. const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings) {
  22. let reloadTimer = null;
  23. let items = [];
  24. let fetchFailedCallback = function () {};
  25. let itemsReceivedCallback = function () {};
  26. if (reloadInterval < 1000) {
  27. reloadInterval = 1000;
  28. }
  29. /* private methods */
  30. /**
  31. * Request the new items.
  32. */
  33. const fetchNews = () => {
  34. clearTimeout(reloadTimer);
  35. reloadTimer = null;
  36. items = [];
  37. const parser = new FeedMe();
  38. parser.on("item", (item) => {
  39. const title = item.title;
  40. let description = item.description || item.summary || item.content || "";
  41. const pubdate = item.pubdate || item.published || item.updated || item["dc:date"];
  42. const url = item.url || item.link || "";
  43. if (title && pubdate) {
  44. const regex = /(<([^>]+)>)/gi;
  45. description = description.toString().replace(regex, "");
  46. items.push({
  47. title: title,
  48. description: description,
  49. pubdate: pubdate,
  50. url: url
  51. });
  52. } else if (logFeedWarnings) {
  53. Log.warn("Can't parse feed item:");
  54. Log.warn(item);
  55. Log.warn("Title: " + title);
  56. Log.warn("Description: " + description);
  57. Log.warn("Pubdate: " + pubdate);
  58. }
  59. });
  60. parser.on("end", () => {
  61. this.broadcastItems();
  62. scheduleTimer();
  63. });
  64. parser.on("error", (error) => {
  65. fetchFailedCallback(this, error);
  66. scheduleTimer();
  67. });
  68. const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
  69. const headers = {
  70. "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)",
  71. "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
  72. Pragma: "no-cache"
  73. };
  74. fetch(url, { headers: headers })
  75. .then(NodeHelper.checkFetchStatus)
  76. .then((response) => {
  77. response.body.pipe(iconv.decodeStream(encoding)).pipe(parser);
  78. })
  79. .catch((error) => {
  80. fetchFailedCallback(this, error);
  81. scheduleTimer();
  82. });
  83. };
  84. /**
  85. * Schedule the timer for the next update.
  86. */
  87. const scheduleTimer = function () {
  88. clearTimeout(reloadTimer);
  89. reloadTimer = setTimeout(function () {
  90. fetchNews();
  91. }, reloadInterval);
  92. };
  93. /* public methods */
  94. /**
  95. * Update the reload interval, but only if we need to increase the speed.
  96. *
  97. * @param {number} interval Interval for the update in milliseconds.
  98. */
  99. this.setReloadInterval = function (interval) {
  100. if (interval > 1000 && interval < reloadInterval) {
  101. reloadInterval = interval;
  102. }
  103. };
  104. /**
  105. * Initiate fetchNews();
  106. */
  107. this.startFetch = function () {
  108. fetchNews();
  109. };
  110. /**
  111. * Broadcast the existing items.
  112. */
  113. this.broadcastItems = function () {
  114. if (items.length <= 0) {
  115. Log.info("Newsfeed-Fetcher: No items to broadcast yet.");
  116. return;
  117. }
  118. Log.info("Newsfeed-Fetcher: Broadcasting " + items.length + " items.");
  119. itemsReceivedCallback(this);
  120. };
  121. this.onReceive = function (callback) {
  122. itemsReceivedCallback = callback;
  123. };
  124. this.onError = function (callback) {
  125. fetchFailedCallback = callback;
  126. };
  127. this.url = function () {
  128. return url;
  129. };
  130. this.items = function () {
  131. return items;
  132. };
  133. };
  134. module.exports = NewsfeedFetcher;