Coverage for src/models/feed.py: 36%
39 statements
« prev ^ index » next coverage.py v7.3.0, created at 2024-12-21 12:23 +0000
« prev ^ index » next coverage.py v7.3.0, created at 2024-12-21 12:23 +0000
1import collections
3from src.template import render_template
4from src import xml
7Item = collections.namedtuple('Item', [
8 'title',
9 'timestamp',
10 'path',
11 'image',
12])
15class Feed:
16 """
17 Website RSS feed.
19 An atom feed that you can build from site information and write
20 locally as a valid atom RSS feed.
21 """
23 filename = 'feed.xml'
25 def __init__(self, site=None, items: list[Item] = []): # noqa: E501
26 """
27 Build a feed object.
29 Takes a list of `Item` objects, which is just this named
30 tuple:
32 ```python
33 Item = collections.namedtuple('Item', [
34 'title',
35 'timestamp',
36 'path', # ex. 2020-01-01.html
37 'image', # ex. 2021-01-01.jpg
38 ])
39 ```
40 """
41 self.site = site
42 self.items = items
44 def render(self):
45 content = render_template('feed.xml.j2', context={
46 'filename': self.filename,
47 'site': self.site,
48 'items': self.items,
49 })
50 return xml.prettify(content)
52 def write(self):
53 with open(f'./www/{self.filename}', 'w') as f:
54 f.write(self.render())
56 def __repr__(self):
57 return f'<Feed {self.filename}>'
60def load_feed(site, entries=[], images=[]) -> Feed: # noqa: E501
61 """
62 Load an RSS feed object.
64 ```python
65 feed = load_feed(site)
66 ```
67 """
68 items = []
70 def convert_timestamp(date):
71 slug = date.strftime("%Y-%m-%d")
72 return f'{slug}T00:00:00+00:00'
74 # add all journal entries
75 for entry in entries:
76 kwargs = {}
77 kwargs['title'] = entry.title
78 kwargs['path'] = entry.filename
80 if entry.banner:
81 kwargs['image'] = f'images/{entry.banner}'
82 else:
83 kwargs['image'] = None
85 kwargs['timestamp'] = convert_timestamp(entry.date)
86 items.append(Item(**kwargs))
88 # add all other images that aren't a banner
89 banners = [e.banner for e in entries if e.banner]
90 for image in images:
91 if image.filename in banners:
92 continue
94 kwargs = {
95 'title': image.title,
96 'path': f'images/{image.filename}',
97 'image': f'images/{image.filename}',
98 'timestamp': convert_timestamp(image.date),
99 }
100 items.append(Item(**kwargs))
102 # sort by descending timestamp
103 items = sorted(items, key=lambda i: i.timestamp, reverse=True)
105 return Feed(site=site, items=items)