From cf64fa8677e7a710455d66b5ea2d610ccd27a599 Mon Sep 17 00:00:00 2001 From: Alexander PapaTutuWawa Date: Mon, 31 Aug 2020 13:06:24 +0200 Subject: [PATCH] feat: Verify the Landkreis and formatting improvements --- janine.conf | 13 ---------- janine.example.conf | 14 +++++++++++ janine/janine.py | 61 ++++++++++++++++++++++++++++++++++++++++++--- janine/sources.py | 11 ++++++++ 4 files changed, 83 insertions(+), 16 deletions(-) delete mode 100644 janine.conf create mode 100644 janine.example.conf diff --git a/janine.conf b/janine.conf deleted file mode 100644 index f030ab8..0000000 --- a/janine.conf +++ /dev/null @@ -1,13 +0,0 @@ -[General] -IHP = y # Hochwasserwarnungen -DWD = y # Unwetterwarnungen -MOWAS = y # Gefahrendurchsagen -BIWAPP = y # Warnmeldungen -Landkreis = Stuttgart # Warnungen für diesen Landkreis weiterleiten -Recipients = some.user@xmpp.server,other@xmpp.server -Timeout=630 - -[Bot] -Avatar = /etc/janine/avatar.png # Setze den Avatar für den Bot -JID = janine@some.server.xmpp -Password = super_secret_password diff --git a/janine.example.conf b/janine.example.conf new file mode 100644 index 0000000..611fc76 --- /dev/null +++ b/janine.example.conf @@ -0,0 +1,14 @@ +[General] +IHP = y # Hochwasserwarnungen +DWD = y # Unwetterwarnungen +MOWAS = y # Gefahrendurchsagen +BIWAPP = y # Warnmeldungen +Landkreis = Stuttgart # Warnungen für diesen Landkreis weiterleiten +Recipients = some.user@xmpp.server,other@xmpp.server # Empfänger +Timeout=630 # Zeit in Sekunden nach welcher nach neuen Warnungen geschaut wird + +[Bot] +Avatar = /etc/janine/avatar.png # Bot Avatar (Optional) +JID = janine@some.server.xmpp # Bot Account +Password = super_secret_password # Bot Passwort +Status = Gibt dir im Notfall Bescheid # Statusnachricht (Optional) diff --git a/janine/janine.py b/janine/janine.py index 6612731..6620c87 100644 --- a/janine/janine.py +++ b/janine/janine.py @@ -1,3 +1,4 @@ +import os import sys import json import datetime @@ -14,9 +15,10 @@ from aioxmpp.structs import PresenceShow import requests from janine.utils import find_one, find_all -from janine.sources import sources_from_config +from janine.sources import sources_from_config, MiscDataSources log = logging.getLogger('janine') +#log.basicConfig(level=logging.INFO) Warning = namedtuple('Warning', ['id', 'sent', @@ -81,6 +83,31 @@ class WarningBot: self._jid, aioxmpp.make_security_layer(self._password)) + # First we check if the entered Landkreis is valid + channels = {} + if not os.path.exists('/etc/janine/channels.json'): + log.debug('Requesting search channels') + req = requests.get(MiscDataSources.channels()) + channels = json.loads(req.text) + + try: + with open('/etc/janine/channels.json', 'w') as f: + f.write(json.dumps(channels)) + except Exception as err: + log.error('Failed to cache channel data:') + log.error(str(err)) + else: + with open('/etc/janine/channels.json', 'r') as f: + channels = json.loads(f.read()) + + for key in channels.keys(): + if channels[key].get('NAME', '') == self._landkreis: + log.info('Landkreis valid') + break + else: + log.error('Invalid Landkreis') + return + async with self._client.connected() as stream: logging.info('Client connected to server') @@ -98,7 +125,7 @@ class WarningBot: self._client.set_presence( aioxmpp.PresenceState(available=True, show=PresenceShow.DND), - 'Gibt dir im Notfall Bescheid') + self._status) # Start our fetch-send loop # NOTE: Originally, I wanted to use a cronjob and @@ -142,13 +169,40 @@ class WarningBot: await self._send_notification(warning) + def __time_format(self, time_str): + ''' + Reformat ISO style time data to a more + readable format. + ''' + date = None + try: + date = datetime.datetime.fromisoformat(time_str) + except: + pass + + if not date: + return time_str + + return '{}.{}.{} {}:{}'.format(date.day, + date.month, + date.year, + date.hour, + date.minute) + async def _send_notification(self, warning): ''' Send a warning to all the recipients ''' - body = '*{}*\n\n{}'.format(warning.headline, warning.description) + # Reformat the message a bit + effective_time = self.__time_format(warning.effective_from) + expiry_time = self.__time_format(warning.expires) + body = '*{}*\n({} bis {})\n\n{}'.format(warning.headline, + effective_time, + expiry_time, + warning.description) # Smells like script injection, but okay body = body.replace('
', '\n') + body = body.replace('
', '\n') for recipient in self._recipients: msg = aioxmpp.stanza.Message( @@ -173,6 +227,7 @@ class WarningBot: self._jid = aioxmpp.JID.fromstr(config['Bot']['JID']) self._password = config['Bot']['Password'] self._avatar = config['Bot'].get('Avatar', None) + self._status = config['Bot'].get('Status', 'Warnt dich vor Katastrophen') def main(): bot = WarningBot() diff --git a/janine/sources.py b/janine/sources.py index ce05dd2..d31ad01 100644 --- a/janine/sources.py +++ b/janine/sources.py @@ -27,6 +27,17 @@ class WarningSources: 'BIWAPP': WarningSources.bbk_biwapp() }[name] +class MiscDataSources: + ''' + A collection of other data sources for various use cases + ''' + @staticmethod + def channels(): + ''' + These are the valid names to retrieve warnings for + ''' + return 'https://warnung.bund.de/assets/json/suche_channel.json' + def sources_from_config(config): sources = [] for module in ('IHP', 'DWD', 'BIWAPP', 'MOWAS'):