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 <[email protected]>
Gerrit-Reviewer: Matěj Suchánek <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to