jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/637872 )

Change subject: [IMPR] add support for some 'wbset' actions in DataSite
......................................................................

[IMPR] add support for some 'wbset' actions in DataSite

It can be useful for atomic operations as the API add automatic summary,
which creates a cleaner page history.

To be decided: add support also at page level or not, given that
method for supporting such actions are present via editEntity.

Change-Id: Idfd5de485d2b5aab8d8b1960ceb3c3a3c6b64315
---
M pywikibot/site/__init__.py
M tests/wikibase_edit_tests.py
2 files changed, 199 insertions(+), 0 deletions(-)

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



diff --git a/pywikibot/site/__init__.py b/pywikibot/site/__init__.py
index c21feb2..f33c42e 100644
--- a/pywikibot/site/__init__.py
+++ b/pywikibot/site/__init__.py
@@ -7637,6 +7637,146 @@
                               total=total, parameters=parameters)
         return gen

+    def _wbset_action(self, itemdef, action, action_data, **kwargs):
+        """
+        Execute wbset{action}' on a Wikibase item.
+
+        Supported actions are:
+            wbsetaliases, wbsetdescription, wbsetlabel and wbsetsitelink
+
+        @param itemdef: Item to modify or create
+        @type itemdef: str, WikibasePage or Page coonected to such item
+        @param action: wbset{action] to perform:
+            'wbsetaliases', 'wbsetdescription', 'wbsetlabel', 'wbsetsitelink'
+        @type action: str
+        @param data: data to be used in API request, see API help
+        @type data: SiteLink or dict
+            wbsetaliases:
+                dict shall have the following structure:
+                {'language': value (str),
+                 'add': list of language codes (str),
+                 'remove': list of language codes (str),
+                 'set' list of language codes (str)
+                  }
+                'add' and 'remove' are alternative to 'set'
+            wbsetdescription and wbsetlabel:
+                dict shall have keys 'language', 'value'
+            wbsetsitelink:
+                dict shall have keys 'linksite', 'linktitle' and
+                optionally 'badges'
+        @kwargs bot: Whether to mark the edit as a bot edit, default is False
+        @type bot: bool
+        @return: query result
+        @rtype: dict
+        @raises AssertionError, TypeError
+        """
+        def format_sitelink(sitelink):
+            """Convert SiteLink to a dict accepted by wbsetsitelink API."""
+            if isinstance(sitelink, pywikibot.page.SiteLink):
+                _dict = {
+                    'linksite': sitelink._sitekey,
+                    'linktitle': sitelink._rawtitle,
+                    'badges': '|'.join([b.title() for b in sitelink.badges]),
+                }
+            else:
+                _dict = sitelink
+
+            return _dict
+
+        def prepare_data(action, data):
+            """Prepare data as expected by API."""
+            if action == 'wbsetaliases':
+                res = data
+                keys = set(res)
+                assert keys < {'language', 'add', 'remove', 'set'}
+                assert keys & {'add', 'set'} == {}
+                assert keys & {'remove', 'set'} == {}
+            elif action in ('wbsetlabel', 'wbsetdescription'):
+                res = data
+                keys = set(res)
+                assert keys == {'language', 'value'}
+            elif action == 'wbsetsitelink':
+                res = format_sitelink(data)
+                keys = set(res)
+                assert keys >= {'linksite'}
+                assert keys <= {'linksite', 'linktitle', 'badges'}
+            else:
+                raise ValueError('Something has gone wrong ...')
+
+            return res
+
+        # Supported actions
+        assert action in ('wbsetaliases', 'wbsetdescription',
+                          'wbsetlabel', 'wbsetsitelink'), \
+            'action {} not supported.'.format(action)
+
+        # prefer ID over (site, title)
+        if isinstance(itemdef, str):
+            itemdef = pywikibot.ItemPage(self, itemdef)
+        elif isinstance(itemdef, pywikibot.Page):
+            try:
+                itemdef = itemdef.data_item()
+            except pywikibot.NoPage:
+                itemdef = pywikibot.ItemPage(self)
+        if not isinstance(itemdef, pywikibot.page.WikibasePage):
+            raise TypeError('itemdef shall be str, WikibasePage or Page')
+
+        params = itemdef._defined_by(singular=True)
+        # TODO: support 'new'
+        baserevid = kwargs.pop('baserevid', 0) or itemdef.latest_revision_id
+        params.update(
+            {'id': itemdef.id,
+             'baserevid': baserevid,
+             'action': action,
+             'token': self.tokens['edit'],
+             'bot': kwargs.pop('bot', False),
+             })
+        params.update(prepare_data(action, action_data))
+
+        for arg in kwargs:
+            if arg in ['summary']:
+                params[arg] = kwargs[arg]
+            else:
+                warn('Unknown parameter {} for action  {}, ignored'
+                     .format(arg, action), UserWarning, 2)
+
+        req = self._simple_request(**params)
+        data = req.submit()
+        return data
+
+    def wbsetaliases(self, itemdef, aliases, **kwargs):
+        """
+        Set aliases for a single Wikibase entity.
+
+        See self._wbset_action(self, itemdef, action, action_data, **kwargs)
+        """
+        return self._wbset_action(itemdef, 'wbsetaliases', aliases, **kwargs)
+
+    def wbsetdescription(self, itemdef, description, **kwargs):
+        """
+        Set description for a single Wikibase entity.
+
+        See self._wbset_action(self, itemdef, action, action_data, **kwargs)
+        """
+        return self._wbset_action(itemdef, 'wbsetdescription', description,
+                                  **kwargs)
+
+    def wbsetlabel(self, itemdef, label, **kwargs):
+        """
+        Set label for a single Wikibase entity.
+
+        See self._wbset_action(self, itemdef, action, action_data, **kwargs)
+        """
+        return self._wbset_action(itemdef, 'wbsetlabel', label, **kwargs)
+
+    def wbsetsitelink(self, itemdef, sitelink, **kwargs):
+        """
+        Set, remove or modify a sitelink on a Wikibase item.
+
+        See self._wbset_action(self, itemdef, action, action_data, **kwargs)
+        """
+        return self._wbset_action(itemdef, 'wbsetsitelink', sitelink, **kwargs)
+

 wrapper = ModuleDeprecationWrapper(__name__)
 # Note: use LoginStatus instead of _LoginStatus
diff --git a/tests/wikibase_edit_tests.py b/tests/wikibase_edit_tests.py
index e8ece10..a75fd81 100644
--- a/tests/wikibase_edit_tests.py
+++ b/tests/wikibase_edit_tests.py
@@ -458,6 +458,65 @@
         self.assertNotIn('P88', claim.qualifiers.keys())


+class TestWikibaseDataSiteWbsetActions(WikibaseTestCase):
+
+    """Run general wikibase write tests."""
+
+    family = 'wikidata'
+    code = 'test'
+
+    user = True
+    write = True
+
+    def setUp(self):
+        """Setup tests."""
+        self.testsite = self.get_repo()
+        self.item = pywikibot.ItemPage(self.testsite, 'Q68')
+        badge = pywikibot.ItemPage(self.testsite, 'Q608')
+        self.sitelink = pywikibot.page.SiteLink('Test page',
+                                                site='enwikisource',
+                                                badges=[badge])
+        super().setUp()
+
+    def tearDown(self):
+        """Tear down tests."""
+        self.item = None
+        self.sitelink = None
+        super().tearDown()
+
+    def test_wbsetlabel_set_from_id(self):
+        """Test setting an Italian label using id."""
+        self.assertEqual(self.item.getID(), 'Q68')
+        self.testsite.wbsetlabel('Q68', {'language': 'it', 'value': 'Test123'})
+        self.item.get(force=True)
+        self.assertEqual(self.item.labels['it'], 'Test123')
+
+    def test_wbsetlabel_remove_from_item(self):
+        """Test removing an Italian label using item."""
+        self.assertEqual(self.item.getID(), 'Q68')
+        self.testsite.wbsetlabel(self.item, {'language': 'it', 'value': ''})
+        # Check 'it' label is removed
+        self.item.get(force=True)
+        self.assertNotIn('it', self.item.labels.keys())
+
+    def test_wbsetsitelink_set_remove(self):
+        """Test setting a sitelink using id."""
+        self.assertEqual(self.item.getID(), 'Q68')
+        # add sitelink
+        self.testsite.wbsetsitelink(
+            'Q68',
+            {'linksite': 'enwikisource',
+             'linktitle': 'Test page',
+             'badges': 'Q608'
+             })
+        self.item.get(force=True)
+        self.assertEqual(self.item.sitelinks['enwikisource'], self.sitelink)
+        # remove sitelink
+        self.testsite.wbsetsitelink(self.item, {'linksite': 'enwikisource'})
+        self.item.get(force=True)
+        self.assertIsNone(self.item.sitelinks.get('enwikisource'))
+
+
 if __name__ == '__main__':  # pragma: no cover
     with suppress(SystemExit):
         unittest.main()

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/637872
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: Idfd5de485d2b5aab8d8b1960ceb3c3a3c6b64315
Gerrit-Change-Number: 637872
Gerrit-PatchSet: 5
Gerrit-Owner: Mpaa <[email protected]>
Gerrit-Reviewer: Matěj Suchánek <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to