This repository has been archived by the owner on Jun 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
157 lines (126 loc) · 4.9 KB
/
utils.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
""" Provides general utilities for the covid_dashboard including settings,
timing functions and storing the users blacklist.
Attributes:
log (Logger): The logger for the covid_dashboard.
"""
import json
import logging
from datetime import datetime, timedelta
from io import StringIO
from html.parser import HTMLParser
from typing import Any
DEFAULT_CONFIG = {
"favicon": "/static/images/fish.gif",
"image": "fish.gif",
"title": "COVID Dashboard",
"location": "Exeter",
"nation": "England",
"api_key": "INSERT-API-KEY-HERE",
}
log = logging.getLogger("covid_dashboard")
def get_settings(*keys) -> tuple:
"""Get multiple settings from the users config.json
Args:
keys: The settings keys to be read from the users config.json.
Returns:
tuple: The values for each given settings from the users config.json
"""
try:
with open("config.json", encoding="utf-8") as file:
log.info("Loading config.json")
config = json.load(file)
except FileNotFoundError:
log.warning(
"No config.json found, creating a new config.json with default values"
)
config = DEFAULT_CONFIG
with open("config.json", "w", encoding="utf-8") as file:
json.dump(config, file, ensure_ascii=False, indent=4)
result = []
if (config["api_key"] == "INSERT-API-KEY-HERE") or (config["api_key"] is None):
log.warning(
"No NewsAPI.org API key found in config, get one from"
" https://newsapi.org/register"
)
for key in keys:
result.append(config[key])
return tuple(result)
def get_setting(key: str) -> Any:
"""Get a single setting from the users config.json
Args:
key (str): The setting key to be read from the users config.json
Returns:
Any: The value for the given setting in the users config.json
"""
result = get_settings(key)
return result[0]
def time_until(target_time: timedelta) -> timedelta:
"""Returns the time until a given time occurs.
Used to calculate how long until a scheduled event will run. For example,
if an event is scheduled to run at 14:15, the function will return the time time
until the clock next strikes 14:15.
Args:
target_time (timedelta): Target time to calculate the difference between.
Returns:
timedelta: Resulting time difference.
"""
now = datetime.now()
current_time = timedelta(hours=now.hour, minutes=now.minute, seconds=now.second)
# If target time is in the future
if current_time < target_time:
time_delta = target_time - current_time
# If target time is in the past, or now
else:
time_delta = timedelta(hours=24) + target_time - current_time
return time_delta
def get_news_blacklist() -> list:
"""Get the users news blacklist from news-blacklist.json.
Returns:
list: List of blacklisted news article titles
"""
try:
with open("news-blacklist.json", encoding="utf-8") as file:
log.info("Getting news blacklist from news-blacklist.json")
user_blacklist = json.load(file)
except FileNotFoundError:
log.warning("No news-blacklist.json found, creating a new one")
user_blacklist = {"blacklist": []}
with open("news-blacklist.json", "w", encoding="utf-8") as file:
json.dump(user_blacklist, file)
return user_blacklist["blacklist"]
def blacklist(title: str) -> None:
"""Blacklist a new news article, and add it to the users news-blacklist.json.
Args:
title (str): The title of the news article that should be blacklisted.
"""
stored_blacklist = list(get_news_blacklist())
stored_blacklist.append(title)
log.info("Blacklisting %s", title)
with open("news-blacklist.json", "w", encoding="utf-8") as file:
json.dump({"blacklist": stored_blacklist}, file)
# from https://stackoverflow.com/questions/753052/strip-html-from-strings-in-python
class HTMLStripper(HTMLParser):
"""A HTML code stripper to remove any HTML elements from the description of news articles."""
# pylint: disable=W0223
def __init__(self) -> None:
super().__init__()
self.reset()
self.convert_charrefs = True
self.strict = False
self.text = StringIO()
def handle_data(self, data: str) -> None:
"""This is called when handling arbitrary HTML data."""
self.text.write(data)
def get_data(self) -> str:
"""This is called when getting sanitised HTML data"""
return self.text.getvalue()
def sanitise_input(html: str) -> str:
"""Sanitises any string and removes any potentially malicious HTML tags.
Args:
html (str): A string which may contain HTML.
Returns:
str: A sanitised version of the input string, with all HTML removed.
"""
sanitiser = HTMLStripper()
sanitiser.feed(html)
return sanitiser.get_data()