-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate.py
143 lines (100 loc) · 3.91 KB
/
generate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import sys
import typing
from datetime import datetime, date, timedelta, timezone, time
from dataclasses import dataclass
import requests
import os
from loguru import logger
from feedgen.feed import FeedGenerator
SECURITY_CHANNELS = ["ubuntu-security", "ubuntu-meeting"]
IRC_CHANNEL_URL_FORMAT = "https://irclogs.ubuntu.com/{}/{}/{}/%23{}.txt"
CACHE_FOLDER = "cache/ubuntu"
XML_FEED_PATH = "feeds/ubuntu.xml"
@dataclass
class UbuSecRSSEntry:
name: str
date: date
content: str
def generate_entries(
since_date: typing.Optional[str],
) -> typing.Generator[UbuSecRSSEntry, None, None]:
yesterday = (datetime.now() - timedelta(1)).date()
if since_date:
day, month, year = since_date.split(".")
start_date = date(int(year), int(month), int(day))
else:
start_date = yesterday
end_date = yesterday
logger.debug(f"Generating entries since {start_date}")
delta = timedelta(days=1)
while start_date <= end_date:
logger.debug(f"Generating an entry for {start_date.strftime('%Y-%m-%d')}")
yield generate_entry_for_date(start_date)
start_date += delta
def generate_entry_for_date(entry_date: date) -> typing.Optional[UbuSecRSSEntry]:
entry_content = ""
channels = []
for channel in SECURITY_CHANNELS:
header = generate_channel_title(channel)
content = get_and_cache_channel_content_for_date(channel, entry_date)
if len(content) > 0:
entry_content += header + "\n\n" + content + "\n"
channels.append(channel)
if len(channels) > 0:
title = generate_rss_entry_title(entry_date, channels)
return UbuSecRSSEntry(title, entry_date, entry_content)
return None
def generate_channel_title(channel_name: str) -> str:
return "# " + channel_name.upper()
def get_and_cache_channel_content_for_date(
channel_name: str, desired_date: date
) -> str:
day = str(desired_date.day).rjust(2, "0")
month = str(desired_date.month).rjust(2, "0")
year = str(desired_date.year).rjust(2, "0")
cache_file = f"{CACHE_FOLDER}/{year}-{month}-{day}-{channel_name}.txt"
if os.path.isfile(cache_file):
logger.debug(f"Using cache file: {cache_file}")
content = open(cache_file, "r").read()
else:
url = IRC_CHANNEL_URL_FORMAT.format(year, month, day, channel_name)
logger.debug(f"Getting content from the URL: {url}")
content = requests.get(url).text
open(cache_file, "w").write(content)
logger.debug(f"Got content for date {desired_date} with length of {len(content)}")
return content
def generate_rss_entry_title(entry_date: date, channels: typing.List[str]) -> str:
return entry_date.strftime("%d.%m.%Y") + ": " + ", ".join(channels)
def generate_and_save_rss_feed(
since_date: typing.Optional[str],
) -> None:
feed = FeedGenerator()
feed.id("ubuntu-security-feeds")
feed.title("Ubuntu Security Feeds")
feed.link(href="https://ubuntu.com", rel="self")
feed.description("Feeds related to security on Ubuntu")
feed.logo("https://assets.ubuntu.com/v1/a7e3c509-Canonical%20Ubuntu.svg")
feed.language("en")
logger.debug("Adding entries in an RSS feed")
for entry in generate_entries(since_date):
if not entry:
continue
rss_entry = feed.add_entry()
rss_entry.id(entry.name)
rss_entry.title(entry.name)
rss_entry.description(entry.content.replace("\n", "<br/>"))
rss_entry.published(
datetime.combine(entry.date, time(0, 0, 0, tzinfo=timezone.utc))
)
logger.debug(f'Added entry with the title: "{entry.name}"')
feed.rss_file(XML_FEED_PATH)
def main() -> None:
since_date = None
if len(sys.argv) == 2:
since_date = sys.argv[1]
elif len(sys.argv) > 2:
exit(1)
logger.debug(f"Set date is: {since_date}")
generate_and_save_rss_feed(since_date)
if __name__ == "__main__":
main()