// newsroom/cron/update-feeds.js // Copyright (C) 2022 DTP Technologies, LLC // License: Apache-2.0 'use strict'; const path = require('path'); const mongoose = require('mongoose'); const Feed = mongoose.model('Feed'); const { CronJob } = require('cron'); const { read: feedReader } = require('feed-reader'); const { SiteAsync } = require('../../../../lib/site-lib'); const { SiteWorkerProcess } = require(path.join(__dirname, '..', '..', '..', '..', 'lib', 'site-lib')); class UpdateFeedsCron extends SiteWorkerProcess { static get COMPONENT ( ) { return { name: 'updateFeeds', slug: 'update-feeds-cron', }; } constructor (worker) { super(worker, UpdateFeedsCron.COMPONENT); } async start ( ) { await super.start(); await this.updateFeeds(); this.job = new CronJob( '0 */15 * * * *', this.updateFeeds.bind(this), null, true, process.env.DTP_CRON_TIMEZONE || 'America/New_York', ); } async stop ( ) { if (this.job) { this.log.info('stopping feed update job'); this.job.stop(); delete this.job; } await super.stop(); } async updateFeeds ( ) { try { await Feed .find() .lean() .cursor() .eachAsync(async (feed) => { await this.updateFeed(feed); }, 4); } catch (error) { this.log.error('failed to update feeds', { error }); } } async updateFeed (feed) { const NOW = new Date(); const { feed: feedService } = this.dtp.services; try { this.log.info('loading latest feed data', { feedId: feed._id, title: feed.title }); const response = await feedReader(feed.url); await SiteAsync.each(response.entries, async (entry) => { await Feed.updateOne({ _id: feed._id }, { $set: { published: feed.published || NOW }}); await feedService.createEntry(feed, entry); }, 4); this.log.info('feed updated', { entries: response.entries.length }); } catch (error) { this.log.error('failed to update feed', { feedId: feed._id, title: feed.title, error }); } } } module.exports = UpdateFeedsCron;