mirror of
https://gitlab.com/chicken-riders/RcGcDw.git
synced 2025-02-23 00:24:09 +00:00
Merge branch 'testing' into 'horse-thread-support'
# Conflicts: # src/discord/queue.py
This commit is contained in:
commit
e457757d6b
|
@ -1,8 +1,5 @@
|
||||||
image: python:3.7-alpine
|
image: python:3.7-alpine
|
||||||
|
|
||||||
include:
|
|
||||||
- template: Code-Quality.gitlab-ci.yml
|
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||||
|
|
||||||
|
@ -37,7 +34,7 @@ pytest:
|
||||||
script:
|
script:
|
||||||
- source venv/bin/activate
|
- source venv/bin/activate
|
||||||
- pip3.7 install -U pytest
|
- pip3.7 install -U pytest
|
||||||
- pytest --junitxml=report.xml
|
- PYTHONPATH=. pytest --junit-xml=report.xml
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
|
|
|
@ -81,7 +81,7 @@ def embed_edit(ctx: Context, change: dict) -> DiscordMessage:
|
||||||
changed_content = ctx.client.make_api_request(
|
changed_content = ctx.client.make_api_request(
|
||||||
"?action=compare&format=json&fromrev={oldrev}&torev={diff}&topst=1&prop=diff".format(
|
"?action=compare&format=json&fromrev={oldrev}&torev={diff}&topst=1&prop=diff".format(
|
||||||
diff=change["revid"], oldrev=change["old_revid"]), "compare", "*")
|
diff=change["revid"], oldrev=change["old_revid"]), "compare", "*")
|
||||||
except ServerError:
|
except (ServerError, MediaWikiError):
|
||||||
changed_content = None
|
changed_content = None
|
||||||
if changed_content:
|
if changed_content:
|
||||||
parse_mediawiki_changes(ctx, changed_content, embed)
|
parse_mediawiki_changes(ctx, changed_content, embed)
|
||||||
|
|
Binary file not shown.
|
@ -10,8 +10,8 @@ msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2021-05-23 17:18+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: magiczocker <jan-frederik-kriete@t-online.de>\n"
|
"Last-Translator: MarkusRost <sukramxro@gmail.com>\n"
|
||||||
"Language-Team: German <https://translate.wikibot.de/projects/rcgcdw/"
|
"Language-Team: German <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"formatters/de/>\n"
|
"formatters/de/>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
@ -19,7 +19,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 4.6\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
"X-Loco-Source-Locale: de_DE\n"
|
"X-Loco-Source-Locale: de_DE\n"
|
||||||
"Generated-By: pygettext.py 1.5\n"
|
"Generated-By: pygettext.py 1.5\n"
|
||||||
"X-Loco-Parser: loco_parse_po\n"
|
"X-Loco-Parser: loco_parse_po\n"
|
||||||
|
@ -1095,7 +1095,7 @@ msgstr "Passive Sichter"
|
||||||
|
|
||||||
#: extensions/base/mediawiki.py:38
|
#: extensions/base/mediawiki.py:38
|
||||||
msgid "autopatrol"
|
msgid "autopatrol"
|
||||||
msgstr "autopatrol"
|
msgstr "Automatisch kontrolliert"
|
||||||
|
|
||||||
#: extensions/base/mediawiki.py:38
|
#: extensions/base/mediawiki.py:38
|
||||||
msgid "wiki_guardian"
|
msgid "wiki_guardian"
|
||||||
|
@ -1402,7 +1402,7 @@ msgstr[0] "Minute"
|
||||||
msgstr[1] "Minuten"
|
msgstr[1] "Minuten"
|
||||||
|
|
||||||
#: extensions/base/mediawiki.py:589
|
#: extensions/base/mediawiki.py:589
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "for {time_number} {time_unit}"
|
msgid "for {time_number} {time_unit}"
|
||||||
msgstr "für {time_number} {time_unit}"
|
msgstr "für {time_number} {time_unit}"
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -8,24 +8,24 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-11-20 09:22+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: MarkusRost <sukramxro@gmail.com>\n"
|
"Last-Translator: MarkusRost <sukramxro@gmail.com>\n"
|
||||||
"Language-Team: German <https://weblate.frisk.space/projects/rcgcdw/redaction/"
|
"Language-Team: German <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"de/>\n"
|
"redaction/de/>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 4.2.1\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "versteckt"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~versteckt~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "Versteckt"
|
#~ msgstr "Versteckt"
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2021-07-11 12:33+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: Tamara Carvallo <carvallotamara@hotmail.com>\n"
|
"Last-Translator: Tamara Carvallo <carvallotamara@hotmail.com>\n"
|
||||||
"Language-Team: Spanish <https://translate.wikibot.de/projects/rcgcdw/"
|
"Language-Team: Spanish <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"formatters/es/>\n"
|
"formatters/es/>\n"
|
||||||
|
@ -139,31 +139,27 @@ msgstr ""
|
||||||
"{target}\""
|
"{target}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:106
|
#: extensions/base/translate.py:106
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) completed moving translation pages from *{article}* "
|
"[{author}]({author_url}) completed moving translation pages from *{article}* "
|
||||||
"to [{target}]({target_url}){comment}"
|
"to [{target}]({target_url}){comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"[{author}]({author_url}) movió la configuración de protección de {redirect}"
|
"[{author}]({author_url}) movió la configuración de protección de *{article}* "
|
||||||
"*{article}* a [{target}]({target_url}){comment}"
|
"a [{target}]({target_url}){comment}"
|
||||||
|
|
||||||
#: extensions/base/translate.py:121
|
#: extensions/base/translate.py:121
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Encountered a problem while moving \"{article}\" to \"{target}\""
|
msgid "Encountered a problem while moving \"{article}\" to \"{target}\""
|
||||||
msgstr ""
|
msgstr "Se encontró un problema al mover \"{article}\" a \"{target}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:133
|
#: extensions/base/translate.py:133
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) encountered a problem while moving [{article}]"
|
"[{author}]({author_url}) encountered a problem while moving [{article}]"
|
||||||
"({article_url}) to [{target}]({target_url}){comment}"
|
"({article_url}) to [{target}]({target_url}){comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
"[{author}]({author_url}) encontró un problema al mover "
|
||||||
"[{author}]({author_url}) fusionó los historiales de revisión de [{article}]"
|
"[{article}]({article_url}) a [{target}]({target_url}){comment}"
|
||||||
"({article_url}) con [{dest}]({dest_url}){comment}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"[{author}]({author_url}) fusionó los historiales de revisión de [{article}]"
|
|
||||||
"({article_url}) en [{dest}]({dest_url}){comment}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:149
|
#: extensions/base/translate.py:149
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
|
@ -171,32 +167,30 @@ msgid ""
|
||||||
"Failed to delete \"{article}\" which belongs to translatable page "
|
"Failed to delete \"{article}\" which belongs to translatable page "
|
||||||
"\"{target}\""
|
"\"{target}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"No se pudo borrar \"{article}\" que pertenece a la página traducible \""
|
||||||
|
"{target}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:161
|
#: extensions/base/translate.py:161
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) failed to delete [{article}]({article_url}) which "
|
"[{author}]({author_url}) failed to delete [{article}]({article_url}) which "
|
||||||
"belongs to translatable page [{target}]({target_url}){comment}"
|
"belongs to translatable page [{target}]({target_url}){comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
"[{author}]({author_url}) no pudo borrar [{article}]({article_url}) que "
|
||||||
"[{author}]({author_url}) fusionó los historiales de revisión de [{article}]"
|
"pertenece a la página traducible [{target}]({target_url}){comment}"
|
||||||
"({article_url}) con [{dest}]({dest_url}){comment}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"[{author}]({author_url}) fusionó los historiales de revisión de [{article}]"
|
|
||||||
"({article_url}) en [{dest}]({dest_url}){comment}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:177
|
#: extensions/base/translate.py:177
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Completed deletion of translation page \"{article}\""
|
msgid "Completed deletion of translation page \"{article}\""
|
||||||
msgstr "Modificó la visibilidad de la revisión en la página {article} "
|
msgstr "Se eliminó completamente la página de traducción \"{article}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:188
|
#: extensions/base/translate.py:188
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) completed deletion of translation page [{article}]"
|
"[{author}]({author_url}) completed deletion of translation page [{article}]"
|
||||||
"({article_url}){comment}"
|
"({article_url}){comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"[{author}]({author_url}) cambió la visibilidad de la revisión en la página "
|
"[{author}]({author_url}) eliminó la página de traducción "
|
||||||
"[{article}]({article_url}){comment}"
|
"[{article}]({article_url}){comment}"
|
||||||
|
|
||||||
#: extensions/base/translate.py:203
|
#: extensions/base/translate.py:203
|
||||||
|
@ -204,108 +198,94 @@ msgstr ""
|
||||||
msgid ""
|
msgid ""
|
||||||
"Failed to delete \"{article}\" which belongs to translation page \"{target}\""
|
"Failed to delete \"{article}\" which belongs to translation page \"{target}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"No se pudo borrar \"{article}\" que pertenece a la página de traducción \""
|
||||||
|
"{target}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:215
|
#: extensions/base/translate.py:215
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) failed to delete [{article}]({article_url}) which "
|
"[{author}]({author_url}) failed to delete [{article}]({article_url}) which "
|
||||||
"belongs to translation page [{target}]({target_url}){comment}"
|
"belongs to translation page [{target}]({target_url}){comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
"[{author}]({author_url}) no pudo borrar [{article}]({article_url}) que "
|
||||||
"[{author}]({author_url}) fusionó los historiales de revisión de [{article}]"
|
"pertenece a la página de traducción [{target}]({target_url}){comment}"
|
||||||
"({article_url}) con [{dest}]({dest_url}){comment}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"[{author}]({author_url}) fusionó los historiales de revisión de [{article}]"
|
|
||||||
"({article_url}) en [{dest}]({dest_url}){comment}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:231
|
#: extensions/base/translate.py:231
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Encouraged translation of \"{article}\""
|
msgid "Encouraged translation of \"{article}\""
|
||||||
msgstr ""
|
msgstr "Traducción recomendada de \"{article}\""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"Quitó la protección de {article}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"Eliminó la protección de {article}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:240
|
#: extensions/base/translate.py:240
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) encouraged translation of [{article}]({article_url})"
|
"[{author}]({author_url}) encouraged translation of [{article}]({article_url})"
|
||||||
"{comment}"
|
"{comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
"[{author}]({author_url}) recomendó la traducción de "
|
||||||
"[{author}]({author_url}) eliminó la protección de [{article}]({article_url})"
|
"[{article}]({article_url}){comment}"
|
||||||
"{comment}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"[{author}]({author_url}) quitó la protección de [{article}]({article_url})"
|
|
||||||
"{comment}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:255
|
#: extensions/base/translate.py:255
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Discouraged translation of \"{article}\""
|
msgid "Discouraged translation of \"{article}\""
|
||||||
msgstr ""
|
msgstr "Traducción desaconsejada de \"{article}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:264
|
#: extensions/base/translate.py:264
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) discouraged translation of [{article}]"
|
"[{author}]({author_url}) discouraged translation of [{article}]"
|
||||||
"({article_url}){comment}"
|
"({article_url}){comment}"
|
||||||
msgstr "[{author}]({author_url}) restauró [{article}]({article_url}){comment}"
|
msgstr ""
|
||||||
|
"[{author}]({author_url}) desaconsejó la traducción de "
|
||||||
|
"[{article}]({article_url}){comment}"
|
||||||
|
|
||||||
#: extensions/base/translate.py:282
|
#: extensions/base/translate.py:282
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Limited languages for \"{article}\" to `{languages}`"
|
msgid "Limited languages for \"{article}\" to `{languages}`"
|
||||||
msgstr ""
|
msgstr "Idiomas limitados para \"{article}\" a `{languages}`"
|
||||||
|
|
||||||
#: extensions/base/translate.py:285
|
#: extensions/base/translate.py:285
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Priority languages for \"{article}\" set to `{languages}`"
|
msgid "Priority languages for \"{article}\" set to `{languages}`"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Los idiomas prioritarios para \"{article}\" se establecieron en `{languages}`"
|
||||||
|
|
||||||
#: extensions/base/translate.py:288
|
#: extensions/base/translate.py:288
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Removed priority languages from \"{article}\""
|
msgid "Removed priority languages from \"{article}\""
|
||||||
msgstr ""
|
msgstr "Se quitaron los idiomas prioritarios de \"{article}\""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"Quitó la protección de {article}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"Eliminó la protección de {article}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:301
|
#: extensions/base/translate.py:301
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) limited languages for [{article}]({article_url}) to "
|
"[{author}]({author_url}) limited languages for [{article}]({article_url}) to "
|
||||||
"`{languages}`{comment}"
|
"`{languages}`{comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"[{author}]({author_url}) modificó la configuración de protección de "
|
"[{author}]({author_url}) limitó los idiomas para [{article}]({article_url}) "
|
||||||
"[{article}]({article_url}) a: {settings}{comment}"
|
"a `{languages}`{comment}"
|
||||||
|
|
||||||
#: extensions/base/translate.py:308
|
#: extensions/base/translate.py:308
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) set the priority languages for [{article}]"
|
"[{author}]({author_url}) set the priority languages for [{article}]"
|
||||||
"({article_url}) to `{languages}`{comment}"
|
"({article_url}) to `{languages}`{comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"[{author}]({author_url}) modificó la configuración de protección de "
|
"[{author}]({author_url}) estableció los idiomas de prioridad para "
|
||||||
"[{article}]({article_url}) a: {settings}{comment}"
|
"[{article}]({article_url}) en `{languages}`{comment}"
|
||||||
|
|
||||||
#: extensions/base/translate.py:315
|
#: extensions/base/translate.py:315
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"[{author}]({author_url}) removed priority languages from [{article}]"
|
"[{author}]({author_url}) removed priority languages from [{article}]"
|
||||||
"({article_url}){comment}"
|
"({article_url}){comment}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"#-#-#-#-# rcgcdw.po (RcGcDw) #-#-#-#-#\n"
|
"[{author}]({author_url}) eliminó los idiomas prioritarios de "
|
||||||
"[{author}]({author_url}) eliminó la protección de [{article}]({article_url})"
|
"[{article}]({article_url}){comment}"
|
||||||
"{comment}\n"
|
|
||||||
"#-#-#-#-# formatters.po (RcGcDw) #-#-#-#-#\n"
|
|
||||||
"[{author}]({author_url}) quitó la protección de [{article}]({article_url})"
|
|
||||||
"{comment}"
|
|
||||||
|
|
||||||
#: extensions/base/translate.py:331
|
#: extensions/base/translate.py:331
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Added translatable page \"{article}\" to aggregate group \"{group}\""
|
msgid "Added translatable page \"{article}\" to aggregate group \"{group}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Se agregó la página traducible \"{article}\" al grupo agregado \"{group}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:342
|
#: extensions/base/translate.py:342
|
||||||
#, fuzzy, python-brace-format
|
#, fuzzy, python-brace-format
|
||||||
|
|
Binary file not shown.
|
@ -8,24 +8,25 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-11-16 22:51+0100\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: Frisk The Evil Goat Overlord <piotrex43@protonmail.ch>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: Polish <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
|
"redaction/pl/>\n"
|
||||||
"Language: pl\n"
|
"Language: pl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: Poedit 2.4.1\n"
|
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 "
|
"|| n%100>=20) ? 1 : 2;\n"
|
||||||
"|| n%100>14) ? 1 : 2);\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "ukryte"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~ukryte~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "Usunięte"
|
#~ msgstr "Usunięte"
|
||||||
|
|
Binary file not shown.
|
@ -21,7 +21,7 @@ msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:34+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:34+0200\n"
|
||||||
"PO-Revision-Date: 2021-07-11 12:33+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: Eduaddad <duduaddad@gmail.com>\n"
|
"Last-Translator: Eduaddad <duduaddad@gmail.com>\n"
|
||||||
"Language-Team: Portuguese (Brazil) <https://translate.wikibot.de/projects/"
|
"Language-Team: Portuguese (Brazil) <https://translate.wikibot.de/projects/"
|
||||||
"rcgcdw/formatters/pt-br/>\n"
|
"rcgcdw/formatters/pt-br/>\n"
|
||||||
|
@ -1402,7 +1402,7 @@ msgstr[0] "minuto"
|
||||||
msgstr[1] "minutos"
|
msgstr[1] "minutos"
|
||||||
|
|
||||||
#: extensions/base/mediawiki.py:589
|
#: extensions/base/mediawiki.py:589
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "for {time_number} {time_unit}"
|
msgid "for {time_number} {time_unit}"
|
||||||
msgstr "por {time_number} {time_unit}"
|
msgstr "por {time_number} {time_unit}"
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -8,24 +8,24 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-11-21 01:09+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: Eduaddad <duduaddad@gmail.com>\n"
|
"Last-Translator: Eduaddad <duduaddad@gmail.com>\n"
|
||||||
"Language-Team: Portuguese (Brazil) <https://weblate.frisk.space/projects/"
|
"Language-Team: Portuguese (Brazil) <https://translate.wikibot.de/projects/"
|
||||||
"rcgcdw/redaction/pt-br/>\n"
|
"rcgcdw/redaction/pt-br/>\n"
|
||||||
"Language: pt-br\n"
|
"Language: pt-br\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 4.2.1\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "oculto"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~oculto~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "Removido"
|
#~ msgstr "Removido"
|
||||||
|
|
Binary file not shown.
|
@ -21,8 +21,8 @@ msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2021-07-11 12:33+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: Philo04 <philipp2012lopu@mail.ru>\n"
|
"Last-Translator: MakandIv <makushkin_andrey@mail.ru>\n"
|
||||||
"Language-Team: Russian <https://translate.wikibot.de/projects/rcgcdw/"
|
"Language-Team: Russian <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"formatters/ru/>\n"
|
"formatters/ru/>\n"
|
||||||
"Language: ru\n"
|
"Language: ru\n"
|
||||||
|
@ -1420,7 +1420,7 @@ msgstr[1] "минуты"
|
||||||
msgstr[2] "минут"
|
msgstr[2] "минут"
|
||||||
|
|
||||||
#: extensions/base/mediawiki.py:589
|
#: extensions/base/mediawiki.py:589
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "for {time_number} {time_unit}"
|
msgid "for {time_number} {time_unit}"
|
||||||
msgstr "на {time_number} {time_unit}"
|
msgstr "на {time_number} {time_unit}"
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -8,8 +8,8 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-12-22 00:13+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: Philo04 <philipp2012lopu@mail.ru>\n"
|
"Last-Translator: MakandIv <makushkin_andrey@mail.ru>\n"
|
||||||
"Language-Team: Russian <https://translate.wikibot.de/projects/rcgcdw/"
|
"Language-Team: Russian <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"redaction/ru/>\n"
|
"redaction/ru/>\n"
|
||||||
"Language: ru\n"
|
"Language: ru\n"
|
||||||
|
@ -18,15 +18,15 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
"X-Generator: Weblate 4.2.1\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "скрыто"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~скрыто~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "Удалено"
|
#~ msgstr "Удалено"
|
||||||
|
|
Binary file not shown.
|
@ -16,32 +16,22 @@
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-11-18 07:47+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: MakandIv <>\n"
|
"Last-Translator: MakandIv <makushkin_andrey@mail.ru>\n"
|
||||||
"Language-Team: Ukrainian <https://weblate.frisk.space/projects/rcgcdw/"
|
"Language-Team: Ukrainian <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"rc_formatters/uk/>\n"
|
"formatters/uk/>\n"
|
||||||
"Language: uk\n"
|
"Language: uk\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"#-#-#-#-# rcgcdw.po #-#-#-#-#\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
|
||||||
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
|
|
||||||
"X-Generator: Poedit 2.4.1\n"
|
|
||||||
"#-#-#-#-# formatters.po #-#-#-#-#\n"
|
|
||||||
"#-#-#-#-# discussion_formatters.po #-#-#-#-#\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"X-Generator: Lokalize 19.12.3\n"
|
|
||||||
"#-#-#-#-# rc_formatters.po #-#-#-#-#\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
"X-Generator: Weblate 4.2.1\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/api/util.py:61 src/api/util.py:66
|
#: src/api/util.py:61 src/api/util.py:66
|
||||||
msgid "__Only whitespace__"
|
msgid "__Only whitespace__"
|
||||||
|
@ -59,10 +49,9 @@ msgstr "Додано"
|
||||||
#: src/api/util.py:141 extensions/base/discussions.py:247
|
#: src/api/util.py:141 extensions/base/discussions.py:247
|
||||||
#: extensions/base/discussions.py:264 extensions/base/abusefilter.py:45
|
#: extensions/base/discussions.py:264 extensions/base/abusefilter.py:45
|
||||||
msgid "Unregistered user"
|
msgid "Unregistered user"
|
||||||
msgstr ""
|
msgstr "Незареєстрований користувач"
|
||||||
|
|
||||||
#: src/api/util.py:160
|
#: src/api/util.py:160
|
||||||
#, fuzzy
|
|
||||||
msgctxt "recent changes Tags"
|
msgctxt "recent changes Tags"
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Теги"
|
msgstr "Теги"
|
||||||
|
@ -88,49 +77,49 @@ msgid "Changed categories"
|
||||||
msgstr "Змінені категорії"
|
msgstr "Змінені категорії"
|
||||||
|
|
||||||
#: extensions/base/cargo.py:37
|
#: extensions/base/cargo.py:37
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Created the Cargo table \"{table}\""
|
msgid "Created the Cargo table \"{table}\""
|
||||||
msgstr "Створив тег \"{tag}\""
|
msgstr "Створив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:45
|
#: extensions/base/cargo.py:45
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "[{author}]({author_url}) created the Cargo table \"{table}\""
|
msgid "[{author}]({author_url}) created the Cargo table \"{table}\""
|
||||||
msgstr "[{author}]({author_url}) створив [тег]({tag_url}) \"{tag}\""
|
msgstr "[{author}]({author_url}) створив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:60
|
#: extensions/base/cargo.py:60
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Recreated the Cargo table \"{table}\""
|
msgid "Recreated the Cargo table \"{table}\""
|
||||||
msgstr "Створив тег \"{tag}\""
|
msgstr "Відтворив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:68
|
#: extensions/base/cargo.py:68
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "[{author}]({author_url}) recreated the Cargo table \"{table}\""
|
msgid "[{author}]({author_url}) recreated the Cargo table \"{table}\""
|
||||||
msgstr "[{author}]({author_url}) створив [тег]({tag_url}) \"{tag}\""
|
msgstr "[{author}]({author_url}) відтворив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:83
|
#: extensions/base/cargo.py:83
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Replaced the Cargo table \"{table}\""
|
msgid "Replaced the Cargo table \"{table}\""
|
||||||
msgstr "Вилучив тег \"{tag}\""
|
msgstr "Замінив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:91
|
#: extensions/base/cargo.py:91
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "[{author}]({author_url}) replaced the Cargo table \"{table}\""
|
msgid "[{author}]({author_url}) replaced the Cargo table \"{table}\""
|
||||||
msgstr "[{author}]({author_url}) створив [тег]({tag_url}) \"{tag}\""
|
msgstr "[{author}]({author_url}) замінив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:105
|
#: extensions/base/cargo.py:105
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Deleted the Cargo table \"{table}\""
|
msgid "Deleted the Cargo table \"{table}\""
|
||||||
msgstr "Вилучив тег \"{tag}\""
|
msgstr "Видалив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/cargo.py:112
|
#: extensions/base/cargo.py:112
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "[{author}]({author_url}) deleted the Cargo table \"{table}\""
|
msgid "[{author}]({author_url}) deleted the Cargo table \"{table}\""
|
||||||
msgstr "[{author}]({author_url}) вилучив [тег]({tag_url}) \"{tag}\""
|
msgstr "[{author}]({author_url}) видалив таблицю Cargo \"{table}\""
|
||||||
|
|
||||||
#: extensions/base/translate.py:41
|
#: extensions/base/translate.py:41
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Marked \"{article}\" for translation"
|
msgid "Marked \"{article}\" for translation"
|
||||||
msgstr ""
|
msgstr "Зазначив сторінку «{article}» як доступну для перекладу"
|
||||||
|
|
||||||
#: extensions/base/translate.py:55
|
#: extensions/base/translate.py:55
|
||||||
#, fuzzy, python-brace-format
|
#, fuzzy, python-brace-format
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2021-05-22 12:08+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: MakandIv <makushkin_andrey@mail.ru>\n"
|
"Last-Translator: MakandIv <makushkin_andrey@mail.ru>\n"
|
||||||
"Language-Team: Ukrainian <https://translate.wikibot.de/projects/rcgcdw/"
|
"Language-Team: Ukrainian <https://translate.wikibot.de/projects/rcgcdw/"
|
||||||
"redaction/uk/>\n"
|
"redaction/uk/>\n"
|
||||||
|
@ -18,15 +18,15 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
"X-Generator: Weblate 4.6\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "приховано"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~приховано~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "Видалено"
|
#~ msgstr "Видалено"
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2021-05-31 21:54+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: lakejason0 <sunliyuan200402@outlook.com>\n"
|
"Last-Translator: lakejason0 <sunliyuan200402@outlook.com>\n"
|
||||||
"Language-Team: Chinese (Simplified) <https://translate.wikibot.de/projects/"
|
"Language-Team: Chinese (Simplified) <https://translate.wikibot.de/projects/"
|
||||||
"rcgcdw/formatters/zh-hans/>\n"
|
"rcgcdw/formatters/zh-hans/>\n"
|
||||||
|
@ -1347,7 +1347,7 @@ msgid_plural "minutes"
|
||||||
msgstr[0] "分"
|
msgstr[0] "分"
|
||||||
|
|
||||||
#: extensions/base/mediawiki.py:589
|
#: extensions/base/mediawiki.py:589
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "for {time_number} {time_unit}"
|
msgid "for {time_number} {time_unit}"
|
||||||
msgstr "时长为 {time_number} {time_unit}"
|
msgstr "时长为 {time_number} {time_unit}"
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-12-13 14:30+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: lakejason0 <sunliyuan200402@outlook.com>\n"
|
"Last-Translator: lakejason0 <sunliyuan200402@outlook.com>\n"
|
||||||
"Language-Team: Chinese (Simplified) <https://translate.wikibot.de/projects/"
|
"Language-Team: Chinese (Simplified) <https://translate.wikibot.de/projects/"
|
||||||
"rcgcdw/redaction/zh-hans/>\n"
|
"rcgcdw/redaction/zh-hans/>\n"
|
||||||
|
@ -17,15 +17,15 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Weblate 4.2.1\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "已隐藏"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~已隐藏~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "移除了"
|
#~ msgstr "移除了"
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: RcGcDw\n"
|
"Project-Id-Version: RcGcDw\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
"POT-Creation-Date: 2021-07-11 14:32+0200\n"
|
||||||
"PO-Revision-Date: 2020-12-13 14:30+0000\n"
|
"PO-Revision-Date: 2021-07-30 10:44+0000\n"
|
||||||
"Last-Translator: lakejason0 <sunliyuan200402@outlook.com>\n"
|
"Last-Translator: lakejason0 <sunliyuan200402@outlook.com>\n"
|
||||||
"Language-Team: Chinese (Traditional) <https://translate.wikibot.de/projects/"
|
"Language-Team: Chinese (Traditional) <https://translate.wikibot.de/projects/"
|
||||||
"rcgcdw/redaction/zh-hant/>\n"
|
"rcgcdw/redaction/zh-hant/>\n"
|
||||||
|
@ -17,15 +17,15 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Weblate 4.2.1\n"
|
"X-Generator: Weblate 4.6.2\n"
|
||||||
|
|
||||||
#: src/discord/redaction.py:77
|
#: src/discord/redaction.py:77
|
||||||
msgid "hidden"
|
msgid "hidden"
|
||||||
msgstr ""
|
msgstr "已隱藏"
|
||||||
|
|
||||||
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
#: src/discord/redaction.py:80 src/discord/redaction.py:85
|
||||||
msgid "~~hidden~~"
|
msgid "~~hidden~~"
|
||||||
msgstr ""
|
msgstr "~~已隱藏~~"
|
||||||
|
|
||||||
#~ msgid "Removed"
|
#~ msgid "Removed"
|
||||||
#~ msgstr "移除了"
|
#~ msgstr "移除了"
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"show_abuselog": false,
|
"show_abuselog": false,
|
||||||
"hide_ips": false,
|
"hide_ips": false,
|
||||||
"discord_message_cooldown": 0,
|
"discord_message_cooldown": 0,
|
||||||
|
"datafile_path": "data.json",
|
||||||
"auto_suppression": {
|
"auto_suppression": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"db_location": ":memory:"
|
"db_location": ":memory:"
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -2,7 +2,7 @@ from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='RcGcDw',
|
name='RcGcDw',
|
||||||
version='1.14',
|
version='1.14.0.1',
|
||||||
packages=[''],
|
packages=[''],
|
||||||
url='https://gitlab.com/piotrex43/RcGcDw/',
|
url='https://gitlab.com/piotrex43/RcGcDw/',
|
||||||
license='GNU GPLv3',
|
license='GNU GPLv3',
|
||||||
|
|
|
@ -21,6 +21,7 @@ from typing import Optional, Callable
|
||||||
|
|
||||||
logger = logging.getLogger("src.api.formatter")
|
logger = logging.getLogger("src.api.formatter")
|
||||||
|
|
||||||
|
|
||||||
def _register_formatter(func, kwargs, formatter_type: str, action_type=None):
|
def _register_formatter(func, kwargs, formatter_type: str, action_type=None):
|
||||||
"""
|
"""
|
||||||
Registers a formatter inside of src.rcgcdw.formatter_hooks
|
Registers a formatter inside of src.rcgcdw.formatter_hooks
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Made just to avoid circular imports
|
# Made just to avoid circular imports
|
||||||
formatter_hooks = {}
|
from typing import Callable, List, Dict
|
||||||
pre_hooks = []
|
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
||||||
post_hooks = []
|
from src.api.context import Context
|
||||||
|
|
||||||
|
formatter_hooks: Dict[str, Callable[[Context, dict], DiscordMessage]] = {}
|
||||||
|
pre_hooks: List[Callable[[Context, dict], None]] = []
|
||||||
|
post_hooks: List[Callable[[DiscordMessage, DiscordMessageMetadata, Context, dict], None]] = []
|
22
src/argparser.py
Normal file
22
src/argparser.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Start RcGcDw")
|
||||||
|
parser.add_argument("--test", action='store_true', help="mode used for testing, sends only 5 entries of both rc and discussion changes and sends daily overview")
|
||||||
|
parser.add_argument("--settings", default="settings.json", type=argparse.FileType(encoding='utf8'), help="provides a path to settings file (default ./settings.json)")
|
||||||
|
command_args, unknown = parser.parse_known_args()
|
||||||
|
|
|
@ -16,19 +16,19 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
from src.argparser import command_args
|
||||||
global settings
|
global settings
|
||||||
|
|
||||||
|
|
||||||
def load_settings():
|
def load_settings():
|
||||||
global settings
|
global settings
|
||||||
try: # load settings
|
try: # load settings
|
||||||
with open("settings.json", encoding="utf8") as sfile:
|
command_args.settings.seek(0)
|
||||||
settings = json.load(sfile)
|
settings = json.load(command_args.settings)
|
||||||
if settings["limitrefetch"] < settings["limit"] and settings["limitrefetch"] != -1:
|
if settings["limitrefetch"] < settings["limit"] and settings["limitrefetch"] != -1:
|
||||||
settings["limitrefetch"] = settings["limit"]
|
settings["limitrefetch"] = settings["limit"]
|
||||||
if "user-agent" in settings["header"]:
|
if "user-agent" in settings["header"]:
|
||||||
settings["header"]["user-agent"] = settings["header"]["user-agent"].format(version="1.14") # set the version in the useragent
|
settings["header"]["user-agent"] = settings["header"]["user-agent"].format(version="1.14.1") # set the version in the useragent
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logging.critical("No config file could be found. Please make sure settings.json is in the directory.")
|
logging.critical("No config file could be found. Please make sure settings.json is in the directory.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -45,4 +45,3 @@ def load_settings():
|
||||||
|
|
||||||
load_settings()
|
load_settings()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional
|
from typing import Optional, Union, Tuple
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from src.configloader import settings
|
from src.configloader import settings
|
||||||
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
from src.discord.message import DiscordMessage, DiscordMessageMetadata, DiscordMessageRaw
|
||||||
|
|
||||||
AUTO_SUPPRESSION_ENABLED = settings.get("auto_suppression", {"enabled": False}).get("enabled")
|
AUTO_SUPPRESSION_ENABLED = settings.get("auto_suppression", {"enabled": False}).get("enabled")
|
||||||
if AUTO_SUPPRESSION_ENABLED:
|
if AUTO_SUPPRESSION_ENABLED:
|
||||||
|
@ -35,7 +35,7 @@ logger = logging.getLogger("rcgcdw.discord.queue")
|
||||||
class MessageQueue:
|
class MessageQueue:
|
||||||
"""Message queue class for undelivered messages"""
|
"""Message queue class for undelivered messages"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._queue = []
|
self._queue: list[Tuple[Union[DiscordMessage, DiscordMessageRaw], DiscordMessageMetadata]] = []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self._queue
|
return self._queue
|
||||||
|
@ -49,10 +49,10 @@ class MessageQueue:
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._queue.clear()
|
self._queue.clear()
|
||||||
|
|
||||||
def add_message(self, message):
|
def add_message(self, message: Tuple[Union[DiscordMessage, DiscordMessageRaw], DiscordMessageMetadata]):
|
||||||
self._queue.append(message)
|
self._queue.append(message)
|
||||||
|
|
||||||
def cut_messages(self, item_num):
|
def cut_messages(self, item_num: int):
|
||||||
self._queue = self._queue[item_num:]
|
self._queue = self._queue[item_num:]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -116,6 +116,9 @@ def handle_discord_http(code, formatted_embed, result):
|
||||||
"Discord have trouble processing the event, and because the HTTP code returned is {} it means we blame them.".format(
|
"Discord have trouble processing the event, and because the HTTP code returned is {} it means we blame them.".format(
|
||||||
code))
|
code))
|
||||||
return 3
|
return 3
|
||||||
|
else:
|
||||||
|
logger.error("There was an unexpected HTTP code returned from Discord: {}".format(code))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def update_ratelimit(request):
|
def update_ratelimit(request):
|
||||||
|
@ -183,5 +186,5 @@ def send_to_discord(data: Optional[DiscordMessage], meta: DiscordMessageMetadata
|
||||||
elif code == 2:
|
elif code == 2:
|
||||||
time.sleep(5.0)
|
time.sleep(5.0)
|
||||||
messagequeue.add_message((data, meta))
|
messagequeue.add_message((data, meta))
|
||||||
elif code < 2:
|
elif code is None or code < 2:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
from typing import List, Union
|
||||||
|
|
||||||
from src.configloader import settings
|
from src.configloader import settings
|
||||||
from src.discord.message import DiscordMessageMetadata, DiscordMessage, DiscordMessageRaw
|
from src.discord.message import DiscordMessageMetadata, DiscordMessageRaw
|
||||||
from src.discord.queue import send_to_discord, messagequeue
|
from src.discord.queue import send_to_discord, messagequeue
|
||||||
from src.fileio.database import db_cursor, db_connection
|
from src.fileio.database import db_cursor, db_connection
|
||||||
from src.i18n import redaction as redaction_translation
|
from src.i18n import redaction as redaction_translation
|
||||||
|
@ -48,14 +50,14 @@ def delete_messages(matching_data: dict):
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
|
|
||||||
|
|
||||||
def redact_messages(ids: list, entry_type: int, to_censor: dict):
|
def redact_messages(ids: Union[List[Union[str, int]], set[Union[int, str]]], entry_type: int, to_censor: dict):
|
||||||
"""Redact past Discord messages
|
"""Redact past Discord messages
|
||||||
|
|
||||||
ids: list of ints
|
ids: list of ints
|
||||||
entry_type: int - 0 for revdel, 1 for logdel
|
entry_type: int - 0 for revdel, 1 for logdel
|
||||||
to_censor: dict - logparams of message parts to censor"""
|
to_censor: dict - logparams of message parts to censor"""
|
||||||
for event_id in ids:
|
for event_id in ids:
|
||||||
if entry_type == 0: # TODO check if queries are proper
|
if entry_type == 0:
|
||||||
message = db_cursor.execute("SELECT content, message_id FROM messages INNER JOIN event ON event.msg_id = messages.message_id WHERE event.revid = ?;", (event_id, ))
|
message = db_cursor.execute("SELECT content, message_id FROM messages INNER JOIN event ON event.msg_id = messages.message_id WHERE event.revid = ?;", (event_id, ))
|
||||||
else:
|
else:
|
||||||
message = db_cursor.execute(
|
message = db_cursor.execute(
|
||||||
|
@ -90,3 +92,23 @@ def redact_messages(ids: list, entry_type: int, to_censor: dict):
|
||||||
send_to_discord(DiscordMessageRaw(message, settings["webhookURL"].split("?", 1)[0]+"/messages/"+str(row[1])), DiscordMessageMetadata("PATCH"))
|
send_to_discord(DiscordMessageRaw(message, settings["webhookURL"].split("?", 1)[0]+"/messages/"+str(row[1])), DiscordMessageMetadata("PATCH"))
|
||||||
else:
|
else:
|
||||||
logger.debug("Could not find message in the database.")
|
logger.debug("Could not find message in the database.")
|
||||||
|
|
||||||
|
|
||||||
|
def find_middle_next(ids: List[str], pageid: int) -> set:
|
||||||
|
"""To address #235 RcGcDw should now remove diffs in next revs relative to redacted revs to protect information in revs that revert revdeleted information.
|
||||||
|
|
||||||
|
:arg ids - list
|
||||||
|
:arg pageid - int
|
||||||
|
|
||||||
|
:return list"""
|
||||||
|
ids = [int(x) for x in ids]
|
||||||
|
result = set()
|
||||||
|
ids.sort() # Just to be sure, sort the list to make sure it's always sorted
|
||||||
|
messages = db_cursor.execute("SELECT revid FROM event WHERE pageid = ? AND revid >= ? ORDER BY revid", (pageid, ids[0],))
|
||||||
|
all_in_page = [x[0] for x in messages.fetchall()]
|
||||||
|
for id in ids:
|
||||||
|
try:
|
||||||
|
result.add(all_in_page[all_in_page.index(id)+1])
|
||||||
|
except (KeyError, ValueError):
|
||||||
|
logger.debug(f"Value {id} not in {all_in_page} or no value after that.")
|
||||||
|
return result - set(ids)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging, schedule, requests
|
import logging, schedule, requests
|
||||||
from typing import Dict, Any, Optional
|
from typing import Optional
|
||||||
|
|
||||||
from src.configloader import settings
|
from src.configloader import settings
|
||||||
|
|
||||||
|
@ -134,6 +134,7 @@ def parse_discussion_post(post, comment_pages):
|
||||||
raise
|
raise
|
||||||
metadata = DiscordMessageMetadata("POST")
|
metadata = DiscordMessageMetadata("POST")
|
||||||
run_hooks(post_hooks, discord_message, metadata, context, post)
|
run_hooks(post_hooks, discord_message, metadata, context, post)
|
||||||
|
discord_message.finish_embed()
|
||||||
send_to_discord(discord_message, metadata)
|
send_to_discord(discord_message, metadata)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,31 @@
|
||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import logging
|
import logging
|
||||||
import json
|
|
||||||
from src.configloader import settings
|
from src.configloader import settings
|
||||||
|
|
||||||
logger = logging.getLogger("rcgcdw.fileio.database")
|
logger = logging.getLogger("rcgcdw.fileio.database")
|
||||||
|
|
||||||
|
|
||||||
|
def catch_db_OperationalError(func):
|
||||||
|
def catcher(*args, **kwargs):
|
||||||
|
global db_connection, db_cursor
|
||||||
|
try:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
if settings.get("error_tolerance", 0) > 1:
|
||||||
|
logger.error("SQL database has been damaged during operation. This can indicate it has been deleted "
|
||||||
|
"during runtime or damaged in some way. If it wasn't purposeful you may want to take a look "
|
||||||
|
"at your disk state. In the meantime, RcGcDw will attempt to recover by re-creating empty database.")
|
||||||
|
db_connection, db_cursor = create_connection()
|
||||||
|
check_tables()
|
||||||
|
func(*args, **kwargs)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
return func
|
||||||
|
|
||||||
|
return catcher
|
||||||
|
|
||||||
|
|
||||||
def create_schema():
|
def create_schema():
|
||||||
"""Creates a SQLite database schema"""
|
"""Creates a SQLite database schema"""
|
||||||
logger.info("Creating database schema...")
|
logger.info("Creating database schema...")
|
||||||
|
@ -60,6 +79,7 @@ def check_tables():
|
||||||
create_schema()
|
create_schema()
|
||||||
|
|
||||||
|
|
||||||
|
@catch_db_OperationalError
|
||||||
def add_entry(pageid: int, revid: int, logid: int, message, message_id: str):
|
def add_entry(pageid: int, revid: int, logid: int, message, message_id: str):
|
||||||
"""Add an edit or log entry to the DB
|
"""Add an edit or log entry to the DB
|
||||||
:param message:
|
:param message:
|
||||||
|
@ -69,21 +89,27 @@ def add_entry(pageid: int, revid: int, logid: int, message, message_id: str):
|
||||||
:param message_id:
|
:param message_id:
|
||||||
"""
|
"""
|
||||||
db_cursor.execute("INSERT INTO messages (message_id, content) VALUES (?, ?)", (message_id, message))
|
db_cursor.execute("INSERT INTO messages (message_id, content) VALUES (?, ?)", (message_id, message))
|
||||||
db_cursor.execute("INSERT INTO event (pageid, revid, logid, msg_id) VALUES (?, ?, ?, ?)", (pageid, revid, logid, message_id))
|
db_cursor.execute("INSERT INTO event (pageid, revid, logid, msg_id) VALUES (?, ?, ?, ?)",
|
||||||
logger.debug("Adding an entry to the database (pageid: {}, revid: {}, logid: {}, message: {})".format(pageid, revid, logid, message))
|
(pageid, revid, logid, message_id))
|
||||||
|
logger.debug(
|
||||||
|
"Adding an entry to the database (pageid: {}, revid: {}, logid: {}, message: {})".format(pageid, revid, logid,
|
||||||
|
message))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
|
|
||||||
|
|
||||||
|
@catch_db_OperationalError
|
||||||
def clean_entries():
|
def clean_entries():
|
||||||
"""Cleans entries that are 50+"""
|
"""Cleans entries that are 50+"""
|
||||||
cleanup = db_cursor.execute(
|
cleanup = db_cursor.execute(
|
||||||
"SELECT message_id FROM messages WHERE message_id NOT IN (SELECT message_id FROM messages ORDER BY message_id desc LIMIT 50);")
|
"SELECT message_id FROM messages WHERE message_id NOT IN (SELECT message_id FROM messages ORDER BY message_id desc LIMIT 50);")
|
||||||
for row in cleanup:
|
for row in cleanup:
|
||||||
db_cursor.execute("DELETE FROM messages WHERE message_id = ?", (row[0],))
|
db_cursor.execute("DELETE FROM messages WHERE message_id = ?", (row[0],))
|
||||||
cleanup = db_cursor.execute("SELECT msg_id FROM event WHERE msg_id NOT IN (SELECT msg_id FROM event ORDER BY msg_id desc LIMIT 50);")
|
cleanup = db_cursor.execute(
|
||||||
|
"SELECT msg_id FROM event WHERE msg_id NOT IN (SELECT msg_id FROM event ORDER BY msg_id desc LIMIT 50);")
|
||||||
for row in cleanup:
|
for row in cleanup:
|
||||||
db_cursor.execute("DELETE FROM event WHERE msg_id = ?", (row[0],))
|
db_cursor.execute("DELETE FROM event WHERE msg_id = ?", (row[0],))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
|
|
||||||
|
|
||||||
db_connection, db_cursor = create_connection()
|
db_connection, db_cursor = create_connection()
|
||||||
check_tables()
|
check_tables()
|
||||||
|
|
14
src/i18n.py
14
src/i18n.py
|
@ -14,9 +14,15 @@
|
||||||
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import gettext, sys, logging
|
import gettext, sys, logging
|
||||||
|
from typing import Union, Optional
|
||||||
from src.configloader import settings
|
from src.configloader import settings
|
||||||
logger = logging.getLogger("rcgcdw.i18n")
|
logger = logging.getLogger("rcgcdw.i18n")
|
||||||
|
rcgcdw: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
|
||||||
|
discussion_formatters: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
|
||||||
|
rc: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
|
||||||
|
formatters_i18n: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
|
||||||
|
misc: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
|
||||||
|
redaction: Optional[Union[gettext.GNUTranslations, gettext.NullTranslations]] = None
|
||||||
# Setup translation
|
# Setup translation
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +33,9 @@ def python37_pgettext_backward_compatibility(context: str, string: str):
|
||||||
return string
|
return string
|
||||||
return translation
|
return translation
|
||||||
|
|
||||||
|
|
||||||
|
def load_languages():
|
||||||
|
global rcgcdw, rc, formatters_i18n, misc, redaction
|
||||||
try:
|
try:
|
||||||
if settings["lang"] != "en":
|
if settings["lang"] != "en":
|
||||||
rcgcdw = gettext.translation('rcgcdw', localedir='locale', languages=[settings["lang"]])
|
rcgcdw = gettext.translation('rcgcdw', localedir='locale', languages=[settings["lang"]])
|
||||||
|
@ -40,3 +49,6 @@ try:
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logger.critical("No language files have been found. Make sure locale folder is located in the directory.")
|
logger.critical("No language files have been found. Make sure locale folder is located in the directory.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
load_languages()
|
30
src/misc.py
30
src/misc.py
|
@ -48,15 +48,15 @@ profile_fields = {"profile-location": _("Location"), "profile-aboutme": _("About
|
||||||
class DataFile:
|
class DataFile:
|
||||||
"""Data class which instance of is shared by multiple modules to remain consistent and do not cause too many IO operations."""
|
"""Data class which instance of is shared by multiple modules to remain consistent and do not cause too many IO operations."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.data = self.load_datafile()
|
self.data_filename: str = settings.get("datafile_path", "data.json")
|
||||||
misc_logger.debug("Current contents of data.json {}".format(self.data))
|
self.data: dict = self.load_datafile()
|
||||||
self.changed = False
|
misc_logger.debug("Current contents of {} {}".format(self.data_filename, self.data))
|
||||||
|
self.changed: bool = False
|
||||||
|
|
||||||
@staticmethod
|
def generate_datafile(self):
|
||||||
def generate_datafile():
|
|
||||||
"""Generate a data.json file from a template."""
|
"""Generate a data.json file from a template."""
|
||||||
try:
|
try:
|
||||||
with open("data.json", 'w', encoding="utf-8") as data:
|
with open(self.data_filename, 'w', encoding="utf-8") as data:
|
||||||
data.write(json.dumps(data_template, indent=4))
|
data.write(json.dumps(data_template, indent=4))
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
misc_logger.critical("Could not create a data file (no permissions). No way to store last edit.")
|
misc_logger.critical("Could not create a data file (no permissions). No way to store last edit.")
|
||||||
|
@ -67,7 +67,7 @@ class DataFile:
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with open("data.json", encoding="utf-8") as data:
|
with open(self.data_filename, encoding="utf-8") as data:
|
||||||
return json.loads(data.read())
|
return json.loads(data.read())
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.generate_datafile()
|
self.generate_datafile()
|
||||||
|
@ -79,7 +79,7 @@ class DataFile:
|
||||||
if self.changed is False: # don't cause unnecessary write operations
|
if self.changed is False: # don't cause unnecessary write operations
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
with open("data.json", "w", encoding="utf-8") as data_file:
|
with open(self.data_filename, "w", encoding="utf-8") as data_file:
|
||||||
data_file.write(json.dumps(self.data, indent=4))
|
data_file.write(json.dumps(self.data, indent=4))
|
||||||
self.changed = False
|
self.changed = False
|
||||||
misc_logger.debug("Saving the database succeeded.")
|
misc_logger.debug("Saving the database succeeded.")
|
||||||
|
@ -89,7 +89,7 @@ class DataFile:
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if settings.get("error_tolerance", 1) > 1:
|
if settings.get("error_tolerance", 1) > 1:
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
if "Invalid argument: 'data.json'" in str(e):
|
if "Invalid argument: '" + self.data_filename + "'" in str(e):
|
||||||
misc_logger.error("Saving the data file failed due to Invalid argument exception, we've seen it "
|
misc_logger.error("Saving the data file failed due to Invalid argument exception, we've seen it "
|
||||||
"before in issue #209, if you know the reason for it happening please reopen the "
|
"before in issue #209, if you know the reason for it happening please reopen the "
|
||||||
"issue with explanation, for now we are going to just ignore it.") # Reference #209
|
"issue with explanation, for now we are going to just ignore it.") # Reference #209
|
||||||
|
@ -97,6 +97,7 @@ class DataFile:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def __setitem__(self, instance, value):
|
def __setitem__(self, instance, value):
|
||||||
|
if self.data[instance] != value:
|
||||||
self.data[instance] = value
|
self.data[instance] = value
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
|
@ -255,16 +256,17 @@ def add_to_dict(dictionary, key):
|
||||||
return dictionary
|
return dictionary
|
||||||
|
|
||||||
|
|
||||||
def prepare_paths(path, dry=False):
|
def prepare_paths(path: str, dry=False):
|
||||||
global WIKI_API_PATH
|
|
||||||
global WIKI_ARTICLE_PATH
|
|
||||||
global WIKI_SCRIPT_PATH
|
|
||||||
global WIKI_JUST_DOMAIN
|
|
||||||
"""Set the URL paths for article namespace and script namespace
|
"""Set the URL paths for article namespace and script namespace
|
||||||
WIKI_API_PATH will be: WIKI_DOMAIN/api.php
|
WIKI_API_PATH will be: WIKI_DOMAIN/api.php
|
||||||
WIKI_ARTICLE_PATH will be: WIKI_DOMAIN/articlepath/$1 where $1 is the replaced string
|
WIKI_ARTICLE_PATH will be: WIKI_DOMAIN/articlepath/$1 where $1 is the replaced string
|
||||||
WIKI_SCRIPT_PATH will be: WIKI_DOMAIN/
|
WIKI_SCRIPT_PATH will be: WIKI_DOMAIN/
|
||||||
WIKI_JUST_DOMAIN will be: WIKI_DOMAIN"""
|
WIKI_JUST_DOMAIN will be: WIKI_DOMAIN"""
|
||||||
|
global WIKI_API_PATH
|
||||||
|
global WIKI_ARTICLE_PATH
|
||||||
|
global WIKI_SCRIPT_PATH
|
||||||
|
global WIKI_JUST_DOMAIN
|
||||||
|
|
||||||
def quick_try_url(url):
|
def quick_try_url(url):
|
||||||
"""Quickly test if URL is the proper script path,
|
"""Quickly test if URL is the proper script path,
|
||||||
False if it appears invalid
|
False if it appears invalid
|
||||||
|
|
|
@ -22,29 +22,30 @@
|
||||||
import time, logging.config, requests, datetime, math, os.path, schedule, sys, re, importlib
|
import time, logging.config, requests, datetime, math, os.path, schedule, sys, re, importlib
|
||||||
|
|
||||||
import src.misc
|
import src.misc
|
||||||
|
import src.configloader
|
||||||
from collections import defaultdict, Counter, OrderedDict
|
from collections import defaultdict, Counter, OrderedDict
|
||||||
|
from src.argparser import command_args
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import src.api.client
|
import src.api.client
|
||||||
from src.api.context import Context
|
from src.api.context import Context
|
||||||
from src.api.hooks import formatter_hooks, pre_hooks, post_hooks
|
from src.api.hooks import formatter_hooks, pre_hooks, post_hooks
|
||||||
from src.configloader import settings
|
from src.misc import add_to_dict, datafile, run_hooks
|
||||||
from src.misc import add_to_dict, datafile, WIKI_API_PATH, LinkParser, run_hooks
|
|
||||||
from src.api.util import create_article_path, default_message
|
from src.api.util import create_article_path, default_message
|
||||||
from src.discord.queue import send_to_discord
|
from src.discord.queue import send_to_discord
|
||||||
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
||||||
from src.exceptions import MWError, ServerError, MediaWikiError, BadRequest, ClientError, NoFormatter
|
from src.exceptions import ServerError, MediaWikiError, NoFormatter
|
||||||
from src.i18n import rcgcdw
|
from src.i18n import rcgcdw
|
||||||
from src.wiki import Wiki
|
from src.wiki import Wiki
|
||||||
|
|
||||||
|
settings = src.configloader.settings
|
||||||
_ = rcgcdw.gettext
|
_ = rcgcdw.gettext
|
||||||
ngettext = rcgcdw.ngettext
|
ngettext = rcgcdw.ngettext
|
||||||
|
|
||||||
TESTING = True if "--test" in sys.argv else False # debug mode, pipeline testing
|
TESTING = command_args.test # debug mode, pipeline testing
|
||||||
AUTO_SUPPRESSION_ENABLED = settings.get("auto_suppression", {"enabled": False}).get("enabled")
|
AUTO_SUPPRESSION_ENABLED = settings.get("auto_suppression", {"enabled": False}).get("enabled")
|
||||||
|
|
||||||
if AUTO_SUPPRESSION_ENABLED:
|
if AUTO_SUPPRESSION_ENABLED:
|
||||||
from src.discord.redaction import delete_messages, redact_messages
|
from src.discord.redaction import delete_messages, redact_messages, find_middle_next
|
||||||
# Prepare logging
|
# Prepare logging
|
||||||
|
|
||||||
logging.config.dictConfig(settings["logging"])
|
logging.config.dictConfig(settings["logging"])
|
||||||
|
@ -259,8 +260,11 @@ def rc_processor(change, changed_categories):
|
||||||
delete_messages(dict(logid=logid))
|
delete_messages(dict(logid=logid))
|
||||||
elif identification_string == "delete/revision" and AUTO_SUPPRESSION_ENABLED:
|
elif identification_string == "delete/revision" and AUTO_SUPPRESSION_ENABLED:
|
||||||
logparams = change.get('logparams', {"ids": []})
|
logparams = change.get('logparams', {"ids": []})
|
||||||
|
if logparams.get("type", "") in ("revision", "logging", "oldimage"):
|
||||||
if settings["appearance"]["mode"] == "embed":
|
if settings["appearance"]["mode"] == "embed":
|
||||||
redact_messages(logparams.get("ids", []), 0, logparams.get("new", {}))
|
redact_messages(logparams.get("ids", []), 0, logparams.get("new", {}))
|
||||||
|
if "content" in logparams.get("new", {}) and settings.get("appearance", {}).get("embed", {}).get("show_edit_changes", False): # Also redact revisions in the middle and next ones in case of content (diffs leak)
|
||||||
|
redact_messages(find_middle_next(logparams.get("ids", []), change.get("pageid", -1)), 0, {"content": ""})
|
||||||
else:
|
else:
|
||||||
for revid in logparams.get("ids", []):
|
for revid in logparams.get("ids", []):
|
||||||
delete_messages(dict(revid=revid))
|
delete_messages(dict(revid=revid))
|
||||||
|
@ -338,6 +342,7 @@ if TESTING:
|
||||||
day_overview()
|
day_overview()
|
||||||
import src.discussions
|
import src.discussions
|
||||||
src.discussions.fetch_discussions()
|
src.discussions.fetch_discussions()
|
||||||
|
logger.info("Test has succeeded without premature exceptions.")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
|
|
|
@ -38,6 +38,7 @@ storage = datafile
|
||||||
|
|
||||||
logger = logging.getLogger("rcgcdw.rc")
|
logger = logging.getLogger("rcgcdw.rc")
|
||||||
|
|
||||||
|
|
||||||
class Wiki(object):
|
class Wiki(object):
|
||||||
"""Store verious data and functions related to wiki and fetching of Recent Changes"""
|
"""Store verious data and functions related to wiki and fetching of Recent Changes"""
|
||||||
def __init__(self, rc_processor: Callable, abuse_processor: Callable):
|
def __init__(self, rc_processor: Callable, abuse_processor: Callable):
|
||||||
|
@ -394,8 +395,7 @@ class Wiki(object):
|
||||||
if self.downtimecredibility < 60:
|
if self.downtimecredibility < 60:
|
||||||
self.downtimecredibility += 15
|
self.downtimecredibility += 15
|
||||||
else:
|
else:
|
||||||
if (
|
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
|
||||||
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_simple("down_detector", _("{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"])
|
_("Connection status"), settings["avatars"]["connection_failed"])
|
||||||
self.last_downtime = time.time()
|
self.last_downtime = time.time()
|
||||||
|
|
93
test/data/rc_objects.json
Normal file
93
test/data/rc_objects.json
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{
|
||||||
|
"edit": {
|
||||||
|
"type": "edit",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Some page",
|
||||||
|
"pageid": 9327,
|
||||||
|
"revid": 2075232,
|
||||||
|
"old_revid": 232555,
|
||||||
|
"rcid": 2793437,
|
||||||
|
"user": "User3",
|
||||||
|
"oldlen": 32882,
|
||||||
|
"newlen": 328,
|
||||||
|
"timestamp": "2022-03-26T11:41:22Z",
|
||||||
|
"parsedcomment": "Work on new as",
|
||||||
|
"tags": ["VisualEdit"]
|
||||||
|
},
|
||||||
|
"abuselog": {
|
||||||
|
"id": 4690092,
|
||||||
|
"filter": "Prevent vandalism",
|
||||||
|
"filter_id": "3",
|
||||||
|
"user": "User4",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Survival",
|
||||||
|
"action": "edit",
|
||||||
|
"result": "tag",
|
||||||
|
"revid": "398328478",
|
||||||
|
"timestamp": "2022-01-13T06:20:58Z"
|
||||||
|
},
|
||||||
|
"cargo/createtable": {
|
||||||
|
"type": "log",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "",
|
||||||
|
"pageid": 0,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 13325,
|
||||||
|
"user": "User 10",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2022-01-13T15:25:09Z",
|
||||||
|
"parsedcomment": "",
|
||||||
|
"logid": 1865,
|
||||||
|
"logtype": "cargo",
|
||||||
|
"logaction": "createtable",
|
||||||
|
"logparams": {
|
||||||
|
"0": "<a href=\"https://somewiki.somefarm.com/wiki/Special:CargoTables/TableTest\">TableTest</a>"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"datadump/generate": {
|
||||||
|
"type": "log",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Datadump",
|
||||||
|
"pageid": 0,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 13325,
|
||||||
|
"user": "User 10",
|
||||||
|
"timestamp": "2022-01-13T15:25:09Z",
|
||||||
|
"parsedcomment": "",
|
||||||
|
"logid": 18,
|
||||||
|
"logtype": "datadump",
|
||||||
|
"logaction": "generate",
|
||||||
|
"logparams": {
|
||||||
|
"filename": "Somefilenoidea.tar.gz"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
"interwiki/iw_add": {
|
||||||
|
"type": "log",
|
||||||
|
"ns": -1,
|
||||||
|
"title": "Special:Interwiki",
|
||||||
|
"pageid": 0,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 13326,
|
||||||
|
"user": "Not An User",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2022-01-13T15:31:25Z",
|
||||||
|
"parsedcomment": "Just a test",
|
||||||
|
"logid": 1866,
|
||||||
|
"logtype": "interwiki",
|
||||||
|
"logaction": "iw_add",
|
||||||
|
"logparams": {
|
||||||
|
"0": "testonlypleaseignore",
|
||||||
|
"1": "https://notawiki.notaplatform.com/wiki/$1",
|
||||||
|
"2": "0",
|
||||||
|
"3": "0"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
}
|
7
test/data/rc_results.json
Normal file
7
test/data/rc_results.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"edit": {"allowed_mentions": {"parse": []}, "avatar_url": "", "embeds": [{"color": 16711680, "url": "https://minecraft.fandom.com/index.php?title=Some_page&curid=9327&diff=2075232&oldid=232555", "title": "Some page (-32554)", "fields": [{"name": "Removed", "value": "__Only whitespace__", "inline": true}, {"name": "Added", "value": "__Only whitespace__", "inline": true}, {"name": "Tagi", "value": "VisualEdit", "inline": false}], "author": {"name": "User3", "url": "https://minecraft.fandom.com/wiki/User:User3", "icon_url": ""}, "timestamp": "2022-03-26T11:41:22Z", "description": "Work on new as"}]},
|
||||||
|
"datadump/generate": {"allowed_mentions": {"parse": []}, "avatar_url": "", "embeds": [{"color": null, "author": {"name": "User 10", "url": "https://minecraft.fandom.com/wiki/User:User_10", "icon_url": ""}, "timestamp": "2022-01-13T15:25:09Z", "description": "", "title": "Generated Somefilenoidea.tar.gz dump", "url": "https://minecraft.fandom.com/wiki/Datadump"}]},
|
||||||
|
"cargo/createtable":{"allowed_mentions": {"parse": []}, "avatar_url": "", "embeds": [{"color": null, "author": {"name": "User 10", "url": "https://minecraft.fandom.com/wiki/User:User_10", "icon_url": ""}, "timestamp": "2022-01-13T15:25:09Z", "description": "", "url": "https://somewiki.somefarm.com/wiki/Special:CargoTables/TableTest", "title": "Created the Cargo table \"TableTest\""}]},
|
||||||
|
"abuselog": {"allowed_mentions": {"parse": []}, "avatar_url": "", "embeds": [{"color": null, "title": "User4 triggered \"Prevent vandalism\"", "fields": [{"name": "Performed", "value": "Edit", "inline": false}, {"name": "Action taken", "value": "Tagged the edit", "inline": false}, {"name": "Title", "value": "Survival", "inline": false}]}]},
|
||||||
|
"interwiki/iw_add": {"allowed_mentions": {"parse": []}, "avatar_url": "", "embeds": [{"color": null, "author": {"name": "Not An User", "url": "https://minecraft.fandom.com/wiki/User:Not_An_User", "icon_url": ""}, "timestamp": "2022-01-13T15:31:25Z", "url": "https://minecraft.fandom.com/wiki/Special:Interwiki", "title": "Added an entry to the interwiki table", "description": "Prefix: testonlypleaseignore, website: https://notawiki.notaplatform.com/wiki/$1 | "}]}
|
||||||
|
}
|
557
test/mockserver/configs/settings1.json
Normal file
557
test/mockserver/configs/settings1.json
Normal file
|
@ -0,0 +1,557 @@
|
||||||
|
{
|
||||||
|
"cooldown": 30,
|
||||||
|
"wiki_url": "http://localhost:8080/",
|
||||||
|
"rc_enabled": true,
|
||||||
|
"lang": "en",
|
||||||
|
"header": {
|
||||||
|
"user-agent": "RcGcDw/{version}"
|
||||||
|
},
|
||||||
|
"limit": 15,
|
||||||
|
"webhookURL": "http://localhost:8080/webhook/",
|
||||||
|
"limitrefetch": 15,
|
||||||
|
"wikiname": "Testing Connection",
|
||||||
|
"avatars": {
|
||||||
|
"connection_failed": "https://i.imgur.com/2jWQEt1.png",
|
||||||
|
"connection_restored": "",
|
||||||
|
"no_event": "",
|
||||||
|
"embed": "",
|
||||||
|
"compact": ""
|
||||||
|
},
|
||||||
|
"ignored": ["external", "newusers/create", "newusers/autocreate", "newusers/create2", "newusers/byemail", "newusers/newusers"],
|
||||||
|
"show_updown_messages": true,
|
||||||
|
"ignored_namespaces": [],
|
||||||
|
"extensions_dir": "extensions",
|
||||||
|
"error_tolerance": 0,
|
||||||
|
"overview": false,
|
||||||
|
"overview_time": "00:00",
|
||||||
|
"send_empty_overview": false,
|
||||||
|
"license_detection": true,
|
||||||
|
"license_regex_detect": "\\{\\{(license|lizenz|licence|copyright)",
|
||||||
|
"license_regex": "\\{\\{(license|lizenz|licence|copyright)(\\ |\\|)(?P<license>.*?)\\}\\}",
|
||||||
|
"disallow_regexes": [],
|
||||||
|
"wiki_bot_login": "",
|
||||||
|
"wiki_bot_password": "",
|
||||||
|
"show_added_categories": true,
|
||||||
|
"show_bots": false,
|
||||||
|
"show_abuselog": false,
|
||||||
|
"hide_ips": false,
|
||||||
|
"discord_message_cooldown": 0,
|
||||||
|
"auto_suppression": {
|
||||||
|
"enabled": true,
|
||||||
|
"db_location": ":memory:"
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"version": 1,
|
||||||
|
"disable_existing_loggers": false,
|
||||||
|
"formatters": {
|
||||||
|
"standard": {
|
||||||
|
"format": "%(name)s - %(asctime)s - %(levelname)s: %(message)s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers": {
|
||||||
|
"default": {
|
||||||
|
"formatter": "standard",
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"stream": "ext://sys.stdout"
|
||||||
|
},
|
||||||
|
"filelogger": {
|
||||||
|
"formatter": "standard",
|
||||||
|
"class": "logging.FileHandler",
|
||||||
|
"filename": "rcgcdw.log",
|
||||||
|
"encoding": "utf-8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"loggers": {
|
||||||
|
"": {
|
||||||
|
"level": 0,
|
||||||
|
"handlers": ["default", "filelogger"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"appearance":{
|
||||||
|
"mode": "embed",
|
||||||
|
"embed": {
|
||||||
|
"show_edit_changes": true,
|
||||||
|
"show_footer": true,
|
||||||
|
"embed_images": true,
|
||||||
|
"show_no_description_provided": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fandom_discussions": {
|
||||||
|
"enabled": false,
|
||||||
|
"wiki_url": "",
|
||||||
|
"cooldown": 60,
|
||||||
|
"webhookURL": "",
|
||||||
|
"limit": 5,
|
||||||
|
"appearance": {
|
||||||
|
"mode": "embed",
|
||||||
|
"embed": {
|
||||||
|
"show_content": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"show_forums": []
|
||||||
|
},
|
||||||
|
"event_appearance": {
|
||||||
|
"daily_overview": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "",
|
||||||
|
"plot": true
|
||||||
|
},
|
||||||
|
"new": {
|
||||||
|
"icon": "https://i.imgur.com/6HIbEq8.png",
|
||||||
|
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
|
||||||
|
"emoji": "🆕"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"icon": "https://i.imgur.com/zKYHkJm.png",
|
||||||
|
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"upload/overwrite": {
|
||||||
|
"icon": "https://i.imgur.com/egJpa81.png",
|
||||||
|
"color": 12390624,
|
||||||
|
"emoji": "🖼️"
|
||||||
|
},
|
||||||
|
"upload/upload": {
|
||||||
|
"icon": "https://i.imgur.com/egJpa81.png",
|
||||||
|
"color": 12390624,
|
||||||
|
"emoji": "🖼️"
|
||||||
|
},
|
||||||
|
"upload/revert": {
|
||||||
|
"icon": "https://i.imgur.com/egJpa81.png",
|
||||||
|
"color": 12390624,
|
||||||
|
"emoji": "⏮️"
|
||||||
|
},
|
||||||
|
"delete/delete": {
|
||||||
|
"icon": "https://i.imgur.com/BU77GD3.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"delete/delete_redir": {
|
||||||
|
"icon": "https://i.imgur.com/BU77GD3.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"delete/restore": {
|
||||||
|
"icon": "https://i.imgur.com/9MnROIU.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "♻️"
|
||||||
|
},
|
||||||
|
"delete/revision": {
|
||||||
|
"icon": "https://i.imgur.com/1gps6EZ.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"delete/event": {
|
||||||
|
"icon": "https://i.imgur.com/1gps6EZ.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"merge/merge": {
|
||||||
|
"icon": "https://i.imgur.com/uQMK9XK.png",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "🖇️"
|
||||||
|
},
|
||||||
|
"move/move": {
|
||||||
|
"icon": "https://i.imgur.com/eXz9dog.png",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📨"
|
||||||
|
},
|
||||||
|
"move/move_redir": {
|
||||||
|
"icon": "https://i.imgur.com/UtC3YX2.png",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📨"
|
||||||
|
},
|
||||||
|
"block/block": {
|
||||||
|
"icon": "https://i.imgur.com/g7KgZHf.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🚫"
|
||||||
|
},
|
||||||
|
"block/unblock": {
|
||||||
|
"icon": "https://i.imgur.com/bvtBJ8o.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "✅"
|
||||||
|
},
|
||||||
|
"block/reblock": {
|
||||||
|
"icon": "https://i.imgur.com/g7KgZHf.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🚫"
|
||||||
|
},
|
||||||
|
"protect/protect": {
|
||||||
|
"icon": "https://i.imgur.com/bzPt89Z.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔒"
|
||||||
|
},
|
||||||
|
"protect/modify": {
|
||||||
|
"icon": "https://i.imgur.com/bzPt89Z.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔐"
|
||||||
|
},
|
||||||
|
"protect/move_prot": {
|
||||||
|
"icon": "https://i.imgur.com/bzPt89Z.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔏"
|
||||||
|
},
|
||||||
|
"protect/unprotect": {
|
||||||
|
"icon": "https://i.imgur.com/2wN3Qcq.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔓"
|
||||||
|
},
|
||||||
|
"import/upload": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "📥"
|
||||||
|
},
|
||||||
|
"import/interwiki": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "📥"
|
||||||
|
},
|
||||||
|
"rights/rights": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🏅"
|
||||||
|
},
|
||||||
|
"rights/autopromote": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🏅"
|
||||||
|
},
|
||||||
|
"abusefilter/modify": {
|
||||||
|
"icon": "https://i.imgur.com/Sn2NzRJ.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔍"
|
||||||
|
},
|
||||||
|
"abusefilter/create": {
|
||||||
|
"icon": "https://i.imgur.com/Sn2NzRJ.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔍"
|
||||||
|
},
|
||||||
|
"interwiki/iw_add": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔗"
|
||||||
|
},
|
||||||
|
"interwiki/iw_edit": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔗"
|
||||||
|
},
|
||||||
|
"interwiki/iw_delete": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔗"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-created": {
|
||||||
|
"icon": "https://i.imgur.com/Lvy5E32.png",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "✉️"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-edited": {
|
||||||
|
"icon": "https://i.imgur.com/Lvy5E32.png",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "📧"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-deleted": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-purged":{
|
||||||
|
"icon":"",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-replied": {
|
||||||
|
"icon": "https://i.imgur.com/hkyYsI1.png",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "📩"
|
||||||
|
},
|
||||||
|
"curseprofile/profile-edited": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "📌"
|
||||||
|
},
|
||||||
|
"contentmodel/change": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📋"
|
||||||
|
},
|
||||||
|
"contentmodel/new": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📋"
|
||||||
|
},
|
||||||
|
"cargo/deletetable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"cargo/createtable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"cargo/replacetable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"cargo/recreatetable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"sprite/sprite": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🪟"
|
||||||
|
},
|
||||||
|
"sprite/sheet": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🪟"
|
||||||
|
},
|
||||||
|
"sprite/slice": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🪟"
|
||||||
|
},
|
||||||
|
"managetags/create": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"managetags/delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"managetags/activate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"managetags/deactivate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"newusers/autocreate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/byemail": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/create": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/create2": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/newusers": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"managewiki/delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"managewiki/lock": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🔒"
|
||||||
|
},
|
||||||
|
"managewiki/namespaces": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"managewiki/namespaces-delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"managewiki/rights": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🏅"
|
||||||
|
},
|
||||||
|
"managewiki/settings": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "⚙️"
|
||||||
|
},
|
||||||
|
"managewiki/undelete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "♻️"
|
||||||
|
},
|
||||||
|
"managewiki/unlock": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🔓"
|
||||||
|
},
|
||||||
|
"datadump/generate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "📤"
|
||||||
|
},
|
||||||
|
"datadump/delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"pagetranslation/mark": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/unmark": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/moveok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/movenok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletefok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletefnok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletelok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletelnok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/encourage": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/discourage": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/prioritylanguages": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/associate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/dissociate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"translationreview/message": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"translationreview/group": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagelang/pagelang": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"renameuser/renameuser": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "📛"
|
||||||
|
},
|
||||||
|
"suppressed": {
|
||||||
|
"icon": "https://i.imgur.com/1gps6EZ.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"discussion": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/post": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/reply": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/poll": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/quiz": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/wall/post": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 3752525,
|
||||||
|
"emoji": "✉️"
|
||||||
|
},
|
||||||
|
"discussion/wall/reply": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 3752525,
|
||||||
|
"emoji": "📩"
|
||||||
|
},
|
||||||
|
"discussion/comment/post": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 10802,
|
||||||
|
"emoji": "🗒️"
|
||||||
|
},
|
||||||
|
"discussion/comment/reply": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 10802,
|
||||||
|
"emoji": "🗒️"
|
||||||
|
},
|
||||||
|
"unknown": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 0,
|
||||||
|
"emoji": "❓"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
557
test/mockserver/configs/settings2.json
Normal file
557
test/mockserver/configs/settings2.json
Normal file
|
@ -0,0 +1,557 @@
|
||||||
|
{
|
||||||
|
"cooldown": 30,
|
||||||
|
"wiki_url": "http://localhost:8080/",
|
||||||
|
"rc_enabled": true,
|
||||||
|
"lang": "en",
|
||||||
|
"header": {
|
||||||
|
"user-agent": "RcGcDw/{version}"
|
||||||
|
},
|
||||||
|
"limit": 15,
|
||||||
|
"webhookURL": "http://localhost:8080/webhook/",
|
||||||
|
"limitrefetch": 15,
|
||||||
|
"wikiname": "Testing Connection",
|
||||||
|
"avatars": {
|
||||||
|
"connection_failed": "https://i.imgur.com/2jWQEt1.png",
|
||||||
|
"connection_restored": "",
|
||||||
|
"no_event": "",
|
||||||
|
"embed": "",
|
||||||
|
"compact": ""
|
||||||
|
},
|
||||||
|
"ignored": ["external", "newusers/create", "newusers/autocreate", "newusers/create2", "newusers/byemail", "newusers/newusers"],
|
||||||
|
"show_updown_messages": true,
|
||||||
|
"ignored_namespaces": [],
|
||||||
|
"extensions_dir": "extensions",
|
||||||
|
"error_tolerance": 2,
|
||||||
|
"overview": true,
|
||||||
|
"overview_time": "00:00",
|
||||||
|
"send_empty_overview": true,
|
||||||
|
"license_detection": false,
|
||||||
|
"license_regex_detect": "\\{\\{(license|lizenz|licence|copyright)",
|
||||||
|
"license_regex": "\\{\\{(license|lizenz|licence|copyright)(\\ |\\|)(?P<license>.*?)\\}\\}",
|
||||||
|
"disallow_regexes": ["{{version nav"],
|
||||||
|
"wiki_bot_login": "",
|
||||||
|
"wiki_bot_password": "",
|
||||||
|
"show_added_categories": false,
|
||||||
|
"show_bots": true,
|
||||||
|
"show_abuselog": false,
|
||||||
|
"hide_ips": true,
|
||||||
|
"discord_message_cooldown": 0,
|
||||||
|
"auto_suppression": {
|
||||||
|
"enabled": false,
|
||||||
|
"db_location": ":memory:"
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"version": 1,
|
||||||
|
"disable_existing_loggers": false,
|
||||||
|
"formatters": {
|
||||||
|
"standard": {
|
||||||
|
"format": "%(name)s - %(asctime)s - %(levelname)s: %(message)s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers": {
|
||||||
|
"default": {
|
||||||
|
"formatter": "standard",
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"stream": "ext://sys.stdout"
|
||||||
|
},
|
||||||
|
"filelogger": {
|
||||||
|
"formatter": "standard",
|
||||||
|
"class": "logging.FileHandler",
|
||||||
|
"filename": "rcgcdw.log",
|
||||||
|
"encoding": "utf-8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"loggers": {
|
||||||
|
"": {
|
||||||
|
"level": 0,
|
||||||
|
"handlers": ["default", "filelogger"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"appearance":{
|
||||||
|
"mode": "compact",
|
||||||
|
"embed": {
|
||||||
|
"show_edit_changes": true,
|
||||||
|
"show_footer": true,
|
||||||
|
"embed_images": true,
|
||||||
|
"show_no_description_provided": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fandom_discussions": {
|
||||||
|
"enabled": false,
|
||||||
|
"wiki_url": "",
|
||||||
|
"cooldown": 60,
|
||||||
|
"webhookURL": "",
|
||||||
|
"limit": 5,
|
||||||
|
"appearance": {
|
||||||
|
"mode": "embed",
|
||||||
|
"embed": {
|
||||||
|
"show_content": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"show_forums": []
|
||||||
|
},
|
||||||
|
"event_appearance": {
|
||||||
|
"daily_overview": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "",
|
||||||
|
"plot": true
|
||||||
|
},
|
||||||
|
"new": {
|
||||||
|
"icon": "https://i.imgur.com/6HIbEq8.png",
|
||||||
|
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
|
||||||
|
"emoji": "🆕"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"icon": "https://i.imgur.com/zKYHkJm.png",
|
||||||
|
"color": "THIS COLOR DEPENDS ON EDIT SIZE, PLEASE DON'T CHANGE",
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"upload/overwrite": {
|
||||||
|
"icon": "https://i.imgur.com/egJpa81.png",
|
||||||
|
"color": 12390624,
|
||||||
|
"emoji": "🖼️"
|
||||||
|
},
|
||||||
|
"upload/upload": {
|
||||||
|
"icon": "https://i.imgur.com/egJpa81.png",
|
||||||
|
"color": 12390624,
|
||||||
|
"emoji": "🖼️"
|
||||||
|
},
|
||||||
|
"upload/revert": {
|
||||||
|
"icon": "https://i.imgur.com/egJpa81.png",
|
||||||
|
"color": 12390624,
|
||||||
|
"emoji": "⏮️"
|
||||||
|
},
|
||||||
|
"delete/delete": {
|
||||||
|
"icon": "https://i.imgur.com/BU77GD3.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"delete/delete_redir": {
|
||||||
|
"icon": "https://i.imgur.com/BU77GD3.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"delete/restore": {
|
||||||
|
"icon": "https://i.imgur.com/9MnROIU.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "♻️"
|
||||||
|
},
|
||||||
|
"delete/revision": {
|
||||||
|
"icon": "https://i.imgur.com/1gps6EZ.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"delete/event": {
|
||||||
|
"icon": "https://i.imgur.com/1gps6EZ.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"merge/merge": {
|
||||||
|
"icon": "https://i.imgur.com/uQMK9XK.png",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "🖇️"
|
||||||
|
},
|
||||||
|
"move/move": {
|
||||||
|
"icon": "https://i.imgur.com/eXz9dog.png",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📨"
|
||||||
|
},
|
||||||
|
"move/move_redir": {
|
||||||
|
"icon": "https://i.imgur.com/UtC3YX2.png",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📨"
|
||||||
|
},
|
||||||
|
"block/block": {
|
||||||
|
"icon": "https://i.imgur.com/g7KgZHf.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🚫"
|
||||||
|
},
|
||||||
|
"block/unblock": {
|
||||||
|
"icon": "https://i.imgur.com/bvtBJ8o.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "✅"
|
||||||
|
},
|
||||||
|
"block/reblock": {
|
||||||
|
"icon": "https://i.imgur.com/g7KgZHf.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "🚫"
|
||||||
|
},
|
||||||
|
"protect/protect": {
|
||||||
|
"icon": "https://i.imgur.com/bzPt89Z.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔒"
|
||||||
|
},
|
||||||
|
"protect/modify": {
|
||||||
|
"icon": "https://i.imgur.com/bzPt89Z.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔐"
|
||||||
|
},
|
||||||
|
"protect/move_prot": {
|
||||||
|
"icon": "https://i.imgur.com/bzPt89Z.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔏"
|
||||||
|
},
|
||||||
|
"protect/unprotect": {
|
||||||
|
"icon": "https://i.imgur.com/2wN3Qcq.png",
|
||||||
|
"color": 16312092,
|
||||||
|
"emoji": "🔓"
|
||||||
|
},
|
||||||
|
"import/upload": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "📥"
|
||||||
|
},
|
||||||
|
"import/interwiki": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "📥"
|
||||||
|
},
|
||||||
|
"rights/rights": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🏅"
|
||||||
|
},
|
||||||
|
"rights/autopromote": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🏅"
|
||||||
|
},
|
||||||
|
"abusefilter/modify": {
|
||||||
|
"icon": "https://i.imgur.com/Sn2NzRJ.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔍"
|
||||||
|
},
|
||||||
|
"abusefilter/create": {
|
||||||
|
"icon": "https://i.imgur.com/Sn2NzRJ.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔍"
|
||||||
|
},
|
||||||
|
"interwiki/iw_add": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔗"
|
||||||
|
},
|
||||||
|
"interwiki/iw_edit": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔗"
|
||||||
|
},
|
||||||
|
"interwiki/iw_delete": {
|
||||||
|
"icon": "https://i.imgur.com/sFkhghb.png",
|
||||||
|
"color": 16711680,
|
||||||
|
"emoji": "🔗"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-created": {
|
||||||
|
"icon": "https://i.imgur.com/Lvy5E32.png",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "✉️"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-edited": {
|
||||||
|
"icon": "https://i.imgur.com/Lvy5E32.png",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "📧"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-deleted": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-purged":{
|
||||||
|
"icon":"",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"curseprofile/comment-replied": {
|
||||||
|
"icon": "https://i.imgur.com/hkyYsI1.png",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "📩"
|
||||||
|
},
|
||||||
|
"curseprofile/profile-edited": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16089376,
|
||||||
|
"emoji": "📌"
|
||||||
|
},
|
||||||
|
"contentmodel/change": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📋"
|
||||||
|
},
|
||||||
|
"contentmodel/new": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 25600,
|
||||||
|
"emoji": "📋"
|
||||||
|
},
|
||||||
|
"cargo/deletetable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"cargo/createtable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"cargo/replacetable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"cargo/recreatetable": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"sprite/sprite": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🪟"
|
||||||
|
},
|
||||||
|
"sprite/sheet": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🪟"
|
||||||
|
},
|
||||||
|
"sprite/slice": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🪟"
|
||||||
|
},
|
||||||
|
"managetags/create": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"managetags/delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"managetags/activate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"managetags/deactivate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 16776960,
|
||||||
|
"emoji": "🏷️"
|
||||||
|
},
|
||||||
|
"newusers/autocreate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/byemail": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/create": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/create2": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"newusers/newusers": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 65280,
|
||||||
|
"emoji": "🗿"
|
||||||
|
},
|
||||||
|
"managewiki/delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"managewiki/lock": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🔒"
|
||||||
|
},
|
||||||
|
"managewiki/namespaces": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "📦"
|
||||||
|
},
|
||||||
|
"managewiki/namespaces-delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"managewiki/rights": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🏅"
|
||||||
|
},
|
||||||
|
"managewiki/settings": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "⚙️"
|
||||||
|
},
|
||||||
|
"managewiki/undelete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "♻️"
|
||||||
|
},
|
||||||
|
"managewiki/unlock": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🔓"
|
||||||
|
},
|
||||||
|
"datadump/generate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "📤"
|
||||||
|
},
|
||||||
|
"datadump/delete": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🗑️"
|
||||||
|
},
|
||||||
|
"pagetranslation/mark": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/unmark": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/moveok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/movenok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletefok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletefnok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletelok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/deletelnok": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/encourage": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/discourage": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/prioritylanguages": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/associate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagetranslation/dissociate": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"translationreview/message": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"translationreview/group": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"pagelang/pagelang": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "🌐"
|
||||||
|
},
|
||||||
|
"renameuser/renameuser": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 8421504,
|
||||||
|
"emoji": "📛"
|
||||||
|
},
|
||||||
|
"suppressed": {
|
||||||
|
"icon": "https://i.imgur.com/1gps6EZ.png",
|
||||||
|
"color": 1,
|
||||||
|
"emoji": "👁️"
|
||||||
|
},
|
||||||
|
"discussion": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/post": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/reply": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/poll": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/forum/quiz": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 54998,
|
||||||
|
"emoji": "📝"
|
||||||
|
},
|
||||||
|
"discussion/wall/post": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 3752525,
|
||||||
|
"emoji": "✉️"
|
||||||
|
},
|
||||||
|
"discussion/wall/reply": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 3752525,
|
||||||
|
"emoji": "📩"
|
||||||
|
},
|
||||||
|
"discussion/comment/post": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 10802,
|
||||||
|
"emoji": "🗒️"
|
||||||
|
},
|
||||||
|
"discussion/comment/reply": {
|
||||||
|
"icon": "https://static.wikia.nocookie.net/663e53f7-1e79-4906-95a7-2c1df4ebbada",
|
||||||
|
"color": 10802,
|
||||||
|
"emoji": "🗒️"
|
||||||
|
},
|
||||||
|
"unknown": {
|
||||||
|
"icon": "",
|
||||||
|
"color": 0,
|
||||||
|
"emoji": "❓"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
test/mockserver/data/response_diff20748742075224.json
Normal file
5
test/mockserver/data/response_diff20748742075224.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"compare": {
|
||||||
|
"*": "<tr>\n <td colspan=\"2\" class=\"diff-lineno\">Line 8:</td>\n <td colspan=\"2\" class=\"diff-lineno\">Line 8:</td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| grasscolor = {{color|#8EB971}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| grasscolor = {{color|#8EB971}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| foliagecolor = {{color|#71A74D}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| foliagecolor = {{color|#71A74D}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n</tr>\n<tr>\n <td colspan=\"2\" class=\"diff-empty\"> </td>\n <td class=\"diff-marker\">+</td>\n <td class=\"diff-addedline\"><div>| waterc</div></td>\n</tr>\n<tr>\n <td class=\"diff-marker\">−</td>\n <td class=\"diff-deletedline\"><div>| watercolor = {{color|#3F76E4}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n <td colspan=\"2\" class=\"diff-empty\"> </td>\n</tr>\n<tr>\n <td class=\"diff-marker\">−</td>\n <td class=\"diff-deletedline\"><div><del class=\"diffchange diffchange-inline\">| structures ={{EnvLink|Dungeon</del>}}<del class=\"diffchange diffchange-inline\">s</del><br>{{<del class=\"diffchange diffchange-inline\">EnvLink</del>|<del class=\"diffchange diffchange-inline\">Mineshaft</del>}}<del class=\"diffchange diffchange-inline\">s</del><br>{{<del class=\"diffchange diffchange-inline\">EnvLink</del>|<del class=\"diffchange diffchange-inline\">Stronghold</del>}}<del class=\"diffchange diffchange-inline\">s</del><br>{{<del class=\"diffchange diffchange-inline\">EnvLink</del>|<del class=\"diffchange diffchange-inline\">Amethyst</del> <del class=\"diffchange diffchange-inline\">Geode</del>}}<del class=\"diffchange diffchange-inline\">s</del></div></td>\n <td class=\"diff-marker\">+</td>\n <td class=\"diff-addedline\"><div><ins class=\"diffchange diffchange-inline\">Dripleaf</ins>}}<br>{{<ins class=\"diffchange diffchange-inline\">BlockLink</ins>|<ins class=\"diffchange diffchange-inline\">Cave Vines</ins>}}<br>{{<ins class=\"diffchange diffchange-inline\">BlockLink</ins>|<ins class=\"diffchange diffchange-inline\">Spore Blossom</ins>}}<br>{{<ins class=\"diffchange diffchange-inline\">ItemLink</ins>|<ins class=\"diffchange diffchange-inline\">Glow</ins> <ins class=\"diffchange diffchange-inline\">Berries}}</ins>}}</div></td>\n</tr>\n<tr>\n <td class=\"diff-marker\">−</td>\n <td class=\"diff-deletedline\"><div>| blocks = {{BlockLink|Oak Log}}<br>{{BlockLink|Azalea Leaves}}<br>{{BlockLink|Flowering Azalea Leaves}}<br>{{BlockLink|Azalea}}<br>{{BlockLink|Flowering Azalea}}<br>{{BlockLink|Rooted Dirt}}<br>{{BlockLink|Hanging Roots}}<br>{{BlockLink|Moss Block}}<br>{{BlockLink|Moss Carpet}}<br>{{BlockLink|Grass}}<br>{{BlockLink|Tall Grass}}<br>{{BlockLink|Vines}}<br>{{BlockLink|Water}}<br>{{BlockLink|Clay}}<br>{{BlockLink|Small Dripleaf}}<br>{{BlockLink|Big Dripleaf}}<br>{{BlockLink|Cave Vines}}<br>{{BlockLink|Spore Blossom}}<br>{{ItemLink|Glow Berries}}}}</div></td>\n <td colspan=\"2\" class=\"diff-empty\"> </td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"></td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>A '''lush cave''' is a temperate [[Overworld]] [[cave]] [[biome]] that has a unique fauna and flora and is found underground below [[azalea tree]]s.</div></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>A '''lush cave''' is a temperate [[Overworld]] [[cave]] [[biome]] that has a unique fauna and flora and is found underground below [[azalea tree]]s.</div></td>\n</tr>\n\n<!-- diff cache key prod:minecraft_gamepedia:diff:wikidiff2:1.12:old-2075454:rev-2076789:1.11.0:0 -->\n"
|
||||||
|
}
|
||||||
|
}
|
5
test/mockserver/data/response_diff20752242075225.json
Normal file
5
test/mockserver/data/response_diff20752242075225.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"compare": {
|
||||||
|
"*": "<tr>\n <td colspan=\"2\" class=\"diff-lineno\">Line 8:</td>\n <td colspan=\"2\" class=\"diff-lineno\">Line 8:</td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| grasscolor = {{color|#8EB971}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| grasscolor = {{color|#8EB971}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| foliagecolor = {{color|#71A74D}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>| foliagecolor = {{color|#71A74D}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n</tr>\n<tr>\n <td colspan=\"2\" class=\"diff-empty\"> </td>\n <td class=\"diff-marker\">+</td>\n <td class=\"diff-addedline\"><div>| watercolor = {{color|#3F76E4}}{{only|java|short=y}}<br>{{Check the code}}{{only|bedrock|short=y}}</div></td>\n</tr>\n<tr>\n <td class=\"diff-marker\">−</td>\n <td class=\"diff-deletedline\"><div>| waterc</div></td>\n <td colspan=\"2\" class=\"diff-empty\"> </td>\n</tr>\n<tr>\n <td class=\"diff-marker\">−</td>\n <td class=\"diff-deletedline\"><div><del class=\"diffchange diffchange-inline\">Dripleaf</del>}}<br>{{<del class=\"diffchange diffchange-inline\">BlockLink</del>|<del class=\"diffchange diffchange-inline\">Cave Vines</del>}}<br>{{<del class=\"diffchange diffchange-inline\">BlockLink</del>|<del class=\"diffchange diffchange-inline\">Spore Blossom</del>}}<br>{{<del class=\"diffchange diffchange-inline\">ItemLink</del>|<del class=\"diffchange diffchange-inline\">Glow</del> <del class=\"diffchange diffchange-inline\">Berries}}</del>}}</div></td>\n <td class=\"diff-marker\">+</td>\n <td class=\"diff-addedline\"><div><ins class=\"diffchange diffchange-inline\">| structures ={{EnvLink|Dungeon</ins>}}<ins class=\"diffchange diffchange-inline\">s</ins><br>{{<ins class=\"diffchange diffchange-inline\">EnvLink</ins>|<ins class=\"diffchange diffchange-inline\">Mineshaft</ins>}}<ins class=\"diffchange diffchange-inline\">s</ins><br>{{<ins class=\"diffchange diffchange-inline\">EnvLink</ins>|<ins class=\"diffchange diffchange-inline\">Stronghold</ins>}}<ins class=\"diffchange diffchange-inline\">s</ins><br>{{<ins class=\"diffchange diffchange-inline\">EnvLink</ins>|<ins class=\"diffchange diffchange-inline\">Amethyst</ins> <ins class=\"diffchange diffchange-inline\">Geode</ins>}}<ins class=\"diffchange diffchange-inline\">s</ins></div></td>\n</tr>\n<tr>\n <td colspan=\"2\" class=\"diff-empty\"> </td>\n <td class=\"diff-marker\">+</td>\n <td class=\"diff-addedline\"><div>| blocks = {{BlockLink|Oak Log}}<br>{{BlockLink|Azalea Leaves}}<br>{{BlockLink|Flowering Azalea Leaves}}<br>{{BlockLink|Azalea}}<br>{{BlockLink|Flowering Azalea}}<br>{{BlockLink|Rooted Dirt}}<br>{{BlockLink|Hanging Roots}}<br>{{BlockLink|Moss Block}}<br>{{BlockLink|Moss Carpet}}<br>{{BlockLink|Grass}}<br>{{BlockLink|Tall Grass}}<br>{{BlockLink|Vines}}<br>{{BlockLink|Water}}<br>{{BlockLink|Clay}}<br>{{BlockLink|Small Dripleaf}}<br>{{BlockLink|Big Dripleaf}}<br>{{BlockLink|Cave Vines}}<br>{{BlockLink|Spore Blossom}}<br>{{ItemLink|Glow Berries}}}}</div></td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"></td>\n</tr>\n<tr>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>A '''lush cave''' is a temperate [[Overworld]] [[cave]] [[biome]] that has a unique fauna and flora and is found underground below [[azalea tree]]s.</div></td>\n <td class=\"diff-marker\"> </td>\n <td class=\"diff-context\"><div>A '''lush cave''' is a temperate [[Overworld]] [[cave]] [[biome]] that has a unique fauna and flora and is found underground below [[azalea tree]]s.</div></td>\n</tr>\n\n<!-- diff cache key prod:minecraft_gamepedia:diff:wikidiff2:1.12:old-2076789:rev-2076791:1.11.0:0 -->\n"
|
||||||
|
}
|
||||||
|
}
|
5
test/mockserver/data/response_diff20752302075231.json
Normal file
5
test/mockserver/data/response_diff20752302075231.json
Normal file
File diff suppressed because one or more lines are too long
5
test/mockserver/data/response_diff2325552075232.json
Normal file
5
test/mockserver/data/response_diff2325552075232.json
Normal file
File diff suppressed because one or more lines are too long
5
test/mockserver/data/response_diff2325562075234.json
Normal file
5
test/mockserver/data/response_diff2325562075234.json
Normal file
File diff suppressed because one or more lines are too long
14
test/mockserver/data/response_error.json
Normal file
14
test/mockserver/data/response_error.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "unknown_action",
|
||||||
|
"key": "apierror-unrecognizedvalue",
|
||||||
|
"params": [
|
||||||
|
"action",
|
||||||
|
"ddd"
|
||||||
|
],
|
||||||
|
"module": "main"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"*": "See https://localhost/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
|
||||||
|
}
|
32
test/mockserver/data/response_image.json
Normal file
32
test/mockserver/data/response_image.json
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"batchcomplete": "",
|
||||||
|
"query": {
|
||||||
|
"pages": {
|
||||||
|
"181124": {
|
||||||
|
"pageid": 181124,
|
||||||
|
"ns": 6,
|
||||||
|
"title": "File:Oak Sign (9).png",
|
||||||
|
"imagerepository": "local",
|
||||||
|
"imageinfo": [
|
||||||
|
{
|
||||||
|
"timestamp": "2021-12-26T12:09:04Z",
|
||||||
|
"url": "http://localhost:8080/test_wiki/images/7/75/Oak_Sign_%289%29.png/revision/latest?cb=20211226120904",
|
||||||
|
"descriptionurl": "http://localhost:8080/wiki/File:Oak_Sign_(9).png",
|
||||||
|
"descriptionshorturl": "http://localhost:8080/index.php?curid=181124"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"revisions": [
|
||||||
|
{
|
||||||
|
"slots": {
|
||||||
|
"main": {
|
||||||
|
"contentmodel": "wikitext",
|
||||||
|
"contentformat": "text/x-wiki",
|
||||||
|
"*": "\n== License ==\n{{License Mojang}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
461
test/mockserver/data/response_init.json
Normal file
461
test/mockserver/data/response_init.json
Normal file
|
@ -0,0 +1,461 @@
|
||||||
|
{
|
||||||
|
"batchcomplete": "",
|
||||||
|
"limits": {
|
||||||
|
"tags": 5000
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "abusefilter-condition-limit",
|
||||||
|
"displayname": "condition limit reached"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "added youtube video",
|
||||||
|
"displayname": "contains YouTube embed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "advanced mobile edit",
|
||||||
|
"displayname": "Advanced mobile edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "character-spam",
|
||||||
|
"displayname": "Character spam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deletiontemplate-addition",
|
||||||
|
"displayname": "Requested deletion"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "maps-visual-edit",
|
||||||
|
"displayname": "Visual map edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "missing signature",
|
||||||
|
"displayname": "missing signature"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mobile edit",
|
||||||
|
"displayname": "Mobile edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mobile web edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mobile-edit",
|
||||||
|
"displayname": "Mobile edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "move",
|
||||||
|
"displayname": "move"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-blank",
|
||||||
|
"displayname": "Blanking"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-changed-redirect-target",
|
||||||
|
"displayname": "Redirect target changed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-contentmodelchange",
|
||||||
|
"displayname": "content model change"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-new-redirect",
|
||||||
|
"displayname": "New redirect"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-removed-redirect",
|
||||||
|
"displayname": "Removed redirect"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-replace",
|
||||||
|
"displayname": "Replaced"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-rollback",
|
||||||
|
"displayname": "Rollback"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mw-undo",
|
||||||
|
"displayname": "Undo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "possible-number-spam",
|
||||||
|
"displayname": "possible-number-spam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "section blanking",
|
||||||
|
"displayname": "section blanked"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "spriteeditor",
|
||||||
|
"displayname": "<a href=\"/wiki/Help:Sprite_editor\" title=\"Help:Sprite editor\">Sprite edit</a>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test",
|
||||||
|
"displayname": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tor",
|
||||||
|
"displayname": "Made through Tor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "visualeditor",
|
||||||
|
"displayname": "Visual edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "visualeditor-needcheck",
|
||||||
|
"displayname": "Visual edit: Check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "visualeditor-switched",
|
||||||
|
"displayname": "<a href=\"/wiki/Minecraft_Wiki:VisualEditor\" title=\"Minecraft Wiki:VisualEditor\">Partial visual edit</a>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 0,
|
||||||
|
"displayname": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "visualeditor-wikitext",
|
||||||
|
"displayname": "2017 source edit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 1,
|
||||||
|
"displayname": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 2,
|
||||||
|
"displayname": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": 3,
|
||||||
|
"displayname": "3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"allmessages": [
|
||||||
|
{
|
||||||
|
"name": "recentchanges-page-added-to-category",
|
||||||
|
"normalizedname": "recentchanges-page-added-to-category",
|
||||||
|
"*": "[[:$1]] added to category"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "recentchanges-page-removed-from-category",
|
||||||
|
"normalizedname": "recentchanges-page-removed-from-category",
|
||||||
|
"*": "[[:$1]] removed from category"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "recentchanges-page-added-to-category-bundled",
|
||||||
|
"normalizedname": "recentchanges-page-added-to-category-bundled",
|
||||||
|
"*": "[[:$1]] added to category, [[Special:WhatLinksHere/$1|this page is included within other pages]]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "recentchanges-page-removed-from-category-bundled",
|
||||||
|
"normalizedname": "recentchanges-page-removed-from-category-bundled",
|
||||||
|
"*": "[[:$1]] removed from category, [[Special:WhatLinksHere/$1|this page is included within other pages]]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"namespaces": {
|
||||||
|
"0": {
|
||||||
|
"id": 0,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"content": "",
|
||||||
|
"*": ""
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"id": 1,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Talk",
|
||||||
|
"*": "Talk"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"id": 2,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "User",
|
||||||
|
"*": "User"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"id": 3,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "User talk",
|
||||||
|
"*": "User talk"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"id": 4,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Project",
|
||||||
|
"*": "Minecraft Wiki"
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"id": 5,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Project talk",
|
||||||
|
"*": "Minecraft Wiki talk"
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"id": 6,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "File",
|
||||||
|
"*": "File"
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"id": 7,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "File talk",
|
||||||
|
"*": "File talk"
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"id": 8,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "MediaWiki",
|
||||||
|
"*": "MediaWiki"
|
||||||
|
},
|
||||||
|
"9": {
|
||||||
|
"id": 9,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "MediaWiki talk",
|
||||||
|
"*": "MediaWiki talk"
|
||||||
|
},
|
||||||
|
"10": {
|
||||||
|
"id": 10,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Template",
|
||||||
|
"*": "Template"
|
||||||
|
},
|
||||||
|
"11": {
|
||||||
|
"id": 11,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Template talk",
|
||||||
|
"*": "Template talk"
|
||||||
|
},
|
||||||
|
"12": {
|
||||||
|
"id": 12,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Help",
|
||||||
|
"*": "Help"
|
||||||
|
},
|
||||||
|
"13": {
|
||||||
|
"id": 13,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Help talk",
|
||||||
|
"*": "Help talk"
|
||||||
|
},
|
||||||
|
"14": {
|
||||||
|
"id": 14,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Category",
|
||||||
|
"*": "Category"
|
||||||
|
},
|
||||||
|
"15": {
|
||||||
|
"id": 15,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Category talk",
|
||||||
|
"*": "Category talk"
|
||||||
|
},
|
||||||
|
"110": {
|
||||||
|
"id": 110,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Forum",
|
||||||
|
"*": "Forum"
|
||||||
|
},
|
||||||
|
"111": {
|
||||||
|
"id": 111,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Forum talk",
|
||||||
|
"*": "Forum talk"
|
||||||
|
},
|
||||||
|
"202": {
|
||||||
|
"id": 202,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "UserProfile",
|
||||||
|
"*": "UserProfile"
|
||||||
|
},
|
||||||
|
"274": {
|
||||||
|
"id": 274,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Widget",
|
||||||
|
"*": "Widget"
|
||||||
|
},
|
||||||
|
"275": {
|
||||||
|
"id": 275,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Widget talk",
|
||||||
|
"*": "Widget talk"
|
||||||
|
},
|
||||||
|
"420": {
|
||||||
|
"id": 420,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "GeoJson",
|
||||||
|
"content": "",
|
||||||
|
"defaultcontentmodel": "GeoJson",
|
||||||
|
"*": "GeoJson"
|
||||||
|
},
|
||||||
|
"421": {
|
||||||
|
"id": 421,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "GeoJson talk",
|
||||||
|
"defaultcontentmodel": "wikitext",
|
||||||
|
"*": "GeoJson talk"
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"id": 500,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "User blog",
|
||||||
|
"*": "User blog"
|
||||||
|
},
|
||||||
|
"501": {
|
||||||
|
"id": 501,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "User blog comment",
|
||||||
|
"*": "User blog comment"
|
||||||
|
},
|
||||||
|
"502": {
|
||||||
|
"id": 502,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Blog",
|
||||||
|
"*": "Blog"
|
||||||
|
},
|
||||||
|
"503": {
|
||||||
|
"id": 503,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Blog talk",
|
||||||
|
"*": "Blog talk"
|
||||||
|
},
|
||||||
|
"828": {
|
||||||
|
"id": 828,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Module",
|
||||||
|
"*": "Module"
|
||||||
|
},
|
||||||
|
"829": {
|
||||||
|
"id": 829,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Module talk",
|
||||||
|
"*": "Module talk"
|
||||||
|
},
|
||||||
|
"1200": {
|
||||||
|
"id": 1200,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Message Wall",
|
||||||
|
"*": "Message Wall"
|
||||||
|
},
|
||||||
|
"1201": {
|
||||||
|
"id": 1201,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Thread",
|
||||||
|
"*": "Thread"
|
||||||
|
},
|
||||||
|
"1202": {
|
||||||
|
"id": 1202,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Message Wall Greeting",
|
||||||
|
"*": "Message Wall Greeting"
|
||||||
|
},
|
||||||
|
"2300": {
|
||||||
|
"id": 2300,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Gadget",
|
||||||
|
"*": "Gadget"
|
||||||
|
},
|
||||||
|
"2301": {
|
||||||
|
"id": 2301,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Gadget talk",
|
||||||
|
"*": "Gadget talk"
|
||||||
|
},
|
||||||
|
"2302": {
|
||||||
|
"id": 2302,
|
||||||
|
"case": "case-sensitive",
|
||||||
|
"canonical": "Gadget definition",
|
||||||
|
"defaultcontentmodel": "GadgetDefinition",
|
||||||
|
"*": "Gadget definition"
|
||||||
|
},
|
||||||
|
"2303": {
|
||||||
|
"id": 2303,
|
||||||
|
"case": "case-sensitive",
|
||||||
|
"canonical": "Gadget definition talk",
|
||||||
|
"*": "Gadget definition talk"
|
||||||
|
},
|
||||||
|
"10000": {
|
||||||
|
"id": 10000,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Minecraft Dungeons",
|
||||||
|
"content": "",
|
||||||
|
"*": "Minecraft Dungeons"
|
||||||
|
},
|
||||||
|
"10001": {
|
||||||
|
"id": 10001,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Minecraft Dungeons talk",
|
||||||
|
"*": "Minecraft Dungeons talk"
|
||||||
|
},
|
||||||
|
"10002": {
|
||||||
|
"id": 10002,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Minecraft Earth",
|
||||||
|
"content": "",
|
||||||
|
"*": "Minecraft Earth"
|
||||||
|
},
|
||||||
|
"10003": {
|
||||||
|
"id": 10003,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Minecraft Earth talk",
|
||||||
|
"*": "Minecraft Earth talk"
|
||||||
|
},
|
||||||
|
"10004": {
|
||||||
|
"id": 10004,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Minecraft Story Mode",
|
||||||
|
"content": "",
|
||||||
|
"*": "Minecraft Story Mode"
|
||||||
|
},
|
||||||
|
"10005": {
|
||||||
|
"id": 10005,
|
||||||
|
"case": "first-letter",
|
||||||
|
"subpages": "",
|
||||||
|
"canonical": "Minecraft Story Mode talk",
|
||||||
|
"*": "Minecraft Story Mode talk"
|
||||||
|
},
|
||||||
|
"-2": {
|
||||||
|
"id": -2,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Media",
|
||||||
|
"*": "Media"
|
||||||
|
},
|
||||||
|
"-1": {
|
||||||
|
"id": -1,
|
||||||
|
"case": "first-letter",
|
||||||
|
"canonical": "Special",
|
||||||
|
"*": "Special"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
209
test/mockserver/data/response_recentchanges.json
Normal file
209
test/mockserver/data/response_recentchanges.json
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
{
|
||||||
|
"batchcomplete": "",
|
||||||
|
"continue": {
|
||||||
|
"rccontinue": "20211226120903|2793420",
|
||||||
|
"continue": "-||"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"recentchanges": [
|
||||||
|
{
|
||||||
|
"type": "edit",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Some different page",
|
||||||
|
"pageid": 9327,
|
||||||
|
"revid": 2075232,
|
||||||
|
"old_revid": 232555,
|
||||||
|
"rcid": 2793437,
|
||||||
|
"user": "User3",
|
||||||
|
"oldlen": 32882,
|
||||||
|
"newlen": 328,
|
||||||
|
"timestamp": "2021-12-26T12:26:32Z",
|
||||||
|
"parsedcomment": "Some changes lol",
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "edit",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Java Edition 1.19",
|
||||||
|
"pageid": 177589,
|
||||||
|
"revid": 2075231,
|
||||||
|
"old_revid": 2075230,
|
||||||
|
"rcid": 2793436,
|
||||||
|
"user": "User2",
|
||||||
|
"minor": "",
|
||||||
|
"oldlen": 811,
|
||||||
|
"newlen": 771,
|
||||||
|
"timestamp": "2021-12-26T12:24:23Z",
|
||||||
|
"parsedcomment": "Revert edits by <a href=\"/wiki/Special:Contributions/192.168.1.1\" title=\"Special:Contributions/192.168.1.1\">192.168.1.1</a> (<span class=\"new\" title=\"User talk:192.168.1.1 (page does not exist)\">talk</span>)",
|
||||||
|
"tags": [
|
||||||
|
"mw-rollback"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"ns": 2,
|
||||||
|
"title": "User:FineUser2",
|
||||||
|
"pageid": 72216,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793427,
|
||||||
|
"user": "Administrator2",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T12:40:00Z",
|
||||||
|
"parsedcomment": "",
|
||||||
|
"logid": 1141234,
|
||||||
|
"logtype": "rights",
|
||||||
|
"logaction": "rights",
|
||||||
|
"logparams": {
|
||||||
|
"oldgroups": [
|
||||||
|
"autopatrol",
|
||||||
|
"rollback"
|
||||||
|
],
|
||||||
|
"newgroups": [
|
||||||
|
"sysop"
|
||||||
|
],
|
||||||
|
"oldmetadata": [
|
||||||
|
{
|
||||||
|
"group": "autopatrol",
|
||||||
|
"expiry": "infinity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "rollback",
|
||||||
|
"expiry": "infinity"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"newmetadata": [
|
||||||
|
{
|
||||||
|
"group": "sysop",
|
||||||
|
"expiry": "infinity"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"ns": 202,
|
||||||
|
"title": "UserProfile:User2",
|
||||||
|
"pageid": 0,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793426,
|
||||||
|
"user": "User2",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T12:20:11Z",
|
||||||
|
"parsedcomment": "CoolUser#1812",
|
||||||
|
"logid": 1141233,
|
||||||
|
"logtype": "curseprofile",
|
||||||
|
"logaction": "profile-edited",
|
||||||
|
"logparams": {
|
||||||
|
"4:section": "profile-link-discord"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"ns": 2,
|
||||||
|
"title": "User:Spammer",
|
||||||
|
"pageid": 0,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793425,
|
||||||
|
"user": "Administrator",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T12:15:04Z",
|
||||||
|
"parsedcomment": "<a href=\"/wiki/Best_Wiki:Wiki_rules/v3#2\" class=\"mw-redirect\" title=\"Best_Wiki:Wiki rules/v3\">Rule #2</a>: Spam",
|
||||||
|
"logid": 1141231,
|
||||||
|
"logtype": "block",
|
||||||
|
"logaction": "block",
|
||||||
|
"logparams": {
|
||||||
|
"duration": "2 weeks",
|
||||||
|
"flags": [
|
||||||
|
"nocreate"
|
||||||
|
],
|
||||||
|
"sitewide": "",
|
||||||
|
"expiry": "2022-01-11T10:38:23Z"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "edit",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Java Edition 1.19",
|
||||||
|
"pageid": 177589,
|
||||||
|
"revid": 2075225,
|
||||||
|
"old_revid": 2075224,
|
||||||
|
"rcid": 2793424,
|
||||||
|
"user": "Good User",
|
||||||
|
"anon": "",
|
||||||
|
"oldlen": 771,
|
||||||
|
"newlen": 811,
|
||||||
|
"timestamp": "2021-12-26T12:13:38Z",
|
||||||
|
"parsedcomment": "Undo revision by 192.168.1.1. Reason: Mad cats",
|
||||||
|
"tags": [
|
||||||
|
"visualeditor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "edit",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Java Edition 1.19",
|
||||||
|
"pageid": 177589,
|
||||||
|
"revid": 2075224,
|
||||||
|
"old_revid": 2074874,
|
||||||
|
"rcid": 2793423,
|
||||||
|
"user": "192.168.1.1",
|
||||||
|
"anon": "",
|
||||||
|
"oldlen": 811,
|
||||||
|
"newlen": 771,
|
||||||
|
"timestamp": "2021-12-26T12:09:18Z",
|
||||||
|
"parsedcomment": "Hahahahhaha, you will never understand my genius!",
|
||||||
|
"tags": [
|
||||||
|
"mobile edit",
|
||||||
|
"mobile web edit",
|
||||||
|
"visualeditor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "categorize",
|
||||||
|
"ns": 14,
|
||||||
|
"title": "Category:Mojang images",
|
||||||
|
"pageid": 181124,
|
||||||
|
"revid": 2075223,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793422,
|
||||||
|
"user": "User1",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T12:09:04Z",
|
||||||
|
"parsedcomment": "<a href=\"/wiki/File:Oak_Sign_(9).png\" title=\"File:Oak Sign (9).png\">File:Oak Sign (9).png</a> added to category",
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"ns": 6,
|
||||||
|
"title": "File:Oak Sign (9).png",
|
||||||
|
"pageid": 181124,
|
||||||
|
"revid": 2075223,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793421,
|
||||||
|
"user": "User1",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T12:09:04Z",
|
||||||
|
"parsedcomment": "",
|
||||||
|
"logid": 1141230,
|
||||||
|
"logtype": "upload",
|
||||||
|
"logaction": "upload",
|
||||||
|
"logparams": {
|
||||||
|
"img_sha1": "l9vzs83denqnn2ph8wya6ieue6b7tvo",
|
||||||
|
"img_timestamp": "2021-12-26T12:09:04Z"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
78
test/mockserver/data/response_recentchanges2.json
Normal file
78
test/mockserver/data/response_recentchanges2.json
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
"batchcomplete": "",
|
||||||
|
"continue": {
|
||||||
|
"rccontinue": "20211226120903|2793420",
|
||||||
|
"continue": "-||"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"recentchanges": [
|
||||||
|
{
|
||||||
|
"type": "edit",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Unique page",
|
||||||
|
"pageid": 9327,
|
||||||
|
"revid": 2075234,
|
||||||
|
"old_revid": 232556,
|
||||||
|
"rcid": 2793440,
|
||||||
|
"user": "User3",
|
||||||
|
"oldlen": 328,
|
||||||
|
"newlen": 32882,
|
||||||
|
"timestamp": "2021-12-26T13:37:10Z",
|
||||||
|
"parsedcomment": "Added content",
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Some different page",
|
||||||
|
"pageid": 9327,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793439,
|
||||||
|
"user": "Frisk",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T13:35:50Z",
|
||||||
|
"parsedcomment": "aaaaaaaaaaaaaaa",
|
||||||
|
"logid": 1141236,
|
||||||
|
"logtype": "delete",
|
||||||
|
"logaction": "delete",
|
||||||
|
"logparams": {},
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"ns": 0,
|
||||||
|
"title": "Java Edition 1.19",
|
||||||
|
"pageid": 177589,
|
||||||
|
"revid": 0,
|
||||||
|
"old_revid": 0,
|
||||||
|
"rcid": 2793438,
|
||||||
|
"user": "Frisk",
|
||||||
|
"oldlen": 0,
|
||||||
|
"newlen": 0,
|
||||||
|
"timestamp": "2021-12-26T13:02:59Z",
|
||||||
|
"parsedcomment": "Heresy!",
|
||||||
|
"logid": 1141235,
|
||||||
|
"logtype": "delete",
|
||||||
|
"logaction": "revision",
|
||||||
|
"logparams": {
|
||||||
|
"type": "revision",
|
||||||
|
"ids": [
|
||||||
|
"2075224"
|
||||||
|
],
|
||||||
|
"old": {
|
||||||
|
"bitmask": 0
|
||||||
|
},
|
||||||
|
"new": {
|
||||||
|
"bitmask": 7,
|
||||||
|
"content": "",
|
||||||
|
"comment": "",
|
||||||
|
"user": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
98
test/mockserver/data/response_siteinfo.json
Normal file
98
test/mockserver/data/response_siteinfo.json
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"batchcomplete": "",
|
||||||
|
"query": {
|
||||||
|
"general": {
|
||||||
|
"mainpage": "Random Wiki",
|
||||||
|
"base": "https://localhost:8080/wiki/Mainpage",
|
||||||
|
"sitename": "Minecraft Wiki",
|
||||||
|
"logo": "https://localhost:8080/localhost/images/b/bc/Wiki.png",
|
||||||
|
"generator": "MediaWiki 1.35.3",
|
||||||
|
"phpversion": "7.3.32",
|
||||||
|
"phpsapi": "fpm-fcgi",
|
||||||
|
"dbtype": "mysql",
|
||||||
|
"dbversion": "5.7.25-28-log",
|
||||||
|
"externalimages": [],
|
||||||
|
"langconversion": "",
|
||||||
|
"titleconversion": "",
|
||||||
|
"linkprefixcharset": "",
|
||||||
|
"linkprefix": "",
|
||||||
|
"linktrail": "/^([a-z]+)(.*)$/sD",
|
||||||
|
"legaltitlechars": " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+",
|
||||||
|
"invalidusernamechars": "@:",
|
||||||
|
"fixarabicunicode": "",
|
||||||
|
"fixmalayalamunicode": "",
|
||||||
|
"case": "first-letter",
|
||||||
|
"lang": "en",
|
||||||
|
"fallback": [],
|
||||||
|
"fallback8bitEncoding": "windows-1252",
|
||||||
|
"writeapi": "",
|
||||||
|
"maxarticlesize": 2097152,
|
||||||
|
"timezone": "UTC",
|
||||||
|
"timeoffset": 0,
|
||||||
|
"articlepath": "/wiki/$1",
|
||||||
|
"scriptpath": "",
|
||||||
|
"script": "/index.php",
|
||||||
|
"variantarticlepath": false,
|
||||||
|
"server": "https://localhost:8080",
|
||||||
|
"servername": "localhost:8080",
|
||||||
|
"wikiid": "localhost",
|
||||||
|
"time": "2021-12-26T21:57:13Z",
|
||||||
|
"misermode": "",
|
||||||
|
"uploadsenabled": "",
|
||||||
|
"maxuploadsize": 10485760,
|
||||||
|
"minuploadchunksize": 1024,
|
||||||
|
"galleryoptions": {
|
||||||
|
"imagesPerRow": 0,
|
||||||
|
"imageWidth": 120,
|
||||||
|
"imageHeight": 120,
|
||||||
|
"captionLength": "",
|
||||||
|
"showBytes": "",
|
||||||
|
"showDimensions": "",
|
||||||
|
"mode": "traditional"
|
||||||
|
},
|
||||||
|
"thumblimits": [
|
||||||
|
120,
|
||||||
|
150,
|
||||||
|
180,
|
||||||
|
200,
|
||||||
|
250,
|
||||||
|
300
|
||||||
|
],
|
||||||
|
"imagelimits": [
|
||||||
|
{
|
||||||
|
"width": 320,
|
||||||
|
"height": 240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 640,
|
||||||
|
"height": 480
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 800,
|
||||||
|
"height": 600
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 1024,
|
||||||
|
"height": 768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"width": 1280,
|
||||||
|
"height": 1024
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"favicon": "https://localhost:8080/favicon.ico",
|
||||||
|
"centralidlookupprovider": "local",
|
||||||
|
"allcentralidlookupproviders": [
|
||||||
|
"local"
|
||||||
|
],
|
||||||
|
"interwikimagic": "",
|
||||||
|
"magiclinks": {
|
||||||
|
"ISBN": ""
|
||||||
|
},
|
||||||
|
"categorycollation": "uppercase",
|
||||||
|
"citeresponsivereferences": "",
|
||||||
|
"gamepedia": "true",
|
||||||
|
"mobileserver": "https://localhost:8080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
test/mockserver/data/response_userinfo.json
Normal file
22
test/mockserver/data/response_userinfo.json
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"batchcomplete": "",
|
||||||
|
"limits": {
|
||||||
|
"usercontribs": 5000
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"usercontribs": [
|
||||||
|
{
|
||||||
|
"userid": 0,
|
||||||
|
"user": "192.168.1.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userid": 0,
|
||||||
|
"user": "192.168.1.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"userid": 0,
|
||||||
|
"user": "192.168.1.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
1
test/mockserver/results/results1.json
Normal file
1
test/mockserver/results/results1.json
Normal file
File diff suppressed because one or more lines are too long
1
test/mockserver/results/results2.json
Normal file
1
test/mockserver/results/results2.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[{"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\uddbc\ufe0f [User1](<http://localhost:8080/wiki/User:User1>) uploaded [File\\:Oak Sign (9).png](<http://localhost:8080/wiki/File:Oak_Sign_%289%29.png>)"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udcdd [Unregistered user](<http://localhost:8080/wiki/User:192.168.1.1>) edited [Java Edition 1.19](<http://localhost:8080/index.php?title=Java_Edition_1.19&curid=177589&diff=2075224&oldid=2074874>) *(Hahahahhaha, you will never understand my genius!)* (-40)"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udcdd [Unregistered user](<http://localhost:8080/wiki/User:Good_User>) edited [Java Edition 1.19](<http://localhost:8080/index.php?title=Java_Edition_1.19&curid=177589&diff=2075225&oldid=2075224>) *(Undo revision by 192.168.1.1. Reason\\: Mad cats)* (+40)"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udeab [Administrator](<http://localhost:8080/wiki/User:Administrator>) blocked [Spammer](<http://localhost:8080/wiki/User:Spammer>) for 15 days, for 22 hours, for 23 minutes *([Rule #2](<http://localhost:8080/wiki/Best_Wiki:Wiki_rules/v3#2>)\\: Spam)*"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udccc [User2](<http://localhost:8080/wiki/User:User2>) edited the Discord handle on [their own](<http://localhost:8080/wiki/UserProfile:User2>) profile. *(CoolUser#1812)*"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83c\udfc5 [Administrator2](<http://localhost:8080/wiki/User:Administrator2>) changed group membership for [FineUser2](<http://localhost:8080/wiki/User:FineUser2>): Added to sysop and removed from autopatrol, rollback."}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udcdd [User2](<http://localhost:8080/wiki/User:User2>) edited [Java Edition 1.19](<http://localhost:8080/index.php?title=Java_Edition_1.19&curid=177589&diff=2075231&oldid=2075230>) *(Revert edits by [192.168.1.1](<http://localhost:8080/wiki/Special:Contributions/192.168.1.1>) (talk))* (-40)"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udcdd [User3](<http://localhost:8080/wiki/User:User3>) edited [Some different page](<http://localhost:8080/index.php?title=Some_different_page&curid=9327&diff=2075232&oldid=232555>) *(Some changes lol)* **(-32554)**"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udc41\ufe0f [Frisk](<http://localhost:8080/wiki/User:Frisk>) changed visibility of revision on page [Java Edition 1.19](<http://localhost:8080/wiki/Java_Edition_1.19>) *(Heresy!)*"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\uddd1\ufe0f [Frisk](<http://localhost:8080/wiki/User:Frisk>) deleted [Some different page](<http://localhost:8080/wiki/Some_different_page>) *(aaaaaaaaaaaaaaa)*"}, {"allowed_mentions": {"parse": []}, "avatar_url": "", "content": "\ud83d\udcdd [User3](<http://localhost:8080/wiki/User:User3>) edited [Unique page](<http://localhost:8080/index.php?title=Unique_page&curid=9327&diff=2075234&oldid=232556>) *(Added content)* **(+32554)**"}]
|
134
test/mockserver/server.py
Normal file
134
test/mockserver/server.py
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
import json
|
||||||
|
import urllib.parse
|
||||||
|
import requests
|
||||||
|
|
||||||
|
response_jsons: dict[str, dict] = {}
|
||||||
|
|
||||||
|
class EndOfContent(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def load_response(name: str):
|
||||||
|
with open("data/response_{}.json".format(name), "r") as response_file:
|
||||||
|
response_json: dict = json.loads(response_file.read())
|
||||||
|
response_jsons[name] = response_json
|
||||||
|
|
||||||
|
|
||||||
|
def get_response(name: str):
|
||||||
|
return response_jsons.get(name)
|
||||||
|
|
||||||
|
|
||||||
|
[load_response(x) for x in ["recentchanges", "recentchanges2", "init", "error", "siteinfo", "image", "userinfo"]]
|
||||||
|
|
||||||
|
|
||||||
|
messages_collector = []
|
||||||
|
askedfor = False
|
||||||
|
|
||||||
|
# Return server response based on some output from Minecraft Wiki
|
||||||
|
class MockServerRequestHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
global askedfor
|
||||||
|
# We assume testing will be for API endpoint only since RcGcDw doesn't do requests to other URLs so no need to check main path
|
||||||
|
# For simplicity, return a dictionary of query arguments, we assume duplicate keys will not appear
|
||||||
|
query = {k: y for (k, y) in urllib.parse.parse_qsl(self.path.split("?")[1])}
|
||||||
|
if query.get("action") == "query":
|
||||||
|
# Regular pooled query for recentchanges
|
||||||
|
if query.get("list") == "recentchanges":
|
||||||
|
self.send_essentials_ok()
|
||||||
|
if askedfor is False:
|
||||||
|
# Limit amount of events accordingly to required amount just in case
|
||||||
|
response_jsons["recentchanges"]["query"]["recentchanges"] = get_response("recentchanges")["query"]["recentchanges"][0:int(query.get("rclimit", 20))]
|
||||||
|
response_content = json.dumps(get_response("recentchanges"))
|
||||||
|
askedfor = True
|
||||||
|
else:
|
||||||
|
response_jsons["recentchanges2"]["query"]["recentchanges"] = get_response("recentchanges2")["query"]["recentchanges"][0:int(query.get("rclimit", 20))]
|
||||||
|
response_content = json.dumps(get_response("recentchanges2"))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
# Init info
|
||||||
|
elif query.get("list") == "tags" and query.get("meta") == "allmessages|siteinfo":
|
||||||
|
self.send_essentials_ok()
|
||||||
|
response_content = json.dumps(get_response("init"))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
elif query.get("meta") == "siteinfo":
|
||||||
|
self.send_essentials_ok()
|
||||||
|
response_content = json.dumps(get_response("siteinfo"))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
elif query.get("prop") == "imageinfo|revisions":
|
||||||
|
self.send_essentials_ok()
|
||||||
|
response_content = json.dumps(get_response("image"))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
elif query.get("list") == "usercontribs":
|
||||||
|
self.send_essentials_ok()
|
||||||
|
response_content = json.dumps(get_response("userinfo"))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
else:
|
||||||
|
self.send_response(400)
|
||||||
|
self.send_header('Content-Type', 'application/json; charset=utf-8')
|
||||||
|
self.end_headers()
|
||||||
|
response_content = json.dumps(get_response("error"))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
elif query.get("action") == "compare":
|
||||||
|
self.send_essentials_ok()
|
||||||
|
name = "diff{}{}".format(query.get("fromrev"), query.get("torev"))
|
||||||
|
load_response(name)
|
||||||
|
response_content = json.dumps(get_response(name))
|
||||||
|
self.wfile.write(response_content.encode('utf-8'))
|
||||||
|
|
||||||
|
def do_POST(self):
|
||||||
|
self.read_ok_collect(method="POST")
|
||||||
|
|
||||||
|
def do_PATCH(self):
|
||||||
|
self.read_ok_collect(method="PATCH")
|
||||||
|
|
||||||
|
def do_DELETE(self):
|
||||||
|
self.read_ok_collect(method="DELETE")
|
||||||
|
|
||||||
|
def read_ok_collect(self, method: str):
|
||||||
|
content_length = int(self.headers['Content-Length'])
|
||||||
|
patch_data = self.rfile.read(content_length)
|
||||||
|
if patch_data:
|
||||||
|
messages_collector.append(json.loads(patch_data.decode('utf-8')))
|
||||||
|
else:
|
||||||
|
messages_collector.append(method + self.path)
|
||||||
|
self.send_essentials_ok()
|
||||||
|
self.wfile.write(json.dumps({"id": len(messages_collector)}).encode('utf-8'))
|
||||||
|
|
||||||
|
def send_essentials_ok(self):
|
||||||
|
self.send_response(requests.codes.ok)
|
||||||
|
self.send_header('Content-Type', 'application/json; charset=utf-8')
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
|
||||||
|
def start_mock_server(port, config):
|
||||||
|
mock_server = HTTPServer(('localhost', port), MockServerRequestHandler)
|
||||||
|
try:
|
||||||
|
print("Server started successfully at http://localhost:{}".format(port))
|
||||||
|
while 1:
|
||||||
|
if (len(messages_collector) < 13 and config.config == 1) or (len(messages_collector) < 11 and config.config == 2):
|
||||||
|
mock_server.handle_request()
|
||||||
|
else:
|
||||||
|
raise EndOfContent
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Shutting down...")
|
||||||
|
except EndOfContent:
|
||||||
|
with open("results/results{}.json".format(config.config), "r") as proper_results:
|
||||||
|
if proper_results.read() == json.dumps(messages_collector):
|
||||||
|
print("Results are correct!")
|
||||||
|
else:
|
||||||
|
print("Results are incorrect, saving failed results to resultsfailed{}.json".format(config.config))
|
||||||
|
with open("results/resultsfailed{}.json".format(config.config), "w") as file_to_write:
|
||||||
|
file_to_write.write(json.dumps(messages_collector))
|
56
test/mockserver/start.py
Normal file
56
test/mockserver/start.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
|
||||||
|
import server
|
||||||
|
import pathlib
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Test RcGcDw with mocked data")
|
||||||
|
parser.add_argument("--config", type=int, default=1, help="Number of config to use while testing the mocked server (default=1). Number corresponds to files in configs/settings#.json")
|
||||||
|
parser.add_argument("--ignore-config", action='store_false', help="Ignore lack of existing config.json")
|
||||||
|
parser.add_argument("--no-client", action='store_true', help="Skip starting the client")
|
||||||
|
command_args = parser.parse_args()
|
||||||
|
|
||||||
|
# Backup old settings.json and copy from configs/settingsX.json to proper relative location
|
||||||
|
if not command_args.no_client:
|
||||||
|
new_settings = pathlib.Path(__file__).parent.absolute().joinpath("configs/settings{}.json".format(command_args.config))
|
||||||
|
old_config = pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve().joinpath("settings.json") # Should be root of RcGcDw
|
||||||
|
if not old_config.exists() and command_args.ignore_config:
|
||||||
|
print("Cannot find currently used settings.json! Exiting to prevent potential damage.")
|
||||||
|
sys.exit(2)
|
||||||
|
backup_filename = pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve().joinpath("settings.json.{}.bak".format(int(time.time())))
|
||||||
|
if backup_filename.exists():
|
||||||
|
print("Backup file under same name exists! Exiting.")
|
||||||
|
sys.exit(3)
|
||||||
|
shutil.move(old_config, backup_filename)
|
||||||
|
shutil.copy(new_settings, old_config)
|
||||||
|
# revert data file to some low number
|
||||||
|
with open(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve().joinpath("data.json"), "r") as data_file:
|
||||||
|
data_file_data = json.loads(data_file.read())
|
||||||
|
data_file_data["rcid"] = 5
|
||||||
|
with open(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve().joinpath("data.json"), "w") as data_file:
|
||||||
|
data_file.write(json.dumps(data_file_data, indent=4))
|
||||||
|
|
||||||
|
# Start mock server
|
||||||
|
server.start_mock_server(8080, command_args)
|
||||||
|
|
||||||
|
# Revert file changes
|
||||||
|
if not command_args.no_client:
|
||||||
|
shutil.copy(backup_filename, old_config)
|
39
test/test_11311_migration.py
Normal file
39
test/test_11311_migration.py
Normal file
File diff suppressed because one or more lines are too long
58
test/test_abusefilter.py
Normal file
58
test/test_abusefilter.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import json
|
||||||
|
from src.configloader import settings
|
||||||
|
from src.api.context import Context
|
||||||
|
from src.api.util import default_message
|
||||||
|
from src.api.hooks import formatter_hooks
|
||||||
|
from src.misc import WIKI_SCRIPT_PATH
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from unittest.mock import PropertyMock
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
def no_formatter(ctx: Context, change: dict) -> None:
|
||||||
|
raise NameError
|
||||||
|
|
||||||
|
|
||||||
|
inject_settings("appearance.mode", "embed")
|
||||||
|
importlib.import_module(settings.get('extensions_dir', 'extensions'), 'extensions')
|
||||||
|
formatter_hooks["no_formatter"] = no_formatter
|
||||||
|
with open("test/data/rc_objects.json", "r") as ob:
|
||||||
|
jsons = json.loads(ob.read())
|
||||||
|
with open("test/data/rc_results.json", "r") as ob:
|
||||||
|
results = json.loads(ob.read())
|
||||||
|
|
||||||
|
|
||||||
|
def get_objects(name: str):
|
||||||
|
return jsons.get(name), json.dumps(results.get(name))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMWFormatter(unittest.TestCase):
|
||||||
|
def test_abusefilter_embed(self):
|
||||||
|
test = default_message("abuselog", formatter_hooks)
|
||||||
|
ctx = PropertyMock()
|
||||||
|
ctx.message_type = "embed"
|
||||||
|
ctx.event_type = "abuselog"
|
||||||
|
ctx.event = "abuselog"
|
||||||
|
ctx.parsedcomment = ""
|
||||||
|
ctx.client.WIKI_SCRIPT_PATH = WIKI_SCRIPT_PATH
|
||||||
|
ctx.webhook_url = "https://example.com"
|
||||||
|
# ctx.client.return_value = Mock(spec=Client)
|
||||||
|
edit_c, results = get_objects("abuselog")
|
||||||
|
result = repr(test(ctx, edit_c))
|
||||||
|
self.assertEqual(results, result)
|
65
test/test_cargo.py
Normal file
65
test/test_cargo.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import json
|
||||||
|
from src.configloader import settings
|
||||||
|
from src.api.context import Context
|
||||||
|
from src.api.util import default_message
|
||||||
|
from src.api.hooks import formatter_hooks
|
||||||
|
from src.misc import WIKI_SCRIPT_PATH, LinkParser
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from unittest.mock import PropertyMock
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
def no_formatter(ctx: Context, change: dict) -> None:
|
||||||
|
raise NameError
|
||||||
|
|
||||||
|
|
||||||
|
inject_settings("appearance.mode", "embed")
|
||||||
|
importlib.import_module(settings.get('extensions_dir', 'extensions'), 'extensions')
|
||||||
|
formatter_hooks["no_formatter"] = no_formatter
|
||||||
|
with open("test/data/rc_objects.json", "r") as ob:
|
||||||
|
jsons = json.loads(ob.read())
|
||||||
|
with open("test/data/rc_results.json", "r") as ob:
|
||||||
|
results = json.loads(ob.read())
|
||||||
|
|
||||||
|
|
||||||
|
def get_objects(name: str):
|
||||||
|
return jsons.get(name), json.dumps(results.get(name))
|
||||||
|
|
||||||
|
|
||||||
|
def parse_links(summary: str):
|
||||||
|
link_parser = LinkParser()
|
||||||
|
link_parser.feed(summary)
|
||||||
|
return link_parser.new_string
|
||||||
|
|
||||||
|
|
||||||
|
class TestMWFormatter(unittest.TestCase):
|
||||||
|
def test_cargo_embed(self):
|
||||||
|
test = default_message("cargo/createtable", formatter_hooks)
|
||||||
|
ctx = PropertyMock()
|
||||||
|
ctx.message_type = "embed"
|
||||||
|
ctx.event_type = "cargo/createtable"
|
||||||
|
ctx.event = "cargo/createtable"
|
||||||
|
ctx.client.parse_links = parse_links
|
||||||
|
ctx.parsedcomment = ""
|
||||||
|
ctx.client.WIKI_SCRIPT_PATH = WIKI_SCRIPT_PATH
|
||||||
|
ctx.webhook_url = "https://example.com"
|
||||||
|
# ctx.client.return_value = Mock(spec=Client)
|
||||||
|
edit_c, results = get_objects("cargo/createtable")
|
||||||
|
result = repr(test(ctx, edit_c))
|
||||||
|
self.assertEqual(results, result)
|
58
test/test_datadump.py
Normal file
58
test/test_datadump.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import json
|
||||||
|
from src.configloader import settings
|
||||||
|
from src.api.context import Context
|
||||||
|
from src.api.util import default_message
|
||||||
|
from src.api.hooks import formatter_hooks
|
||||||
|
from src.misc import WIKI_SCRIPT_PATH
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from unittest.mock import PropertyMock
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
def no_formatter(ctx: Context, change: dict) -> None:
|
||||||
|
raise NameError
|
||||||
|
|
||||||
|
|
||||||
|
inject_settings("appearance.mode", "embed")
|
||||||
|
importlib.import_module(settings.get('extensions_dir', 'extensions'), 'extensions')
|
||||||
|
formatter_hooks["no_formatter"] = no_formatter
|
||||||
|
with open("test/data/rc_objects.json", "r") as ob:
|
||||||
|
jsons = json.loads(ob.read())
|
||||||
|
with open("test/data/rc_results.json", "r") as ob:
|
||||||
|
results = json.loads(ob.read())
|
||||||
|
|
||||||
|
|
||||||
|
def get_objects(name: str):
|
||||||
|
return jsons.get(name), json.dumps(results.get(name))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMWFormatter(unittest.TestCase):
|
||||||
|
def test_datadump_embed(self):
|
||||||
|
test = default_message("datadump/generate", formatter_hooks)
|
||||||
|
ctx = PropertyMock()
|
||||||
|
ctx.message_type = "embed"
|
||||||
|
ctx.event_type = "datadump/generate"
|
||||||
|
ctx.event = "datadump/generate"
|
||||||
|
ctx.parsedcomment = ""
|
||||||
|
ctx.client.WIKI_SCRIPT_PATH = WIKI_SCRIPT_PATH
|
||||||
|
ctx.webhook_url = "https://example.com"
|
||||||
|
# ctx.client.return_value = Mock(spec=Client)
|
||||||
|
edit_c, results = get_objects("datadump/generate")
|
||||||
|
result = repr(test(ctx, edit_c))
|
||||||
|
self.assertEqual(results, result)
|
31
test/test_disconnection.py
Normal file
31
test/test_disconnection.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from src.wiki import Wiki
|
||||||
|
|
||||||
|
|
||||||
|
class login_Testing(unittest.TestCase):
|
||||||
|
wiki = Wiki(None, None)
|
||||||
|
|
||||||
|
def test_connection_checker(self):
|
||||||
|
self.assertTrue(self.wiki.check_connection(looped=True))
|
||||||
|
|
||||||
|
def test_connection_tracker1(self): # expands this test
|
||||||
|
inject_settings("show_updown_messages", True)
|
||||||
|
self.wiki.downtimecredibility = 0
|
||||||
|
self.wiki.downtime_controller(True)
|
||||||
|
self.assertTrue(self.wiki.downtimecredibility > 0)
|
82
test/test_hooks.py
Normal file
82
test/test_hooks.py
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from src.api.context import Context
|
||||||
|
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
||||||
|
from src.api import formatter
|
||||||
|
from src.api.hook import pre_hook, post_hook
|
||||||
|
from src.api.hooks import formatter_hooks, pre_hooks, post_hooks
|
||||||
|
|
||||||
|
|
||||||
|
class ApiTesting(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.temp = formatter_hooks.copy()
|
||||||
|
|
||||||
|
def tearDown(self) -> None:
|
||||||
|
formatter_hooks.update(self.temp)
|
||||||
|
|
||||||
|
def test_embed_formatter_registration(self):
|
||||||
|
formatter_hooks.clear()
|
||||||
|
|
||||||
|
@formatter.embed(event="test", mode="embed")
|
||||||
|
def test_formatter_registration(ctx: Context, change: dict) -> DiscordMessage:
|
||||||
|
pass
|
||||||
|
self.assertEqual(formatter_hooks["test"], test_formatter_registration)
|
||||||
|
|
||||||
|
def test_compact_formatter_registration(self):
|
||||||
|
formatter_hooks.clear()
|
||||||
|
|
||||||
|
@formatter.embed(event="test", mode="compact")
|
||||||
|
def test_formatter_registration(ctx: Context, change: dict) -> DiscordMessage:
|
||||||
|
pass
|
||||||
|
self.assertEqual(formatter_hooks["test"], test_formatter_registration)
|
||||||
|
|
||||||
|
def test_overwrite_formatter_registration_warning(self):
|
||||||
|
formatter_hooks.clear()
|
||||||
|
|
||||||
|
@formatter.embed(event="test", mode="compact")
|
||||||
|
def test_formatter_registration(ctx: Context, change: dict) -> DiscordMessage:
|
||||||
|
pass
|
||||||
|
|
||||||
|
with self.assertLogs("src.api.formatter", level="WARNING"):
|
||||||
|
@formatter.embed(event="test", mode="compact")
|
||||||
|
def test_other_formatter_registration(ctx: Context, change: dict) -> DiscordMessage:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_formatter_aliasing(self):
|
||||||
|
formatter_hooks.clear()
|
||||||
|
|
||||||
|
@formatter.embed(event="test", mode="compact", aliases=["test2", "test3"])
|
||||||
|
def test_formatter_registration(ctx: Context, change: dict) -> DiscordMessage:
|
||||||
|
pass
|
||||||
|
self.assertEqual(formatter_hooks["test2"], test_formatter_registration)
|
||||||
|
|
||||||
|
def test_pre_hook_registration(self):
|
||||||
|
pre_hooks.clear()
|
||||||
|
|
||||||
|
@pre_hook
|
||||||
|
def test_prehook(some_data: Context, change: dict):
|
||||||
|
pass
|
||||||
|
self.assertEqual(pre_hooks[0], test_prehook)
|
||||||
|
|
||||||
|
def test_post_hook_registration(self):
|
||||||
|
post_hooks.clear()
|
||||||
|
|
||||||
|
@post_hook
|
||||||
|
def test_posthook(message: DiscordMessage, metadata: DiscordMessageMetadata, context: Context, change: dict):
|
||||||
|
pass
|
||||||
|
self.assertEqual(post_hooks[0], test_posthook)
|
30
test/test_i18n.py
Normal file
30
test/test_i18n.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
import src.i18n
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class i18nTesting(unittest.TestCase):
|
||||||
|
def test_language_output_polish(self):
|
||||||
|
inject_settings("lang", "pl")
|
||||||
|
src.i18n.load_languages() # reload languages with new language
|
||||||
|
self.assertEqual(src.i18n.rcgcdw.gettext("Daily overview"), "Podsumowanie dnia")
|
||||||
|
|
||||||
|
def test_language_output_english(self):
|
||||||
|
inject_settings("lang", "en")
|
||||||
|
src.i18n.load_languages() # reload languages with new language
|
||||||
|
self.assertEqual(src.i18n.rcgcdw.gettext("Daily overview"), "Daily overview")
|
58
test/test_interwiki.py
Normal file
58
test/test_interwiki.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import json
|
||||||
|
from src.configloader import settings
|
||||||
|
from src.api.context import Context
|
||||||
|
from src.api.util import default_message
|
||||||
|
from src.api.hooks import formatter_hooks
|
||||||
|
from src.misc import WIKI_SCRIPT_PATH
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from unittest.mock import PropertyMock
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
def no_formatter(ctx: Context, change: dict) -> None:
|
||||||
|
raise NameError
|
||||||
|
|
||||||
|
|
||||||
|
inject_settings("appearance.mode", "embed")
|
||||||
|
importlib.import_module(settings.get('extensions_dir', 'extensions'), 'extensions')
|
||||||
|
formatter_hooks["no_formatter"] = no_formatter
|
||||||
|
with open("test/data/rc_objects.json", "r") as ob:
|
||||||
|
jsons = json.loads(ob.read())
|
||||||
|
with open("test/data/rc_results.json", "r") as ob:
|
||||||
|
results = json.loads(ob.read())
|
||||||
|
|
||||||
|
|
||||||
|
def get_objects(name: str):
|
||||||
|
return jsons.get(name), json.dumps(results.get(name))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMWFormatter(unittest.TestCase):
|
||||||
|
def test_interwiki_embed(self):
|
||||||
|
test = default_message("interwiki/iw_add", formatter_hooks)
|
||||||
|
ctx = PropertyMock()
|
||||||
|
ctx.message_type = "embed"
|
||||||
|
ctx.event_type = "interwiki/iw_add"
|
||||||
|
ctx.event = "interwiki/iw_add"
|
||||||
|
ctx.parsedcomment = ""
|
||||||
|
ctx.client.WIKI_SCRIPT_PATH = WIKI_SCRIPT_PATH
|
||||||
|
ctx.webhook_url = "https://example.com"
|
||||||
|
# ctx.client.return_value = Mock(spec=Client)
|
||||||
|
edit_c, results = get_objects("interwiki/iw_add")
|
||||||
|
result = repr(test(ctx, edit_c))
|
||||||
|
self.assertEqual(results, result)
|
58
test/test_mediawiki.py
Normal file
58
test/test_mediawiki.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import json
|
||||||
|
from src.configloader import settings
|
||||||
|
from src.api.context import Context
|
||||||
|
from src.api.util import default_message
|
||||||
|
from src.api.hooks import formatter_hooks
|
||||||
|
from src.misc import WIKI_SCRIPT_PATH
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from unittest.mock import PropertyMock
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
def no_formatter(ctx: Context, change: dict) -> None:
|
||||||
|
raise NameError
|
||||||
|
|
||||||
|
|
||||||
|
inject_settings("appearance.mode", "embed")
|
||||||
|
importlib.import_module(settings.get('extensions_dir', 'extensions'), 'extensions')
|
||||||
|
formatter_hooks["no_formatter"] = no_formatter
|
||||||
|
with open("test/data/rc_objects.json", "r") as ob:
|
||||||
|
jsons = json.loads(ob.read())
|
||||||
|
with open("test/data/rc_results.json", "r") as ob:
|
||||||
|
results = json.loads(ob.read())
|
||||||
|
|
||||||
|
|
||||||
|
def get_objects(name: str):
|
||||||
|
return jsons.get(name), json.dumps(results.get(name))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMWFormatter(unittest.TestCase):
|
||||||
|
def test_edit_embed(self):
|
||||||
|
test = default_message("edit", formatter_hooks)
|
||||||
|
ctx = PropertyMock()
|
||||||
|
ctx.message_type = "embed"
|
||||||
|
ctx.event_type = "edit"
|
||||||
|
ctx.event = "edit"
|
||||||
|
ctx.parsedcomment = "Work on new as"
|
||||||
|
ctx.client.WIKI_SCRIPT_PATH = WIKI_SCRIPT_PATH
|
||||||
|
ctx.webhook_url = "https://example.com"
|
||||||
|
# ctx.client.return_value = Mock(spec=Client)
|
||||||
|
edit_c, results = get_objects("edit")
|
||||||
|
result = repr(test(ctx, edit_c))
|
||||||
|
self.assertEqual(results, result)
|
76
test/test_misc.py
Normal file
76
test/test_misc.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from unittest import TestCase
|
||||||
|
from src.exceptions import MediaWikiError
|
||||||
|
from src.misc import datafile, data_template, weighted_average, prepare_paths, parse_mw_request_info
|
||||||
|
from os.path import exists
|
||||||
|
|
||||||
|
|
||||||
|
class TestDataFile(TestCase):
|
||||||
|
def test_generate_datafile(self):
|
||||||
|
datafile.generate_datafile()
|
||||||
|
self.assertTrue(exists(datafile.data_filename))
|
||||||
|
with open(datafile.data_filename, "r") as df:
|
||||||
|
contents = df.read()
|
||||||
|
print(json.loads(contents))
|
||||||
|
self.assertEqual(json.loads(contents), data_template)
|
||||||
|
|
||||||
|
def test_load_datafile(self):
|
||||||
|
self.assertEqual(datafile.load_datafile(), data_template)
|
||||||
|
|
||||||
|
# def test_save_datafile(self):
|
||||||
|
# datafile["discussion_id"] = 321388838283
|
||||||
|
# datafile.save_datafile()
|
||||||
|
# with open(datafile.data_filename, "r") as df:
|
||||||
|
# contents = json.loads(df.read())
|
||||||
|
# self.assertEqual(contents["discussion_id"], 321388838283)
|
||||||
|
|
||||||
|
|
||||||
|
class Test(TestCase):
|
||||||
|
def test_weighted_average(self):
|
||||||
|
self.assertEqual(weighted_average(3, 5, 30), 7.5)
|
||||||
|
|
||||||
|
def test_prepare_paths(self):
|
||||||
|
self.assertEqual(prepare_paths("https://minecraft.fandom.com/blabhlldlasldllad", dry=True), "https://minecraft.fandom.com")
|
||||||
|
self.assertEqual(prepare_paths("https://minecraft.fandom.com/wiki/Minecraft_Wiki", dry=True), "https://minecraft.fandom.com")
|
||||||
|
self.assertEqual(prepare_paths("https://minecraft.fandom.com/", dry=True), "https://minecraft.fandom.com")
|
||||||
|
|
||||||
|
def test_parse_mw_request_info(self):
|
||||||
|
warning_data = """{"batchcomplete":"","warnings":[{"code":"unrecognizedvalues","key":"apiwarn-unrecognizedvalues","params":["list",{"list":["recentchange"],"type":"comma"},1],"module":"query"},{"code":"unrecognizedparams","key":"apierror-unrecognizedparams","params":[{"list":{"3":"rcshow","4":"rcprop","5":"rclimit","6":"rctype"},"type":"comma"},4],"module":"main"}]}"""
|
||||||
|
warning_data = json.loads(warning_data)
|
||||||
|
error_data = """{"errors":[{"code":"missingparam","key":"apierror-missingparam-at-least-one-of","params":[{"list":["<var>totitle</var>","<var>toid</var>","<var>torev</var>","<var>totext</var>","<var>torelative</var>","<var>toslots</var>"],"type":"text"},6],"module":"compare"}],"*":"See https://minecraft.fandom.com/pl/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."}"""
|
||||||
|
error_data = json.loads(error_data)
|
||||||
|
self.assertRaises(MediaWikiError, parse_mw_request_info, error_data, "dummy")
|
||||||
|
with self.assertLogs("rcgcdw.misc", level="WARNING"):
|
||||||
|
parse_mw_request_info(warning_data, "dummy")
|
||||||
|
# with self.assertNoLogs("rcgcdw.misc", level="WARNING"): # python 3.10
|
||||||
|
# parse_mw_request_info(legit_data, "dummy")
|
66
test/test_queue.py
Normal file
66
test/test_queue.py
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
from src.discord.queue import MessageQueue
|
||||||
|
from src.discord.message import DiscordMessage, DiscordMessageMetadata
|
||||||
|
|
||||||
|
|
||||||
|
def create_dummy(id: int = 0, **kwargs) -> Tuple[DiscordMessage, DiscordMessageMetadata]:
|
||||||
|
dm = DiscordMessage(event_type="log/{}".format(id), message_type="embed", webhook_url="https://example.com/")
|
||||||
|
dmm = DiscordMessageMetadata("POST", log_id=kwargs.get("log_id", int(id)*10), page_id=kwargs.get("page_id", int(id)),
|
||||||
|
rev_id=kwargs.get("rev_id", int(id)*10), webhook_url=kwargs.get("webhook_url", "https://example.com/"))
|
||||||
|
return dm, dmm
|
||||||
|
|
||||||
|
|
||||||
|
class TestQueue(unittest.TestCase):
|
||||||
|
def test_add_message(self):
|
||||||
|
queue = MessageQueue()
|
||||||
|
for _ in range(100):
|
||||||
|
queue.add_message(create_dummy())
|
||||||
|
self.assertEqual(len(queue), 100)
|
||||||
|
|
||||||
|
def test_cut_messages(self):
|
||||||
|
queue = MessageQueue()
|
||||||
|
for num in range(100):
|
||||||
|
queue.add_message(create_dummy(id=num))
|
||||||
|
queue.cut_messages(10)
|
||||||
|
self.assertEqual(list(queue)[0][1].page_id, 10)
|
||||||
|
|
||||||
|
def test_compare_message_to_dict(self):
|
||||||
|
queue = MessageQueue()
|
||||||
|
passing = [create_dummy(id=103, page_id=3928, rev_id=228848), create_dummy(id=108, page_id=3928, rev_id=228853)]
|
||||||
|
failing = [create_dummy(id=105, page_id=39, rev_id=2288), create_dummy(id=110, page_id=392, rev_id=228)]
|
||||||
|
for msg in passing:
|
||||||
|
with self.subTest():
|
||||||
|
self.assertTrue(queue.compare_message_to_dict(msg[1], {"page_id": 3928}))
|
||||||
|
for msg in failing:
|
||||||
|
with self.subTest():
|
||||||
|
self.assertFalse(queue.compare_message_to_dict(msg[1], {"page_id": 3928}))
|
||||||
|
|
||||||
|
def test_delete_all_with_matching_metadata(self):
|
||||||
|
queue = MessageQueue()
|
||||||
|
queue.add_message(create_dummy(id=103, page_id=500, rev_id=228844))
|
||||||
|
for num in range(100):
|
||||||
|
queue.add_message(create_dummy(id=num))
|
||||||
|
queue.add_message(create_dummy(id=105, page_id=3923, rev_id=228848))
|
||||||
|
queue_correct = MessageQueue()
|
||||||
|
for num in range(100):
|
||||||
|
queue_correct.add_message(create_dummy(id=num))
|
||||||
|
queue_correct.add_message(create_dummy(id=105, page_id=3923, rev_id=228848))
|
||||||
|
queue.delete_all_with_matching_metadata(page_id=500)
|
||||||
|
self.assertEqual(len(queue), len(queue_correct)) # Could be better but I'm running out of time
|
25
test/test_utilities.py
Normal file
25
test/test_utilities.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import src.configloader
|
||||||
|
|
||||||
|
|
||||||
|
def inject_settings(setting: str, value: Any):
|
||||||
|
path = setting.split(".")
|
||||||
|
dic = src.configloader.settings
|
||||||
|
for key in path[:-1]:
|
||||||
|
dic = dic[key]
|
||||||
|
dic[path[-1]] = value
|
53
test/test_wiki_login.py
Normal file
53
test/test_wiki_login.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# This file is part of Recent changes Goat compatible Discord webhook (RcGcDw).
|
||||||
|
#
|
||||||
|
# RcGcDw is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# RcGcDw is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with RcGcDw. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from src.configloader import settings
|
||||||
|
from test.test_utilities import inject_settings
|
||||||
|
from src.wiki import Wiki
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_func(func):
|
||||||
|
def wrap(*args, **kwargs):
|
||||||
|
login = settings["wiki_bot_login"]
|
||||||
|
password = settings["wiki_bot_password"]
|
||||||
|
func(*args, **kwargs)
|
||||||
|
inject_settings("wiki_bot_login", login)
|
||||||
|
inject_settings("wiki_bot_password", password)
|
||||||
|
return func
|
||||||
|
return wrap
|
||||||
|
|
||||||
|
|
||||||
|
class login_Testing(unittest.TestCase):
|
||||||
|
wiki = Wiki(None, None)
|
||||||
|
|
||||||
|
def test_success(self):
|
||||||
|
self.wiki.logged_in = False
|
||||||
|
self.wiki.log_in()
|
||||||
|
self.assertTrue(self.wiki.logged_in)
|
||||||
|
|
||||||
|
@cleanup_func
|
||||||
|
def test_failure1(self):
|
||||||
|
self.wiki.logged_in = False
|
||||||
|
inject_settings("wiki_bot_login", "asdkaodhasofaufbasf")
|
||||||
|
with self.assertLogs("rcgcdw.rc", level="ERROR"):
|
||||||
|
self.wiki.log_in()
|
||||||
|
|
||||||
|
@cleanup_func
|
||||||
|
def test_failure2(self):
|
||||||
|
self.wiki.logged_in = False
|
||||||
|
inject_settings("wiki_bot_password", "lkkkkk")
|
||||||
|
with self.assertLogs("rcgcdw.rc", level="ERROR"):
|
||||||
|
self.wiki.log_in()
|
Loading…
Reference in a new issue