From e42dc029a9d5c32d114c89a7c596a2251c953f3d Mon Sep 17 00:00:00 2001 From: Frisk Date: Sat, 25 Apr 2020 13:19:34 +0200 Subject: [PATCH 01/26] Updated German translation --- locale/de/LC_MESSAGES/rcgcdw.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locale/de/LC_MESSAGES/rcgcdw.po b/locale/de/LC_MESSAGES/rcgcdw.po index a50e42d..11946c4 100644 --- a/locale/de/LC_MESSAGES/rcgcdw.po +++ b/locale/de/LC_MESSAGES/rcgcdw.po @@ -3,9 +3,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-03-17 20:53+0100\n" -"PO-Revision-Date: 2020-03-17 21:22+0100\n" +"PO-Revision-Date: 2020-04-23 23:25+0200\n" "Last-Translator: Frisk \n" -"Language-Team: German\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -13,7 +12,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Loco-Source-Locale: de_DE\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.3\n" +"X-Generator: Lokalize 19.12.3\n" "X-Loco-Parser: loco_parse_po\n" #: rcgcdw.py:71 @@ -241,11 +240,12 @@ msgstr "" "Profil von {target}" #: rcgcdw.py:358 -#, fuzzy, python-brace-format +#, python-brace-format #| msgid "[{author}]({author_url}) deleted a comment on {target} profile" msgid "[{author}]({author_url}) purged a comment on {target} profile" msgstr "" "[{author}]({author_url}) löschte ein Kommentar auf dem Profil von {target}" +" dauerhaft" #: rcgcdw.py:368 #, python-brace-format @@ -663,7 +663,7 @@ msgstr "{field} geändert zu: {desc}" #: rcgcdw.py:775 #, python-brace-format msgid "Purged a comment on {target}'s profile" -msgstr "Löschte ein Kommentar auf dem Profil von {target}" +msgstr "Löschte ein Kommentar auf dem Profil von {target} dauerhaft" #: rcgcdw.py:781 #, python-brace-format From 3d63bbf808770b21e457f631236a01c245c5c2df Mon Sep 17 00:00:00 2001 From: Frisk Date: Sat, 25 Apr 2020 13:21:41 +0200 Subject: [PATCH 02/26] Fix #114, added DiscordMessage class storing webhook message related information --- .gitignore | 6 ++++ discussions.pot | 17 ++++++----- discussions.py | 21 ++++++++------ misc.py | 62 ++++++++++++++++++++++++++++++++++------ rcgcdw.py | 66 +++++++++++++++---------------------------- settings.json.example | 11 +++++++- 6 files changed, 112 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index d5b0f0d..0294839 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ pygettext.py lastchange.txt .directory /debug +/index.lokalize +/data.json +/main.lqa +/venv/ +/lokalize-scripts/ +/venvv/ diff --git a/discussions.pot b/discussions.pot index 1a41ab0..48467a8 100644 --- a/discussions.pot +++ b/discussions.pot @@ -1,21 +1,20 @@ -# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-04-06 18:55+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" +"PO-Revision-Date: 2020-04-23 23:41+0200\n" +"Last-Translator: Frisk \n" +"Language-Team: \n" +"Language: en_US\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 19.12.3\n" #: discussions.py:53 #, python-brace-format diff --git a/discussions.py b/discussions.py index 3413f47..35aac2d 100644 --- a/discussions.py +++ b/discussions.py @@ -19,7 +19,7 @@ import logging, gettext, schedule, requests, json, datetime from collections import defaultdict from configloader import settings -from misc import datafile, send_to_discord +from misc import datafile, send_to_discord, DiscordMessage from session import session # Initialize translation @@ -44,8 +44,7 @@ fetch_url = "https://services.fandom.com/discussion/{wikiid}/posts?sortDirection def embed_formatter(post): """Embed formatter for Fandom discussions.""" - embed = defaultdict(dict) - data = {"embeds": []} + embed = DiscordMessage("embed", "discussion") embed["author"]["name"] = post["createdBy"]["name"] embed["author"]["icon_url"] = post["createdBy"]["avatarUrl"] embed["author"]["url"] = "{wikiurl}f/u/{creatorId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]) @@ -59,11 +58,8 @@ def embed_formatter(post): embed["description"] = post["rawContent"] if len(post["rawContent"]) < 2000 else post["rawContent"][0:2000] + "…" embed["footer"]["text"] = post["forumName"] embed["timestamp"] = datetime.datetime.fromtimestamp(post["creationDate"]["epochSecond"], tz=datetime.timezone.utc).isoformat() - data["embeds"].append(dict(embed)) - data['avatar_url'] = settings["avatars"]["embed"] - data['allowed_mentions'] = {'parse': []} - formatted_embed = json.dumps(data, indent=4) - send_to_discord(formatted_embed) + embed.finish_embed() + send_to_discord(embed) def compact_formatter(post): @@ -76,7 +72,7 @@ def compact_formatter(post): message = _("[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], threadId=post["threadId"], postId=post["id"], title=post["_embedded"]["thread"][0]["title"], forumName=post["forumName"] ) - send_to_discord(json.dumps({'content': message, 'allowed_mentions': {'parse': []}})) + send_to_discord(DiscordMessage("compact", "discussion", content=message)) def fetch_discussions(): @@ -100,6 +96,13 @@ def fetch_discussions(): storage["discussion_id"] = int(post["id"]) datafile.save_datafile() +def format_discussion_post(modal): + """This function 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.""" + description = "" + discussion_modal = json.loads(modal) + + def safe_request(url): """Function to assure safety of request, and do not crash the script on exceptions,""" try: diff --git a/misc.py b/misc.py index 4904976..cba04c8 100644 --- a/misc.py +++ b/misc.py @@ -16,11 +16,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import json, logging, sys, re, time +import json, logging, sys, re, time, random, math from html.parser import HTMLParser from urllib.parse import urlparse, urlunparse import requests - +from collections import defaultdict from configloader import settings import gettext @@ -281,12 +281,9 @@ def create_article_path(article: str) -> str: def send_to_discord_webhook(data): header = settings["header"] - if isinstance(data, str): - header['Content-Type'] = 'application/json' - else: - header['Content-Type'] = 'application/x-www-form-urlencoded' + header['Content-Type'] = 'application/json' try: - result = requests.post(settings["webhookURL"], data=data, + result = requests.post(settings["webhookURL"], data=repr(data), headers=header, timeout=10) except requests.exceptions.Timeout: misc_logger.warning("Timeouted while sending data to the webhook.") @@ -310,4 +307,53 @@ def send_to_discord(data): messagequeue.add_message(data) elif code < 2: time.sleep(2.0) - pass \ No newline at end of file + pass + +class DiscordMessage(): + """A class defining a typical Discord JSON representation of webhook payload.""" + def __init__(self, message_type: str, event_type: str, content=None): + self.webhook_object = dict(allowed_mentions={"parse": []}, avatar_url=settings["avatars"].get(message_type, "")) + + if message_type == "embed": + self.__setup_embed() + elif message_type == "compact": + self.webhook_object["content"] = content + + self.event_type = event_type + + def __setitem__(self, key, value): + """Set item is used only in embeds.""" + try: + self.embed[key] = value + except NameError: + raise TypeError("Tried to assign a value when message type is plain message!") + + def __getitem__(self, item): + return self.embed[item] + + def __repr__(self): + """Return the Discord webhook object ready to be sent""" + return json.dumps(self.webhook_object) + + def __setup_embed(self): + self.embed = defaultdict(dict) + self.webhook_object["embeds"] = [self.embed] + self.embed["color"] = None + + def finish_embed(self): + if self.embed["color"] is None: + if settings["appearance"]["embed"].get(self.event_type, {"color": None})["color"] is None: + self.embed["color"] = random.randrange(1, 16777215) + else: + self.embed["color"] = settings["appearance"]["embed"][self.event_type]["color"] + else: + self.embed["color"] = math.floor(self.embed["color"]) + + def set_author(self, name, url): + self.embed["author"]["name"] = name + self.embed["author"]["url"] = url + + def add_field(self, name, value, inline=False): + if "fields" not in self.embed: + self.embed["fields"] = [] + self.embed["fields"].append(dict(name=name, value=value, inline=inline)) \ No newline at end of file diff --git a/rcgcdw.py b/rcgcdw.py index c3bbd94..c6e9d05 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -30,7 +30,7 @@ from urllib.parse import quote_plus from configloader import settings from misc import link_formatter, ContentParser, safe_read, add_to_dict, datafile, \ WIKI_API_PATH, WIKI_SCRIPT_PATH, WIKI_JUST_DOMAIN, create_article_path, messagequeue, send_to_discord_webhook, \ - send_to_discord + send_to_discord, DiscordMessage from session import session if settings["fandom_discussions"]["enabled"]: @@ -433,13 +433,14 @@ def compact_formatter(action, change, parsed_comment, categories): content = _("[{author}]({author_url}) deactivated a [tag]({tag_url}) \"{tag}\"").format(author=author, author_url=author_url, tag=change["logparams"]["tag"], tag_url=link) elif action == "suppressed": content = _("An action has been hidden by administration.") - send_to_discord(json.dumps({'content': content, 'allowed_mentions': {'parse': []}})) + else: + logger.warning("No entry for {event} with params: {params}".format(event=action, params=change)) + return + send_to_discord(DiscordMessage("compact", action, content=content)) def embed_formatter(action, change, parsed_comment, categories): - data = {"embeds": []} - embed = defaultdict(dict) - colornumber = None + embed = DiscordMessage("embed", action) if parsed_comment is None: parsed_comment = _("No description provided") if action != "suppressed": @@ -467,22 +468,21 @@ def embed_formatter(action, change, parsed_comment, categories): amount=recent_changes.map_ips[change["user"]]) else: author_url = create_article_path("User:{}".format(change["user"].replace(" ", "_"))) - embed["author"]["name"] = change["user"] - embed["author"]["url"] = author_url + embed.set_author(change["user"], author_url) if action in ("edit", "new"): # edit or new page editsize = change["newlen"] - change["oldlen"] if editsize > 0: if editsize > 6032: - colornumber = 65280 + embed["color"] = 65280 else: - colornumber = 35840 + (math.floor(editsize / 52)) * 256 + embed["color"] = 35840 + (math.floor(editsize / 52)) * 256 elif editsize < 0: if editsize < -6032: - colornumber = 16711680 + embed["color"] = 16711680 else: - colornumber = 9175040 + (math.floor((editsize * -1) / 52)) * 65536 + embed["color"] = 9175040 + (math.floor((editsize * -1) / 52)) * 65536 elif editsize == 0: - colornumber = 8750469 + embed["color"] = 8750469 if change["title"].startswith("MediaWiki:Tag-"): # Refresh tag list when tag display name is edited recent_changes.init_info() link = "{wiki}index.php?title={article}&curid={pageid}&diff={diff}&oldid={oldrev}".format( @@ -503,8 +503,6 @@ def embed_formatter(action, change, parsed_comment, categories): wiki=WIKI_API_PATH, diff=change["revid"],oldrev=change["old_revid"] )), "compare", "*") if changed_content: - if "fields" not in embed: - embed["fields"] = [] EditDiff = ContentParser() EditDiff.feed(changed_content) if EditDiff.small_prev_del: @@ -519,11 +517,9 @@ def embed_formatter(action, change, parsed_comment, categories): EditDiff.small_prev_ins = EditDiff.small_prev_ins.replace("****", "") logger.debug("Changed content: {}".format(EditDiff.small_prev_ins)) if EditDiff.small_prev_del and not action == "new": - embed["fields"].append( - {"name": _("Removed"), "value": "{data}".format(data=EditDiff.small_prev_del), "inline": True}) + embed.add_field(_("Removed"), "{data}".format(data=EditDiff.small_prev_del), inline=True) if EditDiff.small_prev_ins: - embed["fields"].append( - {"name": _("Added"), "value": "{data}".format(data=EditDiff.small_prev_ins), "inline": True}) + embed.add_field(_("Added"), "{data}".format(data=EditDiff.small_prev_ins), inline=True) else: logger.warning("Unable to download data on the edit content!") elif action in ("upload/overwrite", "upload/upload", "upload/revert"): # sending files @@ -557,8 +553,8 @@ def embed_formatter(action, change, parsed_comment, categories): else: undolink = "{wiki}index.php?title={filename}&action=revert&oldimage={archiveid}".format( wiki=WIKI_SCRIPT_PATH, filename=article_encoded, archiveid=revision["archivename"]) - embed["fields"] = [{"name": _("Options"), "value": _("([preview]({link}) | [undo]({undolink}))").format( - link=image_direct_url, undolink=undolink)}] + embed.add_field(_("Options"), _("([preview]({link}) | [undo]({undolink}))").format( + link=image_direct_url, undolink=undolink)) if settings["appearance"]["embed"]["embed_images"]: embed["image"]["url"] = image_direct_url if action == "upload/overwrite": @@ -596,8 +592,7 @@ def embed_formatter(action, change, parsed_comment, categories): if license is not None: parsed_comment += _("\nLicense: {}").format(license) if additional_info_retrieved: - embed["fields"] = [ - {"name": _("Options"), "value": _("([preview]({link}))").format(link=image_direct_url)}] + embed.add_field(_("Options"), _("([preview]({link}))").format(link=image_direct_url)) if settings["appearance"]["embed"]["embed_images"]: embed["image"]["url"] = image_direct_url elif action == "delete/delete": @@ -661,10 +656,7 @@ def embed_formatter(action, change, parsed_comment, categories): if len(restriction_description) > 1020: logger.debug(restriction_description) restriction_description = restriction_description[:1020]+"…" - if "fields" not in embed: - embed["fields"] = [] - embed["fields"].append( - {"name": _("Partial block details"), "value": restriction_description, "inline": True}) + embed.add_field(_("Partial block details"), restriction_description, inline=True) embed["title"] = _("Blocked {blocked_user} for {time}").format(blocked_user=user, time=block_time) elif action == "block/reblock": link = create_article_path(change["title"].replace(" ", "_").replace(')', '\)')) @@ -860,19 +852,10 @@ def embed_formatter(action, change, parsed_comment, categories): embed["url"] = link if parsed_comment is not None: embed["description"] = parsed_comment - if colornumber is None: - if settings["appearance"]["embed"][action]["color"] is None: - embed["color"] = random.randrange(1, 16777215) - else: - embed["color"] = settings["appearance"]["embed"][action]["color"] - else: - embed["color"] = math.floor(colornumber) if settings["appearance"]["embed"]["show_footer"]: embed["timestamp"] = change["timestamp"] if "tags" in change and change["tags"]: tag_displayname = [] - if "fields" not in embed: - embed["fields"] = [] for tag in change["tags"]: if tag in recent_changes.tags: if recent_changes.tags[tag] is None: @@ -881,19 +864,14 @@ def embed_formatter(action, change, parsed_comment, categories): tag_displayname.append(recent_changes.tags[tag]) else: tag_displayname.append(tag) - embed["fields"].append({"name": _("Tags"), "value": ", ".join(tag_displayname)}) + embed.add_field(_("Tags"), ", ".join(tag_displayname)) logger.debug("Current params in edit action: {}".format(change)) if categories is not None and not (len(categories["new"]) == 0 and len(categories["removed"]) == 0): - if "fields" not in embed: - embed["fields"] = [] new_cat = (_("**Added**: ") + ", ".join(list(categories["new"])[0:16]) + ("\n" if len(categories["new"])<=15 else _(" and {} more\n").format(len(categories["new"])-15))) if categories["new"] else "" del_cat = (_("**Removed**: ") + ", ".join(list(categories["removed"])[0:16]) + ("" if len(categories["removed"])<=15 else _(" and {} more").format(len(categories["removed"])-15))) if categories["removed"] else "" - embed["fields"].append({"name": _("Changed categories"), "value": new_cat + del_cat}) - data["embeds"].append(dict(embed)) - data['avatar_url'] = settings["avatars"]["embed"] - data['allowed_mentions'] = {'parse': []} - formatted_embed = json.dumps(data, indent=4) - send_to_discord(formatted_embed) + embed.add_field(_("Changed categories"), new_cat + del_cat) + embed.finish_embed() + send_to_discord(embed) def essential_info(change, changed_categories): diff --git a/settings.json.example b/settings.json.example index dcb019f..9b5b50b 100644 --- a/settings.json.example +++ b/settings.json.example @@ -14,7 +14,8 @@ "connection_failed": "https://i.imgur.com/2jWQEt1.png", "connection_restored": "", "no_event": "", - "embed": "" + "embed": "", + "compact": "" }, "ignored": ["external"], "show_updown_messages": true, @@ -263,6 +264,14 @@ "suppressed":{ "icon": "https://i.imgur.com/1gps6EZ.png", "color": 8092539 + }, + "discussion/post": { + "icon": "", + "color":null + }, + "discussion/reply": { + "icon": "", + "color":null } } }, From ebb19ba5e94a27078c8e00c414be0f2cc23237da Mon Sep 17 00:00:00 2001 From: Frisk Date: Sat, 25 Apr 2020 16:06:15 +0200 Subject: [PATCH 03/26] Progress on #112 --- discussions.py | 54 ++++++++++++++++++++++++++++++++++++-------------- misc.py | 12 +++++++++-- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/discussions.py b/discussions.py index 35aac2d..8538070 100644 --- a/discussions.py +++ b/discussions.py @@ -42,27 +42,40 @@ storage = datafile.data fetch_url = "https://services.fandom.com/discussion/{wikiid}/posts?sortDirection=descending&sortKey=creation_date&limit={limit}".format(wikiid=settings["fandom_discussions"]["wiki_id"], limit=settings["fandom_discussions"]["limit"]) -def embed_formatter(post): +def embed_formatter(post, post_type): """Embed formatter for Fandom discussions.""" embed = DiscordMessage("embed", "discussion") - embed["author"]["name"] = post["createdBy"]["name"] - embed["author"]["icon_url"] = post["createdBy"]["avatarUrl"] - embed["author"]["url"] = "{wikiurl}f/u/{creatorId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]) - if post["isReply"]: - embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) - embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], postId=post["id"]) - else: - embed["title"] = _("Created \"{title}\"").format(title=post["title"]) - embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"]) - if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: - embed["description"] = post["rawContent"] if len(post["rawContent"]) < 2000 else post["rawContent"][0:2000] + "…" + embed.set_author(post["createdBy"]["name"], "{wikiurl}f/u/{creatorId}".format( + wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]), icon_url=post["createdBy"]["avatarUrl"]) + if post_type == "TEXT": # TODO + if post["isReply"]: + embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) + embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format( + wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], postId=post["id"]) + else: + embed["title"] = _("Created \"{title}\"").format(title=post["title"]) + embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], + threadId=post["threadId"]) + if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: + embed["description"] = post["rawContent"] if len(post["rawContent"]) < 2000 else post["rawContent"][ + 0:2000] + "…" + elif post_type == "POLL": + poll = post["poll"] + embed["title"] = _("Created a poll titled \"{}\"").format(poll["question"]) + 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 _("__[View image]({image_url})__").format(image_url=option["image"]["url"]), + inline=True) embed["footer"]["text"] = post["forumName"] embed["timestamp"] = datetime.datetime.fromtimestamp(post["creationDate"]["epochSecond"], tz=datetime.timezone.utc).isoformat() embed.finish_embed() send_to_discord(embed) -def compact_formatter(post): +def compact_formatter(post, post_type): """Compact formatter for Fandom discussions.""" message = None if not post["isReply"]: @@ -91,12 +104,23 @@ def fetch_discussions(): if request_json: for post in request_json: if int(post["id"]) > storage["discussion_id"]: - formatter(post) + parse_discussion_post(post) if int(post["id"]) > storage["discussion_id"]: storage["discussion_id"] = int(post["id"]) datafile.save_datafile() -def format_discussion_post(modal): +def parse_discussion_post(post): + """Initial post recognition & handling""" + post_type = post.get("funnel", "TEXT") + if post_type == "TEXT": + formatter(post, post_type) + elif post_type == "POLL": + formatter(post, post_type) + else: + discussion_logger.warning("The type of {} is an unknown discussion post type. Please post an issue on the project page to have it added https://gitlab.com/piotrex43/RcGcDw/-/issues.") + + +def format_discussion_text(modal): """This function 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.""" description = "" diff --git a/misc.py b/misc.py index cba04c8..dbc6c01 100644 --- a/misc.py +++ b/misc.py @@ -337,9 +337,16 @@ class DiscordMessage(): def __setup_embed(self): self.embed = defaultdict(dict) - self.webhook_object["embeds"] = [self.embed] + if "embeds" not in self.webhook_object: + self.webhook_object["embeds"] = [self.embed] + else: + self.webhook_object["embeds"].append(self.embed) self.embed["color"] = None + def add_embed(self): + self.finish_embed() + self.__setup_embed() + def finish_embed(self): if self.embed["color"] is None: if settings["appearance"]["embed"].get(self.event_type, {"color": None})["color"] is None: @@ -349,9 +356,10 @@ class DiscordMessage(): else: self.embed["color"] = math.floor(self.embed["color"]) - def set_author(self, name, url): + def set_author(self, name, url, icon_url=""): self.embed["author"]["name"] = name self.embed["author"]["url"] = url + self.embed["author"]["icon_url"] = icon_url def add_field(self, name, value, inline=False): if "fields" not in self.embed: From ef9d6b90232fe474e4a4bbb4256f62bfff9e6985 Mon Sep 17 00:00:00 2001 From: Frisk Date: Sun, 26 Apr 2020 14:40:38 +0200 Subject: [PATCH 04/26] Works on formatting the Fandom discussions, fix to daily overview message handling --- discussions.py | 85 +++++++++++++++++++++++++++++++++++++++++++++----- misc.py | 3 ++ rcgcdw.py | 22 +++++-------- 3 files changed, 87 insertions(+), 23 deletions(-) diff --git a/discussions.py b/discussions.py index 8538070..4f13ac7 100644 --- a/discussions.py +++ b/discussions.py @@ -19,7 +19,7 @@ import logging, gettext, schedule, requests, json, datetime from collections import defaultdict from configloader import settings -from misc import datafile, send_to_discord, DiscordMessage +from misc import datafile, send_to_discord, DiscordMessage, WIKI_SCRIPT_PATH, escape_formatting from session import session # Initialize translation @@ -48,6 +48,7 @@ def embed_formatter(post, post_type): embed.set_author(post["createdBy"]["name"], "{wikiurl}f/u/{creatorId}".format( wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]), icon_url=post["createdBy"]["avatarUrl"]) if post_type == "TEXT": # TODO + npost = DiscussionsFromHellParser(post) if post["isReply"]: embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format( @@ -57,8 +58,7 @@ def embed_formatter(post, post_type): embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"]) if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: - embed["description"] = post["rawContent"] if len(post["rawContent"]) < 2000 else post["rawContent"][ - 0:2000] + "…" + embed["description"] = npost.parse() elif post_type == "POLL": poll = post["poll"] embed["title"] = _("Created a poll titled \"{}\"").format(poll["question"]) @@ -119,12 +119,81 @@ def parse_discussion_post(post): else: discussion_logger.warning("The type of {} is an unknown discussion post type. Please post an issue on the project page to have it added https://gitlab.com/piotrex43/RcGcDw/-/issues.") +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): + self.post = post + self.jsonModal = json.loads(post.get("jsonModel", "{}")) + self.markdown_text = "" + self.item_num = 1 -def format_discussion_text(modal): - """This function 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.""" - description = "" - discussion_modal = json.loads(modal) + def parse(self): + """Main parsing logic""" + for root_item in self.jsonModal["content"]: + if "content" in root_item: + self.parse_content(root_item["content"]) + if len(self.markdown_text) > 2000: + break + images = {} + for num, image in enumerate(self.post["_embedded"]["contentImages"]): + images["img-{}".format(num)] = image["url"] + self.markdown_text = self.markdown_text.format(images) + self.markdown_text = self.markdown_text[0:2000] + "…" + return self.markdown_text + + def parse_content(self, content, ctype=None): + for item in content: + if ctype == "bulletList": + self.markdown_text += "\t• " + if ctype == "orderedList": + self.markdown_text += "\t{num}. ".format(num=self.item_num) + self.item_num += 1 + if item["type"] == "text": + if "marks" in item: + prefix, suffix = self.convert_marks(item["marks"]) + self.markdown_text = "{old}{pre}{text}{suf}".format(old=self.markdown_text, pre=prefix, text=escape_formatting(item["text"]), suf=suffix) + else: + self.markdown_text += escape_formatting(item["text"]) + elif item["type"] == "paragraph": + if "content" in item: + self.parse_content(item, item["type"]) + self.markdown_text += "\n" + elif item["type"] == "openGraph": + if not item["attrs"]["wasAddedWithInlineLink"]: + self.markdown_text = "{old}{link}\n".format(old=self.markdown_text, link=item["attrs"]["url"]) + elif item["type"] == "image": + self.markdown_text = "{old}{img-{img}}\n".format(old=self.markdown_text, img=item["attrs"]["id"]) + elif item["type"] == "code_block": + self.markdown_text += "```\n" + if "content" in item: + self.parse_content(item, item["type"]) + self.markdown_text += "\n```\n" + elif item["type"] == "bulletList": + if "content" in item: + self.parse_content(item, item["type"]) + elif item["type"] == "orderedList": + self.item_num = 1 + if "content" in item: + self.parse_content(item, item["type"]) + + def convert_marks(self, marks): + prefix = "" + suffix = "" + for mark in marks: + if mark["type"] == "mention": + prefix += "[" + suffix = "]({wiki}f/u/{userid}){suffix}".format(wiki=WIKI_SCRIPT_PATH, userid=mark["attrs"]["userId"], suffix=suffix) + elif mark["type"] == "strong": + prefix += "**" + suffix = "**{suffix}".format(suffix=suffix) + elif mark["type"] == "link": + prefix += "[" + suffix = "]({link}){suffix}".format(link=mark["attrs"]["href"], suffix=suffix) + elif mark["type"] == "em": + prefix += "_" + suffix = "_" + suffix + return prefix, suffix def safe_request(url): diff --git a/misc.py b/misc.py index dbc6c01..f250b02 100644 --- a/misc.py +++ b/misc.py @@ -115,6 +115,9 @@ def link_formatter(link): """Formats a link to not embed it""" return "<" + re.sub(r"([)])", "\\\\\\1", link).replace(" ", "_") + ">" +def escape_formatting(data): + """Escape Discord formatting""" + return re.sub(r"([`_*~<>{}@/|\\])", "\\\\\\1", data, 0) class ContentParser(HTMLParser): more = _("\n__And more__") diff --git a/rcgcdw.py b/rcgcdw.py index c6e9d05..404ebc4 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -997,14 +997,11 @@ def day_overview(): if not settings["send_empty_overview"]: return # no changes in this day else: - embed = defaultdict(dict) + embed = DiscordMessage("embed", "daily_overview") embed["title"] = _("Daily overview") embed["url"] = create_article_path("Special:Statistics") embed["description"] = _("No activity") - embed["color"] = settings["appearance"]["embed"]["daily_overview"]["color"] - embed["author"]["icon_url"] = settings["appearance"]["embed"]["daily_overview"]["icon"] - embed["author"]["name"] = settings["wikiname"] - embed["author"]["url"] = create_article_path("") + embed.set_author(settings["wikiname"], create_article_path(""), icon_url=settings["appearance"]["embed"]["daily_overview"]["icon"]) else: for item in result[0]: if "actionhidden" in item or "suppressed" in item or "userhidden" in item: @@ -1025,13 +1022,10 @@ def day_overview(): admin = admin + 1 if item["logtype"] in ["delete", "merge", "block", "protect", "import", "rights", "abusefilter", "interwiki", "managetags"] else admin overall = round(new_articles + edits * 0.1 + files * 0.3 + admin * 0.1 + math.fabs(changed_bytes * 0.001), 2) - embed = defaultdict(dict) + embed = DiscordMessage("embed", "daily_overview") embed["title"] = _("Daily overview") embed["url"] = create_article_path("Special:Statistics") - embed["color"] = settings["appearance"]["embed"]["daily_overview"]["color"] - embed["author"]["icon_url"] = settings["appearance"]["embed"]["daily_overview"]["icon"] - embed["author"]["name"] = settings["wikiname"] - embed["author"]["url"] = create_article_path("") + embed.set_author(settings["wikiname"], create_article_path(""), icon_url=settings["appearance"]["embed"]["daily_overview"]["icon"]) if activity: active_users = [] for user, numberu in Counter(activity).most_common(3): # find most active users @@ -1050,7 +1044,6 @@ def day_overview(): houramount = "" if not active_articles: active_articles = [_("But nobody came")] - embed["fields"] = [] edits, files, admin, changed_bytes, new_articles, unique_contributors, overall = daily_overview_sync(edits, files, admin, changed_bytes, new_articles, len(activity), overall) fields = ( (ngettext("Most active user", "Most active users", len(active_users)), ', '.join(active_users)), @@ -1061,10 +1054,9 @@ def day_overview(): (ngettext("Most active hour", "Most active hours", len(active_hours)), ', '.join(active_hours) + houramount), (_("Day score"), overall)) for name, value in fields: - embed["fields"].append({"name": name, "value": value, "inline": True}) - data = {"embeds": [dict(embed)]} - formatted_embed = json.dumps(data, indent=4) - send_to_discord(formatted_embed) + embed.add_field(name, value, inline=True) + embed.finish_embed() + send_to_discord(embed) else: logger.debug("function requesting changes for day overview returned with error code") From 1f0a96b83a50dcfe7086d5387ae5225fba5b0bc7 Mon Sep 17 00:00:00 2001 From: Frisk Date: Sun, 26 Apr 2020 15:42:26 +0200 Subject: [PATCH 05/26] Finished work on #112 --- discussions.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/discussions.py b/discussions.py index 4f13ac7..0f2d0b2 100644 --- a/discussions.py +++ b/discussions.py @@ -47,8 +47,7 @@ def embed_formatter(post, post_type): embed = DiscordMessage("embed", "discussion") embed.set_author(post["createdBy"]["name"], "{wikiurl}f/u/{creatorId}".format( wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]), icon_url=post["createdBy"]["avatarUrl"]) - if post_type == "TEXT": # TODO - npost = DiscussionsFromHellParser(post) + if post_type == "TEXT": if post["isReply"]: embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format( @@ -58,6 +57,7 @@ def embed_formatter(post, post_type): embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"]) if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: + npost = DiscussionsFromHellParser(post) embed["description"] = npost.parse() elif post_type == "POLL": poll = post["poll"] @@ -130,16 +130,13 @@ class DiscussionsFromHellParser: def parse(self): """Main parsing logic""" - for root_item in self.jsonModal["content"]: - if "content" in root_item: - self.parse_content(root_item["content"]) - if len(self.markdown_text) > 2000: - break + self.parse_content(self.jsonModal["content"]) images = {} for num, image in enumerate(self.post["_embedded"]["contentImages"]): images["img-{}".format(num)] = image["url"] - self.markdown_text = self.markdown_text.format(images) - self.markdown_text = self.markdown_text[0:2000] + "…" + self.markdown_text = self.markdown_text.format(**images) + if len(self.markdown_text) > 2000: + self.markdown_text = self.markdown_text[0:2000] + "…" return self.markdown_text def parse_content(self, content, ctype=None): @@ -157,25 +154,28 @@ class DiscussionsFromHellParser: self.markdown_text += escape_formatting(item["text"]) elif item["type"] == "paragraph": if "content" in item: - self.parse_content(item, item["type"]) + self.parse_content(item["content"], item["type"]) self.markdown_text += "\n" elif item["type"] == "openGraph": if not item["attrs"]["wasAddedWithInlineLink"]: self.markdown_text = "{old}{link}\n".format(old=self.markdown_text, link=item["attrs"]["url"]) elif item["type"] == "image": - self.markdown_text = "{old}{img-{img}}\n".format(old=self.markdown_text, img=item["attrs"]["id"]) + self.markdown_text = "{old}{{img-{img}}}\n".format(old=self.markdown_text, img=item["attrs"]["id"]) + discussion_logger.debug(self.markdown_text) elif item["type"] == "code_block": self.markdown_text += "```\n" if "content" in item: - self.parse_content(item, item["type"]) + self.parse_content(item["content"], item["type"]) self.markdown_text += "\n```\n" elif item["type"] == "bulletList": if "content" in item: - self.parse_content(item, item["type"]) + self.parse_content(item["content"], item["type"]) elif item["type"] == "orderedList": self.item_num = 1 if "content" in item: - self.parse_content(item, item["type"]) + self.parse_content(item["content"], item["type"]) + elif item["type"] == "listItem": + self.parse_content(item["content"], item["type"]) def convert_marks(self, marks): prefix = "" From 897178bb765aa7bc4ba3b4f92737019033d1d593 Mon Sep 17 00:00:00 2001 From: Frisk Date: Sun, 26 Apr 2020 20:59:38 +0200 Subject: [PATCH 06/26] Updated read me --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 867f351..69f5ba1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ **Screenshots** of the script in action can be found [on the wiki](https://gitlab.com/piotrex43/RcGcDw/wikis/Presentation). ### Features ### -* Fetch recent changes from MediaWiki wiki and send them to Discord channel using a webhook +* Fetch recent changes from MediaWiki wiki or/and Discussions from Fandom wikis and send them to Discord channel using a webhook * Two appearance modes - embed and compact * Send daily overviews, that show general information about wiki activity * Supports multiple languages (included EN, PL, BR, RU, FR, UK) From 1bf9a42ad3e463e21871ff96675572d7a5e0b898 Mon Sep 17 00:00:00 2001 From: Frisk Date: Sun, 26 Apr 2020 21:12:47 +0200 Subject: [PATCH 07/26] If one image just add it to embed --- discussions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/discussions.py b/discussions.py index 0f2d0b2..07b1052 100644 --- a/discussions.py +++ b/discussions.py @@ -59,6 +59,9 @@ def embed_formatter(post, post_type): if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: npost = DiscussionsFromHellParser(post) embed["description"] = npost.parse() + if npost.image_only: + embed["image"]["url"] = embed["description"].strip() + embed["description"] = "" elif post_type == "POLL": poll = post["poll"] embed["title"] = _("Created a poll titled \"{}\"").format(poll["question"]) @@ -127,6 +130,7 @@ class DiscussionsFromHellParser: self.jsonModal = json.loads(post.get("jsonModel", "{}")) self.markdown_text = "" self.item_num = 1 + self.image_only = False def parse(self): """Main parsing logic""" @@ -134,6 +138,8 @@ class DiscussionsFromHellParser: images = {} for num, image in enumerate(self.post["_embedded"]["contentImages"]): images["img-{}".format(num)] = image["url"] + if len(images.keys()) == 1 and self.markdown_text.strip() == "{img-0}": + self.image_only = True self.markdown_text = self.markdown_text.format(**images) if len(self.markdown_text) > 2000: self.markdown_text = self.markdown_text[0:2000] + "…" From 8d54081316f54e7ef387804fa6c5c9d41521f642 Mon Sep 17 00:00:00 2001 From: Frisk Date: Sun, 26 Apr 2020 22:27:52 +0200 Subject: [PATCH 08/26] Added #115, additional enchantments --- discussions.pot | 46 +++-- discussions.py | 25 ++- locale/pl/LC_MESSAGES/discussions.mo | Bin 1060 -> 1517 bytes locale/pl/LC_MESSAGES/discussions.po | 33 +++- locale/pt-br/LC_MESSAGES/discussions.mo | Bin 0 -> 999 bytes locale/pt-br/LC_MESSAGES/discussions.po | 67 +++++++ misc.pot | 4 +- rcgcdw.pot | 252 ++++++++++++------------ rcgcdw.py | 2 + settings.json.example | 4 + 10 files changed, 280 insertions(+), 153 deletions(-) create mode 100644 locale/pt-br/LC_MESSAGES/discussions.mo create mode 100644 locale/pt-br/LC_MESSAGES/discussions.po diff --git a/discussions.pot b/discussions.pot index 48467a8..45b2dc0 100644 --- a/discussions.pot +++ b/discussions.pot @@ -1,41 +1,63 @@ +# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. # +#, fuzzy msgid "" msgstr "" -"Project-Id-Version: \n" +"Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-06 18:55+0200\n" -"PO-Revision-Date: 2020-04-23 23:41+0200\n" -"Last-Translator: Frisk \n" -"Language-Team: \n" -"Language: en_US\n" +"POT-Creation-Date: 2020-04-26 22:05+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" +"Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Lokalize 19.12.3\n" #: discussions.py:53 #, python-brace-format msgid "Replied to \"{title}\"" msgstr "" -#: discussions.py:56 +#: discussions.py:58 #, python-brace-format msgid "Created \"{title}\"" msgstr "" -#: discussions.py:73 +#: discussions.py:70 +#, python-brace-format +msgid "Created a poll titled \"{title}\"" +msgstr "" + +#: discussions.py:75 +msgid "Option {}" +msgstr "" + +#: discussions.py:76 +#, python-brace-format +msgid "__[View image]({image_url})__" +msgstr "" + +#: discussions.py:89 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " "in {forumName}" msgstr "" -#: discussions.py:76 +#: discussions.py:92 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" "{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}" msgstr "" + +#: discussions.py:97 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" +msgstr "" diff --git a/discussions.py b/discussions.py index 07b1052..d073d9f 100644 --- a/discussions.py +++ b/discussions.py @@ -49,10 +49,12 @@ def embed_formatter(post, post_type): wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]), icon_url=post["createdBy"]["avatarUrl"]) if post_type == "TEXT": if post["isReply"]: + embed.event_type = "discussion/reply" embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format( wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], postId=post["id"]) else: + embed.event_type = "discussion/post" embed["title"] = _("Created \"{title}\"").format(title=post["title"]) embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"]) @@ -63,8 +65,9 @@ def embed_formatter(post, post_type): embed["image"]["url"] = embed["description"].strip() embed["description"] = "" elif post_type == "POLL": + embed.event_type = "discussion/poll" poll = post["poll"] - embed["title"] = _("Created a poll titled \"{}\"").format(poll["question"]) + embed["title"] = _("Created a poll titled \"{title}\"").format(title=poll["question"]) image_type = False if poll["answers"][0]["image"] is not None: image_type = True @@ -81,13 +84,19 @@ def embed_formatter(post, post_type): def compact_formatter(post, post_type): """Compact formatter for Fandom discussions.""" message = None - if not post["isReply"]: - message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) in {forumName}").format( - author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["title"], threadId=post["threadId"], forumName=post["forumName"]) - else: - message = _("[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( - author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], threadId=post["threadId"], postId=post["id"], title=post["_embedded"]["thread"][0]["title"], forumName=post["forumName"] - ) + if post_type == "TEXT": + if not post["isReply"]: + message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) in {forumName}").format( + author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["title"], threadId=post["threadId"], forumName=post["forumName"]) + else: + message = _("[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( + author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], threadId=post["threadId"], postId=post["id"], title=post["_embedded"]["thread"][0]["title"], forumName=post["forumName"] + ) + elif post_type == "POLL": + message = _( + "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/{threadId}>) in {forumName}").format( + author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], + creatorId=post["creatorId"], title=post["title"], threadId=post["threadId"], forumName=post["forumName"]) send_to_discord(DiscordMessage("compact", "discussion", content=message)) diff --git a/locale/pl/LC_MESSAGES/discussions.mo b/locale/pl/LC_MESSAGES/discussions.mo index d0c7c005925e2534b52541d1d84588465d4604eb..b2f227b88f61ece217018d04692203676e618dfd 100644 GIT binary patch delta 476 zcmZXO&r1SP5XWa*s}=Lm4+tvjp@-}cGyf%TpIw+uTK-h%2H99XfQ7 zEyAEq9lQB2C`5lkhbTLDh>l(Qx|jqFeE7UKGjHD9D<6UC%Y^TW5PmQR(jW*PKrddw zICujK;0yG6CncgOI0PqP6+VYAU=B|Yp$3=W1LUsZ8Qec*^ul94B88|*n>a8ecHm>! zfSd3moPm?WL}B;|#vCtD8U*Ij2*6x#vC)17!wFA_w(>d`dYXmH!Vsoj2@f)y+4GiZ zGB5wPA#Mx9%CT~#ar5m4q-CFtw#IWTq-lryhF)aGDbMIf(XwZ)kT)w!n&w_g+lsoz zRCPVJ+Ip83rHwsNwDL}=Q;+f`#&aizF4|4za8VM4PTeZFf5Yj^$Cy0u%1+o>$a m*Db$1E8+8qyDJBk-?wf;UWs6fgq7qehdJqNyO}cntwKMN|7~^v delta 187 zcmaFMy@aFwo)F7a1|VPsVi_QI0b+I_&H-W&=m26tAnpWW5g?uo#8E)J0f<3j+>8ti zkw82Zh^2u1_e=~73P75RnSmh=NNWS>nLxS=NCTBH0HwhIWFHFygERwB90Ht+QWHy3 rQxue{OEODxQfrka%P{_)Je|pn!@x|z(89{pZ1Ynlb;iveEK-aB$VeH) diff --git a/locale/pl/LC_MESSAGES/discussions.po b/locale/pl/LC_MESSAGES/discussions.po index d220975..e8aa815 100644 --- a/locale/pl/LC_MESSAGES/discussions.po +++ b/locale/pl/LC_MESSAGES/discussions.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-06 18:55+0200\n" -"PO-Revision-Date: 2020-04-06 18:56+0200\n" +"POT-Creation-Date: 2020-04-26 22:05+0200\n" +"PO-Revision-Date: 2020-04-26 22:15+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: pl\n" @@ -24,12 +24,26 @@ msgstr "" msgid "Replied to \"{title}\"" msgstr "Odpowiedział(a) w „{title}”" -#: discussions.py:56 +#: discussions.py:58 #, python-brace-format msgid "Created \"{title}\"" msgstr "Utworzył(a) „{title}”" -#: discussions.py:73 +#: discussions.py:70 +#, python-brace-format +msgid "Created a poll titled \"{title}\"" +msgstr "Utworzył(a) ankietę zatytułowaną „{title}”" + +#: discussions.py:75 +msgid "Option {}" +msgstr "Opcja {}" + +#: discussions.py:76 +#, python-brace-format +msgid "__[View image]({image_url})__" +msgstr "__[Zobacz zdjęcie]({image_url})__" + +#: discussions.py:89 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " @@ -38,7 +52,7 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) utworzył(a) [{title}](<{url}f/p/{threadId}" ">) w {forumName}" -#: discussions.py:76 +#: discussions.py:92 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -47,3 +61,12 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) utworzył(a) [odpowiedź](<{url}f/p/" "{threadId}/r/{postId}>) pod tematem [{title}](<{url}f/p/{threadId}>) w " "{forumName}" + +#: discussions.py:97 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) utworzył(a) ankietę [{title}](<{url}f/p/" +"{threadId}>) w {forumName}" diff --git a/locale/pt-br/LC_MESSAGES/discussions.mo b/locale/pt-br/LC_MESSAGES/discussions.mo new file mode 100644 index 0000000000000000000000000000000000000000..7a7c9a6b3d239ab16ad35f7908f697b5669aea2f GIT binary patch literal 999 zcmb7C(P|Sx6di3v*uJQUPd!q2?0HiqTeO}x{Rg~+=-ZO=T5pr z%(h8Sq=^LM^a?r1dFCeC%--!B2Si06|QmGZ?W1^SGXAo!%oyt$5M?WTKgcK*G)3R6V}pZ zY9p%Bd1)JAotB@C9Yr5CXmz*lyXWi!dk!3tnT(70>nCv literal 0 HcmV?d00001 diff --git a/locale/pt-br/LC_MESSAGES/discussions.po b/locale/pt-br/LC_MESSAGES/discussions.po new file mode 100644 index 0000000..f132340 --- /dev/null +++ b/locale/pt-br/LC_MESSAGES/discussions.po @@ -0,0 +1,67 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Frisk , 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-04-26 22:05+0200\n" +"PO-Revision-Date: 2020-04-26 22:18+0200\n" +"Last-Translator: Frisk \n" +"Language-Team: \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.3\n" + +#: discussions.py:53 +#, python-brace-format +msgid "Replied to \"{title}\"" +msgstr "Respondido o \"{title}\"" + +#: discussions.py:58 +#, python-brace-format +msgid "Created \"{title}\"" +msgstr "Criado \"{title}\"" + +#: discussions.py:70 +#, python-brace-format +msgid "Created a poll titled \"{title}\"" +msgstr "" + +#: discussions.py:75 +msgid "Option {}" +msgstr "" + +#: discussions.py:76 +#, python-brace-format +msgid "__[View image]({image_url})__" +msgstr "" + +#: discussions.py:89 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " +"in {forumName}" +msgstr "" +"Criado [{title}](<{url}f/p/{threadId}>) por [{author}](<{url}f/u/{creatorId}" +">) no {forumName}" + +#: discussions.py:92 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" +"{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}" +msgstr "" +"[Responder](<{url}f/p/{threadId}/r/{postId}>) por [{author}](<{url}f/u/" +"{creatorId}>) do [{title}](<{url}f/p/{threadId}>) do {forumName}" + +#: discussions.py:97 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" +msgstr "" diff --git a/misc.pot b/misc.pot index ac516c8..8b2322c 100644 --- a/misc.pot +++ b/misc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-06 18:47+0200\n" +"POT-Creation-Date: 2020-04-26 21:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: misc.py:120 +#: misc.py:123 msgid "" "\n" "__And more__" diff --git a/rcgcdw.pot b/rcgcdw.pot index 0fb1eea..eabec84 100644 --- a/rcgcdw.pot +++ b/rcgcdw.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-06 18:47+0200\n" +"POT-Creation-Date: 2020-04-26 21:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,7 +70,7 @@ msgstr "" msgid "Battle.net handle" msgstr "" -#: rcgcdw.py:132 rcgcdw.py:856 +#: rcgcdw.py:132 rcgcdw.py:848 msgid "Unknown" msgstr "" @@ -151,7 +151,7 @@ msgid "" "* to [{target}]({target_url}){comment}" msgstr "" -#: rcgcdw.py:222 rcgcdw.py:631 +#: rcgcdw.py:222 rcgcdw.py:626 msgid "infinity and beyond" msgstr "" @@ -159,7 +159,7 @@ msgstr "" msgid " on pages: " msgstr "" -#: rcgcdw.py:246 rcgcdw.py:651 +#: rcgcdw.py:246 rcgcdw.py:646 msgid " and namespaces: " msgstr "" @@ -240,11 +240,11 @@ msgid "" "[{author}]({author_url}) edited the {field} on {target} profile. *({desc})*" msgstr "" -#: rcgcdw.py:317 rcgcdw.py:319 rcgcdw.py:732 rcgcdw.py:734 +#: rcgcdw.py:317 rcgcdw.py:319 rcgcdw.py:724 rcgcdw.py:726 msgid "none" msgstr "" -#: rcgcdw.py:325 rcgcdw.py:719 +#: rcgcdw.py:325 rcgcdw.py:711 msgid "System" msgstr "" @@ -255,7 +255,7 @@ msgid "" "following settings: {settings}{comment}" msgstr "" -#: rcgcdw.py:332 rcgcdw.py:340 rcgcdw.py:742 rcgcdw.py:748 +#: rcgcdw.py:332 rcgcdw.py:340 rcgcdw.py:734 rcgcdw.py:740 msgid " [cascading]" msgstr "" @@ -419,7 +419,7 @@ msgstr "" msgid "An action has been hidden by administration." msgstr "" -#: rcgcdw.py:444 rcgcdw.py:735 +#: rcgcdw.py:445 rcgcdw.py:727 msgid "No description provided" msgstr "" @@ -435,559 +435,559 @@ msgstr "" msgid "b" msgstr "" -#: rcgcdw.py:512 rcgcdw.py:517 +#: rcgcdw.py:510 rcgcdw.py:515 msgid "__Only whitespace__" msgstr "" -#: rcgcdw.py:523 +#: rcgcdw.py:520 msgid "Removed" msgstr "" -#: rcgcdw.py:526 +#: rcgcdw.py:522 msgid "Added" msgstr "" -#: rcgcdw.py:560 rcgcdw.py:600 +#: rcgcdw.py:556 rcgcdw.py:595 msgid "Options" msgstr "" -#: rcgcdw.py:560 +#: rcgcdw.py:556 #, python-brace-format msgid "([preview]({link}) | [undo]({undolink}))" msgstr "" -#: rcgcdw.py:565 +#: rcgcdw.py:561 #, python-brace-format msgid "Uploaded a new version of {name}" msgstr "" -#: rcgcdw.py:567 +#: rcgcdw.py:563 #, python-brace-format msgid "Reverted a version of {name}" msgstr "" -#: rcgcdw.py:569 +#: rcgcdw.py:565 #, python-brace-format msgid "Uploaded {name}" msgstr "" -#: rcgcdw.py:585 +#: rcgcdw.py:581 msgid "**No license!**" msgstr "" -#: rcgcdw.py:597 +#: rcgcdw.py:593 msgid "" "\n" "License: {}" msgstr "" -#: rcgcdw.py:600 +#: rcgcdw.py:595 #, python-brace-format msgid "([preview]({link}))" msgstr "" -#: rcgcdw.py:605 +#: rcgcdw.py:600 #, python-brace-format msgid "Deleted page {article}" msgstr "" -#: rcgcdw.py:608 +#: rcgcdw.py:603 #, python-brace-format msgid "Deleted redirect {article} by overwriting" msgstr "" -#: rcgcdw.py:612 +#: rcgcdw.py:607 msgid "No redirect has been made" msgstr "" -#: rcgcdw.py:613 +#: rcgcdw.py:608 msgid "A redirect has been made" msgstr "" -#: rcgcdw.py:614 +#: rcgcdw.py:609 #, python-brace-format msgid "Moved {redirect}{article} to {target}" msgstr "" -#: rcgcdw.py:617 +#: rcgcdw.py:612 #, python-brace-format msgid "Moved {redirect}{article} to {title} over redirect" msgstr "" -#: rcgcdw.py:621 +#: rcgcdw.py:616 #, python-brace-format msgid "Moved protection settings from {redirect}{article} to {title}" msgstr "" -#: rcgcdw.py:644 +#: rcgcdw.py:639 msgid "Blocked from editing the following pages: " msgstr "" -#: rcgcdw.py:653 +#: rcgcdw.py:648 msgid "Blocked from editing pages on following namespaces: " msgstr "" -#: rcgcdw.py:667 +#: rcgcdw.py:659 msgid "Partial block details" msgstr "" -#: rcgcdw.py:668 +#: rcgcdw.py:660 #, python-brace-format msgid "Blocked {blocked_user} for {time}" msgstr "" -#: rcgcdw.py:672 +#: rcgcdw.py:664 #, python-brace-format msgid "Changed block settings for {blocked_user}" msgstr "" -#: rcgcdw.py:676 +#: rcgcdw.py:668 #, python-brace-format msgid "Unblocked {blocked_user}" msgstr "" -#: rcgcdw.py:681 +#: rcgcdw.py:673 #, python-brace-format msgid "Left a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:683 +#: rcgcdw.py:675 msgid "Left a comment on their own profile" msgstr "" -#: rcgcdw.py:688 +#: rcgcdw.py:680 #, python-brace-format msgid "Replied to a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:690 +#: rcgcdw.py:682 msgid "Replied to a comment on their own profile" msgstr "" -#: rcgcdw.py:695 +#: rcgcdw.py:687 #, python-brace-format msgid "Edited a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:697 +#: rcgcdw.py:689 msgid "Edited a comment on their own profile" msgstr "" -#: rcgcdw.py:700 +#: rcgcdw.py:692 #, python-brace-format msgid "Edited {target}'s profile" msgstr "" -#: rcgcdw.py:700 +#: rcgcdw.py:692 msgid "Edited their own profile" msgstr "" -#: rcgcdw.py:702 +#: rcgcdw.py:694 #, python-brace-format msgid "Cleared the {field} field" msgstr "" -#: rcgcdw.py:704 +#: rcgcdw.py:696 #, python-brace-format msgid "{field} field changed to: {desc}" msgstr "" -#: rcgcdw.py:707 +#: rcgcdw.py:699 #, python-brace-format msgid "Purged a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:713 +#: rcgcdw.py:705 #, python-brace-format msgid "Deleted a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:717 +#: rcgcdw.py:709 #, python-brace-format msgid "Changed group membership for {target}" msgstr "" -#: rcgcdw.py:721 +#: rcgcdw.py:713 #, python-brace-format msgid "{target} got autopromoted to a new usergroup" msgstr "" -#: rcgcdw.py:736 +#: rcgcdw.py:728 #, python-brace-format msgid "Groups changed from {old_groups} to {new_groups}{reason}" msgstr "" -#: rcgcdw.py:740 +#: rcgcdw.py:732 #, python-brace-format msgid "Protected {target}" msgstr "" -#: rcgcdw.py:746 +#: rcgcdw.py:738 #, python-brace-format msgid "Changed protection level for {article}" msgstr "" -#: rcgcdw.py:752 +#: rcgcdw.py:744 #, python-brace-format msgid "Removed protection from {article}" msgstr "" -#: rcgcdw.py:756 +#: rcgcdw.py:748 #, python-brace-format msgid "Changed visibility of revision on page {article} " msgid_plural "Changed visibility of {amount} revisions on page {article} " msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:761 +#: rcgcdw.py:753 #, python-brace-format msgid "Imported {article} with {count} revision" msgid_plural "Imported {article} with {count} revisions" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:766 +#: rcgcdw.py:758 #, python-brace-format msgid "Restored {article}" msgstr "" -#: rcgcdw.py:769 +#: rcgcdw.py:761 msgid "Changed visibility of log events" msgstr "" -#: rcgcdw.py:772 +#: rcgcdw.py:764 msgid "Imported interwiki" msgstr "" -#: rcgcdw.py:775 +#: rcgcdw.py:767 #, python-brace-format msgid "Edited abuse filter number {number}" msgstr "" -#: rcgcdw.py:778 +#: rcgcdw.py:770 #, python-brace-format msgid "Created abuse filter number {number}" msgstr "" -#: rcgcdw.py:781 +#: rcgcdw.py:773 #, python-brace-format msgid "Merged revision histories of {article} into {dest}" msgstr "" -#: rcgcdw.py:785 +#: rcgcdw.py:777 msgid "Added an entry to the interwiki table" msgstr "" -#: rcgcdw.py:786 rcgcdw.py:792 +#: rcgcdw.py:778 rcgcdw.py:784 #, python-brace-format msgid "Prefix: {prefix}, website: {website} | {desc}" msgstr "" -#: rcgcdw.py:791 +#: rcgcdw.py:783 msgid "Edited an entry in interwiki table" msgstr "" -#: rcgcdw.py:797 +#: rcgcdw.py:789 msgid "Deleted an entry in interwiki table" msgstr "" -#: rcgcdw.py:798 +#: rcgcdw.py:790 #, python-brace-format msgid "Prefix: {prefix} | {desc}" msgstr "" -#: rcgcdw.py:801 +#: rcgcdw.py:793 #, python-brace-format msgid "Changed the content model of the page {article}" msgstr "" -#: rcgcdw.py:802 +#: rcgcdw.py:794 #, python-brace-format msgid "Model changed from {old} to {new}: {reason}" msgstr "" -#: rcgcdw.py:807 +#: rcgcdw.py:799 #, python-brace-format msgid "Edited the sprite for {article}" msgstr "" -#: rcgcdw.py:810 +#: rcgcdw.py:802 #, python-brace-format msgid "Created the sprite sheet for {article}" msgstr "" -#: rcgcdw.py:813 +#: rcgcdw.py:805 #, python-brace-format msgid "Edited the slice for {article}" msgstr "" -#: rcgcdw.py:819 +#: rcgcdw.py:811 #, python-brace-format msgid "Created the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:823 +#: rcgcdw.py:815 #, python-brace-format msgid "Deleted the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:830 +#: rcgcdw.py:822 #, python-brace-format msgid "Recreated the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:837 +#: rcgcdw.py:829 #, python-brace-format msgid "Replaced the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:841 +#: rcgcdw.py:833 #, python-brace-format msgid "Created a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:845 +#: rcgcdw.py:837 #, python-brace-format msgid "Deleted a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:849 +#: rcgcdw.py:841 #, python-brace-format msgid "Activated a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:852 +#: rcgcdw.py:844 #, python-brace-format msgid "Deactivated a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:855 +#: rcgcdw.py:847 msgid "Action has been hidden by administration." msgstr "" -#: rcgcdw.py:884 +#: rcgcdw.py:867 msgid "Tags" msgstr "" -#: rcgcdw.py:889 +#: rcgcdw.py:870 msgid "**Added**: " msgstr "" -#: rcgcdw.py:889 +#: rcgcdw.py:870 msgid " and {} more\n" msgstr "" -#: rcgcdw.py:890 +#: rcgcdw.py:871 msgid "**Removed**: " msgstr "" -#: rcgcdw.py:890 +#: rcgcdw.py:871 msgid " and {} more" msgstr "" -#: rcgcdw.py:891 +#: rcgcdw.py:872 msgid "Changed categories" msgstr "" -#: rcgcdw.py:911 +#: rcgcdw.py:889 msgid "~~hidden~~" msgstr "" -#: rcgcdw.py:917 +#: rcgcdw.py:895 msgid "hidden" msgstr "" -#: rcgcdw.py:984 rcgcdw.py:986 rcgcdw.py:988 rcgcdw.py:990 rcgcdw.py:992 -#: rcgcdw.py:994 rcgcdw.py:996 +#: rcgcdw.py:965 rcgcdw.py:967 rcgcdw.py:969 rcgcdw.py:971 rcgcdw.py:973 +#: rcgcdw.py:975 rcgcdw.py:977 #, python-brace-format msgid "{value} (avg. {avg})" msgstr "" -#: rcgcdw.py:1020 rcgcdw.py:1048 +#: rcgcdw.py:1001 rcgcdw.py:1026 msgid "Daily overview" msgstr "" -#: rcgcdw.py:1022 +#: rcgcdw.py:1003 msgid "No activity" msgstr "" -#: rcgcdw.py:1057 +#: rcgcdw.py:1032 msgid " ({} action)" msgid_plural " ({} actions)" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1059 +#: rcgcdw.py:1034 msgid " ({} edit)" msgid_plural " ({} edits)" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1064 +#: rcgcdw.py:1039 msgid " UTC ({} action)" msgid_plural " UTC ({} actions)" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1066 rcgcdw.py:1067 rcgcdw.py:1071 +#: rcgcdw.py:1041 rcgcdw.py:1042 rcgcdw.py:1046 msgid "But nobody came" msgstr "" -#: rcgcdw.py:1075 +#: rcgcdw.py:1049 msgid "Most active user" msgid_plural "Most active users" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1076 +#: rcgcdw.py:1050 msgid "Most edited article" msgid_plural "Most edited articles" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1077 +#: rcgcdw.py:1051 msgid "Edits made" msgstr "" -#: rcgcdw.py:1077 +#: rcgcdw.py:1051 msgid "New files" msgstr "" -#: rcgcdw.py:1077 +#: rcgcdw.py:1051 msgid "Admin actions" msgstr "" -#: rcgcdw.py:1078 +#: rcgcdw.py:1052 msgid "Bytes changed" msgstr "" -#: rcgcdw.py:1078 +#: rcgcdw.py:1052 msgid "New articles" msgstr "" -#: rcgcdw.py:1079 +#: rcgcdw.py:1053 msgid "Unique contributors" msgstr "" -#: rcgcdw.py:1080 +#: rcgcdw.py:1054 msgid "Most active hour" msgid_plural "Most active hours" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1081 +#: rcgcdw.py:1055 msgid "Day score" msgstr "" -#: rcgcdw.py:1223 +#: rcgcdw.py:1196 #, python-brace-format msgid "Connection to {wiki} seems to be stable now." msgstr "" -#: rcgcdw.py:1224 rcgcdw.py:1339 +#: rcgcdw.py:1197 rcgcdw.py:1312 msgid "Connection status" msgstr "" -#: rcgcdw.py:1338 +#: rcgcdw.py:1311 #, python-brace-format msgid "{wiki} seems to be down or unreachable." msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "director" msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "bot" msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "editor" msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "directors" msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "sysop" msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "bureaucrat" msgstr "" -#: rcgcdw.py:1397 +#: rcgcdw.py:1386 msgid "reviewer" msgstr "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "autoreview" msgstr "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "autopatrol" msgstr "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "wiki_guardian" msgstr "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "week" msgid_plural "weeks" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "month" msgid_plural "months" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "year" msgid_plural "years" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "millennium" msgid_plural "millennia" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "decade" msgid_plural "decades" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1398 +#: rcgcdw.py:1387 msgid "century" msgid_plural "centuries" msgstr[0] "" diff --git a/rcgcdw.py b/rcgcdw.py index 404ebc4..429ef17 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -1395,6 +1395,8 @@ if TESTING: recent_changes.ids = [1] recent_changes.fetch(amount=5) day_overview() + import discussions + discussions.fetch_discussions() sys.exit(0) while 1: diff --git a/settings.json.example b/settings.json.example index 9b5b50b..cf1025b 100644 --- a/settings.json.example +++ b/settings.json.example @@ -272,6 +272,10 @@ "discussion/reply": { "icon": "", "color":null + }, + "discussion/poll": { + "icon": "", + "color": null } } }, From 4dcea63f86a1b4bc9af33d69102ce45ded24ef5b Mon Sep 17 00:00:00 2001 From: Frisk Date: Mon, 27 Apr 2020 18:06:48 +0200 Subject: [PATCH 09/26] German translation by Markus, small fixes from initial testing --- discussions.py | 15 ++++++----- locale/de/LC_MESSAGES/discussions.mo | Bin 985 -> 1428 bytes locale/de/LC_MESSAGES/discussions.po | 37 ++++++++++++++++++++++----- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/discussions.py b/discussions.py index d073d9f..2e69ec6 100644 --- a/discussions.py +++ b/discussions.py @@ -59,11 +59,14 @@ def embed_formatter(post, post_type): embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"]) if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: - npost = DiscussionsFromHellParser(post) - embed["description"] = npost.parse() - if npost.image_only: - embed["image"]["url"] = embed["description"].strip() - embed["description"] = "" + if post.get("jsonModel") is not None: + npost = DiscussionsFromHellParser(post) + embed["description"] = npost.parse() + if npost.image_only: + embed["image"]["url"] = embed["description"].strip() + embed["description"] = "" + else: # Fallback when model is not available + embed["description"] = post.get("rawContent", "") elif post_type == "POLL": embed.event_type = "discussion/poll" poll = post["poll"] @@ -198,7 +201,7 @@ class DiscussionsFromHellParser: for mark in marks: if mark["type"] == "mention": prefix += "[" - suffix = "]({wiki}f/u/{userid}){suffix}".format(wiki=WIKI_SCRIPT_PATH, userid=mark["attrs"]["userId"], suffix=suffix) + suffix = "]({wiki}f/u/{userid}){suffix}".format(wiki=settings["fandom_discussions"]["wiki_url"], userid=mark["attrs"]["userId"], suffix=suffix) elif mark["type"] == "strong": prefix += "**" suffix = "**{suffix}".format(suffix=suffix) diff --git a/locale/de/LC_MESSAGES/discussions.mo b/locale/de/LC_MESSAGES/discussions.mo index 75a22cd6e6cc8b45b7d01a65a4915918c0494da9..290c27a51efefeb0cf0825b9a268f6222a301106 100644 GIT binary patch delta 543 zcmZ9HO-lkn7{_PTvebfJz>C&k9SRXtB0)M8;U(x|9eQCI*ijb7Rdz>0WYKGfAXy`b z=o54cqI>6{YaOEe3K0Yy>hC79_`sjv%=7-d1iRtZ+ic*1z$T#>q(M{AE!4MnXa@R# z7NJk5pF5`zG7rYV127Aof@dHDqdvsI21wz%1f%#r_z77CpF#9#kuN;@gMYyzFcu)> z9BhC(7#jN@EJ5^f4WXf-FBykW?k*M_L?%F#5VB=*Cb>ovO{q)4?ZnW-Xlx+&~cRdu>bVI!NPnOuHt zJ(8ti z3P3y+h{b{YZA=hz&H?EdApbRxo&cmhm>C#=N*I7#FaX)d!oVQS02GG+=c3falGGFh zrRtK*lAP39rO7gkzb8*;a+5VMS1>fRGBwsVFfuUU@=44~FHKBO)eT8a%(YUOEXiCf z=#yAnq8n0_m{**WSdw1^6zyi#QH80rQb) created [{title}](<{url}f/p/{threadId}>) " @@ -37,7 +51,7 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) erstellte [{title}](<{url}f/p/{threadId}" ">) in {forumName}" -#: discussions.py:76 +#: discussions.py:92 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -45,3 +59,12 @@ msgid "" msgstr "" "[{author}](<{url}f/u/{creatorId}>) erstellte eine [Antwork](<{url}f/p/" "{threadId}/r/{postId}>) zu [{title}](<{url}f/p/{threadId}>) in {forumName}" + +#: discussions.py:97 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) erstellte eine Umfrage [{title}](<{url}f/" +"p/{threadId}>) in {forumName}" From 4690fa1fe30436444da9f3060159e61ba43c471c Mon Sep 17 00:00:00 2001 From: Frisk Date: Tue, 28 Apr 2020 02:49:36 +0200 Subject: [PATCH 10/26] Fixed #117 --- discussions.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/discussions.py b/discussions.py index 2e69ec6..c09eeed 100644 --- a/discussions.py +++ b/discussions.py @@ -147,12 +147,6 @@ class DiscussionsFromHellParser: def parse(self): """Main parsing logic""" self.parse_content(self.jsonModal["content"]) - images = {} - for num, image in enumerate(self.post["_embedded"]["contentImages"]): - images["img-{}".format(num)] = image["url"] - if len(images.keys()) == 1 and self.markdown_text.strip() == "{img-0}": - self.image_only = True - self.markdown_text = self.markdown_text.format(**images) if len(self.markdown_text) > 2000: self.markdown_text = self.markdown_text[0:2000] + "…" return self.markdown_text @@ -178,7 +172,11 @@ class DiscussionsFromHellParser: if not item["attrs"]["wasAddedWithInlineLink"]: self.markdown_text = "{old}{link}\n".format(old=self.markdown_text, link=item["attrs"]["url"]) elif item["type"] == "image": - self.markdown_text = "{old}{{img-{img}}}\n".format(old=self.markdown_text, img=item["attrs"]["id"]) + try: + discussion_logger.debug(item["attrs"]["id"]) + self.markdown_text = "{old}{img_url}\n".format(old=self.markdown_text, img_url=self.post["_embedded"]["contentImages"][int(item["attrs"]["id"])]["url"]) + except (IndexError, ValueError): + discussion_logger.warning("Image {} not found.".format(item["attrs"]["id"])) discussion_logger.debug(self.markdown_text) elif item["type"] == "code_block": self.markdown_text += "```\n" From 1d2015148131a45d7f5835151f6c5281fd8d1891 Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 6 May 2020 10:34:20 +0200 Subject: [PATCH 11/26] Fixed #124 --- rcgcdw.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rcgcdw.py b/rcgcdw.py index 429ef17..d651d64 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -635,12 +635,12 @@ def embed_formatter(action, change, parsed_comment, categories): return if "sitewide" not in change["logparams"]: restriction_description = "" - if change["logparams"]["restrictions"]["pages"]: + if "pages" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["pages"]: restriction_description = _("Blocked from editing the following pages: ") for page in change["logparams"]["restrictions"]["pages"]: restricted_pages = ["*"+i["page_title"]+"*" for i in change["logparams"]["restrictions"]["pages"]] restriction_description = restriction_description + ", ".join(restricted_pages) - if change["logparams"]["restrictions"]["namespaces"]: + if "namespaces" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["namespaces"]: namespaces = [] if restriction_description: restriction_description = restriction_description + _(" and namespaces: ") From 925934b6e456281511dc03dea7cc350abe77cbf9 Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 6 May 2020 10:42:33 +0200 Subject: [PATCH 12/26] Fixed #124 for compact --- rcgcdw.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rcgcdw.py b/rcgcdw.py index d651d64..29b7d09 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -235,12 +235,12 @@ def compact_formatter(action, change, parsed_comment, categories): return if "sitewide" not in change["logparams"]: restriction_description = "" - if change["logparams"]["restrictions"]["pages"]: + if "pages" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["pages"]: restriction_description = _(" on pages: ") for page in change["logparams"]["restrictions"]["pages"]: restricted_pages = ["*{page}*".format(page=i["page_title"]) for i in change["logparams"]["restrictions"]["pages"]] restriction_description = restriction_description + ", ".join(restricted_pages) - if change["logparams"]["restrictions"]["namespaces"]: + if "namespaces" in change["logparams"]["restrictions"] and change["logparams"]["restrictions"]["namespaces"]: namespaces = [] if restriction_description: restriction_description = restriction_description + _(" and namespaces: ") From 9a66a8c6f940ff55a55605c3414e590dfca37fb3 Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 6 May 2020 11:06:27 +0200 Subject: [PATCH 13/26] Fixed #123 --- discussions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/discussions.py b/discussions.py index c09eeed..63cdc4e 100644 --- a/discussions.py +++ b/discussions.py @@ -174,7 +174,8 @@ class DiscussionsFromHellParser: elif item["type"] == "image": try: discussion_logger.debug(item["attrs"]["id"]) - self.markdown_text = "{old}{img_url}\n".format(old=self.markdown_text, img_url=self.post["_embedded"]["contentImages"][int(item["attrs"]["id"])]["url"]) + if item["attrs"]["id"] is not None: + self.markdown_text = "{old}{img_url}\n".format(old=self.markdown_text, img_url=self.post["_embedded"]["contentImages"][int(item["attrs"]["id"])]["url"]) except (IndexError, ValueError): discussion_logger.warning("Image {} not found.".format(item["attrs"]["id"])) discussion_logger.debug(self.markdown_text) From 8770fcea4709adcf53ebe0286aa37288728d659e Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 6 May 2020 11:13:51 +0200 Subject: [PATCH 14/26] Fixed #122 --- discussions.py | 3 ++- misc.py | 20 ++++++++++++++++++++ rcgcdw.py | 20 +------------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/discussions.py b/discussions.py index 63cdc4e..8d0d682 100644 --- a/discussions.py +++ b/discussions.py @@ -19,7 +19,7 @@ import logging, gettext, schedule, requests, json, datetime from collections import defaultdict from configloader import settings -from misc import datafile, send_to_discord, DiscordMessage, WIKI_SCRIPT_PATH, escape_formatting +from misc import datafile, send_to_discord, DiscordMessage, WIKI_SCRIPT_PATH, escape_formatting, messagequeue from session import session # Initialize translation @@ -104,6 +104,7 @@ def compact_formatter(post, post_type): def fetch_discussions(): + messagequeue.resend_msgs() request = safe_request(fetch_url) if request: try: diff --git a/misc.py b/misc.py index f250b02..48006a3 100644 --- a/misc.py +++ b/misc.py @@ -102,6 +102,26 @@ class MessageQueue: def cut_messages(self, item_num): self._queue = self._queue[item_num:] + def resend_msgs(self): + if self._queue: + misc_logger.info( + "{} messages waiting to be delivered to Discord due to Discord throwing errors/no connection to Discord servers.".format( + len(self._queue))) + for num, item in enumerate(self._queue): + misc_logger.debug( + "Trying to send a message to Discord from the queue with id of {} and content {}".format(str(num), + str(item))) + if send_to_discord_webhook(item) < 2: + misc_logger.debug("Sending message succeeded") + time.sleep(2.5) + else: + misc_logger.debug("Sending message failed") + break + else: + self.clear() + misc_logger.debug("Queue emptied, all messages delivered") + self.cut_messages(num) + misc_logger.debug(self._queue) messagequeue = MessageQueue() datafile = DataFile() diff --git a/rcgcdw.py b/rcgcdw.py index 29b7d09..af46b5a 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -1133,25 +1133,7 @@ class Recent_Changes_Class(object): self.ids.pop(0) def fetch(self, amount=settings["limit"]): - if messagequeue: - logger.info( - "{} messages waiting to be delivered to Discord due to Discord throwing errors/no connection to Discord servers.".format( - len(messagequeue))) - for num, item in enumerate(messagequeue): - logger.debug( - "Trying to send a message to Discord from the queue with id of {} and content {}".format(str(num), - str(item))) - if send_to_discord_webhook(item) < 2: - logger.debug("Sending message succeeded") - time.sleep(2.5) - else: - logger.debug("Sending message failed") - break - else: - messagequeue.clear() - logger.debug("Queue emptied, all messages delivered") - messagequeue.cut_messages(num) - logger.debug(messagequeue) + messagequeue.resend_msgs() last_check = self.fetch_changes(amount=amount) # If the request succeeds the last_check will be the last rcid from recentchanges query if last_check is not None: From b0698bdddeb4338340e104c822cc746cd24a14e4 Mon Sep 17 00:00:00 2001 From: Frisk Date: Sat, 9 May 2020 00:16:14 +0200 Subject: [PATCH 15/26] Fixed #120 --- misc.py | 16 +++++++++++++++- rcgcdw.py | 16 +++------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/misc.py b/misc.py index 48006a3..179b6f6 100644 --- a/misc.py +++ b/misc.py @@ -302,6 +302,14 @@ def create_article_path(article: str) -> str: return WIKI_ARTICLE_PATH.replace("$1", article) +def send_simple(msgtype, message, name, avatar): + discord_msg = DiscordMessage("compact", msgtype, content=message) + discord_msg.set_avatar(avatar) + discord_msg.set_name(name) + messagequeue.resend_msgs() + send_to_discord(discord_msg) + + def send_to_discord_webhook(data): header = settings["header"] header['Content-Type'] = 'application/json' @@ -387,4 +395,10 @@ class DiscordMessage(): def add_field(self, name, value, inline=False): if "fields" not in self.embed: self.embed["fields"] = [] - self.embed["fields"].append(dict(name=name, value=value, inline=inline)) \ No newline at end of file + self.embed["fields"].append(dict(name=name, value=value, inline=inline)) + + def set_avatar(self, url): + self.webhook_object["avatar_url"] = url + + def set_name(self, name): + self.webhook_object["username"] = name \ No newline at end of file diff --git a/rcgcdw.py b/rcgcdw.py index af46b5a..54f7c7b 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -30,7 +30,7 @@ from urllib.parse import quote_plus from configloader import settings from misc import link_formatter, ContentParser, safe_read, add_to_dict, datafile, \ WIKI_API_PATH, WIKI_SCRIPT_PATH, WIKI_JUST_DOMAIN, create_article_path, messagequeue, send_to_discord_webhook, \ - send_to_discord, DiscordMessage + send_to_discord, DiscordMessage, send_simple from session import session if settings["fandom_discussions"]["enabled"]: @@ -114,16 +114,6 @@ LinkParser = LinkParser() class MWError(Exception): pass - -def send(message, name, avatar): - dictionary_creator = {"content": message} - if name: - dictionary_creator["username"] = name - if avatar: - dictionary_creator["avatar_url"] = avatar - send_to_discord(dictionary_creator) - - def profile_field_name(name, embed): try: return profile_fields[name] @@ -1175,7 +1165,7 @@ class Recent_Changes_Class(object): self.streak += 1 if self.streak > 8: self.streak = -1 - send(_("Connection to {wiki} seems to be stable now.").format(wiki=settings["wikiname"]), + send_simple("down_detector", _("Connection to {wiki} seems to be stable now.").format(wiki=settings["wikiname"]), _("Connection status"), settings["avatars"]["connection_restored"]) # In the first for loop we analize the categorize events and figure if we will need more changes to fetch # in order to cover all of the edits @@ -1290,7 +1280,7 @@ class Recent_Changes_Class(object): else: if ( time.time() - self.last_downtime) > 1800 and self.check_connection(): # check if last downtime happened within 30 minutes, if yes, don't send a message - send(_("{wiki} seems to be down or unreachable.").format(wiki=settings["wikiname"]), + send_simple("down_detector", _("{wiki} seems to be down or unreachable.").format(wiki=settings["wikiname"]), _("Connection status"), settings["avatars"]["connection_failed"]) self.last_downtime = time.time() self.streak = 0 From 58da12ac9e2380d396a2253a67c8266e164a12ef Mon Sep 17 00:00:00 2001 From: Frisk Date: Fri, 22 May 2020 17:30:58 +0200 Subject: [PATCH 16/26] Fixed #116 --- discussions.py | 4 ++-- misc.py | 7 ++++--- rcgcdw.py | 17 +++++++---------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/discussions.py b/discussions.py index 8d0d682..acf84f4 100644 --- a/discussions.py +++ b/discussions.py @@ -44,7 +44,7 @@ fetch_url = "https://services.fandom.com/discussion/{wikiid}/posts?sortDirection def embed_formatter(post, post_type): """Embed formatter for Fandom discussions.""" - embed = DiscordMessage("embed", "discussion") + embed = DiscordMessage("embed", "discussion", settings["fandom_discussions"]["webhookURL"]) embed.set_author(post["createdBy"]["name"], "{wikiurl}f/u/{creatorId}".format( wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]), icon_url=post["createdBy"]["avatarUrl"]) if post_type == "TEXT": @@ -100,7 +100,7 @@ def compact_formatter(post, post_type): "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/{threadId}>) in {forumName}").format( author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["title"], threadId=post["threadId"], forumName=post["forumName"]) - send_to_discord(DiscordMessage("compact", "discussion", content=message)) + send_to_discord(DiscordMessage("compact", "discussion", settings["fandom_discussions"]["webhookURL"], content=message)) def fetch_discussions(): diff --git a/misc.py b/misc.py index 179b6f6..8667357 100644 --- a/misc.py +++ b/misc.py @@ -303,7 +303,7 @@ def create_article_path(article: str) -> str: def send_simple(msgtype, message, name, avatar): - discord_msg = DiscordMessage("compact", msgtype, content=message) + discord_msg = DiscordMessage("compact", msgtype, settings["webhookURL"], content=message) discord_msg.set_avatar(avatar) discord_msg.set_name(name) messagequeue.resend_msgs() @@ -314,7 +314,7 @@ def send_to_discord_webhook(data): header = settings["header"] header['Content-Type'] = 'application/json' try: - result = requests.post(settings["webhookURL"], data=repr(data), + result = requests.post(data.webhook_url, data=repr(data), headers=header, timeout=10) except requests.exceptions.Timeout: misc_logger.warning("Timeouted while sending data to the webhook.") @@ -342,8 +342,9 @@ def send_to_discord(data): class DiscordMessage(): """A class defining a typical Discord JSON representation of webhook payload.""" - def __init__(self, message_type: str, event_type: str, content=None): + def __init__(self, message_type: str, event_type: str, webhook_url: str, content=None): self.webhook_object = dict(allowed_mentions={"parse": []}, avatar_url=settings["avatars"].get(message_type, "")) + self.webhook_url = webhook_url if message_type == "embed": self.__setup_embed() diff --git a/rcgcdw.py b/rcgcdw.py index 54f7c7b..ba84852 100644 --- a/rcgcdw.py +++ b/rcgcdw.py @@ -426,11 +426,11 @@ def compact_formatter(action, change, parsed_comment, categories): else: logger.warning("No entry for {event} with params: {params}".format(event=action, params=change)) return - send_to_discord(DiscordMessage("compact", action, content=content)) + send_to_discord(DiscordMessage("compact", action, settings["webhookURL"], content=content)) def embed_formatter(action, change, parsed_comment, categories): - embed = DiscordMessage("embed", action) + embed = DiscordMessage("embed", action, settings["webhookURL"]) if parsed_comment is None: parsed_comment = _("No description provided") if action != "suppressed": @@ -983,15 +983,16 @@ def day_overview(): changed_bytes = 0 new_articles = 0 active_articles = [] + embed = DiscordMessage("embed", "daily_overview", settings["webhookURL"]) + embed["title"] = _("Daily overview") + embed["url"] = create_article_path("Special:Statistics") + embed.set_author(settings["wikiname"], create_article_path(""), + icon_url=settings["appearance"]["embed"]["daily_overview"]["icon"]) if not result[0]: if not settings["send_empty_overview"]: return # no changes in this day else: - embed = DiscordMessage("embed", "daily_overview") - embed["title"] = _("Daily overview") - embed["url"] = create_article_path("Special:Statistics") embed["description"] = _("No activity") - embed.set_author(settings["wikiname"], create_article_path(""), icon_url=settings["appearance"]["embed"]["daily_overview"]["icon"]) else: for item in result[0]: if "actionhidden" in item or "suppressed" in item or "userhidden" in item: @@ -1012,10 +1013,6 @@ def day_overview(): admin = admin + 1 if item["logtype"] in ["delete", "merge", "block", "protect", "import", "rights", "abusefilter", "interwiki", "managetags"] else admin overall = round(new_articles + edits * 0.1 + files * 0.3 + admin * 0.1 + math.fabs(changed_bytes * 0.001), 2) - embed = DiscordMessage("embed", "daily_overview") - embed["title"] = _("Daily overview") - embed["url"] = create_article_path("Special:Statistics") - embed.set_author(settings["wikiname"], create_article_path(""), icon_url=settings["appearance"]["embed"]["daily_overview"]["icon"]) if activity: active_users = [] for user, numberu in Counter(activity).most_common(3): # find most active users From 731d2d3f41908f240e31b630f01ffd839ff79940 Mon Sep 17 00:00:00 2001 From: Frisk Date: Fri, 19 Jun 2020 17:18:29 +0200 Subject: [PATCH 17/26] Added #118 --- discussions.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/discussions.py b/discussions.py index acf84f4..c5cc6d4 100644 --- a/discussions.py +++ b/discussions.py @@ -62,9 +62,9 @@ def embed_formatter(post, post_type): if post.get("jsonModel") is not None: npost = DiscussionsFromHellParser(post) embed["description"] = npost.parse() - if npost.image_only: - embed["image"]["url"] = embed["description"].strip() - embed["description"] = "" + if npost.image_last: + embed["image"]["url"] = npost.image_last + embed["description"] = embed["description"].replace(npost.image_last, "") else: # Fallback when model is not available embed["description"] = post.get("rawContent", "") elif post_type == "POLL": @@ -143,9 +143,9 @@ class DiscussionsFromHellParser: self.jsonModal = json.loads(post.get("jsonModel", "{}")) self.markdown_text = "" self.item_num = 1 - self.image_only = False + self.image_last = None - def parse(self): + def parse(self) -> str: """Main parsing logic""" self.parse_content(self.jsonModal["content"]) if len(self.markdown_text) > 2000: @@ -153,6 +153,7 @@ class DiscussionsFromHellParser: return self.markdown_text def parse_content(self, content, ctype=None): + self.image_last = None for item in content: if ctype == "bulletList": self.markdown_text += "\t• " @@ -177,6 +178,7 @@ class DiscussionsFromHellParser: discussion_logger.debug(item["attrs"]["id"]) if item["attrs"]["id"] is not None: self.markdown_text = "{old}{img_url}\n".format(old=self.markdown_text, img_url=self.post["_embedded"]["contentImages"][int(item["attrs"]["id"])]["url"]) + self.image_last = self.post["_embedded"]["contentImages"][int(item["attrs"]["id"])]["url"] except (IndexError, ValueError): discussion_logger.warning("Image {} not found.".format(item["attrs"]["id"])) discussion_logger.debug(self.markdown_text) From 4c6cfda9010c31239b77b0e26fb4ca4e376082d5 Mon Sep 17 00:00:00 2001 From: Frisk Date: Fri, 19 Jun 2020 21:55:21 +0200 Subject: [PATCH 18/26] Fixed #127 --- discussions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/discussions.py b/discussions.py index c5cc6d4..1e72648 100644 --- a/discussions.py +++ b/discussions.py @@ -165,7 +165,10 @@ class DiscussionsFromHellParser: prefix, suffix = self.convert_marks(item["marks"]) self.markdown_text = "{old}{pre}{text}{suf}".format(old=self.markdown_text, pre=prefix, text=escape_formatting(item["text"]), suf=suffix) else: - self.markdown_text += escape_formatting(item["text"]) + if ctype == "code_block": + self.markdown_text += item["text"] # ignore formatting on preformatted text which cannot have additional formatting anyways + else: + self.markdown_text += escape_formatting(item["text"]) elif item["type"] == "paragraph": if "content" in item: self.parse_content(item["content"], item["type"]) From 62fd4e0e33e2127a214035052b01dab09c11fc7f Mon Sep 17 00:00:00 2001 From: Frisk Date: Tue, 23 Jun 2020 15:02:38 +0200 Subject: [PATCH 19/26] Added support for wall discussion posts as per #126 --- discussions.pot | 32 ++- discussions.py | 44 +++- locale/en/LC_MESSAGES/discussions.mo | Bin 846 -> 1648 bytes locale/en/LC_MESSAGES/discussions.po | 79 +++++- locale/pl/LC_MESSAGES/discussions.mo | Bin 1517 -> 1863 bytes locale/pl/LC_MESSAGES/discussions.po | 37 ++- rcgcdw.pot | 368 +++++++++++++-------------- 7 files changed, 335 insertions(+), 225 deletions(-) diff --git a/discussions.pot b/discussions.pot index 45b2dc0..78b75f9 100644 --- a/discussions.pot +++ b/discussions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-26 22:05+0200\n" +"POT-Creation-Date: 2020-06-23 14:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,45 +17,59 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: discussions.py:53 +#: discussions.py:56 #, python-brace-format msgid "Replied to \"{title}\"" msgstr "" -#: discussions.py:58 +#: discussions.py:63 discussions.py:79 +msgid "unknown" +msgstr "" + +#: discussions.py:68 +#, python-brace-format +msgid "Replied to \"{title}\" on {user}'s Message Wall" +msgstr "" + +#: discussions.py:72 #, python-brace-format msgid "Created \"{title}\"" msgstr "" -#: discussions.py:70 +#: discussions.py:86 +#, python-brace-format +msgid "Created \"{title}\" on {user}'s Message Wall" +msgstr "" + +#: discussions.py:99 #, python-brace-format msgid "Created a poll titled \"{title}\"" msgstr "" -#: discussions.py:75 +#: discussions.py:104 msgid "Option {}" msgstr "" -#: discussions.py:76 +#: discussions.py:105 #, python-brace-format msgid "__[View image]({image_url})__" msgstr "" -#: discussions.py:89 +#: discussions.py:118 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " "in {forumName}" msgstr "" -#: discussions.py:92 +#: discussions.py:121 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" "{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}" msgstr "" -#: discussions.py:97 +#: discussions.py:126 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" diff --git a/discussions.py b/discussions.py index 1e72648..eb03eed 100644 --- a/discussions.py +++ b/discussions.py @@ -19,6 +19,7 @@ import logging, gettext, schedule, requests, json, datetime from collections import defaultdict from configloader import settings +from urllib.parse import quote_plus from misc import datafile, send_to_discord, DiscordMessage, WIKI_SCRIPT_PATH, escape_formatting, messagequeue from session import session @@ -47,17 +48,42 @@ def embed_formatter(post, post_type): embed = DiscordMessage("embed", "discussion", settings["fandom_discussions"]["webhookURL"]) embed.set_author(post["createdBy"]["name"], "{wikiurl}f/u/{creatorId}".format( wikiurl=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"]), icon_url=post["createdBy"]["avatarUrl"]) + discussion_post_type = post["_embedded"]["thread"][0].get("containerType", "FORUM") # Can be FORUM, ARTICLE_COMMENT or WALL on UCP if post_type == "TEXT": if post["isReply"]: - embed.event_type = "discussion/reply" - embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) - embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format( - wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], postId=post["id"]) + if discussion_post_type == "FORUM": + embed.event_type = "discussion/forum/reply" + embed["title"] = _("Replied to \"{title}\"").format(title=post["_embedded"]["thread"][0]["title"]) + embed["url"] = "{wikiurl}f/p/{threadId}/r/{postId}".format( + wikiurl=settings["fandom_discussions"]["wiki_url"], threadId=post["threadId"], postId=post["id"]) + elif discussion_post_type == "ARTICLE_COMMENT": + discussion_logger.warning("Article comments are not yet implemented. For reasons see https://gitlab.com/piotrex43/RcGcDw/-/issues/126#note_366480037") + return + elif discussion_post_type == "WALL": + user_wall = _("unknown") # Fail safe + embed.event_type = "discussion/wall/reply" + if post["forumName"].endswith(' Message Wall'): + user_wall = post["forumName"][:-13] + embed["url"] = "{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}#{replyId}".format(wikiurl=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(title=post["_embedded"]["thread"][0]["title"], user=user_wall) else: - embed.event_type = "discussion/post" - embed["title"] = _("Created \"{title}\"").format(title=post["title"]) - embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], - threadId=post["threadId"]) + if discussion_post_type == "FORUM": + embed.event_type = "discussion/forum/post" + embed["title"] = _("Created \"{title}\"").format(title=post["title"]) + embed["url"] = "{wikiurl}f/p/{threadId}".format(wikiurl=settings["fandom_discussions"]["wiki_url"], + threadId=post["threadId"]) + elif discussion_post_type == "ARTICLE_COMMENT": + discussion_logger.warning("Article comments are not yet implemented. For reasons see https://gitlab.com/piotrex43/RcGcDw/-/issues/126#note_366480037") + return + elif discussion_post_type == "WALL": + user_wall = _("unknown") # Fail safe + embed.event_type = "discussion/wall/post" + if post["forumName"].endswith(' Message Wall'): + user_wall = post["forumName"][:-13] + embed["url"] = "{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}".format( + wikiurl=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["_embedded"]["thread"][0]["title"], user=user_wall) if settings["fandom_discussions"]["appearance"]["embed"]["show_content"]: if post.get("jsonModel") is not None: npost = DiscussionsFromHellParser(post) @@ -68,7 +94,7 @@ def embed_formatter(post, post_type): else: # Fallback when model is not available embed["description"] = post.get("rawContent", "") elif post_type == "POLL": - embed.event_type = "discussion/poll" + embed.event_type = "discussion/forum/poll" poll = post["poll"] embed["title"] = _("Created a poll titled \"{title}\"").format(title=poll["question"]) image_type = False diff --git a/locale/en/LC_MESSAGES/discussions.mo b/locale/en/LC_MESSAGES/discussions.mo index 319abce320d31f296a889b31d0cedc869dca190a..25fa1aaa8fa7f888e781d8ba5df7c7e3bc7b4bbc 100644 GIT binary patch literal 1648 zcmeH`O>fgM7{>z}Z-EOFM-bi)(1N_a@lv&v17kx)E32k52Gv%X#%;q=JF*?d6v7!k z0NnTvoH%pm%nfnoWAJx^)=CVC9XP=wIlnyClmGv*9eGD zXeHeTwCbF+6E>C)D7tVxS&&4!#jVnMK9%19`KfTRl3 zQfr~{?Z=6;&cncmjgeDM2TlIotQ)h)jHF7oa<}401<9Zg72>|_U#g~;+|H9UflK%2 zVkVVgAvPnFdRd{5rUp_);|FZa6Xy`pjC2*&vUjj_K^5XqYLmHOv46Fbbkh&((Cc+K ze7;NkF^+L77pLsm{ml1zP9%1O+!an+$!EN8Xw#z`TxpzQjkq{3sSIuDq3_W<(NNQl z#B_U&uJh-r zHlE6BgbTOTY%NdBON&K!NeaUSH1 z0hdo=UV3R_da7) created [{title}](<{url}f/p/{threadId}>) " -"in ${forumName}" -msgstr "" -"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " -"in ${forumName}" #: discussions.py:56 #, python-brace-format +msgid "Replied to \"{title}\"" +msgstr "Replied to \"{title}\"" + +#: discussions.py:63 discussions.py:79 +msgid "unknown" +msgstr "unknown" + +#: discussions.py:68 +#, python-brace-format +msgid "Replied to \"{title}\" on {user}'s Message Wall" +msgstr "Replied to \"{title}\" on {user}'s Message Wall" + +#: discussions.py:72 +#, python-brace-format +msgid "Created \"{title}\"" +msgstr "Created \"{title}\"" + +#: discussions.py:86 +#, python-brace-format +msgid "Created \"{title}\" on {user}'s Message Wall" +msgstr "Created \"{title}\" on {user}'s Message Wall" + +#: discussions.py:99 +#, python-brace-format +msgid "Created a poll titled \"{title}\"" +msgstr "Created a poll titled \"{title}\"" + +#: discussions.py:104 +msgid "Option {}" +msgstr "Option {}" + +#: discussions.py:105 +#, python-brace-format +msgid "__[View image]({image_url})__" +msgstr "__[View image]({image_url})__" + +#: discussions.py:118 +#, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in ${forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " +"in {forumName}" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " +"in {forumName}" + +#: discussions.py:121 +#, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" "{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}" msgstr "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" "{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}" + +#: discussions.py:126 +#, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in ${forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" diff --git a/locale/pl/LC_MESSAGES/discussions.mo b/locale/pl/LC_MESSAGES/discussions.mo index b2f227b88f61ece217018d04692203676e618dfd..88a1676b25a1f05078934a575e35b23d293ca1a2 100644 GIT binary patch delta 588 zcmbWzOG^S#6bJA-qh@LaNt@m`7rj8rC*eZcw2UBxu!VKgNiH+ZNHZd8rnIW1Nr8lY zgCLk)w3QZpg=!(RY|{sb{xbm%oMh$kL@NAiuILm2ATK6W) zX|elQHe^(CnXUXTvK5*4=WF?#neY8TKQl5*1juj Qww)=#qjIUDGPO*;0Rkn5IRF3v delta 277 zcmX|*y=nqM6h`m3jv9Z_2m#T!Xekyh8x7moSXkO>v9KbFk6>jNNReugkaw^U_8|=2 && n%10<=4 && (n%100<12 " "|| n%100>14) ? 1 : 2);\n" -#: discussions.py:53 +#: discussions.py:56 #, python-brace-format msgid "Replied to \"{title}\"" msgstr "Odpowiedział(a) w „{title}”" -#: discussions.py:58 +#: discussions.py:63 discussions.py:79 +msgid "unknown" +msgstr "nieznany" + +#: discussions.py:68 +#, python-brace-format +msgid "Replied to \"{title}\" on {user}'s Message Wall" +msgstr "" +"Odpowiedział(a) na „{title}” z tablicy wiadomości użytkownika/użytkowniczki " +"{user}" + +#: discussions.py:72 #, python-brace-format msgid "Created \"{title}\"" msgstr "Utworzył(a) „{title}”" -#: discussions.py:70 +#: discussions.py:86 +#, python-brace-format +msgid "Created \"{title}\" on {user}'s Message Wall" +msgstr "" +"Utworzył(a) „{title}” na tablicy wiadomości użytkownika/użytkowniczki {user}" + +#: discussions.py:99 #, python-brace-format msgid "Created a poll titled \"{title}\"" msgstr "Utworzył(a) ankietę zatytułowaną „{title}”" -#: discussions.py:75 +#: discussions.py:104 msgid "Option {}" msgstr "Opcja {}" -#: discussions.py:76 +#: discussions.py:105 #, python-brace-format msgid "__[View image]({image_url})__" msgstr "__[Zobacz zdjęcie]({image_url})__" -#: discussions.py:89 +#: discussions.py:118 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " @@ -52,7 +69,7 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) utworzył(a) [{title}](<{url}f/p/{threadId}" ">) w {forumName}" -#: discussions.py:92 +#: discussions.py:121 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -62,7 +79,7 @@ msgstr "" "{threadId}/r/{postId}>) pod tematem [{title}](<{url}f/p/{threadId}>) w " "{forumName}" -#: discussions.py:97 +#: discussions.py:126 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" diff --git a/rcgcdw.pot b/rcgcdw.pot index eabec84..c40cdb6 100644 --- a/rcgcdw.pot +++ b/rcgcdw.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-26 21:54+0200\n" +"POT-Creation-Date: 2020-06-23 14:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,210 +70,210 @@ msgstr "" msgid "Battle.net handle" msgstr "" -#: rcgcdw.py:132 rcgcdw.py:848 +#: rcgcdw.py:122 rcgcdw.py:838 msgid "Unknown" msgstr "" -#: rcgcdw.py:134 +#: rcgcdw.py:124 msgid "unknown" msgstr "" -#: rcgcdw.py:172 +#: rcgcdw.py:162 #, python-brace-format msgid "" "[{author}]({author_url}) edited [{article}]({edit_link}){comment} ({sign}" "{edit_size})" msgstr "" -#: rcgcdw.py:174 +#: rcgcdw.py:164 #, python-brace-format msgid "" "[{author}]({author_url}) created [{article}]({edit_link}){comment} ({sign}" "{edit_size})" msgstr "" -#: rcgcdw.py:177 +#: rcgcdw.py:167 #, python-brace-format msgid "[{author}]({author_url}) uploaded [{file}]({file_link}){comment}" msgstr "" -#: rcgcdw.py:184 +#: rcgcdw.py:174 #, python-brace-format msgid "" "[{author}]({author_url}) reverted a version of [{file}]({file_link}){comment}" msgstr "" -#: rcgcdw.py:188 +#: rcgcdw.py:178 #, python-brace-format msgid "" "[{author}]({author_url}) uploaded a new version of [{file}]({file_link})" "{comment}" msgstr "" -#: rcgcdw.py:191 +#: rcgcdw.py:181 #, python-brace-format msgid "[{author}]({author_url}) deleted [{page}]({page_link}){comment}" msgstr "" -#: rcgcdw.py:195 +#: rcgcdw.py:185 #, python-brace-format msgid "" "[{author}]({author_url}) deleted redirect by overwriting [{page}]" "({page_link}){comment}" msgstr "" -#: rcgcdw.py:199 rcgcdw.py:204 +#: rcgcdw.py:189 rcgcdw.py:194 msgid "without making a redirect" msgstr "" -#: rcgcdw.py:199 rcgcdw.py:205 +#: rcgcdw.py:189 rcgcdw.py:195 msgid "with a redirect" msgstr "" -#: rcgcdw.py:200 +#: rcgcdw.py:190 #, python-brace-format msgid "" "[{author}]({author_url}) moved {redirect}*{article}* to [{target}]" "({target_url}) {made_a_redirect}{comment}" msgstr "" -#: rcgcdw.py:206 +#: rcgcdw.py:196 #, python-brace-format msgid "" "[{author}]({author_url}) moved {redirect}*{article}* over redirect to " "[{target}]({target_url}) {made_a_redirect}{comment}" msgstr "" -#: rcgcdw.py:211 +#: rcgcdw.py:201 #, python-brace-format msgid "" "[{author}]({author_url}) moved protection settings from {redirect}*{article}" "* to [{target}]({target_url}){comment}" msgstr "" -#: rcgcdw.py:222 rcgcdw.py:626 +#: rcgcdw.py:212 rcgcdw.py:616 msgid "infinity and beyond" msgstr "" -#: rcgcdw.py:239 +#: rcgcdw.py:229 msgid " on pages: " msgstr "" -#: rcgcdw.py:246 rcgcdw.py:646 +#: rcgcdw.py:236 rcgcdw.py:636 msgid " and namespaces: " msgstr "" -#: rcgcdw.py:248 +#: rcgcdw.py:238 msgid " on namespaces: " msgstr "" -#: rcgcdw.py:260 +#: rcgcdw.py:250 #, python-brace-format msgid "" "[{author}]({author_url}) blocked [{user}]({user_url}) for {time}" "{restriction_desc}{comment}" msgstr "" -#: rcgcdw.py:264 +#: rcgcdw.py:254 #, python-brace-format msgid "" "[{author}]({author_url}) changed block settings for [{blocked_user}]" "({user_url}){comment}" msgstr "" -#: rcgcdw.py:268 +#: rcgcdw.py:258 #, python-brace-format msgid "" "[{author}]({author_url}) unblocked [{blocked_user}]({user_url}){comment}" msgstr "" -#: rcgcdw.py:271 +#: rcgcdw.py:261 #, python-brace-format msgid "" "[{author}]({author_url}) left a [comment]({comment}) on {target} profile" msgstr "" -#: rcgcdw.py:271 +#: rcgcdw.py:261 msgid "their own profile" msgstr "" -#: rcgcdw.py:274 +#: rcgcdw.py:264 #, python-brace-format msgid "" "[{author}]({author_url}) replied to a [comment]({comment}) on {target} " "profile" msgstr "" -#: rcgcdw.py:277 rcgcdw.py:283 rcgcdw.py:294 rcgcdw.py:298 +#: rcgcdw.py:267 rcgcdw.py:273 rcgcdw.py:284 rcgcdw.py:288 msgid "their own" msgstr "" -#: rcgcdw.py:280 +#: rcgcdw.py:270 #, python-brace-format msgid "" "[{author}]({author_url}) edited a [comment]({comment}) on {target} profile" msgstr "" -#: rcgcdw.py:286 +#: rcgcdw.py:276 #, python-brace-format msgid "[{author}]({author_url}) purged a comment on {target} profile" msgstr "" -#: rcgcdw.py:296 +#: rcgcdw.py:286 #, python-brace-format msgid "[{author}]({author_url}) deleted a comment on {target} profile" msgstr "" -#: rcgcdw.py:302 +#: rcgcdw.py:292 #, python-brace-format msgid "[{target}]({target_url})'s" msgstr "" -#: rcgcdw.py:302 +#: rcgcdw.py:292 #, python-brace-format msgid "[their own]({target_url})" msgstr "" -#: rcgcdw.py:303 +#: rcgcdw.py:293 #, python-brace-format msgid "" "[{author}]({author_url}) edited the {field} on {target} profile. *({desc})*" msgstr "" -#: rcgcdw.py:317 rcgcdw.py:319 rcgcdw.py:724 rcgcdw.py:726 +#: rcgcdw.py:307 rcgcdw.py:309 rcgcdw.py:714 rcgcdw.py:716 msgid "none" msgstr "" -#: rcgcdw.py:325 rcgcdw.py:711 +#: rcgcdw.py:315 rcgcdw.py:701 msgid "System" msgstr "" -#: rcgcdw.py:330 +#: rcgcdw.py:320 #, python-brace-format msgid "" "[{author}]({author_url}) protected [{article}]({article_url}) with the " "following settings: {settings}{comment}" msgstr "" -#: rcgcdw.py:332 rcgcdw.py:340 rcgcdw.py:734 rcgcdw.py:740 +#: rcgcdw.py:322 rcgcdw.py:330 rcgcdw.py:724 rcgcdw.py:730 msgid " [cascading]" msgstr "" -#: rcgcdw.py:337 +#: rcgcdw.py:327 #, python-brace-format msgid "" "[{author}]({author_url}) modified protection settings of [{article}]" "({article_url}) to: {settings}{comment}" msgstr "" -#: rcgcdw.py:344 +#: rcgcdw.py:334 #, python-brace-format msgid "" "[{author}]({author_url}) removed protection from [{article}]({article_url})" "{comment}" msgstr "" -#: rcgcdw.py:348 +#: rcgcdw.py:338 #, python-brace-format msgid "" "[{author}]({author_url}) changed visibility of revision on page [{article}]" @@ -284,7 +284,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:353 +#: rcgcdw.py:343 #, python-brace-format msgid "" "[{author}]({author_url}) imported [{article}]({article_url}) with {count} " @@ -295,699 +295,699 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:358 +#: rcgcdw.py:348 #, python-brace-format msgid "[{author}]({author_url}) restored [{article}]({article_url}){comment}" msgstr "" -#: rcgcdw.py:360 +#: rcgcdw.py:350 #, python-brace-format msgid "[{author}]({author_url}) changed visibility of log events{comment}" msgstr "" -#: rcgcdw.py:362 +#: rcgcdw.py:352 #, python-brace-format msgid "[{author}]({author_url}) imported interwiki{comment}" msgstr "" -#: rcgcdw.py:365 +#: rcgcdw.py:355 #, python-brace-format msgid "" "[{author}]({author_url}) edited abuse filter [number {number}]({filter_url})" msgstr "" -#: rcgcdw.py:369 +#: rcgcdw.py:359 #, python-brace-format msgid "" "[{author}]({author_url}) created abuse filter [number {number}]({filter_url})" msgstr "" -#: rcgcdw.py:373 +#: rcgcdw.py:363 #, python-brace-format msgid "" "[{author}]({author_url}) merged revision histories of [{article}]" "({article_url}) into [{dest}]({dest_url}){comment}" msgstr "" -#: rcgcdw.py:377 +#: rcgcdw.py:367 #, python-brace-format msgid "" "[{author}]({author_url}) added an entry to the [interwiki table]" "({table_url}) pointing to {website} with {prefix} prefix" msgstr "" -#: rcgcdw.py:383 +#: rcgcdw.py:373 #, python-brace-format msgid "" "[{author}]({author_url}) edited an entry in [interwiki table]({table_url}) " "pointing to {website} with {prefix} prefix" msgstr "" -#: rcgcdw.py:389 +#: rcgcdw.py:379 #, python-brace-format msgid "" "[{author}]({author_url}) deleted an entry in [interwiki table]({table_url})" msgstr "" -#: rcgcdw.py:392 +#: rcgcdw.py:382 #, python-brace-format msgid "" "[{author}]({author_url}) changed the content model of the page [{article}]" "({article_url}) from {old} to {new}{comment}" msgstr "" -#: rcgcdw.py:396 +#: rcgcdw.py:386 #, python-brace-format msgid "" "[{author}]({author_url}) edited the sprite for [{article}]({article_url})" msgstr "" -#: rcgcdw.py:399 +#: rcgcdw.py:389 #, python-brace-format msgid "" "[{author}]({author_url}) created the sprite sheet for [{article}]" "({article_url})" msgstr "" -#: rcgcdw.py:402 +#: rcgcdw.py:392 #, python-brace-format msgid "" "[{author}]({author_url}) edited the slice for [{article}]({article_url})" msgstr "" -#: rcgcdw.py:407 +#: rcgcdw.py:397 #, python-brace-format msgid "[{author}]({author_url}) created the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:409 +#: rcgcdw.py:399 #, python-brace-format msgid "[{author}]({author_url}) deleted the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:414 +#: rcgcdw.py:404 #, python-brace-format msgid "[{author}]({author_url}) recreated the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:419 +#: rcgcdw.py:409 #, python-brace-format msgid "[{author}]({author_url}) replaced the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:422 +#: rcgcdw.py:412 #, python-brace-format msgid "[{author}]({author_url}) created a [tag]({tag_url}) \"{tag}\"" msgstr "" -#: rcgcdw.py:426 +#: rcgcdw.py:416 #, python-brace-format msgid "[{author}]({author_url}) deleted a [tag]({tag_url}) \"{tag}\"" msgstr "" -#: rcgcdw.py:430 +#: rcgcdw.py:420 #, python-brace-format msgid "[{author}]({author_url}) activated a [tag]({tag_url}) \"{tag}\"" msgstr "" -#: rcgcdw.py:433 +#: rcgcdw.py:423 #, python-brace-format msgid "[{author}]({author_url}) deactivated a [tag]({tag_url}) \"{tag}\"" msgstr "" -#: rcgcdw.py:435 +#: rcgcdw.py:425 msgid "An action has been hidden by administration." msgstr "" -#: rcgcdw.py:445 rcgcdw.py:727 +#: rcgcdw.py:435 rcgcdw.py:717 msgid "No description provided" msgstr "" -#: rcgcdw.py:492 +#: rcgcdw.py:482 msgid "(N!) " msgstr "" -#: rcgcdw.py:493 +#: rcgcdw.py:483 msgid "m" msgstr "" -#: rcgcdw.py:493 +#: rcgcdw.py:483 msgid "b" msgstr "" -#: rcgcdw.py:510 rcgcdw.py:515 +#: rcgcdw.py:500 rcgcdw.py:505 msgid "__Only whitespace__" msgstr "" -#: rcgcdw.py:520 +#: rcgcdw.py:510 msgid "Removed" msgstr "" -#: rcgcdw.py:522 +#: rcgcdw.py:512 msgid "Added" msgstr "" -#: rcgcdw.py:556 rcgcdw.py:595 +#: rcgcdw.py:546 rcgcdw.py:585 msgid "Options" msgstr "" -#: rcgcdw.py:556 +#: rcgcdw.py:546 #, python-brace-format msgid "([preview]({link}) | [undo]({undolink}))" msgstr "" -#: rcgcdw.py:561 +#: rcgcdw.py:551 #, python-brace-format msgid "Uploaded a new version of {name}" msgstr "" -#: rcgcdw.py:563 +#: rcgcdw.py:553 #, python-brace-format msgid "Reverted a version of {name}" msgstr "" -#: rcgcdw.py:565 +#: rcgcdw.py:555 #, python-brace-format msgid "Uploaded {name}" msgstr "" -#: rcgcdw.py:581 +#: rcgcdw.py:571 msgid "**No license!**" msgstr "" -#: rcgcdw.py:593 +#: rcgcdw.py:583 msgid "" "\n" "License: {}" msgstr "" -#: rcgcdw.py:595 +#: rcgcdw.py:585 #, python-brace-format msgid "([preview]({link}))" msgstr "" -#: rcgcdw.py:600 +#: rcgcdw.py:590 #, python-brace-format msgid "Deleted page {article}" msgstr "" -#: rcgcdw.py:603 +#: rcgcdw.py:593 #, python-brace-format msgid "Deleted redirect {article} by overwriting" msgstr "" -#: rcgcdw.py:607 +#: rcgcdw.py:597 msgid "No redirect has been made" msgstr "" -#: rcgcdw.py:608 +#: rcgcdw.py:598 msgid "A redirect has been made" msgstr "" -#: rcgcdw.py:609 +#: rcgcdw.py:599 #, python-brace-format msgid "Moved {redirect}{article} to {target}" msgstr "" -#: rcgcdw.py:612 +#: rcgcdw.py:602 #, python-brace-format msgid "Moved {redirect}{article} to {title} over redirect" msgstr "" -#: rcgcdw.py:616 +#: rcgcdw.py:606 #, python-brace-format msgid "Moved protection settings from {redirect}{article} to {title}" msgstr "" -#: rcgcdw.py:639 +#: rcgcdw.py:629 msgid "Blocked from editing the following pages: " msgstr "" -#: rcgcdw.py:648 +#: rcgcdw.py:638 msgid "Blocked from editing pages on following namespaces: " msgstr "" -#: rcgcdw.py:659 +#: rcgcdw.py:649 msgid "Partial block details" msgstr "" -#: rcgcdw.py:660 +#: rcgcdw.py:650 #, python-brace-format msgid "Blocked {blocked_user} for {time}" msgstr "" -#: rcgcdw.py:664 +#: rcgcdw.py:654 #, python-brace-format msgid "Changed block settings for {blocked_user}" msgstr "" -#: rcgcdw.py:668 +#: rcgcdw.py:658 #, python-brace-format msgid "Unblocked {blocked_user}" msgstr "" -#: rcgcdw.py:673 +#: rcgcdw.py:663 #, python-brace-format msgid "Left a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:675 +#: rcgcdw.py:665 msgid "Left a comment on their own profile" msgstr "" -#: rcgcdw.py:680 +#: rcgcdw.py:670 #, python-brace-format msgid "Replied to a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:682 +#: rcgcdw.py:672 msgid "Replied to a comment on their own profile" msgstr "" -#: rcgcdw.py:687 +#: rcgcdw.py:677 #, python-brace-format msgid "Edited a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:689 +#: rcgcdw.py:679 msgid "Edited a comment on their own profile" msgstr "" -#: rcgcdw.py:692 +#: rcgcdw.py:682 #, python-brace-format msgid "Edited {target}'s profile" msgstr "" -#: rcgcdw.py:692 +#: rcgcdw.py:682 msgid "Edited their own profile" msgstr "" -#: rcgcdw.py:694 +#: rcgcdw.py:684 #, python-brace-format msgid "Cleared the {field} field" msgstr "" -#: rcgcdw.py:696 +#: rcgcdw.py:686 #, python-brace-format msgid "{field} field changed to: {desc}" msgstr "" -#: rcgcdw.py:699 +#: rcgcdw.py:689 #, python-brace-format msgid "Purged a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:705 +#: rcgcdw.py:695 #, python-brace-format msgid "Deleted a comment on {target}'s profile" msgstr "" -#: rcgcdw.py:709 +#: rcgcdw.py:699 #, python-brace-format msgid "Changed group membership for {target}" msgstr "" -#: rcgcdw.py:713 +#: rcgcdw.py:703 #, python-brace-format msgid "{target} got autopromoted to a new usergroup" msgstr "" -#: rcgcdw.py:728 +#: rcgcdw.py:718 #, python-brace-format msgid "Groups changed from {old_groups} to {new_groups}{reason}" msgstr "" -#: rcgcdw.py:732 +#: rcgcdw.py:722 #, python-brace-format msgid "Protected {target}" msgstr "" -#: rcgcdw.py:738 +#: rcgcdw.py:728 #, python-brace-format msgid "Changed protection level for {article}" msgstr "" -#: rcgcdw.py:744 +#: rcgcdw.py:734 #, python-brace-format msgid "Removed protection from {article}" msgstr "" -#: rcgcdw.py:748 +#: rcgcdw.py:738 #, python-brace-format msgid "Changed visibility of revision on page {article} " msgid_plural "Changed visibility of {amount} revisions on page {article} " msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:753 +#: rcgcdw.py:743 #, python-brace-format msgid "Imported {article} with {count} revision" msgid_plural "Imported {article} with {count} revisions" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:758 +#: rcgcdw.py:748 #, python-brace-format msgid "Restored {article}" msgstr "" -#: rcgcdw.py:761 +#: rcgcdw.py:751 msgid "Changed visibility of log events" msgstr "" -#: rcgcdw.py:764 +#: rcgcdw.py:754 msgid "Imported interwiki" msgstr "" -#: rcgcdw.py:767 +#: rcgcdw.py:757 #, python-brace-format msgid "Edited abuse filter number {number}" msgstr "" -#: rcgcdw.py:770 +#: rcgcdw.py:760 #, python-brace-format msgid "Created abuse filter number {number}" msgstr "" -#: rcgcdw.py:773 +#: rcgcdw.py:763 #, python-brace-format msgid "Merged revision histories of {article} into {dest}" msgstr "" -#: rcgcdw.py:777 +#: rcgcdw.py:767 msgid "Added an entry to the interwiki table" msgstr "" -#: rcgcdw.py:778 rcgcdw.py:784 +#: rcgcdw.py:768 rcgcdw.py:774 #, python-brace-format msgid "Prefix: {prefix}, website: {website} | {desc}" msgstr "" -#: rcgcdw.py:783 +#: rcgcdw.py:773 msgid "Edited an entry in interwiki table" msgstr "" -#: rcgcdw.py:789 +#: rcgcdw.py:779 msgid "Deleted an entry in interwiki table" msgstr "" -#: rcgcdw.py:790 +#: rcgcdw.py:780 #, python-brace-format msgid "Prefix: {prefix} | {desc}" msgstr "" -#: rcgcdw.py:793 +#: rcgcdw.py:783 #, python-brace-format msgid "Changed the content model of the page {article}" msgstr "" -#: rcgcdw.py:794 +#: rcgcdw.py:784 #, python-brace-format msgid "Model changed from {old} to {new}: {reason}" msgstr "" -#: rcgcdw.py:799 +#: rcgcdw.py:789 #, python-brace-format msgid "Edited the sprite for {article}" msgstr "" -#: rcgcdw.py:802 +#: rcgcdw.py:792 #, python-brace-format msgid "Created the sprite sheet for {article}" msgstr "" -#: rcgcdw.py:805 +#: rcgcdw.py:795 #, python-brace-format msgid "Edited the slice for {article}" msgstr "" -#: rcgcdw.py:811 +#: rcgcdw.py:801 #, python-brace-format msgid "Created the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:815 +#: rcgcdw.py:805 #, python-brace-format msgid "Deleted the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:822 +#: rcgcdw.py:812 #, python-brace-format msgid "Recreated the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:829 +#: rcgcdw.py:819 #, python-brace-format msgid "Replaced the Cargo table \"{table}\"" msgstr "" -#: rcgcdw.py:833 +#: rcgcdw.py:823 #, python-brace-format msgid "Created a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:837 +#: rcgcdw.py:827 #, python-brace-format msgid "Deleted a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:841 +#: rcgcdw.py:831 #, python-brace-format msgid "Activated a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:844 +#: rcgcdw.py:834 #, python-brace-format msgid "Deactivated a tag \"{tag}\"" msgstr "" -#: rcgcdw.py:847 +#: rcgcdw.py:837 msgid "Action has been hidden by administration." msgstr "" -#: rcgcdw.py:867 +#: rcgcdw.py:857 msgid "Tags" msgstr "" -#: rcgcdw.py:870 +#: rcgcdw.py:860 msgid "**Added**: " msgstr "" -#: rcgcdw.py:870 +#: rcgcdw.py:860 msgid " and {} more\n" msgstr "" -#: rcgcdw.py:871 +#: rcgcdw.py:861 msgid "**Removed**: " msgstr "" -#: rcgcdw.py:871 +#: rcgcdw.py:861 msgid " and {} more" msgstr "" -#: rcgcdw.py:872 +#: rcgcdw.py:862 msgid "Changed categories" msgstr "" -#: rcgcdw.py:889 +#: rcgcdw.py:879 msgid "~~hidden~~" msgstr "" -#: rcgcdw.py:895 +#: rcgcdw.py:885 msgid "hidden" msgstr "" -#: rcgcdw.py:965 rcgcdw.py:967 rcgcdw.py:969 rcgcdw.py:971 rcgcdw.py:973 -#: rcgcdw.py:975 rcgcdw.py:977 +#: rcgcdw.py:955 rcgcdw.py:957 rcgcdw.py:959 rcgcdw.py:961 rcgcdw.py:963 +#: rcgcdw.py:965 rcgcdw.py:967 #, python-brace-format msgid "{value} (avg. {avg})" msgstr "" -#: rcgcdw.py:1001 rcgcdw.py:1026 +#: rcgcdw.py:987 msgid "Daily overview" msgstr "" -#: rcgcdw.py:1003 +#: rcgcdw.py:995 msgid "No activity" msgstr "" -#: rcgcdw.py:1032 +#: rcgcdw.py:1019 msgid " ({} action)" msgid_plural " ({} actions)" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1034 +#: rcgcdw.py:1021 msgid " ({} edit)" msgid_plural " ({} edits)" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1039 +#: rcgcdw.py:1026 msgid " UTC ({} action)" msgid_plural " UTC ({} actions)" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1041 rcgcdw.py:1042 rcgcdw.py:1046 +#: rcgcdw.py:1028 rcgcdw.py:1029 rcgcdw.py:1033 msgid "But nobody came" msgstr "" -#: rcgcdw.py:1049 +#: rcgcdw.py:1036 msgid "Most active user" msgid_plural "Most active users" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1050 +#: rcgcdw.py:1037 msgid "Most edited article" msgid_plural "Most edited articles" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1051 +#: rcgcdw.py:1038 msgid "Edits made" msgstr "" -#: rcgcdw.py:1051 +#: rcgcdw.py:1038 msgid "New files" msgstr "" -#: rcgcdw.py:1051 +#: rcgcdw.py:1038 msgid "Admin actions" msgstr "" -#: rcgcdw.py:1052 +#: rcgcdw.py:1039 msgid "Bytes changed" msgstr "" -#: rcgcdw.py:1052 +#: rcgcdw.py:1039 msgid "New articles" msgstr "" -#: rcgcdw.py:1053 +#: rcgcdw.py:1040 msgid "Unique contributors" msgstr "" -#: rcgcdw.py:1054 +#: rcgcdw.py:1041 msgid "Most active hour" msgid_plural "Most active hours" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1055 +#: rcgcdw.py:1042 msgid "Day score" msgstr "" -#: rcgcdw.py:1196 +#: rcgcdw.py:1165 #, python-brace-format msgid "Connection to {wiki} seems to be stable now." msgstr "" -#: rcgcdw.py:1197 rcgcdw.py:1312 +#: rcgcdw.py:1166 rcgcdw.py:1281 msgid "Connection status" msgstr "" -#: rcgcdw.py:1311 +#: rcgcdw.py:1280 #, python-brace-format msgid "{wiki} seems to be down or unreachable." msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "director" msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "bot" msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "editor" msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "directors" msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "sysop" msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "bureaucrat" msgstr "" -#: rcgcdw.py:1386 +#: rcgcdw.py:1355 msgid "reviewer" msgstr "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "autoreview" msgstr "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "autopatrol" msgstr "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "wiki_guardian" msgstr "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "week" msgid_plural "weeks" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "month" msgid_plural "months" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "year" msgid_plural "years" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "millennium" msgid_plural "millennia" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "decade" msgid_plural "decades" msgstr[0] "" msgstr[1] "" -#: rcgcdw.py:1387 +#: rcgcdw.py:1356 msgid "century" msgid_plural "centuries" msgstr[0] "" From 28dc2eb1e5ee663527b6fbc7dc99f9a772393be4 Mon Sep 17 00:00:00 2001 From: Frisk Date: Fri, 26 Jun 2020 02:18:55 +0200 Subject: [PATCH 20/26] Updated settings example with new names for the discussions --- settings.json.example | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/settings.json.example b/settings.json.example index cf1025b..b8bb995 100644 --- a/settings.json.example +++ b/settings.json.example @@ -265,17 +265,25 @@ "icon": "https://i.imgur.com/1gps6EZ.png", "color": 8092539 }, - "discussion/post": { + "discussion/forum/post": { "icon": "", "color":null }, - "discussion/reply": { - "icon": "", - "color":null + "discussion/forum/reply": { + "icon": "", + "color":null + }, + "discussion/forum/poll": { + "icon": "", + "color":null }, - "discussion/poll": { - "icon": "", - "color": null + "discussion/wall/post": { + "icon": "", + "color":null + }, + "discussion/wall/reply": { + "icon": "", + "color":null } } }, From 5679b9f7687c2e3e395bf9d2283315fd3ecd85de Mon Sep 17 00:00:00 2001 From: Frisk Date: Sun, 28 Jun 2020 16:38:13 +0200 Subject: [PATCH 21/26] Added compact streams for message walls threads --- discussions.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/discussions.py b/discussions.py index eb03eed..918a552 100644 --- a/discussions.py +++ b/discussions.py @@ -113,14 +113,41 @@ def embed_formatter(post, post_type): def compact_formatter(post, post_type): """Compact formatter for Fandom discussions.""" message = None + discussion_post_type = post["_embedded"]["thread"][0].get("containerType", + "FORUM") # Can be FORUM, ARTICLE_COMMENT or WALL on UCP if post_type == "TEXT": if not post["isReply"]: - message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) in {forumName}").format( + if discussion_post_type == "FORUM": + message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) in {forumName}").format( author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["title"], threadId=post["threadId"], forumName=post["forumName"]) + elif discussion_post_type == "ARTICLE_COMMENT": + discussion_logger.warning("Article comments are not yet implemented. For reasons see https://gitlab.com/piotrex43/RcGcDw/-/issues/126#note_366480037") + return + elif discussion_post_type == "WALL": + user_wall = _("unknown") # Fail safe + if post["forumName"].endswith(' Message Wall'): + user_wall = post["forumName"][:-13] + message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall".format( + author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["_embedded"]["thread"][0]["title"], user=user_wall, + wikiurl=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), threadid=post["threadId"] + )) else: - message = _("[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( + if discussion_post_type == "FORUM": + message = _("[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], threadId=post["threadId"], postId=post["id"], title=post["_embedded"]["thread"][0]["title"], forumName=post["forumName"] - ) + ) + elif discussion_post_type == "ARTICLE_COMMENT": + discussion_logger.warning("Article comments are not yet implemented. For reasons see https://gitlab.com/piotrex43/RcGcDw/-/issues/126#note_366480037") + return + elif discussion_post_type == "WALL": + user_wall = _("unknown") # Fail safe + if post["forumName"].endswith(' Message Wall'): + user_wall = post["forumName"][:-13] + message = _( + "[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message Wall".format( + author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["_embedded"]["thread"][0]["title"], user=user_wall, + wikiurl=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), threadid=post["threadId"], replyId=post["id"])) + elif post_type == "POLL": message = _( "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/{threadId}>) in {forumName}").format( From ec980ebd0476b0ca761d4b3ad797cf355581cc39 Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 1 Jul 2020 16:34:46 +0200 Subject: [PATCH 22/26] Added #93 --- misc.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/misc.py b/misc.py index 8667357..07b39a6 100644 --- a/misc.py +++ b/misc.py @@ -327,6 +327,17 @@ def send_to_discord_webhook(data): def send_to_discord(data): + for regex in settings["disallow_regexes"]: + if data.webhook_object.get("content", None): + if re.search(re.compile(regex), data.webhook_object["content"]): + misc_logger.info("Message {} has been rejected due to matching filter ({}).".format(data.webhook_object["content"], regex)) + return # discard the message without anything + else: + for to_check in [data.webhook_object.get("description", ""), data.webhook_object.get("title", ""), *[x["value"] for x in data["fields"]], data.webhook_object.get("author", {"name": ""}).get("name", "")]: + if re.search(re.compile(regex), to_check): + misc_logger.info("Message \"{}\" has been rejected due to matching filter ({}).".format( + to_check, regex)) + return # discard the message without anything if messagequeue: messagequeue.add_message(data) else: From de8d0155d9a0e094f4096bb528eecfa902780767 Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 1 Jul 2020 16:36:09 +0200 Subject: [PATCH 23/26] Added disallow_regexes to settings.json.example related to #93 --- settings.json.example | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.json.example b/settings.json.example index b8bb995..65bcec6 100644 --- a/settings.json.example +++ b/settings.json.example @@ -25,6 +25,7 @@ "license_detection": true, "license_regex_detect": "\\{\\{(license|lizenz|licence|copyright)", "license_regex": "\\{\\{(license|lizenz|licence|copyright)(\\ |\\|)(?P.*?)\\}\\}", + "disallow_regexes": [], "wiki_bot_login": "", "wiki_bot_password": "", "show_added_categories": true, From 4305ce5b52860e38ce86e9444d256e8f37929a19 Mon Sep 17 00:00:00 2001 From: Frisk Date: Wed, 1 Jul 2020 16:38:34 +0200 Subject: [PATCH 24/26] Bump version to 1.11 --- configloader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configloader.py b/configloader.py index ba667c8..42c7bce 100644 --- a/configloader.py +++ b/configloader.py @@ -6,7 +6,7 @@ try: # load settings if settings["limitrefetch"] < settings["limit"] and settings["limitrefetch"] != -1: settings["limitrefetch"] = settings["limit"] if "user-agent" in settings["header"]: - settings["header"]["user-agent"] = settings["header"]["user-agent"].format(version="1.10") # set the version in the useragent + settings["header"]["user-agent"] = settings["header"]["user-agent"].format(version="1.11") # set the version in the useragent except FileNotFoundError: logging.critical("No config file could be found. Please make sure settings.json is in the directory.") sys.exit(1) From e29a3c844e59f2c5b9665bb05857c5e10bed36b6 Mon Sep 17 00:00:00 2001 From: Dianliang233 Date: Fri, 3 Jul 2020 08:00:56 +0000 Subject: [PATCH 25/26] Update webhook url & add uk language --- configbuilder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configbuilder.py b/configbuilder.py index e0da517..3ee0665 100644 --- a/configbuilder.py +++ b/configbuilder.py @@ -154,8 +154,8 @@ def set_wiki(): def set_lang(): option = default_or_custom(input( - "Please provide a language code for translation of the script. Translations available: en, de, ru, pt-br, fr, pl. (default en)\n"), "en") - if option in ["en", "de", "ru", "pt-br", "fr", "pl"]: + "Please provide a language code for translation of the script. Translations available: en, de, ru, pt-br, fr, pl, uk. (default en)\n"), "en") + if option in ["en", "de", "ru", "pt-br", "fr", "pl", "uk"]: settings["lang"] = option return True return False @@ -163,7 +163,7 @@ def set_lang(): def set_webhook(): option = input( "Webhook URL is required. You can get it on Discord by following instructions on this page: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks\n") - if option.startswith("https://discordapp.com/api/webhooks/"): + if option.startswith("https://discord.com/api/webhooks/") or option.startswith("https://discordapp.com/api/webhooks/"): test_webhook = requests.get(option) if test_webhook.status_code != 200: print("The webhook URL does not seem right. Reason: {}".format(test_webhook.json()["message"])) @@ -172,7 +172,7 @@ def set_webhook(): settings["webhookURL"] = option return True else: - print("The webhook URL should start with https://discordapp.com/api/webhooks/, are you sure it's the right URL?") + print("The webhook URL should start with https://discord.com/api/webhooks/, are you sure it's the right URL?") return False def set_wikiname(): From b494011e947ab3cb7cd744bfb33813b41cef29cc Mon Sep 17 00:00:00 2001 From: Frisk Date: Sat, 4 Jul 2020 01:12:19 +0200 Subject: [PATCH 26/26] Added some translations --- discussions.pot | 25 ++++++-- discussions.py | 8 +-- locale/de/LC_MESSAGES/discussions.mo | Bin 1428 -> 2378 bytes locale/de/LC_MESSAGES/discussions.po | 55 +++++++++++++--- locale/fr/LC_MESSAGES/discussions.mo | Bin 981 -> 1245 bytes locale/fr/LC_MESSAGES/discussions.po | 82 +++++++++++++++++++++--- locale/pl/LC_MESSAGES/discussions.mo | Bin 1863 -> 2568 bytes locale/pl/LC_MESSAGES/discussions.po | 33 ++++++++-- locale/pt-br/LC_MESSAGES/discussions.mo | Bin 999 -> 1274 bytes locale/pt-br/LC_MESSAGES/discussions.po | 59 ++++++++++++++--- misc.pot | 4 +- rcgcdw.pot | 2 +- 12 files changed, 222 insertions(+), 46 deletions(-) diff --git a/discussions.pot b/discussions.pot index 78b75f9..c516b66 100644 --- a/discussions.pot +++ b/discussions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-06-23 14:54+0200\n" +"POT-Creation-Date: 2020-07-04 00:58+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -22,7 +22,7 @@ msgstr "" msgid "Replied to \"{title}\"" msgstr "" -#: discussions.py:63 discussions.py:79 +#: discussions.py:63 discussions.py:79 discussions.py:127 discussions.py:143 msgid "unknown" msgstr "" @@ -55,21 +55,36 @@ msgstr "" msgid "__[View image]({image_url})__" msgstr "" -#: discussions.py:118 +#: discussions.py:121 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " "in {forumName}" msgstr "" -#: discussions.py:121 +#: discussions.py:130 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall" +msgstr "" + +#: discussions.py:136 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" "{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}" msgstr "" -#: discussions.py:126 +#: discussions.py:147 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message " +"Wall" +msgstr "" + +#: discussions.py:153 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" diff --git a/discussions.py b/discussions.py index 918a552..8b7b750 100644 --- a/discussions.py +++ b/discussions.py @@ -127,10 +127,10 @@ def compact_formatter(post, post_type): user_wall = _("unknown") # Fail safe if post["forumName"].endswith(' Message Wall'): user_wall = post["forumName"][:-13] - message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall".format( + message = _("[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall").format( author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["_embedded"]["thread"][0]["title"], user=user_wall, wikiurl=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), threadid=post["threadId"] - )) + ) else: if discussion_post_type == "FORUM": message = _("[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/{postId}>) to [{title}](<{url}f/p/{threadId}>) in {forumName}").format( @@ -144,9 +144,9 @@ def compact_formatter(post, post_type): if post["forumName"].endswith(' Message Wall'): user_wall = post["forumName"][:-13] message = _( - "[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message Wall".format( + "[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message Wall").format( author=post["createdBy"]["name"], url=settings["fandom_discussions"]["wiki_url"], creatorId=post["creatorId"], title=post["_embedded"]["thread"][0]["title"], user=user_wall, - wikiurl=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), threadid=post["threadId"], replyId=post["id"])) + wikiurl=settings["fandom_discussions"]["wiki_url"], user_wall=quote_plus(user_wall.replace(" ", "_")), threadid=post["threadId"], replyId=post["id"]) elif post_type == "POLL": message = _( diff --git a/locale/de/LC_MESSAGES/discussions.mo b/locale/de/LC_MESSAGES/discussions.mo index 290c27a51efefeb0cf0825b9a268f6222a301106..7e93b3daa11716a34a864cb97e23f311d7d41b12 100644 GIT binary patch literal 2378 zcmcJP&ubGw6vxNk8nxgL@S-?Y!A998tpz19T3cH!*dIt*#VBE#og`y7vtf4DSeJ!f zR74M61P|h|UOjpABKk*o@F4yN-o%67*`!TETZxelOg=l4H}Ac9@6G#maQiEQ(Svyu z^9AN1%-@)1T;D>-0dN951LnZv;1h5UxC|Z!--8zT8N37j1fPRbTM2mvegzq5ZzJS2 z_ys%$=C>2F3k*SuGmpU|STFA&Bn^H9Pl3NcWAFIRx}R}y80&HHF8CBQdVhc~!4OIX z*t46Eci=Pi~;9#`RMk4|#WV+F~?aIWwh!#4vjRls+z89VGf7nCa*dI zX0+R4X}!&jjpYL7>$0oDdwmxJUpZkh;U|KE@!wSwc6cdHqXn$w8kcEGRuh3PL)5Md z3OH4Cm0y`+6&{ieiNh8D1c3{U@q7woL22!hyG*`g{&Tw4U>@1=jH^jQBgsy-|Gt^ z=1s2S`8@IEf^=(=%qaIhFKBDRw&u9<06+l~qi7j;U*$yuoD2hZ|Owvr5Z4MQt9N zoR}PI8XxFS#ztMKxrC0zDvW6UP$#Mm6EaN;Wu`o?Gqc%o>q1k`*eY^mjmd&*3t39h z3-dz9Zd=#50tl4*o@;V=2+vds(2|XtI^WS45n%QGt(#Oi3}Zxr(Y5I`rF&E-Q9NFt<(x*VwjDH4txSVn8@MUjJC5wH-sCWMeGMG8R~ga1J+ zEo^NqM6ehA4RW=47bOFaw>z^lv#+(gt=VVIEQKgS6NXTRM@Zufs_+ea@B``FdPZa$ z@8A>M!wYtv;W4)4?s0?rb5^8<-!XG$l5j{D|Kd~JG$J>6j7PYX`&%4i=B$I# zCYUQO(7ygy{=ZVdw1^yBMPVEbtv88B@kKQCHkr^~>TSl?BPY) created [{title}](<{url}f/p/{threadId}>) " @@ -51,7 +65,17 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) erstellte [{title}](<{url}f/p/{threadId}" ">) in {forumName}" -#: discussions.py:92 +#: discussions.py:130 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) erstellte [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) auf der Nachrichtenseite von " +"{user}" + +#: discussions.py:136 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -60,7 +84,18 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) erstellte eine [Antwork](<{url}f/p/" "{threadId}/r/{postId}>) zu [{title}](<{url}f/p/{threadId}>) in {forumName}" -#: discussions.py:97 +#: discussions.py:147 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message " +"Wall" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) antwortete auf [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) auf der " +"Nachrichtenseite von {user}" + +#: discussions.py:153 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" diff --git a/locale/fr/LC_MESSAGES/discussions.mo b/locale/fr/LC_MESSAGES/discussions.mo index deacaa02ec011832f885a3af544f780a773cf6b9..341a72aec4d9ea68d9ecbe6c8a35a530ad782604 100644 GIT binary patch delta 504 zcmaivze~eF7>2L0wpAy^MJx8`B2-eN_=^q>RtLc@r6`EYVXq}Ly_DPqhZ4j|+$_;a z2M3qp;OOAiF7*%SB)Zwz(a|?mK?m`JC(q^O`z~L)(dVI~m$C2#LB+rn*asuv3Ix>w zqu>#wz!Mk;kq{v|9EbPdE%+3^funF*BP4^ zI2ZoBpbKNZf7u`$RInssg4TXT@YEW|lS^5LGsTNESy!gAxR<21pmkSr$D5Hf$E9Rt zPIsAQkvy+iCR&x|Y+1I%1MO{%5_M!04Lz`8ti z@<2Qlh(YpOnHU(Pf%GXLod%?z0qJ%i?aR!-093*Nj0}@& zS(GQ|Fdmw0#^fSzqHAQNU}RurYN>5tWMIJMlbDxYnwXxd80- F4* 1);\n" -"Language: fr\n" -#: discussions.py:53 +#: discussions.py:56 #, python-brace-format msgid "Replied to \"{title}\"" msgstr "A répondu à « {title} »" -#: discussions.py:56 +#: discussions.py:63 discussions.py:79 discussions.py:127 discussions.py:143 +msgid "unknown" +msgstr "inconnu" + +#: discussions.py:68 +#, python-brace-format +msgid "Replied to \"{title}\" on {user}'s Message Wall" +msgstr "Réponse à « {title} » sur le mur de {user}" + +#: discussions.py:72 #, python-brace-format msgid "Created \"{title}\"" msgstr "Création de {title}" -#: discussions.py:73 +#: discussions.py:86 +#, python-brace-format +msgid "Created \"{title}\" on {user}'s Message Wall" +msgstr "Création de « {title} » sur le mur de {user}" + +#: discussions.py:99 +#, fuzzy, python-brace-format +#| msgid "Created \"{title}\"" +msgid "Created a poll titled \"{title}\"" +msgstr "Création de {title}" + +#: discussions.py:104 +msgid "Option {}" +msgstr "" + +#: discussions.py:105 +#, python-brace-format +msgid "__[View image]({image_url})__" +msgstr "" + +#: discussions.py:121 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " @@ -37,7 +66,19 @@ msgstr "" "Création de [{title}](<{url}f/p/{threadId}>) par [{author}](<{url}f/u/" "{creatorId}>) dans {forumName}" -#: discussions.py:76 +#: discussions.py:130 +#, fuzzy, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in {forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall" +msgstr "" +"Création de [{title}](<{url}f/p/{threadId}>) par [{author}](<{url}f/u/" +"{creatorId}>) dans {forumName}" + +#: discussions.py:136 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -45,3 +86,28 @@ msgid "" msgstr "" "[Réponse](<{url}f/p/{threadId}/r/{postId}>) de [{author}](<{url}f/u/" "{creatorId}>) à [{title}](<{url}f/p/{threadId}>) dans {forumName}" + +#: discussions.py:147 +#, fuzzy, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in {forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message " +"Wall" +msgstr "" +"Création de [{title}](<{url}f/p/{threadId}>) par [{author}](<{url}f/u/" +"{creatorId}>) dans {forumName}" + +#: discussions.py:153 +#, fuzzy, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in {forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" +"{threadId}>) in {forumName}" +msgstr "" +"Création de [{title}](<{url}f/p/{threadId}>) par [{author}](<{url}f/u/" +"{creatorId}>) dans {forumName}" diff --git a/locale/pl/LC_MESSAGES/discussions.mo b/locale/pl/LC_MESSAGES/discussions.mo index 88a1676b25a1f05078934a575e35b23d293ca1a2..a25426a4e80883d5a5ef300e4bdeba4b03946086 100644 GIT binary patch delta 723 zcmb`@&npCB7zglYW`AK(mV;envX@=i>`KwD9|wt5NGY+{re>^RvYH)jOw-nujkryU zf56FM*WTO|_UtP02ROP(@qHJ6fqm-f^S(3hJkR?~rTM5W_u{di5uzE{i9AKNB0rHV zra7V(7>B(u0lQ%V*27EK28%ER@8Jr3hbM53Cpv~tP=u0==o~)4E}|SI?L;m-FyS&j zI)py#UmZk?@BQ2h ze^$<9#FU&|5>+*7>}6yvnZ?o^*Ecm;l;YB;@v~ASb1Z0;xJhe)zqN|Ie^rxrRYjHr zJuTFvyx(9I_v62fe3r+y)i4wa4+`N(G%`>w*zS1i&EbyyXMl=5X5Ba<){OJf@;d!e bTG~x#F~xx*-sb~iP}mV`KMZTy;p+Pa8O*c8 delta 325 zcmXBQKM%n`7{~FaRn(tIh=memFbIkN5knKB-NHaj60bp6Sv3ZOmmraJvq>ZdlUT)T z@xA&bPd~jjclX?F(~rdFn=%eU;#7`WQAz4Uso2_oT*M0F78Y=d5nN*$w^+jyPVk94 zEbAh3ykH(v0g*7)ajeNkdc0)$us1|Tc*Z8`K@k%>XrqH_;TcZxibu?ZL>A~_2`yGv z^BklHKQW&C_BUplAGRTuNEFmbROrRO37Qqt8)!Yv4F+!R%veUdwPwq1wELZ|_crdj LJ2YSJCsO?Z)e0YE diff --git a/locale/pl/LC_MESSAGES/discussions.po b/locale/pl/LC_MESSAGES/discussions.po index 6606ca4..6bd9b94 100644 --- a/locale/pl/LC_MESSAGES/discussions.po +++ b/locale/pl/LC_MESSAGES/discussions.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-06-23 14:54+0200\n" -"PO-Revision-Date: 2020-06-23 14:56+0200\n" +"POT-Creation-Date: 2020-07-04 00:58+0200\n" +"PO-Revision-Date: 2020-07-04 01:12+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: pl\n" @@ -24,7 +24,7 @@ msgstr "" msgid "Replied to \"{title}\"" msgstr "Odpowiedział(a) w „{title}”" -#: discussions.py:63 discussions.py:79 +#: discussions.py:63 discussions.py:79 discussions.py:127 discussions.py:143 msgid "unknown" msgstr "nieznany" @@ -60,7 +60,7 @@ msgstr "Opcja {}" msgid "__[View image]({image_url})__" msgstr "__[Zobacz zdjęcie]({image_url})__" -#: discussions.py:118 +#: discussions.py:121 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " @@ -69,7 +69,17 @@ msgstr "" "[{author}](<{url}f/u/{creatorId}>) utworzył(a) [{title}](<{url}f/p/{threadId}" ">) w {forumName}" -#: discussions.py:121 +#: discussions.py:130 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) utworzył(a) [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) na tablicy wiadomości " +"użytkownika/użytkowniczki {user}" + +#: discussions.py:136 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -79,7 +89,18 @@ msgstr "" "{threadId}/r/{postId}>) pod tematem [{title}](<{url}f/p/{threadId}>) w " "{forumName}" -#: discussions.py:126 +#: discussions.py:147 +#, python-brace-format +msgid "" +"[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message " +"Wall" +msgstr "" +"[{author}](<{url}f/u/{creatorId}>) odpowiedział(a) na[{title}](<{wikiurl}" +"wiki/Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) na tablicy " +"wiadomości użytkownika/użytkowniczki {user}" + +#: discussions.py:153 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" diff --git a/locale/pt-br/LC_MESSAGES/discussions.mo b/locale/pt-br/LC_MESSAGES/discussions.mo index 7a7c9a6b3d239ab16ad35f7908f697b5669aea2f..b766170f09e1ae7598dca441576e6134beab8578 100644 GIT binary patch delta 471 zcma)$Jxjw-6oyZln$#~)5r-;xse>T2MyQI876%6x7ePe0GzSf)_m+GhQc7_Woea^< z(SP99U!bFN!9~HzKj7q>iqJ*yz?0|Xa6ayb{WaWqoyy-4q5$T=As7YsAd4q337)|c z=z(cq8AN4x7CwM?;4An6w&6;SXbbroJc0jnlV};fhG*a|Tty4LAUQ(8$`f6}43EK| zFy{NqhTtr+N1{v^>4$}HF1aYK)&iChyQ0*JyvXNvNoXZnamYb?F%-KThVq!jzVvx+n!TqqQmFr<c*0nm}I=0d`iS=*( delta 203 zcmeyx`JBD}o)F7a1|VPsVi_QI0b+I_&H-W&=m26tAnpWW5g?uo#8E)J0f<3j+>8ti zPCz^rhy{TB8%zugVnF&Okd6b=49pA+?LaCXNCTBH0ENK-WFHHN%RKR*)MRN!k;xv6 z&nBBOxp0~28ks2=8Ce-xY;IvEiTBhSIAdTsxHYa$w{qMVsI|XOiY>l Lhf#U59?O0JKvW_1 diff --git a/locale/pt-br/LC_MESSAGES/discussions.po b/locale/pt-br/LC_MESSAGES/discussions.po index f132340..d9bc866 100644 --- a/locale/pt-br/LC_MESSAGES/discussions.po +++ b/locale/pt-br/LC_MESSAGES/discussions.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-26 22:05+0200\n" -"PO-Revision-Date: 2020-04-26 22:18+0200\n" +"POT-Creation-Date: 2020-07-04 00:58+0200\n" +"PO-Revision-Date: 2020-07-04 01:09+0200\n" "Last-Translator: Frisk \n" "Language-Team: \n" "Language: en_US\n" @@ -17,31 +17,45 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.3\n" -#: discussions.py:53 +#: discussions.py:56 #, python-brace-format msgid "Replied to \"{title}\"" msgstr "Respondido o \"{title}\"" -#: discussions.py:58 +#: discussions.py:63 discussions.py:79 discussions.py:127 discussions.py:143 +msgid "unknown" +msgstr "desconhecido" + +#: discussions.py:68 +#, python-brace-format +msgid "Replied to \"{title}\" on {user}'s Message Wall" +msgstr "Respondeu a \"{title}\" no mural de mensagem de {user}" + +#: discussions.py:72 #, python-brace-format msgid "Created \"{title}\"" msgstr "Criado \"{title}\"" -#: discussions.py:70 +#: discussions.py:86 +#, python-brace-format +msgid "Created \"{title}\" on {user}'s Message Wall" +msgstr "Criado \"{title}\" no mural de mensagem de {user}" + +#: discussions.py:99 #, python-brace-format msgid "Created a poll titled \"{title}\"" msgstr "" -#: discussions.py:75 +#: discussions.py:104 msgid "Option {}" msgstr "" -#: discussions.py:76 +#: discussions.py:105 #, python-brace-format msgid "__[View image]({image_url})__" msgstr "" -#: discussions.py:89 +#: discussions.py:121 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}>) " @@ -50,7 +64,19 @@ msgstr "" "Criado [{title}](<{url}f/p/{threadId}>) por [{author}](<{url}f/u/{creatorId}" ">) no {forumName}" -#: discussions.py:92 +#: discussions.py:130 +#, fuzzy, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in {forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) created [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}>) on {user}'s Message Wall" +msgstr "" +"Criado [{title}](<{url}f/p/{threadId}>) por [{author}](<{url}f/u/{creatorId}" +">) no {forumName}" + +#: discussions.py:136 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a [reply](<{url}f/p/{threadId}/r/" @@ -59,7 +85,20 @@ msgstr "" "[Responder](<{url}f/p/{threadId}/r/{postId}>) por [{author}](<{url}f/u/" "{creatorId}>) do [{title}](<{url}f/p/{threadId}>) do {forumName}" -#: discussions.py:97 +#: discussions.py:147 +#, fuzzy, python-brace-format +#| msgid "" +#| "[{author}](<{url}f/u/{creatorId}>) created [{title}](<{url}f/p/{threadId}" +#| ">) in {forumName}" +msgid "" +"[{author}](<{url}f/u/{creatorId}>) replied to [{title}](<{wikiurl}wiki/" +"Message_Wall:{user_wall}?threadId={threadid}#{replyId}>) on {user}'s Message " +"Wall" +msgstr "" +"Criado [{title}](<{url}f/p/{threadId}>) por [{author}](<{url}f/u/{creatorId}" +">) no {forumName}" + +#: discussions.py:153 #, python-brace-format msgid "" "[{author}](<{url}f/u/{creatorId}>) created a poll [{title}](<{url}f/p/" diff --git a/misc.pot b/misc.pot index 8b2322c..4988f4e 100644 --- a/misc.pot +++ b/misc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-26 21:54+0200\n" +"POT-Creation-Date: 2020-07-04 00:57+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: misc.py:123 +#: misc.py:143 msgid "" "\n" "__And more__" diff --git a/rcgcdw.pot b/rcgcdw.pot index c40cdb6..039b485 100644 --- a/rcgcdw.pot +++ b/rcgcdw.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-06-23 14:54+0200\n" +"POT-Creation-Date: 2020-07-04 00:46+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n"