/
notifier.py
145 lines (113 loc) · 4.42 KB
/
notifier.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
# Import necessary packages
from enum import Enum
import sys
import requests
class OrderedEnum(Enum):
"""Based on https://docs.python.org/3/library/enum.html"""
def __ge__(self, other):
if self.__class__ is other.__class__:
return self.value >= other.value
return NotImplemented
def __gt__(self, other):
if self.__class__ is other.__class__:
return self.value > other.value
return NotImplemented
def __le__(self, other):
if self.__class__ is other.__class__:
return self.value <= other.value
return NotImplemented
def __lt__(self, other):
if self.__class__ is other.__class__:
return self.value < other.value
return NotImplemented
class Verbosity(OrderedEnum):
"""Enum for verbosity of Notifier."""
silent = -2
quiet = -1
normal = 0
verbose = 1
class OutputMethod(Enum):
"""Enum for output methods for Notifier."""
console = 1
telegram = 2
class OutputMethodError(ValueError):
"""Exception raised if specified output method is not recognised."""
def __init__(self, output_method):
self.output_method = output_method
@property
def message(self) -> str:
"""Generate a basic error message, with the bad output type."""
return "The specified output method (%(output_method)s) is not supported." \
% {"output_method": self.output_method}
class Notifier:
"""
Notifier
Handles notifying the user of messages and errors.
"""
TELEGRAM_URL = "https://api.telegram.org/bot%(bot_token)s/" \
"sendMessage?chat_id=%(user_id)s&text=%(message)s" \
"&parse_mode=Markdown"
def __init__(self, config=None, verbosity=Verbosity):
"""
Initialise the Notifier.
If no configuration is specified, the Notifier defaults to the console
as its output method.
An OutputMethodError will be raised if the specified notification
method is not one included in the OutputMethod Enum.
"""
self._verbosity = verbosity
self.outputMethod = OutputMethod.console
if config is not None:
self.config = config
if config["method"] == OutputMethod.telegram.name:
self.outputMethod = OutputMethod.telegram
elif config["method"] == OutputMethod.console.name:
self.outputMethod = OutputMethod.console
else:
raise OutputMethodError(config["method"])
# Error Functions
def _error_console(self, message):
print(message, file=sys.stderr, end='')
def _error_telegram(self, message):
bot_token = self.config["bot_token"]
user_id = self.config["user_id"]
message = "*ERROR*: " + message
requests.get(self.TELEGRAM_URL % locals())
_errorFunctions = {
OutputMethod.console: _error_console,
OutputMethod.telegram: _error_telegram
}
def error(self, message):
"""Send the user an error message via the previously specified method."""
if self._verbosity >= Verbosity.quiet:
self._errorFunctions[self.outputMethod](self, message)
# Notification Functions
def _notify_console(self, message):
print(message, file=sys.stdout, end='')
def _notify_telegram(self, message):
bot_token = self.config["bot_token"]
user_id = self.config["user_id"]
requests.get(self.TELEGRAM_URL % locals())
_notifyFunctions = {
OutputMethod.console: _notify_console,
OutputMethod.telegram: _notify_telegram
}
def notify(self, message):
"""Notify the user via the previously specified method."""
if self._verbosity >= Verbosity.normal:
self._notifyFunctions[self.outputMethod](self, message)
# Log Functions
def _log_console(self, message):
print(message, file=sys.stdout, end='')
def _log_telegram(self, message):
bot_token = self.config["bot_token"]
user_id = self.config["user_id"]
requests.get(self.TELEGRAM_URL % locals())
_logFunctions = {
OutputMethod.console: _log_console,
OutputMethod.telegram: _log_telegram
}
def log(self, message):
"""Log additional information to the user via the previously specified method."""
if self._verbosity >= Verbosity.verbose:
self._logFunctions[self.outputMethod](self, message)