diff --git a/notification.py b/notification.py index 6051474..a60ef95 100644 --- a/notification.py +++ b/notification.py @@ -5,6 +5,8 @@ import requests import time import click +from tenacity import retry +from tenacity import stop_after_attempt, wait_exponential log.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s', datefmt='%d-%m-%Y:%H:%M:%S', level=log.DEBUG) @@ -50,26 +52,23 @@ def query_low(self, port_id_list, threshold): result = self.cursor.fetchall() return result + @retry(stop=stop_after_attempt(2), wait=wait_exponential(multiplier=1, min=1, max=32)) def send_msg(self, date, port_id, tide_type, tide_time, tide_timezone, height): location = self.get_location_name(port_id) - sent = False - cnt = 0 + day_of_week = datetime.strptime(date, '%Y-%m-%d').strftime('%A') message = f'Spring {tide_type} tide {height}m at {location}: \n' + \ - f'on: {date} at {tide_time} ({tide_timezone})' + f'on: {date} ({day_of_week}) at {tide_time} ({tide_timezone})' log.info(f"message = {message}") - while not sent: + + try: r = requests.post(self.config['DEFAULT']['Webhook'], json={'text': message}) - cnt += 1 - if not (r.status_code == 200 and r.reason == 'OK'): - log.debug(f"HTTP POST failed: {r.status_code} {r.reason}") - if cnt > 10: - log.debug(f"failed {cnt} times, quitting") - break - time.sleep(min(300, 2**cnt)) - else: - log.debug(f"HTTP POST successful: {r.status_code} {r.reason}") - sent = True + + if r.status_code == 403 and r.text == 'invalid_token': + log.error(f"Invalid token, please check your slack webhook url") + exit(-1) + except (requests.exceptions.ConnectionError, requests.exceptions.RetryError) as e: + raise e @click.command() @@ -78,9 +77,9 @@ def send_msg(self, date, port_id, tide_type, tide_time, tide_timezone, height): @click.option('-p', '--port-id', multiple=True, help='port-ids to monitor') @click.option('-t', '--low-threshold', type=float, default=0.5, help='send notification when tide is lower than this') -def main(config_file, port_id, threshold): +def main(config_file, port_id, low_threshold): n = Notification(config_file) - r = n.query_low(port_id, threshold) + r = n.query_low(port_id, low_threshold) log.debug(f"{len(r)} record(s) found") for record in r: d = record[0] @@ -90,6 +89,7 @@ def main(config_file, port_id, threshold): tide_timezone = record[4] height = record[5] n.send_msg(d, port_id, tide_type, tide_time, tide_timezone, height) + log.debug(f"(re)try attempts: {n.send_msg.retry.statistics['attempt_number']}") if __name__ == '__main__': diff --git a/tide_time.py b/tide_time.py index 3a63a17..8d33389 100644 --- a/tide_time.py +++ b/tide_time.py @@ -35,7 +35,7 @@ def __init__(self, config_file, loging): with open(config_file) as f: self.config.read_file(f) except IOError as e: - log.error(f"config file {config_file} not found!") + self.logging.error(f"config file {config_file} not found!") raise e self.con = sqlite3.connect(self.config['DEFAULT']['Database']) self.cursor = self.con.cursor() @@ -105,6 +105,7 @@ def get_location_name(self, port_id): # retry 5 times in case of bad network connection @retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=1, max=32)) + @retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=1, max=32)) def parse_record(self, area_id, port_id): location_code = str(area_id) + '/' + port_id url = Tidal.BASE_URL + location_code