import Parser from "rss-parser/index"; 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 | undefined = undefined; loopRunning: boolean = false; /** * @brief constructor * @param config ListenerRSSInfos interface who's contain the ListenerInfos */ constructor(config: ListenerInfo) { super(); this.setData(config); this.setParser(); } /** * @brief Private function. Is useed to initilize the parser object with the customfields var */ setParser() { // set parser this.parser = new Parser( this.customfields !== undefined ? { customFields: { feed: [], item: Object.entries(this.customfields).map(([, value]) => { return Array.isArray(value) ? value[0] : value; }), }, } : {} ); // if customfield is set -> let's set the parser with, else let the option empty } /** * @brief Private function. Initialized the listener with an ListenerRSSInfos interface * @param infos ListenerRSSInfos interface who's contain the ListenerInfos */ setData(infos: ListenerInfo) { // Set data this.name = infos.name; this.address = infos.address; this.timeloop = infos.timeloop === undefined ? DEFAULT_TIMELOOP : infos.timeloop; this.customfields = infos.customfields; } /** * @brief use the parseURL function from rss-parser with the objects datas * @return return a promise with the received data */ fetchRSS(): Promise> { if (this.parser !== undefined && this.address !== undefined) { return this.parser.parseURL(this.address).catch((err) => { throw new Error("bad address or no access : " + err); }); } else throw new Error("listener must be first initialized"); } /** * @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("update_err", 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; } }