Coverage for portality / tasks / read_news.py: 37%
60 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-05 00:09 +0100
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-05 00:09 +0100
1import feedparser
3from portality import models
4from portality.background import BackgroundTask, BackgroundApi
5from portality.core import app
6from portality.tasks.helpers import background_helper
7from portality.tasks.redis_huey import scheduled_short_queue as queue
8from portality.lib import dates
11class FeedError(Exception):
12 pass
15class ReadNewsBackgroundTask(BackgroundTask):
17 __action__ = "read_news"
19 def run(self):
20 """
21 Execute the task as specified by the background_jon
22 :return:
23 """
24 read_feed()
26 def cleanup(self):
27 """
28 Cleanup after a successful OR failed run of the task
29 :return:
30 """
31 pass
33 @classmethod
34 def prepare(cls, username, **kwargs):
35 """
36 Take an arbitrary set of keyword arguments and return an instance of a BackgroundJob,
37 or fail with a suitable exception
39 :param kwargs: arbitrary keyword arguments pertaining to this task type
40 :return: a BackgroundJob instance representing this task
41 """
43 # first prepare a job record
44 return background_helper.create_job(username, cls.__action__,
45 queue_id=huey_helper.queue_id, )
47 @classmethod
48 def submit(cls, background_job):
49 """
50 Submit the specified BackgroundJob to the background queue
52 :param background_job: the BackgroundJob instance
53 :return:
54 """
55 background_job.save()
56 read_news.schedule(args=(background_job.id,), delay=app.config.get('HUEY_ASYNC_DELAY', 10))
57 # fixme: schedule() could raise a huey.exceptions.HueyException and not reach redis- would that be logged?
60# TODO factor this into the object above, rather than sitting out here as a function (it was migrated
61# here from another file)
62def read_feed():
63 """~~NewsReader:Feature->News:ExternalService"""
64 feed_url = app.config.get("BLOG_FEED_URL")
65 if feed_url is None:
66 raise FeedError("No BLOG_FEED_URL defined in settings")
68 f = feedparser.parse(feed_url)
69 if f.bozo > 0:
70 raise FeedError(f.bozo_exception)
72 for e in f.entries:
73 save_entry(e)
75def save_entry(entry):
76 news = None
77 existing = models.News.by_remote_id(entry.id)
78 if len(existing) > 1:
79 raise FeedError("There is more than one object with this id in the index: " + entry.id)
80 elif len(existing) == 1:
81 news = existing[0]
82 else:
83 news = models.News()
85 alts = [l.get("href") for l in entry.links if l.get("rel") == "alternate"]
86 if len(alts) == 0:
87 raise FeedError("Unable to get url of post from link@rel=alternate")
89 news.remote_id = entry.id
90 news.url = alts[0]
91 news.title = entry.title
92 news.updated = dates.format(dates.timestruct2datetime(entry.updated_parsed))
93 news.summary = entry.summary
94 news.published = dates.format(dates.timestruct2datetime(entry.published_parsed))
96 news.save()
99huey_helper = ReadNewsBackgroundTask.create_huey_helper(queue)
102@huey_helper.register_schedule
103def scheduled_read_news():
104 user = app.config.get("SYSTEM_USERNAME")
105 job = ReadNewsBackgroundTask.prepare(user)
106 ReadNewsBackgroundTask.submit(job)
109@huey_helper.register_execute(is_load_config=False)
110def read_news(job_id):
111 job = models.BackgroundJob.pull(job_id)
112 task = ReadNewsBackgroundTask(job)
113 BackgroundApi.execute(task)