jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/968553 )
Change subject: Add MediaInfo editLabels, AddClaim and removeClaim functions.
......................................................................
Add MediaInfo editLabels, AddClaim and removeClaim functions.
Added editLabels, addClaim, removeClaims functions to MediaInfo.
Bug: T348422
Change-Id: Ic3822e4b10419fabb26bae9a7756c8c39bbbe7a0
---
M pywikibot/page/_wikibase.py
M tests/file_tests.py
2 files changed, 195 insertions(+), 18 deletions(-)
Approvals:
Matěj Suchánek: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/page/_wikibase.py b/pywikibot/page/_wikibase.py
index bbfd71f..0b88472 100644
--- a/pywikibot/page/_wikibase.py
+++ b/pywikibot/page/_wikibase.py
@@ -487,6 +487,60 @@
self._assert_has_id()
return super().getID(numeric=numeric)
+ def editLabels(self, labels: LANGUAGE_TYPE, **kwargs) -> None:
+ """Edit MediaInfo labels (eg. captions).
+
+ *labels* should be a dict, with the key as a language or a site
+ object. The value should be the string to set it to. You can set
+ it to ``''`` to remove the label.
+
+ Usage:
+
+ >>> repo = pywikibot.Site('commons','commons')
+ >>> page = pywikibot.FilePage(repo, 'File:Sandbox-Test.svg')
+ >>> item = page.data_item()
+ >>> item.editLabels({'en': 'Test file.'}) # doctest:
+SKIP
+ """
+ data = {'labels': labels}
+ self.editEntity(data, **kwargs)
+
+ def addClaim(self, claim, bot: bool = True, **kwargs):
+ """
+ Add a claim to the MediaInfo.
+
+ :param claim: The claim to add
+ :type claim: pywikibot.page.Claim
+ :param bot: Whether to flag as bot (if possible)
+ """
+ if claim.on_item is not None:
+ raise ValueError(
+ 'The provided Claim instance is already used in an entity')
+
+ self._assert_has_id()
+ if not hasattr(self, '_revid'):
+ # workaround for uninitialized mediainfo's
+ self._revid = self.file.latest_revision_id
+
+ self.repo.addClaim(self, claim, bot=bot, **kwargs)
+ claim.on_item = self
+
+ def removeClaims(self, claims, **kwargs) -> None:
+ """
+ Remove the claims from the MediaInfo.
+
+ :param claims: list of claims to be removed
+ :type claims: list or pywikibot.Claim
+ """
+ # this check allows single claims to be removed by pushing them into a
+ # list of length one.
+ if isinstance(claims, pywikibot.Claim):
+ claims = [claims]
+ data = self.repo.removeClaims(claims, **kwargs)
+ for claim in claims:
+ claim.on_item.latest_revision_id =
data['pageinfo']['lastrevid']
+ claim.on_item = None
+ claim.snak = None
+
class WikibasePage(BasePage, WikibaseEntity):
diff --git a/tests/file_tests.py b/tests/file_tests.py
index 8a252c4..0f59774 100755
--- a/tests/file_tests.py
+++ b/tests/file_tests.py
@@ -17,6 +17,7 @@
NoPageError,
NoWikibaseEntityError,
PageRelatedError,
+ UserRightsError,
)
from pywikibot import pagegenerators
from tests import join_images_path
@@ -405,27 +406,31 @@
)
# Seek to first page without mediainfo.
- for page in gen:
- if 'mediainfo' in page.latest_revision.slots:
- continue
+ # Retry loop is for excepting incorrect files
+ for retry in range(5):
+ try:
+ for page in gen:
+ slots = page.latest_revision.slots
+ if 'mediainfo' not in slots:
+ break
+ break
+ except ValueError:
+ pass
- item = page.data_item()
- self.assertIsInstance(item, pywikibot.MediaInfo)
+ item = page.data_item()
+ self.assertIsInstance(item, pywikibot.MediaInfo)
- # Get fails as there is no mediainfo.
- with self.assertRaises(NoWikibaseEntityError):
- item.get()
+ # Get fails as there is no mediainfo.
+ with self.assertRaises(NoWikibaseEntityError):
+ item.get()
- self.assertFalse(item.exists())
- self.assertEqual(f'M{page.pageid}', item.id)
- self.assertIsInstance(
- item.labels, pywikibot.page._collections.LanguageDict)
- self.assertIsInstance(
- item.statements,
- pywikibot.page._collections.ClaimCollection)
-
- # break the loop after checking first file
- break
+ self.assertFalse(item.exists())
+ self.assertEqual(f'M{page.pageid}', item.id)
+ self.assertIsInstance(
+ item.labels, pywikibot.page._collections.LanguageDict)
+ self.assertIsInstance(
+ item.statements,
+ pywikibot.page._collections.ClaimCollection)
def test_data_list_to_dict_workaround(self):
"""Test that T222159 workaround converts [] to
{}."""
@@ -441,6 +446,112 @@
item.statements, pywikibot.page._collections.ClaimCollection)
+class TestMediaInfoReadonlyEditing(TestCase):
+
+ """Test writing structured data of FilePage."""
+
+ # Create valid API requests which will fail to missing permission.
+
+ #
commons.wikimedia.beta.wmflabs.org
+ family = 'commons'
+ code = 'beta'
+
+ def test_edit_label(self):
+ """Test label editing without writing rights."""
+ page = pywikibot.FilePage(self.site, 'File:123_4.jpg')
+ item = page.data_item()
+ error_message = 'User "None" does not have required user right
"edit"'
+
+ data = {}
+ lang = 'fi'
+ label = 'Edit label with editEntity and dict()'
+ data.update({'labels': {lang: label}})
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ item.editEntity(data, summary=label)
+
+ data = item.get()
+ label = 'Edit label with editEntity and item.get()'
+ data.update({'labels': {lang: label}})
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ item.editEntity(data, summary=label)
+
+ data = item.get(force=True)
+ label = 'Edit label with editEntity and item.get(force=True)'
+ data.update({'labels': {lang: label}})
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ item.editEntity(data, summary=label)
+
+ lang = 'fi'
+ label = 'Edit label with editLabels and dict()'
+ data = {lang: label}
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ item.editLabels(data, summary=label)
+
+ # Test label editing when file doesn't exists
+ page = pywikibot.FilePage(self.site, 'File:123_4_DOESNT_EXISTS.jpg')
+ item = page.data_item()
+
+ data = {}
+ lang = 'fi'
+ label = 'Edit label of missing file with editEntity and dict()'
+ data.update({'labels': {lang: label}})
+ with self.assertRaises(UserRightsError):
+ item.editEntity(data, summary=label)
+
+ lang = 'fi'
+ label = 'Edit label of missing file with editLabels and dict()'
+ data = {lang: label}
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ item.editLabels(data, summary=label)
+
+ def test_edit_claims(self):
+ """Test claim editing without writing rights."""
+ error_message = 'User "None" does not have required user right
"edit"'
+ wikidata_site = pywikibot.Site('wikidata', 'wikidata')
+
+ # Test adding claim existing file
+ page = pywikibot.FilePage(self.site, 'File:123_4.jpg')
+ item = page.data_item()
+
+ # Create claim
+ finna_id = 'test123'
+ new_claim = pywikibot.Claim(wikidata_site, 'P9478')
+ new_claim.setTarget(finna_id)
+
+ # Do actual edit
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ item.addClaim(new_claim)
+
+ # Test removing first claim using item.statements
+ for property_id in item.statements:
+ for statement in item.statements[property_id]:
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ summary = f'Removing {property_id}'
+ item.removeClaims(statement, summary=summary)
+ break
+
+ # Test removing first claim using item.claims
+ for property_id in item.claims:
+ for claim in item.claims[property_id]:
+ with self.assertRaisesRegex(UserRightsError, error_message):
+ summary = f'Removing {property_id}'
+ item.removeClaims(claim, summary=summary)
+ break
+
+ # Test adding claim to non-existing file
+ page = pywikibot.FilePage(self.site, 'File:123_4_DOESNT_EXISTS.jpg')
+ item = page.data_item()
+
+ # Create claim
+ finna_id = 'test123'
+ new_claim = pywikibot.Claim(wikidata_site, 'P9478')
+ new_claim.setTarget(finna_id)
+
+ # Do actual edit
+ with self.assertRaises(NoWikibaseEntityError):
+ item.addClaim(new_claim)
+
+
if __name__ == '__main__': # pragma: no cover
with suppress(SystemExit):
unittest.main()
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/968553
To unsubscribe, or for help writing mail filters, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ic3822e4b10419fabb26bae9a7756c8c39bbbe7a0
Gerrit-Change-Number: 968553
Gerrit-PatchSet: 3
Gerrit-Owner: Zache-tool <kimmo.virtanen(a)gmail.com>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged