jenkins-bot submitted this change.

View Change

Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
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(-)

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}
+ 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}
+
+ @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):


To view, visit change 671364. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: If0d0944bd0f775d6e0fc8d5970db2fbee2ab1704
Gerrit-Change-Number: 671364
Gerrit-PatchSet: 2
Gerrit-Owner: Huji <huji.huji@gmail.com>
Gerrit-Reviewer: DannyS712 <DannyS712.enwiki@gmail.com>
Gerrit-Reviewer: Ebrahim <ebrahim@gnu.org>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97@gmail.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged