jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/538006 )

Change subject: [bugfix] Implement deletedrevisions api call
......................................................................

[bugfix] Implement deletedrevisions api call

deletedrevs is deprecated and might be removed.

site changes:
- With mw 1.25 a 'deletedrevisions' PropertyGenerator is used
  to get deleted revisions.
- All API parameters can be used as keyword options
- The revids parameter is available too.
- page was renamed to titles. Both titles and revids are allowed to
  be an iterable instead of a single item
- All properties can be set with prop parameter if others than the default
  properties should be shown. If the content of a revision is requested,
  this will be added to the given properties or added to the default.
- Fallback to 'deletedrevs' ListGenerator for mw_version prior than 1.25
- Take into account that the two request types have different dicts

Test changes:
- Replace "page" with "titles"
- Use subTest to separate tests inside test method
- The generator must be started to validate the AssertionError
  since we have a real generator instead an iterable

Bug: T75370
Change-Id: I4c47abbc9ba0fcb03c20bcd4486020ac829a5b2b
---
M pywikibot/site.py
M tests/site_tests.py
2 files changed, 182 insertions(+), 91 deletions(-)

Approvals:
  Huji: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/site.py b/pywikibot/site.py
index a55a66c..d1b6518 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -5015,69 +5015,129 @@
                                                 filters)
         return wlgen

-    # TODO: T75370
-    @deprecated_args(step=None, get_text='content')
-    def deletedrevs(self, page, start=None, end=None, reverse=False,
-                    content=False, total=None):
+    @deprecated_args(step=None, get_text='content', page='titles',
+                     limit='total')
+    def deletedrevs(self, titles=None, start=None, end=None, reverse=False,
+                    content=False, total=None, **kwargs):
         """Iterate deleted revisions.

         Each value returned by the iterator will be a dict containing the
         'title' and 'ns' keys for a particular Page and a 'revisions' key
         whose value is a list of revisions in the same format as
-        recentchanges (plus a 'content' element if requested). If get_text
-        is true, the toplevel dict will contain a 'token' key as well.
+        recentchanges plus a 'content' element with key '*' if requested
+        when 'content' parameter is set. For older wikis a 'token' key is
+        also given with the content request.

-        @see: U{https://www.mediawiki.org/wiki/API:Deletedrevs}
+        @see: U{https://www.mediawiki.org/wiki/API:Deletedrevisions}

-        @param page: The page to check for deleted revisions
+        @param titles: The page titles to check for deleted revisions
+        @type titles: str (multiple titles delimited with '|')
+            or pywikibot.Page or typing.Iterable[pywikibot.Page]
+            or typing.Iterable[str]
+        @keyword revids: Get revisions by their ID
+
+        @note either titles or revids must be set but not both
+
         @param start: Iterate revisions starting at this Timestamp
         @param end: Iterate revisions ending at this Timestamp
         @param reverse: Iterate oldest revisions first (default: newest)
         @type reverse: bool
-        @param content: If True, retrieve the content of each revision and
-            an undelete token
+        @param content: If True, retrieve the content of each revision
+        @param total: number of revisions to retrieve
+        @keyword user: List revisions by this user
+        @keyword excludeuser: Exclude revisions by this user
+        @keyword tag: Only list revision tagged with this tag
+        @keyword prop: Which properties to get. Defaults are ids, user,
+            comment, flags and timestamp
         """
+        def handle_props(props):
+            """Translate deletedrev props to deletedrevisions props."""
+            if isinstance(props, UnicodeType):
+                props = props.split('|')
+            if self.mw_version >= '1.25':
+                return props
+
+            old_props = []
+            for item in props:
+                if item == 'ids':
+                    old_props += ['revid', 'parentid']
+                elif item == 'flags':
+                    old_props.append('minor')
+                elif item == 'timestamp':
+                    pass
+                else:
+                    old_props.append(item)
+                    if item == 'content' and self.mw_version < '1.24':
+                        old_props.append('token')
+            return old_props
+
         if start and end:
             self.assert_valid_iter_params('deletedrevs', start, end, reverse)

         if not self.logged_in():
             self.login()
+
+        err = ('deletedrevs: User:{} not authorized to '
+               .format(self.user()))
         if 'deletedhistory' not in self.userinfo['rights']:
-            try:
-                self.login(True)
-            except NoUsername:
-                pass
-            if 'deletedhistory' not in self.userinfo['rights']:
-                raise Error(
-                    'deletedrevs: '
-                    'User:%s not authorized to access deleted revisions.'
-                    % self.user())
+            raise Error(err + 'access deleted revisions.')
         if content:
             if 'undelete' not in self.userinfo['rights']:
-                try:
-                    self.login(True)
-                except NoUsername:
-                    pass
-                if 'undelete' not in self.userinfo['rights']:
-                    raise Error(
-                        'deletedrevs: '
-                        'User:%s not authorized to view deleted content.'
-                        % self.user())
+                raise Error(err + 'view deleted content.')

-        drgen = self._generator(api.ListGenerator, type_arg='deletedrevs',
-                                titles=page.title(with_section=False),
-                                drprop='revid|user|comment|minor',
-                                total=total)
+        revids = kwargs.pop('revids', None)
+        if not (bool(titles) ^ (revids is not None)):
+            raise Error('deletedrevs: either "titles" or "revids" parameter '
+                        'must be given.')
+        if revids and self.mw_version < '1.25':
+            raise NotImplementedError(
+                'deletedrevs: "revid" is not implemented with MediaWiki {}'
+                .format(self.mw_version))
+
+        if self.mw_version >= '1.25':
+            pre = 'drv'
+            type_arg = 'deletedrevisions'
+            generator = api.PropertyGenerator
+        else:
+            pre = 'dr'
+            type_arg = 'deletedrevs'
+            generator = api.ListGenerator
+
+        gen = self._generator(generator, type_arg=type_arg,
+                              titles=titles, revids=revids,
+                              total=total)
+
+        gen.request[pre + 'start'] = start
+        gen.request[pre + 'end'] = end
+
+        # handle properties
+        prop = kwargs.pop('prop',
+                          ['ids', 'user', 'comment', 'flags', 'timestamp'])
         if content:
-            drgen.request['drprop'] = (drgen.request['drprop']
-                                       + ['content', 'token'])
-        if start is not None:
-            drgen.request['drstart'] = start
-        if end is not None:
-            drgen.request['drend'] = end
+            prop.append('content')
+        prop = handle_props(prop)
+        gen.request[pre + 'prop'] = prop
+
+        # handle other parameters like user
+        for k, v in kwargs.items():
+            gen.request[pre + k] = v
+
         if reverse:
-            drgen.request['drdir'] = 'newer'
-        return drgen
+            gen.request[pre + 'dir'] = 'newer'
+
+        if self.mw_version < '1.25':
+            # yield from gen
+            for data in gen:
+                yield data
+        else:
+            # The dict result is different for both generators
+            for data in gen:
+                try:
+                    data['revisions'] = data.pop('deletedrevisions')
+                except KeyError:
+                    pass
+                else:
+                    yield data

     def users(self, usernames):
         """Iterate info about a list of users by name or IP.
diff --git a/tests/site_tests.py b/tests/site_tests.py
index d4bf58c..4c84f3b 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -1885,66 +1885,97 @@
         """Test the site.deletedrevs() method."""
         mysite = self.get_site()
         mainpage = self.get_mainpage()
-        gen = mysite.deletedrevs(total=10, page=mainpage)
+        gen = mysite.deletedrevs(total=10, titles=mainpage)
+
         for dr in gen:
             break
         else:
             self.skipTest(
                 '{0} contains no deleted revisions.'.format(mainpage))
         self.assertLessEqual(len(dr['revisions']), 10)
-        self.assertTrue(all(isinstance(rev, dict)
-                            for rev in dr['revisions']))
-        for item in mysite.deletedrevs(start='2008-10-11T01:02:03Z',
-                                       page=mainpage, total=5):
-            for rev in item['revisions']:
-                self.assertIsInstance(rev, dict)
-                self.assertLessEqual(rev['timestamp'], '2008-10-11T01:02:03Z')
-        for item in mysite.deletedrevs(end='2008-04-01T02:03:04Z',
-                                       page=mainpage, total=5):
-            for rev in item['revisions']:
-                self.assertIsInstance(rev, dict)
-                self.assertGreaterEqual(rev['timestamp'],
-                                        '2008-10-11T02:03:04Z')
-        for item in mysite.deletedrevs(start='2008-10-11T03:05:07Z',
-                                       page=mainpage, total=5,
-                                       reverse=True):
-            for rev in item['revisions']:
-                self.assertIsInstance(rev, dict)
-                self.assertGreaterEqual(rev['timestamp'],
-                                        '2008-10-11T03:05:07Z')
-        for item in mysite.deletedrevs(end='2008-10-11T04:06:08Z',
-                                       page=mainpage, total=5,
-                                       reverse=True):
-            for rev in item['revisions']:
-                self.assertIsInstance(rev, dict)
-                self.assertLessEqual(rev['timestamp'], '2008-10-11T04:06:08Z')
-        for item in mysite.deletedrevs(start='2008-10-13T11:59:59Z',
-                                       end='2008-10-13T00:00:01Z',
-                                       page=mainpage, total=5):
-            for rev in item['revisions']:
-                self.assertIsInstance(rev, dict)
-                self.assertLessEqual(rev['timestamp'], '2008-10-13T11:59:59Z')
-                self.assertGreaterEqual(rev['timestamp'],
-                                        '2008-10-13T00:00:01Z')
-        for item in mysite.deletedrevs(start='2008-10-15T06:00:01Z',
-                                       end='2008-10-15T23:59:59Z',
-                                       page=mainpage, reverse=True,
-                                       total=5):
-            for rev in item['revisions']:
-                self.assertIsInstance(rev, dict)
-                self.assertLessEqual(rev['timestamp'], '2008-10-15T23:59:59Z')
-                self.assertGreaterEqual(rev['timestamp'],
-                                        '2008-10-15T06:00:01Z')
+        self.assertTrue(all(isinstance(rev, dict) for rev in dr['revisions']))
+
+        with self.subTest(start='2008-10-11T01:02:03Z', reverse=False):
+            for item in mysite.deletedrevs(start='2008-10-11T01:02:03Z',
+                                           titles=mainpage, total=5):
+                for rev in item['revisions']:
+                    self.assertIsInstance(rev, dict)
+                    self.assertLessEqual(rev['timestamp'],
+                                         '2008-10-11T01:02:03Z')
+
+        with self.subTest(end='2008-04-01T02:03:04Z', reverse=False):
+            for item in mysite.deletedrevs(end='2008-04-01T02:03:04Z',
+                                           titles=mainpage, total=5):
+                for rev in item['revisions']:
+                    self.assertIsInstance(rev, dict)
+                    self.assertGreaterEqual(rev['timestamp'],
+                                            '2008-10-11T02:03:04Z')
+
+        with self.subTest(start='2008-10-11T03:05:07Z', reverse=True):
+            for item in mysite.deletedrevs(start='2008-10-11T03:05:07Z',
+                                           titles=mainpage, total=5,
+                                           reverse=True):
+                for rev in item['revisions']:
+                    self.assertIsInstance(rev, dict)
+                    self.assertGreaterEqual(rev['timestamp'],
+                                            '2008-10-11T03:05:07Z')
+
+        with self.subTest(end='2008-10-11T04:06:08Z', reverse=True):
+            for item in mysite.deletedrevs(end='2008-10-11T04:06:08Z',
+                                           titles=mainpage, total=5,
+                                           reverse=True):
+                for rev in item['revisions']:
+                    self.assertIsInstance(rev, dict)
+                    self.assertLessEqual(rev['timestamp'],
+                                         '2008-10-11T04:06:08Z')
+
+        with self.subTest(start='2008-10-13T11:59:59Z',
+                          end='2008-10-13T00:00:01Z',
+                          reverse=False):
+            for item in mysite.deletedrevs(start='2008-10-13T11:59:59Z',
+                                           end='2008-10-13T00:00:01Z',
+                                           titles=mainpage, total=5):
+                for rev in item['revisions']:
+                    self.assertIsInstance(rev, dict)
+                    self.assertLessEqual(rev['timestamp'],
+                                         '2008-10-13T11:59:59Z')
+                    self.assertGreaterEqual(rev['timestamp'],
+                                            '2008-10-13T00:00:01Z')
+
+        with self.subTest(start='2008-10-15T06:00:01Z',
+                          end='2008-10-15T23:59:59Z',
+                          reverse=True):
+            for item in mysite.deletedrevs(start='2008-10-15T06:00:01Z',
+                                           end='2008-10-15T23:59:59Z',
+                                           titles=mainpage, total=5,
+                                           reverse=True):
+                for rev in item['revisions']:
+                    self.assertIsInstance(rev, dict)
+                    self.assertLessEqual(rev['timestamp'],
+                                         '2008-10-15T23:59:59Z')
+                    self.assertGreaterEqual(rev['timestamp'],
+                                            '2008-10-15T06:00:01Z')

         # start earlier than end
-        self.assertRaises(AssertionError, mysite.deletedrevs,
-                          page=mainpage, start='2008-09-03T00:00:01Z',
-                          end='2008-09-03T23:59:59Z', total=5)
+        with self.subTest(start='2008-09-03T00:00:01Z',
+                          end='2008-09-03T23:59:59Z',
+                          reverse=False):
+            with self.assertRaises(AssertionError):
+                gen = mysite.deletedrevs(titles=mainpage,
+                                         start='2008-09-03T00:00:01Z',
+                                         end='2008-09-03T23:59:59Z', total=5)
+                next(gen)
+
         # reverse: end earlier than start
-        self.assertRaises(AssertionError, mysite.deletedrevs,
-                          page=mainpage, start='2008-09-03T23:59:59Z',
-                          end='2008-09-03T00:00:01Z', reverse=True,
-                          total=5)
+        with self.subTest(start='2008-09-03T23:59:59Z',
+                          end='2008-09-03T00:00:01Z',
+                          reverse=True):
+            with self.assertRaises(AssertionError):
+                gen = mysite.deletedrevs(titles=mainpage,
+                                         start='2008-09-03T23:59:59Z',
+                                         end='2008-09-03T00:00:01Z', total=5,
+                                         reverse=True)
+                next(gen)


 class TestSiteSysopWrite(TestCase):

--
To view, visit https://gerrit.wikimedia.org/r/538006
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I4c47abbc9ba0fcb03c20bcd4486020ac829a5b2b
Gerrit-Change-Number: 538006
Gerrit-PatchSet: 16
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Huji <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot (75)
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to