From 7b091fabe4ecfa0c99a37440a9e81a34c022603f Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Tue, 18 Feb 2020 22:12:53 +0100 Subject: [PATCH 01/19] Add Telegram Plugin and Documentation --- docu/docs/plugin/telegram.md | 66 +++++++++++++++++++++ docu/mkdocs.yml | 3 +- plugin/telegram.py | 112 +++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 docu/docs/plugin/telegram.md create mode 100644 plugin/telegram.py diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md new file mode 100644 index 0000000..1f1b3d4 --- /dev/null +++ b/docu/docs/plugin/telegram.md @@ -0,0 +1,66 @@ +#
Telegram
+--- + +## Beschreibung +Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. +Außerdem unterstützt das Plugin das Versenden von Location über folgende geocoding-Api's: + +- Mapbox +- Google Maps + +## Resource +`telegram` + +## Konfiguration + +|Feld|Beschreibung|Default| +|----|------------|-------| +|name|Beliebiger Name des Plugins|| + +#### `config:` + +|Feld|Beschreibung|Default| +|----|------------|-------| +|botToken|Der Api-Key des Telegram-Bots|| +|chatId|Die Chat-Id des Empfängers / der Emfänger-Gruppe|| +|geocoding|Aktivieren des Geocodings|false| +|geoRegex|Regex Capture-Group zum Herausfiltern der Adresse|| +|geoApiProvider|Der Provider für das Geocoding|| +|geoApiToken|Der Api-Token fuer die Geocoding-Api|| + +#### Verfügbare Geocoding Provider + +|Name|Einstellungswert| +|----|------------| +|Mapbox|mapbox| +|Google Maps|google| + +**Beispiel:** +```yaml + - type: plugin + name: Telegram Plugin + res: telegram + config: + botToken: {{ Telegram Bot Token }} + chatId: {{ Telegram Chat Id }} + geocoding: true + geoRegex: ((?:[^ ]*,)*?) + geoApiProvider: mapbox + geoApiToken: {{ Mapbox Api Key }} +``` + +--- +## Abhängigkeiten + +- python-telegram-bot +- geocoder + +--- +## Paket Modifikationen + +- keine + +--- +## Zusätzliche Wildcards + +- keine diff --git a/docu/mkdocs.yml b/docu/mkdocs.yml index 0948dd6..846363e 100644 --- a/docu/mkdocs.yml +++ b/docu/mkdocs.yml @@ -21,7 +21,8 @@ nav: - Mode Filter: modul/mode_filter.md - Regex Filter: modul/regex_filter.md - Descriptor: modul/descriptor.md - - Plugins: tbd.md + - Plugins: + - Telegram: plugin/telegram.md - Entwickler: - Eigenes Modul/Plugin schreiben: develop/ModulPlugin.md - BOSWatch Alarmpaket Format: develop/packet.md diff --git a/plugin/telegram.py b/plugin/telegram.py new file mode 100644 index 0000000..6250ce4 --- /dev/null +++ b/plugin/telegram.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: template_module.py +@date: 14.01.2018 +@author: Bastian Schroll +@description: Template Plugin File +""" +import logging + +from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, ChatMigrated, NetworkError) +from plugin.pluginBase import PluginBase +import telegram +import re +import geocoder + +# ###################### # +# Custom plugin includes # + +# ###################### # + +logging.debug("- %s loaded", __name__) + + +class BoswatchPlugin(PluginBase): + """!Description of the Plugin""" + + def __init__(self, config): + """!Do not change anything here!""" + super().__init__(__name__, config) # you can access the config class on 'self.config' + + def onLoad(self): + """!Called by import of the plugin""" + pass + + def setup(self): + """!Called before alarm""" + self.bot = telegram.Bot(token=self.config.get("botToken", default="")) + pass + + def fms(self, bwPacket): + """!Called on FMS alarm + + @param bwPacket: bwPacket instance""" + logging.warning('Telegram Plugin does not work for FMS') + pass + + def pocsag(self, bwPacket): + """!Called on POCSAG alarm + + @param bwPacket: bwPacket instance""" + + try: + # Send Message via Telegram + msg = bwPacket.get("ric") + " (" + bwPacket.get("subric") + ")\n" + bwPacket.get("message") + self.bot.send_message(chat_id=self.config.get("chatId", default=""), text=msg) + + # Send Location via Telegram if Geocoding is enabled and Provider and Key are set + if self.config.get("geocoding", default=False): + try: + address = re.search(self.config.get("geoRegex"), bwPacket.get("message"))[1] + provider = self.config.get("geoApiProvider") + + if "mapbox" == provider: + g = geocoder.mapbox(address, key=self.config.get("geoApiToken")) + elif "google" == provider: + g = geocoder.google(address, key=self.config.get("geoApiToken")) + else: + return + + (lat, lng) = g.latlng + self.bot.sendLocation(chat_id=self.config.get("chatId", default=""), latitude=lat, longitude=lng) + except Exception: + logging.error('Error while sending location, please Check your geocoding provider and api-key') + except Unauthorized: + logging.error('Error while Telegram Message, please Check your api-key') + except TimedOut or NetworkError: + logging.error('Error while Telegram Message, please Check your connectivity') + except BadRequest or TelegramError: + logging.error('Error while Telegram Message') + + pass + + def zvei(self, bwPacket): + """!Called on ZVEI alarm + + @param bwPacket: bwPacket instance""" + logging.warning('Telegram Plugin does not work for ZVEI') + pass + + def msg(self, bwPacket): + """!Called on MSG packet + + @param bwPacket: bwPacket instance""" + logging.warning('Telegram Plugin does not work for MSG') + pass + + def teardown(self): + """!Called after alarm""" + pass + + def onUnload(self): + """!Called by destruction of the plugin""" + pass From 4e79feb92b25c131d2b15509d8542178de36aa24 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Tue, 18 Feb 2020 23:06:14 +0100 Subject: [PATCH 02/19] coding-styles --- plugin/telegram.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/plugin/telegram.py b/plugin/telegram.py index 6250ce4..ebaf1cf 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -50,7 +50,7 @@ class BoswatchPlugin(PluginBase): """!Called on FMS alarm @param bwPacket: bwPacket instance""" - logging.warning('Telegram Plugin does not work for FMS') + logging.warning("Telegram Plugin does not work for FMS") pass def pocsag(self, bwPacket): @@ -78,14 +78,16 @@ class BoswatchPlugin(PluginBase): (lat, lng) = g.latlng self.bot.sendLocation(chat_id=self.config.get("chatId", default=""), latitude=lat, longitude=lng) + except IndexError: + logging.warning("Address was not found in current Message, skipping Location") except Exception: - logging.error('Error while sending location, please Check your geocoding provider and api-key') + logging.error("Error while sending location, please Check your geocoding provider and api-key") except Unauthorized: - logging.error('Error while Telegram Message, please Check your api-key') + logging.error("Error while Telegram Message, please Check your api-key") except TimedOut or NetworkError: - logging.error('Error while Telegram Message, please Check your connectivity') + logging.error("Error while Telegram Message, please Check your connectivity") except BadRequest or TelegramError: - logging.error('Error while Telegram Message') + logging.error("Error while Telegram Message") pass @@ -93,14 +95,14 @@ class BoswatchPlugin(PluginBase): """!Called on ZVEI alarm @param bwPacket: bwPacket instance""" - logging.warning('Telegram Plugin does not work for ZVEI') + logging.warning("Telegram Plugin does not work for ZVEI") pass def msg(self, bwPacket): """!Called on MSG packet @param bwPacket: bwPacket instance""" - logging.warning('Telegram Plugin does not work for MSG') + logging.warning("Telegram Plugin does not work for MSG") pass def teardown(self): From 4a2f2992b2f1b541142d1f5d6c659b086db070e5 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Tue, 18 Feb 2020 23:26:13 +0100 Subject: [PATCH 03/19] better error handling --- plugin/telegram.py | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/plugin/telegram.py b/plugin/telegram.py index ebaf1cf..e97c5bc 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -65,29 +65,28 @@ class BoswatchPlugin(PluginBase): # Send Location via Telegram if Geocoding is enabled and Provider and Key are set if self.config.get("geocoding", default=False): - try: - address = re.search(self.config.get("geoRegex"), bwPacket.get("message"))[1] - provider = self.config.get("geoApiProvider") + address = re.search(self.config.get("geoRegex"), bwPacket.get("message"))[1] + provider = self.config.get("geoApiProvider") - if "mapbox" == provider: - g = geocoder.mapbox(address, key=self.config.get("geoApiToken")) - elif "google" == provider: - g = geocoder.google(address, key=self.config.get("geoApiToken")) - else: - return + if "mapbox" == provider: + g = geocoder.mapbox(address, key=self.config.get("geoApiToken")) + elif "google" == provider: + g = geocoder.google(address, key=self.config.get("geoApiToken")) + else: + return - (lat, lng) = g.latlng - self.bot.sendLocation(chat_id=self.config.get("chatId", default=""), latitude=lat, longitude=lng) - except IndexError: - logging.warning("Address was not found in current Message, skipping Location") - except Exception: - logging.error("Error while sending location, please Check your geocoding provider and api-key") + (lat, lng) = g.latlng + self.bot.sendLocation(chat_id=self.config.get("chatId", default=""), latitude=lat, longitude=lng) + except (IndexError, TypeError, ValueError): + logging.warning("Address was not found in current Message, skipping Location") except Unauthorized: - logging.error("Error while Telegram Message, please Check your api-key") - except TimedOut or NetworkError: - logging.error("Error while Telegram Message, please Check your connectivity") - except BadRequest or TelegramError: - logging.error("Error while Telegram Message") + logging.error("Error while sending Telegram Message, please Check your api-key") + except (TimedOut, NetworkError): + logging.error("Error while sending Telegram Message, please Check your connectivity") + except (BadRequest, TelegramError): + logging.error("Error while sending Telegram Message") + except Exception as e: + logging.error("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e)) pass From 4aea7b5d78c2d8f2bb299804deb583b24c1411a4 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sat, 22 Feb 2020 19:08:53 +0100 Subject: [PATCH 04/19] add geocoding module, resolve threads --- docu/docs/modul/geocoding.md | 53 ++++++++++++++ docu/docs/plugin/telegram.md | 36 ++-------- docu/mkdocs.yml | 1 + module/geocoding.py | 72 +++++++++++++++++++ plugin/telegram.py | 95 +++++++------------------ testPackage.py | 134 +++++++++++++++++++++++++++++++++++ 6 files changed, 291 insertions(+), 100 deletions(-) create mode 100644 docu/docs/modul/geocoding.md create mode 100644 module/geocoding.py create mode 100644 testPackage.py diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md new file mode 100644 index 0000000..ca939ea --- /dev/null +++ b/docu/docs/modul/geocoding.md @@ -0,0 +1,53 @@ +#
Geocoding
+--- + +## Beschreibung +Mit diesem Modul können einem Paket die Koordinaten eines Ortes oder einer Adresse angefügt werden. + +## Unterstützte Alarmtypen + - Pocsag + +## Resource +`geocoding` + +## Konfiguration + +|Feld|Beschreibung|Default| +|----|------------|-------| +apiProvider|Der Provider für das Geocoding| +apiToken|Der Api-Token fuer die Geocoding-Api| +geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| + +#### Verfügbare Geocoding Provider + +|Name|Einstellungswert| +|----|------------| +|Mapbox|mapbox| +|Google Maps|google| + +**Beispiel:** +```yaml + - type: module + name: Geocoding Module + res: geocoding + config: + apiProvider: "{{ Provider für Geocoding }}" + apiToken: "{{ API-Key für Provider }}" + regex: "((?:[^ ]*,)*?)" +``` + +--- +## Abhängigkeiten + +- geocoder +- re + +--- +## Paket Modifikationen + +- Im Paket werden die Felder `lat` und `lng` hinterlegt + +--- +## Zusätzliche Wildcards + +- keine \ No newline at end of file diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md index 1f1b3d4..d6afdfb 100644 --- a/docu/docs/plugin/telegram.md +++ b/docu/docs/plugin/telegram.md @@ -2,38 +2,20 @@ --- ## Beschreibung -Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. -Außerdem unterstützt das Plugin das Versenden von Location über folgende geocoding-Api's: +Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. Außerdem werden Locations versenden, wenn die Felder `lat` und `lng` im Paket definiert sind. -- Mapbox -- Google Maps +## Unterstütze Alarmtypen +- Pocsag ## Resource `telegram` ## Konfiguration -|Feld|Beschreibung|Default| -|----|------------|-------| -|name|Beliebiger Name des Plugins|| - -#### `config:` - |Feld|Beschreibung|Default| |----|------------|-------| |botToken|Der Api-Key des Telegram-Bots|| -|chatId|Die Chat-Id des Empfängers / der Emfänger-Gruppe|| -|geocoding|Aktivieren des Geocodings|false| -|geoRegex|Regex Capture-Group zum Herausfiltern der Adresse|| -|geoApiProvider|Der Provider für das Geocoding|| -|geoApiToken|Der Api-Token fuer die Geocoding-Api|| - -#### Verfügbare Geocoding Provider - -|Name|Einstellungswert| -|----|------------| -|Mapbox|mapbox| -|Google Maps|google| +|chatIds|Liste mit Chat-Ids der Empfängers / der Emfänger-Gruppen|| **Beispiel:** ```yaml @@ -41,19 +23,15 @@ Außerdem unterstützt das Plugin das Versenden von Location über folgende geoc name: Telegram Plugin res: telegram config: - botToken: {{ Telegram Bot Token }} - chatId: {{ Telegram Chat Id }} - geocoding: true - geoRegex: ((?:[^ ]*,)*?) - geoApiProvider: mapbox - geoApiToken: {{ Mapbox Api Key }} + botToken: "{{ Telegram Bot Token }}" + chatIds: + - "{{ Telegram Chat Id }}" ``` --- ## Abhängigkeiten - python-telegram-bot -- geocoder --- ## Paket Modifikationen diff --git a/docu/mkdocs.yml b/docu/mkdocs.yml index 846363e..5ba0bc9 100644 --- a/docu/mkdocs.yml +++ b/docu/mkdocs.yml @@ -21,6 +21,7 @@ nav: - Mode Filter: modul/mode_filter.md - Regex Filter: modul/regex_filter.md - Descriptor: modul/descriptor.md + - Geocoding: modul/geocoding.md - Plugins: - Telegram: plugin/telegram.md - Entwickler: diff --git a/module/geocoding.py b/module/geocoding.py new file mode 100644 index 0000000..b2bbb5c --- /dev/null +++ b/module/geocoding.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: geocoding.py +@date: 01.03.2019 +@author: Jan Speller +@description: Geocoding Module +""" +import logging +from module.moduleBase import ModuleBase + +# ###################### # +# Custom plugin includes # +import geocoder +import re +# ###################### # + +logging.debug("- %s loaded", __name__) + + +class BoswatchModule(ModuleBase): + """!Description of the Module""" + def __init__(self, config): + """!Do not change anything here!""" + super().__init__(__name__, config) # you can access the config class on 'self.config' + + def doWork(self, bwPacket): + """!start an run of the module. + + @param bwPacket: A BOSWatch packet instance""" + if bwPacket.get("mode") == "pocsag": + self.geocode(bwPacket) + pass + + return bwPacket + + def geocode(self, bwPacket): + """!find address in message and get latitude and longitude + + @param bwPacket: A BOSWatch packet instance""" + try: + address = re.search(self.config.get("regex"), bwPacket.get("message"))[1] + provider = self.config.get("apiProvider") + if "mapbox" == provider: + g = geocoder.mapbox(address, key=self.config.get("apiToken")) + print(address) + elif "google" == provider: + g = geocoder.google(address, key=self.config.get("apiToken")) + else: + return bwPacket + + (lat, lng) = g.latlng + bwPacket.set("lat", lat) + bwPacket.set("lng", lng) + return bwPacket + except (IndexError, TypeError, ValueError): + logging.warning("Address was not found in current Message, skipping geocoding") + except Exception as e: + logging.error("Unknown Error while executing geocoding module: " + str(type(e).__name__) + ": " + str(e)) + return bwPacket + + def onUnload(self): + """!Called by destruction of the plugin""" + pass diff --git a/plugin/telegram.py b/plugin/telegram.py index e97c5bc..f32a0cf 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -9,22 +9,19 @@ German BOS Information Script by Bastian Schroll -@file: template_module.py -@date: 14.01.2018 -@author: Bastian Schroll -@description: Template Plugin File +@file: telegram.py +@date: 20.02.2020 +@author: Jan Speller +@description: Telegram Plugin """ import logging -from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, ChatMigrated, NetworkError) from plugin.pluginBase import PluginBase -import telegram -import re -import geocoder # ###################### # # Custom plugin includes # - +from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, ChatMigrated, NetworkError) +import telegram # ###################### # logging.debug("- %s loaded", __name__) @@ -39,75 +36,31 @@ class BoswatchPlugin(PluginBase): def onLoad(self): """!Called by import of the plugin""" - pass - - def setup(self): - """!Called before alarm""" self.bot = telegram.Bot(token=self.config.get("botToken", default="")) pass - def fms(self, bwPacket): - """!Called on FMS alarm - - @param bwPacket: bwPacket instance""" - logging.warning("Telegram Plugin does not work for FMS") - pass - def pocsag(self, bwPacket): """!Called on POCSAG alarm @param bwPacket: bwPacket instance""" + msg = bwPacket.get("ric") + " (" + bwPacket.get("subric") + ")\n" + bwPacket.get("message") - try: - # Send Message via Telegram - msg = bwPacket.get("ric") + " (" + bwPacket.get("subric") + ")\n" + bwPacket.get("message") - self.bot.send_message(chat_id=self.config.get("chatId", default=""), text=msg) - - # Send Location via Telegram if Geocoding is enabled and Provider and Key are set - if self.config.get("geocoding", default=False): - address = re.search(self.config.get("geoRegex"), bwPacket.get("message"))[1] - provider = self.config.get("geoApiProvider") - - if "mapbox" == provider: - g = geocoder.mapbox(address, key=self.config.get("geoApiToken")) - elif "google" == provider: - g = geocoder.google(address, key=self.config.get("geoApiToken")) - else: - return - - (lat, lng) = g.latlng - self.bot.sendLocation(chat_id=self.config.get("chatId", default=""), latitude=lat, longitude=lng) - except (IndexError, TypeError, ValueError): - logging.warning("Address was not found in current Message, skipping Location") - except Unauthorized: - logging.error("Error while sending Telegram Message, please Check your api-key") - except (TimedOut, NetworkError): - logging.error("Error while sending Telegram Message, please Check your connectivity") - except (BadRequest, TelegramError): - logging.error("Error while sending Telegram Message") - except Exception as e: - logging.error("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e)) + if bwPacket.get("lat") is not None and bwPacket.get("lng") is not None: + (lat, lng) = (bwPacket.get("lat"), bwPacket.get("lng")) + for chatId in self.config.get("chatIds", default=[]): + try: + # Send Message via Telegram + self.bot.send_message(chat_id=chatId, default=""), text=msg) - pass - - def zvei(self, bwPacket): - """!Called on ZVEI alarm - - @param bwPacket: bwPacket instance""" - logging.warning("Telegram Plugin does not work for ZVEI") - pass - - def msg(self, bwPacket): - """!Called on MSG packet - - @param bwPacket: bwPacket instance""" - logging.warning("Telegram Plugin does not work for MSG") - pass - - def teardown(self): - """!Called after alarm""" - pass - - def onUnload(self): - """!Called by destruction of the plugin""" + # Send Location via Telegram if lat and lng exist in Package + if lat is not None and lng is not None: + self.bot.sendLocation(chat_id=chatId, latitude=lat, longitude=lng) + except Unauthorized: + logging.error("Error while sending Telegram Message, please Check your api-key") + except (TimedOut, NetworkError): + logging.error("Error while sending Telegram Message, please Check your connectivity") + except (BadRequest, TelegramError): + logging.error("Error while sending Telegram Message") + except Exception as e: + logging.error("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e)) pass diff --git a/testPackage.py b/testPackage.py new file mode 100644 index 0000000..a9bfeb7 --- /dev/null +++ b/testPackage.py @@ -0,0 +1,134 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import logging +import socket +import select + +logging.debug("- %s loaded", __name__) + +HEADERSIZE = 10 +class TCPClient: + """!TCP client class""" + + def __init__(self, timeout=3): + """!Create a new instance + + @param timeout: timeout for the client in sec. (3)""" + socket.setdefaulttimeout(timeout) + self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + def connect(self, host="localhost", port=8080): + """!Connect to the server + + @param host: Server IP address ("localhost") + @param port: Server Port (8080) + @return True or False""" + try: + if not self.isConnected: + self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._sock.connect((host, port)) + logging.debug("connected to %s:%s", host, port) + return True + logging.warning("client always connected") + return True + except socket.error as e: + logging.error(e) + return False + + def disconnect(self): + """!Disconnect from the server + + @return True or False""" + try: + if self.isConnected: + self._sock.shutdown(socket.SHUT_RDWR) + self._sock.close() + logging.debug("disconnected") + return True + logging.warning("client always disconnected") + return True + except socket.error as e: + logging.error(e) + return False + + def transmit(self, data): + """!Send a data packet to the server + + @param data: data to send to the server + @return True or False""" + try: + logging.debug("transmitting:\n%s", data) + data = data.encode("utf-8") + header = str(len(data)).ljust(HEADERSIZE).encode("utf-8") + self._sock.sendall(header + data) + logging.debug("transmitted...") + return True + except socket.error as e: + logging.error(e) + return False + + def receive(self, timeout=1): + """!Receive data from the server + + @param timeout: to wait for incoming data in seconds + @return received data""" + try: + read, _, _ = select.select([self._sock], [], [], timeout) + if not read: # check if there is something to read + return False + + header = self._sock.recv(HEADERSIZE).decode("utf-8") + if not len(header): # check if there data + return False + + length = int(header.strip()) + received = self._sock.recv(length).decode("utf-8") + + logging.debug("recv header: '%s'", header) + logging.debug("received %d bytes: %s", len(received), received) + return received + except socket.error as e: + logging.error(e) + return False + + @property + def isConnected(self): + """!Property of client connected state""" + try: + if self._sock: + _, write, _ = select.select([], [self._sock], [], 0.1) + if write: + data = "".encode("utf-8") + header = str(len(data)).ljust(HEADERSIZE).encode("utf-8") + self._sock.sendall(header + data) + return True + return False + except socket.error as e: + if e.errno != 32: + logging.exception(e) + return False + except ValueError: + return False + +client = TCPClient() +client.connect() +client.transmit(str({ + 'serverName': 'TestServer', + 'serverVersion': '3.0', + 'serverBuildDate': '01.01.2020', + 'serverBranch': 'develop', + 'clientName': 'TestClient', + 'clientIP': '127.0.0.1', + 'clientVersion': '3.0', + 'clientBuildDate': '01.01.2020', + 'clientBranch': 'develop', + 'inputSource': 'sdr', + 'timestamp': '15:30', + 'frequency': '173.240', + 'mode': 'pocsag', + 'bitrate': '512', + 'ric': '1326089', + 'subric': '1', + 'subricText': 'a', + 'message': '17:22 FW 18865 Gebäudebrand_kle Sandkampstr.,15,-,Hopsten,NRW rauchentwicklung' +})) \ No newline at end of file From c7f99bcfcbe96d6cdc69eda3b72db6c8f8ec232e Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sat, 22 Feb 2020 19:11:21 +0100 Subject: [PATCH 05/19] changes to telegram --- plugin/telegram.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugin/telegram.py b/plugin/telegram.py index f32a0cf..3050afc 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -15,12 +15,11 @@ @description: Telegram Plugin """ import logging - from plugin.pluginBase import PluginBase # ###################### # # Custom plugin includes # -from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, ChatMigrated, NetworkError) +from telegram.error import (TelegramError, Unauthorized, BadRequest, TimedOut, NetworkError) import telegram # ###################### # @@ -44,15 +43,15 @@ class BoswatchPlugin(PluginBase): @param bwPacket: bwPacket instance""" msg = bwPacket.get("ric") + " (" + bwPacket.get("subric") + ")\n" + bwPacket.get("message") - if bwPacket.get("lat") is not None and bwPacket.get("lng") is not None: (lat, lng) = (bwPacket.get("lat"), bwPacket.get("lng")) + for chatId in self.config.get("chatIds", default=[]): try: # Send Message via Telegram - self.bot.send_message(chat_id=chatId, default=""), text=msg) - - # Send Location via Telegram if lat and lng exist in Package + self.bot.send_message(chat_id=chatId, text=msg) + + # Send Location via Telegram if lat and lng are defined if lat is not None and lng is not None: self.bot.sendLocation(chat_id=chatId, latitude=lat, longitude=lng) except Unauthorized: From 716d7a18c0477e00b624dd78aa3211e1fc5385a9 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sat, 22 Feb 2020 19:14:45 +0100 Subject: [PATCH 06/19] Delete test env --- testPackage.py | 134 ------------------------------------------------- 1 file changed, 134 deletions(-) delete mode 100644 testPackage.py diff --git a/testPackage.py b/testPackage.py deleted file mode 100644 index a9bfeb7..0000000 --- a/testPackage.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -import logging -import socket -import select - -logging.debug("- %s loaded", __name__) - -HEADERSIZE = 10 -class TCPClient: - """!TCP client class""" - - def __init__(self, timeout=3): - """!Create a new instance - - @param timeout: timeout for the client in sec. (3)""" - socket.setdefaulttimeout(timeout) - self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - def connect(self, host="localhost", port=8080): - """!Connect to the server - - @param host: Server IP address ("localhost") - @param port: Server Port (8080) - @return True or False""" - try: - if not self.isConnected: - self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._sock.connect((host, port)) - logging.debug("connected to %s:%s", host, port) - return True - logging.warning("client always connected") - return True - except socket.error as e: - logging.error(e) - return False - - def disconnect(self): - """!Disconnect from the server - - @return True or False""" - try: - if self.isConnected: - self._sock.shutdown(socket.SHUT_RDWR) - self._sock.close() - logging.debug("disconnected") - return True - logging.warning("client always disconnected") - return True - except socket.error as e: - logging.error(e) - return False - - def transmit(self, data): - """!Send a data packet to the server - - @param data: data to send to the server - @return True or False""" - try: - logging.debug("transmitting:\n%s", data) - data = data.encode("utf-8") - header = str(len(data)).ljust(HEADERSIZE).encode("utf-8") - self._sock.sendall(header + data) - logging.debug("transmitted...") - return True - except socket.error as e: - logging.error(e) - return False - - def receive(self, timeout=1): - """!Receive data from the server - - @param timeout: to wait for incoming data in seconds - @return received data""" - try: - read, _, _ = select.select([self._sock], [], [], timeout) - if not read: # check if there is something to read - return False - - header = self._sock.recv(HEADERSIZE).decode("utf-8") - if not len(header): # check if there data - return False - - length = int(header.strip()) - received = self._sock.recv(length).decode("utf-8") - - logging.debug("recv header: '%s'", header) - logging.debug("received %d bytes: %s", len(received), received) - return received - except socket.error as e: - logging.error(e) - return False - - @property - def isConnected(self): - """!Property of client connected state""" - try: - if self._sock: - _, write, _ = select.select([], [self._sock], [], 0.1) - if write: - data = "".encode("utf-8") - header = str(len(data)).ljust(HEADERSIZE).encode("utf-8") - self._sock.sendall(header + data) - return True - return False - except socket.error as e: - if e.errno != 32: - logging.exception(e) - return False - except ValueError: - return False - -client = TCPClient() -client.connect() -client.transmit(str({ - 'serverName': 'TestServer', - 'serverVersion': '3.0', - 'serverBuildDate': '01.01.2020', - 'serverBranch': 'develop', - 'clientName': 'TestClient', - 'clientIP': '127.0.0.1', - 'clientVersion': '3.0', - 'clientBuildDate': '01.01.2020', - 'clientBranch': 'develop', - 'inputSource': 'sdr', - 'timestamp': '15:30', - 'frequency': '173.240', - 'mode': 'pocsag', - 'bitrate': '512', - 'ric': '1326089', - 'subric': '1', - 'subricText': 'a', - 'message': '17:22 FW 18865 Gebäudebrand_kle Sandkampstr.,15,-,Hopsten,NRW rauchentwicklung' -})) \ No newline at end of file From a12af18b544299236fcbb98e77c50f9a90d8f5df Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sat, 22 Feb 2020 22:53:03 +0100 Subject: [PATCH 07/19] resolve threads (: --- docu/docs/modul/geocoding.md | 2 +- docu/docs/plugin/telegram.md | 4 +++- module/geocoding.py | 17 ++++++++--------- plugin/telegram.py | 15 ++++++++------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md index ca939ea..5876f08 100644 --- a/docu/docs/modul/geocoding.md +++ b/docu/docs/modul/geocoding.md @@ -45,7 +45,7 @@ geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| --- ## Paket Modifikationen -- Im Paket werden die Felder `lat` und `lng` hinterlegt +- Im Paket werden die Felder `lat` und `lon` hinterlegt --- ## Zusätzliche Wildcards diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md index d6afdfb..d72a84e 100644 --- a/docu/docs/plugin/telegram.md +++ b/docu/docs/plugin/telegram.md @@ -2,7 +2,9 @@ --- ## Beschreibung -Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. Außerdem werden Locations versenden, wenn die Felder `lat` und `lng` im Paket definiert sind. +Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. +Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das Geocoding-Modul) + ## Unterstütze Alarmtypen - Pocsag diff --git a/module/geocoding.py b/module/geocoding.py index b2bbb5c..765bafc 100644 --- a/module/geocoding.py +++ b/module/geocoding.py @@ -10,7 +10,7 @@ by Bastian Schroll @file: geocoding.py -@date: 01.03.2019 +@date: 22.02.2020 @author: Jan Speller @description: Geocoding Module """ @@ -38,7 +38,6 @@ class BoswatchModule(ModuleBase): @param bwPacket: A BOSWatch packet instance""" if bwPacket.get("mode") == "pocsag": self.geocode(bwPacket) - pass return bwPacket @@ -49,24 +48,24 @@ class BoswatchModule(ModuleBase): try: address = re.search(self.config.get("regex"), bwPacket.get("message"))[1] provider = self.config.get("apiProvider") + + logging.info("Found address: '" + address + "' in packet") if "mapbox" == provider: + logging.info("Using Mapbox as provider") g = geocoder.mapbox(address, key=self.config.get("apiToken")) - print(address) elif "google" == provider: + logging.info("Using Google as provider") g = geocoder.google(address, key=self.config.get("apiToken")) else: return bwPacket - (lat, lng) = g.latlng + (lat, lon) = g.latlng + logging.info("Found following coordinates for address: [lat=" + str(lat) + ", lon=" + str(lon) + "]") bwPacket.set("lat", lat) - bwPacket.set("lng", lng) + bwPacket.set("lon", lon) return bwPacket except (IndexError, TypeError, ValueError): logging.warning("Address was not found in current Message, skipping geocoding") except Exception as e: logging.error("Unknown Error while executing geocoding module: " + str(type(e).__name__) + ": " + str(e)) return bwPacket - - def onUnload(self): - """!Called by destruction of the plugin""" - pass diff --git a/plugin/telegram.py b/plugin/telegram.py index 3050afc..b27ce6d 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -36,24 +36,26 @@ class BoswatchPlugin(PluginBase): def onLoad(self): """!Called by import of the plugin""" self.bot = telegram.Bot(token=self.config.get("botToken", default="")) - pass def pocsag(self, bwPacket): """!Called on POCSAG alarm @param bwPacket: bwPacket instance""" msg = bwPacket.get("ric") + " (" + bwPacket.get("subric") + ")\n" + bwPacket.get("message") - if bwPacket.get("lat") is not None and bwPacket.get("lng") is not None: - (lat, lng) = (bwPacket.get("lat"), bwPacket.get("lng")) + if bwPacket.get("lat") is not None and bwPacket.get("lon") is not None: + logging.info("Found coordinates in packet") + (lat, lon) = (bwPacket.get("lat"), bwPacket.get("lon")) for chatId in self.config.get("chatIds", default=[]): try: # Send Message via Telegram + logging.info("Sending message to " + chatId) self.bot.send_message(chat_id=chatId, text=msg) - # Send Location via Telegram if lat and lng are defined - if lat is not None and lng is not None: - self.bot.sendLocation(chat_id=chatId, latitude=lat, longitude=lng) + # Send Location via Telegram if lat and lon are defined + if lat is not None and lon is not None: + logging.info("Sending location to " + chatId) + self.bot.sendLocation(chat_id=chatId, latitude=lat, longitude=lon) except Unauthorized: logging.error("Error while sending Telegram Message, please Check your api-key") except (TimedOut, NetworkError): @@ -62,4 +64,3 @@ class BoswatchPlugin(PluginBase): logging.error("Error while sending Telegram Message") except Exception as e: logging.error("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e)) - pass From cb64045f3200fc9ad8051635a02a155def6d7f60 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sat, 22 Feb 2020 23:47:13 +0100 Subject: [PATCH 08/19] fix wildcard replacement --- boswatch/wildcard.py | 62 +++++++++++++++++++++++--------------------- plugin/pluginBase.py | 2 +- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/boswatch/wildcard.py b/boswatch/wildcard.py index 71d1c42..91f2fea 100644 --- a/boswatch/wildcard.py +++ b/boswatch/wildcard.py @@ -52,51 +52,53 @@ def replaceWildcards(message, bwPacket): # info wildcards # server - "{SNAME}": bwPacket.getField("serverName"), - "{SVERS}": bwPacket.getField("serverVersion"), - "{SDATE}": bwPacket.getField("serverBuildDate"), - "{SBRCH}": bwPacket.getField("serverBranch"), + "{SNAME}": bwPacket.get("serverName"), + "{SVERS}": bwPacket.get("serverVersion"), + "{SDATE}": bwPacket.get("serverBuildDate"), + "{SBRCH}": bwPacket.get("serverBranch"), # client - "{CNAME}": bwPacket.getField("clientName"), - "{CIP}": bwPacket.getField("clientIP"), - "{CVERS}": bwPacket.getField("clientVersion"), - "{CDATE}": bwPacket.getField("clientBuildDate"), - "{CBRCH}": bwPacket.getField("clientBranch"), + "{CNAME}": bwPacket.get("clientName"), + "{CIP}": bwPacket.get("clientIP"), + "{CVERS}": bwPacket.get("clientVersion"), + "{CDATE}": bwPacket.get("clientBuildDate"), + "{CBRCH}": bwPacket.get("clientBranch"), # boswatch wildcards - "{INSRC}": bwPacket.getField("mode"), - "{TIMES}": bwPacket.getField("mode"), - "{FREQ}": bwPacket.getField("frequency"), - "{MODE}": bwPacket.getField("mode"), + "{INSRC}": bwPacket.get("mode"), + "{TIMES}": bwPacket.get("mode"), + "{FREQ}": bwPacket.get("frequency"), + "{MODE}": bwPacket.get("mode"), # fms wildcards - "{FMS}": bwPacket.getField("fms"), - "{SERV}": bwPacket.getField("service"), - "{COUNT}": bwPacket.getField("country"), - "{LOC}": bwPacket.getField("location"), - "{VEHC}": bwPacket.getField("vehicle"), - "{STAT}": bwPacket.getField("status"), - "{DIR}": bwPacket.getField("direction"), - "{DIRT}": bwPacket.getField("dirextionText"), - "{TACI}": bwPacket.getField("tacticalInfo"), + "{FMS}": bwPacket.get("fms"), + "{SERV}": bwPacket.get("service"), + "{COUNT}": bwPacket.get("country"), + "{LOC}": bwPacket.get("location"), + "{VEHC}": bwPacket.get("vehicle"), + "{STAT}": bwPacket.get("status"), + "{DIR}": bwPacket.get("direction"), + "{DIRT}": bwPacket.get("dirextionText"), + "{TACI}": bwPacket.get("tacticalInfo"), # pocsag wildcards - "{BIT}": bwPacket.getField("bitrate"), - "{RIC}": bwPacket.getField("ric"), - "{SRIC}": bwPacket.getField("subric"), - "{SRICT}": bwPacket.getField("subricText"), - "{MSG}": bwPacket.getField("message"), + "{BIT}": bwPacket.get("bitrate"), + "{RIC}": bwPacket.get("ric"), + "{SRIC}": bwPacket.get("subric"), + "{SRICT}": bwPacket.get("subricText"), + "{MSG}": bwPacket.get("message"), # zvei wildcards - "{TONE}": bwPacket.getField("tone"), + "{TONE}": bwPacket.get("tone"), # message for MSG packet is done in poc } for wildcard, field in _wildcards.items(): - message = message.replace(wildcard, field) + if field is not None: + message = message.replace(wildcard, field) for wildcard, field in _additionalWildcards.items(): - message = message.replace(wildcard, bwPacket.getField(field)) + if field is not None: + message = message.replace(wildcard, bwPacket.getField(field)) return message diff --git a/plugin/pluginBase.py b/plugin/pluginBase.py index 5785d69..e26a54b 100644 --- a/plugin/pluginBase.py +++ b/plugin/pluginBase.py @@ -189,4 +189,4 @@ class PluginBase(ABC): if self._bwPacket is None: logging.warning("wildcard replacing not allowed - no bwPacket set") return msg - return wildcard.replaceWildcards(self._bwPacket, msg) + return wildcard.replaceWildcards(msg, self._bwPacket) From 51b1b3e13e61d1fb9486ab2bee55ebcb2dd9387e Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sun, 23 Feb 2020 01:07:10 +0100 Subject: [PATCH 09/19] add http plugin --- plugin/http.py | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 plugin/http.py diff --git a/plugin/http.py b/plugin/http.py new file mode 100644 index 0000000..cacc0e0 --- /dev/null +++ b/plugin/http.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: http.py +@date: 23.02.2020 +@author: Jan Speller +@description: Http Plugin +""" +import logging +from plugin.pluginBase import PluginBase + +# ###################### # +# Custom plugin includes # +import asyncio +from aiohttp import ClientSession +# ###################### # + +logging.debug("- %s loaded", __name__) + + +class BoswatchPlugin(PluginBase): + """!Description of the Plugin""" + def __init__(self, config): + """!Do not change anything here!""" + super().__init__(__name__, config) # you can access the config class on 'self.config' + + async def fetch(self, url, session): + """Fetches requests + + @param url: url + + @param session: Clientsession instance""" + async with session.get(url) as response: + logging.info("{} returned [{}]".format(response.url, response.status)) + return await response.read() + + async def asyncRequests(self, urls): + """Handles asynchronus requests + + @param urls: array of urls to send requests to""" + tasks = [] + + async with ClientSession() as session: + for url in urls: + task = asyncio.ensure_future(self.fetch(url, session)) + tasks.append(task) + + responses = asyncio.gather(*tasks) + await responses + + def makeRequests(self, urls): + """Parses wildcard urls and handles asynchronus requests + + @param urls: array of urls""" + urls = [self.parseWildcards(url) for url in urls] + + loop = asyncio.get_event_loop() + + future = asyncio.ensure_future(self.asyncRequests(urls)) + loop.run_until_complete(future) + + def fms(self, bwPacket): + """!Called on FMS alarm + + @param bwPacket: bwPacket instance + Remove if not implemented""" + urls = self.config.get("fms") + self.makeRequests(urls) + + def pocsag(self, bwPacket): + """!Called on POCSAG alarm + + @param bwPacket: bwPacket instance + Remove if not implemented""" + urls = self.config.get("pocsag") + self.makeRequests(urls) + + def zvei(self, bwPacket): + """!Called on ZVEI alarm + + @param bwPacket: bwPacket instance + Remove if not implemented""" + urls = self.config.get("zvei") + self.makeRequests(urls) + + def msg(self, bwPacket): + """!Called on MSG packet + + @param bwPacket: bwPacket instance + Remove if not implemented""" + urls = self.config.get("msg") + self.makeRequests(urls) From bf52816c17908048ec14e4a0941d3bb1d5ded343 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sun, 23 Feb 2020 01:16:02 +0100 Subject: [PATCH 10/19] Add docu --- docu/docs/plugin/http.md | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docu/docs/plugin/http.md diff --git a/docu/docs/plugin/http.md b/docu/docs/plugin/http.md new file mode 100644 index 0000000..e4c1411 --- /dev/null +++ b/docu/docs/plugin/http.md @@ -0,0 +1,53 @@ +#
Http
+--- + +## Beschreibung +Mit diesem Plugin ist es moeglich, Http-Anfragen für Alarmierungen zu senden. +Wildcards in den Urls werden automatisch ersetzt. + +## Unterstütze Alarmtypen +- Fms +- Pocsag +- Zvei +- Msg + +## Resource +`http` + +## Konfiguration + +|Feld|Beschreibung|Default| +|----|------------|-------| +|fms|Liste mit Urls für Fms-Alarmierung|| +|pocsag|Liste mit Urls für Pocsag-Alarmierung|| +|zvei|Liste mit Urls für Zvei-Alarmierung|| +|msg|Liste mit Urls für Msg-Alarmierung|| + +**Beispiel:** +```yaml + - type: plugin + name: HTTP Plugin + res: http + config: + pocsag: + - "http://google.com?q={MSG}" + - "http://duckduckgo.com?q={MSG}" + fms: + - "http://duckduckgo.com?q={LOC}" +``` + +--- +## Abhängigkeiten + +- asyncio +- aiohttp + +--- +## Paket Modifikationen + +- keine + +--- +## Zusätzliche Wildcards + +- keine \ No newline at end of file From 1c052458671db82d67eef94355ad6add3420f283 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Sun, 23 Feb 2020 01:17:26 +0100 Subject: [PATCH 11/19] add http to mkdocs --- docu/mkdocs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docu/mkdocs.yml b/docu/mkdocs.yml index 0948dd6..611cbfe 100644 --- a/docu/mkdocs.yml +++ b/docu/mkdocs.yml @@ -21,7 +21,8 @@ nav: - Mode Filter: modul/mode_filter.md - Regex Filter: modul/regex_filter.md - Descriptor: modul/descriptor.md - - Plugins: tbd.md + - Plugins: + - Http: plugin/http.md - Entwickler: - Eigenes Modul/Plugin schreiben: develop/ModulPlugin.md - BOSWatch Alarmpaket Format: develop/packet.md From 4b0614c7dacd7d8e8f0be1c4cb96cbae5ee12579 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Mon, 24 Feb 2020 21:51:19 +0100 Subject: [PATCH 12/19] threads and a few fixes to wildcards --- boswatch/wildcard.py | 8 ++++---- docu/docs/develop/packet.md | 2 +- docu/docs/modul/geocoding.md | 5 +++-- docu/docs/plugin/telegram.md | 12 ++---------- module/geocoding.py | 15 ++++++++++++--- plugin/telegram.py | 4 ++-- 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/boswatch/wildcard.py b/boswatch/wildcard.py index 91f2fea..3519502 100644 --- a/boswatch/wildcard.py +++ b/boswatch/wildcard.py @@ -65,8 +65,8 @@ def replaceWildcards(message, bwPacket): "{CBRCH}": bwPacket.get("clientBranch"), # boswatch wildcards - "{INSRC}": bwPacket.get("mode"), - "{TIMES}": bwPacket.get("mode"), + "{INSRC}": bwPacket.get("inputSource"), + "{TIMES}": bwPacket.get("timestamp"), "{FREQ}": bwPacket.get("frequency"), "{MODE}": bwPacket.get("mode"), @@ -78,7 +78,7 @@ def replaceWildcards(message, bwPacket): "{VEHC}": bwPacket.get("vehicle"), "{STAT}": bwPacket.get("status"), "{DIR}": bwPacket.get("direction"), - "{DIRT}": bwPacket.get("dirextionText"), + "{DIRT}": bwPacket.get("directionText"), "{TACI}": bwPacket.get("tacticalInfo"), # pocsag wildcards @@ -99,6 +99,6 @@ def replaceWildcards(message, bwPacket): for wildcard, field in _additionalWildcards.items(): if field is not None: - message = message.replace(wildcard, bwPacket.getField(field)) + message = message.replace(wildcard, bwPacket.get(field)) return message diff --git a/docu/docs/develop/packet.md b/docu/docs/develop/packet.md index 14d2e88..e67de83 100644 --- a/docu/docs/develop/packet.md +++ b/docu/docs/develop/packet.md @@ -47,5 +47,5 @@ Ein BOSWatch Datenpaket wird in einem Python Dict abgebildet. In der nachfolgend |vehicle|X||||`{VEC}`|| |status|X||||`{STAT}`|| |direction|X||||`{DIR}`|| -|dirextionText|X||||`{DIRT}`|(Fhz->Lst, Lst->Fhz)| +|directionText|X||||`{DIRT}`|(Fhz->Lst, Lst->Fhz)| |tacticalInfo|X||||`{TACI}`|(I, II, III, IV)| diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md index 5876f08..eb69eff 100644 --- a/docu/docs/modul/geocoding.md +++ b/docu/docs/modul/geocoding.md @@ -40,7 +40,6 @@ geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| ## Abhängigkeiten - geocoder -- re --- ## Paket Modifikationen @@ -50,4 +49,6 @@ geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| --- ## Zusätzliche Wildcards -- keine \ No newline at end of file +- `{ADDRESS}`: gefundene Adresse +- `{LAT}`: Latitude der Adresse +- `{LON}`: Longitude der Adresse \ No newline at end of file diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md index d72a84e..2273cc5 100644 --- a/docu/docs/plugin/telegram.md +++ b/docu/docs/plugin/telegram.md @@ -16,6 +16,7 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d |Feld|Beschreibung|Default| |----|------------|-------| +|message|Format der Nachricht|| |botToken|Der Api-Key des Telegram-Bots|| |chatIds|Liste mit Chat-Ids der Empfängers / der Emfänger-Gruppen|| @@ -25,6 +26,7 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d name: Telegram Plugin res: telegram config: + message: "{RIC}({SRIC})\n{MSG}" botToken: "{{ Telegram Bot Token }}" chatIds: - "{{ Telegram Chat Id }}" @@ -34,13 +36,3 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d ## Abhängigkeiten - python-telegram-bot - ---- -## Paket Modifikationen - -- keine - ---- -## Zusätzliche Wildcards - -- keine diff --git a/module/geocoding.py b/module/geocoding.py index 765bafc..c6cb8c5 100644 --- a/module/geocoding.py +++ b/module/geocoding.py @@ -46,10 +46,18 @@ class BoswatchModule(ModuleBase): @param bwPacket: A BOSWatch packet instance""" try: - address = re.search(self.config.get("regex"), bwPacket.get("message"))[1] + addressArray = re.search(self.config.get("regex"), bwPacket.get("message")) provider = self.config.get("apiProvider") + if addressArray[1] is None: + logging.warning("Address was not found in current Message, skipping geocoding") + return bwPacket + + address = addressArray[1] + bwPacket.set("address", address) + self.registerWildcard("{ADDRESS}", "address") logging.info("Found address: '" + address + "' in packet") + if "mapbox" == provider: logging.info("Using Mapbox as provider") g = geocoder.mapbox(address, key=self.config.get("apiToken")) @@ -63,9 +71,10 @@ class BoswatchModule(ModuleBase): logging.info("Found following coordinates for address: [lat=" + str(lat) + ", lon=" + str(lon) + "]") bwPacket.set("lat", lat) bwPacket.set("lon", lon) + self.registerWildcard("{LAT}", "lat") + self.registerWildcard("{LON}", "lon") + return bwPacket - except (IndexError, TypeError, ValueError): - logging.warning("Address was not found in current Message, skipping geocoding") except Exception as e: logging.error("Unknown Error while executing geocoding module: " + str(type(e).__name__) + ": " + str(e)) return bwPacket diff --git a/plugin/telegram.py b/plugin/telegram.py index b27ce6d..b37ebf5 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -41,9 +41,9 @@ class BoswatchPlugin(PluginBase): """!Called on POCSAG alarm @param bwPacket: bwPacket instance""" - msg = bwPacket.get("ric") + " (" + bwPacket.get("subric") + ")\n" + bwPacket.get("message") + msg = self.parseWildcards(self.config.get("message")) if bwPacket.get("lat") is not None and bwPacket.get("lon") is not None: - logging.info("Found coordinates in packet") + logging.debug("Found coordinates in packet") (lat, lon) = (bwPacket.get("lat"), bwPacket.get("lon")) for chatId in self.config.get("chatIds", default=[]): From e5d11b74afd2af3122589fc60fceb1c70a44c14d Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Mon, 24 Feb 2020 22:07:23 +0100 Subject: [PATCH 13/19] threads --- docu/docs/modul/geocoding.md | 4 +++- module/geocoding.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md index eb69eff..8f7d1f5 100644 --- a/docu/docs/modul/geocoding.md +++ b/docu/docs/modul/geocoding.md @@ -44,7 +44,9 @@ geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| --- ## Paket Modifikationen -- Im Paket werden die Felder `lat` und `lon` hinterlegt +- `address`: gefundene Adresse +- `lat`: Latitude der Adresse +- `lon`: Longitude der Adresse --- ## Zusätzliche Wildcards diff --git a/module/geocoding.py b/module/geocoding.py index c6cb8c5..c8e2f3c 100644 --- a/module/geocoding.py +++ b/module/geocoding.py @@ -50,7 +50,7 @@ class BoswatchModule(ModuleBase): provider = self.config.get("apiProvider") if addressArray[1] is None: - logging.warning("Address was not found in current Message, skipping geocoding") + logging.info("No address found, skipping geocoding") return bwPacket address = addressArray[1] From 9fb7fe9ea5dd436b1ae7f324319af23b8b8cb924 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Mon, 24 Feb 2020 22:15:28 +0100 Subject: [PATCH 14/19] threads --- docu/docs/modul/geocoding.md | 7 +++++-- docu/docs/plugin/telegram.md | 4 +++- module/geocoding.py | 2 +- plugin/telegram.py | 8 ++++---- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md index 8f7d1f5..0acf43e 100644 --- a/docu/docs/modul/geocoding.md +++ b/docu/docs/modul/geocoding.md @@ -4,8 +4,11 @@ ## Beschreibung Mit diesem Modul können einem Paket die Koordinaten eines Ortes oder einer Adresse angefügt werden. +## Externe Abhängigkeiten +- geocoder + ## Unterstützte Alarmtypen - - Pocsag +- Pocsag ## Resource `geocoding` @@ -39,7 +42,7 @@ geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| --- ## Abhängigkeiten -- geocoder +- keine --- ## Paket Modifikationen diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md index 2273cc5..cad7821 100644 --- a/docu/docs/plugin/telegram.md +++ b/docu/docs/plugin/telegram.md @@ -5,6 +5,8 @@ Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das Geocoding-Modul) +## Externe Abhängigkeiten +- python-telegram-bot ## Unterstütze Alarmtypen - Pocsag @@ -35,4 +37,4 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d --- ## Abhängigkeiten -- python-telegram-bot +- keine diff --git a/module/geocoding.py b/module/geocoding.py index c8e2f3c..572bc0d 100644 --- a/module/geocoding.py +++ b/module/geocoding.py @@ -76,5 +76,5 @@ class BoswatchModule(ModuleBase): return bwPacket except Exception as e: - logging.error("Unknown Error while executing geocoding module: " + str(type(e).__name__) + ": " + str(e)) + logging.exception("Unknown Error while executing geocoding module: " + str(type(e).__name__) + ": " + str(e)) return bwPacket diff --git a/plugin/telegram.py b/plugin/telegram.py index b37ebf5..80ff9e7 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -57,10 +57,10 @@ class BoswatchPlugin(PluginBase): logging.info("Sending location to " + chatId) self.bot.sendLocation(chat_id=chatId, latitude=lat, longitude=lon) except Unauthorized: - logging.error("Error while sending Telegram Message, please Check your api-key") + logging.exception("Error while sending Telegram Message, please Check your api-key") except (TimedOut, NetworkError): - logging.error("Error while sending Telegram Message, please Check your connectivity") + logging.exception("Error while sending Telegram Message, please Check your connectivity") except (BadRequest, TelegramError): - logging.error("Error while sending Telegram Message") + logging.exception("Error while sending Telegram Message") except Exception as e: - logging.error("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e)) + logging.exception("Unknown Error while sending Telegram Message: " + str(type(e).__name__) + ": " + str(e)) From 4d9bf5b126bcb85d4d59a492727b1f3576d387bd Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Mon, 24 Feb 2020 22:35:30 +0100 Subject: [PATCH 15/19] threads --- docu/docs/plugin/telegram.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md index cad7821..3003bbe 100644 --- a/docu/docs/plugin/telegram.md +++ b/docu/docs/plugin/telegram.md @@ -37,4 +37,6 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d --- ## Abhängigkeiten -- keine +- Modul geocoding (Falls in Paket vorhanden): + - `lat` + - `lon` From ded21160097786a0ecb39fec975e9bd9ce93386c Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Mon, 24 Feb 2020 22:47:40 +0100 Subject: [PATCH 16/19] move methods to bottom --- plugin/http.py | 70 +++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/plugin/http.py b/plugin/http.py index cacc0e0..5d206bc 100644 --- a/plugin/http.py +++ b/plugin/http.py @@ -32,41 +32,6 @@ class BoswatchPlugin(PluginBase): """!Do not change anything here!""" super().__init__(__name__, config) # you can access the config class on 'self.config' - async def fetch(self, url, session): - """Fetches requests - - @param url: url - - @param session: Clientsession instance""" - async with session.get(url) as response: - logging.info("{} returned [{}]".format(response.url, response.status)) - return await response.read() - - async def asyncRequests(self, urls): - """Handles asynchronus requests - - @param urls: array of urls to send requests to""" - tasks = [] - - async with ClientSession() as session: - for url in urls: - task = asyncio.ensure_future(self.fetch(url, session)) - tasks.append(task) - - responses = asyncio.gather(*tasks) - await responses - - def makeRequests(self, urls): - """Parses wildcard urls and handles asynchronus requests - - @param urls: array of urls""" - urls = [self.parseWildcards(url) for url in urls] - - loop = asyncio.get_event_loop() - - future = asyncio.ensure_future(self.asyncRequests(urls)) - loop.run_until_complete(future) - def fms(self, bwPacket): """!Called on FMS alarm @@ -98,3 +63,38 @@ class BoswatchPlugin(PluginBase): Remove if not implemented""" urls = self.config.get("msg") self.makeRequests(urls) + + def makeRequests(self, urls): + """Parses wildcard urls and handles asynchronus requests + + @param urls: array of urls""" + urls = [self.parseWildcards(url) for url in urls] + + loop = asyncio.get_event_loop() + + future = asyncio.ensure_future(self.asyncRequests(urls)) + loop.run_until_complete(future) + + async def asyncRequests(self, urls): + """Handles asynchronus requests + + @param urls: array of urls to send requests to""" + tasks = [] + + async with ClientSession() as session: + for url in urls: + task = asyncio.ensure_future(self.fetch(url, session)) + tasks.append(task) + + responses = asyncio.gather(*tasks) + await responses + + async def fetch(self, url, session): + """Fetches requests + + @param url: url + + @param session: Clientsession instance""" + async with session.get(url) as response: + logging.info("{} returned [{}]".format(response.url, response.status)) + return await response.read() From 0ba3f5ca3be09cef00930e97327557e533fcf8b3 Mon Sep 17 00:00:00 2001 From: Jan Speller Date: Mon, 24 Feb 2020 22:55:16 +0100 Subject: [PATCH 17/19] Update http documentation --- docu/docs/plugin/http.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/docu/docs/plugin/http.md b/docu/docs/plugin/http.md index e4c1411..f9051bf 100644 --- a/docu/docs/plugin/http.md +++ b/docu/docs/plugin/http.md @@ -5,6 +5,10 @@ Mit diesem Plugin ist es moeglich, Http-Anfragen für Alarmierungen zu senden. Wildcards in den Urls werden automatisch ersetzt. +## Externe Abhängigkeiten +- asyncio +- aiohttp + ## Unterstütze Alarmtypen - Fms - Pocsag @@ -39,15 +43,4 @@ Wildcards in den Urls werden automatisch ersetzt. --- ## Abhängigkeiten -- asyncio -- aiohttp - ---- -## Paket Modifikationen - - keine - ---- -## Zusätzliche Wildcards - -- keine \ No newline at end of file From 62f3f1aff1a906c52f618a97c014d6d39eeb6e74 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Mon, 24 Feb 2020 23:38:13 +0100 Subject: [PATCH 18/19] some docu edits --- docu/docs/modul/descriptor.md | 17 +++++++++++------ docu/docs/modul/geocoding.md | 14 +++++--------- docu/docs/modul/mode_filter.md | 15 +++++++++++---- docu/docs/modul/regex_filter.md | 17 +++++++++++------ docu/docs/plugin/http.md | 13 ++++++------- docu/docs/plugin/telegram.md | 17 +++++++++-------- docu/mkdocs.yml | 2 +- 7 files changed, 54 insertions(+), 41 deletions(-) diff --git a/docu/docs/modul/descriptor.md b/docu/docs/modul/descriptor.md index dd53b5d..a472b0f 100644 --- a/docu/docs/modul/descriptor.md +++ b/docu/docs/modul/descriptor.md @@ -4,11 +4,16 @@ ## Beschreibung Mit diesem Modul können einem Alarmpaket beliebige Beschreibungen in Abhänigkeit der enthaltenen Informationen hinzugefügt werden. +## Unterstütze Alarmtypen +- Fms +- Pocsag +- Zvei +- Msg + ## Resource `descriptor` ## Konfiguration - Informationen zum Aufbau eines [BOSWatch Pakets](../develop/packet.md) |Feld|Beschreibung|Default| @@ -19,7 +24,6 @@ Informationen zum Aufbau eines [BOSWatch Pakets](../develop/packet.md) |descriptions|Liste der Beschreibungen|| #### `descriptions:` - |Feld|Beschreibung|Default| |----|------------|-------| |for|Inhalt im `scanField` auf welchem geprüft werden soll|| @@ -50,17 +54,18 @@ Informationen zum Aufbau eines [BOSWatch Pakets](../develop/packet.md) ``` --- -## Abhängigkeiten +## Modul Abhängigkeiten +- keine +--- +## Externe Abhängigkeiten - keine --- ## Paket Modifikationen - - Wenn im Paket das Feld `scanField` vorhanden ist, wird das Feld `descrField` dem Paket hinzugefügt - Wenn keine Beschreibung vorhanden ist, wird im Feld `descrField` der Inhalt des Feldes `scanField` hinterlegt --- ## Zusätzliche Wildcards - -- Von der Konfiguration abhängig \ No newline at end of file +- Von der Konfiguration abhängig diff --git a/docu/docs/modul/geocoding.md b/docu/docs/modul/geocoding.md index 0acf43e..f2e69d7 100644 --- a/docu/docs/modul/geocoding.md +++ b/docu/docs/modul/geocoding.md @@ -4,9 +4,6 @@ ## Beschreibung Mit diesem Modul können einem Paket die Koordinaten eines Ortes oder einer Adresse angefügt werden. -## Externe Abhängigkeiten -- geocoder - ## Unterstützte Alarmtypen - Pocsag @@ -14,7 +11,6 @@ Mit diesem Modul können einem Paket die Koordinaten eines Ortes oder einer Adre `geocoding` ## Konfiguration - |Feld|Beschreibung|Default| |----|------------|-------| apiProvider|Der Provider für das Geocoding| @@ -22,7 +18,6 @@ apiToken|Der Api-Token fuer die Geocoding-Api| geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| #### Verfügbare Geocoding Provider - |Name|Einstellungswert| |----|------------| |Mapbox|mapbox| @@ -40,20 +35,21 @@ geoRegex|Regex Capture-Group zum Herausfiltern der Adresse| ``` --- -## Abhängigkeiten - +## Modul Abhängigkeiten - keine --- -## Paket Modifikationen +## Externe Abhängigkeiten +- geocoder +--- +## Paket Modifikationen - `address`: gefundene Adresse - `lat`: Latitude der Adresse - `lon`: Longitude der Adresse --- ## Zusätzliche Wildcards - - `{ADDRESS}`: gefundene Adresse - `{LAT}`: Latitude der Adresse - `{LON}`: Longitude der Adresse \ No newline at end of file diff --git a/docu/docs/modul/mode_filter.md b/docu/docs/modul/mode_filter.md index f805835..e016003 100644 --- a/docu/docs/modul/mode_filter.md +++ b/docu/docs/modul/mode_filter.md @@ -4,11 +4,16 @@ ## Beschreibung Mit diesem Modul ist es möglich, die Pakete auf bestimmte Modes (FMS, POCSAG, ZVEI) zu Filtern. Je nach Konfiguration werden Pakete eines bestimmten Modes im aktuellen Router weitergeleitet oder verworfen. +## Unterstütze Alarmtypen +- Fms +- Pocsag +- Zvei +- Msg + ## Resource `filter.modeFilter` ## Konfiguration - |Feld|Beschreibung|Default| |----|------------|-------| |allowed|Liste der erlaubten Paket Typen `fms` `zvei` `pocsag` `msg`|| @@ -24,16 +29,18 @@ Mit diesem Modul ist es möglich, die Pakete auf bestimmte Modes (FMS, POCSAG, Z ``` --- -## Abhängigkeiten +## Modul Abhängigkeiten +- keine +--- +## Externe Abhängigkeiten - keine --- ## Paket Modifikationen - - keine --- ## Zusätzliche Wildcards - - keine + diff --git a/docu/docs/modul/regex_filter.md b/docu/docs/modul/regex_filter.md index f554452..77e0a1d 100644 --- a/docu/docs/modul/regex_filter.md +++ b/docu/docs/modul/regex_filter.md @@ -15,18 +15,22 @@ Folgendes gilt: Vereinfacht kann man sagen, dass einzelnen Router ODER-verknüpft und die jeweiligen Checks UND-verknüpft sind. +## Unterstütze Alarmtypen +- Fms +- Pocsag +- Zvei +- Msg + ## Resource `filter.regexFilter` ## Konfiguration - |Feld|Beschreibung|Default| |----|------------|-------| |name|Beliebiger Name des Filters|| |checks|Liste der einzelnen Checks innerhalb des Filters|| #### `checks:` - |Feld|Beschreibung|Default| |----|------------|-------| |field|Name des Feldes innerhalb des BOSWatch Pakets welches untersucht werden soll|| @@ -50,16 +54,17 @@ Vereinfacht kann man sagen, dass einzelnen Router ODER-verknüpft und die jeweil ``` --- -## Abhängigkeiten +## Modul Abhängigkeiten +- keine +--- +## Externe Abhängigkeiten - keine --- ## Paket Modifikationen - - keine --- ## Zusätzliche Wildcards - -- keine +- keine \ No newline at end of file diff --git a/docu/docs/plugin/http.md b/docu/docs/plugin/http.md index f9051bf..82f5a9f 100644 --- a/docu/docs/plugin/http.md +++ b/docu/docs/plugin/http.md @@ -5,10 +5,6 @@ Mit diesem Plugin ist es moeglich, Http-Anfragen für Alarmierungen zu senden. Wildcards in den Urls werden automatisch ersetzt. -## Externe Abhängigkeiten -- asyncio -- aiohttp - ## Unterstütze Alarmtypen - Fms - Pocsag @@ -19,7 +15,6 @@ Wildcards in den Urls werden automatisch ersetzt. `http` ## Konfiguration - |Feld|Beschreibung|Default| |----|------------|-------| |fms|Liste mit Urls für Fms-Alarmierung|| @@ -41,6 +36,10 @@ Wildcards in den Urls werden automatisch ersetzt. ``` --- -## Abhängigkeiten - +## Modul Abhängigkeiten - keine + +--- +## Externe Abhängigkeiten +- asyncio +- aiohttp diff --git a/docu/docs/plugin/telegram.md b/docu/docs/plugin/telegram.md index 3003bbe..1eb5a01 100644 --- a/docu/docs/plugin/telegram.md +++ b/docu/docs/plugin/telegram.md @@ -3,10 +3,7 @@ ## Beschreibung Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden. -Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das Geocoding-Modul) - -## Externe Abhängigkeiten -- python-telegram-bot +Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das [Geocoding](../modul/geocoding.md) Modul) ## Unterstütze Alarmtypen - Pocsag @@ -35,8 +32,12 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d ``` --- -## Abhängigkeiten +## Modul Abhängigkeiten +Aus dem Modul [Geocoding](../modul/geocoding.md) (optional): -- Modul geocoding (Falls in Paket vorhanden): - - `lat` - - `lon` +- `lat` +- `lon` + +--- +## Externe Abhängigkeiten +- python-telegram-bot diff --git a/docu/mkdocs.yml b/docu/mkdocs.yml index 2a9d54b..df708b9 100644 --- a/docu/mkdocs.yml +++ b/docu/mkdocs.yml @@ -18,7 +18,7 @@ nav: - Routing Mechanismus: information/router.md - Changelog: changelog.md - Module: - - Descriptor: modul/descriptor.md + - Descriptor: modul/descriptor.md - Geocoding: modul/geocoding.md - Mode Filter: modul/mode_filter.md - Regex Filter: modul/regex_filter.md From 40d7a33a026637c97f7b91c044381ae182629ad8 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Mon, 24 Feb 2020 23:52:20 +0100 Subject: [PATCH 19/19] fix some pep8 errors --- plugin/telegram.py | 4 ++-- pytest.sh | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 pytest.sh diff --git a/plugin/telegram.py b/plugin/telegram.py index 80ff9e7..5dea41f 100644 --- a/plugin/telegram.py +++ b/plugin/telegram.py @@ -45,13 +45,13 @@ class BoswatchPlugin(PluginBase): if bwPacket.get("lat") is not None and bwPacket.get("lon") is not None: logging.debug("Found coordinates in packet") (lat, lon) = (bwPacket.get("lat"), bwPacket.get("lon")) - + for chatId in self.config.get("chatIds", default=[]): try: # Send Message via Telegram logging.info("Sending message to " + chatId) self.bot.send_message(chat_id=chatId, text=msg) - + # Send Location via Telegram if lat and lon are defined if lat is not None and lon is not None: logging.info("Sending location to " + chatId) diff --git a/pytest.sh b/pytest.sh new file mode 100644 index 0000000..2a06d75 --- /dev/null +++ b/pytest.sh @@ -0,0 +1,3 @@ +source ./venv/bin/activate +pytest -c test/pytest.ini +deactivate \ No newline at end of file