Updated the docs reflecting changed functionality, added changed functionality with translations

This commit is contained in:
Frisk 2022-06-28 14:01:56 +02:00
parent adc6d1eb61
commit 0bd2cf6330
No known key found for this signature in database
GPG key ID: 213F7C15068AF8AC
5 changed files with 25 additions and 19 deletions

View file

@ -118,6 +118,10 @@ Context can consist of the following fields:
- `categories` - {"new": set(), "removed": set()} - each set containing strings of added or removed categories for given page - `categories` - {"new": set(), "removed": set()} - each set containing strings of added or removed categories for given page
- `parsedcomment` - string - contains escaped and Markdown parsed summary (parsed_comment) of a log/edit action - `parsedcomment` - string - contains escaped and Markdown parsed summary (parsed_comment) of a log/edit action
- `comment_page` - dict - containing `fullUrl` and `article` with strings both to full article url and its name - `comment_page` - dict - containing `fullUrl` and `article` with strings both to full article url and its name
- `_` gettext.gettext - function for singular translations
- `ngettext` gettext.ngettext function for plural translations
- `pgettext` gettext.pgettext function for translations differentiated by the context
- `npgettext` gettext.npgettext function for plural translations differentiated by the context
### Util ### Util
**Path**: `src.api.util` **Path**: `src.api.util`

View file

@ -17,24 +17,19 @@ import ipaddress
import logging import logging
from src.discord.message import DiscordMessage from src.discord.message import DiscordMessage
from src.api import formatter from src.api import formatter
from src.i18n import formatters_i18n
from src.api.context import Context from src.api.context import Context
from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \ from src.api.util import embed_helper, sanitize_to_url, parse_mediawiki_changes, clean_link, compact_author, \
create_article_path, sanitize_to_markdown create_article_path, sanitize_to_markdown
from src.configloader import settings
_ = formatters_i18n.gettext abusefilter_translatable = lambda string, _, default: {"edit": _("Edit"), "upload": _("Upload"), "move": _("Move"), "stashupload": _("Stash upload"), "delete": _("Deletion"), "createaccount": _("Account creation"), "autocreateaccount": _("Auto account creation"), "": _("None"), "warn": _("Warning issued"), "block": _("**Blocked user**"), "tag": _("Tagged the edit"), "disallow": _("Disallowed the action"), "rangeblock": _("**IP range blocked**"), "throttle": _("Throttled actions"), "blockautopromote": _("Removed autoconfirmed group"), "degroup": _("**Removed from privileged groups**")}.get(string, default)
ngettext = formatters_i18n.ngettext
abusefilter_results = {"": _("None"), "warn": _("Warning issued"), "block": _("**Blocked user**"), "tag": _("Tagged the edit"), "disallow": _("Disallowed the action"), "rangeblock": _("**IP range blocked**"), "throttle": _("Throttled actions"), "blockautopromote": _("Removed autoconfirmed group"), "degroup": _("**Removed from privileged groups**")}
abusefilter_actions = {"edit": _("Edit"), "upload": _("Upload"), "move": _("Move"), "stashupload": _("Stash upload"), "delete": _("Deletion"), "createaccount": _("Account creation"), "autocreateaccount": _("Auto account creation")}
logger = logging.getLogger("extensions.base") logger = logging.getLogger("extensions.base")
# AbuseFilter - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:AbuseFilter # AbuseFilter - https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:AbuseFilter
# Processing Abuselog LOG events, separate from RC logs # Processing Abuselog LOG events, separate from RC logs
def abuse_filter_format_user(change):
def abuse_filter_format_user(change, settings):
author = change["user"] author = change["user"]
if settings.get("hide_ips", False): if settings.get("hide_ips", False):
try: try:
@ -50,10 +45,10 @@ def abuse_filter_format_user(change):
def embed_abuselog(ctx: Context, change: dict): def embed_abuselog(ctx: Context, change: dict):
action = "abuselog/{}".format(change["result"]) action = "abuselog/{}".format(change["result"])
embed = DiscordMessage(ctx.message_type, action, ctx.webhook_url) embed = DiscordMessage(ctx.message_type, action, ctx.webhook_url)
author = abuse_filter_format_user(change) author = abuse_filter_format_user(change, ctx.settings)
embed["title"] = _("{user} triggered \"{abuse_filter}\"").format(user=author, abuse_filter=sanitize_to_markdown(change["filter"])) embed["title"] = _("{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(_("Performed"), abusefilter_translatable(change["action"], ctx._, _("Unknown")))
embed.add_field(_("Action taken"), abusefilter_results.get(change["result"], _("Unknown"))) embed.add_field(_("Action taken"), abusefilter_translatable(change["result"], ctx._, _("Unknown")))
embed.add_field(_("Title"), sanitize_to_markdown(change.get("title", _("Unknown")))) embed.add_field(_("Title"), sanitize_to_markdown(change.get("title", _("Unknown"))))
return embed return embed
@ -62,12 +57,12 @@ def embed_abuselog(ctx: Context, change: dict):
def compact_abuselog(ctx: Context, change: dict): def compact_abuselog(ctx: Context, change: dict):
action = "abuselog/{}".format(change["result"]) action = "abuselog/{}".format(change["result"])
author_url = clean_link(create_article_path("User:{user}".format(user=change["user"]))) author_url = clean_link(create_article_path("User:{user}".format(user=change["user"])))
author = abuse_filter_format_user(change) author = abuse_filter_format_user(change, ctx.settings)
message = _("[{author}]({author_url}) triggered *{abuse_filter}*, performing the action \"{action}\" on *[{target}]({target_url})* - action taken: {result}.").format( message = _("[{author}]({author_url}) triggered *{abuse_filter}*, performing the action \"{action}\" on *[{target}]({target_url})* - action taken: {result}.").format(
author=author, author_url=author_url, abuse_filter=sanitize_to_markdown(change["filter"]), author=author, author_url=author_url, abuse_filter=sanitize_to_markdown(change["filter"]),
action=abusefilter_actions.get(change["action"], _("Unknown")), target=change.get("title", _("Unknown")), action=abusefilter_translatable(change["action"], ctx._, _("Unknown")), target=change.get("title", _("Unknown")),
target_url=clean_link(create_article_path(sanitize_to_url(change.get("title", _("Unknown"))))), target_url=clean_link(create_article_path(sanitize_to_url(change.get("title", _("Unknown"))))),
result=abusefilter_results.get(change["result"], _("Unknown"))) result=abusefilter_translatable(change["result"], ctx._, _("Unknown")))
return DiscordMessage(ctx.message_type, action, ctx.webhook_url, content=message) return DiscordMessage(ctx.message_type, action, ctx.webhook_url, content=message)
# abusefilter/modify - AbuseFilter filter modification # abusefilter/modify - AbuseFilter filter modification
@ -111,6 +106,7 @@ def embed_abuselog_create(ctx: Context, change: dict):
embed["title"] = _("Created abuse filter number {number}").format(number=change["logparams"]['newId']) embed["title"] = _("Created abuse filter number {number}").format(number=change["logparams"]['newId'])
return embed return embed
@formatter.compact(event="abusefilter/create") @formatter.compact(event="abusefilter/create")
def compact_abuselog_create(ctx: Context, change: dict): def compact_abuselog_create(ctx: Context, change: dict):
author, author_url = compact_author(ctx, change) author, author_url = compact_author(ctx, change)

View file

@ -13,6 +13,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>. # along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
import gettext
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
@ -22,7 +24,7 @@ if TYPE_CHECKING:
class Context: class Context:
"""Context object containing client and some metadata regarding specific formatter call, """Context object containing client and some metadata regarding specific formatter call,
they are mainly used as a bridge between part that fetches the changes and API's formatters""" 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): def __init__(self, message_type: str, feed_type: str, webhook_url: str, client: Client, language: gettext.GNUTranslations, settings: dict):
self.client = client self.client = client
self.webhook_url = webhook_url self.webhook_url = webhook_url
self.message_type = message_type self.message_type = message_type
@ -31,6 +33,11 @@ class Context:
self.parsedcomment = None self.parsedcomment = None
self.event = None self.event = None
self.comment_page = None self.comment_page = None
self._ = language.gettext # Singular translations (ex. ctx._("Large goat"))
self.ngettext = language.npgettext # Plural translations depending on amount (ex. ctx.ngettext("{} action", "{} actions", action_amount))
self.pgettext = language.pgettext # Translation with context (ex. ctx.pgettext("From mediawiki module", "Blocked {} user"))
self.npgettext = language.npgettext # Plural translation with context (ex. ctx.npgettext("From mediawiki module", "Edited {} time", "Edited {} times", edit_amoint)
self.settings = settings
def set_categories(self, cats): def set_categories(self, cats):
self.categories = cats self.categories = cats

View file

@ -18,7 +18,6 @@ from typing import Union, Optional
from src.configloader import settings from src.configloader import settings
logger = logging.getLogger("rcgcdw.i18n") logger = logging.getLogger("rcgcdw.i18n")
rcgcdw: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None rcgcdw: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
discussion_formatters: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
rc: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None rc: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
formatters_i18n: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None formatters_i18n: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
misc: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None misc: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
@ -44,7 +43,7 @@ def load_languages():
misc = gettext.translation('misc', localedir='locale', languages=[settings["lang"]]) misc = gettext.translation('misc', localedir='locale', languages=[settings["lang"]])
redaction = gettext.translation('redaction', localedir='locale', languages=[settings["lang"]]) redaction = gettext.translation('redaction', localedir='locale', languages=[settings["lang"]])
else: else:
rcgcdw, discussion_formatters, rc, formatters_i18n, misc, redaction = gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations() rcgcdw, rc, formatters_i18n, misc, redaction = gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations(), gettext.NullTranslations()
formatters_i18n.pgettext = python37_pgettext_backward_compatibility formatters_i18n.pgettext = python37_pgettext_backward_compatibility
except FileNotFoundError: except FileNotFoundError:
logger.critical("No language files have been found. Make sure locale folder is located in the directory.") logger.critical("No language files have been found. Make sure locale folder is located in the directory.")

View file

@ -34,7 +34,7 @@ from src.api.util import create_article_path, default_message
from src.discord.queue import send_to_discord from src.discord.queue import send_to_discord
from src.discord.message import DiscordMessage, DiscordMessageMetadata from src.discord.message import DiscordMessage, DiscordMessageMetadata
from src.exceptions import ServerError, MediaWikiError, NoFormatter from src.exceptions import ServerError, MediaWikiError, NoFormatter
from src.i18n import rcgcdw from src.i18n import rcgcdw, formatters_i18n
from src.wiki import Wiki from src.wiki import Wiki
settings = src.configloader.settings settings = src.configloader.settings
@ -202,7 +202,7 @@ def rc_processor(change, changed_categories):
metadata = DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", None), metadata = DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", None),
page_id=change.get("pageid", None)) page_id=change.get("pageid", None))
logger.debug(change) logger.debug(change)
context = Context(settings["appearance"]["mode"], "recentchanges", settings["webhookURL"], client) context = Context(settings["appearance"]["mode"], "recentchanges", settings["webhookURL"], client, formatters_i18n, settings)
if ("actionhidden" in change or "suppressed" in change) and "suppressed" not in settings["ignored"]: # if event is hidden using suppression if ("actionhidden" in change or "suppressed" in change) and "suppressed" not in settings["ignored"]: # if event is hidden using suppression
context.event = "suppressed" context.event = "suppressed"
run_hooks(pre_hooks, context, change) run_hooks(pre_hooks, context, change)