More fixes

This commit is contained in:
Frisk 2020-07-26 23:52:24 +02:00
parent dd04bef9fb
commit 238385021a
No known key found for this signature in database
GPG key ID: 213F7C15068AF8AC
5 changed files with 61 additions and 46 deletions

View file

@ -64,22 +64,27 @@ async def wiki_scanner():
local_wiki = all_wikis[db_wiki[3]] # set a reference to a wiki object from memory local_wiki = all_wikis[db_wiki[3]] # set a reference to a wiki object from memory
if local_wiki.mw_messages is None: if local_wiki.mw_messages is None:
extended = True extended = True
logger.debug("test") async with aiohttp.ClientSession(headers=settings["header"],
timeout=aiohttp.ClientTimeout(2.0)) as session:
try: try:
wiki_response = await local_wiki.fetch_wiki(extended, db_wiki[3]) wiki_response = await local_wiki.fetch_wiki(extended, db_wiki[3], session)
await local_wiki.check_status(db_wiki[3], wiki_response.status) await local_wiki.check_status(db_wiki[3], wiki_response.status)
except (WikiServerError, WikiError): except (WikiServerError, WikiError):
logger.exception("Exeption when fetching the wiki") logger.exception("Exeption when fetching the wiki")
continue # ignore this wiki if it throws errors continue # ignore this wiki if it throws errors
try: try:
recent_changes_resp = await wiki_response.json(encoding="UTF-8") recent_changes_resp = await wiki_response.json()
if "error" in recent_changes_resp or "errors" in recent_changes_resp: if "error" in recent_changes_resp or "errors" in recent_changes_resp:
# TODO Remove on some errors (example "code": "readapidenied") error = recent_changes_resp.get("error", recent_changes_resp["errors"])
if error["code"] == "readapidenied":
await local_wiki.fail_add(db_wiki[3], 410)
continue
raise WikiError raise WikiError
recent_changes = recent_changes_resp['query']['recentchanges'] recent_changes = recent_changes_resp['query']['recentchanges']
recent_changes.reverse() recent_changes.reverse()
except asyncio.exceptions.TimeoutError: except aiohttp.ContentTypeError:
logger.debug("Timeout on fetching {}.".format(db_wiki[3])) logger.exception("Wiki seems to be resulting in non-json content.")
await local_wiki.fail_add(db_wiki[3], 410)
continue continue
except: except:
logger.exception("On loading json of response.") logger.exception("On loading json of response.")
@ -108,7 +113,7 @@ async def wiki_scanner():
DBHandler.update_db() DBHandler.update_db()
await asyncio.sleep(delay=calc_delay) await asyncio.sleep(delay=calc_delay)
except asyncio.CancelledError: except asyncio.CancelledError:
return raise
async def message_sender(): async def message_sender():
@ -121,6 +126,7 @@ def shutdown(loop, signal=None):
loop.stop() loop.stop()
logger.info("Script has shut down due to signal {}.".format(signal)) logger.info("Script has shut down due to signal {}.".format(signal))
for task in asyncio.all_tasks(loop): for task in asyncio.all_tasks(loop):
logger.debug("Killing task {}".format(task.get_name()))
task.cancel() task.cancel()
sys.exit(0) sys.exit(0)
@ -134,17 +140,20 @@ async def main_loop():
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
try: try:
signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT) signals = (signal.SIGHUP, signal.SIGTERM, signal.SIGINT)
except AttributeError:
logger.info("Running on Windows huh? This complicates things")
signals = (signal.SIGBREAK, signal.SIGTERM, signal.SIGINT)
for s in signals: for s in signals:
loop.add_signal_handler( loop.add_signal_handler(
s, lambda s=s: shutdown(loop, signal=s)) s, lambda s=s: shutdown(loop, signal=s))
except AttributeError:
logger.info("Running on Windows huh? This complicates things")
signals = (signal.SIGBREAK, signal.SIGTERM, signal.SIGINT)
loop.set_exception_handler(global_exception_handler) loop.set_exception_handler(global_exception_handler)
try:
task1 = asyncio.create_task(wiki_scanner()) task1 = asyncio.create_task(wiki_scanner())
task2 = asyncio.create_task(message_sender()) task2 = asyncio.create_task(message_sender())
await task1 await task1
await task2 await task2
except KeyboardInterrupt:
shutdown(loop)
asyncio.run(main_loop()) asyncio.run(main_loop())

View file

@ -21,7 +21,7 @@ async def wiki_removal(wiki_id, status):
"""Our own translation string to make it compatible with async""" """Our own translation string to make it compatible with async"""
return langs[observer[4]].gettext(string) return langs[observer[4]].gettext(string)
reasons = {410: _("wiki deletion"), 404: _("wiki deletion"), 401: _("wiki becoming inaccessible"), reasons = {410: _("wiki deletion"), 404: _("wiki deletion"), 401: _("wiki becoming inaccessible"),
402: _("wiki becoming inaccessible"), 403: _("wiki becoming inaccessible")} 402: _("wiki becoming inaccessible"), 403: _("wiki becoming inaccessible"), 410: _("wiki becoming inaccessible")}
reason = reasons.get(status, _("unknown error")) reason = reasons.get(status, _("unknown error"))
await send_to_discord_webhook(DiscordMessage("compact", "webhook/remove", webhook_url=[observer[2]], content=_("The webhook for {} has been removed due to {}.".format(wiki_id, reason)), wiki=None)) await send_to_discord_webhook(DiscordMessage("compact", "webhook/remove", webhook_url=[observer[2]], content=_("The webhook for {} has been removed due to {}.".format(wiki_id, reason)), wiki=None))
header = settings["header"] header = settings["header"]

View file

@ -104,10 +104,13 @@ async def compact_formatter(action, change, parsed_comment, categories, recent_c
english_length_num = re.sub(r"(\D+)", "", change["logparams"]["duration"]) english_length_num = re.sub(r"(\D+)", "", change["logparams"]["duration"])
try: try:
english_length = english_length.rstrip("s").strip() english_length = english_length.rstrip("s").strip()
try:
block_time = "{num} {translated_length}".format(num=english_length_num, block_time = "{num} {translated_length}".format(num=english_length_num,
translated_length=ngettext(english_length, translated_length=ngettext(english_length,
english_length + "s", english_length + "s",
int(english_length_num))) int(english_length_num)))
except ValueError:
logger.exception("Couldn't properly resolve block expiry.")
except AttributeError: except AttributeError:
logger.error("Could not strip s from the block event, seems like the regex didn't work?") logger.error("Could not strip s from the block event, seems like the regex didn't work?")
return return

View file

@ -40,9 +40,9 @@ class MessageQueue:
logger.debug( logger.debug(
"Trying to send a message to Discord from the queue with id of {} and content {}".format(str(num), "Trying to send a message to Discord from the queue with id of {} and content {}".format(str(num),
str(item))) str(item)))
if await send_to_discord_webhook(item, self.session) < 2: if await send_to_discord_webhook(item) < 2:
logger.debug("Sending message succeeded") logger.debug("Sending message succeeded")
await asyncio.sleep(1.5) await asyncio.sleep(1.9)
else: else:
logger.debug("Sending message failed") logger.debug("Sending message failed")
break break

View file

@ -7,6 +7,7 @@ from src.formatters.rc import embed_formatter, compact_formatter
from src.misc import parse_link from src.misc import parse_link
from src.i18n import langs from src.i18n import langs
import src.discord import src.discord
import asyncio
from src.config import settings from src.config import settings
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
@ -22,7 +23,7 @@ class Wiki:
session: aiohttp.ClientSession = None session: aiohttp.ClientSession = None
async def fetch_wiki(self, extended, script_path) -> aiohttp.ClientResponse: async def fetch_wiki(self, extended, script_path, session) -> aiohttp.ClientResponse:
url_path = script_path + "api.php" url_path = script_path + "api.php"
amount = 20 amount = 20
if extended: if extended:
@ -30,17 +31,16 @@ class Wiki:
"meta": "allmessages|siteinfo", "meta": "allmessages|siteinfo",
"utf8": 1, "tglimit": "max", "tgprop": "displayname", "utf8": 1, "tglimit": "max", "tgprop": "displayname",
"rcprop": "title|redirect|timestamp|ids|loginfo|parsedcomment|sizes|flags|tags|user", "rcprop": "title|redirect|timestamp|ids|loginfo|parsedcomment|sizes|flags|tags|user",
"rclimit": amount, "rctype": "edit|new|log|external", "rclimit": amount, "rcshow": "!bot", "rctype": "edit|new|log|external",
"ammessages": "recentchanges-page-added-to-category|recentchanges-page-removed-from-category|recentchanges-page-added-to-category-bundled|recentchanges-page-removed-from-category-bundled", "ammessages": "recentchanges-page-added-to-category|recentchanges-page-removed-from-category|recentchanges-page-added-to-category-bundled|recentchanges-page-removed-from-category-bundled",
"amenableparser": 1, "amincludelocal": 1, "siprop": "namespaces|general"} "amenableparser": 1, "amincludelocal": 1, "siprop": "namespaces|general"}
else: else:
params = {"action": "query", "format": "json", "uselang": "content", "list": "tags|recentchanges", params = {"action": "query", "format": "json", "uselang": "content", "list": "tags|recentchanges",
"meta": "siteinfo", "utf8": 1, "meta": "siteinfo", "utf8": 1,
"tglimit": "max", "tgprop": "displayname", "tglimit": "max", "rcshow": "!bot", "tgprop": "displayname",
"rcprop": "title|redirect|timestamp|ids|loginfo|parsedcomment|sizes|flags|tags|user", "rcprop": "title|redirect|timestamp|ids|loginfo|parsedcomment|sizes|flags|tags|user",
"rclimit": amount, "rctype": "edit|new|log|external", "siprop": "namespaces|general"} "rclimit": amount, "rctype": "edit|new|log|external", "siprop": "namespaces|general"}
try: try:
async with aiohttp.ClientSession(headers=settings["header"], timeout=aiohttp.ClientTimeout(6.0)) as session:
response = await session.get(url_path, params=params) response = await session.get(url_path, params=params)
except (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError): except (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError):
logger.exception("A connection error occurred while requesting {}".format(url_path)) logger.exception("A connection error occurred while requesting {}".format(url_path))
@ -49,7 +49,7 @@ class Wiki:
async def safe_request(self, url): async def safe_request(self, url):
try: try:
async with aiohttp.ClientSession(headers=settings["header"], timeout=aiohttp.ClientTimeout(5.0)) as session: async with aiohttp.ClientSession(headers=settings["header"], timeout=aiohttp.ClientTimeout(2.0)) as session:
request = await session.get(url, timeout=5, allow_redirects=False) request = await session.get(url, timeout=5, allow_redirects=False)
request.raise_for_status() request.raise_for_status()
except (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError): except (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError):
@ -58,15 +58,19 @@ class Wiki:
else: else:
return request return request
async def fail_add(self, wiki_url, status):
logger.debug("Increasing fail_times to {}".format(self.fail_times+3))
self.fail_times += 3
if self.fail_times > 9:
await self.remove(wiki_url, status)
async def check_status(self, wiki_url, status): async def check_status(self, wiki_url, status):
if 199 < status < 300: if 199 < status < 300:
self.fail_times = 0 self.fail_times -= 1
pass pass
elif 400 < status < 500: # ignore 400 error since this might be our fault elif 400 < status < 500: # ignore 400 error since this might be our fault
self.fail_times += 1 await self.fail_add(wiki_url, status)
logger.warning("Wiki {} responded with HTTP code {}, increased fail_times to {}, skipping...".format(wiki_url, status, self.fail_times)) logger.warning("Wiki {} responded with HTTP code {}, increased fail_times to {}, skipping...".format(wiki_url, status, self.fail_times))
if self.fail_times > 3:
await self.remove(wiki_url, status)
raise WikiError raise WikiError
elif 499 < status < 600: elif 499 < status < 600:
logger.warning("Wiki {} responded with HTTP code {}, skipping...".format(wiki_url, status, self.fail_times)) logger.warning("Wiki {} responded with HTTP code {}, skipping...".format(wiki_url, status, self.fail_times))
@ -75,8 +79,8 @@ class Wiki:
async def remove(self, wiki_id, reason): async def remove(self, wiki_id, reason):
await src.discord.wiki_removal(wiki_id, reason) await src.discord.wiki_removal(wiki_id, reason)
await src.discord.wiki_removal_monitor(wiki_id, reason) await src.discord.wiki_removal_monitor(wiki_id, reason)
db_cursor.execute("DELETE FROM rcgcdw WHERE wiki = ?", (wiki_id,)) db_cursor.execute('DELETE FROM rcgcdw WHERE wiki = "?"', (wiki_id,))
logger.warning("{} rows affected by DELETE FROM rcgcdw WHERE wiki = {}".format(db_cursor.rowcount, wiki_id)) logger.warning('{} rows affected by DELETE FROM rcgcdw WHERE wiki = "{}"'.format(db_cursor.rowcount, wiki_id))
db_connection.commit() db_connection.commit()
async def pull_comment(self, comment_id, WIKI_API_PATH): async def pull_comment(self, comment_id, WIKI_API_PATH):
@ -143,7 +147,7 @@ async def process_mwmsgs(wiki_response: dict, local_wiki: Wiki, mw_msgs: dict):
if not "missing" in message: # ignore missing strings if not "missing" in message: # ignore missing strings
msgs.append((message["name"], re.sub(r'\[\[.*?\]\]', '', message["*"]))) msgs.append((message["name"], re.sub(r'\[\[.*?\]\]', '', message["*"])))
else: else:
logging.warning("Could not fetch the MW message translation for: {}".format(message["name"])) logger.warning("Could not fetch the MW message translation for: {}".format(message["name"]))
msgs = tuple(msgs) msgs = tuple(msgs)
for key, set in mw_msgs.items(): for key, set in mw_msgs.items():
if msgs == set: if msgs == set:
@ -163,7 +167,6 @@ async def essential_info(change: dict, changed_categories, local_wiki: Wiki, db_
lang = langs[target[0][0]] lang = langs[target[0][0]]
ngettext = lang.ngettext ngettext = lang.ngettext
# recent_changes = RecentChangesClass() # TODO Look into replacing RecentChangesClass with local_wiki # recent_changes = RecentChangesClass() # TODO Look into replacing RecentChangesClass with local_wiki
logger.debug(change)
appearance_mode = embed_formatter if target[0][1] > 0 else compact_formatter appearance_mode = embed_formatter if target[0][1] > 0 else compact_formatter
if ("actionhidden" in change or "suppressed" in change): # if event is hidden using suppression if ("actionhidden" in change or "suppressed" in change): # if event is hidden using suppression
await appearance_mode("suppressed", change, "", changed_categories, local_wiki, target, _, ngettext, paths) await appearance_mode("suppressed", change, "", changed_categories, local_wiki, target, _, ngettext, paths)