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):
pywikibot-commits@lists.wikimedia.org