mirror of
https://github.com/TitanEmbeds/Titan.git
synced 2024-11-15 02:21:21 +01:00
Show global header message when bot loses connection with server
This commit is contained in:
parent
926d4d14a9
commit
2647753007
@ -18,6 +18,9 @@ class Titan(discord.Client):
|
|||||||
self.database = DatabaseInterface(self)
|
self.database = DatabaseInterface(self)
|
||||||
self.command = Commands(self, self.database)
|
self.command = Commands(self, self.database)
|
||||||
|
|
||||||
|
self.database_connected = False
|
||||||
|
self.loop.create_task(self.send_webserver_heartbeat())
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
try:
|
try:
|
||||||
self.loop.run_until_complete(self.logout())
|
self.loop.run_until_complete(self.logout())
|
||||||
@ -32,6 +35,14 @@ class Titan(discord.Client):
|
|||||||
except: # Can be ignored
|
except: # Can be ignored
|
||||||
pass
|
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):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
self.loop.run_until_complete(self.start(config["bot-token"]))
|
self.loop.run_until_complete(self.start(config["bot-token"]))
|
||||||
@ -57,6 +68,7 @@ class Titan(discord.Client):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
await self.database.connect(config["database-uri"] + "?charset=utf8mb4")
|
await self.database.connect(config["database-uri"] + "?charset=utf8mb4")
|
||||||
|
self.database_connected = True
|
||||||
except Exception:
|
except Exception:
|
||||||
self.logger.error("Unable to connect to specified database!")
|
self.logger.error("Unable to connect to specified database!")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
@ -7,6 +7,7 @@ from sqlalchemy.ext.declarative import declarative_base
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import discord
|
import discord
|
||||||
|
import time
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ from titanembeds.database.messages import Messages
|
|||||||
from titanembeds.database.guild_members import GuildMembers
|
from titanembeds.database.guild_members import GuildMembers
|
||||||
from titanembeds.database.unauthenticated_users import UnauthenticatedUsers
|
from titanembeds.database.unauthenticated_users import UnauthenticatedUsers
|
||||||
from titanembeds.database.unauthenticated_bans import UnauthenticatedBans
|
from titanembeds.database.unauthenticated_bans import UnauthenticatedBans
|
||||||
|
from titanembeds.database.keyvalue_properties import KeyValueProperties
|
||||||
|
|
||||||
class DatabaseInterface(object):
|
class DatabaseInterface(object):
|
||||||
# Courtesy of https://github.com/SunDwarf/Jokusoramame
|
# Courtesy of https://github.com/SunDwarf/Jokusoramame
|
||||||
@ -363,3 +365,15 @@ class DatabaseInterface(object):
|
|||||||
dbuser.revoked = True
|
dbuser.revoked = True
|
||||||
session.commit()
|
session.commit()
|
||||||
return "Successfully kicked **{}#{}**!".format(dbuser.username, dbuser.discriminator)
|
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()
|
||||||
|
17
discordbot/titanembeds/database/keyvalue_properties.py
Normal file
17
discordbot/titanembeds/database/keyvalue_properties.py
Normal file
@ -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
|
@ -2,7 +2,7 @@ from config import config
|
|||||||
from database import db
|
from database import db
|
||||||
from flask import Flask, render_template, request, session, url_for, redirect, jsonify
|
from flask import Flask, render_template, request, session, url_for, redirect, jsonify
|
||||||
from flask_sslify import SSLify
|
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.api
|
||||||
import blueprints.user
|
import blueprints.user
|
||||||
import blueprints.embed
|
import blueprints.embed
|
||||||
@ -38,3 +38,8 @@ def about():
|
|||||||
def before_request():
|
def before_request():
|
||||||
db.create_all()
|
db.create_all()
|
||||||
discord_api.init_discordrest()
|
discord_api.init_discordrest()
|
||||||
|
|
||||||
|
@app.context_processor
|
||||||
|
def context_processor():
|
||||||
|
bot_status = bot_alive()
|
||||||
|
return {"bot_status": bot_status}
|
@ -21,6 +21,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
{% include 'nobot_header.html.j2' %}
|
||||||
<div class="navbar-fixed">
|
<div class="navbar-fixed">
|
||||||
<nav>
|
<nav>
|
||||||
<div class="nav-wrapper">
|
<div class="nav-wrapper">
|
||||||
@ -76,6 +77,7 @@
|
|||||||
|
|
||||||
<div id="loginmodal" class="modal">
|
<div id="loginmodal" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
{% include 'nobot_header.html.j2' %}
|
||||||
<h4>{{ login_greeting }}</h4>
|
<h4>{{ login_greeting }}</h4>
|
||||||
<div id="loginmodal-maincontent" class="row valign-wrap">
|
<div id="loginmodal-maincontent" class="row valign-wrap">
|
||||||
<div id="modal_guildinfobox" class="col m3 s12 center-align">
|
<div id="modal_guildinfobox" class="col m3 s12 center-align">
|
||||||
|
10
webapp/titanembeds/templates/nobot_header.html.j2
Normal file
10
webapp/titanembeds/templates/nobot_header.html.j2
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{% if not bot_status["status"] %}
|
||||||
|
<div style="border: solid 3px red; background-color: yellow; color: black;">
|
||||||
|
<p>
|
||||||
|
<strong>NOTICE!</strong>
|
||||||
|
The bot is <strong>currently not online</strong> or has <strong>lost the connection</strong> to the webserver.
|
||||||
|
If you see this header, please <a href="https://discord.io/titan" target="_blank" style="background-color: orange; color: blue;">notify us</a> as soon as possible for us to fix this issue.
|
||||||
|
Down since approximately <code>{{ bot_status["formatted_utc"] }}</code> UTC (<code>{{ bot_status["epoch_seconds"] }} epoch seconds</code>).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
@ -19,6 +19,7 @@
|
|||||||
{% include 'google_analytics.html.j2' %}
|
{% include 'google_analytics.html.j2' %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
{% include 'nobot_header.html.j2' %}
|
||||||
<main>
|
<main>
|
||||||
{% if session['unauthenticated'] is defined and not session['unauthenticated'] %}
|
{% if session['unauthenticated'] is defined and not session['unauthenticated'] %}
|
||||||
<ul id="menu_dropdown" class="dropdown-content">
|
<ul id="menu_dropdown" class="dropdown-content">
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
from titanembeds.database import db, Guilds, KeyValueProperties
|
from titanembeds.database import db, Guilds, KeyValueProperties, get_keyvalproperty
|
||||||
from flask import request, session
|
from flask import request, session
|
||||||
from flask_limiter import Limiter
|
from flask_limiter import Limiter
|
||||||
from config import config
|
from config import config
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import time
|
||||||
|
|
||||||
from titanembeds.discordrest import DiscordREST
|
from titanembeds.discordrest import DiscordREST
|
||||||
|
|
||||||
@ -73,4 +74,18 @@ def guild_query_unauth_users_bool(guild_id):
|
|||||||
dbGuild = db.session.query(Guilds).filter(Guilds.guild_id==guild_id).first()
|
dbGuild = db.session.query(Guilds).filter(Guilds.guild_id==guild_id).first()
|
||||||
return dbGuild.unauth_users
|
return dbGuild.unauth_users
|
||||||
|
|
||||||
|
def bot_alive():
|
||||||
|
results = {"status": False, "formatted_utc": "Never", "epoch_seconds": None}
|
||||||
|
epoch = get_keyvalproperty("bot_heartbeat")
|
||||||
|
if not epoch:
|
||||||
|
return results
|
||||||
|
epoch = float(epoch)
|
||||||
|
utc = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(epoch))
|
||||||
|
results["formatted_utc"] = utc
|
||||||
|
results["epoch_seconds"] = epoch
|
||||||
|
now = time.time()
|
||||||
|
if now - epoch < 60 * 5:
|
||||||
|
results["status"] = True
|
||||||
|
return results
|
||||||
|
|
||||||
rate_limiter = Limiter(key_func=get_client_ipaddr) # Default limit by ip address
|
rate_limiter = Limiter(key_func=get_client_ipaddr) # Default limit by ip address
|
||||||
|
Loading…
Reference in New Issue
Block a user