diff --git a/LastStateCrawler.py b/LastStateCrawler.py new file mode 100644 index 0000000..9960881 --- /dev/null +++ b/LastStateCrawler.py @@ -0,0 +1,51 @@ +import pymysql + + +def getWebsiteStates(conn: pymysql.Connection) -> dict: + # Get latest known states to check against + cur = conn.cursor() + + cur.execute(""" + WITH summary AS ( + SELECT web.website_id, + web.success, + ROW_NUMBER() OVER(PARTITION BY web.website_id + ORDER BY web.ping_id DESC) AS rk + FROM website_pings web) + SELECT s.* + FROM summary s + WHERE s.rk = 1; + """) + websiteStates = cur.fetchall() + cur.close() + + returnStates = {} + for site in websiteStates: + returnStates[site[0]] = (site[1] == 1) + + return returnStates + + +def getServerStates(conn: pymysql.Connection) -> dict: + # Get latest known states to check against + cur = conn.cursor() + + cur.execute(""" + WITH summary AS ( + SELECT srv.server_id, + srv.success, + ROW_NUMBER() OVER(PARTITION BY srv.server_id + ORDER BY srv.ping_id DESC) AS rk + FROM server_pings srv) + SELECT s.* + FROM summary s + WHERE s.rk = 1; + """) + serverStates = cur.fetchall() + cur.close() + + returnStates = {} + for server in serverStates: + returnStates[server[0]] = (server[1] == 1) + + return returnStates diff --git a/main.py b/main.py index fbcfbca..ccff7ae 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,7 @@ import ServerPingService import WebsitePingService import SQLConnectionHandler import TelegramHandler +import LastStateCrawler def runPings(): telegram = TelegramHandler.TelegramHandler() @@ -21,20 +22,37 @@ def runPings(): serverPingResults = [] websitePingResults = [] + websiteStates = LastStateCrawler.getWebsiteStates(conn) + serverStates = LastStateCrawler.getServerStates(conn) + for server in servers: ping = ServerPingService.ping(server['hostname']) + success = False if ping != -1: + # Ping successful, save success + success = True resTuple = (server['server_id'], True, ping) else: resTuple = (server['server_id'], False, ping) - telegram.sendMessage(users[server['admin_id']]['telegram_id'], ( - 'Your server {} ({}) is not reachable at the moment. Maybe give it a check.' - ).format(server['name'], server['hostname'])) serverPingResults.append(resTuple) + # Send Telegram message if state has changed + if success != serverStates[server['server_id']]: + # State has changed, send a message + if success: + telegram.sendMessage(users[server['admin_id']]['telegram_id'], ( + 'Your server {} ({}) is back online again!' + ).format(server['name'], server['hostname'])) + else: + telegram.sendMessage(users[server['admin_id']]['telegram_id'], ( + 'Your server {} ({}) is not reachable at the moment. Maybe give it a check.' + ).format(server['name'], server['hostname'])) + for website in websites: statusCode = WebsitePingService.ping(website['url']) + success = False if statusCode == 200: + success = True resTuple = (website['website_id'], True, statusCode) else: resTuple = (website['website_id'], False, statusCode) @@ -43,7 +61,20 @@ def runPings(): ).format(website['name'], website['url'], statusCode)) websitePingResults.append(resTuple) + # Send Telegram message if state has changed + if success != websiteStates[website['website_id']]: + # State has changed, send a message + if success: + telegram.sendMessage(users[website['admin_id']]['telegram_id'], ( + 'Your website {} ({}) is back online again!' + ).format(website['name'], website['url'])) + else: + telegram.sendMessage(users[website['admin_id']]['telegram_id'], ( + 'Your website {} ({}) is not reachable at the moment (Code {}). Maybe give it a check.' + ).format(website['name'], website['url'], statusCode)) + cur = conn.cursor() + # Insert server ping results cur.executemany('INSERT INTO server_pings (server_id, success, milliseconds) VALUES (%s, %s, %s)', serverPingResults)