Added a lot of different stuff

This commit is contained in:
Frisk 2020-07-10 22:07:33 +02:00
parent 2e7f12a7bc
commit 7872c7b3bc
No known key found for this signature in database
GPG key ID: 213F7C15068AF8AC
4 changed files with 94 additions and 14 deletions

View file

@ -3,14 +3,13 @@ from src.config import settings
import sqlite3
from src.wiki import Wiki
import asyncio, aiohttp
from src.exceptions import *
from src.database import db_cursor
logging.config.dictConfig(settings["logging"])
logger = logging.getLogger("rcgcdb.bot")
logger.debug("Current settings: {settings}".format(settings=settings))
conn = sqlite3.connect('rcgcdb.db')
c = conn.cursor()
# Log Fail states with structure wiki_id: number of fail states
all_wikis = {}
mw_msgs = {} # will have the type of id: tuple
@ -19,21 +18,22 @@ mw_msgs = {} # will have the type of id: tuple
# Reasons for this: 1. we require amount of wikis to calculate the cooldown between requests
# 2. Easier to code
for wiki in c.execute('SELECT ROWID, * FROM wikis'):
for wiki in db_cursor.execute('SELECT ROWID, * FROM wikis'):
all_wikis[wiki[0]] = Wiki()
# Start queueing logic
async def main_loop():
for db_wiki in c.execute('SELECT ROWID, * FROM wikis'):
for db_wiki in db_cursor.execute('SELECT ROWID, * FROM wikis'):
extended = False
if wiki[0] not in all_wikis:
logger.debug("New wiki: {}".format(wiki[1]))
all_wikis[wiki[0]] = Wiki()
local_wiki = all_wikis[wiki[0]] # set a reference to a wiki object from memory
if all_wikis[wiki[0]].mw_messages is None:
if local_wiki.mw_messages is None:
extended = True
wiki_response = await local_wiki.fetch_wiki(extended)
try:
wiki_response = await local_wiki.fetch_wiki(extended, db_wiki[3], db_wiki[4])
await local_wiki.check_status(wiki[0], wiki_response.status, db_wiki[1])
except:
except (WikiServerError, WikiError):
continue # ignore this wikis if it throws errors

View file

@ -1,2 +1,4 @@
import sqlite3
conn = sqlite3.connect('rcgcdb.db')
db_cursor = conn.cursor()

View file

@ -0,0 +1,74 @@
import json, random, math, logging
from collections import defaultdict
logger = logging.getLogger("rcgcdb.discord")
# General functions
class DiscordMessage():
"""A class defining a typical Discord JSON representation of webhook payload."""
def __init__(self, message_type: str, event_type: str, webhook_url: str, content=None):
self.webhook_object = dict(allowed_mentions={"parse": []})
self.webhook_url = webhook_url
if message_type == "embed":
self.__setup_embed()
elif message_type == "compact":
self.webhook_object["content"] = content
self.event_type = event_type
def __setitem__(self, key, value):
"""Set item is used only in embeds."""
try:
self.embed[key] = value
except NameError:
raise TypeError("Tried to assign a value when message type is plain message!")
def __getitem__(self, item):
return self.embed[item]
def __repr__(self):
"""Return the Discord webhook object ready to be sent"""
return json.dumps(self.webhook_object)
def __setup_embed(self):
self.embed = defaultdict(dict)
if "embeds" not in self.webhook_object:
self.webhook_object["embeds"] = [self.embed]
else:
self.webhook_object["embeds"].append(self.embed)
self.embed["color"] = None
def add_embed(self):
self.finish_embed()
self.__setup_embed()
def finish_embed(self):
if self.embed["color"] is None:
self.embed["color"] = random.randrange(1, 16777215)
else:
self.embed["color"] = math.floor(self.embed["color"])
def set_author(self, name, url, icon_url=""):
self.embed["author"]["name"] = name
self.embed["author"]["url"] = url
self.embed["author"]["icon_url"] = icon_url
def add_field(self, name, value, inline=False):
if "fields" not in self.embed:
self.embed["fields"] = []
self.embed["fields"].append(dict(name=name, value=value, inline=inline))
def set_avatar(self, url):
self.webhook_object["avatar_url"] = url
def set_name(self, name):
self.webhook_object["username"] = name
# User facing webhook functions
# Monitoring webhook functions
def wiki_removal(wiki_id):
pass

View file

@ -2,6 +2,8 @@ from dataclasses import dataclass
from src.session import session
import logging, aiohttp
from src.exceptions import *
from src.database import db_cursor
import src.discord
logger = logging.getLogger("rcgcdb.wiki")
@ -10,8 +12,8 @@ class Wiki:
mw_messages: int = None
fail_times: int = 0 # corresponding to amount of times connection with wiki failed for client reasons (400-499)
async def fetch_wiki(self, extended, api_path) -> aiohttp.ClientResponse:
url_path = api_path
async def fetch_wiki(self, extended, script_path, api_path) -> aiohttp.ClientResponse:
url_path = script_path + api_path
amount = 20
if extended:
params = {"action": "query", "format": "json", "uselang": "content", "list": "tags|recentchanges",
@ -29,8 +31,9 @@ class Wiki:
"rclimit": amount, "rctype": "edit|new|log|external", "siprop": "namespaces"}
try:
response = await session.get(url_path, params=params)
except:
raise NotImplemented
except (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError):
logger.exception("A connection error occurred while requesting {}".format(url_path))
raise WikiServerError
return response
async def check_status(self, wiki_id, status, name):
@ -41,10 +44,11 @@ class Wiki:
self.fail_times += 1
logger.warning("Wiki {} responded with HTTP code {}, increased fail_times to {}, skipping...".format(name, status, self.fail_times))
if self.fail_times > 3:
await self.remove(wiki_id)
await self.remove(wiki_id, status)
raise WikiError
elif 499 < status < 600:
logger.warning("Wiki {} responded with HTTP code {}, skipping...".format(name, status, self.fail_times))
raise WikiServerError
async def remove(self, wiki_id):
async def remove(self, wiki_id, reason):
src.discord.wiki_removal()