|
18 | 18 | import re |
19 | 19 | import shelve |
20 | 20 | import time |
| 21 | +from datetime import datetime |
| 22 | +from functools import total_ordering |
21 | 23 | from hashlib import md5 |
22 | 24 | from html.parser import HTMLParser |
23 | 25 | from typing import cast |
@@ -95,7 +97,7 @@ def template_info(item, date_format): |
95 | 97 | else: |
96 | 98 | info[key] = item[key] |
97 | 99 | if "title" in item.keys(): |
98 | | - info["title_plain"] = stripHtml(info["title"]).result |
| 100 | + info["title_plain"] = Markup(info["title"]) |
99 | 101 |
|
100 | 102 | return info |
101 | 103 |
|
@@ -243,6 +245,7 @@ def run(self, planet_name, planet_link, template_files, offline=False): |
243 | 245 |
|
244 | 246 | # The other configuration blocks are channels to subscribe to |
245 | 247 | for feed_url in self.config.sections(): |
| 248 | + # The "Planet" config section is a special case. We also allow template-file specific configuration, apparently :D |
246 | 249 | if feed_url == "Planet" or feed_url in template_files: |
247 | 250 | continue |
248 | 251 |
|
@@ -457,7 +460,7 @@ def items( |
457 | 460 |
|
458 | 461 | if item.id not in seen_guids: |
459 | 462 | seen_guids[item.id] = 1 |
460 | | - items.append((time.mktime(item.date), item.order, item)) |
| 463 | + items.append((item.time_since_epoch, item.order, item)) |
461 | 464 |
|
462 | 465 | # Sort the list |
463 | 466 | if sorted: |
@@ -597,7 +600,7 @@ def items(self, hidden=False, sorted=False): |
597 | 600 | for item in self._items.values(): |
598 | 601 | if hidden or "hidden" not in item: |
599 | 602 | try: |
600 | | - items.append((time.mktime(item.date), item.order, item)) |
| 603 | + items.append((item.time_since_epoch, item.order, item)) |
601 | 604 | except OverflowError: |
602 | 605 | log.warning(f"Unable to parse date for {item.id}") |
603 | 606 |
|
@@ -855,12 +858,13 @@ def update_entries(self, entries): |
855 | 858 | def get_name(self, key): |
856 | 859 | """Return the key containing the name.""" |
857 | 860 | for key in ("name", "title"): |
858 | | - if key in self and self.key_type(key) != self.NULL: |
| 861 | + if self.has_key(key) and self.key_type(key) != self.NULL: |
859 | 862 | return self.get_as_string(key) |
860 | 863 |
|
861 | 864 | return "" |
862 | 865 |
|
863 | 866 |
|
| 867 | +@total_ordering |
864 | 868 | class NewsItem(cache.CachedInfo): |
865 | 869 | """An item of news. |
866 | 870 |
|
@@ -997,6 +1001,18 @@ def update(self, entry): |
997 | 1001 | # Generate the date field if we need to |
998 | 1002 | self.get_date("date") |
999 | 1003 |
|
| 1004 | + def __eq__(self, other): |
| 1005 | + return self.id == other.id |
| 1006 | + |
| 1007 | + def __lt__(self, other): |
| 1008 | + # compare on the date field, and then the order field |
| 1009 | + if self.date < other.date: |
| 1010 | + return True |
| 1011 | + elif self.date == other.date: |
| 1012 | + return self.order < other.order |
| 1013 | + else: |
| 1014 | + return False |
| 1015 | + |
1000 | 1016 | def get_date(self, key): |
1001 | 1017 | """Get (or update) the date key. |
1002 | 1018 |
|
@@ -1030,6 +1046,13 @@ def get_date(self, key): |
1030 | 1046 | self.set_as_date(key, date) |
1031 | 1047 | return date |
1032 | 1048 |
|
| 1049 | + @property |
| 1050 | + def time_since_epoch(self) -> float: |
| 1051 | + try: |
| 1052 | + return time.mktime(self.date) |
| 1053 | + except OverflowError: |
| 1054 | + return 0.0 |
| 1055 | + |
1033 | 1056 | def get_content(self, key): |
1034 | 1057 | """Return the key containing the content.""" |
1035 | 1058 | for key in ("content", "tagline", "summary"): |
|
0 commit comments