diff --git a/extensions/base/__init__.py b/extensions/base/__init__.py index 56ec8e7..e6ffd54 100644 --- a/extensions/base/__init__.py +++ b/extensions/base/__init__.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,7 +11,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import extensions.base.mediawiki import extensions.base.abusefilter diff --git a/extensions/base/abusefilter.py b/extensions/base/abusefilter.py index 769be3e..253b138 100644 --- a/extensions/base/abusefilter.py +++ b/extensions/base/abusefilter.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,30 +11,25 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import ipaddress import logging from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n from src.api.context import Context from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \ create_article_path, sanitize_to_markdown -from src.configloader import settings -_ = formatters_i18n.gettext -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")} +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) logger = logging.getLogger("extensions.base") # AbuseFilter - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:AbuseFilter # Processing Abuselog LOG events, separate from RC logs -def abuse_filter_format_user(change): + +def abuse_filter_format_user(change, settings): author = change["user"] if settings.get("hide_ips", False): try: @@ -50,11 +45,11 @@ def abuse_filter_format_user(change): def embed_abuselog(ctx: Context, change: dict): action = "abuselog/{}".format(change["result"]) embed = DiscordMessage(ctx.message_type, action, ctx.webhook_url) - author = abuse_filter_format_user(change) - embed["title"] = _("{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(_("Action taken"), abusefilter_results.get(change["result"], _("Unknown"))) - embed.add_field(_("Title"), sanitize_to_markdown(change.get("title", _("Unknown")))) + author = abuse_filter_format_user(change, ctx.settings) + embed["title"] = ctx._("{user} triggered \"{abuse_filter}\"").format(user=author, abuse_filter=sanitize_to_markdown(change["filter"])) + embed.add_field(ctx._("Performed"), abusefilter_translatable(change["action"], ctx._, ctx._("Unknown"))) + embed.add_field(ctx._("Action taken"), abusefilter_translatable(change["result"], ctx._, ctx._("Unknown"))) + embed.add_field(ctx._("Title"), sanitize_to_markdown(change.get("title", ctx._("Unknown")))) return embed @@ -62,12 +57,12 @@ def embed_abuselog(ctx: Context, change: dict): def compact_abuselog(ctx: Context, change: dict): action = "abuselog/{}".format(change["result"]) author_url = clean_link(create_article_path("User:{user}".format(user=change["user"]))) - author = abuse_filter_format_user(change) - message = _("[{author}]({author_url}) triggered *{abuse_filter}*, performing the action \"{action}\" on *[{target}]({target_url})* - action taken: {result}.").format( + author = abuse_filter_format_user(change, ctx.settings) + 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"]), - action=abusefilter_actions.get(change["action"], _("Unknown")), target=change.get("title", _("Unknown")), - target_url=clean_link(create_article_path(sanitize_to_url(change.get("title", _("Unknown"))))), - result=abusefilter_results.get(change["result"], _("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", ctx._("Unknown"))))), + result=abusefilter_translatable(change["result"], ctx._, ctx._("Unknown"))) return DiscordMessage(ctx.message_type, action, ctx.webhook_url, content=message) # abusefilter/modify - AbuseFilter filter modification @@ -80,7 +75,7 @@ def embed_abuselog_modify(ctx: Context, change: dict): embed["url"] = create_article_path( "Special:AbuseFilter/history/{number}/diff/prev/{historyid}".format(number=change["logparams"]['newId'], 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 @@ -92,7 +87,7 @@ def compact_abuselog_modify(ctx: Context, change: dict): historyid=change["logparams"][ "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, number=change[ "logparams"][ @@ -108,15 +103,16 @@ def embed_abuselog_create(ctx: Context, change: dict): embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed_helper(ctx, embed, change) 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 + @formatter.compact(event="abusefilter/create") def compact_abuselog_create(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) link = clean_link( 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, number=change[ "logparams"][ diff --git a/extensions/base/cargo.py b/extensions/base/cargo.py index 5a5cbce..063d01d 100644 --- a/extensions/base/cargo.py +++ b/extensions/base/cargo.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,20 +11,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import logging import re from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n from src.api.context import Context 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/createtable - Creation of Cargo table @@ -34,7 +29,7 @@ def embed_cargo_createtable(ctx: Context, change: dict): embed_helper(ctx, embed, change) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) 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 @@ -42,7 +37,7 @@ def embed_cargo_createtable(ctx: Context, change: dict): def compact_cargo_createtable(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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, table=table) 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) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) 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 @@ -65,7 +60,7 @@ def embed_cargo_recreatetable(ctx: Context, change: dict): def compact_cargo_recreatetable(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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, table=table) 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) table = re.search(r"\[(.*?)]\(<(.*?)>\)", ctx.client.parse_links(change["logparams"]["0"])) 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 @@ -88,7 +83,7 @@ def embed_cargo_replacetable(ctx: Context, change: dict): def compact_cargo_replacetable(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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, table=table) 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_helper(ctx, embed, change) 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 @formatter.compact(event="cargo/deletetable") def compact_cargo_deletetable(ctx: Context, change: dict): 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, table=sanitize_to_markdown(change["logparams"]["0"])) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) diff --git a/extensions/base/curseprofile.py b/extensions/base/curseprofile.py index 3cc2d5c..5c0b92e 100644 --- a/extensions/base/curseprofile.py +++ b/extensions/base/curseprofile.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,20 +11,16 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . + import logging -from src.configloader import settings from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n 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.misc import profile_field_name -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - # CurseProfile - https://help.fandom.com/wiki/Extension:CurseProfile # 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) target_user = change["title"].split(':', 1)[1] 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: - embed["title"] = _("Edited their own profile") + embed["title"] = ctx._("Edited their own profile") 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: - 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)) 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))) if target_user != author: 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: - 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, field=profile_field_name(change["logparams"]['4:section'], False), desc=ctx.parsedcomment) else: 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: - 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, field=profile_field_name(change["logparams"]['4:section'], False), desc=ctx.parsedcomment) 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) target_user = change["title"].split(':', 1)[1] 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: - embed["title"] = _("Left a comment on their own profile") - if settings["appearance"]["embed"]["show_edit_changes"]: + embed["title"] = ctx._("Left a comment on their own profile") + if ctx.settings["appearance"]["embed"]["show_edit_changes"]: 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"])) return embed @@ -93,10 +89,10 @@ def compact_curseprofile_comment_created(ctx: Context, change: dict) -> DiscordM target_user = change["title"].split(':', 1)[1] link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))) 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)) 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) @@ -109,10 +105,10 @@ def embed_curseprofile_comment_edited(ctx: Context, change: dict) -> DiscordMess embed_helper(ctx, embed, change) target_user = change["title"].split(':', 1)[1] 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: - embed["title"] = _("Edited a comment on their own profile") - if settings["appearance"]["embed"]["show_edit_changes"]: + embed["title"] = ctx._("Edited a comment on their own profile") + if ctx.settings["appearance"]["embed"]["show_edit_changes"]: 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"])) return embed @@ -124,10 +120,10 @@ def compact_curseprofile_comment_edited(ctx: Context, change: dict) -> DiscordMe target_user = change["title"].split(':', 1)[1] link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))) 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)) 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) @@ -140,10 +136,10 @@ def embed_curseprofile_comment_replied(ctx: Context, change: dict) -> DiscordMes embed_helper(ctx, embed, change) target_user = change["title"].split(':', 1)[1] 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: - embed["title"] = _("Replied to a comment on their own profile") - if settings["appearance"]["embed"]["show_edit_changes"]: + embed["title"] = ctx._("Replied to a comment on their own profile") + if ctx.settings["appearance"]["embed"]["show_edit_changes"]: 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"])) return embed @@ -155,10 +151,10 @@ def compact_curseprofile_comment_replied(ctx: Context, change: dict) -> DiscordM target_user = change["title"].split(':', 1)[1] link = clean_link(create_article_path("Special:CommentPermalink/{commentid}".format(commentid=change["logparams"]["4:comment_id"]))) 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)) 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) @@ -171,9 +167,9 @@ def embed_curseprofile_comment_deleted(ctx: Context, change: dict) -> DiscordMes embed_helper(ctx, embed, change) target_user = change["title"].split(':', 1)[1] 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: - 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: embed["description"] = ctx.parsedcomment 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))) parsed_comment = "" if ctx.parsedcomment is None else " *(" + ctx.parsedcomment + ")*" 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) 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) 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) target_user = change["title"].split(':', 1)[1] 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: - 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: embed["description"] = ctx.parsedcomment 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))) parsed_comment = "" if ctx.parsedcomment is None else " *(" + ctx.parsedcomment + ")*" 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) 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) diff --git a/extensions/base/datadump.py b/extensions/base/datadump.py index 96ef1f9..d15070f 100644 --- a/extensions/base/datadump.py +++ b/extensions/base/datadump.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,19 +11,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import logging from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n 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 -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - # DataDumps - https://www.mediawiki.org/wiki/Extension:DataDump # datadump/generate - Generating a dump of wiki @@ -33,7 +29,7 @@ ngettext = formatters_i18n.ngettext def embed_datadump_generate(ctx: Context, change: dict) -> DiscordMessage: embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) 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"])) return embed @@ -42,7 +38,7 @@ def embed_datadump_generate(ctx: Context, change: dict) -> DiscordMessage: def compact_datadump_generate(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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"]), comment=parsed_comment ) @@ -55,7 +51,7 @@ def compact_datadump_generate(ctx: Context, change: dict): def embed_datadump_delete(ctx: Context, change: dict) -> DiscordMessage: embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) 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"])) return embed @@ -64,7 +60,7 @@ def embed_datadump_delete(ctx: Context, change: dict) -> DiscordMessage: def compact_datadump_delete(ctx: Context, change: dict) -> DiscordMessage: author, author_url = compact_author(ctx, change) 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"]), comment=parsed_comment ) diff --git a/extensions/base/discussions.py b/extensions/base/discussions.py index 23841ba..ff701a4 100644 --- a/extensions/base/discussions.py +++ b/extensions/base/discussions.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,24 +11,18 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . # Discussions - Custom Fandom technology which apparently doesn't have any documentation or homepage, not even open-source, go figure import json import datetime, logging -import gettext 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.context import Context from src.discord.queue import send_to_discord from src.discord.message import DiscordMessage, DiscordMessageMetadata from src.api import formatter -from src.i18n import formatters_i18n - -_ = formatters_i18n.gettext 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. 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.jsonModal = json.loads(post.get("jsonModel", "{}")) self.markdown_text = "" self.item_num = 1 self.image_last = None + self.ctx = ctx def parse(self) -> str: """Main parsing logic""" @@ -103,14 +98,13 @@ class DiscussionsFromHellParser: elif item["type"] == "listItem": self.parse_content(item["content"], item["type"]) - @staticmethod - def convert_marks(marks): + def convert_marks(self, marks): prefix = "" suffix = "" for mark in marks: if mark["type"] == "mention": 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) elif mark["type"] == "strong": prefix += "**" @@ -124,11 +118,11 @@ class DiscussionsFromHellParser: 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""" - if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: + if ctx.settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: if post.get("jsonModel") is not None: - npost = DiscussionsFromHellParser(post) + npost = DiscussionsFromHellParser(post, ctx) embed["description"] = npost.parse() if 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") def embed_discussion_forum(ctx: Context, post: dict): - embed = DiscordMessage("embed", "discussion", settings["fandom_discussions"]["webhookURL"]) - common_discussions(post, embed) - author = _("unknown") # Fail safe + embed = DiscordMessage("embed", "discussion", ctx.settings["fandom_discussions"]["webhookURL"]) + common_discussions(post, embed, ctx) + author = ctx._("unknown") # Fail safe if 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"]), icon_url=post["createdBy"]["avatarUrl"]) 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"]) - embed["title"] = _("Created \"{title}\"").format(title=post["title"]) + embed["title"] = ctx._("Created \"{title}\"").format(title=post["title"]) thread_funnel = post.get("funnel") if thread_funnel == "POLL": embed.event_type = "discussion/forum/poll" - embed["title"] = _("Created a poll \"{title}\"").format(title=post["title"]) - if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: + embed["title"] = ctx._("Created a poll \"{title}\"").format(title=post["title"]) + if ctx.settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: poll = post["poll"] image_type = False if poll["answers"][0]["image"] is not None: image_type = True for num, option in enumerate(poll["answers"]): - embed.add_field(option["text"] if image_type is True else _("Option {}").format(num + 1), - option["text"] if image_type is False else _( + embed.add_field(option["text"] if image_type is True else ctx._("Option {}").format(num + 1), + option["text"] if image_type is False else ctx._( "__[View image]({image_url})__").format(image_url=option["image"]["url"]), inline=True) elif thread_funnel == "QUIZ": embed.event_type = "discussion/forum/quiz" - embed["title"] = _("Created a quiz \"{title}\"").format(title=post["title"]) - if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: + embed["title"] = ctx._("Created a quiz \"{title}\"").format(title=post["title"]) + if ctx.settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: quiz = post["_embedded"]["quizzes"][0] embed["description"] = quiz["title"] 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( quote_plus(tag["articleTitle"].replace(" ", "_"), "/:?=&")))) 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: - 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: embed.event_type = "discussion/forum/reply" - embed["title"] = _("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["title"] = ctx._("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) + embed["url"] = "{url}f/p/{threadId}/r/{postId}".format(url=ctx.settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], postId=post["id"]) return embed @@ -204,20 +198,20 @@ def embed_discussion_forum(ctx: Context, post: dict): @formatter.compact(event="discussion/forum") def compact_discussion_forum(ctx: Context, post: dict): message = None - author = _("unknown") # Fail safe + author = ctx._("unknown") # Fail safe if 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"]) if not post["isReply"]: 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": 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": 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": event_type = "discussion/forum/post" else: @@ -226,13 +220,13 @@ def compact_discussion_forum(ctx: Context, post: dict): thread_funnel)) event_type = "unknown" 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"]) else: 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, 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"], forumName=post["forumName"]) 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 -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""" - author = _("unknown") # Fail safe + author = ctx._("unknown") # Fail safe if post["creatorIp"]: - author = post["creatorIp"][1:] if settings.get("hide_ips", False) is False else _("Unregistered user") - author_url = "<{url}wiki/Special:Contributions{creatorIp}>".format(url=settings["fandom_discussions"]["wiki_url"], + 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=ctx.settings["fandom_discussions"]["wiki_url"], creatorIp=post["creatorIp"]) else: if post["createdBy"]["name"]: author = post["createdBy"]["name"] author_url = clean_link(create_article_path("User:{user}".format(user=author))) 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"]) return author, author_url -def embed_author_discussions(post: dict, embed: DiscordMessage): - author = _("unknown") # Fail safe +def embed_author_discussions(post: dict, embed: DiscordMessage, ctx: Context): + author = ctx._("unknown") # Fail safe if post["creatorIp"]: 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=settings["fandom_discussions"]["wiki_url"], creatorIp=post["creatorIp"])) + url=ctx.settings["fandom_discussions"]["wiki_url"], creatorIp=post["creatorIp"])) else: if 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(" ", "_")), icon_url=post["createdBy"]["avatarUrl"]) 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"]), icon_url=post["createdBy"]["avatarUrl"]) @formatter.embed(event="discussion/wall") 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) - embed_author_discussions(post, embed) - user_wall = _("unknown") # Fail safe + embed_author_discussions(post, embed, ctx) + user_wall = ctx._("unknown") # Fail safe if post["forumName"].endswith(' Message Wall'): user_wall = post["forumName"][:-13] if not post["isReply"]: embed.event_type = "discussion/wall/post" 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"]) - 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: embed.event_type = "discussion/wall/reply" 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"]) - 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) return embed @formatter.compact(event="discussion/wall") def compact_discussion_wall(ctx: Context, post: dict): - author, author_url = compact_author_discussions(post) - user_wall = _("unknown") # Fail safe + author, author_url = compact_author_discussions(post, ctx) + user_wall = ctx._("unknown") # Fail safe if post["forumName"].endswith(' Message Wall'): user_wall = post["forumName"][:-13] if not post["isReply"]: 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, 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"]) else: 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, 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, user_wall=quote_plus(user_wall.replace(" ", "_")), threadId=post["threadId"], replyId=post["id"]) 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") 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) - embed_author_discussions(post, embed) + embed_author_discussions(post, embed, ctx) article_paths = ctx.comment_page 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"]: embed.event_type = "discussion/comment/post" 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: embed.event_type = "discussion/comment/reply" embed["url"] = "{url}?commentId={commentId}&replyId={replyId}".format(url=article_paths["fullUrl"], commentId=post["threadId"], 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"] return embed @formatter.compact(event="discussion/article_comment") 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 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("()", "\(") if not post["isReply"]: event_type = "discussion/comment/post" - message = _( + message = ctx._( "[{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"], commentId=post["threadId"]) else: 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, author_url=author_url, url=article_paths["fullUrl"], article=article_paths["title"], commentId=post["threadId"], replyId=post["id"]) - return DiscordMessage("compact", event_type, ctx.webhook_url, content=message) \ No newline at end of file + return DiscordMessage("compact", event_type, ctx.webhook_url, content=message) diff --git a/extensions/base/interwiki.py b/extensions/base/interwiki.py index 211bf0d..8dae985 100644 --- a/extensions/base/interwiki.py +++ b/extensions/base/interwiki.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,20 +11,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import logging from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n 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 -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - - # Interwiki - https://www.mediawiki.org/wiki/Extension:Interwiki # 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_helper(ctx, embed, change, set_desc=False) embed["url"] = create_article_path("Special:Interwiki") - embed["title"] = _("Added an entry to the interwiki table") - embed["description"] = _("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment, + embed["title"] = ctx._("Added an entry to the interwiki table") + embed["description"] = ctx._("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment, prefix=change["logparams"]['0'], website=change["logparams"]['1']) return embed @@ -46,7 +41,7 @@ def compact_interwiki_iw_add(ctx: Context, change: dict) -> DiscordMessage: author, author_url = compact_author(ctx, change) link = clean_link(create_article_path("Special:Interwiki")) 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, author_url=author_url, desc=parsed_comment, prefix=change["logparams"]['0'], 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_helper(ctx, embed, change, set_desc=False) embed["url"] = create_article_path("Special:Interwiki") - embed["title"] = _("Edited an entry in interwiki table") - embed["description"] = _("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment, + embed["title"] = ctx._("Edited an entry in interwiki table") + embed["description"] = ctx._("Prefix: {prefix}, website: {website} | {desc}").format(desc=ctx.parsedcomment, prefix=change["logparams"]['0'], website=change["logparams"]['1']) return embed @@ -73,7 +68,7 @@ def compact_interwiki_iw_edit(ctx: Context, change: dict) -> DiscordMessage: author, author_url = compact_author(ctx, change) link = clean_link(create_article_path("Special:Interwiki")) 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, author_url=author_url, desc=parsed_comment, prefix=change["logparams"]['0'], 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_helper(ctx, embed, change, set_desc=False) embed["url"] = create_article_path("Special:Interwiki") - embed["title"] = _("Deleted an entry in interwiki table") - embed["description"] = _("Prefix: {prefix} | {desc}").format(desc=ctx.parsedcomment, + embed["title"] = ctx._("Deleted an entry in interwiki table") + embed["description"] = ctx._("Prefix: {prefix} | {desc}").format(desc=ctx.parsedcomment, prefix=change["logparams"]['0']) return embed @@ -99,7 +94,7 @@ def compact_interwiki_iw_delete(ctx: Context, change: dict) -> DiscordMessage: author, author_url = compact_author(ctx, change) link = clean_link(create_article_path("Special:Interwiki")) 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_url=author_url, table_url=link, diff --git a/extensions/base/managewiki.py b/extensions/base/managewiki.py index c75140e..2415407 100644 --- a/extensions/base/managewiki.py +++ b/extensions/base/managewiki.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,17 +11,13 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n 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 -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - # ManageWiki - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:ManageWiki # 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_helper(ctx, embed, change) 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", ""): embed.add_field("Setting", sanitize_to_markdown(change["logparams"].get("changes"))) return embed @@ -41,7 +37,7 @@ def embed_managewiki_settings(ctx: Context, change: dict): def compact_managewiki_settings(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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) # 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_helper(ctx, embed, change) 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 @@ -60,11 +56,11 @@ def embed_managewiki_delete(ctx: Context, change: dict): def compact_managewiki_delete(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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, wiki_name=change[ "logparams"].get("wiki", - _("Unknown")), + ctx._("Unknown")), comment=parsed_comment) 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["url"] = create_article_path(sanitize_to_url(change["title"])) 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 @@ -86,7 +82,7 @@ def compact_managewiki_delete_group(ctx: Context, change: dict) -> DiscordMessag author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, group=group, 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_helper(ctx, embed, change) 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 @@ -108,8 +104,8 @@ def embed_managewiki_lock(ctx: Context, change: dict): def compact_managewiki_lock(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) - content = _("[{author}]({author_url}) locked a wiki *{wiki_name}*{comment}").format( - author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", _("Unknown")), + content = ctx._("[{author}]({author_url}) locked a wiki *{wiki_name}*{comment}").format( + author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment) 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_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) - embed["title"] = _("Modified \"{namespace_name}\" namespace").format( - namespace_name=change["logparams"].get("namespace", _("Unknown"))) - embed.add_field(_('Wiki'), change["logparams"].get("wiki", _("Unknown"))) + embed["title"] = ctx._("Modified \"{namespace_name}\" namespace").format( + namespace_name=change["logparams"].get("namespace", ctx._("Unknown"))) + embed.add_field(ctx._('Wiki'), change["logparams"].get("wiki", ctx._("Unknown"))) return embed @@ -131,9 +127,9 @@ def embed_managewiki_namespaces(ctx: Context, change: dict): def compact_managewiki_namespaces(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) - content = _("[{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")), - wiki_name=change["logparams"].get("wiki", _("Unknown")), comment=parsed_comment) + 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", ctx._("Unknown")), + wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) # 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_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) - embed["title"] = _("Deleted a \"{namespace_name}\" namespace").format( - namespace_name=change["logparams"].get("namespace", _("Unknown"))) - embed.add_field(_('Wiki'), change["logparams"].get("wiki", _("Unknown"))) + embed["title"] = ctx._("Deleted a \"{namespace_name}\" namespace").format( + namespace_name=change["logparams"].get("namespace", ctx._("Unknown"))) + embed.add_field(ctx._('Wiki'), change["logparams"].get("wiki", ctx._("Unknown"))) return embed @@ -154,11 +150,11 @@ def embed_managewiki_namespaces_delete(ctx: Context, change: dict): def compact_managewiki_namespaces_delete(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) - content = _( + content = ctx._( "[{author}]({author_url}) deleted a namespace *{namespace_name}* on *{wiki_name}*{comment}").format( author=author, author_url=author_url, - namespace_name=change["logparams"].get("namespace", _("Unknown")), - wiki_name=change["logparams"].get("wiki", _("Unknown")), comment=parsed_comment) + namespace_name=change["logparams"].get("namespace", ctx._("Unknown")), + wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) # managewiki/rights - Modifying user groups @@ -170,7 +166,7 @@ def embed_managewiki_rights(ctx: Context, change: dict): embed_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) 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 @@ -179,7 +175,7 @@ def compact_managewiki_rights(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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 ) 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_helper(ctx, embed, change) 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 @@ -200,8 +196,8 @@ def embed_managewiki_undelete(ctx: Context, change: dict): def compact_managewiki_undelete(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) - content = _("[{author}]({author_url}) undeleted a wiki *{wiki_name}*{comment}").format( - author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", _("Unknown")), + content = ctx._("[{author}]({author_url}) undeleted a wiki *{wiki_name}*{comment}").format( + author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment ) 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_helper(ctx, embed, change) 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 @@ -222,8 +218,8 @@ def embed_managewiki_unlock(ctx: Context, change: dict): def compact_managewiki_unlock(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) - content = _("[{author}]({author_url}) unlocked a wiki *{wiki_name}*{comment}").format( - author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", _("Unknown")), + content = ctx._("[{author}]({author_url}) unlocked a wiki *{wiki_name}*{comment}").format( + author=author, author_url=author_url, wiki_name=change["logparams"].get("wiki", ctx._("Unknown")), comment=parsed_comment ) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) diff --git a/extensions/base/mediawiki.py b/extensions/base/mediawiki.py index 8a14ec7..285f04f 100644 --- a/extensions/base/mediawiki.py +++ b/extensions/base/mediawiki.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,8 +11,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . - +# along with RcGcDw. If not, see . import ipaddress import logging import math @@ -22,19 +21,15 @@ import datetime from collections import OrderedDict from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n from src.api.context import Context 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 -from src.configloader import settings from src.exceptions import * -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - logger = logging.getLogger("extensions.base") if 1 == 2: # additional translation strings in unreachable code + _ = lambda a: a print(_("director"), _("bot"), _("editor"), _("directors"), _("sysop"), _("bureaucrat"), _("reviewer"), _("autoreview"), _("autopatrol"), _("wiki_guardian")) @@ -68,11 +63,11 @@ def embed_edit(ctx: Context, change: dict) -> DiscordMessage: redirect="⤷ " if "redirect" in change else "", article=sanitize_to_markdown(change["title"]), editsize="+" + str(editsize) if editsize > 0 else editsize, - new=_("(N!) ") if action == "new" else "", - minor=_("m") if action == "edit" and "minor" in change else "", - bot=_('b') if "bot" in change else "", + new=ctx._("(N!) ") if action == "new" else "", + minor=ctx._("m") if action == "edit" and "minor" 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 "") - if settings["appearance"]["embed"]["show_edit_changes"]: + if ctx.settings["appearance"]["embed"]["show_edit_changes"]: try: if action == "new": 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( "?action=compare&format=json&fromrev={oldrev}&torev={diff}&topst=1&prop=diff".format( diff=change["revid"], oldrev=change["old_revid"]), "compare", "*") - except ServerError: + except (ServerError, MediaWikiError): changed_content = None if changed_content: parse_mediawiki_changes(ctx, changed_content, embed) @@ -109,12 +104,12 @@ def compact_edit(ctx: Context, change: dict) -> DiscordMessage: if abs(edit_size) > 500: bold = "**" if action == "edit": - content = _( + content = ctx._( "[{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, edit_size=edit_size, sign=sign, bold=bold) else: - content = _( + content = ctx._( "[{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, edit_size=edit_size, sign=sign, bold=bold) @@ -133,7 +128,7 @@ def embed_upload_upload(ctx, change) -> DiscordMessage: params = OrderedDict() params["action"] = "query" 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["rvprop"] = "content" 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( wiki=ctx.client.WIKI_SCRIPT_PATH, filename=sanitize_to_url(change["title"]), 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)) - if settings["appearance"]["embed"]["embed_images"]: + if ctx.settings["appearance"]["embed"]["embed_images"]: embed["image"]["url"] = image_direct_url 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": - 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: - embed["title"] = _("Uploaded {name}").format(name=sanitize_to_markdown(change["title"])) - if settings["license_detection"] and image_direct_url: + embed["title"] = ctx._("Uploaded {name}").format(name=sanitize_to_markdown(change["title"])) + if ctx.settings["license_detection"] and image_direct_url: try: 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: license = matches.group("license") else: - if re.search(re.compile(settings["license_regex_detect"], re.IGNORECASE), content) is None: - license = _("**No license!**") + if re.search(re.compile(ctx.settings["license_regex_detect"], re.IGNORECASE), content) is None: + license = ctx._("**No license!**") else: license = "?" except IndexError: @@ -221,12 +216,12 @@ def embed_upload_upload(ctx, change) -> DiscordMessage: logger.exception( "Unknown error when retriefing the image data for a license, full content: {}".format(image_data)) if image_direct_url: - embed.add_field(_("Options"), _("([preview]({link}))").format(link=image_direct_url)) - if settings["appearance"]["embed"]["embed_images"]: + embed.add_field(ctx._("Options"), ctx._("([preview]({link}))").format(link=image_direct_url)) + if ctx.settings["appearance"]["embed"]["embed_images"]: embed["image"]["url"] = image_direct_url embed_helper(ctx, embed, change) if license is not None: - embed["description"] += _("\nLicense: {}").format(license) + embed["description"] += ctx._("\nLicense: {}").format(license) return embed @@ -235,7 +230,7 @@ def compact_upload_revert(ctx, change) -> DiscordMessage: author, author_url = compact_author(ctx, change) file_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, comment=parsed_comment) 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) file_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, comment=parsed_comment) 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) file_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, file=sanitize_to_markdown( change["title"]), @@ -272,7 +267,7 @@ def embed_delete_delete(ctx, change) -> DiscordMessage: embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed_helper(ctx, embed, change) 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 @@ -281,7 +276,7 @@ def compact_delete_delete(ctx, change) -> DiscordMessage: parsed_comment = compact_summary(ctx) author, author_url = compact_author(ctx, change) 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, page=sanitize_to_markdown( 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_helper(ctx, embed, change) 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"])) 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"]))) author, author_url = compact_author(ctx, change) 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, comment=parsed_comment) 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_helper(ctx, embed, change) 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 @@ -329,7 +324,7 @@ def compact_delete_restore(ctx, change) -> DiscordMessage: page_link = clean_link(create_article_path(sanitize_to_url(change["title"]))) author, author_url = compact_author(ctx, change) 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, article=sanitize_to_markdown( change["title"]), @@ -346,7 +341,7 @@ def embed_delete_event(ctx, change) -> DiscordMessage: embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed_helper(ctx, embed, change) embed['url'] = create_article_path("Special:RecentChanges") - embed["title"] = _("Changed visibility of log events") + embed["title"] = ctx._("Changed visibility of log events") return embed @@ -354,7 +349,7 @@ def embed_delete_event(ctx, change) -> DiscordMessage: def compact_delete_event(ctx, change) -> DiscordMessage: author, author_url = compact_author(ctx, change) 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, comment=parsed_comment) 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) amount = len(change["logparams"]["ids"]) 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( article=sanitize_to_markdown(change["title"]), amount=amount) return embed @@ -380,7 +375,7 @@ def compact_delete_revision(ctx, change) -> DiscordMessage: amount = len(change["logparams"]["ids"]) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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 {amount} revisions on page [{article}]({article_url}){comment}", 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["url"] = create_article_path(sanitize_to_url(change["logparams"]['target_title'])) embed["description"] = "{supress}. {desc}".format(desc=ctx.parsedcomment, - supress=_("No redirect has been made") if "suppressredirect" in - change["logparams"] else _("A redirect has been made")) - embed["title"] = _("Moved {redirect}{article} to {target}").format(redirect="⤷ " if "redirect" in change else "", + supress=ctx._("No redirect has been made") if "suppressredirect" in + change["logparams"] else ctx._("A redirect has been made")) + embed["title"] = ctx._("Moved {redirect}{article} to {target}").format(redirect="⤷ " if "redirect" in change else "", article=sanitize_to_markdown(change["title"]), target=sanitize_to_markdown( change["logparams"]['target_title'])) @@ -410,10 +405,10 @@ def embed_move_move(ctx, change) -> DiscordMessage: def compact_move_move(ctx, change) -> DiscordMessage: author, author_url = compact_author(ctx, change) 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") 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, 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, @@ -430,9 +425,9 @@ def embed_move_move_redir(ctx, change) -> DiscordMessage: embed_helper(ctx, embed, change, set_desc=False) embed["url"] = create_article_path(sanitize_to_url(change["logparams"]['target_title'])) embed["description"] = "{supress}. {desc}".format(desc=ctx.parsedcomment, - supress=_("No redirect has been made") if "suppressredirect" in - change["logparams"] else _("A redirect has been made")) - embed["title"] = _("Moved {redirect}{article} to {title} over redirect").format( + supress=ctx._("No redirect has been made") if "suppressredirect" in + change["logparams"] else ctx._("A redirect has been made")) + embed["title"] = ctx._("Moved {redirect}{article} to {title} over redirect").format( redirect="⤷ " if "redirect" in change else "", article=sanitize_to_markdown(change["title"]), title=sanitize_to_markdown(change["logparams"]["target_title"])) return embed @@ -442,10 +437,10 @@ def embed_move_move_redir(ctx, change) -> DiscordMessage: def compact_move_move_redir(ctx, change) -> DiscordMessage: author, author_url = compact_author(ctx, change) 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") 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, author_url=author_url, redirect="⤷ " if "redirect" in change else "", 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_helper(ctx, embed, change) 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 "", article=sanitize_to_markdown(change["logparams"]["oldtitle_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) link = clean_link(create_article_path(sanitize_to_url(change["logparams"]["oldtitle_title"]))) 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, author_url=author_url, redirect="⤷ " if "redirect" in change else "", 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_helper(ctx, embed, change, set_desc=False) 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( 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) return embed @@ -503,12 +498,12 @@ def compact_protect_protect(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) parsed_comment = compact_summary(ctx) - content = _( + content = ctx._( "[{author}]({author_url}) protected [{article}]({article_url}) with the following settings: {settings}{comment}").format( author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, settings=change["logparams"].get("description", "") + ( - _(" [cascading]") if "cascade" in change["logparams"] else ""), + ctx._(" [cascading]") if "cascade" in change["logparams"] else ""), comment=parsed_comment) 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_helper(ctx, embed, change, set_desc=False) 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( 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) return embed @@ -534,12 +529,12 @@ def compact_protect_modify(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) parsed_comment = compact_summary(ctx) - content = _( + content = ctx._( "[{author}]({author_url}) modified protection settings of [{article}]({article_url}) to: {settings}{comment}").format( author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, 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) 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_helper(ctx, embed, change) 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 @@ -561,16 +556,16 @@ def compact_protect_unprotect(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, comment=parsed_comment) return DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url, content=content) # 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"]: - return _("for infinity and beyond") + return ctx._("for infinity and beyond") else: if "expiry" in change["logparams"]: 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, \ timedelta_for_expiry % 86400 // 3600, timedelta_for_expiry % 3600 // 60 if not any([years, days, hours, minutes]): - return _("for less than a minute") + return ctx._("for less than a minute") time_names = ( - ngettext("year", "years", years), ngettext("day", "days", days), ngettext("hour", "hours", hours), - ngettext("minute", "minutes", minutes)) + ctx.ngettext("year", "years", years), ctx.ngettext("day", "days", days), ctx.ngettext("hour", "hours", hours), + ctx.ngettext("minute", "minutes", minutes)) final_time = [] for num, timev in enumerate([years, days, hours, minutes]): if timev: 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) else: 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 = "" if "restrictions" in change["logparams"]: 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"]] restriction_description = restriction_description + ", ".join(restricted_pages) if "namespaces" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"][ "namespaces"]: namespaces = [] if restriction_description: - restriction_description = restriction_description + _(" and namespaces: ") + restriction_description = restriction_description + ctx._(" and namespaces: ") 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"]: 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)]["*"])) @@ -626,12 +621,12 @@ def embed_block_block(ctx, change): if len(restriction_description) > 1020: logger.debug(restriction_description) 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") 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 - 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) return embed @@ -651,7 +646,7 @@ def compact_block_block(ctx, change): if "sitewide" not in change["logparams"]: if "restrictions" in change["logparams"]: 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 change["logparams"]["restrictions"]["pages"]] restriction_description = restriction_description + ", ".join(restricted_pages) @@ -659,9 +654,9 @@ def compact_block_block(ctx, change): "namespaces"]: namespaces = [] if restriction_description: - restriction_description = restriction_description + _(" and namespaces: ") + restriction_description = restriction_description + ctx._(" and namespaces: ") else: - restriction_description = _(" on namespaces: ") + restriction_description = ctx._(" on 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 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: logger.debug(restriction_description) restriction_description = restriction_description[:1020] + "…" - content = _( + content = ctx._( "[{author}]({author_url}) blocked [{user}]({user_url}) {time}{restriction_desc}{comment}").format(author=author, author_url=author_url, user=user, time=block_expiry( - change), + change, ctx), user_url=link, restriction_desc=restriction_description, comment=parsed_comment) @@ -691,7 +686,7 @@ def embed_block_reblock(ctx, change): embed_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) 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 @@ -701,7 +696,7 @@ def compact_block_reblock(ctx, change): link = clean_link(create_article_path(sanitize_to_url(change["title"]))) user = change["title"].split(':', 1)[1] 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) 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["url"] = create_article_path(sanitize_to_url(change["title"])) 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 @@ -724,7 +719,7 @@ def compact_block_unblock(ctx, change): link = clean_link(create_article_path(sanitize_to_url(change["title"]))) user = change["title"].split(':', 1)[1] 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, blocked_user=sanitize_to_markdown(user), user_url=link, @@ -740,14 +735,14 @@ def compact_block_unblock(ctx, change): def embed_suppressed(ctx, change): embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed["url"] = create_article_path("") - embed["title"] = _("Action has been hidden by administration") - embed["author"]["name"] = _("Unknown") + embed["title"] = ctx._("Action has been hidden by administration") + embed["author"]["name"] = ctx._("Unknown") return embed @formatter.compact(event="suppressed", mode="compact") 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) @@ -758,7 +753,7 @@ def embed_import_upload(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(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( article=sanitize_to_markdown(change["title"]), count=change["logparams"]["count"]) return embed @@ -769,7 +764,7 @@ def compact_import_upload(ctx, change): link = clean_link(create_article_path(sanitize_to_url(change["title"]))) author, author_url = compact_author(ctx, change) 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}", change["logparams"]["count"]).format( 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_helper(ctx, embed, change) 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}\"", change["logparams"]["count"]).format( 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) source_link = clean_link(create_article_path(change["logparams"]["interwiki_title"])) 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} revisions from [{source}]({source_url}){comment}", change["logparams"]["count"]).format( @@ -811,17 +806,17 @@ def compact_import_interwiki(ctx, change): # 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""" def expiry_parse_time(passed_time): 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: 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 - old_groups = {_(x) for x in change["logparams"]["oldgroups"]} - new_groups = {_(x) for x in change["logparams"]["newgroups"]} + old_groups = {ctx._(x) for x in change["logparams"]["oldgroups"]} + new_groups = {ctx._(x) for x in change["logparams"]["newgroups"]} added = [x + new_group_meta.get(x, "") for x in new_groups - old_groups] removed = [x for x in old_groups - new_groups] return added, removed @@ -832,18 +827,18 @@ def embed_rights_rights(ctx, change): embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed["url"] = create_article_path(sanitize_to_url("User:{}".format(change["title"].split(":")[1]))) 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: - embed.set_author(_("System"), "") - embed["title"] = _("{target} got autopromoted to a new usergroup").format( + embed.set_author(ctx._("System"), "") + embed["title"] = ctx._("{target} got autopromoted to a new usergroup").format( target=sanitize_to_markdown(change["title"].split(":")[1])) # if len(change["logparams"]["oldgroups"]) < len(change["logparams"]["newgroups"]): # embed["thumbnail"]["url"] = "https://i.imgur.com/WnGhF5g.gif" - added, removed = get_changed_groups(change) + added, removed = get_changed_groups(change, ctx) 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: - 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) return embed @@ -851,25 +846,25 @@ def embed_rights_rights(ctx, change): @formatter.compact(event="rights/rights", aliases=["rights/autopromote"]) def compact_rights_rights(ctx, change): 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) parsed_comment = compact_summary(ctx) if ctx.event == "rights/rights": group_changes = "Unknown group changes." # Because I don't know if it can handle time extensions correctly if added and removed: - group_changes = _("Added to {added} and removed from {removed}.").format( - added=_(", ").join(added), removed=_(", ").join(removed)) + group_changes = ctx._("Added to {added} and removed from {removed}.").format( + added=ctx._(", ").join(added), removed=ctx._(", ").join(removed)) elif added: - group_changes = _("Added to {added}.").format(added=_(", ").join(added)) + group_changes = ctx._("Added to {added}.").format(added=ctx._(", ").join(added)) elif removed: - group_changes = _("Removed from {removed}.").format(removed=_(", ").join(removed)) - content = _("[{author}]({author_url}) changed group membership for [{target}]({target_url}): {group_changes}{comment}").format( + group_changes = ctx._("Removed from {removed}.").format(removed=ctx._(", ").join(removed)) + 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]), target_url=link, group_changes=group_changes, comment=parsed_comment) 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, - 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) @@ -880,7 +875,7 @@ def embed_merge_merge(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(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"]), dest=sanitize_to_markdown(change["logparams"][ "dest_title"])) @@ -893,7 +888,7 @@ def compact_merge_merge(ctx, change): parsed_comment = compact_summary(ctx) 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"]))) - content = _( + content = ctx._( "[{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, 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_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) - embed["title"] = _("Created account automatically") + embed["title"] = ctx._("Created account automatically") return embed @formatter.compact(event="newusers/autocreate") def compact_newusers_autocreate(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) 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_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) - embed["title"] = _("Created account") + embed["title"] = ctx._("Created account") return embed @formatter.compact(event="newusers/create") def compact_newusers_create(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) @@ -947,7 +942,7 @@ def embed_newusers_create2(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(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 @@ -956,7 +951,7 @@ def compact_newusers_create2(ctx, change): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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) 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_helper(ctx, embed, change) 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"])) return embed @@ -979,7 +974,7 @@ def compact_newusers_byemail(ctx, change): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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( 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) @@ -993,14 +988,33 @@ def embed_newusers_newusers(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"] = _("Created account") + embed["title"] = ctx._("Created account") return embed @formatter.compact(event="newusers/newusers") def compact_newusers_newusers(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) @@ -1012,9 +1026,9 @@ def embed_contentmodel_change(ctx, change): embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed_helper(ctx, embed, change, set_desc=False) 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"])) - 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"], reason=ctx.parsedcomment) return embed @@ -1025,7 +1039,7 @@ def compact_contentmodel_change(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, 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_helper(ctx, embed, change, set_desc=False) 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"])) - 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) return embed @@ -1053,7 +1067,7 @@ def compact_contentmodel_new(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, new=change["logparams"]["newmodel"], comment=parsed_comment) @@ -1069,7 +1083,7 @@ def embed_managetags_create(ctx, change): embed_helper(ctx, embed, change) ctx.client.refresh_internal_data() 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 @@ -1079,7 +1093,7 @@ def compact_managetags_create(ctx, change): link = clean_link(create_article_path(sanitize_to_url(change["title"]))) ctx.client.refresh_internal_data() 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, tag= sanitize_to_markdown( @@ -1100,9 +1114,9 @@ def embed_managetags_delete(ctx, change): embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) ctx.client.refresh_internal_data() 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: - 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"])) embed_helper(ctx, embed, change) return embed @@ -1115,7 +1129,7 @@ def compact_managetags_delete(ctx, change): ctx.client.refresh_internal_data() parsed_comment = compact_summary(ctx) 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, tag=sanitize_to_markdown( change[ @@ -1124,7 +1138,7 @@ def compact_managetags_delete(ctx, change): tag_url=link, comment=parsed_comment) 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} revisions and/or log entries{comment}", 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_helper(ctx, embed, change) 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 @@ -1151,7 +1165,7 @@ def compact_managetags_activate(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, tag=sanitize_to_markdown( change[ @@ -1170,7 +1184,7 @@ def embed_managetags_deactivate(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(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 @@ -1179,7 +1193,7 @@ def compact_managetags_deactivate(ctx, change): author, author_url = compact_author(ctx, change) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, tag=sanitize_to_markdown( change[ diff --git a/extensions/base/renameuser.py b/extensions/base/renameuser.py index b0e1155..5fc7a0c 100644 --- a/extensions/base/renameuser.py +++ b/extensions/base/renameuser.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,20 +11,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import logging from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n 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 -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - - # Renameuser - https://www.mediawiki.org/wiki/Extension:Renameuser # renameuser/renameuser - Renaming a user @@ -35,12 +30,12 @@ def embed_renameuser_renameuser(ctx: Context, change: dict) -> DiscordMessage: embed_helper(ctx, embed, change) edits = change["logparams"]["edits"] 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( old_name=sanitize_to_markdown(change["logparams"]["olduser"]), edits=edits, new_name=sanitize_to_markdown(change["logparams"]["newuser"])) 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"]), new_name=sanitize_to_markdown(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"] parsed_comment = compact_summary(ctx) 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} edits to [{new_name}]({link}){comment}", 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 ) 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"]), new_name=sanitize_to_markdown(change["logparams"]["newuser"]), link=link, comment=parsed_comment ) diff --git a/extensions/base/sprite.py b/extensions/base/sprite.py index 54ff77c..730f17d 100644 --- a/extensions/base/sprite.py +++ b/extensions/base/sprite.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,19 +11,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import logging from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n from src.api.context import Context from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, \ clean_link -_ = formatters_i18n.gettext -ngettext = formatters_i18n.ngettext - # SpriteSheet - https://www.mediawiki.org/wiki/Extension:SpriteSheet # 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_helper(ctx, embed, change) 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 @@ -42,7 +38,7 @@ def embed_sprite_sprite(ctx: Context, change: dict): def compact_sprite_sprite(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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, article=sanitize_to_markdown(change[ "title"]), @@ -57,7 +53,7 @@ def embed_sprite_sheet(ctx: Context, change: dict): embed = DiscordMessage(ctx.message_type, ctx.event, ctx.webhook_url) embed_helper(ctx, embed, change) 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 @@ -65,7 +61,7 @@ def embed_sprite_sheet(ctx: Context, change: dict): def compact_sprite_sheet(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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) # 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_helper(ctx, embed, change) 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 @formatter.compact(event="sprite/slice") def compact_sprite_slice(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) 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, article=sanitize_to_markdown(change[ "title"]), diff --git a/extensions/base/translate.py b/extensions/base/translate.py index 9fefb12..c4cd67f 100644 --- a/extensions/base/translate.py +++ b/extensions/base/translate.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,19 +11,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import logging from src.discord.message import DiscordMessage from src.api import formatter -from src.i18n import formatters_i18n from src.api.context import Context from src.api.util import embed_helper, compact_author, create_article_path, sanitize_to_markdown, sanitize_to_url, \ 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 # Translate - https://www.mediawiki.org/wiki/Extension:Translate # 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"]) else: 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 @@ -52,7 +48,7 @@ def compact_pagetranslation_mark(ctx: Context, change: dict): link = link + "?oldid={}".format(change["logparams"]["revision"]) link = clean_link(link) 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, article=sanitize_to_markdown(change["title"]), article_url=link, 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_helper(ctx, embed, change) 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 @@ -76,7 +72,7 @@ def compact_pagetranslation_unmark(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, author_url=author_url, 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_helper(ctx, embed, change) 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"])) return embed @@ -102,7 +98,7 @@ def compact_pagetranslation_moveok(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, author_url=author_url, 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_helper(ctx, embed, change) 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"])) return embed @@ -129,7 +125,7 @@ def compact_pagetranslation_movenok(ctx: Context, change: dict): parsed_comment = compact_summary(ctx) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, author_url=author_url, 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_helper(ctx, embed, change) 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"])) return embed @@ -157,7 +153,7 @@ def compact_pagetranslation_deletefnok(ctx: Context, change: dict): parsed_comment = compact_summary(ctx) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, author_url=author_url, 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_helper(ctx, embed, change) 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"])) return embed @@ -184,7 +180,7 @@ def compact_pagetranslation_deletelok(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, author_url=author_url, 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_helper(ctx, embed, change) 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"])) return embed @@ -211,7 +207,7 @@ def compact_pagetranslation_deletelnok(ctx: Context, change: dict): parsed_comment = compact_summary(ctx) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, author_url=author_url, 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_helper(ctx, embed, change) 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 @@ -237,7 +233,7 @@ def compact_pagetranslation_encourage(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, article=sanitize_to_markdown(change["title"]), article_url=link, 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_helper(ctx, embed, change) 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 @@ -261,7 +257,7 @@ def compact_pagetranslation_discourage(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, article=sanitize_to_markdown(change["title"]), article_url=link, comment=parsed_comment @@ -279,13 +275,13 @@ def embed_pagetranslation_prioritylanguages(ctx: Context, change: dict): if "languages" in change["logparams"]: languages = "`, `".join(change["logparams"]["languages"].split(",")) 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) 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) 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 @@ -297,21 +293,21 @@ def compact_pagetranslation_prioritylanguages(ctx: Context, change: dict): if "languages" in change["logparams"]: languages = "`, `".join(change["logparams"]["languages"].split(",")) if change["logparams"]["force"] == "on": - content = _( + content = ctx._( "[{author}]({author_url}) limited languages for [{article}]({article_url}) to `{languages}`{comment}").format( author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, languages=languages, comment=parsed_comment ) else: - content = _( + content = ctx._( "[{author}]({author_url}) set the priority languages for [{article}]({article_url}) to `{languages}`{comment}").format( author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, languages=languages, comment=parsed_comment ) else: - content = _( + content = ctx._( "[{author}]({author_url}) removed priority languages from [{article}]({article_url}){comment}").format( author=author, author_url=author_url, 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_helper(ctx, embed, change) 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"]) return embed @@ -338,7 +334,7 @@ def compact_pagetranslation_associate(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, author_url=author_url, 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_helper(ctx, embed, change) 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"]) return embed @@ -364,7 +360,7 @@ def compact_pagetranslation_dissociate(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) 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, author_url=author_url, 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"]) else: 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 @@ -398,7 +394,7 @@ def compact_translationreview_message(ctx: Context, change: dict): else: link = link + "?oldid={}".format(change["logparams"]["revision"]) 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, article=sanitize_to_markdown(change["title"]), article_url=link, 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_helper(ctx, embed, change) 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"])) if "old-state" in change["logparams"]: - embed.add_field(_("Old state"), change["logparams"]["old-state"], inline=True) - embed.add_field(_("New state"), change["logparams"]["new-state"], inline=True) + embed.add_field(ctx._("Old state"), change["logparams"]["old-state"], inline=True) + embed.add_field(ctx._("New state"), change["logparams"]["new-state"], inline=True) return embed @@ -427,7 +423,7 @@ def compact_translationreview_group(ctx: Context, change: dict): parsed_comment = compact_summary(ctx) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) 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, author_url=author_url, language=change["logparams"]["language"], 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 ) else: - content = _( + content = ctx._( "[{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"], 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 -def get_languages(change): +def get_languages(change: dict, ctx: Context): old_lang = "`{}`".format(change["logparams"]["oldlanguage"]) 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"]) 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 @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_helper(ctx, embed, change) embed["url"] = create_article_path(sanitize_to_url(change["title"])) - old_lang, new_lang = get_languages(change) - embed["title"] = _("Changed the language of \"{article}\"").format(article=sanitize_to_markdown(change["title"])) - embed.add_field(_("Old language"), old_lang, inline=True) - embed.add_field(_("New language"), new_lang, inline=True) + old_lang, new_lang = get_languages(change, ctx) + embed["title"] = ctx._("Changed the language of \"{article}\"").format(article=sanitize_to_markdown(change["title"])) + embed.add_field(ctx._("Old language"), old_lang, inline=True) + embed.add_field(ctx._("New language"), new_lang, inline=True) return embed @@ -472,8 +468,8 @@ def compact_pagelang_pagelang(ctx: Context, change: dict): author, author_url = compact_author(ctx, change) parsed_comment = compact_summary(ctx) link = clean_link(create_article_path(sanitize_to_url(change["title"]))) - old_lang, new_lang = get_languages(change) - content = _( + old_lang, new_lang = get_languages(change, ctx) + content = ctx._( "[{author}]({author_url}) changed the language of [{article}]({article_url}) from {old_lang} to {new_lang}{comment}").format( author=author, author_url=author_url, article=sanitize_to_markdown(change["title"]), article_url=link, diff --git a/settings.json.example b/settings.json.example index c81496c..9004d01 100644 --- a/settings.json.example +++ b/settings.json.example @@ -70,472 +70,5 @@ "rcgcdb.discord": {}, "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>" - } } } diff --git a/src/api/__init__.py b/src/api/__init__.py index e69de29..360afcf 100644 --- a/src/api/__init__.py +++ b/src/api/__init__.py @@ -0,0 +1 @@ +from .formatter import * diff --git a/src/api/client.py b/src/api/client.py index c80e3f3..4d055bc 100644 --- a/src/api/client.py +++ b/src/api/client.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,17 +11,16 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . from __future__ import annotations +from datetime import datetime import src.misc -from src.exceptions import TagNotFound -from bs4 import BeautifulSoup -from typing import Union, TYPE_CHECKING, Optional +import sched +from typing import Union, Callable from collections import OrderedDict -from functools import cache -from urllib.parse import urlparse, urlunparse +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from src.wiki import Wiki @@ -30,13 +29,55 @@ class Client: """ 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.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.tags = self.__recent_changes.tags 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 + 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 def namespaces(self) -> dict: """Return a dict of namespaces, if None return empty dict""" @@ -45,37 +86,6 @@ class Client: else: 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): link_parser = self.LinkParser() 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) + def get_formatters(self): + return self._formatters + def get_ipmapper(self) -> dict: """Returns a dict mapping IPs with amount of their edits""" return self.__recent_changes.map_ips diff --git a/src/api/context.py b/src/api/context.py index cdea133..8da32b2 100644 --- a/src/api/context.py +++ b/src/api/context.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,26 +11,34 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . from __future__ import annotations + +import gettext from typing import TYPE_CHECKING -from collections import namedtuple if TYPE_CHECKING: from src.api.client import Client class Context: - """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): + """Context object containing client and some metadata regarding specific formatter call, + 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.webhook_url = webhook_url - self.display_options = display_options - self.message_type = display_options.display + self.message_type = message_type + self.feed_type = feed_type self.categories = None self.parsedcomment = None self.event = 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): self.categories = cats @@ -40,3 +48,6 @@ class Context: def set_comment_page(self, page): self.comment_page = page + + def __str__(self): + return f". +# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw). + +# RcGcDw is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# RcGcDw is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with RcGcDw. If not, see . import src.api.hooks import logging from src.configloader import settings @@ -21,6 +21,7 @@ from typing import Optional, Callable logger = logging.getLogger("src.api.formatter") + def _register_formatter(func, kwargs, formatter_type: str, action_type=None): """ 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) if action_type is None: raise FormatterBreaksAPISpec("event type") - for act in [action_type] + kwargs.get("aliases", []): # Make action_type string a list and merge with aliases - if act in src.api.hooks.formatter_hooks[formatter_type]: - logger.warning(f"Action {act} is already defined inside of " - f"{src.api.hooks.formatter_hooks[formatter_type][act].__module__}! " - f"Overwriting it with one from {func.__module__}") - src.api.hooks.formatter_hooks[formatter_type][act] = func + if settings["appearance"]["mode"] == formatter_type: + for act in [action_type] + kwargs.get("aliases", []): # Make action_type string a list and merge with aliases + if act in src.api.hooks.formatter_hooks: + logger.warning(f"Action {act} is already defined inside of " + f"{src.api.hooks.formatter_hooks[act].__module__}! " + f"Overwriting it with one from {func.__module__}") + src.api.hooks.formatter_hooks[act] = func def embed(**kwargs): diff --git a/src/api/hook.py b/src/api/hook.py index bc80919..4f5d12b 100644 --- a/src/api/hook.py +++ b/src/api/hook.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,7 +11,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . import src.api.hooks diff --git a/src/api/hooks.py b/src/api/hooks.py index 04b1ada..b0d7674 100644 --- a/src/api/hooks.py +++ b/src/api/hooks.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,10 +11,13 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . # Made just to avoid circular imports -from typing import Callable -formatter_hooks: dict[str, dict[str, Callable]] = {"embed": {}, "compact": {}} -pre_hooks = [] -post_hooks = [] \ No newline at end of file +from typing import Callable, List, Dict +from src.discord.message import DiscordMessage, DiscordMessageMetadata +from src.api.context import Context + +formatter_hooks: Dict[str, Callable[[Context, dict], DiscordMessage]] = {} +pre_hooks: List[Callable[[Context, dict], None]] = [] +post_hooks: List[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], None]] = [] \ No newline at end of file diff --git a/src/api/template_settings.json b/src/api/template_settings.json new file mode 100644 index 0000000..36b67f4 --- /dev/null +++ b/src/api/template_settings.json @@ -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.*?)\\}\\}", + "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": "❓" + } + } +} \ No newline at end of file diff --git a/src/api/util.py b/src/api/util.py index 06999d9..6a9c650 100644 --- a/src/api/util.py +++ b/src/api/util.py @@ -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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. @@ -11,13 +11,13 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with RcGcDb. If not, see . +# along with RcGcDw. If not, see . from __future__ import annotations import re from urllib.parse import quote 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.configloader import settings import src.misc @@ -32,9 +32,9 @@ if TYPE_CHECKING: 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.""" - 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: @@ -57,15 +57,15 @@ def parse_mediawiki_changes(ctx: Context, content: str, embed: DiscordMessage) - edit_diff = ctx.client.content_parser() edit_diff.feed(content) 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__') 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.replace("**", "").isspace(): + if edit_diff.small_prev_ins.replace("**", "").replace("__", "").isspace(): edit_diff.small_prev_ins = _('__Only whitespace__') 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)) 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) @@ -148,17 +148,17 @@ def embed_helper(ctx: Context, message: DiscordMessage, change: dict, set_user=T if settings["appearance"]["embed"]["show_footer"]: message["timestamp"] = change["timestamp"] if "tags" in change and change["tags"]: - tags_displayname = [] + tag_displayname = [] for tag in change["tags"]: - try: - tag_display = ctx.client.tag(tag) - if tag_display is None: + if tag in ctx.client.tags: + if ctx.client.tags[tag] is None: continue # Ignore hidden tags else: - tags_displayname.append(tag_display) - except TagNotFound: - tags_displayname.append(tag) - message.add_field(formatters_i18n.pgettext("recent changes Tags", "Tags"), ", ".join(tags_displayname)) + tag_displayname.append(ctx.client.tags[tag]) + else: + tag_displayname.append(tag) + 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): new_cat = (_("**Added**: ") + ", ".join(list(ctx.categories["new"])[0:16]) + ( "\n" if len(ctx.categories["new"]) <= 15 else _(" and {} more\n").format( diff --git a/src/domain_manager.py b/src/domain_manager.py index d8e5994..5048e5d 100644 --- a/src/domain_manager.py +++ b/src/domain_manager.py @@ -24,8 +24,15 @@ class DomainManager: if len(split_payload) < 2: raise ValueError("Improper pub/sub message! Pub/sub payload: {}".format(payload)) 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": + 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]) else: raise ValueError("Unknown pub/sub command! Payload: {}".format(payload)) diff --git a/src/statistics.py b/src/statistics.py index 73c0890..379e6a8 100644 --- a/src/statistics.py +++ b/src/statistics.py @@ -1,4 +1,7 @@ import time + +import aiohttp.web_request + from src.config import settings from typing import Union, Optional from enum import Enum @@ -32,6 +35,7 @@ class LimitedList(list): class Statistics: 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_action: Optional[int] = rc_id self.last_checked_discussion: Optional[int] = None diff --git a/src/wiki.py b/src/wiki.py index 0ab9c2a..4b6faa4 100644 --- a/src/wiki.py +++ b/src/wiki.py @@ -1,9 +1,11 @@ from __future__ import annotations +import json import time from dataclasses import dataclass import re import logging, aiohttp +from functools import cache from api.util import default_message from mw_messages import MWMessages @@ -27,6 +29,7 @@ from bs4 import BeautifulSoup from collections import OrderedDict, defaultdict, namedtuple from typing import Union, Optional, TYPE_CHECKING +Settings = namedtuple("Settings", ["lang", "display"]) logger = logging.getLogger("rcgcdb.wiki") 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.statistics: Statistics = Statistics(rc_id, discussion_id) 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.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 def rc_id(self): 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): # logger.info("Removing a wiki {}".format(self.script_url)) # await src.discord.wiki_removal(self.script_url, reason) @@ -68,7 +83,7 @@ class Wiki: # else: # 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. :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) 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"]) - return target_settings + self.targets = target_settings 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""" @@ -189,6 +204,7 @@ class Wiki: except WikiServerError as e: self.statistics.update(Log(type=LogType.CONNECTION_ERROR, title=e.)) # We need more details in WIkiServerError exception if not self.mw_messages: + # TODO Split into other function mw_messages = request.get("query", {}).get("allmessages", []) final_mw_messages = dict() for msg in mw_messages: @@ -197,6 +213,7 @@ class Wiki: else: logger.warning("Could not fetch the MW message translation for: {}".format(msg["name"])) self.mw_messages = MWMessages(final_mw_messages) + # TODO Split into other function try: recent_changes = request["query"]["recentchanges"] recent_changes.reverse() @@ -230,23 +247,31 @@ class Wiki: self.tags[tag["name"]] = (BeautifulSoup(tag["displayname"], "lxml")).get_text() except KeyError: 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) for change in recent_changes: # Yeah, second loop since the categories require to be all loaded up 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 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) 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]: from src.misc import LinkParser LinkParser = LinkParser() metadata = src.discord.DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", 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 context.event = "suppressed" try: