jenkins-bot has submitted this change and it was merged.
Change subject: Add patrol to site.py
......................................................................
Add patrol to site.py
Add API: patrol to site.py
Change-Id: Id8262d765f7a7bbb398ce8c125d2358a8ca178fc
---
M pywikibot/site.py
M tests/site_tests.py
2 files changed, 125 insertions(+), 1 deletion(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 82a7299..d4fe555 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -57,8 +57,11 @@
from urllib.parse import urlencode
basestring = (str,)
unicode = str
+ from itertools import zip_longest
else:
from urllib import urlencode
+ from itertools import izip_longest as zip_longest
+
_logger = "wiki.site"
@@ -4084,7 +4087,100 @@
# TODO: implement undelete
- # TODO: implement patrol
+ _patrol_errors = {
+ "nosuchrcid": "There is no change with rcid %(rcid)s",
+ "nosuchrevid": "There is no change with revid %(revid)s",
+ "patroldisabled": "Patrolling is disabled on %(site)s wiki",
+ "noautopatrol": "User %(user)s has no permission to patrol its own
changes, 'autopatrol' is needed",
+ "notpatrollable": "The revision %(revid)s can't be patrolled
as it's too old."
+ }
+
+ # test it with:
+ # python -m unittest tests.site_tests.SiteUserTestCase.testPatrol
+
+ def patrol(self, rcid=None, revid=None, revision=None):
+ """Return a generator of patrolled pages.
+
+ Pages to be patrolled are identified by rcid, revid or revision.
+ At least one of the parameters is mandatory.
+ See
https://www.mediawiki.org/wiki/API:Patrol.
+
+ @param rcid: an int/string/iterable/iterator providing rcid of pages
+ to be patrolled.
+ @type rcid: iterable/iterator which returns a number or string which
+ contains only digits; it also supports a string (as above) or int
+ @param revid: an int/string/iterable/iterator providing revid of pages
+ to be patrolled.
+ @type revid: iterable/iterator which returns a number or string which
+ contains only digits; it also supports a string (as above) or int.
+ @param revision: an Revision/iterable/iterator providing Revision object
+ of pages to be patrolled.
+ @type revision: iterable/iterator which returns a Revision object; it
+ also supports a single Revision.
+ @yield: dict with 'rcid', 'ns' and 'title' of the
patrolled page.
+
+ """
+
+ # If patrol is not enabled, attr will be set the first time a
+ # request is done.
+ if hasattr(self, u'_patroldisabled'):
+ if self._patroldisabled:
+ return
+
+ if all(_ is None for _ in [rcid, revid, revision]):
+ raise Error('No rcid, revid or revision provided.')
+
+ if isinstance(rcid, int) or isinstance(rcid, basestring):
+ rcid = set([rcid])
+ if isinstance(revid, int) or isinstance(revid, basestring):
+ revid = set([revid])
+ if isinstance(revision, pywikibot.page.Revision):
+ revision = set([revision])
+
+ # Handle param=None.
+ rcid = rcid or set()
+ revid = revid or set()
+ revision = revision or set()
+
+ # TODO: remove exeception for mw < 1.22
+ if (revid or revision) and LV(self.version()) < LV("1.22"):
+ raise NotImplementedError(
+ u'Support of "revid" parameter\n'
+ u'is not implemented in MediaWiki version <
"1.22"')
+ else:
+ combined_revid = set(revid) | set(r.revid for r in revision)
+
+ gen = itertools.chain(
+ zip_longest(rcid, [], fillvalue='rcid'),
+ zip_longest(combined_revid, [], fillvalue='revid'))
+
+ token = self.tokens['patrol']
+
+ for idvalue, idtype in gen:
+ req = api.Request(site=self, action='patrol',
+ token=token, **{idtype: idvalue})
+
+ try:
+ result = req.submit()
+ except api.APIError as err:
+ # patrol is disabled, store in attr to avoid other requests
+ if err.code == u'patroldisabled':
+ self._patroldisabled = True
+ return
+
+ errdata = {
+ 'site': self,
+ 'user': self.user(),
+ }
+ errdata[idtype] = idvalue
+ if err.code in self._patrol_errors:
+ raise Error(self._patrol_errors[err.code] % errdata)
+ pywikibot.debug(u"protect: Unexpected error code '%s'
received."
+ % err.code,
+ _logger)
+ raise
+
+ yield result['patrol']
@must_be(group='sysop')
def blockuser(self, user, expiry, reason, anononly=True, nocreate=True,
diff --git a/tests/site_tests.py b/tests/site_tests.py
index 6b8295f..fca7262 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -15,6 +15,7 @@
import re
import pywikibot
+from pywikibot.data import api
from tests.aspects import (
unittest, TestCase,
DefaultSiteTestCase,
@@ -1032,6 +1033,33 @@
self.assertTrue(user["name"]
in ["Jimbo Wales", "Brion VIBBER",
"Tim Starling"])
+ def testPatrol(self):
+ """Test the site.patrol() method."""
+ mysite = self.get_site()
+
+ rc = list(mysite.recentchanges(total=1))[0]
+
+ # site.patrol() needs params
+ self.assertRaises(pywikibot.Error, lambda x: list(x), mysite.patrol())
+ result = list(mysite.patrol(rcid=rc['rcid']))
+
+ if hasattr(mysite, u'_patroldisabled') and mysite._patroldisabled:
+ raise unittest.SkipTest(u'Patrolling is disabled on %s wiki.'
+ % mysite)
+
+ result = result[0]
+ self.assertIsInstance(result, dict)
+
+ try:
+ # no such rcid, revid or too old revid
+ result = list(mysite.patrol(rcid=0, revid=[0, 1]))
+ except api.APIError as error:
+ if error.code == u'badtoken':
+ raise unittest.SkipTest(error)
+ except pywikibot.Error as error:
+ #expected result
+ pass
+
class SiteRandomTestCase(DefaultSiteTestCase):
--
To view, visit
https://gerrit.wikimedia.org/r/159197
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id8262d765f7a7bbb398ce8c125d2358a8ca178fc
Gerrit-PatchSet: 11
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>