From a4fca2998fd5f8b00dd53a22e8e2ccca0d71b6a2 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 6 Jul 2012 18:32:22 -0400 Subject: [PATCH 1/3] Beginning Page.check_exclusion() --- docs/toolset.rst | 3 +++ earwigbot/wiki/page.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/toolset.rst b/docs/toolset.rst index 06b36bf..c7808d2 100644 --- a/docs/toolset.rst +++ b/docs/toolset.rst @@ -164,6 +164,9 @@ and the following methods: `: checks the page like :py:meth:`~earwigbot.wiki.copyvios.CopyvioMixIn.copyvio_check`, but against a specific URL +- :py:meth:`check_exclusion(username=None, optouts=None) + `: checks whether or not we are + allowed to edit the page per ``{{bots}}``/``{{nobots}}`` Additionally, :py:class:`~earwigbot.wiki.category.Category` objects (created with :py:meth:`site.get_category(name) ` diff --git a/earwigbot/wiki/page.py b/earwigbot/wiki/page.py index 58efe50..96bb7db 100644 --- a/earwigbot/wiki/page.py +++ b/earwigbot/wiki/page.py @@ -68,6 +68,8 @@ class Page(CopyrightMixIn): - :py:meth:`parse`: parses the page content for templates, links, etc - :py:meth:`edit`: replaces the page's content or creates a new page - :py:meth:`add_section`: adds a new section at the bottom of the page + - :py:meth:`check_exclusion`: checks whether or not we are allowed to edit + the page, per ``{{bots}}``/``{{nobots}}`` - :py:meth:`~earwigbot.wiki.copyvios.CopyrightMixIn.copyvio_check`: checks the page for copyright violations @@ -723,3 +725,37 @@ class Page(CopyrightMixIn): """ self._edit(text=text, summary=title, minor=minor, bot=bot, force=force, section="new") + + def check_exclusion(self, username=None, optouts=None): + """Check whether or not we are allowed to edit the page. + + Return ``True`` if we *are* allowed to edit this page, or ``False`` if + we aren't. + + *username* is used to determine whether we are part of a specific list + of allowed or disallowed bots (e.g. ``{{bots|allow=EarwigBot}}`` or + ``{{bots|deny=FooBot,EarwigBot}}``). It's ``None`` by default, which + will swipe our username from :py:meth:`site.get_user() + `.\ + :py:attr:`~earwigbot.wiki.user.User.name`. + + *optouts* is a list of messages to consider this check as part of for + the purpose of opt-out; it defaults to ``None``, which ignores the + parameter completely. For example, if *optouts* is ``["nolicense"]``, + we'll return ``False`` on ``{{bots|optout=nolicense}}`` or + ``{{bots|optout=all}}``, but `True` on + ``{{bots|optout=orfud,norationale,replaceable}}``. + """ + re_bots = "\{\{(no)?bots(\||\}\})" + filter = self.parse().filter_templates(matches=re_bots, recursive=True) + for template in filter: + if template.get("deny", None): + pass + if template.get("allow", None): + pass + if template.get("optout", None): + pass + if template.name.matches("nobots"): + return False + if template.name.matches("bots"): + return True From e6956ba2b39d873d131feb5bba1eff18c94811ff Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 6 Jul 2012 20:23:22 -0400 Subject: [PATCH 2/3] Completing check_exclusion() (#26) --- earwigbot/wiki/page.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/earwigbot/wiki/page.py b/earwigbot/wiki/page.py index 96bb7db..9df3746 100644 --- a/earwigbot/wiki/page.py +++ b/earwigbot/wiki/page.py @@ -746,16 +746,26 @@ class Page(CopyrightMixIn): ``{{bots|optout=all}}``, but `True` on ``{{bots|optout=orfud,norationale,replaceable}}``. """ - re_bots = "\{\{(no)?bots(\||\}\})" + if not username: + username = self.site.get_user().name + + re_bots = "\{\{\s*(no)?bots\s*(\||\}\})" filter = self.parse().filter_templates(matches=re_bots, recursive=True) for template in filter: - if template.get("deny", None): - pass - if template.get("allow", None): - pass - if template.get("optout", None): - pass - if template.name.matches("nobots"): + if template.has_param("deny"): + denies = template.get_param("deny").value.split(",") + if "all" in denies or username in denies: + return False + if template.has_param("allow"): + allows = template.get_param("allow").value.split(",") + if "all" in allows or username in allows: + continue + if optouts and template.has_param("optout"): + tasks = template.get_param("optout").value.split(",") + matches = [optout in tasks for optout in optouts] + if "all" in tasks or any(matches): + return False + if template.name.strip().lower() == "nobots": return False - if template.name.matches("bots"): - return True + + return True From b04494b3f396e2fecc340cf4b4bb6780e3d3067c Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 6 Jul 2012 20:37:47 -0400 Subject: [PATCH 3/3] Made check_exclusion() more case-insensitive (#26) --- earwigbot/wiki/page.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/earwigbot/wiki/page.py b/earwigbot/wiki/page.py index 9df3746..3e8c29a 100644 --- a/earwigbot/wiki/page.py +++ b/earwigbot/wiki/page.py @@ -729,7 +729,7 @@ class Page(CopyrightMixIn): def check_exclusion(self, username=None, optouts=None): """Check whether or not we are allowed to edit the page. - Return ``True`` if we *are* allowed to edit this page, or ``False`` if + Return ``True`` if we *are* allowed to edit this page, and ``False`` if we aren't. *username* is used to determine whether we are part of a specific list @@ -746,22 +746,30 @@ class Page(CopyrightMixIn): ``{{bots|optout=all}}``, but `True` on ``{{bots|optout=orfud,norationale,replaceable}}``. """ + def parse_param(template, param): + value = template.get_param(param).value + return [item.strip().lower() for item in value.split(",")] + if not username: username = self.site.get_user().name + # Lowercase everything: + username = username.lower() + optouts = [optout.lower() for optout in optouts] if optouts else [] + re_bots = "\{\{\s*(no)?bots\s*(\||\}\})" filter = self.parse().filter_templates(matches=re_bots, recursive=True) for template in filter: if template.has_param("deny"): - denies = template.get_param("deny").value.split(",") + denies = parse_param(template, "deny") if "all" in denies or username in denies: return False if template.has_param("allow"): - allows = template.get_param("allow").value.split(",") + allows = parse_param(template, "allow") if "all" in allows or username in allows: continue if optouts and template.has_param("optout"): - tasks = template.get_param("optout").value.split(",") + tasks = parse_param(template, "optout") matches = [optout in tasks for optout in optouts] if "all" in tasks or any(matches): return False