From 26477530070dcc8e81d653fe6ec1ece6308e087a Mon Sep 17 00:00:00 2001 From: Jeremy Zhang Date: Tue, 13 Jun 2017 01:39:49 +0000 Subject: [PATCH] Show global header message when bot loses connection with server --- discordbot/titanembeds/bot.py | 12 ++++++++++++ discordbot/titanembeds/database/__init__.py | 14 ++++++++++++++ .../titanembeds/database/keyvalue_properties.py | 17 +++++++++++++++++ webapp/titanembeds/app.py | 7 ++++++- webapp/titanembeds/templates/embed.html.j2 | 2 ++ .../titanembeds/templates/nobot_header.html.j2 | 10 ++++++++++ .../titanembeds/templates/site_layout.html.j2 | 1 + webapp/titanembeds/utils.py | 17 ++++++++++++++++- 8 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 discordbot/titanembeds/database/keyvalue_properties.py create mode 100644 webapp/titanembeds/templates/nobot_header.html.j2 diff --git a/discordbot/titanembeds/bot.py b/discordbot/titanembeds/bot.py index 238842c..4bf6cc6 100644 --- a/discordbot/titanembeds/bot.py +++ b/discordbot/titanembeds/bot.py @@ -17,6 +17,9 @@ class Titan(discord.Client): self.http.user_agent += ' TitanEmbeds-Bot' self.database = DatabaseInterface(self) self.command = Commands(self, self.database) + + self.database_connected = False + self.loop.create_task(self.send_webserver_heartbeat()) def _cleanup(self): try: @@ -31,6 +34,14 @@ class Titan(discord.Client): gathered.exception() except: # Can be ignored pass + + async def send_webserver_heartbeat(self): + await self.wait_until_ready() + while not self.database_connected: + await asyncio.sleep(1) # Wait until db is connected + while not self.is_closed: + await self.database.send_webserver_heartbeat() + await asyncio.sleep(60) def run(self): try: @@ -57,6 +68,7 @@ class Titan(discord.Client): try: await self.database.connect(config["database-uri"] + "?charset=utf8mb4") + self.database_connected = True except Exception: self.logger.error("Unable to connect to specified database!") traceback.print_exc() diff --git a/discordbot/titanembeds/database/__init__.py b/discordbot/titanembeds/database/__init__.py index cd53bcd..2d2df33 100644 --- a/discordbot/titanembeds/database/__init__.py +++ b/discordbot/titanembeds/database/__init__.py @@ -7,6 +7,7 @@ from sqlalchemy.ext.declarative import declarative_base import json import discord +import time Base = declarative_base() @@ -15,6 +16,7 @@ from titanembeds.database.messages import Messages from titanembeds.database.guild_members import GuildMembers from titanembeds.database.unauthenticated_users import UnauthenticatedUsers from titanembeds.database.unauthenticated_bans import UnauthenticatedBans +from titanembeds.database.keyvalue_properties import KeyValueProperties class DatabaseInterface(object): # Courtesy of https://github.com/SunDwarf/Jokusoramame @@ -363,3 +365,15 @@ class DatabaseInterface(object): dbuser.revoked = True session.commit() return "Successfully kicked **{}#{}**!".format(dbuser.username, dbuser.discriminator) + + async def send_webserver_heartbeat(self): + async with threadpool(): + with self.get_session() as session: + key = "bot_heartbeat" + q = session.query(KeyValueProperties).filter(KeyValueProperties.key == key) + if q.count() == 0: + session.add(KeyValueProperties(key=key, value=time.time())) + else: + firstobj = q.first() + firstobj.value = time.time() + session.commit() diff --git a/discordbot/titanembeds/database/keyvalue_properties.py b/discordbot/titanembeds/database/keyvalue_properties.py new file mode 100644 index 0000000..32ec8d7 --- /dev/null +++ b/discordbot/titanembeds/database/keyvalue_properties.py @@ -0,0 +1,17 @@ +from titanembeds.database import db, Base +import datetime + +class KeyValueProperties(Base): + __tablename__ = "keyvalue_properties" + id = db.Column(db.Integer, primary_key=True) # Auto incremented id + key = db.Column(db.String(255), nullable=False) # Property Key + value = db.Column(db.Text()) # Property value + expiration = db.Column(db.TIMESTAMP) # Suggested Expiration for value (None = no expire) in secs + + def __init__(self, key, value, expiration=None): + self.key = key + self.value = value + if expiration: + self.expiration = datetime.now() + timedelta(seconds = expiration) + else: + self.expiration = None \ No newline at end of file diff --git a/webapp/titanembeds/app.py b/webapp/titanembeds/app.py index cab84af..956e394 100644 --- a/webapp/titanembeds/app.py +++ b/webapp/titanembeds/app.py @@ -2,7 +2,7 @@ from config import config from database import db from flask import Flask, render_template, request, session, url_for, redirect, jsonify from flask_sslify import SSLify -from titanembeds.utils import rate_limiter, discord_api +from titanembeds.utils import rate_limiter, discord_api, bot_alive import blueprints.api import blueprints.user import blueprints.embed @@ -38,3 +38,8 @@ def about(): def before_request(): db.create_all() discord_api.init_discordrest() + +@app.context_processor +def context_processor(): + bot_status = bot_alive() + return {"bot_status": bot_status} \ No newline at end of file diff --git a/webapp/titanembeds/templates/embed.html.j2 b/webapp/titanembeds/templates/embed.html.j2 index bcee46d..25a0a2b 100644 --- a/webapp/titanembeds/templates/embed.html.j2 +++ b/webapp/titanembeds/templates/embed.html.j2 @@ -21,6 +21,7 @@ {% endif %} + {% include 'nobot_header.html.j2' %}