feat: Verify the Landkreis and formatting improvements

This commit is contained in:
PapaTutuWawa 2020-08-31 13:06:24 +02:00
parent f939914864
commit cf64fa8677
4 changed files with 83 additions and 16 deletions

View File

@ -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

14
janine.example.conf Normal file
View File

@ -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)

View File

@ -1,3 +1,4 @@
import os
import sys import sys
import json import json
import datetime import datetime
@ -14,9 +15,10 @@ from aioxmpp.structs import PresenceShow
import requests import requests
from janine.utils import find_one, find_all 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 = logging.getLogger('janine')
#log.basicConfig(level=logging.INFO)
Warning = namedtuple('Warning', ['id', Warning = namedtuple('Warning', ['id',
'sent', 'sent',
@ -81,6 +83,31 @@ class WarningBot:
self._jid, self._jid,
aioxmpp.make_security_layer(self._password)) 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: async with self._client.connected() as stream:
logging.info('Client connected to server') logging.info('Client connected to server')
@ -98,7 +125,7 @@ class WarningBot:
self._client.set_presence( self._client.set_presence(
aioxmpp.PresenceState(available=True, aioxmpp.PresenceState(available=True,
show=PresenceShow.DND), show=PresenceShow.DND),
'Gibt dir im Notfall Bescheid') self._status)
# Start our fetch-send loop # Start our fetch-send loop
# NOTE: Originally, I wanted to use a cronjob and # NOTE: Originally, I wanted to use a cronjob and
@ -142,13 +169,40 @@ class WarningBot:
await self._send_notification(warning) 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): async def _send_notification(self, warning):
''' '''
Send a warning to all the recipients 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 # Smells like script injection, but okay
body = body.replace('<br>', '\n') body = body.replace('<br>', '\n')
body = body.replace('<br/>', '\n')
for recipient in self._recipients: for recipient in self._recipients:
msg = aioxmpp.stanza.Message( msg = aioxmpp.stanza.Message(
@ -173,6 +227,7 @@ class WarningBot:
self._jid = aioxmpp.JID.fromstr(config['Bot']['JID']) self._jid = aioxmpp.JID.fromstr(config['Bot']['JID'])
self._password = config['Bot']['Password'] self._password = config['Bot']['Password']
self._avatar = config['Bot'].get('Avatar', None) self._avatar = config['Bot'].get('Avatar', None)
self._status = config['Bot'].get('Status', 'Warnt dich vor Katastrophen')
def main(): def main():
bot = WarningBot() bot = WarningBot()

View File

@ -27,6 +27,17 @@ class WarningSources:
'BIWAPP': WarningSources.bbk_biwapp() 'BIWAPP': WarningSources.bbk_biwapp()
}[name] }[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): def sources_from_config(config):
sources = [] sources = []
for module in ('IHP', 'DWD', 'BIWAPP', 'MOWAS'): for module in ('IHP', 'DWD', 'BIWAPP', 'MOWAS'):