This commit is contained in:
Frisk 2022-07-24 22:02:25 +02:00
parent 2b09e7019a
commit e15613246e
No known key found for this signature in database
GPG key ID: 213F7C15068AF8AC
24 changed files with 1089 additions and 1008 deletions

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,7 +11,7 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import extensions.base.mediawiki import extensions.base.mediawiki
import extensions.base.abusefilter import extensions.base.abusefilter

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,30 +11,25 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import ipaddress import ipaddress
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \ from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \
create_article_path, sanitize_to_markdown create_article_path, sanitize_to_markdown
from src.configloader import settings
_ = formatters_i18n.gettext abusefilter_translatable = lambda string, _, default: {"edit": _("Edit"), "upload": _("Upload"), "move": _("Move"), "stashupload": _("Stash upload"), "delete": _("Deletion"), "createaccount": _("Account creation"), "autocreateaccount": _("Auto account creation"), "": _("None"), "warn": _("Warning issued"), "block": _("**Blocked user**"), "tag": _("Tagged the edit"), "disallow": _("Disallowed the action"), "rangeblock": _("**IP range blocked**"), "throttle": _("Throttled actions"), "blockautopromote": _("Removed autoconfirmed group"), "degroup": _("**Removed from privileged groups**")}.get(string, default)
ngettext = formatters_i18n.ngettext
abusefilter_results = {"": _("None"), "warn": _("Warning issued"), "block": _("**Blocked user**"), "tag": _("Tagged the edit"), "disallow": _("Disallowed the action"), "rangeblock": _("**IP range blocked**"), "throttle": _("Throttled actions"), "blockautopromote": _("Removed autoconfirmed group"), "degroup": _("**Removed from privileged groups**")}
abusefilter_actions = {"edit": _("Edit"), "upload": _("Upload"), "move": _("Move"), "stashupload": _("Stash upload"), "delete": _("Deletion"), "createaccount": _("Account creation"), "autocreateaccount": _("Auto account creation")}
logger = logging.getLogger("extensions.base") logger = logging.getLogger("extensions.base")
# AbuseFilter - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:AbuseFilter # AbuseFilter - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:AbuseFilter
# Processing Abuselog LOG events, separate from RC logs # Processing Abuselog LOG events, separate from RC logs
def abuse_filter_format_user(change):
def abuse_filter_format_user(change, settings):
author = change["user"] author = change["user"]
if settings.get("hide_ips", False): if settings.get("hide_ips", False):
try: try:
@ -50,11 +45,11 @@ def abuse_filter_format_user(change):
def embed_abuselog(ctx: Context, change: dict): def embed_abuselog(ctx: Context, change: dict):
action = "abuselog/{}".format(change["result"]) action = "abuselog/{}".format(change["result"])
embed = DiscordMessage(ctx.message_type, action, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, action, ctx.webhook_url)
author = abuse_filter_format_user(change) author = abuse_filter_format_user(change, ctx.settings)
embed["title"] = _("{user} triggered \"{abuse_filter}\"").format(user=author, abuse_filter=sanitize_to_markdown(change["filter"])) embed["title"] = ctx._("{user} triggered \"{abuse_filter}\"").format(user=author, abuse_filter=sanitize_to_markdown(change["filter"]))
embed.add_field(_("Performed"), abusefilter_actions.get(change["action"], _("Unknown"))) embed.add_field(ctx._("Performed"), abusefilter_translatable(change["action"], ctx._, ctx._("Unknown")))
embed.add_field(_("Action taken"), abusefilter_results.get(change["result"], _("Unknown"))) embed.add_field(ctx._("Action taken"), abusefilter_translatable(change["result"], ctx._, ctx._("Unknown")))
embed.add_field(_("Title"), sanitize_to_markdown(change.get("title", _("Unknown")))) embed.add_field(ctx._("Title"), sanitize_to_markdown(change.get("title", ctx._("Unknown"))))
return embed return embed
@ -62,12 +57,12 @@ def embed_abuselog(ctx: Context, change: dict):
def compact_abuselog(ctx: Context, change: dict): def compact_abuselog(ctx: Context, change: dict):
action = "abuselog/{}".format(change["result"]) action = "abuselog/{}".format(change["result"])
author_url = clean_link(create_article_path("User:{user}".format(user=change["user"]))) author_url = clean_link(create_article_path("User:{user}".format(user=change["user"])))
author = abuse_filter_format_user(change) author = abuse_filter_format_user(change, ctx.settings)
message = _("[{author}]({author_url}) triggered *{abuse_filter}*, performing the action \"{action}\" on *[{target}]({target_url})* - action taken: {result}.").format( message = ctx._("[{author}]({author_url}) triggered *{abuse_filter}*, performing the action \"{action}\" on *[{target}]({target_url})* - action taken: {result}.").format(
author=author, author_url=author_url, abuse_filter=sanitize_to_markdown(change["filter"]), author=author, author_url=author_url, abuse_filter=sanitize_to_markdown(change["filter"]),
action=abusefilter_actions.get(change["action"], _("Unknown")), target=change.get("title", _("Unknown")), action=abusefilter_translatable(change["action"], ctx._, ctx._("Unknown")), target=change.get("title", ctx._("Unknown")),
target_url=clean_link(create_article_path(sanitize_to_url(change.get("title", _("Unknown"))))), target_url=clean_link(create_article_path(sanitize_to_url(change.get("title", ctx._("Unknown"))))),
result=abusefilter_results.get(change["result"], _("Unknown"))) result=abusefilter_translatable(change["result"], ctx._, ctx._("Unknown")))
return DiscordMessage(ctx.message_type, action, ctx.webhook_url, content=message) return DiscordMessage(ctx.message_type, action, ctx.webhook_url, content=message)
# abusefilter/modify - AbuseFilter filter modification # abusefilter/modify - AbuseFilter filter modification
@ -80,7 +75,7 @@ def embed_abuselog_modify(ctx: Context, change: dict):
embed["url"] = create_article_path( embed["url"] = create_article_path(
"Special:AbuseFilter/history/{number}/diff/prev/{historyid}".format(number=change["logparams"]['newId'], "Special:AbuseFilter/history/{number}/diff/prev/{historyid}".format(number=change["logparams"]['newId'],
historyid=change["logparams"]["historyId"])) historyid=change["logparams"]["historyId"]))
embed["title"] = _("Edited abuse filter number {number}").format(number=change["logparams"]['newId']) embed["title"] = ctx._("Edited abuse filter number {number}").format(number=change["logparams"]['newId'])
return embed return embed
@ -92,7 +87,7 @@ def compact_abuselog_modify(ctx: Context, change: dict):
historyid=change["logparams"][ historyid=change["logparams"][
"historyId"]))) "historyId"])))
content = _("[{author}]({author_url}) edited abuse filter [number {number}]({filter_url})").format(author=author, content = ctx._("[{author}]({author_url}) edited abuse filter [number {number}]({filter_url})").format(author=author,
author_url=author_url, author_url=author_url,
number=change[ number=change[
"logparams"][ "logparams"][
@ -108,15 +103,16 @@ def embed_abuselog_create(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path("Special:AbuseFilter/{number}".format(number=change["logparams"]['newId'])) embed["url"] = create_article_path("Special:AbuseFilter/{number}".format(number=change["logparams"]['newId']))
embed["title"] = _("Created abuse filter number {number}").format(number=change["logparams"]['newId']) embed["title"] = ctx._("Created abuse filter number {number}").format(number=change["logparams"]['newId'])
return embed return embed
@formatter.compact(event="abusefilter/create") @formatter.compact(event="abusefilter/create")
def compact_abuselog_create(ctx: Context, change: dict): def compact_abuselog_create(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link( link = clean_link(
create_article_path("Special:AbuseFilter/{number}".format(number=change["logparams"]['newId']))) create_article_path("Special:AbuseFilter/{number}".format(number=change["logparams"]['newId'])))
content = _("[{author}]({author_url}) created abuse filter [number {number}]({filter_url})").format(author=author, content = ctx._("[{author}]({author_url}) created abuse filter [number {number}]({filter_url})").format(author=author,
author_url=author_url, author_url=author_url,
number=change[ number=change[
"logparams"][ "logparams"][

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,20 +11,15 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
import re import re
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# Cargo - https://www.mediawiki.org/wiki/Extension:Cargo # Cargo - https://www.mediawiki.org/wiki/Extension:Cargo
# cargo/createtable - Creation of Cargo table # cargo/createtable - Creation of Cargo table
@ -34,7 +29,7 @@ def embed_cargo_createtable(ctx: Context, change: dict):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"]))
embed["url"] = table.group(2) embed["url"] = table.group(2)
embed["title"] = _("Created the Cargo table \"{table}\"").format(table=table.group(1)) embed["title"] = ctx._("Created the Cargo table \"{table}\"").format(table=table.group(1))
return embed return embed
@ -42,7 +37,7 @@ def embed_cargo_createtable(ctx: Context, change: dict):
def compact_cargo_createtable(ctx: Context, change: dict): def compact_cargo_createtable(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"]))
content = _("[{author}]({author_url}) created the Cargo table \"{table}\"").format(author=author, content = ctx._("[{author}]({author_url}) created the Cargo table \"{table}\"").format(author=author,
author_url=author_url, author_url=author_url,
table=table) table=table)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -57,7 +52,7 @@ def embed_cargo_recreatetable(ctx: Context, change: dict):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"]))
embed["url"] = table.group(2) embed["url"] = table.group(2)
embed["title"] = _("Recreated the Cargo table \"{table}\"").format(table=table.group(1)) embed["title"] = ctx._("Recreated the Cargo table \"{table}\"").format(table=table.group(1))
return embed return embed
@ -65,7 +60,7 @@ def embed_cargo_recreatetable(ctx: Context, change: dict):
def compact_cargo_recreatetable(ctx: Context, change: dict): def compact_cargo_recreatetable(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"]))
content = _("[{author}]({author_url}) recreated the Cargo table \"{table}\"").format(author=author, content = ctx._("[{author}]({author_url}) recreated the Cargo table \"{table}\"").format(author=author,
author_url=author_url, author_url=author_url,
table=table) table=table)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -80,7 +75,7 @@ def embed_cargo_replacetable(ctx: Context, change: dict):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"]))
embed["url"] = table.group(2) embed["url"] = table.group(2)
embed["title"] = _("Replaced the Cargo table \"{table}\"").format(table=table.group(1)) embed["title"] = ctx._("Replaced the Cargo table \"{table}\"").format(table=table.group(1))
return embed return embed
@ -88,7 +83,7 @@ def embed_cargo_replacetable(ctx: Context, change: dict):
def compact_cargo_replacetable(ctx: Context, change: dict): def compact_cargo_replacetable(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"]))
content = _("[{author}]({author_url}) replaced the Cargo table \"{table}\"").format(author=author, content = ctx._("[{author}]({author_url}) replaced the Cargo table \"{table}\"").format(author=author,
author_url=author_url, author_url=author_url,
table=table) table=table)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -102,14 +97,14 @@ def embed_cargo_deletetable(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path("Special:CargoTables") embed["url"] = create_article_path("Special:CargoTables")
embed["title"] = _("Deleted the Cargo table \"{table}\"").format(table=sanitize_to_markdown(change["logparams"]["0"])) embed["title"] = ctx._("Deleted the Cargo table \"{table}\"").format(table=sanitize_to_markdown(change["logparams"]["0"]))
return embed return embed
@formatter.compact(event="cargo/deletetable") @formatter.compact(event="cargo/deletetable")
def compact_cargo_deletetable(ctx: Context, change: dict): def compact_cargo_deletetable(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
content = _("[{author}]({author_url}) deleted the Cargo table \"{table}\"").format(author=author, content = ctx._("[{author}]({author_url}) deleted the Cargo table \"{table}\"").format(author=author,
author_url=author_url, author_url=author_url,
table=sanitize_to_markdown(change["logparams"]["0"])) table=sanitize_to_markdown(change["logparams"]["0"]))
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,20 +11,16 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from src.configloader import settings
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, clean_link, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url from src.api.util import embed_helper, clean_link, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url
from src.misc import profile_field_name from src.misc import profile_field_name
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# CurseProfile - https://help.fandom.com/wiki/Extension:CurseProfile # CurseProfile - https://help.fandom.com/wiki/Extension:CurseProfile
# curseprofile/profile-edited - Editing user profile # curseprofile/profile-edited - Editing user profile
@ -36,13 +32,13 @@ def embed_curseprofile_profile_edited(ctx: Context, change: dict) -> DiscordMess
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
if target_user != change["user"]: if target_user != change["user"]:
embed["title"] = _("Edited {target}'s profile").format(target=sanitize_to_markdown(target_user)) embed["title"] = ctx._("Edited {target}'s profile").format(target=sanitize_to_markdown(target_user))
else: else:
embed["title"] = _("Edited their own profile") embed["title"] = ctx._("Edited their own profile")
if ctx.parsedcomment is None: # If the field is empty if ctx.parsedcomment is None: # If the field is empty
embed["description"] = _("Cleared the {field} field").format(field=profile_field_name(change["logparams"]['4:section'], True)) embed["description"] = ctx._("Cleared the {field} field").format(field=profile_field_name(change["logparams"]['4:section'], True))
else: else:
embed["description"] = _("{field} field changed to: {desc}").format(field=profile_field_name(change["logparams"]['4:section'], True), desc=ctx.parsedcomment) embed["description"] = ctx._("{field} field changed to: {desc}").format(field=profile_field_name(change["logparams"]['4:section'], True), desc=ctx.parsedcomment)
embed["url"] = create_article_path("UserProfile:" + sanitize_to_url(target_user)) embed["url"] = create_article_path("UserProfile:" + sanitize_to_url(target_user))
return embed return embed
@ -54,16 +50,16 @@ def compact_curseprofile_profile_edited(ctx: Context, change: dict) -> DiscordMe
link = clean_link(create_article_path("UserProfile:" + sanitize_to_url(target_user))) link = clean_link(create_article_path("UserProfile:" + sanitize_to_url(target_user)))
if target_user != author: if target_user != author:
if ctx.parsedcomment is None: # If the field is empty if ctx.parsedcomment is None: # If the field is empty
edit_clear_message = _("[{author}]({author_url}) cleared the {field} on [{target}]({target_url})'s profile.") edit_clear_message = ctx._("[{author}]({author_url}) cleared the {field} on [{target}]({target_url})'s profile.")
else: else:
edit_clear_message = _("[{author}]({author_url}) edited the {field} on [{target}]({target_url})'s profile. *({desc})*") edit_clear_message = ctx._("[{author}]({author_url}) edited the {field} on [{target}]({target_url})'s profile. *({desc})*")
content = edit_clear_message.format(author=author, author_url=author_url, target=sanitize_to_markdown(target_user), target_url=link, content = edit_clear_message.format(author=author, author_url=author_url, target=sanitize_to_markdown(target_user), target_url=link,
field=profile_field_name(change["logparams"]['4:section'], False), desc=ctx.parsedcomment) field=profile_field_name(change["logparams"]['4:section'], False), desc=ctx.parsedcomment)
else: else:
if ctx.parsedcomment is None: # If the field is empty if ctx.parsedcomment is None: # If the field is empty
edit_clear_message = _("[{author}]({author_url}) cleared the {field} on [their own]({target_url}) profile.") edit_clear_message = ctx._("[{author}]({author_url}) cleared the {field} on [their own]({target_url}) profile.")
else: else:
edit_clear_message = _("[{author}]({author_url}) edited the {field} on [their own]({target_url}) profile. *({desc})*") edit_clear_message = ctx._("[{author}]({author_url}) edited the {field} on [their own]({target_url}) profile. *({desc})*")
content = edit_clear_message.format(author=author, author_url=author_url, target_url=link, content = edit_clear_message.format(author=author, author_url=author_url, target_url=link,
field=profile_field_name(change["logparams"]['4:section'], False), desc=ctx.parsedcomment) field=profile_field_name(change["logparams"]['4:section'], False), desc=ctx.parsedcomment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -78,10 +74,10 @@ def embed_curseprofile_comment_created(ctx: Context, change: dict) -> DiscordMes
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
if target_user != change["user"]: if target_user != change["user"]:
embed["title"] = _("Left a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user)) embed["title"] = ctx._("Left a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user))
else: else:
embed["title"] = _("Left a comment on their own profile") embed["title"] = ctx._("Left a comment on their own profile")
if settings["appearance"]["embed"]["show_edit_changes"]: if ctx.settings["appearance"]["embed"]["show_edit_changes"]:
embed["description"] = ctx.client.pull_curseprofile_comment(change["logparams"]["4:comment_id"]) embed["description"] = ctx.client.pull_curseprofile_comment(change["logparams"]["4:comment_id"])
embed["url"] = create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"])) embed["url"] = create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))
return embed return embed
@ -93,10 +89,10 @@ def compact_curseprofile_comment_created(ctx: Context, change: dict) -> DiscordM
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))) link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"])))
if target_user != author: if target_user != author:
content = _("[{author}]({author_url}) left a [comment]({comment}) on {target}'s profile.").format( content = ctx._("[{author}]({author_url}) left a [comment]({comment}) on {target}'s profile.").format(
author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user)) author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user))
else: else:
content = _("[{author}]({author_url}) left a [comment]({comment}) on their own profile.").format(author=author, author_url=author_url, comment=link) content = ctx._("[{author}]({author_url}) left a [comment]({comment}) on their own profile.").format(author=author, author_url=author_url, comment=link)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -109,10 +105,10 @@ def embed_curseprofile_comment_edited(ctx: Context, change: dict) -> DiscordMess
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
if target_user != change["user"]: if target_user != change["user"]:
embed["title"] = _("Edited a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user)) embed["title"] = ctx._("Edited a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user))
else: else:
embed["title"] = _("Edited a comment on their own profile") embed["title"] = ctx._("Edited a comment on their own profile")
if settings["appearance"]["embed"]["show_edit_changes"]: if ctx.settings["appearance"]["embed"]["show_edit_changes"]:
embed["description"] = ctx.client.pull_curseprofile_comment(change["logparams"]["4:comment_id"]) embed["description"] = ctx.client.pull_curseprofile_comment(change["logparams"]["4:comment_id"])
embed["url"] = create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"])) embed["url"] = create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))
return embed return embed
@ -124,10 +120,10 @@ def compact_curseprofile_comment_edited(ctx: Context, change: dict) -> DiscordMe
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))) link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"])))
if target_user != author: if target_user != author:
content = _("[{author}]({author_url}) edited a [comment]({comment}) on {target}'s profile.").format( content = ctx._("[{author}]({author_url}) edited a [comment]({comment}) on {target}'s profile.").format(
author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user)) author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user))
else: else:
content = _("[{author}]({author_url}) edited a [comment]({comment}) on their own profile.").format(author=author, author_url=author_url, comment=link) content = ctx._("[{author}]({author_url}) edited a [comment]({comment}) on their own profile.").format(author=author, author_url=author_url, comment=link)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -140,10 +136,10 @@ def embed_curseprofile_comment_replied(ctx: Context, change: dict) -> DiscordMes
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
if target_user != change["user"]: if target_user != change["user"]:
embed["title"] = _("Replied to a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user)) embed["title"] = ctx._("Replied to a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user))
else: else:
embed["title"] = _("Replied to a comment on their own profile") embed["title"] = ctx._("Replied to a comment on their own profile")
if settings["appearance"]["embed"]["show_edit_changes"]: if ctx.settings["appearance"]["embed"]["show_edit_changes"]:
embed["description"] = ctx.client.pull_curseprofile_comment(change["logparams"]["4:comment_id"]) embed["description"] = ctx.client.pull_curseprofile_comment(change["logparams"]["4:comment_id"])
embed["url"] = create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"])) embed["url"] = create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))
return embed return embed
@ -155,10 +151,10 @@ def compact_curseprofile_comment_replied(ctx: Context, change: dict) -> DiscordM
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))) link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"])))
if target_user != author: if target_user != author:
content = _("[{author}]({author_url}) replied to a [comment]({comment}) on {target}'s profile.").format( content = ctx._("[{author}]({author_url}) replied to a [comment]({comment}) on {target}'s profile.").format(
author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user)) author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user))
else: else:
content = _("[{author}]({author_url}) replied to a [comment]({comment}) on their own profile.").format(author=author, author_url=author_url, comment=link) content = ctx._("[{author}]({author_url}) replied to a [comment]({comment}) on their own profile.").format(author=author, author_url=author_url, comment=link)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -171,9 +167,9 @@ def embed_curseprofile_comment_deleted(ctx: Context, change: dict) -> DiscordMes
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
if target_user != change["user"]: if target_user != change["user"]:
embed["title"] = _("Deleted a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user)) embed["title"] = ctx._("Deleted a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user))
else: else:
embed["title"] = _("Deleted a comment on their own profile") embed["title"] = ctx._("Deleted a comment on their own profile")
if ctx.parsedcomment is not None: if ctx.parsedcomment is not None:
embed["description"] = ctx.parsedcomment embed["description"] = ctx.parsedcomment
if "4:comment_id" in change["logparams"]: if "4:comment_id" in change["logparams"]:
@ -193,10 +189,10 @@ def compact_curseprofile_comment_deleted(ctx: Context, change: dict) -> DiscordM
link = clean_link(create_article_path("UserProfile:" + sanitize_to_url(target_user))) link = clean_link(create_article_path("UserProfile:" + sanitize_to_url(target_user)))
parsed_comment = "" if ctx.parsedcomment is None else " *(" + ctx.parsedcomment + ")*" parsed_comment = "" if ctx.parsedcomment is None else " *(" + ctx.parsedcomment + ")*"
if target_user != author: if target_user != author:
content = _("[{author}]({author_url}) deleted a [comment]({comment}) on {target}'s profile.{reason}").format( content = ctx._("[{author}]({author_url}) deleted a [comment]({comment}) on {target}'s profile.{reason}").format(
author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user), reason=parsed_comment) author=author, author_url=author_url, comment=link, target=sanitize_to_markdown(target_user), reason=parsed_comment)
else: else:
content = _("[{author}]({author_url}) deleted a [comment]({comment}) on their own profile.{reason}").format( content = ctx._("[{author}]({author_url}) deleted a [comment]({comment}) on their own profile.{reason}").format(
author=author, author_url=author_url, comment=link, reason=parsed_comment) author=author, author_url=author_url, comment=link, reason=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -210,9 +206,9 @@ def embed_curseprofile_comment_purged(ctx: Context, change: dict) -> DiscordMess
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
target_user = change["title"].split(':', 1)[1] target_user = change["title"].split(':', 1)[1]
if target_user != change["user"]: if target_user != change["user"]:
embed["title"] = _("Purged a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user)) embed["title"] = ctx._("Purged a comment on {target}'s profile").format(target=sanitize_to_markdown(target_user))
else: else:
embed["title"] = _("Purged a comment on their own profile") embed["title"] = ctx._("Purged a comment on their own profile")
if ctx.parsedcomment is not None: if ctx.parsedcomment is not None:
embed["description"] = ctx.parsedcomment embed["description"] = ctx.parsedcomment
embed["url"] = create_article_path("UserProfile:" + sanitize_to_url(target_user)) embed["url"] = create_article_path("UserProfile:" + sanitize_to_url(target_user))
@ -226,8 +222,8 @@ def compact_curseprofile_comment_purged(ctx: Context, change: dict) -> DiscordMe
link = clean_link(create_article_path("UserProfile:" + sanitize_to_url(target_user))) link = clean_link(create_article_path("UserProfile:" + sanitize_to_url(target_user)))
parsed_comment = "" if ctx.parsedcomment is None else " *(" + ctx.parsedcomment + ")*" parsed_comment = "" if ctx.parsedcomment is None else " *(" + ctx.parsedcomment + ")*"
if target_user != author: if target_user != author:
content = _("[{author}]({author_url}) purged a comment on [{target}]({link})'s profile.{reason}").format( content = ctx._("[{author}]({author_url}) purged a comment on [{target}]({link})'s profile.{reason}").format(
author=author, author_url=author_url, link=link, target=sanitize_to_markdown(target_user), reason=parsed_comment) author=author, author_url=author_url, link=link, target=sanitize_to_markdown(target_user), reason=parsed_comment)
else: else:
content = _("[{author}]({author_url}) purged a comment on [their own]({link}) profile.{reason}").format(author=author, author_url=author_url, link=link) content = ctx._("[{author}]({author_url}) purged a comment on [their own]({link}) profile.{reason}").format(author=author, author_url=author_url, link=link)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content, reason=parsed_comment) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content, reason=parsed_comment)

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,19 +11,15 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, compact_summary from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, compact_summary
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# DataDumps - https://www.mediawiki.org/wiki/Extension:DataDump # DataDumps - https://www.mediawiki.org/wiki/Extension:DataDump
# datadump/generate - Generating a dump of wiki # datadump/generate - Generating a dump of wiki
@ -33,7 +29,7 @@ ngettext = formatters_i18n.ngettext
def embed_datadump_generate(ctx: Context, change: dict) -> DiscordMessage: def embed_datadump_generate(ctx: Context, change: dict) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["title"] = _("Generated {file} dump").format(file=change["logparams"]["filename"]) embed["title"] = ctx._("Generated {file} dump").format(file=change["logparams"]["filename"])
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
return embed return embed
@ -42,7 +38,7 @@ def embed_datadump_generate(ctx: Context, change: dict) -> DiscordMessage:
def compact_datadump_generate(ctx: Context, change: dict): def compact_datadump_generate(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) generated *{file}* dump{comment}").format( content = ctx._("[{author}]({author_url}) generated *{file}* dump{comment}").format(
author=author, author_url=author_url, file=sanitize_to_markdown(change["logparams"]["filename"]), author=author, author_url=author_url, file=sanitize_to_markdown(change["logparams"]["filename"]),
comment=parsed_comment comment=parsed_comment
) )
@ -55,7 +51,7 @@ def compact_datadump_generate(ctx: Context, change: dict):
def embed_datadump_delete(ctx: Context, change: dict) -> DiscordMessage: def embed_datadump_delete(ctx: Context, change: dict) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["title"] = _("Deleted {file} dump").format(file=sanitize_to_markdown(change["logparams"]["filename"])) embed["title"] = ctx._("Deleted {file} dump").format(file=sanitize_to_markdown(change["logparams"]["filename"]))
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
return embed return embed
@ -64,7 +60,7 @@ def embed_datadump_delete(ctx: Context, change: dict) -> DiscordMessage:
def compact_datadump_delete(ctx: Context, change: dict) -> DiscordMessage: def compact_datadump_delete(ctx: Context, change: dict) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) deleted *{file}* dump{comment}").format( content = ctx._("[{author}]({author_url}) deleted *{file}* dump{comment}").format(
author=author, author_url=author_url, file=sanitize_to_markdown(change["logparams"]["filename"]), author=author, author_url=author_url, file=sanitize_to_markdown(change["logparams"]["filename"]),
comment=parsed_comment comment=parsed_comment
) )

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,24 +11,18 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
# Discussions - Custom Fandom technology which apparently doesn't have any documentation or homepage, not even open-source, go figure # Discussions - Custom Fandom technology which apparently doesn't have any documentation or homepage, not even open-source, go figure
import json import json
import datetime, logging import datetime, logging
import gettext
from urllib.parse import quote_plus from urllib.parse import quote_plus
from src.configloader import settings
from src.api.util import create_article_path, clean_link, sanitize_to_markdown from src.api.util import create_article_path, clean_link, sanitize_to_markdown
from src.api.context import Context from src.api.context import Context
from src.discord.queue import send_to_discord from src.discord.queue import send_to_discord
from src.discord.message import DiscordMessage, DiscordMessageMetadata from src.discord.message import DiscordMessage, DiscordMessageMetadata
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
_ = formatters_i18n.gettext
logger = logging.getLogger("rcgcdw.discussion_formatter") logger = logging.getLogger("rcgcdw.discussion_formatter")
@ -38,12 +32,13 @@ class DiscussionsFromHellParser:
"""This class converts fairly convoluted Fandom jsonModal of a discussion post into Markdown formatted usable thing. """This class converts fairly convoluted Fandom jsonModal of a discussion post into Markdown formatted usable thing.
Takes string, returns string. Kudos to MarkusRost for allowing me to implement this formatter based on his code in Wiki-Bot.""" Takes string, returns string. Kudos to MarkusRost for allowing me to implement this formatter based on his code in Wiki-Bot."""
def __init__(self, post): def __init__(self, post, ctx):
self.post = post self.post = post
self.jsonModal = json.loads(post.get("jsonModel", "{}")) self.jsonModal = json.loads(post.get("jsonModel", "{}"))
self.markdown_text = "" self.markdown_text = ""
self.item_num = 1 self.item_num = 1
self.image_last = None self.image_last = None
self.ctx = ctx
def parse(self) -> str: def parse(self) -> str:
"""Main parsing logic""" """Main parsing logic"""
@ -103,14 +98,13 @@ class DiscussionsFromHellParser:
elif item["type"] == "listItem": elif item["type"] == "listItem":
self.parse_content(item["content"], item["type"]) self.parse_content(item["content"], item["type"])
@staticmethod def convert_marks(self, marks):
def convert_marks(marks):
prefix = "" prefix = ""
suffix = "" suffix = ""
for mark in marks: for mark in marks:
if mark["type"] == "mention": if mark["type"] == "mention":
prefix += "[" prefix += "["
suffix = "]({wiki}f/u/{userid}){suffix}".format(wiki=settings["fandom_discussions"]["wiki_url"], suffix = "]({wiki}f/u/{userid}){suffix}".format(wiki=self.ctx.settings["fandom_discussions"]["wiki_url"],
userid=mark["attrs"]["userId"], suffix=suffix) userid=mark["attrs"]["userId"], suffix=suffix)
elif mark["type"] == "strong": elif mark["type"] == "strong":
prefix += "**" prefix += "**"
@ -124,11 +118,11 @@ class DiscussionsFromHellParser:
return prefix, suffix return prefix, suffix
def common_discussions(post: dict, embed: DiscordMessage): def common_discussions(post: dict, embed: DiscordMessage, ctx: Context):
"""A method to setup embeds with common info shared between all types of discussion posts""" """A method to setup embeds with common info shared between all types of discussion posts"""
if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: if ctx.settings["fandom_discussions"]["appearance"]["embed"]["show_content"]:
if post.get("jsonModel") is not None: if post.get("jsonModel") is not None:
npost = DiscussionsFromHellParser(post) npost = DiscussionsFromHellParser(post, ctx)
embed["description"] = npost.parse() embed["description"] = npost.parse()
if npost.image_last: if npost.image_last:
embed["image"]["url"] = npost.image_last embed["image"]["url"] = npost.image_last
@ -143,36 +137,36 @@ def common_discussions(post: dict, embed: DiscordMessage):
@formatter.embed(event="discussion/forum") @formatter.embed(event="discussion/forum")
def embed_discussion_forum(ctx: Context, post: dict): def embed_discussion_forum(ctx: Context, post: dict):
embed = DiscordMessage("embed", "discussion", settings["fandom_discussions"]["webhookURL"]) embed = DiscordMessage("embed", "discussion", ctx.settings["fandom_discussions"]["webhookURL"])
common_discussions(post, embed) common_discussions(post, embed, ctx)
author = _("unknown") # Fail safe author = ctx._("unknown") # Fail safe
if post["createdBy"]["name"]: if post["createdBy"]["name"]:
author = post["createdBy"]["name"] author = post["createdBy"]["name"]
embed.set_author(author, "{url}f/u/{creatorId}".format(url=settings["fandom_discussions"]["wiki_url"], embed.set_author(author, "{url}f/u/{creatorId}".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
creatorId=post["creatorId"]), creatorId=post["creatorId"]),
icon_url=post["createdBy"]["avatarUrl"]) icon_url=post["createdBy"]["avatarUrl"])
if not post["isReply"]: if not post["isReply"]:
embed["url"] = "{url}f/p/{threadId}".format(url=settings["fandom_discussions"]["wiki_url"], embed["url"] = "{url}f/p/{threadId}".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
threadId=post["threadId"]) threadId=post["threadId"])
embed["title"] = _("Created \"{title}\"").format(title=post["title"]) embed["title"] = ctx._("Created \"{title}\"").format(title=post["title"])
thread_funnel = post.get("funnel") thread_funnel = post.get("funnel")
if thread_funnel == "POLL": if thread_funnel == "POLL":
embed.event_type = "discussion/forum/poll" embed.event_type = "discussion/forum/poll"
embed["title"] = _("Created a poll \"{title}\"").format(title=post["title"]) embed["title"] = ctx._("Created a poll \"{title}\"").format(title=post["title"])
if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: if ctx.settings["fandom_discussions"]["appearance"]["embed"]["show_content"]:
poll = post["poll"] poll = post["poll"]
image_type = False image_type = False
if poll["answers"][0]["image"] is not None: if poll["answers"][0]["image"] is not None:
image_type = True image_type = True
for num, option in enumerate(poll["answers"]): for num, option in enumerate(poll["answers"]):
embed.add_field(option["text"] if image_type is True else _("Option {}").format(num + 1), embed.add_field(option["text"] if image_type is True else ctx._("Option {}").format(num + 1),
option["text"] if image_type is False else _( option["text"] if image_type is False else ctx._(
"__[View image]({image_url})__").format(image_url=option["image"]["url"]), "__[View image]({image_url})__").format(image_url=option["image"]["url"]),
inline=True) inline=True)
elif thread_funnel == "QUIZ": elif thread_funnel == "QUIZ":
embed.event_type = "discussion/forum/quiz" embed.event_type = "discussion/forum/quiz"
embed["title"] = _("Created a quiz \"{title}\"").format(title=post["title"]) embed["title"] = ctx._("Created a quiz \"{title}\"").format(title=post["title"])
if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: if ctx.settings["fandom_discussions"]["appearance"]["embed"]["show_content"]:
quiz = post["_embedded"]["quizzes"][0] quiz = post["_embedded"]["quizzes"][0]
embed["description"] = quiz["title"] embed["description"] = quiz["title"]
if quiz["image"] is not None: if quiz["image"] is not None:
@ -190,13 +184,13 @@ def embed_discussion_forum(ctx: Context, post: dict):
tag_displayname.append("[{title}]({url})".format(title=tag["articleTitle"], url=create_article_path( tag_displayname.append("[{title}]({url})".format(title=tag["articleTitle"], url=create_article_path(
quote_plus(tag["articleTitle"].replace(" ", "_"), "/:?=&")))) quote_plus(tag["articleTitle"].replace(" ", "_"), "/:?=&"))))
if len(", ".join(tag_displayname)) > 1000: if len(", ".join(tag_displayname)) > 1000:
embed.add_field(formatters_i18n.pgettext("Fandom discussions Tags/Forums", "Tags"), formatters_i18n.pgettext("Fandom discussions amount of Tags/Forums", "{} tags").format(len(post["_embedded"]["thread"][0]["tags"]))) embed.add_field(ctx.pgettext("Fandom discussions Tags/Forums", "Tags"), ctx.pgettext("Fandom discussions amount of Tags/Forums", "{} tags").format(len(post["_embedded"]["thread"][0]["tags"])))
else: else:
embed.add_field(formatters_i18n.pgettext("Fandom discussions Tags/Forums", "Tags"), ", ".join(tag_displayname)) embed.add_field(ctx.pgettext("Fandom discussions Tags/Forums", "Tags"), ", ".join(tag_displayname))
else: else:
embed.event_type = "discussion/forum/reply" embed.event_type = "discussion/forum/reply"
embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) embed["title"] = ctx._("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"])
embed["url"] = "{url}f/p/{threadId}/r/{postId}".format(url=settings["fandom_discussions"]["wiki_url"], embed["url"] = "{url}f/p/{threadId}/r/{postId}".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
threadId=post["threadId"], postId=post["id"]) threadId=post["threadId"], postId=post["id"])
return embed return embed
@ -204,20 +198,20 @@ def embed_discussion_forum(ctx: Context, post: dict):
@formatter.compact(event="discussion/forum") @formatter.compact(event="discussion/forum")
def compact_discussion_forum(ctx: Context, post: dict): def compact_discussion_forum(ctx: Context, post: dict):
message = None message = None
author = _("unknown") # Fail safe author = ctx._("unknown") # Fail safe
if post["createdBy"]["name"]: if post["createdBy"]["name"]:
author = post["createdBy"]["name"] author = post["createdBy"]["name"]
author_url = "<{url}f/u/{creatorId}>".format(url=settings["fandom_discussions"]["wiki_url"], author_url = "<{url}f/u/{creatorId}>".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
creatorId=post["creatorId"]) creatorId=post["creatorId"])
if not post["isReply"]: if not post["isReply"]:
thread_funnel = post.get("funnel") thread_funnel = post.get("funnel")
msg_text = _("[{author}]({author_url}) created [{title}](<{url}f/p/{threadId}>) in {forumName}") msg_text = ctx._("[{author}]({author_url}) created [{title}](<{url}f/p/{threadId}>) in {forumName}")
if thread_funnel == "POLL": if thread_funnel == "POLL":
event_type = "discussion/forum/poll" event_type = "discussion/forum/poll"
msg_text = _("[{author}]({author_url}) created a poll [{title}](<{url}f/p/{threadId}>) in {forumName}") msg_text = ctx._("[{author}]({author_url}) created a poll [{title}](<{url}f/p/{threadId}>) in {forumName}")
elif thread_funnel == "QUIZ": elif thread_funnel == "QUIZ":
event_type = "discussion/forum/quiz" event_type = "discussion/forum/quiz"
msg_text = _("[{author}]({author_url}) created a quiz [{title}](<{url}f/p/{threadId}>) in {forumName}") msg_text = ctx._("[{author}]({author_url}) created a quiz [{title}](<{url}f/p/{threadId}>) in {forumName}")
elif thread_funnel == "TEXT": elif thread_funnel == "TEXT":
event_type = "discussion/forum/post" event_type = "discussion/forum/post"
else: else:
@ -226,13 +220,13 @@ def compact_discussion_forum(ctx: Context, post: dict):
thread_funnel)) thread_funnel))
event_type = "unknown" event_type = "unknown"
message = msg_text.format(author=author, author_url=author_url, title=post["title"], message = msg_text.format(author=author, author_url=author_url, title=post["title"],
url=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], url=ctx.settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"],
forumName=post["forumName"]) forumName=post["forumName"])
else: else:
event_type = "discussion/forum/reply" event_type = "discussion/forum/reply"
message = _( message = ctx._(
"[{author}]({author_url}) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( "[{author}]({author_url}) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format(
author=author, author_url=author_url, url=settings["fandom_discussions"]["wiki_url"], author=author, author_url=author_url, url=ctx.settings["fandom_discussions"]["wiki_url"],
threadId=post["threadId"], postId=post["id"], title=post["_embedded"]["thread"][0]["title"], threadId=post["threadId"], postId=post["id"], title=post["_embedded"]["thread"][0]["title"],
forumName=post["forumName"]) forumName=post["forumName"])
return DiscordMessage("compact", event_type, ctx.webhook_url, content=message) return DiscordMessage("compact", event_type, ctx.webhook_url, content=message)
@ -240,83 +234,83 @@ def compact_discussion_forum(ctx: Context, post: dict):
# discussion/wall - Wall posts/replies # discussion/wall - Wall posts/replies
def compact_author_discussions(post: dict): def compact_author_discussions(post: dict, ctx: Context):
"""A common function for a few discussion related foramtters, it's formatting author's name and URL to their profile""" """A common function for a few discussion related foramtters, it's formatting author's name and URL to their profile"""
author = _("unknown") # Fail safe author = ctx._("unknown") # Fail safe
if post["creatorIp"]: if post["creatorIp"]:
author = post["creatorIp"][1:] if settings.get("hide_ips", False) is False else _("Unregistered user") author = post["creatorIp"][1:] if ctx.settings.get("hide_ips", False) is False else ctx._("Unregistered user")
author_url = "<{url}wiki/Special:Contributions{creatorIp}>".format(url=settings["fandom_discussions"]["wiki_url"], author_url = "<{url}wiki/Special:Contributions{creatorIp}>".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
creatorIp=post["creatorIp"]) creatorIp=post["creatorIp"])
else: else:
if post["createdBy"]["name"]: if post["createdBy"]["name"]:
author = post["createdBy"]["name"] author = post["createdBy"]["name"]
author_url = clean_link(create_article_path("User:{user}".format(user=author))) author_url = clean_link(create_article_path("User:{user}".format(user=author)))
else: else:
author_url = "<{url}f/u/{creatorId}>".format(url=settings["fandom_discussions"]["wiki_url"], author_url = "<{url}f/u/{creatorId}>".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
creatorId=post["creatorId"]) creatorId=post["creatorId"])
return author, author_url return author, author_url
def embed_author_discussions(post: dict, embed: DiscordMessage): def embed_author_discussions(post: dict, embed: DiscordMessage, ctx: Context):
author = _("unknown") # Fail safe author = ctx._("unknown") # Fail safe
if post["creatorIp"]: if post["creatorIp"]:
author = post["creatorIp"][1:] author = post["creatorIp"][1:]
embed.set_author(author if settings.get("hide_ips", False) is False else _("Unregistered user"), embed.set_author(author if ctx.settings.get("hide_ips", False) is False else ctx._("Unregistered user"),
"{url}wiki/Special:Contributions{creatorIp}".format( "{url}wiki/Special:Contributions{creatorIp}".format(
url=settings["fandom_discussions"]["wiki_url"], creatorIp=post["creatorIp"])) url=ctx.settings["fandom_discussions"]["wiki_url"], creatorIp=post["creatorIp"]))
else: else:
if post["createdBy"]["name"]: if post["createdBy"]["name"]:
author = post["createdBy"]["name"] author = post["createdBy"]["name"]
embed.set_author(author, "{url}wiki/User:{creator}".format(url=settings["fandom_discussions"]["wiki_url"], embed.set_author(author, "{url}wiki/User:{creator}".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
creator=author.replace(" ", "_")), creator=author.replace(" ", "_")),
icon_url=post["createdBy"]["avatarUrl"]) icon_url=post["createdBy"]["avatarUrl"])
else: else:
embed.set_author(author, "{url}f/u/{creatorId}".format(url=settings["fandom_discussions"]["wiki_url"], embed.set_author(author, "{url}f/u/{creatorId}".format(url=ctx.settings["fandom_discussions"]["wiki_url"],
creatorId=post["creatorId"]), creatorId=post["creatorId"]),
icon_url=post["createdBy"]["avatarUrl"]) icon_url=post["createdBy"]["avatarUrl"])
@formatter.embed(event="discussion/wall") @formatter.embed(event="discussion/wall")
def embed_discussion_wall(ctx: Context, post: dict): def embed_discussion_wall(ctx: Context, post: dict):
embed = DiscordMessage("embed", "discussion", settings["fandom_discussions"]["webhookURL"]) embed = DiscordMessage("embed", "discussion", ctx.settings["fandom_discussions"]["webhookURL"])
common_discussions(post, embed) common_discussions(post, embed)
embed_author_discussions(post, embed) embed_author_discussions(post, embed, ctx)
user_wall = _("unknown") # Fail safe user_wall = ctx._("unknown") # Fail safe
if post["forumName"].endswith(' Message Wall'): if post["forumName"].endswith(' Message Wall'):
user_wall = post["forumName"][:-13] user_wall = post["forumName"][:-13]
if not post["isReply"]: if not post["isReply"]:
embed.event_type = "discussion/wall/post" embed.event_type = "discussion/wall/post"
embed["url"] = "{url}wiki/Message_Wall:{user_wall}?threadId={threadId}".format( embed["url"] = "{url}wiki/Message_Wall:{user_wall}?threadId={threadId}".format(
url=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), url=ctx.settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")),
threadId=post["threadId"]) threadId=post["threadId"])
embed["title"] = _("Created \"{title}\" on {user}'s Message Wall").format(title=post["title"], user=user_wall) embed["title"] = ctx._("Created \"{title}\" on {user}'s Message Wall").format(title=post["title"], user=user_wall)
else: else:
embed.event_type = "discussion/wall/reply" embed.event_type = "discussion/wall/reply"
embed["url"] = "{url}wiki/Message_Wall:{user_wall}?threadId={threadId}#{replyId}".format( embed["url"] = "{url}wiki/Message_Wall:{user_wall}?threadId={threadId}#{replyId}".format(
url=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), url=ctx.settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")),
threadId=post["threadId"], replyId=post["id"]) threadId=post["threadId"], replyId=post["id"])
embed["title"] = _("Replied to \"{title}\" on {user}'s Message Wall").format( embed["title"] = ctx._("Replied to \"{title}\" on {user}'s Message Wall").format(
title=post["_embedded"]["thread"][0]["title"], user=user_wall) title=post["_embedded"]["thread"][0]["title"], user=user_wall)
return embed return embed
@formatter.compact(event="discussion/wall") @formatter.compact(event="discussion/wall")
def compact_discussion_wall(ctx: Context, post: dict): def compact_discussion_wall(ctx: Context, post: dict):
author, author_url = compact_author_discussions(post) author, author_url = compact_author_discussions(post, ctx)
user_wall = _("unknown") # Fail safe user_wall = ctx._("unknown") # Fail safe
if post["forumName"].endswith(' Message Wall'): if post["forumName"].endswith(' Message Wall'):
user_wall = post["forumName"][:-13] user_wall = post["forumName"][:-13]
if not post["isReply"]: if not post["isReply"]:
event_type = "discussion/wall/post" event_type = "discussion/wall/post"
message = _( message = ctx._(
"[{author}]({author_url}) created [{title}](<{url}wiki/Message_Wall:{user_wall}?threadId={threadId}>) on [{user}'s Message Wall](<{url}wiki/Message_Wall:{user_wall}>)").format( "[{author}]({author_url}) created [{title}](<{url}wiki/Message_Wall:{user_wall}?threadId={threadId}>) on [{user}'s Message Wall](<{url}wiki/Message_Wall:{user_wall}>)").format(
author=author, author_url=author_url, title=post["title"], url=settings["fandom_discussions"]["wiki_url"], author=author, author_url=author_url, title=post["title"], url=ctx.settings["fandom_discussions"]["wiki_url"],
user=user_wall, user_wall=quote_plus(user_wall.replace(" ", "_")), threadId=post["threadId"]) user=user_wall, user_wall=quote_plus(user_wall.replace(" ", "_")), threadId=post["threadId"])
else: else:
event_type = "discussion/wall/reply" event_type = "discussion/wall/reply"
message = _( message = ctx._(
"[{author}]({author_url}) created a [reply](<{url}wiki/Message_Wall:{user_wall}?threadId={threadId}#{replyId}>) to [{title}](<{url}wiki/Message_Wall:{user_wall}?threadId={threadId}>) on [{user}'s Message Wall](<{url}wiki/Message_Wall:{user_wall}>)").format( "[{author}]({author_url}) created a [reply](<{url}wiki/Message_Wall:{user_wall}?threadId={threadId}#{replyId}>) to [{title}](<{url}wiki/Message_Wall:{user_wall}?threadId={threadId}>) on [{user}'s Message Wall](<{url}wiki/Message_Wall:{user_wall}>)").format(
author=author, author_url=author_url, url=settings["fandom_discussions"]["wiki_url"], author=author, author_url=author_url, url=ctx.settings["fandom_discussions"]["wiki_url"],
title=post["_embedded"]["thread"][0]["title"], user=user_wall, title=post["_embedded"]["thread"][0]["title"], user=user_wall,
user_wall=quote_plus(user_wall.replace(" ", "_")), threadId=post["threadId"], replyId=post["id"]) user_wall=quote_plus(user_wall.replace(" ", "_")), threadId=post["threadId"], replyId=post["id"])
return DiscordMessage("compact", event_type, ctx.webhook_url, content=message) return DiscordMessage("compact", event_type, ctx.webhook_url, content=message)
@ -326,43 +320,43 @@ def compact_discussion_wall(ctx: Context, post: dict):
@formatter.embed(event="discussion/article_comment") @formatter.embed(event="discussion/article_comment")
def embed_discussion_article_comment(ctx: Context, post: dict): def embed_discussion_article_comment(ctx: Context, post: dict):
embed = DiscordMessage("embed", "discussion", settings["fandom_discussions"]["webhookURL"]) embed = DiscordMessage("embed", "discussion", ctx.settings["fandom_discussions"]["webhookURL"])
common_discussions(post, embed) common_discussions(post, embed)
embed_author_discussions(post, embed) embed_author_discussions(post, embed, ctx)
article_paths = ctx.comment_page article_paths = ctx.comment_page
if article_paths is None: if article_paths is None:
article_page = {"title": _("unknown"), "fullUrl": settings["fandom_discussions"]["wiki_url"]} # No page known article_paths = {"title": ctx._("unknown"), "fullUrl": ctx.settings["fandom_discussions"]["wiki_url"]} # No page known
if not post["isReply"]: if not post["isReply"]:
embed.event_type = "discussion/comment/post" embed.event_type = "discussion/comment/post"
embed["url"] = "{url}?commentId={commentId}".format(url=article_paths["fullUrl"], commentId=post["threadId"]) embed["url"] = "{url}?commentId={commentId}".format(url=article_paths["fullUrl"], commentId=post["threadId"])
embed["title"] = _("Commented on {article}").format(article=article_paths["title"]) embed["title"] = ctx._("Commented on {article}").format(article=article_paths["title"])
else: else:
embed.event_type = "discussion/comment/reply" embed.event_type = "discussion/comment/reply"
embed["url"] = "{url}?commentId={commentId}&replyId={replyId}".format(url=article_paths["fullUrl"], embed["url"] = "{url}?commentId={commentId}&replyId={replyId}".format(url=article_paths["fullUrl"],
commentId=post["threadId"], commentId=post["threadId"],
replyId=post["id"]) replyId=post["id"])
embed["title"] = _("Replied to a comment on {article}").format(article=article_paths["title"]) embed["title"] = ctx._("Replied to a comment on {article}").format(article=article_paths["title"])
embed["footer"]["text"] = article_paths["title"] embed["footer"]["text"] = article_paths["title"]
return embed return embed
@formatter.compact(event="discussion/article_comment") @formatter.compact(event="discussion/article_comment")
def compact_discussion_article_comment(ctx: Context, post: dict): def compact_discussion_article_comment(ctx: Context, post: dict):
author, author_url = compact_author_discussions(post) author, author_url = compact_author_discussions(post, ctx)
article_paths = ctx.comment_page article_paths = ctx.comment_page
if article_paths is None: if article_paths is None:
article_paths = {"title": _("unknown"), "fullUrl": settings["fandom_discussions"]["wiki_url"]} # No page known article_paths = {"title": ctx._("unknown"), "fullUrl": ctx.settings["fandom_discussions"]["wiki_url"]} # No page known
article_paths["fullUrl"] = article_paths["fullUrl"].replace(")", "\)").replace("()", "\(") article_paths["fullUrl"] = article_paths["fullUrl"].replace(")", "\)").replace("()", "\(")
if not post["isReply"]: if not post["isReply"]:
event_type = "discussion/comment/post" event_type = "discussion/comment/post"
message = _( message = ctx._(
"[{author}]({author_url}) created a [comment](<{url}?commentId={commentId}>) on [{article}](<{url}>)").format( "[{author}]({author_url}) created a [comment](<{url}?commentId={commentId}>) on [{article}](<{url}>)").format(
author=author, author_url=author_url, url=article_paths["fullUrl"], article=article_paths["title"], author=author, author_url=author_url, url=article_paths["fullUrl"], article=article_paths["title"],
commentId=post["threadId"]) commentId=post["threadId"])
else: else:
event_type = "discussion/comment/reply" event_type = "discussion/comment/reply"
message = _( message = ctx._(
"[{author}]({author_url}) created a [reply](<{url}?commentId={commentId}&replyId={replyId}>) to a [comment](<{url}?commentId={commentId}>) on [{article}](<{url}>)").format( "[{author}]({author_url}) created a [reply](<{url}?commentId={commentId}&replyId={replyId}>) to a [comment](<{url}?commentId={commentId}>) on [{article}](<{url}>)").format(
author=author, author_url=author_url, url=article_paths["fullUrl"], article=article_paths["title"], author=author, author_url=author_url, url=article_paths["fullUrl"], article=article_paths["title"],
commentId=post["threadId"], replyId=post["id"]) commentId=post["threadId"], replyId=post["id"])
return DiscordMessage("compact", event_type, ctx.webhook_url, content=message) return DiscordMessage("compact", event_type, ctx.webhook_url, content=message)

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,20 +11,15 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, clean_link, compact_author, create_article_path, sanitize_to_url, compact_summary from src.api.util import embed_helper, clean_link, compact_author, create_article_path, sanitize_to_url, compact_summary
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# Interwiki - https://www.mediawiki.org/wiki/Extension:Interwiki # Interwiki - https://www.mediawiki.org/wiki/Extension:Interwiki
# interwiki/iw_add - Added entry to interwiki table # interwiki/iw_add - Added entry to interwiki table
@ -34,8 +29,8 @@ def embed_interwiki_iw_add(ctx: Context, change: dict) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path("Special:Interwiki") embed["url"] = create_article_path("Special:Interwiki")
embed["title"] = _("Added an entry to the interwiki table") embed["title"] = ctx._("Added an entry to the interwiki table")
embed["description"] = _("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment, embed["description"] = ctx._("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment,
prefix=change["logparams"]['0'], prefix=change["logparams"]['0'],
website=change["logparams"]['1']) website=change["logparams"]['1'])
return embed return embed
@ -46,7 +41,7 @@ def compact_interwiki_iw_add(ctx: Context, change: dict) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path("Special:Interwiki")) link = clean_link(create_article_path("Special:Interwiki"))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) added an entry to the [interwiki table]({table_url}) pointing to {website} with {prefix} prefix").format( "[{author}]({author_url}) added an entry to the [interwiki table]({table_url}) pointing to {website} with {prefix} prefix").format(
author=author, author_url=author_url, desc=parsed_comment, prefix=change["logparams"]['0'], author=author, author_url=author_url, desc=parsed_comment, prefix=change["logparams"]['0'],
website=change["logparams"]['1'], table_url=link) website=change["logparams"]['1'], table_url=link)
@ -61,8 +56,8 @@ def embed_interwiki_iw_edit(ctx: Context, change: dict) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path("Special:Interwiki") embed["url"] = create_article_path("Special:Interwiki")
embed["title"] = _("Edited an entry in interwiki table") embed["title"] = ctx._("Edited an entry in interwiki table")
embed["description"] = _("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment, embed["description"] = ctx._("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment,
prefix=change["logparams"]['0'], prefix=change["logparams"]['0'],
website=change["logparams"]['1']) website=change["logparams"]['1'])
return embed return embed
@ -73,7 +68,7 @@ def compact_interwiki_iw_edit(ctx: Context, change: dict) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path("Special:Interwiki")) link = clean_link(create_article_path("Special:Interwiki"))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) edited an entry in [interwiki table]({table_url}) pointing to {website} with {prefix} prefix").format( "[{author}]({author_url}) edited an entry in [interwiki table]({table_url}) pointing to {website} with {prefix} prefix").format(
author=author, author_url=author_url, desc=parsed_comment, prefix=change["logparams"]['0'], author=author, author_url=author_url, desc=parsed_comment, prefix=change["logparams"]['0'],
website=change["logparams"]['1'], table_url=link) website=change["logparams"]['1'], table_url=link)
@ -88,8 +83,8 @@ def embed_interwiki_iw_delete(ctx: Context, change: dict) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path("Special:Interwiki") embed["url"] = create_article_path("Special:Interwiki")
embed["title"] = _("Deleted an entry in interwiki table") embed["title"] = ctx._("Deleted an entry in interwiki table")
embed["description"] = _("Prefix: {prefix} | {desc}").format(desc=ctx.parsedcomment, embed["description"] = ctx._("Prefix: {prefix} | {desc}").format(desc=ctx.parsedcomment,
prefix=change["logparams"]['0']) prefix=change["logparams"]['0'])
return embed return embed
@ -99,7 +94,7 @@ def compact_interwiki_iw_delete(ctx: Context, change: dict) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path("Special:Interwiki")) link = clean_link(create_article_path("Special:Interwiki"))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) deleted an entry in [interwiki table]({table_url}){desc}").format( content = ctx._("[{author}]({author_url}) deleted an entry in [interwiki table]({table_url}){desc}").format(
author=author, author=author,
author_url=author_url, author_url=author_url,
table_url=link, table_url=link,

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,17 +11,13 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, compact_summary from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, compact_summary
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# ManageWiki - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:ManageWiki # ManageWiki - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:ManageWiki
# managewiki/settings - Changing wiki settings # managewiki/settings - Changing wiki settings
@ -31,7 +27,7 @@ def embed_managewiki_settings(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Changed wiki settings") embed["title"] = ctx._("Changed wiki settings")
if change["logparams"].get("changes", ""): if change["logparams"].get("changes", ""):
embed.add_field("Setting", sanitize_to_markdown(change["logparams"].get("changes"))) embed.add_field("Setting", sanitize_to_markdown(change["logparams"].get("changes")))
return embed return embed
@ -41,7 +37,7 @@ def embed_managewiki_settings(ctx: Context, change: dict):
def compact_managewiki_settings(ctx: Context, change: dict): def compact_managewiki_settings(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) changed wiki settings{reason}".format(author=author, author_url=author_url, reason=parsed_comment)) content = ctx._("[{author}]({author_url}) changed wiki settings{reason}".format(author=author, author_url=author_url, reason=parsed_comment))
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
# managewiki/delete - Deleting a wiki # managewiki/delete - Deleting a wiki
@ -52,7 +48,7 @@ def embed_managewiki_delete(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Deleted a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", _("Unknown"))) embed["title"] = ctx._("Deleted a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", ctx._("Unknown")))
return embed return embed
@ -60,11 +56,11 @@ def embed_managewiki_delete(ctx: Context, change: dict):
def compact_managewiki_delete(ctx: Context, change: dict): def compact_managewiki_delete(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) deleted a wiki *{wiki_name}*{comment}").format(author=author, content = ctx._("[{author}]({author_url}) deleted a wiki *{wiki_name}*{comment}").format(author=author,
author_url=author_url, author_url=author_url,
wiki_name=change[ wiki_name=change[
"logparams"].get("wiki", "logparams"].get("wiki",
_("Unknown")), ctx._("Unknown")),
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -77,7 +73,7 @@ def embed_managewiki_delete_group(ctx: Context, change: dict) -> DiscordMessage:
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
group = change["title"].split("/")[-1] group = change["title"].split("/")[-1]
embed["title"] = _("Deleted a \"{group}\" user group").format(wiki=group) embed["title"] = ctx._("Deleted a \"{group}\" user group").format(wiki=group)
return embed return embed
@ -86,7 +82,7 @@ def compact_managewiki_delete_group(ctx: Context, change: dict) -> DiscordMessag
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
group = change["title"].split("/")[-1] group = change["title"].split("/")[-1]
content = _("[{author}]({author_url}) deleted a usergroup *{group}*{comment}").format(author=author, content = ctx._("[{author}]({author_url}) deleted a usergroup *{group}*{comment}").format(author=author,
author_url=author_url, author_url=author_url,
group=group, group=group,
comment=parsed_comment) comment=parsed_comment)
@ -100,7 +96,7 @@ def embed_managewiki_lock(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Locked a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", _("Unknown"))) embed["title"] = ctx._("Locked a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", ctx._("Unknown")))
return embed return embed
@ -108,8 +104,8 @@ def embed_managewiki_lock(ctx: Context, change: dict):
def compact_managewiki_lock(ctx: Context, change: dict): def compact_managewiki_lock(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) locked a wiki *{wiki_name}*{comment}").format( content = ctx._("[{author}]({author_url}) locked a wiki *{wiki_name}*{comment}").format(
author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", _("Unknown")), author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", ctx._("Unknown")),
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -121,9 +117,9 @@ def embed_managewiki_namespaces(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Modified \"{namespace_name}\" namespace").format( embed["title"] = ctx._("Modified \"{namespace_name}\" namespace").format(
namespace_name=change["logparams"].get("namespace", _("Unknown"))) namespace_name=change["logparams"].get("namespace", ctx._("Unknown")))
embed.add_field(_('Wiki'), change["logparams"].get("wiki", _("Unknown"))) embed.add_field(ctx._('Wiki'), change["logparams"].get("wiki", ctx._("Unknown")))
return embed return embed
@ -131,9 +127,9 @@ def embed_managewiki_namespaces(ctx: Context, change: dict):
def compact_managewiki_namespaces(ctx: Context, change: dict): def compact_managewiki_namespaces(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) modified namespace *{namespace_name}* on *{wiki_name}*{comment}").format( content = ctx._("[{author}]({author_url}) modified namespace *{namespace_name}* on *{wiki_name}*{comment}").format(
author=author, author_url=author_url, namespace_name=change["logparams"].get("namespace", _("Unknown")), author=author, author_url=author_url, namespace_name=change["logparams"].get("namespace", ctx._("Unknown")),
wiki_name=change["logparams"].get("wiki", _("Unknown")), comment=parsed_comment) wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
# managewiki/namespaces-delete - Deleteing a namespace # managewiki/namespaces-delete - Deleteing a namespace
@ -144,9 +140,9 @@ def embed_managewiki_namespaces_delete(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Deleted a \"{namespace_name}\" namespace").format( embed["title"] = ctx._("Deleted a \"{namespace_name}\" namespace").format(
namespace_name=change["logparams"].get("namespace", _("Unknown"))) namespace_name=change["logparams"].get("namespace", ctx._("Unknown")))
embed.add_field(_('Wiki'), change["logparams"].get("wiki", _("Unknown"))) embed.add_field(ctx._('Wiki'), change["logparams"].get("wiki", ctx._("Unknown")))
return embed return embed
@ -154,11 +150,11 @@ def embed_managewiki_namespaces_delete(ctx: Context, change: dict):
def compact_managewiki_namespaces_delete(ctx: Context, change: dict): def compact_managewiki_namespaces_delete(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) deleted a namespace *{namespace_name}* on *{wiki_name}*{comment}").format( "[{author}]({author_url}) deleted a namespace *{namespace_name}* on *{wiki_name}*{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
namespace_name=change["logparams"].get("namespace", _("Unknown")), namespace_name=change["logparams"].get("namespace", ctx._("Unknown")),
wiki_name=change["logparams"].get("wiki", _("Unknown")), comment=parsed_comment) wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
# managewiki/rights - Modifying user groups # managewiki/rights - Modifying user groups
@ -170,7 +166,7 @@ def embed_managewiki_rights(ctx: Context, change: dict):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
group_name = change["title"].split("/permissions/", 1)[1] group_name = change["title"].split("/permissions/", 1)[1]
embed["title"] = _("Modified \"{usergroup_name}\" usergroup").format(usergroup_name=group_name) embed["title"] = ctx._("Modified \"{usergroup_name}\" usergroup").format(usergroup_name=group_name)
return embed return embed
@ -179,7 +175,7 @@ def compact_managewiki_rights(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
group_name = change["title"].split("/permissions/", 1)[1] group_name = change["title"].split("/permissions/", 1)[1]
content = _("[{author}]({author_url}) modified user group *{group_name}*{comment}").format( content = ctx._("[{author}]({author_url}) modified user group *{group_name}*{comment}").format(
author=author, author_url=author_url, group_name=group_name, comment=parsed_comment author=author, author_url=author_url, group_name=group_name, comment=parsed_comment
) )
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -192,7 +188,7 @@ def embed_managewiki_undelete(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Undeleted a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", _("Unknown"))) embed["title"] = ctx._("Undeleted a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", ctx._("Unknown")))
return embed return embed
@ -200,8 +196,8 @@ def embed_managewiki_undelete(ctx: Context, change: dict):
def compact_managewiki_undelete(ctx: Context, change: dict): def compact_managewiki_undelete(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) undeleted a wiki *{wiki_name}*{comment}").format( content = ctx._("[{author}]({author_url}) undeleted a wiki *{wiki_name}*{comment}").format(
author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", _("Unknown")), author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", ctx._("Unknown")),
comment=parsed_comment comment=parsed_comment
) )
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -214,7 +210,7 @@ def embed_managewiki_unlock(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Unlocked a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", _("Unknown"))) embed["title"] = ctx._("Unlocked a \"{wiki}\" wiki").format(wiki=change["logparams"].get("wiki", ctx._("Unknown")))
return embed return embed
@ -222,8 +218,8 @@ def embed_managewiki_unlock(ctx: Context, change: dict):
def compact_managewiki_unlock(ctx: Context, change: dict): def compact_managewiki_unlock(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) unlocked a wiki *{wiki_name}*{comment}").format( content = ctx._("[{author}]({author_url}) unlocked a wiki *{wiki_name}*{comment}").format(
author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", _("Unknown")), author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", ctx._("Unknown")),
comment=parsed_comment comment=parsed_comment
) )
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,8 +11,7 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import ipaddress import ipaddress
import logging import logging
import math import math
@ -22,19 +21,15 @@ import datetime
from collections import OrderedDict from collections import OrderedDict
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \ from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \
create_article_path, sanitize_to_markdown, compact_summary create_article_path, sanitize_to_markdown, compact_summary
from src.configloader import settings
from src.exceptions import * from src.exceptions import *
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
logger = logging.getLogger("extensions.base") logger = logging.getLogger("extensions.base")
if 1 == 2: # additional translation strings in unreachable code if 1 == 2: # additional translation strings in unreachable code
_ = lambda a: a
print(_("director"), _("bot"), _("editor"), _("directors"), _("sysop"), _("bureaucrat"), _("reviewer"), print(_("director"), _("bot"), _("editor"), _("directors"), _("sysop"), _("bureaucrat"), _("reviewer"),
_("autoreview"), _("autopatrol"), _("wiki_guardian")) _("autoreview"), _("autopatrol"), _("wiki_guardian"))
@ -68,11 +63,11 @@ def embed_edit(ctx: Context, change: dict) -> DiscordMessage:
redirect="" if "redirect" in change else "", redirect="" if "redirect" in change else "",
article=sanitize_to_markdown(change["title"]), article=sanitize_to_markdown(change["title"]),
editsize="+" + str(editsize) if editsize > 0 else editsize, editsize="+" + str(editsize) if editsize > 0 else editsize,
new=_("(N!) ") if action == "new" else "", new=ctx._("(N!) ") if action == "new" else "",
minor=_("m") if action == "edit" and "minor" in change else "", minor=ctx._("m") if action == "edit" and "minor" in change else "",
bot=_('b') if "bot" in change else "", bot=ctx._('b') if "bot" in change else "",
space=" " if "bot" in change or (action == "edit" and "minor" in change) or action == "new" else "") space=" " if "bot" in change or (action == "edit" and "minor" in change) or action == "new" else "")
if settings["appearance"]["embed"]["show_edit_changes"]: if ctx.settings["appearance"]["embed"]["show_edit_changes"]:
try: try:
if action == "new": if action == "new":
changed_content = ctx.client.make_api_request( changed_content = ctx.client.make_api_request(
@ -82,7 +77,7 @@ def embed_edit(ctx: Context, change: dict) -> DiscordMessage:
changed_content = ctx.client.make_api_request( changed_content = ctx.client.make_api_request(
"?action=compare&format=json&fromrev={oldrev}&torev={diff}&topst=1&prop=diff".format( "?action=compare&format=json&fromrev={oldrev}&torev={diff}&topst=1&prop=diff".format(
diff=change["revid"], oldrev=change["old_revid"]), "compare", "*") diff=change["revid"], oldrev=change["old_revid"]), "compare", "*")
except ServerError: except (ServerError, MediaWikiError):
changed_content = None changed_content = None
if changed_content: if changed_content:
parse_mediawiki_changes(ctx, changed_content, embed) parse_mediawiki_changes(ctx, changed_content, embed)
@ -109,12 +104,12 @@ def compact_edit(ctx: Context, change: dict) -> DiscordMessage:
if abs(edit_size) > 500: if abs(edit_size) > 500:
bold = "**" bold = "**"
if action == "edit": if action == "edit":
content = _( content = ctx._(
"[{author}]({author_url}) edited [{article}]({edit_link}){comment} {bold}({sign}{edit_size}){bold}").format( "[{author}]({author_url}) edited [{article}]({edit_link}){comment} {bold}({sign}{edit_size}){bold}").format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), edit_link=edit_link, comment=parsed_comment, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), edit_link=edit_link, comment=parsed_comment,
edit_size=edit_size, sign=sign, bold=bold) edit_size=edit_size, sign=sign, bold=bold)
else: else:
content = _( content = ctx._(
"[{author}]({author_url}) created [{article}]({edit_link}){comment} {bold}({sign}{edit_size}){bold}").format( "[{author}]({author_url}) created [{article}]({edit_link}){comment} {bold}({sign}{edit_size}){bold}").format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), edit_link=edit_link, comment=parsed_comment, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), edit_link=edit_link, comment=parsed_comment,
edit_size=edit_size, sign=sign, bold=bold) edit_size=edit_size, sign=sign, bold=bold)
@ -133,7 +128,7 @@ def embed_upload_upload(ctx, change) -> DiscordMessage:
params = OrderedDict() params = OrderedDict()
params["action"] = "query" params["action"] = "query"
params["format"] = "json" params["format"] = "json"
if settings["license_detection"] and action == "upload/upload": if ctx.settings["license_detection"] and action == "upload/upload":
params["prop"] = "imageinfo|revisions" params["prop"] = "imageinfo|revisions"
params["rvprop"] = "content" params["rvprop"] = "content"
params["rvslots"] = "main" params["rvslots"] = "main"
@ -188,25 +183,25 @@ def embed_upload_upload(ctx, change) -> DiscordMessage:
undolink = "{wiki}index.php?title={filename}&action=revert&oldimage={archiveid}".format( undolink = "{wiki}index.php?title={filename}&action=revert&oldimage={archiveid}".format(
wiki=ctx.client.WIKI_SCRIPT_PATH, filename=sanitize_to_url(change["title"]), wiki=ctx.client.WIKI_SCRIPT_PATH, filename=sanitize_to_url(change["title"]),
archiveid=revision["archivename"]) archiveid=revision["archivename"])
embed.add_field(_("Options"), _("([preview]({link}) | [undo]({undolink}))").format( embed.add_field(ctx._("Options"), ctx._("([preview]({link}) | [undo]({undolink}))").format(
link=image_direct_url, undolink=undolink)) link=image_direct_url, undolink=undolink))
if settings["appearance"]["embed"]["embed_images"]: if ctx.settings["appearance"]["embed"]["embed_images"]:
embed["image"]["url"] = image_direct_url embed["image"]["url"] = image_direct_url
if action == "upload/overwrite": if action == "upload/overwrite":
embed["title"] = _("Uploaded a new version of {name}").format(name=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Uploaded a new version of {name}").format(name=sanitize_to_markdown(change["title"]))
elif action == "upload/revert": elif action == "upload/revert":
embed["title"] = _("Reverted a version of {name}").format(name=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Reverted a version of {name}").format(name=sanitize_to_markdown(change["title"]))
else: else:
embed["title"] = _("Uploaded {name}").format(name=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Uploaded {name}").format(name=sanitize_to_markdown(change["title"]))
if settings["license_detection"] and image_direct_url: if ctx.settings["license_detection"] and image_direct_url:
try: try:
content = image_data['revisions'][0]["slots"]["main"]['*'] content = image_data['revisions'][0]["slots"]["main"]['*']
matches = re.search(re.compile(settings["license_regex"], re.IGNORECASE), content) matches = re.search(re.compile(ctx.settings["license_regex"], re.IGNORECASE), content)
if matches is not None: if matches is not None:
license = matches.group("license") license = matches.group("license")
else: else:
if re.search(re.compile(settings["license_regex_detect"], re.IGNORECASE), content) is None: if re.search(re.compile(ctx.settings["license_regex_detect"], re.IGNORECASE), content) is None:
license = _("**No license!**") license = ctx._("**No license!**")
else: else:
license = "?" license = "?"
except IndexError: except IndexError:
@ -221,12 +216,12 @@ def embed_upload_upload(ctx, change) -> DiscordMessage:
logger.exception( logger.exception(
"Unknown error when retriefing the image data for a license, full content: {}".format(image_data)) "Unknown error when retriefing the image data for a license, full content: {}".format(image_data))
if image_direct_url: if image_direct_url:
embed.add_field(_("Options"), _("([preview]({link}))").format(link=image_direct_url)) embed.add_field(ctx._("Options"), ctx._("([preview]({link}))").format(link=image_direct_url))
if settings["appearance"]["embed"]["embed_images"]: if ctx.settings["appearance"]["embed"]["embed_images"]:
embed["image"]["url"] = image_direct_url embed["image"]["url"] = image_direct_url
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
if license is not None: if license is not None:
embed["description"] += _("\nLicense: {}").format(license) embed["description"] += ctx._("\nLicense: {}").format(license)
return embed return embed
@ -235,7 +230,7 @@ def compact_upload_revert(ctx, change) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
file_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) file_link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) reverted a version of [{file}]({file_link}){comment}").format( content = ctx._("[{author}]({author_url}) reverted a version of [{file}]({file_link}){comment}").format(
author=author, author_url=author_url, file=sanitize_to_markdown(change["title"]), file_link=file_link, author=author, author_url=author_url, file=sanitize_to_markdown(change["title"]), file_link=file_link,
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -246,7 +241,7 @@ def compact_upload_overwrite(ctx, change) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
file_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) file_link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) uploaded a new version of [{file}]({file_link}){comment}").format( content = ctx._("[{author}]({author_url}) uploaded a new version of [{file}]({file_link}){comment}").format(
author=author, author_url=author_url, file=sanitize_to_markdown(change["title"]), file_link=file_link, author=author, author_url=author_url, file=sanitize_to_markdown(change["title"]), file_link=file_link,
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -257,7 +252,7 @@ def compact_upload_upload(ctx, change) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
file_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) file_link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) uploaded [{file}]({file_link}){comment}").format(author=author, content = ctx._("[{author}]({author_url}) uploaded [{file}]({file_link}){comment}").format(author=author,
author_url=author_url, author_url=author_url,
file=sanitize_to_markdown( file=sanitize_to_markdown(
change["title"]), change["title"]),
@ -272,7 +267,7 @@ def embed_delete_delete(ctx, change) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed['url'] = create_article_path(sanitize_to_url(change["title"])) embed['url'] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Deleted page {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Deleted page {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -281,7 +276,7 @@ def compact_delete_delete(ctx, change) -> DiscordMessage:
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
page_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) page_link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("[{author}]({author_url}) deleted [{page}]({page_link}){comment}").format(author=author, content = ctx._("[{author}]({author_url}) deleted [{page}]({page_link}){comment}").format(author=author,
author_url=author_url, author_url=author_url,
page=sanitize_to_markdown( page=sanitize_to_markdown(
change["title"]), change["title"]),
@ -296,7 +291,7 @@ def embed_delete_delete_redir(ctx, change) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed['url'] = create_article_path(sanitize_to_url(change["title"])) embed['url'] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Deleted redirect {article} by overwriting").format( embed["title"] = ctx._("Deleted redirect {article} by overwriting").format(
article=sanitize_to_markdown(change["title"])) article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -306,7 +301,7 @@ def compact_delete_delete_redir(ctx, change) -> DiscordMessage:
page_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) page_link = clean_link(create_article_path(sanitize_to_url(change["title"])))
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) deleted redirect by overwriting [{page}]({page_link}){comment}").format( content = ctx._("[{author}]({author_url}) deleted redirect by overwriting [{page}]({page_link}){comment}").format(
author=author, author_url=author_url, page=sanitize_to_markdown(change["title"]), page_link=page_link, author=author, author_url=author_url, page=sanitize_to_markdown(change["title"]), page_link=page_link,
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -320,7 +315,7 @@ def embed_delete_restore(ctx, change) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed['url'] = create_article_path(sanitize_to_url(change["title"])) embed['url'] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Restored {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Restored {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -329,7 +324,7 @@ def compact_delete_restore(ctx, change) -> DiscordMessage:
page_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) page_link = clean_link(create_article_path(sanitize_to_url(change["title"])))
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) restored [{article}]({article_url}){comment}").format(author=author, content = ctx._("[{author}]({author_url}) restored [{article}]({article_url}){comment}").format(author=author,
author_url=author_url, author_url=author_url,
article=sanitize_to_markdown( article=sanitize_to_markdown(
change["title"]), change["title"]),
@ -346,7 +341,7 @@ def embed_delete_event(ctx, change) -> DiscordMessage:
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed['url'] = create_article_path("Special:RecentChanges") embed['url'] = create_article_path("Special:RecentChanges")
embed["title"] = _("Changed visibility of log events") embed["title"] = ctx._("Changed visibility of log events")
return embed return embed
@ -354,7 +349,7 @@ def embed_delete_event(ctx, change) -> DiscordMessage:
def compact_delete_event(ctx, change) -> DiscordMessage: def compact_delete_event(ctx, change) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) changed visibility of log events{comment}").format(author=author, content = ctx._("[{author}]({author_url}) changed visibility of log events{comment}").format(author=author,
author_url=author_url, author_url=author_url,
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -368,7 +363,7 @@ def embed_delete_revision(ctx, change) -> DiscordMessage:
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
amount = len(change["logparams"]["ids"]) amount = len(change["logparams"]["ids"])
embed['url'] = create_article_path(sanitize_to_url(change["title"])) embed['url'] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = ngettext("Changed visibility of revision on page {article} ", embed["title"] = ctx.ngettext("Changed visibility of revision on page {article} ",
"Changed visibility of {amount} revisions on page {article} ", amount).format( "Changed visibility of {amount} revisions on page {article} ", amount).format(
article=sanitize_to_markdown(change["title"]), amount=amount) article=sanitize_to_markdown(change["title"]), amount=amount)
return embed return embed
@ -380,7 +375,7 @@ def compact_delete_revision(ctx, change) -> DiscordMessage:
amount = len(change["logparams"]["ids"]) amount = len(change["logparams"]["ids"])
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = ngettext( content = ctx.ngettext(
"[{author}]({author_url}) changed visibility of revision on page [{article}]({article_url}){comment}", "[{author}]({author_url}) changed visibility of revision on page [{article}]({article_url}){comment}",
"[{author}]({author_url}) changed visibility of {amount} revisions on page [{article}]({article_url}){comment}", "[{author}]({author_url}) changed visibility of {amount} revisions on page [{article}]({article_url}){comment}",
amount).format(author=author, author_url=author_url, amount).format(author=author, author_url=author_url,
@ -397,9 +392,9 @@ def embed_move_move(ctx, change) -> DiscordMessage:
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path(sanitize_to_url(change["logparams"]['target_title'])) embed["url"] = create_article_path(sanitize_to_url(change["logparams"]['target_title']))
embed["description"] = "{supress}. {desc}".format(desc=ctx.parsedcomment, embed["description"] = "{supress}. {desc}".format(desc=ctx.parsedcomment,
supress=_("No redirect has been made") if "suppressredirect" in supress=ctx._("No redirect has been made") if "suppressredirect" in
change["logparams"] else _("A redirect has been made")) change["logparams"] else ctx._("A redirect has been made"))
embed["title"] = _("Moved {redirect}{article} to {target}").format(redirect="" if "redirect" in change else "", embed["title"] = ctx._("Moved {redirect}{article} to {target}").format(redirect="" if "redirect" in change else "",
article=sanitize_to_markdown(change["title"]), article=sanitize_to_markdown(change["title"]),
target=sanitize_to_markdown( target=sanitize_to_markdown(
change["logparams"]['target_title'])) change["logparams"]['target_title']))
@ -410,10 +405,10 @@ def embed_move_move(ctx, change) -> DiscordMessage:
def compact_move_move(ctx, change) -> DiscordMessage: def compact_move_move(ctx, change) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["logparams"]['target_title']))) link = clean_link(create_article_path(sanitize_to_url(change["logparams"]['target_title'])))
redirect_status = _("without making a redirect") if "suppressredirect" in change["logparams"] else _( redirect_status = ctx._("without making a redirect") if "suppressredirect" in change["logparams"] else ctx._(
"with a redirect") "with a redirect")
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) moved {redirect}*{article}* to [{target}]({target_url}) {made_a_redirect}{comment}").format( "[{author}]({author_url}) moved {redirect}*{article}* to [{target}]({target_url}) {made_a_redirect}{comment}").format(
author=author, author_url=author_url, redirect="" if "redirect" in change else "", article=sanitize_to_markdown(change["title"]), author=author, author_url=author_url, redirect="" if "redirect" in change else "", article=sanitize_to_markdown(change["title"]),
target=sanitize_to_markdown(change["logparams"]['target_title']), target_url=link, comment=parsed_comment, target=sanitize_to_markdown(change["logparams"]['target_title']), target_url=link, comment=parsed_comment,
@ -430,9 +425,9 @@ def embed_move_move_redir(ctx, change) -> DiscordMessage:
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path(sanitize_to_url(change["logparams"]['target_title'])) embed["url"] = create_article_path(sanitize_to_url(change["logparams"]['target_title']))
embed["description"] = "{supress}. {desc}".format(desc=ctx.parsedcomment, embed["description"] = "{supress}. {desc}".format(desc=ctx.parsedcomment,
supress=_("No redirect has been made") if "suppressredirect" in supress=ctx._("No redirect has been made") if "suppressredirect" in
change["logparams"] else _("A redirect has been made")) change["logparams"] else ctx._("A redirect has been made"))
embed["title"] = _("Moved {redirect}{article} to {title} over redirect").format( embed["title"] = ctx._("Moved {redirect}{article} to {title} over redirect").format(
redirect="" if "redirect" in change else "", article=sanitize_to_markdown(change["title"]), redirect="" if "redirect" in change else "", article=sanitize_to_markdown(change["title"]),
title=sanitize_to_markdown(change["logparams"]["target_title"])) title=sanitize_to_markdown(change["logparams"]["target_title"]))
return embed return embed
@ -442,10 +437,10 @@ def embed_move_move_redir(ctx, change) -> DiscordMessage:
def compact_move_move_redir(ctx, change) -> DiscordMessage: def compact_move_move_redir(ctx, change) -> DiscordMessage:
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["logparams"]['target_title']))) link = clean_link(create_article_path(sanitize_to_url(change["logparams"]['target_title'])))
redirect_status = _("without making a redirect") if "suppressredirect" in change["logparams"] else _( redirect_status = ctx._("without making a redirect") if "suppressredirect" in change["logparams"] else ctx._(
"with a redirect") "with a redirect")
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) moved {redirect}*{article}* over redirect to [{target}]({target_url}) {made_a_redirect}{comment}").format( "[{author}]({author_url}) moved {redirect}*{article}* over redirect to [{target}]({target_url}) {made_a_redirect}{comment}").format(
author=author, author_url=author_url, redirect="" if "redirect" in change else "", author=author, author_url=author_url, redirect="" if "redirect" in change else "",
article=sanitize_to_markdown(change["title"]), article=sanitize_to_markdown(change["title"]),
@ -462,7 +457,7 @@ def embed_protect_move_prot(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["logparams"]["oldtitle_title"])) embed["url"] = create_article_path(sanitize_to_url(change["logparams"]["oldtitle_title"]))
embed["title"] = _("Moved protection settings from {redirect}{article} to {title}").format( embed["title"] = ctx._("Moved protection settings from {redirect}{article} to {title}").format(
redirect="" if "redirect" in change else "", redirect="" if "redirect" in change else "",
article=sanitize_to_markdown(change["logparams"]["oldtitle_title"]), article=sanitize_to_markdown(change["logparams"]["oldtitle_title"]),
title=sanitize_to_markdown(change["title"])) title=sanitize_to_markdown(change["title"]))
@ -474,7 +469,7 @@ def compact_protect_move_prot(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["logparams"]["oldtitle_title"]))) link = clean_link(create_article_path(sanitize_to_url(change["logparams"]["oldtitle_title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) moved protection settings from {redirect}*{article}* to [{target}]({target_url}){comment}").format( "[{author}]({author_url}) moved protection settings from {redirect}*{article}* to [{target}]({target_url}){comment}").format(
author=author, author_url=author_url, redirect="" if "redirect" in change else "", author=author, author_url=author_url, redirect="" if "redirect" in change else "",
article=sanitize_to_markdown(change["logparams"]["oldtitle_title"]), article=sanitize_to_markdown(change["logparams"]["oldtitle_title"]),
@ -490,10 +485,10 @@ def embed_protect_protect(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Protected {target}").format(target=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Protected {target}").format(target=sanitize_to_markdown(change["title"]))
embed["description"] = "{settings}{cascade} | {reason}".format( embed["description"] = "{settings}{cascade} | {reason}".format(
settings=sanitize_to_markdown(change["logparams"].get("description", "")), settings=sanitize_to_markdown(change["logparams"].get("description", "")),
cascade=_(" [cascading]") if "cascade" in change["logparams"] else "", cascade=ctx._(" [cascading]") if "cascade" in change["logparams"] else "",
reason=ctx.parsedcomment) reason=ctx.parsedcomment)
return embed return embed
@ -503,12 +498,12 @@ def compact_protect_protect(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) protected [{article}]({article_url}) with the following settings: {settings}{comment}").format( "[{author}]({author_url}) protected [{article}]({article_url}) with the following settings: {settings}{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
settings=change["logparams"].get("description", "") + ( settings=change["logparams"].get("description", "") + (
_(" [cascading]") if "cascade" in change["logparams"] else ""), ctx._(" [cascading]") if "cascade" in change["logparams"] else ""),
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -521,10 +516,10 @@ def embed_protect_modify(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Changed protection level for {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Changed protection level for {article}").format(article=sanitize_to_markdown(change["title"]))
embed["description"] = "{settings}{cascade} | {reason}".format( embed["description"] = "{settings}{cascade} | {reason}".format(
settings=sanitize_to_markdown(change["logparams"].get("description", "")), settings=sanitize_to_markdown(change["logparams"].get("description", "")),
cascade=_(" [cascading]") if "cascade" in change["logparams"] else "", cascade=ctx._(" [cascading]") if "cascade" in change["logparams"] else "",
reason=ctx.parsedcomment) reason=ctx.parsedcomment)
return embed return embed
@ -534,12 +529,12 @@ def compact_protect_modify(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) modified protection settings of [{article}]({article_url}) to: {settings}{comment}").format( "[{author}]({author_url}) modified protection settings of [{article}]({article_url}) to: {settings}{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
settings=sanitize_to_markdown(change["logparams"].get("description", "")) + ( settings=sanitize_to_markdown(change["logparams"].get("description", "")) + (
_(" [cascading]") if "cascade" in change["logparams"] else ""), ctx._(" [cascading]") if "cascade" in change["logparams"] else ""),
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -552,7 +547,7 @@ def embed_protect_unprotect(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Removed protection from {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Removed protection from {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -561,16 +556,16 @@ def compact_protect_unprotect(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) removed protection from [{article}]({article_url}){comment}").format( content = ctx._("[{author}]({author_url}) removed protection from [{article}]({article_url}){comment}").format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link,
comment=parsed_comment) comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
# block/block - Blocking an user # block/block - Blocking an user
def block_expiry(change: dict) -> str: def block_expiry(change: dict, ctx: Context) -> str:
if change["logparams"]["duration"] in ["infinite", "indefinite", "infinity", "never"]: if change["logparams"]["duration"] in ["infinite", "indefinite", "infinity", "never"]:
return _("for infinity and beyond") return ctx._("for infinity and beyond")
else: else:
if "expiry" in change["logparams"]: if "expiry" in change["logparams"]:
expiry_date_time_obj = datetime.datetime.strptime(change["logparams"]["expiry"], '%Y-%m-%dT%H:%M:%SZ') expiry_date_time_obj = datetime.datetime.strptime(change["logparams"]["expiry"], '%Y-%m-%dT%H:%M:%SZ')
@ -579,15 +574,15 @@ def block_expiry(change: dict) -> str:
years, days, hours, minutes = timedelta_for_expiry // 31557600, timedelta_for_expiry % 31557600 // 86400, \ years, days, hours, minutes = timedelta_for_expiry // 31557600, timedelta_for_expiry % 31557600 // 86400, \
timedelta_for_expiry % 86400 // 3600, timedelta_for_expiry % 3600 // 60 timedelta_for_expiry % 86400 // 3600, timedelta_for_expiry % 3600 // 60
if not any([years, days, hours, minutes]): if not any([years, days, hours, minutes]):
return _("for less than a minute") return ctx._("for less than a minute")
time_names = ( time_names = (
ngettext("year", "years", years), ngettext("day", "days", days), ngettext("hour", "hours", hours), ctx.ngettext("year", "years", years), ctx.ngettext("day", "days", days), ctx.ngettext("hour", "hours", hours),
ngettext("minute", "minutes", minutes)) ctx.ngettext("minute", "minutes", minutes))
final_time = [] final_time = []
for num, timev in enumerate([years, days, hours, minutes]): for num, timev in enumerate([years, days, hours, minutes]):
if timev: if timev:
final_time.append( final_time.append(
_("for {time_number} {time_unit}").format(time_unit=time_names[num], time_number=int(timev))) ctx._("for {time_number} {time_unit}").format(time_unit=time_names[num], time_number=int(timev)))
return ", ".join(final_time) return ", ".join(final_time)
else: else:
return change["logparams"]["duration"] # Temporary? Should be rare? We will see in testing return change["logparams"]["duration"] # Temporary? Should be rare? We will see in testing
@ -606,16 +601,16 @@ def embed_block_block(ctx, change):
restriction_description = "" restriction_description = ""
if "restrictions" in change["logparams"]: if "restrictions" in change["logparams"]:
if "pages" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["pages"]: if "pages" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["pages"]:
restriction_description = _("Blocked from editing the following pages: ") restriction_description = ctx._("Blocked from editing the following pages: ")
restricted_pages = ["*" + i["page_title"] + "*" for i in change["logparams"]["restrictions"]["pages"]] restricted_pages = ["*" + i["page_title"] + "*" for i in change["logparams"]["restrictions"]["pages"]]
restriction_description = restriction_description + ", ".join(restricted_pages) restriction_description = restriction_description + ", ".join(restricted_pages)
if "namespaces" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"][ if "namespaces" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"][
"namespaces"]: "namespaces"]:
namespaces = [] namespaces = []
if restriction_description: if restriction_description:
restriction_description = restriction_description + _(" and namespaces: ") restriction_description = restriction_description + ctx._(" and namespaces: ")
else: else:
restriction_description = _("Blocked from editing pages on following namespaces: ") restriction_description = ctx._("Blocked from editing pages on following namespaces: ")
for namespace in change["logparams"]["restrictions"]["namespaces"]: for namespace in change["logparams"]["restrictions"]["namespaces"]:
if str(namespace) in ctx.client.namespaces: # if we have cached namespace name for given namespace number, add its name to the list if str(namespace) in ctx.client.namespaces: # if we have cached namespace name for given namespace number, add its name to the list
namespaces.append("*{ns}*".format(ns=ctx.client.namespaces[str(namespace)]["*"])) namespaces.append("*{ns}*".format(ns=ctx.client.namespaces[str(namespace)]["*"]))
@ -626,12 +621,12 @@ def embed_block_block(ctx, change):
if len(restriction_description) > 1020: if len(restriction_description) > 1020:
logger.debug(restriction_description) logger.debug(restriction_description)
restriction_description = restriction_description[:1020] + "" restriction_description = restriction_description[:1020] + ""
embed.add_field(_("Partial block details"), restriction_description, inline=True) embed.add_field(ctx._("Partial block details"), restriction_description, inline=True)
block_flags = change["logparams"].get("flags") block_flags = change["logparams"].get("flags")
if block_flags: if block_flags:
embed.add_field(_("Block flags"), ", ".join( embed.add_field(ctx._("Block flags"), ", ".join(
block_flags)) # TODO Translate flags into MW messages, this requires making additional request in init_request since we want to get all messages with prefix (amprefix) block-log-flags- and that parameter is exclusive with ammessages block_flags)) # TODO Translate flags into MW messages, this requires making additional request in init_request since we want to get all messages with prefix (amprefix) block-log-flags- and that parameter is exclusive with ammessages
embed["title"] = _("Blocked {blocked_user} {time}").format(blocked_user=user, time=block_expiry(change)) embed["title"] = ctx._("Blocked {blocked_user} {time}").format(blocked_user=user, time=block_expiry(change, ctx))
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
return embed return embed
@ -651,7 +646,7 @@ def compact_block_block(ctx, change):
if "sitewide" not in change["logparams"]: if "sitewide" not in change["logparams"]:
if "restrictions" in change["logparams"]: if "restrictions" in change["logparams"]:
if "pages" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["pages"]: if "pages" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["pages"]:
restriction_description = _(" on pages: ") restriction_description = ctx._(" on pages: ")
restricted_pages = ["*{page}*".format(page=i["page_title"]) for i in restricted_pages = ["*{page}*".format(page=i["page_title"]) for i in
change["logparams"]["restrictions"]["pages"]] change["logparams"]["restrictions"]["pages"]]
restriction_description = restriction_description + ", ".join(restricted_pages) restriction_description = restriction_description + ", ".join(restricted_pages)
@ -659,9 +654,9 @@ def compact_block_block(ctx, change):
"namespaces"]: "namespaces"]:
namespaces = [] namespaces = []
if restriction_description: if restriction_description:
restriction_description = restriction_description + _(" and namespaces: ") restriction_description = restriction_description + ctx._(" and namespaces: ")
else: else:
restriction_description = _(" on namespaces: ") restriction_description = ctx._(" on namespaces: ")
for namespace in change["logparams"]["restrictions"]["namespaces"]: for namespace in change["logparams"]["restrictions"]["namespaces"]:
if str(namespace) in ctx.client.namespaces: # if we have cached namespace name for given namespace number, add its name to the list if str(namespace) in ctx.client.namespaces: # if we have cached namespace name for given namespace number, add its name to the list
namespaces.append("*{ns}*".format(ns=ctx.client.namespaces[str(namespace)]["*"])) namespaces.append("*{ns}*".format(ns=ctx.client.namespaces[str(namespace)]["*"]))
@ -672,12 +667,12 @@ def compact_block_block(ctx, change):
if len(restriction_description) > 1020: if len(restriction_description) > 1020:
logger.debug(restriction_description) logger.debug(restriction_description)
restriction_description = restriction_description[:1020] + "" restriction_description = restriction_description[:1020] + ""
content = _( content = ctx._(
"[{author}]({author_url}) blocked [{user}]({user_url}) {time}{restriction_desc}{comment}").format(author=author, "[{author}]({author_url}) blocked [{user}]({user_url}) {time}{restriction_desc}{comment}").format(author=author,
author_url=author_url, author_url=author_url,
user=user, user=user,
time=block_expiry( time=block_expiry(
change), change, ctx),
user_url=link, user_url=link,
restriction_desc=restriction_description, restriction_desc=restriction_description,
comment=parsed_comment) comment=parsed_comment)
@ -691,7 +686,7 @@ def embed_block_reblock(ctx, change):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
user = change["title"].split(':', 1)[1] user = change["title"].split(':', 1)[1]
embed["title"] = _("Changed block settings for {blocked_user}").format(blocked_user=sanitize_to_markdown(user)) embed["title"] = ctx._("Changed block settings for {blocked_user}").format(blocked_user=sanitize_to_markdown(user))
return embed return embed
@ -701,7 +696,7 @@ def compact_block_reblock(ctx, change):
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
user = change["title"].split(':', 1)[1] user = change["title"].split(':', 1)[1]
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) changed block settings for [{blocked_user}]({user_url}){comment}").format( content = ctx._("[{author}]({author_url}) changed block settings for [{blocked_user}]({user_url}){comment}").format(
author=author, author_url=author_url, blocked_user=sanitize_to_markdown(user), user_url=link, comment=parsed_comment) author=author, author_url=author_url, blocked_user=sanitize_to_markdown(user), user_url=link, comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -714,7 +709,7 @@ def embed_block_unblock(ctx, change):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
user = change["title"].split(':', 1)[1] user = change["title"].split(':', 1)[1]
embed["title"] = _("Unblocked {blocked_user}").format(blocked_user=sanitize_to_markdown(user)) embed["title"] = ctx._("Unblocked {blocked_user}").format(blocked_user=sanitize_to_markdown(user))
return embed return embed
@ -724,7 +719,7 @@ def compact_block_unblock(ctx, change):
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
user = change["title"].split(':', 1)[1] user = change["title"].split(':', 1)[1]
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) unblocked [{blocked_user}]({user_url}){comment}").format(author=author, content = ctx._("[{author}]({author_url}) unblocked [{blocked_user}]({user_url}){comment}").format(author=author,
author_url=author_url, author_url=author_url,
blocked_user=sanitize_to_markdown(user), blocked_user=sanitize_to_markdown(user),
user_url=link, user_url=link,
@ -740,14 +735,14 @@ def compact_block_unblock(ctx, change):
def embed_suppressed(ctx, change): def embed_suppressed(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed["url"] = create_article_path("") embed["url"] = create_article_path("")
embed["title"] = _("Action has been hidden by administration") embed["title"] = ctx._("Action has been hidden by administration")
embed["author"]["name"] = _("Unknown") embed["author"]["name"] = ctx._("Unknown")
return embed return embed
@formatter.compact(event="suppressed", mode="compact") @formatter.compact(event="suppressed", mode="compact")
def compact_suppressed(ctx, change): def compact_suppressed(ctx, change):
content = _("An action has been hidden by administration.") content = ctx._("An action has been hidden by administration.")
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -758,7 +753,7 @@ def embed_import_upload(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = ngettext("Imported {article} with {count} revision", embed["title"] = ctx.ngettext("Imported {article} with {count} revision",
"Imported {article} with {count} revisions", change["logparams"]["count"]).format( "Imported {article} with {count} revisions", change["logparams"]["count"]).format(
article=sanitize_to_markdown(change["title"]), count=change["logparams"]["count"]) article=sanitize_to_markdown(change["title"]), count=change["logparams"]["count"])
return embed return embed
@ -769,7 +764,7 @@ def compact_import_upload(ctx, change):
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = ngettext("[{author}]({author_url}) imported [{article}]({article_url}) with {count} revision{comment}", content = ctx.ngettext("[{author}]({author_url}) imported [{article}]({article_url}) with {count} revision{comment}",
"[{author}]({author_url}) imported [{article}]({article_url}) with {count} revisions{comment}", "[{author}]({author_url}) imported [{article}]({article_url}) with {count} revisions{comment}",
change["logparams"]["count"]).format( change["logparams"]["count"]).format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -785,7 +780,7 @@ def embed_import_interwiki(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = ngettext("Imported {article} with {count} revision from \"{source}\"", embed["title"] = ctx.ngettext("Imported {article} with {count} revision from \"{source}\"",
"Imported {article} with {count} revisions from \"{source}\"", "Imported {article} with {count} revisions from \"{source}\"",
change["logparams"]["count"]).format( change["logparams"]["count"]).format(
article=sanitize_to_markdown(change["title"]), count=change["logparams"]["count"], article=sanitize_to_markdown(change["title"]), count=change["logparams"]["count"],
@ -799,7 +794,7 @@ def compact_import_interwiki(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
source_link = clean_link(create_article_path(change["logparams"]["interwiki_title"])) source_link = clean_link(create_article_path(change["logparams"]["interwiki_title"]))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = ngettext( content = ctx.ngettext(
"[{author}]({author_url}) imported [{article}]({article_url}) with {count} revision from [{source}]({source_url}){comment}", "[{author}]({author_url}) imported [{article}]({article_url}) with {count} revision from [{source}]({source_url}){comment}",
"[{author}]({author_url}) imported [{article}]({article_url}) with {count} revisions from [{source}]({source_url}){comment}", "[{author}]({author_url}) imported [{article}]({article_url}) with {count} revisions from [{source}]({source_url}){comment}",
change["logparams"]["count"]).format( change["logparams"]["count"]).format(
@ -811,17 +806,17 @@ def compact_import_interwiki(ctx, change):
# rights/rights - Assigning rights groups # rights/rights - Assigning rights groups
def get_changed_groups(change: dict) -> [[str], [str]]: def get_changed_groups(change: dict, ctx: Context) -> [[str], [str]]:
"""Creates strings comparing the changes between the user groups for the user""" """Creates strings comparing the changes between the user groups for the user"""
def expiry_parse_time(passed_time): def expiry_parse_time(passed_time):
try: try:
return _(" (until {date_and_time})").format(date_and_time=datetime.datetime.strptime(passed_time, "%Y-%m-%dT%H:%M:%SZ").strftime("%Y-%m-%d %H:%M:%S UTC")) return ctx._(" (until {date_and_time})").format(date_and_time=datetime.datetime.strptime(passed_time, "%Y-%m-%dT%H:%M:%SZ").strftime("%Y-%m-%d %H:%M:%S UTC"))
except ValueError: except ValueError:
return "" return ""
new_group_meta = {_(t["group"]): expiry_parse_time(t.get("expiry", "infinity")) for t in change["logparams"].get("newmetadata", [])} new_group_meta = {ctx._(t["group"]): expiry_parse_time(t.get("expiry", "infinity")) for t in change["logparams"].get("newmetadata", [])}
# translate all groups and pull them into a set # translate all groups and pull them into a set
old_groups = {_(x) for x in change["logparams"]["oldgroups"]} old_groups = {ctx._(x) for x in change["logparams"]["oldgroups"]}
new_groups = {_(x) for x in change["logparams"]["newgroups"]} new_groups = {ctx._(x) for x in change["logparams"]["newgroups"]}
added = [x + new_group_meta.get(x, "") for x in new_groups - old_groups] added = [x + new_group_meta.get(x, "") for x in new_groups - old_groups]
removed = [x for x in old_groups - new_groups] removed = [x for x in old_groups - new_groups]
return added, removed return added, removed
@ -832,18 +827,18 @@ def embed_rights_rights(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed["url"] = create_article_path(sanitize_to_url("User:{}".format(change["title"].split(":")[1]))) embed["url"] = create_article_path(sanitize_to_url("User:{}".format(change["title"].split(":")[1])))
if ctx.event == "rights/rights": if ctx.event == "rights/rights":
embed["title"] = _("Changed group membership for {target}").format(target=sanitize_to_markdown(change["title"].split(":")[1])) embed["title"] = ctx._("Changed group membership for {target}").format(target=sanitize_to_markdown(change["title"].split(":")[1]))
else: else:
embed.set_author(_("System"), "") embed.set_author(ctx._("System"), "")
embed["title"] = _("{target} got autopromoted to a new usergroup").format( embed["title"] = ctx._("{target} got autopromoted to a new usergroup").format(
target=sanitize_to_markdown(change["title"].split(":")[1])) target=sanitize_to_markdown(change["title"].split(":")[1]))
# if len(change["logparams"]["oldgroups"]) < len(change["logparams"]["newgroups"]): # if len(change["logparams"]["oldgroups"]) < len(change["logparams"]["newgroups"]):
# embed["thumbnail"]["url"] = "https://i.imgur.com/WnGhF5g.gif" # embed["thumbnail"]["url"] = "https://i.imgur.com/WnGhF5g.gif"
added, removed = get_changed_groups(change) added, removed = get_changed_groups(change, ctx)
if added: if added:
embed.add_field(ngettext("Added group", "Added groups", len(added)), "\n".join(added), inline=True) embed.add_field(ctx.ngettext("Added group", "Added groups", len(added)), "\n".join(added), inline=True)
if removed: if removed:
embed.add_field(ngettext("Removed group", "Removed groups", len(removed)), "\n".join(removed), inline=True) embed.add_field(ctx.ngettext("Removed group", "Removed groups", len(removed)), "\n".join(removed), inline=True)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
return embed return embed
@ -851,25 +846,25 @@ def embed_rights_rights(ctx, change):
@formatter.compact(event="rights/rights", aliases=["rights/autopromote"]) @formatter.compact(event="rights/rights", aliases=["rights/autopromote"])
def compact_rights_rights(ctx, change): def compact_rights_rights(ctx, change):
link = clean_link(create_article_path(sanitize_to_url("User:{user}".format(user=change["title"].split(":")[1])))) link = clean_link(create_article_path(sanitize_to_url("User:{user}".format(user=change["title"].split(":")[1]))))
added, removed = get_changed_groups(change) added, removed = get_changed_groups(change, ctx)
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
if ctx.event == "rights/rights": if ctx.event == "rights/rights":
group_changes = "Unknown group changes." # Because I don't know if it can handle time extensions correctly group_changes = "Unknown group changes." # Because I don't know if it can handle time extensions correctly
if added and removed: if added and removed:
group_changes = _("Added to {added} and removed from {removed}.").format( group_changes = ctx._("Added to {added} and removed from {removed}.").format(
added=_(", ").join(added), removed=_(", ").join(removed)) added=ctx._(", ").join(added), removed=ctx._(", ").join(removed))
elif added: elif added:
group_changes = _("Added to {added}.").format(added=_(", ").join(added)) group_changes = ctx._("Added to {added}.").format(added=ctx._(", ").join(added))
elif removed: elif removed:
group_changes = _("Removed from {removed}.").format(removed=_(", ").join(removed)) group_changes = ctx._("Removed from {removed}.").format(removed=ctx._(", ").join(removed))
content = _("[{author}]({author_url}) changed group membership for [{target}]({target_url}): {group_changes}{comment}").format( content = ctx._("[{author}]({author_url}) changed group membership for [{target}]({target_url}): {group_changes}{comment}").format(
author=author, author_url=author_url, target=sanitize_to_markdown(change["title"].split(":")[1]), author=author, author_url=author_url, target=sanitize_to_markdown(change["title"].split(":")[1]),
target_url=link, group_changes=group_changes, comment=parsed_comment) target_url=link, group_changes=group_changes, comment=parsed_comment)
else: else:
content = _("The system autopromoted [{target}]({target_url}) to {added}.{comment}").format( content = ctx._("The system autopromoted [{target}]({target_url}) to {added}.{comment}").format(
target=sanitize_to_markdown(change["title"].split(":")[1]), target_url=link, target=sanitize_to_markdown(change["title"].split(":")[1]), target_url=link,
added=_(", ").join(added), comment=parsed_comment) added=ctx._(", ").join(added), comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -880,7 +875,7 @@ def embed_merge_merge(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Merged revision histories of {article} into {dest}").format( embed["title"] = ctx._("Merged revision histories of {article} into {dest}").format(
article=sanitize_to_markdown(change["title"]), article=sanitize_to_markdown(change["title"]),
dest=sanitize_to_markdown(change["logparams"][ dest=sanitize_to_markdown(change["logparams"][
"dest_title"])) "dest_title"]))
@ -893,7 +888,7 @@ def compact_merge_merge(ctx, change):
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
link_dest = clean_link(create_article_path(sanitize_to_url(change["logparams"]["dest_title"]))) link_dest = clean_link(create_article_path(sanitize_to_url(change["logparams"]["dest_title"])))
content = _( content = ctx._(
"[{author}]({author_url}) merged revision histories of [{article}]({article_url}) into [{dest}]({dest_url}){comment}").format( "[{author}]({author_url}) merged revision histories of [{article}]({article_url}) into [{dest}]({dest_url}){comment}").format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, dest_url=link_dest, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, dest_url=link_dest,
dest=sanitize_to_markdown(change["logparams"]["dest_title"]), comment=parsed_comment) dest=sanitize_to_markdown(change["logparams"]["dest_title"]), comment=parsed_comment)
@ -908,14 +903,14 @@ def embed_newusers_autocreate(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created account automatically") embed["title"] = ctx._("Created account automatically")
return embed return embed
@formatter.compact(event="newusers/autocreate") @formatter.compact(event="newusers/autocreate")
def compact_newusers_autocreate(ctx, change): def compact_newusers_autocreate(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
content = _("Account [{author}]({author_url}) was created automatically").format(author=author, content = ctx._("Account [{author}]({author_url}) was created automatically").format(author=author,
author_url=author_url) author_url=author_url)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -928,14 +923,14 @@ def embed_newusers_create(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created account") embed["title"] = ctx._("Created account")
return embed return embed
@formatter.compact(event="newusers/create") @formatter.compact(event="newusers/create")
def compact_newusers_create(ctx, change): def compact_newusers_create(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
content = _("Account [{author}]({author_url}) was created").format(author=author, author_url=author_url) content = ctx._("Account [{author}]({author_url}) was created").format(author=author, author_url=author_url)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -947,7 +942,7 @@ def embed_newusers_create2(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created account {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Created account {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -956,7 +951,7 @@ def compact_newusers_create2(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("Account [{article}]({article_url}) was created by [{author}]({author_url}){comment}").format( content = ctx._("Account [{article}]({article_url}) was created by [{author}]({author_url}){comment}").format(
article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, comment=parsed_comment) article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -969,7 +964,7 @@ def embed_newusers_byemail(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created account {article} and password was sent by email").format( embed["title"] = ctx._("Created account {article} and password was sent by email").format(
article=sanitize_to_markdown(change["title"])) article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -979,7 +974,7 @@ def compact_newusers_byemail(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _( content = ctx._(
"Account [{article}]({article_url}) was created by [{author}]({author_url}) and password was sent by email{comment}").format( "Account [{article}]({article_url}) was created by [{author}]({author_url}) and password was sent by email{comment}").format(
article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, comment=parsed_comment) article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, comment=parsed_comment)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -993,14 +988,33 @@ def embed_newusers_newusers(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url("User:{}".format(change["user"]))) embed["url"] = create_article_path(sanitize_to_url("User:{}".format(change["user"])))
embed["title"] = _("Created account") embed["title"] = ctx._("Created account")
return embed return embed
@formatter.compact(event="newusers/newusers") @formatter.compact(event="newusers/newusers")
def compact_newusers_newusers(ctx, change): def compact_newusers_newusers(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
content = _("Account [{author}]({author_url}) was created").format(author=author, author_url=author_url) content = ctx._("Account [{author}]({author_url}) was created").format(author=author, author_url=author_url)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
# newusers/reclaim - New user reclaimed
@formatter.embed(event="newusers/reclaim", mode="embed")
def embed_newusers_reclaim(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url("User:{}".format(change["user"])))
embed["title"] = ctx._("Reclaimed account")
return embed
@formatter.compact(event="newusers/reclaim")
def compact_newusers_reclaim(ctx, change):
author, author_url = compact_author(ctx, change)
content = ctx._("Account [{author}]({author_url}) was reclaimed").format(author=author, author_url=author_url)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
@ -1012,9 +1026,9 @@ def embed_contentmodel_change(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Changed the content model of the page {article}").format( embed["title"] = ctx._("Changed the content model of the page {article}").format(
article=sanitize_to_markdown(change["title"])) article=sanitize_to_markdown(change["title"]))
embed["description"] = _("Model changed from {old} to {new}: {reason}").format(old=change["logparams"]["oldmodel"], embed["description"] = ctx._("Model changed from {old} to {new}: {reason}").format(old=change["logparams"]["oldmodel"],
new=change["logparams"]["newmodel"], new=change["logparams"]["newmodel"],
reason=ctx.parsedcomment) reason=ctx.parsedcomment)
return embed return embed
@ -1025,7 +1039,7 @@ def compact_contentmodel_change(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) changed the content model of the page [{article}]({article_url}) from {old} to {new}{comment}").format( "[{author}]({author_url}) changed the content model of the page [{article}]({article_url}) from {old} to {new}{comment}").format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link,
old=change["logparams"]["oldmodel"], old=change["logparams"]["oldmodel"],
@ -1041,9 +1055,9 @@ def embed_contentmodel_new(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change, set_desc=False) embed_helper(ctx, embed, change, set_desc=False)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created the page {article} using a non-default content model").format( embed["title"] = ctx._("Created the page {article} using a non-default content model").format(
article=sanitize_to_markdown(change["title"])) article=sanitize_to_markdown(change["title"]))
embed["description"] = _("Created with model {new}: {reason}").format(new=change["logparams"]["newmodel"], embed["description"] = ctx._("Created with model {new}: {reason}").format(new=change["logparams"]["newmodel"],
reason=ctx.parsedcomment) reason=ctx.parsedcomment)
return embed return embed
@ -1053,7 +1067,7 @@ def compact_contentmodel_new(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _( content = ctx._(
"[{author}]({author_url}) created the page [{article}]({article_url}) using a non-default content model {new}{comment}").format( "[{author}]({author_url}) created the page [{article}]({article_url}) using a non-default content model {new}{comment}").format(
author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link,
new=change["logparams"]["newmodel"], comment=parsed_comment) new=change["logparams"]["newmodel"], comment=parsed_comment)
@ -1069,7 +1083,7 @@ def embed_managetags_create(ctx, change):
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
ctx.client.refresh_internal_data() ctx.client.refresh_internal_data()
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"])) embed["title"] = ctx._("Created the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"]))
return embed return embed
@ -1079,7 +1093,7 @@ def compact_managetags_create(ctx, change):
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
ctx.client.refresh_internal_data() ctx.client.refresh_internal_data()
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) created the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author, content = ctx._("[{author}]({author_url}) created the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author,
author_url=author_url, author_url=author_url,
tag= tag=
sanitize_to_markdown( sanitize_to_markdown(
@ -1100,9 +1114,9 @@ def embed_managetags_delete(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
ctx.client.refresh_internal_data() ctx.client.refresh_internal_data()
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Deleted the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"])) embed["title"] = ctx._("Deleted the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"]))
if change["logparams"]["count"] > 0: if change["logparams"]["count"] > 0:
embed.add_field(_('Removed from'), ngettext("{} revision or log entry", "{} revisions and/or log entries", embed.add_field(ctx._('Removed from'), ctx.ngettext("{} revision or log entry", "{} revisions and/or log entries",
change["logparams"]["count"]).format(change["logparams"]["count"])) change["logparams"]["count"]).format(change["logparams"]["count"]))
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
return embed return embed
@ -1115,7 +1129,7 @@ def compact_managetags_delete(ctx, change):
ctx.client.refresh_internal_data() ctx.client.refresh_internal_data()
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
if change["logparams"]["count"] == 0: if change["logparams"]["count"] == 0:
content = _("[{author}]({author_url}) deleted the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author, content = ctx._("[{author}]({author_url}) deleted the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author,
author_url=author_url, author_url=author_url,
tag=sanitize_to_markdown( tag=sanitize_to_markdown(
change[ change[
@ -1124,7 +1138,7 @@ def compact_managetags_delete(ctx, change):
tag_url=link, tag_url=link,
comment=parsed_comment) comment=parsed_comment)
else: else:
content = ngettext( content = ctx.ngettext(
"[{author}]({author_url}) deleted the [tag]({tag_url}) \"{tag}\" and removed it from {count} revision or log entry{comment}", "[{author}]({author_url}) deleted the [tag]({tag_url}) \"{tag}\" and removed it from {count} revision or log entry{comment}",
"[{author}]({author_url}) deleted the [tag]({tag_url}) \"{tag}\" and removed it from {count} revisions and/or log entries{comment}", "[{author}]({author_url}) deleted the [tag]({tag_url}) \"{tag}\" and removed it from {count} revisions and/or log entries{comment}",
change["logparams"]["count"]).format(author=author, author_url=author_url, change["logparams"]["count"]).format(author=author, author_url=author_url,
@ -1142,7 +1156,7 @@ def embed_managetags_activate(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Activated the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"])) embed["title"] = ctx._("Activated the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"]))
return embed return embed
@ -1151,7 +1165,7 @@ def compact_managetags_activate(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) activated the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author, content = ctx._("[{author}]({author_url}) activated the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author,
author_url=author_url, author_url=author_url,
tag=sanitize_to_markdown( tag=sanitize_to_markdown(
change[ change[
@ -1170,7 +1184,7 @@ def embed_managetags_deactivate(ctx, change):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Deactivated the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"])) embed["title"] = ctx._("Deactivated the tag \"{tag}\"").format(tag=sanitize_to_markdown(change["logparams"]["tag"]))
return embed return embed
@ -1179,7 +1193,7 @@ def compact_managetags_deactivate(ctx, change):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) deactivated the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author, content = ctx._("[{author}]({author_url}) deactivated the [tag]({tag_url}) \"{tag}\"{comment}").format(author=author,
author_url=author_url, author_url=author_url,
tag=sanitize_to_markdown( tag=sanitize_to_markdown(
change[ change[

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,20 +11,15 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, compact_summary, clean_link, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url from src.api.util import embed_helper, compact_summary, clean_link, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# Renameuser - https://www.mediawiki.org/wiki/Extension:Renameuser # Renameuser - https://www.mediawiki.org/wiki/Extension:Renameuser
# renameuser/renameuser - Renaming a user # renameuser/renameuser - Renaming a user
@ -35,12 +30,12 @@ def embed_renameuser_renameuser(ctx: Context, change: dict) -> DiscordMessage:
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
edits = change["logparams"]["edits"] edits = change["logparams"]["edits"]
if edits > 0: if edits > 0:
embed["title"] = ngettext("Renamed user \"{old_name}\" with {edits} edit to \"{new_name}\"", embed["title"] = ctx.ngettext("Renamed user \"{old_name}\" with {edits} edit to \"{new_name}\"",
"Renamed user \"{old_name}\" with {edits} edits to \"{new_name}\"", edits).format( "Renamed user \"{old_name}\" with {edits} edits to \"{new_name}\"", edits).format(
old_name=sanitize_to_markdown(change["logparams"]["olduser"]), edits=edits, old_name=sanitize_to_markdown(change["logparams"]["olduser"]), edits=edits,
new_name=sanitize_to_markdown(change["logparams"]["newuser"])) new_name=sanitize_to_markdown(change["logparams"]["newuser"]))
else: else:
embed["title"] = _("Renamed user \"{old_name}\" to \"{new_name}\"").format( embed["title"] = ctx._("Renamed user \"{old_name}\" to \"{new_name}\"").format(
old_name=sanitize_to_markdown(change["logparams"]["olduser"]), old_name=sanitize_to_markdown(change["logparams"]["olduser"]),
new_name=sanitize_to_markdown(change["logparams"]["newuser"])) new_name=sanitize_to_markdown(change["logparams"]["newuser"]))
embed["url"] = create_article_path("User:" + sanitize_to_url(change["logparams"]["newuser"])) embed["url"] = create_article_path("User:" + sanitize_to_url(change["logparams"]["newuser"]))
@ -54,7 +49,7 @@ def compact_renameuser_renameuser(ctx: Context, change: dict) -> DiscordMessage:
edits = change["logparams"]["edits"] edits = change["logparams"]["edits"]
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
if edits > 0: if edits > 0:
content = ngettext( content = ctx.ngettext(
"[{author}]({author_url}) renamed user *{old_name}* with {edits} edit to [{new_name}]({link}){comment}", "[{author}]({author_url}) renamed user *{old_name}* with {edits} edit to [{new_name}]({link}){comment}",
"[{author}]({author_url}) renamed user *{old_name}* with {edits} edits to [{new_name}]({link}){comment}", "[{author}]({author_url}) renamed user *{old_name}* with {edits} edits to [{new_name}]({link}){comment}",
edits).format( edits).format(
@ -63,7 +58,7 @@ def compact_renameuser_renameuser(ctx: Context, change: dict) -> DiscordMessage:
new_name=sanitize_to_markdown(change["logparams"]["newuser"]), link=link, comment=parsed_comment new_name=sanitize_to_markdown(change["logparams"]["newuser"]), link=link, comment=parsed_comment
) )
else: else:
content = _("[{author}]({author_url}) renamed user *{old_name}* to [{new_name}]({link}){comment}").format( content = ctx._("[{author}]({author_url}) renamed user *{old_name}* to [{new_name}]({link}){comment}").format(
author=author, author_url=author_url, old_name=sanitize_to_markdown(change["logparams"]["olduser"]), author=author, author_url=author_url, old_name=sanitize_to_markdown(change["logparams"]["olduser"]),
new_name=sanitize_to_markdown(change["logparams"]["newuser"]), link=link, comment=parsed_comment new_name=sanitize_to_markdown(change["logparams"]["newuser"]), link=link, comment=parsed_comment
) )

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,19 +11,15 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, \ from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, \
clean_link clean_link
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# SpriteSheet - https://www.mediawiki.org/wiki/Extension:SpriteSheet # SpriteSheet - https://www.mediawiki.org/wiki/Extension:SpriteSheet
# sprite/sprite - Editing a sprite # sprite/sprite - Editing a sprite
@ -34,7 +30,7 @@ def embed_sprite_sprite(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Edited the sprite for {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Edited the sprite for {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -42,7 +38,7 @@ def embed_sprite_sprite(ctx: Context, change: dict):
def compact_sprite_sprite(ctx: Context, change: dict): def compact_sprite_sprite(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("[{author}]({author_url}) edited the sprite for [{article}]({article_url})").format(author=author, content = ctx._("[{author}]({author_url}) edited the sprite for [{article}]({article_url})").format(author=author,
author_url=author_url, author_url=author_url,
article=sanitize_to_markdown(change[ article=sanitize_to_markdown(change[
"title"]), "title"]),
@ -57,7 +53,7 @@ def embed_sprite_sheet(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Created the sprite sheet for {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Created the sprite sheet for {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -65,7 +61,7 @@ def embed_sprite_sheet(ctx: Context, change: dict):
def compact_sprite_sheet(ctx: Context, change: dict): def compact_sprite_sheet(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("[{author}]({author_url}) created the sprite sheet for [{article}]({article_url})").format(author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link) content = ctx._("[{author}]({author_url}) created the sprite sheet for [{article}]({article_url})").format(author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link)
return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content)
# sprite/slice - Editing a slice # sprite/slice - Editing a slice
@ -76,14 +72,14 @@ def embed_sprite_slice(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Edited the slice for {article}").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Edited the slice for {article}").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@formatter.compact(event="sprite/slice") @formatter.compact(event="sprite/slice")
def compact_sprite_slice(ctx: Context, change: dict): def compact_sprite_slice(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("[{author}]({author_url}) edited the slice for [{article}]({article_url})").format(author=author, content = ctx._("[{author}]({author_url}) edited the slice for [{article}]({article_url})").format(author=author,
author_url=author_url, author_url=author_url,
article=sanitize_to_markdown(change[ article=sanitize_to_markdown(change[
"title"]), "title"]),

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,19 +11,15 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, \ from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, \
clean_link, compact_summary clean_link, compact_summary
_ = formatters_i18n.gettext
ngettext = formatters_i18n.ngettext
# I cried when I realized I have to migrate Translate extension logs, but this way I atone for my countless sins # I cried when I realized I have to migrate Translate extension logs, but this way I atone for my countless sins
# Translate - https://www.mediawiki.org/wiki/Extension:Translate # Translate - https://www.mediawiki.org/wiki/Extension:Translate
# pagetranslation/mark - Marking a page for translation # pagetranslation/mark - Marking a page for translation
@ -38,7 +34,7 @@ def embed_pagetranslation_mark(ctx: Context, change: dict):
embed["url"] = link + "&oldid={}".format(change["logparams"]["revision"]) embed["url"] = link + "&oldid={}".format(change["logparams"]["revision"])
else: else:
embed["url"] = link + "?oldid={}".format(change["logparams"]["revision"]) embed["url"] = link + "?oldid={}".format(change["logparams"]["revision"])
embed["title"] = _("Marked \"{article}\" for translation").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Marked \"{article}\" for translation").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -52,7 +48,7 @@ def compact_pagetranslation_mark(ctx: Context, change: dict):
link = link + "?oldid={}".format(change["logparams"]["revision"]) link = link + "?oldid={}".format(change["logparams"]["revision"])
link = clean_link(link) link = clean_link(link)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
content = _("[{author}]({author_url}) marked [{article}]({article_url}) for translation{comment}").format( content = ctx._("[{author}]({author_url}) marked [{article}]({article_url}) for translation{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
comment=parsed_comment comment=parsed_comment
@ -67,7 +63,7 @@ def embed_pagetranslation_unmark(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Removed \"{article}\" from the translation system").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Removed \"{article}\" from the translation system").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -76,7 +72,7 @@ def compact_pagetranslation_unmark(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _( content = ctx._(
"[{author}]({author_url}) removed [{article}]({article_url}) from the translation system{comment}").format( "[{author}]({author_url}) removed [{article}]({article_url}) from the translation system{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -92,7 +88,7 @@ def embed_pagetranslation_moveok(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["logparams"]["target"])) embed["url"] = create_article_path(sanitize_to_url(change["logparams"]["target"]))
embed["title"] = _("Completed moving translation pages from \"{article}\" to \"{target}\"").format( embed["title"] = ctx._("Completed moving translation pages from \"{article}\" to \"{target}\"").format(
article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"])) article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"]))
return embed return embed
@ -102,7 +98,7 @@ def compact_pagetranslation_moveok(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"]))) link = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"])))
content = _( content = ctx._(
"[{author}]({author_url}) completed moving translation pages from *{article}* to [{target}]({target_url}){comment}").format( "[{author}]({author_url}) completed moving translation pages from *{article}* to [{target}]({target_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"]), article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"]),
@ -118,7 +114,7 @@ def embed_pagetranslation_movenok(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Encountered a problem while moving \"{article}\" to \"{target}\"").format( embed["title"] = ctx._("Encountered a problem while moving \"{article}\" to \"{target}\"").format(
article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"])) article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"]))
return embed return embed
@ -129,7 +125,7 @@ def compact_pagetranslation_movenok(ctx: Context, change: dict):
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
target_url = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"]))) target_url = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"])))
content = _( content = ctx._(
"[{author}]({author_url}) encountered a problem while moving [{article}]({article_url}) to [{target}]({target_url}){comment}").format( "[{author}]({author_url}) encountered a problem while moving [{article}]({article_url}) to [{target}]({target_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -146,7 +142,7 @@ def embed_pagetranslation_deletefnok(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Failed to delete \"{article}\" which belongs to translatable page \"{target}\"").format( embed["title"] = ctx._("Failed to delete \"{article}\" which belongs to translatable page \"{target}\"").format(
article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"])) article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"]))
return embed return embed
@ -157,7 +153,7 @@ def compact_pagetranslation_deletefnok(ctx: Context, change: dict):
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
target_url = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"]))) target_url = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"])))
content = _( content = ctx._(
"[{author}]({author_url}) failed to delete [{article}]({article_url}) which belongs to translatable page [{target}]({target_url}){comment}").format( "[{author}]({author_url}) failed to delete [{article}]({article_url}) which belongs to translatable page [{target}]({target_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -174,7 +170,7 @@ def embed_pagetranslation_deletelok(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Completed deletion of translation page \"{article}\"").format( embed["title"] = ctx._("Completed deletion of translation page \"{article}\"").format(
article=sanitize_to_markdown(change["title"])) article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -184,7 +180,7 @@ def compact_pagetranslation_deletelok(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _( content = ctx._(
"[{author}]({author_url}) completed deletion of translation page [{article}]({article_url}){comment}").format( "[{author}]({author_url}) completed deletion of translation page [{article}]({article_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -200,7 +196,7 @@ def embed_pagetranslation_deletelnok(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Failed to delete \"{article}\" which belongs to translation page \"{target}\"").format( embed["title"] = ctx._("Failed to delete \"{article}\" which belongs to translation page \"{target}\"").format(
article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"])) article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown(change["logparams"]["target"]))
return embed return embed
@ -211,7 +207,7 @@ def compact_pagetranslation_deletelnok(ctx: Context, change: dict):
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
target_url = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"]))) target_url = clean_link(create_article_path(sanitize_to_url(change["logparams"]["target"])))
content = _( content = ctx._(
"[{author}]({author_url}) failed to delete [{article}]({article_url}) which belongs to translation page [{target}]({target_url}){comment}").format( "[{author}]({author_url}) failed to delete [{article}]({article_url}) which belongs to translation page [{target}]({target_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -228,7 +224,7 @@ def embed_pagetranslation_encourage(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Encouraged translation of \"{article}\"").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Encouraged translation of \"{article}\"").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -237,7 +233,7 @@ def compact_pagetranslation_encourage(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("[{author}]({author_url}) encouraged translation of [{article}]({article_url}){comment}").format( content = ctx._("[{author}]({author_url}) encouraged translation of [{article}]({article_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
comment=parsed_comment comment=parsed_comment
@ -252,7 +248,7 @@ def embed_pagetranslation_discourage(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Discouraged translation of \"{article}\"").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Discouraged translation of \"{article}\"").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -261,7 +257,7 @@ def compact_pagetranslation_discourage(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _("[{author}]({author_url}) discouraged translation of [{article}]({article_url}){comment}").format( content = ctx._("[{author}]({author_url}) discouraged translation of [{article}]({article_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
comment=parsed_comment comment=parsed_comment
@ -279,13 +275,13 @@ def embed_pagetranslation_prioritylanguages(ctx: Context, change: dict):
if "languages" in change["logparams"]: if "languages" in change["logparams"]:
languages = "`, `".join(change["logparams"]["languages"].split(",")) languages = "`, `".join(change["logparams"]["languages"].split(","))
if change["logparams"]["force"] == "on": if change["logparams"]["force"] == "on":
embed["title"] = _("Limited languages for \"{article}\" to `{languages}`").format(article=sanitize_to_markdown(change["title"]), embed["title"] = ctx._("Limited languages for \"{article}\" to `{languages}`").format(article=sanitize_to_markdown(change["title"]),
languages=languages) languages=languages)
else: else:
embed["title"] = _("Priority languages for \"{article}\" set to `{languages}`").format( embed["title"] = ctx._("Priority languages for \"{article}\" set to `{languages}`").format(
article=sanitize_to_markdown(change["title"]), languages=languages) article=sanitize_to_markdown(change["title"]), languages=languages)
else: else:
embed["title"] = _("Removed priority languages from \"{article}\"").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Removed priority languages from \"{article}\"").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -297,21 +293,21 @@ def compact_pagetranslation_prioritylanguages(ctx: Context, change: dict):
if "languages" in change["logparams"]: if "languages" in change["logparams"]:
languages = "`, `".join(change["logparams"]["languages"].split(",")) languages = "`, `".join(change["logparams"]["languages"].split(","))
if change["logparams"]["force"] == "on": if change["logparams"]["force"] == "on":
content = _( content = ctx._(
"[{author}]({author_url}) limited languages for [{article}]({article_url}) to `{languages}`{comment}").format( "[{author}]({author_url}) limited languages for [{article}]({article_url}) to `{languages}`{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
languages=languages, comment=parsed_comment languages=languages, comment=parsed_comment
) )
else: else:
content = _( content = ctx._(
"[{author}]({author_url}) set the priority languages for [{article}]({article_url}) to `{languages}`{comment}").format( "[{author}]({author_url}) set the priority languages for [{article}]({article_url}) to `{languages}`{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
languages=languages, comment=parsed_comment languages=languages, comment=parsed_comment
) )
else: else:
content = _( content = ctx._(
"[{author}]({author_url}) removed priority languages from [{article}]({article_url}){comment}").format( "[{author}]({author_url}) removed priority languages from [{article}]({article_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -328,7 +324,7 @@ def embed_pagetranslation_associate(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Added translatable page \"{article}\" to aggregate group \"{group}\"").format( embed["title"] = ctx._("Added translatable page \"{article}\" to aggregate group \"{group}\"").format(
article=sanitize_to_markdown(change["title"]), group=change["logparams"]["aggregategroup"]) article=sanitize_to_markdown(change["title"]), group=change["logparams"]["aggregategroup"])
return embed return embed
@ -338,7 +334,7 @@ def compact_pagetranslation_associate(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _( content = ctx._(
"[{author}]({author_url}) added translatable page [{article}]({article_url}) to aggregate group \"{group}\"{comment}").format( "[{author}]({author_url}) added translatable page [{article}]({article_url}) to aggregate group \"{group}\"{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -354,7 +350,7 @@ def embed_pagetranslation_dissociate(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Removed translatable page \"{article}\" from aggregate group \"{group}\"").format( embed["title"] = ctx._("Removed translatable page \"{article}\" from aggregate group \"{group}\"").format(
article=sanitize_to_markdown(change["title"]), group=change["logparams"]["aggregategroup"]) article=sanitize_to_markdown(change["title"]), group=change["logparams"]["aggregategroup"])
return embed return embed
@ -364,7 +360,7 @@ def compact_pagetranslation_dissociate(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
content = _( content = ctx._(
"[{author}]({author_url}) removed translatable page [{article}]({article_url}) from aggregate group \"{group}\"{comment}").format( "[{author}]({author_url}) removed translatable page [{article}]({article_url}) from aggregate group \"{group}\"{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
@ -384,7 +380,7 @@ def embed_translationreview_message(ctx: Context, change: dict):
embed["url"] = link + "&oldid={}".format(change["logparams"]["revision"]) embed["url"] = link + "&oldid={}".format(change["logparams"]["revision"])
else: else:
embed["url"] = link + "?oldid={}".format(change["logparams"]["revision"]) embed["url"] = link + "?oldid={}".format(change["logparams"]["revision"])
embed["title"] = _("Reviewed translation \"{article}\"").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Reviewed translation \"{article}\"").format(article=sanitize_to_markdown(change["title"]))
return embed return embed
@ -398,7 +394,7 @@ def compact_translationreview_message(ctx: Context, change: dict):
else: else:
link = link + "?oldid={}".format(change["logparams"]["revision"]) link = link + "?oldid={}".format(change["logparams"]["revision"])
link = clean_link(link) link = clean_link(link)
content = _("[{author}]({author_url}) reviewed translation [{article}]({article_url}){comment}").format( content = ctx._("[{author}]({author_url}) reviewed translation [{article}]({article_url}){comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,
comment=parsed_comment comment=parsed_comment
@ -413,11 +409,11 @@ def embed_translationreview_group(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
embed["title"] = _("Changed the state of `{language}` translations of \"{article}\"").format( embed["title"] = ctx._("Changed the state of `{language}` translations of \"{article}\"").format(
language=change["logparams"]["language"], article=sanitize_to_markdown(change["title"])) language=change["logparams"]["language"], article=sanitize_to_markdown(change["title"]))
if "old-state" in change["logparams"]: if "old-state" in change["logparams"]:
embed.add_field(_("Old state"), change["logparams"]["old-state"], inline=True) embed.add_field(ctx._("Old state"), change["logparams"]["old-state"], inline=True)
embed.add_field(_("New state"), change["logparams"]["new-state"], inline=True) embed.add_field(ctx._("New state"), change["logparams"]["new-state"], inline=True)
return embed return embed
@ -427,7 +423,7 @@ def compact_translationreview_group(ctx: Context, change: dict):
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
if "old-state" in change["logparams"]: if "old-state" in change["logparams"]:
content = _( content = ctx._(
"[{author}]({author_url}) changed the state of `{language}` translations of [{article}]({article_url}) from `{old_state}` to `{new_state}`{comment}").format( "[{author}]({author_url}) changed the state of `{language}` translations of [{article}]({article_url}) from `{old_state}` to `{new_state}`{comment}").format(
author=author, author_url=author_url, language=change["logparams"]["language"], author=author, author_url=author_url, language=change["logparams"]["language"],
article=sanitize_to_markdown(change["logparams"]["group-label"]), article_url=link, article=sanitize_to_markdown(change["logparams"]["group-label"]), article_url=link,
@ -435,7 +431,7 @@ def compact_translationreview_group(ctx: Context, change: dict):
comment=parsed_comment comment=parsed_comment
) )
else: else:
content = _( content = ctx._(
"[{author}]({author_url}) changed the state of `{language}` translations of [{article}]({article_url}) to `{new_state}`{comment}").format( "[{author}]({author_url}) changed the state of `{language}` translations of [{article}]({article_url}) to `{new_state}`{comment}").format(
author=author, author_url=author_url, language=change["logparams"]["language"], author=author, author_url=author_url, language=change["logparams"]["language"],
article=sanitize_to_markdown(change["logparams"]["group-label"]), article_url=link, article=sanitize_to_markdown(change["logparams"]["group-label"]), article_url=link,
@ -446,13 +442,13 @@ def compact_translationreview_group(ctx: Context, change: dict):
# pagelang/pagelang - Changing the language of a page # pagelang/pagelang - Changing the language of a page
def get_languages(change): def get_languages(change: dict, ctx: Context):
old_lang = "`{}`".format(change["logparams"]["oldlanguage"]) old_lang = "`{}`".format(change["logparams"]["oldlanguage"])
if change["logparams"]["oldlanguage"][-5:] == "[def]": if change["logparams"]["oldlanguage"][-5:] == "[def]":
old_lang = "`{}` {}".format(change["logparams"]["oldlanguage"][:-5], _("(default)")) old_lang = "`{}` {}".format(change["logparams"]["oldlanguage"][:-5], ctx._("(default)"))
new_lang = "`{}`".format(change["logparams"]["newlanguage"]) new_lang = "`{}`".format(change["logparams"]["newlanguage"])
if change["logparams"]["newlanguage"][-5:] == "[def]": if change["logparams"]["newlanguage"][-5:] == "[def]":
new_lang = "`{}` {}".format(change["logparams"]["oldlanguage"][:-5], _("(default)")) new_lang = "`{}` {}".format(change["logparams"]["oldlanguage"][:-5], ctx._("(default)"))
return old_lang, new_lang return old_lang, new_lang
@formatter.embed(event="pagelang/pagelang") @formatter.embed(event="pagelang/pagelang")
@ -460,10 +456,10 @@ def embed_pagelang_pagelang(ctx: Context, change: dict):
embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url)
embed_helper(ctx, embed, change) embed_helper(ctx, embed, change)
embed["url"] = create_article_path(sanitize_to_url(change["title"])) embed["url"] = create_article_path(sanitize_to_url(change["title"]))
old_lang, new_lang = get_languages(change) old_lang, new_lang = get_languages(change, ctx)
embed["title"] = _("Changed the language of \"{article}\"").format(article=sanitize_to_markdown(change["title"])) embed["title"] = ctx._("Changed the language of \"{article}\"").format(article=sanitize_to_markdown(change["title"]))
embed.add_field(_("Old language"), old_lang, inline=True) embed.add_field(ctx._("Old language"), old_lang, inline=True)
embed.add_field(_("New language"), new_lang, inline=True) embed.add_field(ctx._("New language"), new_lang, inline=True)
return embed return embed
@ -472,8 +468,8 @@ def compact_pagelang_pagelang(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)
parsed_comment = compact_summary(ctx) parsed_comment = compact_summary(ctx)
link = clean_link(create_article_path(sanitize_to_url(change["title"]))) link = clean_link(create_article_path(sanitize_to_url(change["title"])))
old_lang, new_lang = get_languages(change) old_lang, new_lang = get_languages(change, ctx)
content = _( content = ctx._(
"[{author}]({author_url}) changed the language of [{article}]({article_url}) from {old_lang} to {new_lang}{comment}").format( "[{author}]({author_url}) changed the language of [{article}]({article_url}) from {old_lang} to {new_lang}{comment}").format(
author=author, author_url=author_url, author=author, author_url=author_url,
article=sanitize_to_markdown(change["title"]), article_url=link, article=sanitize_to_markdown(change["title"]), article_url=link,

View file

@ -70,472 +70,5 @@
"rcgcdb.discord": {}, "rcgcdb.discord": {},
"rcgcdb.wiki": {} "rcgcdb.wiki": {}
} }
},
"event_appearance": {
"new": {
"icon": "https://i.imgur.com/6HIbEq8.png",
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
"emoji": "🆕"
},
"edit": {
"icon": "",
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
"emoji": "📝"
},
"upload/overwrite": {
"icon": "https://i.imgur.com/egJpa81.png",
"color": 12390624,
"emoji": "🖼️"
},
"upload/upload": {
"icon": "https://i.imgur.com/egJpa81.png",
"color": 12390624,
"emoji": "🖼️"
},
"upload/revert": {
"icon": "https://i.imgur.com/egJpa81.png",
"color": 12390624,
"emoji": "⏮️"
},
"delete/delete": {
"icon": "https://i.imgur.com/BU77GD3.png",
"color": 1,
"emoji": "🗑️"
},
"delete/delete_redir": {
"icon": "https://i.imgur.com/BU77GD3.png",
"color": 1,
"emoji": "🗑️"
},
"delete/restore": {
"icon": "https://i.imgur.com/9MnROIU.png",
"color": 1,
"emoji": "♻️"
},
"delete/revision": {
"icon": "https://i.imgur.com/1gps6EZ.png",
"color": 1,
"emoji": "👁️"
},
"delete/event": {
"icon": "https://i.imgur.com/1gps6EZ.png",
"color": 1,
"emoji": "👁️"
},
"merge/merge": {
"icon": "https://i.imgur.com/uQMK9XK.png",
"color": 25600,
"emoji": "🖇️"
},
"move/move": {
"icon": "https://i.imgur.com/eXz9dog.png",
"color": 25600,
"emoji": "📨"
},
"move/move_redir": {
"icon": "https://i.imgur.com/UtC3YX2.png",
"color": 25600,
"emoji": "📨"
},
"block/block": {
"icon": "https://i.imgur.com/g7KgZHf.png",
"color": 1,
"emoji": "🚫"
},
"block/unblock": {
"icon": "https://i.imgur.com/bvtBJ8o.png",
"color": 1,
"emoji": "✅"
},
"block/reblock": {
"icon": "https://i.imgur.com/g7KgZHf.png",
"color": 1,
"emoji": "🚫"
},
"protect/protect": {
"icon": "https://i.imgur.com/bzPt89Z.png",
"color": 16312092,
"emoji": "🔒"
},
"protect/modify": {
"icon": "https://i.imgur.com/bzPt89Z.png",
"color": 16312092,
"emoji": "🔐"
},
"protect/move_prot": {
"icon": "https://i.imgur.com/bzPt89Z.png",
"color": 16312092,
"emoji": "🔏"
},
"protect/unprotect": {
"icon": "https://i.imgur.com/2wN3Qcq.png",
"color": 16312092,
"emoji": "🔓"
},
"import/upload": {
"icon": "",
"color": 65280,
"emoji": "📥"
},
"import/interwiki": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 65280,
"emoji": "📥"
},
"rights/rights": {
"icon": "",
"color": 16711680,
"emoji": "🏅"
},
"rights/autopromote": {
"icon": "",
"color": 16711680,
"emoji": "🏅"
},
"abusefilter/modify": {
"icon": "https://i.imgur.com/Sn2NzRJ.png",
"color": 16711680,
"emoji": "🔍"
},
"abusefilter/create": {
"icon": "https://i.imgur.com/Sn2NzRJ.png",
"color": 16711680,
"emoji": "🔍"
},
"interwiki/iw_add": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 16711680,
"emoji": "🔗"
},
"interwiki/iw_edit": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 16711680,
"emoji": "🔗"
},
"interwiki/iw_delete": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 16711680,
"emoji": "🔗"
},
"curseprofile/comment-created": {
"icon": "https://i.imgur.com/Lvy5E32.png",
"color": 16089376,
"emoji": "✉️"
},
"curseprofile/comment-edited": {
"icon": "https://i.imgur.com/Lvy5E32.png",
"color": 16089376,
"emoji": "📧"
},
"curseprofile/comment-deleted": {
"icon": "",
"color": 16089376,
"emoji": "🗑️"
},
"curseprofile/comment-purged":{
"icon":"",
"color": 16089376,
"emoji": "👁️"
},
"curseprofile/comment-replied": {
"icon": "https://i.imgur.com/hkyYsI1.png",
"color": 16089376,
"emoji": "📩"
},
"curseprofile/profile-edited": {
"icon": "",
"color": 16089376,
"emoji": "📌"
},
"contentmodel/change": {
"icon": "",
"color": 25600,
"emoji": "📋"
},
"contentmodel/new": {
"icon": "",
"color": 25600,
"emoji": "📋"
},
"cargo/deletetable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"cargo/createtable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"cargo/replacetable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"cargo/recreatetable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"sprite/sprite": {
"icon": "",
"color": 16776960,
"emoji": "🪟"
},
"sprite/sheet": {
"icon": "",
"color": 16776960,
"emoji": "🪟"
},
"sprite/slice": {
"icon": "",
"color": 16776960,
"emoji": "🪟"
},
"managetags/create": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"managetags/delete": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"managetags/activate": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"managetags/deactivate": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"newusers/autocreate": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/byemail": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/create": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/create2": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/newusers": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"managewiki/delete": {
"icon": "",
"color": 8421504,
"emoji": "🗑️"
},
"managewiki/lock": {
"icon": "",
"color": 8421504,
"emoji": "🔒"
},
"managewiki/namespaces": {
"icon": "",
"color": 8421504,
"emoji": "📦"
},
"managewiki/namespaces-delete": {
"icon": "",
"color": 8421504,
"emoji": "🗑️"
},
"managewiki/rights": {
"icon": "",
"color": 8421504,
"emoji": "🏅"
},
"managewiki/settings": {
"icon": "",
"color": 8421504,
"emoji": "⚙️"
},
"managewiki/undelete": {
"icon": "",
"color": 8421504,
"emoji": "♻️"
},
"managewiki/unlock": {
"icon": "",
"color": 8421504,
"emoji": "🔓"
},
"datadump/generate": {
"icon": "",
"color": 8421504,
"emoji": "📤"
},
"datadump/delete": {
"icon": "",
"color": 8421504,
"emoji": "🗑️"
},
"pagetranslation/mark": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/unmark": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/moveok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/movenok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletefok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletefnok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletelok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletelnok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/encourage": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/discourage": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/prioritylanguages": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/associate": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/dissociate": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"translationreview/message": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"translationreview/group": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagelang/pagelang": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"renameuser/renameuser": {
"icon": "",
"color": 8421504,
"emoji": "📛"
},
"suppressed": {
"icon": "https://i.imgur.com/1gps6EZ.png",
"color": 1,
"emoji": "👁️"
},
"discussion": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/post": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/reply": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/poll": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/quiz": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/wall/post": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 3752525,
"emoji": "✉️"
},
"discussion/wall/reply": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 3752525,
"emoji": "📩"
},
"discussion/comment/post": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 10802,
"emoji": "🗒️"
},
"discussion/comment/reply": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 10802,
"emoji": "🗒️"
},
"unknown": {
"icon": "",
"color": 0,
"emoji": "❓"
},
"webhook/remove": {
"icon": "https://raw.githubusercontent.com/Markus-Rost/discord-wiki-bot/master/dashboard/src/icon.png",
"color": 0,
"emoji": "<:wikibot:588723255972593672>"
},
"bot/exception": {
"icon": "https://raw.githubusercontent.com/Markus-Rost/discord-wiki-bot/master/dashboard/src/icon.png",
"color": 0,
"emoji": "<:wikibot:588723255972593672>"
}
} }
} }

View file

@ -0,0 +1 @@
from .formatter import *

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,17 +11,16 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
from datetime import datetime
import src.misc import src.misc
from src.exceptions import TagNotFound import sched
from bs4 import BeautifulSoup from typing import Union, Callable
from typing import Union, TYPE_CHECKING, Optional
from collections import OrderedDict from collections import OrderedDict
from functools import cache from typing import TYPE_CHECKING, Optional
from urllib.parse import urlparse, urlunparse
if TYPE_CHECKING: if TYPE_CHECKING:
from src.wiki import Wiki from src.wiki import Wiki
@ -30,13 +29,55 @@ class Client:
""" """
A client for interacting with RcGcDw when creating formatters or hooks. A client for interacting with RcGcDw when creating formatters or hooks.
""" """
def __init__(self, wiki): def __init__(self, hooks, wiki):
self._formatters = hooks
self.__recent_changes: Wiki = wiki self.__recent_changes: Wiki = wiki
self.WIKI_API_PATH: str = src.misc.WIKI_API_PATH
self.WIKI_ARTICLE_PATH: str = src.misc.WIKI_ARTICLE_PATH
self.WIKI_SCRIPT_PATH: str = src.misc.WIKI_SCRIPT_PATH
self.WIKI_JUST_DOMAIN: str = src.misc.WIKI_JUST_DOMAIN
self.content_parser = src.misc.ContentParser self.content_parser = src.misc.ContentParser
self.tags = self.__recent_changes.tags
self.LinkParser: type(src.misc.LinkParser) = src.misc.LinkParser self.LinkParser: type(src.misc.LinkParser) = src.misc.LinkParser
self.last_request: Optional[dict] = None self.scheduler: sched.scheduler = sched.scheduler()
#self.make_api_request: src.rc.wiki.__recent_changes.api_request = self.__recent_changes.api_request #self.make_api_request: src.rc.wiki.__recent_changes.api_request = self.__recent_changes.api_request
def schedule(self, function: Callable, *args: list, every: Optional[float] = None, at: Optional[str] = None,
priority: int = 5, **kwargs: dict):
"""Schedules a function indefinitely, does not execute function immediately
Parameters:
function (callable): a function to call each scheduled execution
*args: arguments provided to callable function
every (float): float of time between each execution
at (str): string of time
priority (int): priority of the task (lower - more important, RcGcDw tasks are executed at 5)
**kwargs: key-value provided to callable function
Returns:
FIRST sched.event, later cycles have their own sched.event and will be viewable by client.scheduler.queue
"""
def return_delay(given_time: Union[float, str]) -> float:
"""Converts UTC time to amount of seconds from now, if amount of seconds given returns seconds as a float"""
if isinstance(given_time, float) or isinstance(given_time, int):
return float(given_time)
now = datetime.utcnow()
then = datetime(now.year, now.month, now.day, *(map(int, given_time.split(':'))), 0, 0)
return float((then - now).seconds)
def wrap_reschedule(function, period: float, *args, **kwargs):
"""Function for rescheduling a function every period of times. It provides args and kwargs to the function"""
self.schedule(function, every=period, *args, **kwargs)
function(*args, **kwargs)
if not any([every, at]) or all([every, at]):
raise ValueError("Either every or at (and not both) has to be set for client.schedule function.")
return self.scheduler.enter(return_delay(every or at), priority, wrap_reschedule, argument=(function, every or 86400.0, *args), kwargs=kwargs)
def refresh_internal_data(self):
"""Refreshes internal storage data for wiki tags and MediaWiki messages."""
self.__recent_changes.init_info()
@property @property
def namespaces(self) -> dict: def namespaces(self) -> dict:
"""Return a dict of namespaces, if None return empty dict""" """Return a dict of namespaces, if None return empty dict"""
@ -45,37 +86,6 @@ class Client:
else: else:
return dict() return dict()
@cache
def tag(self, tag_name: str):
for tag in self.last_request["tags"]:
if tag["name"] == tag_name:
try:
return (BeautifulSoup(tag["displayname"], "lxml")).get_text()
except KeyError:
return None # Tags with no display name are hidden and should not appear on RC as well
raise TagNotFound
@property
def WIKI_API_PATH(self):
return self.__recent_changes.script_url + "api.php"
@property
def WIKI_SCRIPT_PATH(self):
return self.__recent_changes.script_url
@property
def WIKI_JUST_DOMAIN(self):
parsed_url = urlparse(self.__recent_changes.script_url)
return urlunparse((*parsed_url[0:2], "", "", "", ""))
@property
def WIKI_ARTICLE_PATH(self):
parsed_url = urlparse(self.__recent_changes.script_url)
try:
return urlunparse((*parsed_url[0:2], "", "", "", "")) + self.last_request["query"]["general"]["articlepath"]
except KeyError:
return urlunparse((*parsed_url[0:2], "", "", "", "")) + "wiki/"
def parse_links(self, summary: str): def parse_links(self, summary: str):
link_parser = self.LinkParser() link_parser = self.LinkParser()
link_parser.feed(summary) link_parser.feed(summary)
@ -113,6 +123,9 @@ class Client:
""" """
return self.__recent_changes.api_request(params, *json_path, timeout=timeout, allow_redirects=allow_redirects) return self.__recent_changes.api_request(params, *json_path, timeout=timeout, allow_redirects=allow_redirects)
def get_formatters(self):
return self._formatters
def get_ipmapper(self) -> dict: def get_ipmapper(self) -> dict:
"""Returns a dict mapping IPs with amount of their edits""" """Returns a dict mapping IPs with amount of their edits"""
return self.__recent_changes.map_ips return self.__recent_changes.map_ips

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,26 +11,34 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
import gettext
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from collections import namedtuple
if TYPE_CHECKING: if TYPE_CHECKING:
from src.api.client import Client from src.api.client import Client
class Context: class Context:
"""Context object containing client and some metadata regarding specific formatter call""" """Context object containing client and some metadata regarding specific formatter call,
def __init__(self, display_options: namedtuple("Settings", ["lang", "display"]), webhook_url: list, client: Client): they are mainly used as a bridge between part that fetches the changes and API's formatters"""
def __init__(self, message_type: str, feed_type: str, webhook_url: str, client: Client, language: gettext.GNUTranslations, settings: dict):
self.client = client self.client = client
self.webhook_url = webhook_url self.webhook_url = webhook_url
self.display_options = display_options self.message_type = message_type
self.message_type = display_options.display self.feed_type = feed_type
self.categories = None self.categories = None
self.parsedcomment = None self.parsedcomment = None
self.event = None self.event = None
self.comment_page = None self.comment_page = None
self._ = language.gettext # Singular translations (ex. ctx._("Large goat"))
self.gettext = language.gettext # In case you dislike _ or using "protected field" of ctx
self.ngettext = language.npgettext # Plural translations depending on amount (ex. ctx.ngettext("{} action", "{} actions", action_amount))
self.pgettext = language.pgettext # Translation with context (ex. ctx.pgettext("From mediawiki module", "Blocked {} user"))
self.npgettext = language.npgettext # Plural translation with context (ex. ctx.npgettext("From mediawiki module", "Edited {} time", "Edited {} times", edit_amoint)
self.settings = settings
def set_categories(self, cats): def set_categories(self, cats):
self.categories = cats self.categories = cats
@ -40,3 +48,6 @@ class Context:
def set_comment_page(self, page): def set_comment_page(self, page):
self.comment_page = page self.comment_page = page
def __str__(self):
return f"<Context message_type={self.message_type} feed_type={self.feed_type} event={self.event} webhook_url={self.webhook_url}"

View file

@ -1,17 +1,17 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
#
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
#
# RcGcDw is distributed in the hope that it will be useful, # RcGcDw is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import src.api.hooks import src.api.hooks
import logging import logging
from src.configloader import settings from src.configloader import settings
@ -21,6 +21,7 @@ from typing import Optional, Callable
logger = logging.getLogger("src.api.formatter") logger = logging.getLogger("src.api.formatter")
def _register_formatter(func, kwargs, formatter_type: str, action_type=None): def _register_formatter(func, kwargs, formatter_type: str, action_type=None):
""" """
Registers a formatter inside of src.rcgcdw.formatter_hooks Registers a formatter inside of src.rcgcdw.formatter_hooks
@ -34,12 +35,13 @@ def _register_formatter(func, kwargs, formatter_type: str, action_type=None):
action_type = kwargs.get("event", action_type) action_type = kwargs.get("event", action_type)
if action_type is None: if action_type is None:
raise FormatterBreaksAPISpec("event type") raise FormatterBreaksAPISpec("event type")
for act in [action_type] + kwargs.get("aliases", []): # Make action_type string a list and merge with aliases if settings["appearance"]["mode"] == formatter_type:
if act in src.api.hooks.formatter_hooks[formatter_type]: for act in [action_type] + kwargs.get("aliases", []): # Make action_type string a list and merge with aliases
logger.warning(f"Action {act} is already defined inside of " if act in src.api.hooks.formatter_hooks:
f"{src.api.hooks.formatter_hooks[formatter_type][act].__module__}! " logger.warning(f"Action {act} is already defined inside of "
f"Overwriting it with one from {func.__module__}") f"{src.api.hooks.formatter_hooks[act].__module__}! "
src.api.hooks.formatter_hooks[formatter_type][act] = func f"Overwriting it with one from {func.__module__}")
src.api.hooks.formatter_hooks[act] = func
def embed(**kwargs): def embed(**kwargs):

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,7 +11,7 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
import src.api.hooks import src.api.hooks

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,10 +11,13 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
# Made just to avoid circular imports # Made just to avoid circular imports
from typing import Callable from typing import Callable, List, Dict
formatter_hooks: dict[str, dict[str, Callable]] = {"embed": {}, "compact": {}} from src.discord.message import DiscordMessage, DiscordMessageMetadata
pre_hooks = [] from src.api.context import Context
post_hooks = []
formatter_hooks: Dict[str, Callable[[Context, dict], DiscordMessage]] = {}
pre_hooks: List[Callable[[Context, dict], None]] = []
post_hooks: List[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], None]] = []

View file

@ -0,0 +1,513 @@
{
"rc_enabled": true,
"lang": "en",
"avatars": {
"connection_failed": "https://i.imgur.com/2jWQEt1.png",
"connection_restored": "",
"no_event": "",
"embed": "",
"compact": ""
},
"show_updown_messages": true,
"ignored_namespaces": [],
"extensions_dir": "extensions",
"error_tolerance": 1,
"send_empty_overview": false,
"license_detection": false,
"license_regex_detect": "\\{\\{(license|lizenz|licence|copyright)",
"license_regex": "\\{\\{(license|lizenz|licence|copyright)(\\ |\\|)(?P<license>.*?)\\}\\}",
"show_added_categories": true,
"show_bots": false,
"show_abuselog": false,
"hide_ips": false,
"discord_message_cooldown": 0,
"datafile_path": "data.json",
"auto_suppression": {
"enabled": false,
"db_location": ":memory:"
},
"appearance":{
"mode": "embed",
"embed": {
"show_edit_changes": null,
"show_footer": true,
"embed_images": null
}
},
"fandom_discussions": {
"appearance": {
"mode": "embed",
"embed": {
"show_content": true
}
},
"show_forums": []
},
"event_appearance": {
"daily_overview": {
"icon": "",
"color": 16312092,
"emoji": ""
},
"new": {
"icon": "https://i.imgur.com/6HIbEq8.png",
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
"emoji": "🆕"
},
"edit": {
"icon": "",
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
"emoji": "📝"
},
"upload/overwrite": {
"icon": "https://i.imgur.com/egJpa81.png",
"color": 12390624,
"emoji": "🖼️"
},
"upload/upload": {
"icon": "https://i.imgur.com/egJpa81.png",
"color": 12390624,
"emoji": "🖼️"
},
"upload/revert": {
"icon": "https://i.imgur.com/egJpa81.png",
"color": 12390624,
"emoji": "⏮️"
},
"delete/delete": {
"icon": "https://i.imgur.com/BU77GD3.png",
"color": 1,
"emoji": "🗑️"
},
"delete/delete_redir": {
"icon": "https://i.imgur.com/BU77GD3.png",
"color": 1,
"emoji": "🗑️"
},
"delete/restore": {
"icon": "https://i.imgur.com/9MnROIU.png",
"color": 1,
"emoji": "♻️"
},
"delete/revision": {
"icon": "https://i.imgur.com/1gps6EZ.png",
"color": 1,
"emoji": "👁️"
},
"delete/event": {
"icon": "https://i.imgur.com/1gps6EZ.png",
"color": 1,
"emoji": "👁️"
},
"merge/merge": {
"icon": "https://i.imgur.com/uQMK9XK.png",
"color": 25600,
"emoji": "🖇️"
},
"move/move": {
"icon": "https://i.imgur.com/eXz9dog.png",
"color": 25600,
"emoji": "📨"
},
"move/move_redir": {
"icon": "https://i.imgur.com/UtC3YX2.png",
"color": 25600,
"emoji": "📨"
},
"block/block": {
"icon": "https://i.imgur.com/g7KgZHf.png",
"color": 1,
"emoji": "🚫"
},
"block/unblock": {
"icon": "https://i.imgur.com/bvtBJ8o.png",
"color": 1,
"emoji": "✅"
},
"block/reblock": {
"icon": "https://i.imgur.com/g7KgZHf.png",
"color": 1,
"emoji": "🚫"
},
"protect/protect": {
"icon": "https://i.imgur.com/bzPt89Z.png",
"color": 16312092,
"emoji": "🔒"
},
"protect/modify": {
"icon": "https://i.imgur.com/bzPt89Z.png",
"color": 16312092,
"emoji": "🔐"
},
"protect/move_prot": {
"icon": "https://i.imgur.com/bzPt89Z.png",
"color": 16312092,
"emoji": "🔏"
},
"protect/unprotect": {
"icon": "https://i.imgur.com/2wN3Qcq.png",
"color": 16312092,
"emoji": "🔓"
},
"import/upload": {
"icon": "",
"color": 65280,
"emoji": "📥"
},
"import/interwiki": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 65280,
"emoji": "📥"
},
"rights/rights": {
"icon": "",
"color": 16711680,
"emoji": "🏅"
},
"rights/autopromote": {
"icon": "",
"color": 16711680,
"emoji": "🏅"
},
"abusefilter/modify": {
"icon": "https://i.imgur.com/Sn2NzRJ.png",
"color": 16711680,
"emoji": "🔍"
},
"abusefilter/create": {
"icon": "https://i.imgur.com/Sn2NzRJ.png",
"color": 16711680,
"emoji": "🔍"
},
"interwiki/iw_add": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 16711680,
"emoji": "🔗"
},
"interwiki/iw_edit": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 16711680,
"emoji": "🔗"
},
"interwiki/iw_delete": {
"icon": "https://i.imgur.com/sFkhghb.png",
"color": 16711680,
"emoji": "🔗"
},
"curseprofile/comment-created": {
"icon": "https://i.imgur.com/Lvy5E32.png",
"color": 16089376,
"emoji": "✉️"
},
"curseprofile/comment-edited": {
"icon": "https://i.imgur.com/Lvy5E32.png",
"color": 16089376,
"emoji": "📧"
},
"curseprofile/comment-deleted": {
"icon": "",
"color": 16089376,
"emoji": "🗑️"
},
"curseprofile/comment-purged":{
"icon":"",
"color": 16089376,
"emoji": "👁️"
},
"curseprofile/comment-replied": {
"icon": "https://i.imgur.com/hkyYsI1.png",
"color": 16089376,
"emoji": "📩"
},
"curseprofile/profile-edited": {
"icon": "",
"color": 16089376,
"emoji": "📌"
},
"contentmodel/change": {
"icon": "",
"color": 25600,
"emoji": "📋"
},
"contentmodel/new": {
"icon": "",
"color": 25600,
"emoji": "📋"
},
"cargo/deletetable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"cargo/createtable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"cargo/replacetable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"cargo/recreatetable": {
"icon": "",
"color": 16776960,
"emoji": "📦"
},
"sprite/sprite": {
"icon": "",
"color": 16776960,
"emoji": "🪟"
},
"sprite/sheet": {
"icon": "",
"color": 16776960,
"emoji": "🪟"
},
"sprite/slice": {
"icon": "",
"color": 16776960,
"emoji": "🪟"
},
"managetags/create": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"managetags/delete": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"managetags/activate": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"managetags/deactivate": {
"icon": "",
"color": 16776960,
"emoji": "🏷️"
},
"newusers/autocreate": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/byemail": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/create": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/create2": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/newusers": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"newusers/reclaim": {
"icon": "",
"color": 65280,
"emoji": "🗿"
},
"managewiki/delete": {
"icon": "",
"color": 8421504,
"emoji": "🗑️"
},
"managewiki/lock": {
"icon": "",
"color": 8421504,
"emoji": "🔒"
},
"managewiki/namespaces": {
"icon": "",
"color": 8421504,
"emoji": "📦"
},
"managewiki/namespaces-delete": {
"icon": "",
"color": 8421504,
"emoji": "🗑️"
},
"managewiki/rights": {
"icon": "",
"color": 8421504,
"emoji": "🏅"
},
"managewiki/settings": {
"icon": "",
"color": 8421504,
"emoji": "⚙️"
},
"managewiki/undelete": {
"icon": "",
"color": 8421504,
"emoji": "♻️"
},
"managewiki/unlock": {
"icon": "",
"color": 8421504,
"emoji": "🔓"
},
"datadump/generate": {
"icon": "",
"color": 8421504,
"emoji": "📤"
},
"datadump/delete": {
"icon": "",
"color": 8421504,
"emoji": "🗑️"
},
"pagetranslation/mark": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/unmark": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/moveok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/movenok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletefok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletefnok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletelok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/deletelnok": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/encourage": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/discourage": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/prioritylanguages": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/associate": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagetranslation/dissociate": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"translationreview/message": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"translationreview/group": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"pagelang/pagelang": {
"icon": "",
"color": 8421504,
"emoji": "🌐"
},
"renameuser/renameuser": {
"icon": "",
"color": 8421504,
"emoji": "📛"
},
"suppressed": {
"icon": "https://i.imgur.com/1gps6EZ.png",
"color": 1,
"emoji": "👁️"
},
"discussion": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/post": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/reply": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/poll": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/forum/quiz": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 54998,
"emoji": "📝"
},
"discussion/wall/post": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 3752525,
"emoji": "✉️"
},
"discussion/wall/reply": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 3752525,
"emoji": "📩"
},
"discussion/comment/post": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 10802,
"emoji": "🗒️"
},
"discussion/comment/reply": {
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
"color": 10802,
"emoji": "🗒️"
},
"unknown": {
"icon": "",
"color": 0,
"emoji": "❓"
}
}
}

View file

@ -1,6 +1,6 @@
# This file is part of Recent changes Goat compatible Discord bot (RcGcDb). # This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
# #
# RcGcDb is free software: you can redistribute it and/or modify # RcGcDw is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
@ -11,13 +11,13 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDb. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
import re import re
from urllib.parse import quote from urllib.parse import quote
from typing import Optional, Callable, TYPE_CHECKING from typing import Optional, Callable, TYPE_CHECKING
from src.exceptions import ServerError, MediaWikiError, TagNotFound from src.exceptions import ServerError, MediaWikiError
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.configloader import settings from src.configloader import settings
import src.misc import src.misc
@ -32,9 +32,9 @@ if TYPE_CHECKING:
logger = logging.getLogger("src.api.util") logger = logging.getLogger("src.api.util")
def default_message(event: str, display: str, formatter_hooks: dict) -> Callable: def default_message(event: str, formatter_hooks: dict) -> Callable:
"""Returns a method of a formatter responsible for the event or None if such does not exist.""" """Returns a method of a formatter responsible for the event or None if such does not exist."""
return formatter_hooks[display].get(event, formatter_hooks.get("generic", formatter_hooks["no_formatter"])) return formatter_hooks.get(event, formatter_hooks.get("generic", formatter_hooks["no_formatter"]))
def clean_link(link: str) -> str: def clean_link(link: str) -> str:
@ -57,15 +57,15 @@ def parse_mediawiki_changes(ctx: Context, content: str, embed: DiscordMessage) -
edit_diff = ctx.client.content_parser() edit_diff = ctx.client.content_parser()
edit_diff.feed(content) edit_diff.feed(content)
if edit_diff.small_prev_del: if edit_diff.small_prev_del:
if edit_diff.small_prev_del.replace("~~", "").isspace(): if edit_diff.small_prev_del.replace("~~", "").replace("__", "").isspace():
edit_diff.small_prev_del = _('__Only whitespace__') edit_diff.small_prev_del = _('__Only whitespace__')
else: else:
edit_diff.small_prev_del = edit_diff.small_prev_del.replace("~~~~", "") edit_diff.small_prev_del = edit_diff.small_prev_del.replace("~~~~", "").replace("____", "")
if edit_diff.small_prev_ins: if edit_diff.small_prev_ins:
if edit_diff.small_prev_ins.replace("**", "").isspace(): if edit_diff.small_prev_ins.replace("**", "").replace("__", "").isspace():
edit_diff.small_prev_ins = _('__Only whitespace__') edit_diff.small_prev_ins = _('__Only whitespace__')
else: else:
edit_diff.small_prev_ins = edit_diff.small_prev_ins.replace("****", "") edit_diff.small_prev_ins = edit_diff.small_prev_ins.replace("****", "").replace("____", "")
logger.debug("Changed content: {}".format(edit_diff.small_prev_ins)) logger.debug("Changed content: {}".format(edit_diff.small_prev_ins))
if edit_diff.small_prev_del and not ctx.event == "new": if edit_diff.small_prev_del and not ctx.event == "new":
embed.add_field(_("Removed"), "{data}".format(data=edit_diff.small_prev_del), inline=True) embed.add_field(_("Removed"), "{data}".format(data=edit_diff.small_prev_del), inline=True)
@ -148,17 +148,17 @@ def embed_helper(ctx: Context, message: DiscordMessage, change: dict, set_user=T
if settings["appearance"]["embed"]["show_footer"]: if settings["appearance"]["embed"]["show_footer"]:
message["timestamp"] = change["timestamp"] message["timestamp"] = change["timestamp"]
if "tags" in change and change["tags"]: if "tags" in change and change["tags"]:
tags_displayname = [] tag_displayname = []
for tag in change["tags"]: for tag in change["tags"]:
try: if tag in ctx.client.tags:
tag_display = ctx.client.tag(tag) if ctx.client.tags[tag] is None:
if tag_display is None:
continue # Ignore hidden tags continue # Ignore hidden tags
else: else:
tags_displayname.append(tag_display) tag_displayname.append(ctx.client.tags[tag])
except TagNotFound: else:
tags_displayname.append(tag) tag_displayname.append(tag)
message.add_field(formatters_i18n.pgettext("recent changes Tags", "Tags"), ", ".join(tags_displayname)) if tag_displayname:
message.add_field(formatters_i18n.pgettext("recent changes Tags", "Tags"), ", ".join(tag_displayname))
if ctx.categories is not None and not (len(ctx.categories["new"]) == 0 and len(ctx.categories["removed"]) == 0): if ctx.categories is not None and not (len(ctx.categories["new"]) == 0 and len(ctx.categories["removed"]) == 0):
new_cat = (_("**Added**: ") + ", ".join(list(ctx.categories["new"])[0:16]) + ( new_cat = (_("**Added**: ") + ", ".join(list(ctx.categories["new"])[0:16]) + (
"\n" if len(ctx.categories["new"]) <= 15 else _(" and {} more\n").format( "\n" if len(ctx.categories["new"]) <= 15 else _(" and {} more\n").format(

View file

@ -24,8 +24,15 @@ class DomainManager:
if len(split_payload) < 2: if len(split_payload) < 2:
raise ValueError("Improper pub/sub message! Pub/sub payload: {}".format(payload)) raise ValueError("Improper pub/sub message! Pub/sub payload: {}".format(payload))
if split_payload[0] == "ADD": if split_payload[0] == "ADD":
await self.new_wiki(Wiki(split_payload[1], None, None)) await self.new_wiki(Wiki(split_payload[1], None, None)) # TODO Can already exist
elif split_payload[0] == "REMOVE": elif split_payload[0] == "REMOVE":
try:
results = await connection.fetch("SELECT * FROM rcgcdw WHERE wiki = $1;", split_payload[1])
if len(results) > 0:
return
except asyncpg.IdleSessionTimeoutError:
logger.error("Couldn't check amount of webhooks with {} wiki!".format(split_payload[1]))
return
self.remove_wiki(split_payload[1]) self.remove_wiki(split_payload[1])
else: else:
raise ValueError("Unknown pub/sub command! Payload: {}".format(payload)) raise ValueError("Unknown pub/sub command! Payload: {}".format(payload))

View file

@ -1,4 +1,7 @@
import time import time
import aiohttp.web_request
from src.config import settings from src.config import settings
from typing import Union, Optional from typing import Union, Optional
from enum import Enum from enum import Enum
@ -32,6 +35,7 @@ class LimitedList(list):
class Statistics: class Statistics:
def __init__(self, rc_id: Optional[int], discussion_id: Optional[int]): def __init__(self, rc_id: Optional[int], discussion_id: Optional[int]):
self.last_request: Optional[aiohttp.web_request.Request] = None
self.last_checked_rc: Optional[int] = None self.last_checked_rc: Optional[int] = None
self.last_action: Optional[int] = rc_id self.last_action: Optional[int] = rc_id
self.last_checked_discussion: Optional[int] = None self.last_checked_discussion: Optional[int] = None

View file

@ -1,9 +1,11 @@
from __future__ import annotations from __future__ import annotations
import json
import time import time
from dataclasses import dataclass from dataclasses import dataclass
import re import re
import logging, aiohttp import logging, aiohttp
from functools import cache
from api.util import default_message from api.util import default_message
from mw_messages import MWMessages from mw_messages import MWMessages
@ -27,6 +29,7 @@ from bs4 import BeautifulSoup
from collections import OrderedDict, defaultdict, namedtuple from collections import OrderedDict, defaultdict, namedtuple
from typing import Union, Optional, TYPE_CHECKING from typing import Union, Optional, TYPE_CHECKING
Settings = namedtuple("Settings", ["lang", "display"])
logger = logging.getLogger("rcgcdb.wiki") logger = logging.getLogger("rcgcdb.wiki")
wiki_reamoval_reasons = {410: _("wiki deleted"), 404: _("wiki deleted"), 401: _("wiki inaccessible"), wiki_reamoval_reasons = {410: _("wiki deleted"), 404: _("wiki deleted"), 401: _("wiki inaccessible"),
@ -41,14 +44,26 @@ 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.mw_messages: Optional[MWMessages] = None self.mw_messages: Optional[MWMessages] = None
self.tags: dict[str, Optional[str]] = {} # Tag can be None if hidden
self.first_fetch_done: bool = False self.first_fetch_done: bool = False
self.domain: Optional[Domain] = None self.domain: Optional[Domain] = None
self.client: Client = Client(self) self.targets: Optional[defaultdict[Settings, list[str]]] = None
self.client: Client = Client(formatter_hooks, self)
self.update_targets()
@property @property
def rc_id(self): def rc_id(self):
return self.statistics.last_action return self.statistics.last_action
@property
def last_request(self):
return self.statistics.last_request
@last_request.setter
def last_request(self, value):
self.statistics.last_request = value
# async def remove(self, reason): # async def remove(self, reason):
# logger.info("Removing a wiki {}".format(self.script_url)) # logger.info("Removing a wiki {}".format(self.script_url))
# await src.discord.wiki_removal(self.script_url, reason) # await src.discord.wiki_removal(self.script_url, reason)
@ -68,7 +83,7 @@ class Wiki:
# else: # else:
# self.fail_times -= 1 # self.fail_times -= 1
async def generate_targets(self) -> defaultdict[namedtuple, list[str]]: async def update_targets(self) -> None:
"""This function generates all possible varations of outputs that we need to generate messages for. """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""" :returns defaultdict[namedtuple, list[str]] - where namedtuple is a named tuple with settings for given webhooks in list"""
@ -76,7 +91,7 @@ class Wiki:
target_settings: defaultdict[Settings, list[str]] = defaultdict(list) target_settings: defaultdict[Settings, list[str]] = defaultdict(list)
async for webhook in DBHandler.fetch_rows("SELECT webhook, lang, display FROM rcgcdw WHERE wiki = $1 AND (rcid != -1 OR rcid IS NULL)", self.script_url): async for webhook in DBHandler.fetch_rows("SELECT webhook, lang, display FROM rcgcdw WHERE wiki = $1 AND (rcid != -1 OR rcid IS NULL)", self.script_url):
target_settings[Settings(webhook["lang"], webhook["display"])].append(webhook["webhook"]) target_settings[Settings(webhook["lang"], webhook["display"])].append(webhook["webhook"])
return target_settings self.targets = 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"""
@ -189,6 +204,7 @@ class Wiki:
except WikiServerError as e: except WikiServerError as e:
self.statistics.update(Log(type=LogType.CONNECTION_ERROR, title=e.)) # We need more details in WIkiServerError exception self.statistics.update(Log(type=LogType.CONNECTION_ERROR, title=e.)) # We need more details in WIkiServerError exception
if not self.mw_messages: if not self.mw_messages:
# TODO Split into other function
mw_messages = request.get("query", {}).get("allmessages", []) mw_messages = request.get("query", {}).get("allmessages", [])
final_mw_messages = dict() final_mw_messages = dict()
for msg in mw_messages: for msg in mw_messages:
@ -197,6 +213,7 @@ class Wiki:
else: else:
logger.warning("Could not fetch the MW message translation for: {}".format(msg["name"])) logger.warning("Could not fetch the MW message translation for: {}".format(msg["name"]))
self.mw_messages = MWMessages(final_mw_messages) self.mw_messages = MWMessages(final_mw_messages)
# TODO Split into other function
try: try:
recent_changes = request["query"]["recentchanges"] recent_changes = request["query"]["recentchanges"]
recent_changes.reverse() recent_changes.reverse()
@ -230,23 +247,31 @@ class Wiki:
self.tags[tag["name"]] = (BeautifulSoup(tag["displayname"], "lxml")).get_text() self.tags[tag["name"]] = (BeautifulSoup(tag["displayname"], "lxml")).get_text()
except KeyError: except KeyError:
self.tags[tag["name"]] = None self.tags[tag["name"]] = None
targets = await self.generate_targets() # TODO Cache this in Wiki and update based on Redis updates
message_list = defaultdict(list) message_list = defaultdict(list)
for change in recent_changes: # Yeah, second loop since the categories require to be all loaded up for change in recent_changes: # Yeah, second loop since the categories require to be all loaded up
if change["rcid"] > self.rc_id: if change["rcid"] > self.rc_id:
if highest_id is None or change["rcid"] > highest_id: # make sure that the highest_rc is really highest rcid but do allow other entries with potentially lesser rcids come after without breaking the cycle if highest_id is None or change["rcid"] > highest_id: # make sure that the highest_rc is really highest rcid but do allow other entries with potentially lesser rcids come after without breaking the cycle
highest_id = change["rcid"] highest_id = change["rcid"]
for combination, webhooks in targets.items(): for combination, webhooks in self.targets.items():
message, metadata = await rc_processor(self, change, categorize_events, combination, webhooks) message, metadata = await rc_processor(self, change, categorize_events, combination, webhooks)
break break
@cache
def prepare_settings(display_mode: int) -> dict:
"""Prepares dict of RcGcDw compatible settings based on a template and display mode of given call"""
with open("src/api/template_settings.json", "r") as template_json:
template = json.load(template_json)
template["appearance"]["embed"]["embed_images"] = True if display_mode > 1 else False
template["appearance"]["embed"]["show_edit_changes"] = True if display_mode > 2 else False
return template
async def rc_processor(wiki: Wiki, change: dict, changed_categories: dict, display_options: namedtuple("Settings", ["lang", "display"]), webhooks: list) -> tuple[src.discord.DiscordMessage, src.discord.DiscordMessageMetadata]: async def rc_processor(wiki: Wiki, change: dict, changed_categories: dict, display_options: namedtuple("Settings", ["lang", "display"]), webhooks: list) -> tuple[src.discord.DiscordMessage, src.discord.DiscordMessageMetadata]:
from src.misc import LinkParser from src.misc import LinkParser
LinkParser = LinkParser() LinkParser = LinkParser()
metadata = src.discord.DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", None), metadata = src.discord.DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", None),
page_id=change.get("pageid", None)) page_id=change.get("pageid", None))
context = Context(display_options, webhooks, wiki.client) context = Context("embed" if display_options.display > 0 else "compact", "recentchanges", webhook, wiki.client, langs[display_options.lang]["rc_formatters"], prepare_settings(display_options.display))
if ("actionhidden" in change or "suppressed" in change) and "suppressed" not in settings["ignored"]: # if event is hidden using suppression if ("actionhidden" in change or "suppressed" in change) and "suppressed" not in settings["ignored"]: # if event is hidden using suppression
context.event = "suppressed" context.event = "suppressed"
try: try: