import Parser from "rss-parser"; import { ListenerRSSInfos as ListenerInfo } from "./Models/ListenerRSSInfos"; import EventEmitter from "events"; const DEFAULT_TIMELOOP: number = 5 * 60; // default timeloop is 5 min /** * Emit 'update' when he's making a fetch during the start fun * Emit 'update_err' when the fetch has an issue */ export class ListenerRss extends EventEmitter { name: string = ""; address: string = ""; timeloop: number = DEFAULT_TIMELOOP; // time in seconds customfields?: { [key: string]: string[] | string }; // private fields parser: Parser; loopRunning: boolean = false; /** * @brief constructor * @param config ListenerRSSInfos interface who's contain the ListenerInfos */ constructor(config: ListenerInfo) { super(); this.name = config.name; this.address = config.address; this.timeloop = config.timeloop === undefined ? DEFAULT_TIMELOOP : config.timeloop; this.customfields = config.customfields; this.parser = this.generateParser(); } /** * @brief Private function. Is useed to initilize the parser object with the customfields var */ generateParser() { const parserConfig = this.customfields && { customFields: { feed: [], item: Object.entries(this.customfields).map(([, value]) => { return Array.isArray(value) ? value[0] : value; }), }, }; return new Parser(parserConfig); } /** * @brief use the parseURL function from rss-parser with the objects datas * @return return a promise with the received data */ fetchRSS(): Promise> { return this.parser.parseURL(this.address); } /** * @brief call the callback function each looptime * @param callback function who's going to be called with the latest get */ start(): void { this.loopRunning = true; const fun: () => void = () => { this.fetchRSS() .then((obj: { [key: string]: any }) => this.emit("update", obj)) .catch((err) => this.emit("error", err)); }; (async () => { while (this.loopRunning) { await fun(); await new Promise((res) => setTimeout(res, this.timeloop * 1000)); } })(); } /** * @brief stop the async function */ stop(): void { this.loopRunning = false; } }