messenger.py 11.5 KB
Newer Older
1
#
David Trattnig's avatar
David Trattnig committed
2
# Aura Engine (https://gitlab.servus.at/aura/engine)
3
#
David Trattnig's avatar
David Trattnig committed
4
# Copyright (C) 2017-2020 - The Aura Engine Team.
5
#
David Trattnig's avatar
David Trattnig committed
6
7
8
9
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
10
#
David Trattnig's avatar
David Trattnig committed
11
12
13
14
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
15
#
David Trattnig's avatar
David Trattnig committed
16
17
18
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

19

20
21
import time
import logging
22
import datetime
23

David Trattnig's avatar
David Trattnig committed
24
from modules.communication.redis.statestore import RedisStateStore
25
from modules.communication.mail import AuraMailer
26
from modules.base.exceptions import PlaylistException
David Trattnig's avatar
David Trattnig committed
27
from modules.base.enum import RedisChannel
David Trattnig's avatar
David Trattnig committed
28
from modules.base.logger import AuraLogger
29
30

"""
31
Send and receive redis messages
32
"""
33
34


35
# ------------------------------------------------------------------------------------------ #
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
36
class RedisMessenger():
37
    logger = None
38
39
    rstore = None

40
    # ------------------------------------------------------------------------------------------ #
41
    def __init__(self, config):
42
        super(RedisMessenger, self).__init__()
43
44
45
        """
            Constructor
        """
46
        self.logger = logging.getLogger("AuraEngine")
47
        self.channel = RedisChannel.STANDARD
48
        self.section = ''
49
        self.rstore = RedisStateStore(config)
50
51
52
53
        self.errnr = '00'
        self.components = {'controller':'01', 'scheduling':'02', 'playd':'03', 'recorder':'04', 'helpers':'09'}
        self.fromMail = ''
        self.adminMails = ''
54
55

    # ------------------------------------------------------------------------------------------ #
56
    def set_channel(self, channel):
57
58
59
60
61
62
63
64
        """
        Einen "Kanal" setzen - zb scheduling
        @type channel: string
        @param channel: Kanal/Name der Komponente
        """
        self.channel = channel
        if channel in self.components:
            self.errnr = self.components[channel]
65
        self.rstore.set_channel(channel)
66
67

    # ------------------------------------------------------------------------------------------ #
68
    def set_section(self, section):
69
70
71
72
73
74
75
76
        """
        Einen Sektion / Gültigkeitsbereich der Meldung setzen - zb internal
        @type section: string
        @param section: Gültigkeitsbereich
        """
        self.section = section


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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#     # ------------------------------------------------------------------------------------------ #
#     def set_mail_addresses(self, fromMail, adminMails):
#         """
#         Einen Sektion / Gültigkeitsbereich der Meldung setzen - zb internal
#         @type section: string
#         @param section: Gültigkeitsbereich
#         """
#         self.fromMail = fromMail
#         self.adminMails = adminMails

#     # ------------------------------------------------------------------------------------------ #
#     def send(self, message, code, level, job, value='', section=''):
#         """
#         Eine Message senden
#         @type message:  string
#         @param message: menschenverständliche Nachricht
#         @type code:     string
#         @param code:    Fehlercode - endet mit 00 bei Erfolg
#         @type level:    string
#         @param level:   Error-Level - info, warning, error, fatal
#         @type job:      string
#         @param job:     Name der ausgeführten Funktion
#         @type value:    string
#         @param value:   Ein Wert
#         @type section:  string
#         @param section: Globale Sektion überschreiben
#         """
#         section = self.section if section == '' else section
#         self.time = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S:%f'))
#         self.utime = time.time()
#         state = {'message':message.strip().replace("'","\\'"), 'code':self.errnr + str(code),'job':job,'value':value}
#         self.rstore.set_section(section)
#         self.rstore.store(level, state)

#         if level == 'info' or level == 'success':
#             self.logger.info(message)
#         elif level == 'warning':
#             self.logger.warning(message)
#         elif level == 'error':
#             self.logger.error(message)
#             self.send_admin_mail(level, message, state)

#         elif level == 'fatal':
#             self.logger.critical(message)
#             self.send_admin_mail(level, message, state)

#     # ------------------------------------------------------------------------------------------ #
#     def say_alive(self):
#         """
#         Soll alle 20 Sekunden von den Komponenten ausgeführt werden,
#         um zu melden, dass sie am Leben sind
#         """
#         self.rstore.set_alive_state()

#     # ------------------------------------------------------------------------------------------ #
#     def get_alive_state(self, channel):
#         """
#         Live State abfragen
#         @type channel: string
#         @param channel: Channel/Komponente
#         """
#         return self.rstore.get_alive_state(channel)

#     # ------------------------------------------------------------------------------------------ #
#     def set_state(self, name, value, expires=None, channel=None):
#         """
#         Kündigt einen Event an
#         @type name: string
#         @param name: Name des state
#         @type value: string
#         @param value: Wert
#         @type channel: string
#         @param channel: Kanal (optional)
#         """
#         if not channel:
#             channel = self.channel

#         self.rstore.set_state(name, value, expires, channel)

#     # ------------------------------------------------------------------------------------------ #
#     def queue_add_event(self, name, eventtime, value, channel=None):
#         """
#         Kündigt einen Event an
#         @type name: string
#         @param name: der Name des Events
#         @type eventtime: string|datetime.datetime
#         @param eventtime: Datum und Zeit des events
#         @type value: dict
#         @param value: Werte
#         @type channel: string
#         @param channel: Kanal (optional)
#         """
#         if not channel:
#             channel = self.channel

#         if type(eventtime) == type(str()):
#             eventtime_str = datetime.datetime.strptime(eventtime[0:16].replace(' ','T'), "%Y-%m-%dT%H:%M").strftime("%Y-%m-%dT%H:%M")

#         elif type(eventtime) is datetime.datetime:
#             eventtime_str = eventtime.strftime("%Y-%m-%dT%H:%M")

#         else:
#             raise TypeError('eventtime must be a datetime.date or a string, not a %s' % type(eventtime))

#         self.rstore.queue_add_event(eventtime_str, name, value, channel)

#     # ------------------------------------------------------------------------------------------ #
#     def queue_remove_events(self, name, channel=None):
#         """
#         Löscht Events
#         @type name: string
#         @param name: der Name des Events
#         @type channel: string
#         @param channel: Kanal (optional)
#         """
#         if not channel:
#             channel = self.channel

#         self.rstore.queue_remove_events(name, channel)

#     # ------------------------------------------------------------------------------------------ #
#     def fire_event(self, name, value, channel=None):
#         """
#         Feuert einen Event
#         @type name: string
#         @param name: der Name des Events
#         @type value: dict
#         @param value: Werte
#         @type channel: string
#         @param channel: Kanal (optional)
#         """
#         if not channel:
#             channel = self.channel

#         self.rstore.fire_event(name, value, channel)

#     # ------------------------------------------------------------------------------------------ #
#     def get_event_queue(self, name=None, channel=None):
#         """
#         Holt events eines Kanals
#         @type channel: string
#         @param channel: Kanal (optional)
#         @rtype: list
#         @return: Liste der Events
#         """
#         queue = self.rstore.get_event_queue(name, channel)
#         return queue

#     # ------------------------------------------------------------------------------------------ #
#     def get_events(self, name=None, channel=None):
#         """
#         Holt events eines Kanals
#         @type channel: string
#         @param channel: Kanal (optional)
#         @rtype: list
#         @return: Liste der Events
#         """
#         events = self.rstore.get_events(name, channel)
#         return events

#     # ------------------------------------------------------------------------------------------ #
#     def get_event(self, name=None, channel=None):
#         """
#         Holt event eines Kanals
#         @type channel: string
#         @param channel: Kanal (optional)
#         @rtype: dict
#         @return: Event
#         """
#         events = self.rstore.get_events(name, channel)
#         result = False
#         if events:
#             result = events.pop(0)
#         return result

#     # ------------------------------------------------------------------------------------------ #
#     def send_admin_mail(self, level, message, state):
#         """
#         Sendent mail an Admin(s),
#         @type message: string
#         @param message: Die Message
#         @type state: dict
#         @param state: Der State
#         @return result
#         """
262
        
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#         # FIXME Make Mailer functional: Invalid constructor
#         if self.fromMail and self.adminMails:
#             #subject = "Possible comba problem on job " + state['job'] + " - " + level
#             mailmessage = "Hi Admin,\n comba reports a possible problem\n\n"
#             mailmessage = mailmessage + level + "!\n"
#             mailmessage = mailmessage + message + "\n\n"
#             mailmessage = mailmessage + "Additional information:\n"
#             mailmessage = mailmessage + "##################################################\n"
#             mailmessage = mailmessage + "Job:\t" + state['job'] + "\n"
#             mailmessage = mailmessage + "Code:\t" + state['code'] + "\n"
#             mailmessage = mailmessage + "Value:\t" + str(state['value']) + "\n"

#             #mailer = AuraMailer(self.adminMails, self.fromMail)
#             #mailer.send_admin_mail(subject, mailmessage)
#         else:
#             return False

#     # ------------------------------------------------------------------------------------------ #
#     def receive(self):
#         """
#         Bisher wird nichts empfangen
#         """
#         return ""

#     # ------------------------------------------------------------------------------------------ #
#     def get_next_file_for(self, playlisttype):
#         next = self.rstore.db.get('next_'+playlisttype+'file')

#         if next is None:
#             next = b""

#         return next.decode('utf-8')
Gottfried Gaisbauer's avatar
Gottfried Gaisbauer committed
295

296
    # ------------------------------------------------------------------------------------------ #
297
298
    # def on_play(self, info):
    #     result = self.rstore.db.get('on_play')
299

300
301
    #     if result is None:
    #         result = b""
302

303
    #     return result.decode('utf-8')
304

305
    # ------------------------------------------------------------------------------------------ #
306
307
    # def set_next_file_for(self, playlisttype, file):
    #     self.rstore.db.set("next_" + playlisttype + "file", file)
308

309