jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/671364 )
Change subject: Support deleting and undeleting specific file versions ......................................................................
Support deleting and undeleting specific file versions
Bug: T276725 Change-Id: If0d0944bd0f775d6e0fc8d5970db2fbee2ab1704 --- M pywikibot/site/_apisite.py M tests/site_tests.py 2 files changed, 124 insertions(+), 1 deletion(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/site/_apisite.py b/pywikibot/site/_apisite.py index 196bffc..698d10b 100644 --- a/pywikibot/site/_apisite.py +++ b/pywikibot/site/_apisite.py @@ -3750,7 +3750,8 @@ 'cantdelete': 'Could not delete [[%(title)s]]. Maybe it was deleted already.', 'cantundelete': 'Could not undelete [[%(title)s]]. ' - 'Revision may not exist or was already undeleted.' + 'Revision may not exist or was already undeleted.', + 'nodeleteablefile': 'No such old version of file' } # other errors shouldn't occur because of pre-submission checks
@need_right('delete') @@ -3799,6 +3800,54 @@ finally: self.unlock_page(page)
+ @need_right('delete') + def deleteoldimage(self, page, oldimage, reason: str): + """Delete a specific version of a file. Requires appropriate privileges. + + @see: U{https://www.mediawiki.org/wiki/API:Delete%7D + The oldimage identifier for the specific version of the image must be + provided. + + @param page: Page to be deleted or its pageid + @type page: Page or, in case of pageid, int or str + @param oldimage: oldimageid of the file version to be deleted. + @param reason: Deletion reason. + @raises TypeError, ValueError: page has wrong type/value. + + """ + token = self.tokens['delete'] + params = {'action': 'delete', 'oldimage': oldimage, + 'token': token, 'reason': reason} + + if isinstance(page, pywikibot.Page): + params['title'] = page + msg = page.title(withSection=False) + else: + pageid = int(page) + params['pageid'] = pageid + msg = pageid + + req = self._simple_request(**params) + self.lock_page(page) + try: + req.submit() + except api.APIError as err: + errdata = { + 'site': self, + 'title': msg, + 'user': self.user(), + } + if err.code in self._dl_errors: + raise Error(self._dl_errors[err.code] % errdata) + pywikibot.debug("delete: Unexpected error code '%s' received." + % err.code, + _logger) + raise + else: + page.clear_cache() + finally: + self.unlock_page(page) + @need_right('undelete') @deprecate_arg('summary', 'reason') def undelete_page(self, page, reason: str, revisions=None): @@ -3839,6 +3888,43 @@ finally: self.unlock_page(page)
+ @need_right('undelete') + def undelete_file_versions(self, page, reason: str, fileids=None): + """Undelete page from the wiki. Requires appropriate privilege level. + + @see: U{https://www.mediawiki.org/wiki/API:Undelete%7D + + @param page: Page to be deleted. + @type page: pywikibot.BasePage + @param reason: Undeletion reason. + @param fileids: List of fileids to restore. + @type fileids: list + """ + token = self.tokens['delete'] + self.lock_page(page) + + req = self._simple_request(action='undelete', + title=page, + reason=reason, + token=token, + fileids=fileids) + try: + req.submit() + except api.APIError as err: + errdata = { + 'site': self, + 'title': page.title(with_section=False), + 'user': self.user(), + } + if err.code in self._dl_errors: + raise Error(self._dl_errors[err.code] % errdata) + pywikibot.debug("delete: Unexpected error code '%s' received." + % err.code, + _logger) + raise + finally: + self.unlock_page(page) + _protect_errors = { 'noapiwrite': 'API editing not enabled on %(site)s wiki', 'writeapidenied': 'User %(user)s not allowed to edit through the API', diff --git a/tests/site_tests.py b/tests/site_tests.py index 3a5337d..2d4c74c 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -2165,6 +2165,43 @@ revs = list(p.revisions()) self.assertGreater(len(revs), 2)
+ def test_delete_oldimage(self): + """Test deleting and undeleting specific versions of files.""" + site = self.get_site() + fp = pywikibot.FilePage(site, 'File:T276725.png') + + # Verify state + gen = site.filearchive(start='T276725.png', end='T276725.pngg') + fileid = None + + for filearchive in gen: + fileid = filearchive['id'] + break + + if fileid is not None: + site.undelete_file_versions(fp, 'pywikibot unit tests', + fileids=[fileid]) + + # Delete the older version of file + hist = fp.get_file_history() + ts = pywikibot.Timestamp(2021, 3, 8, 2, 38, 57) + oldimageid = hist[ts]['archivename'] + + site.deleteoldimage(fp, oldimageid, 'pywikibot unit tests') + + # Undelete the older revision of file + gen = site.filearchive(start='T276725.png', end='T276725.pngg') + fileid = None + + for filearchive in gen: + fileid = filearchive['id'] + break + + self.assertIsNotNone(fileid) + + site.undelete_file_versions(fp, 'pywikibot unit tests', + fileids=[fileid]) +
class TestUsernameInUsers(DefaultSiteTestCase):
pywikibot-commits@lists.wikimedia.org