mirror of
https://gitlab.com/chicken-riders/RcGcDb.git
synced 2025-02-23 00:54:09 +00:00
More progress, added better target handler
This commit is contained in:
parent
d7add6b2a8
commit
db50490e56
|
@ -46,11 +46,15 @@ class Domain:
|
||||||
else:
|
else:
|
||||||
logger.error(f"Tried to start a task for domain {self.name} however the task already exists!")
|
logger.error(f"Tried to start a task for domain {self.name} however the task already exists!")
|
||||||
|
|
||||||
|
def remove_wiki(self, script_url: str):
|
||||||
|
|
||||||
|
|
||||||
def add_wiki(self, wiki: src.wiki.Wiki, first=False):
|
def add_wiki(self, wiki: src.wiki.Wiki, first=False):
|
||||||
"""Adds a wiki to domain list.
|
"""Adds a wiki to domain list.
|
||||||
|
|
||||||
:parameter wiki - Wiki object
|
:parameter wiki - Wiki object
|
||||||
:parameter first (optional) - bool indicating if wikis should be added as first or last in the ordered dict"""
|
:parameter first (optional) - bool indicating if wikis should be added as first or last in the ordered dict"""
|
||||||
|
wiki.set_domain(self)
|
||||||
self.wikis[wiki.script_url] = wiki
|
self.wikis[wiki.script_url] = wiki
|
||||||
if first:
|
if first:
|
||||||
self.wikis.move_to_end(wiki.script_url, last=False)
|
self.wikis.move_to_end(wiki.script_url, last=False)
|
||||||
|
|
|
@ -12,3 +12,9 @@ class MWMessages:
|
||||||
self.mw_id = len(message_sets)
|
self.mw_id = len(message_sets)
|
||||||
message_sets[self.mw_id] = mc_messages
|
message_sets[self.mw_id] = mc_messages
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
message_sets[self.mw_id].get(item, "============")
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for key, item in message_sets[self.mw_id].items():
|
||||||
|
yield key, item
|
||||||
|
|
77
src/wiki.py
77
src/wiki.py
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import annotations
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import re
|
import re
|
||||||
import logging, aiohttp
|
import logging, aiohttp
|
||||||
|
@ -17,11 +18,16 @@ import asyncio
|
||||||
from src.config import settings
|
from src.config import settings
|
||||||
# noinspection PyPackageRequirements
|
# noinspection PyPackageRequirements
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict, defaultdict, namedtuple
|
||||||
from typing import Union, Optional
|
from typing import Union, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
logger = logging.getLogger("rcgcdb.wiki")
|
logger = logging.getLogger("rcgcdb.wiki")
|
||||||
|
|
||||||
|
wiki_reamoval_reasons = {410: _("wiki deleted"), 404: _("wiki deleted"), 401: _("wiki inaccessible"),
|
||||||
|
402: _("wiki inaccessible"), 403: _("wiki inaccessible"), 1000: _("discussions disabled")}
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from src.domain import Domain
|
||||||
|
|
||||||
class Wiki:
|
class Wiki:
|
||||||
def __init__(self, script_url: str, rc_id: int, discussion_id: int):
|
def __init__(self, script_url: str, rc_id: int, discussion_id: int):
|
||||||
|
@ -29,29 +35,45 @@ class Wiki:
|
||||||
self.session = aiohttp.ClientSession(headers=settings["header"], timeout=aiohttp.ClientTimeout(6.0))
|
self.session = aiohttp.ClientSession(headers=settings["header"], timeout=aiohttp.ClientTimeout(6.0))
|
||||||
self.statistics: Statistics = Statistics(rc_id, discussion_id)
|
self.statistics: Statistics = Statistics(rc_id, discussion_id)
|
||||||
self.fail_times: int = 0
|
self.fail_times: int = 0
|
||||||
self.mw_messages: Optional[MWMessages] = None # TODO Need to initialize MWMessages() somewhere
|
self.mw_messages: Optional[MWMessages] = None
|
||||||
self.first_fetch_done: bool = False
|
self.first_fetch_done: bool = False
|
||||||
|
self.domain: Optional[Domain] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rc_id(self):
|
def rc_id(self):
|
||||||
return self.statistics.last_action
|
return self.statistics.last_action
|
||||||
|
|
||||||
@staticmethod
|
async def remove(self, reason):
|
||||||
async def remove(wiki_url, reason):
|
logger.info("Removing a wiki {}".format(self.script_url))
|
||||||
logger.info("Removing a wiki {}".format(wiki_url))
|
await src.discord.wiki_removal(self.script_url, reason)
|
||||||
await src.discord.wiki_removal(wiki_url, reason)
|
await src.discord.wiki_removal_monitor(self.script_url, reason)
|
||||||
await src.discord.wiki_removal_monitor(wiki_url, reason)
|
|
||||||
async with db.pool().acquire() as connection:
|
async with db.pool().acquire() as connection:
|
||||||
result = await connection.execute('DELETE FROM rcgcdw WHERE wiki = $1', wiki_url)
|
result = await connection.execute('DELETE FROM rcgcdw WHERE wiki = $1', self.script_url)
|
||||||
logger.warning('{} rows affected by DELETE FROM rcgcdw WHERE wiki = "{}"'.format(result, wiki_url))
|
logger.warning('{} rows affected by DELETE FROM rcgcdw WHERE wiki = "{}"'.format(result, self.script_url))
|
||||||
|
|
||||||
def downtime_controller(self, down): # TODO Finish this one
|
def set_domain(self, domain: Domain):
|
||||||
|
self.domain = domain
|
||||||
|
|
||||||
|
async def downtime_controller(self, down, reason=None):
|
||||||
if down:
|
if down:
|
||||||
self.fail_times += 1
|
self.fail_times += 1
|
||||||
|
if self.fail_times > 20:
|
||||||
|
await self.remove(reason)
|
||||||
else:
|
else:
|
||||||
self.fail_times -= 1
|
self.fail_times -= 1
|
||||||
|
|
||||||
|
def generate_targets(self) -> defaultdict[namedtuple, list[str]]:
|
||||||
|
"""This function generates all possible varations of outputs that we need to generate messages for.
|
||||||
|
|
||||||
|
:returns defaultdict[namedtuple, list[str]] - where namedtuple is a named tuple with settings for given webhooks in list"""
|
||||||
|
Settings = namedtuple("Settings", ["lang", "display"])
|
||||||
|
target_settings: defaultdict[Settings, list[str]] = defaultdict(list)
|
||||||
|
async with db.pool().acquire() as connection:
|
||||||
|
async with connection.transaction():
|
||||||
|
async for webhook in connection.cursor('SELECT webhook, lang, display FROM rcgcdw WHERE wiki = $1', self.script_url):
|
||||||
|
target_settings[Settings(webhook["lang"], webhook["display"])].append(webhook["webhook"])
|
||||||
|
return target_settings
|
||||||
|
|
||||||
def parse_mw_request_info(self, request_data: dict, url: str):
|
def parse_mw_request_info(self, request_data: dict, url: str):
|
||||||
"""A function parsing request JSON message from MediaWiki logging all warnings and raising on MediaWiki errors"""
|
"""A function parsing request JSON message from MediaWiki logging all warnings and raising on MediaWiki errors"""
|
||||||
# any([True for k in request_data.keys() if k in ("error", "errors")])
|
# any([True for k in request_data.keys() if k in ("error", "errors")])
|
||||||
|
@ -103,11 +125,9 @@ class Wiki:
|
||||||
except (aiohttp.ServerConnectionError, aiohttp.ServerTimeoutError) as exc:
|
except (aiohttp.ServerConnectionError, aiohttp.ServerTimeoutError) as exc:
|
||||||
logger.warning("Reached {error} error for request on link {url}".format(error=repr(exc),
|
logger.warning("Reached {error} error for request on link {url}".format(error=repr(exc),
|
||||||
url=self.script_url + str(params)))
|
url=self.script_url + str(params)))
|
||||||
self.downtime_controller(True)
|
|
||||||
raise ServerError
|
raise ServerError
|
||||||
# Catching HTTP errors
|
# Catching HTTP errors
|
||||||
if 499 < request.status < 600:
|
if 499 < request.status < 600:
|
||||||
self.downtime_controller(True)
|
|
||||||
raise ServerError
|
raise ServerError
|
||||||
elif request.status == 302:
|
elif request.status == 302:
|
||||||
logger.critical(
|
logger.critical(
|
||||||
|
@ -115,6 +135,8 @@ class Wiki:
|
||||||
request.url))
|
request.url))
|
||||||
elif 399 < request.status < 500:
|
elif 399 < request.status < 500:
|
||||||
logger.error("Request returned ClientError status code on {url}".format(url=request.url))
|
logger.error("Request returned ClientError status code on {url}".format(url=request.url))
|
||||||
|
if request.status in wiki_reamoval_reasons:
|
||||||
|
await self.downtime_controller(True, reason=request.status)
|
||||||
raise ClientError(request)
|
raise ClientError(request)
|
||||||
else:
|
else:
|
||||||
# JSON Extraction
|
# JSON Extraction
|
||||||
|
@ -124,7 +146,6 @@ class Wiki:
|
||||||
request_json = request_json[item]
|
request_json = request_json[item]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logger.warning("ValueError when extracting JSON data on {url}".format(url=request.url))
|
logger.warning("ValueError when extracting JSON data on {url}".format(url=request.url))
|
||||||
self.downtime_controller(True)
|
|
||||||
raise ServerError
|
raise ServerError
|
||||||
except MediaWikiError:
|
except MediaWikiError:
|
||||||
logger.exception("MediaWiki error on request: {}".format(request.url))
|
logger.exception("MediaWiki error on request: {}".format(request.url))
|
||||||
|
@ -161,12 +182,30 @@ class Wiki:
|
||||||
try:
|
try:
|
||||||
request = await self.fetch_wiki()
|
request = await self.fetch_wiki()
|
||||||
except WikiServerError:
|
except WikiServerError:
|
||||||
self.downtime_controller(True)
|
|
||||||
return # TODO Add a log entry?
|
return # TODO Add a log entry?
|
||||||
else:
|
else:
|
||||||
self.downtime_controller(False)
|
await self.downtime_controller(False)
|
||||||
if not self.mw_messages:
|
if not self.mw_messages:
|
||||||
mw_messages = request.get("query")
|
mw_messages = request.get("query", {}).get("allmessages", [])
|
||||||
|
final_mw_messages = dict()
|
||||||
|
for msg in mw_messages:
|
||||||
|
if "missing" not in msg: # ignore missing strings
|
||||||
|
final_mw_messages[msg["name"]] = re.sub(r'\[\[.*?]]', '', msg["*"])
|
||||||
|
else:
|
||||||
|
logger.warning("Could not fetch the MW message translation for: {}".format(msg["name"]))
|
||||||
|
self.mw_messages = MWMessages(final_mw_messages)
|
||||||
|
try:
|
||||||
|
recent_changes = request["query"]["recentchanges"]
|
||||||
|
recent_changes.reverse()
|
||||||
|
except KeyError:
|
||||||
|
raise WikiError
|
||||||
|
if self.rc_id in (0, None, -1):
|
||||||
|
if len(recent_changes) > 0:
|
||||||
|
self.statistics.last_action = recent_changes[-1]["rcid"]
|
||||||
|
else:
|
||||||
|
self.statistics.last_action = 0
|
||||||
|
db.add(queued_wiki.url, 0)
|
||||||
|
await DBHandler.update_db()
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Wiki_old:
|
class Wiki_old:
|
||||||
|
@ -282,7 +321,7 @@ class Wiki_old:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
async def process_cats(event: dict, local_wiki: Wiki, category_msgs: dict, categorize_events: dict):
|
async def process_cats(event: dict, local_wiki: Wiki, category_msgs: dict, categorize_events: dict): # TODO Rewrite this
|
||||||
"""Process categories based on local MW messages. """
|
"""Process categories based on local MW messages. """
|
||||||
if event["type"] == "categorize":
|
if event["type"] == "categorize":
|
||||||
if "commenthidden" not in event:
|
if "commenthidden" not in event:
|
||||||
|
|
Loading…
Reference in a new issue