Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 83 additions & 12 deletions pywikibot/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -3914,7 +3914,22 @@ def latest_revision_id(self):
self.clear_cache()

@staticmethod
def _normalizeLanguages(data):
def _normalizeLanguage(value):
"""
Helper function to replace a site object with its language code.

@param value: The value to normalize
@type value: str|pywikibot.site.BaseSite

@return: the language string
@rtype: str
"""
if isinstance(value, pywikibot.site.BaseSite):
return value.lang
return value

@classmethod
def _normalizeLanguages(cls, data):
"""
Helper function to replace site objects with their language codes.

Expand All @@ -3924,11 +3939,10 @@ def _normalizeLanguages(data):
@return: the altered dict from parameter data.
@rtype: dict
"""
for key in data:
if isinstance(key, pywikibot.site.BaseSite):
data[key.lang] = data[key]
del data[key]
return data
return {
cls._normalizeLanguage(key): value
for key, value in data.items()
}

@classmethod
def _normalizeData(cls, data):
Expand Down Expand Up @@ -4013,17 +4027,70 @@ def editEntity(self, data=None, **kwargs):
self._content = updates['entity']
self.get()

@allow_asynchronous
def setLabel(self, language, value, **kwargs):
"""
Set/edit a label using the Wikibase wbsetlabel API.

To set labels in multiple languages, use the editLabels method instead.

@param language: Label language code or Site
@type language: str or L{pywikibot.site.BaseSite}
@param value: Label value string
@type value: str
@keyword asynchronous: if True, launch a separate thread to add claim
asynchronously
@type asynchronous: bool
@keyword callback: a callable object that will be called after the entity
has been updated. It must take two arguments: (1) a WikibasePage
object, and (2) an exception instance, which will be None if the
page was saved successfully. This is intended for use by bots that
need to keep track of which saves were successful.
@type callback: callable
"""
self.repo.setLabel(self, self._normalizeLanguage(language), value,
**kwargs)

def editLabels(self, labels, **kwargs):
"""
Edit entity labels.

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.
@param labels: 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.
@type labels: dict
"""
data = {'labels': labels}
self.editEntity(data, **kwargs)
if len(labels.items()) == 1:
language, value = list(labels.items())[0]
self.setLabel(language, value)
else:
self.editEntity(data, **kwargs)

@allow_asynchronous
def setDescription(self, language, value, **kwargs):
"""
Set/edit a description using the Wikibase wbsetdescription API.

To set descriptions in multiple languages, use the editDescriptions
method instead.

@param language: Description language code or Site
@type language: str or L{pywikibot.site.BaseSite}
@param value: Description value string
@type value: str
@keyword asynchronous: if True, launch a separate thread to add claim
asynchronously
@type asynchronous: bool
@keyword callback: a callable object that will be called after the entity
has been updated. It must take two arguments: (1) a WikibasePage
object, and (2) an exception instance, which will be None if the
page was saved successfully. This is intended for use by bots that
need to keep track of which saves were successful.
@type callback: callable
"""
self.repo.setDescription(self, self._normalizeLanguage(language), value,
**kwargs)

def editDescriptions(self, descriptions, **kwargs):
"""
Expand All @@ -4035,7 +4102,11 @@ def editDescriptions(self, descriptions, **kwargs):
You can set it to '' to remove the description.
"""
data = {'descriptions': descriptions}
self.editEntity(data, **kwargs)
if len(descriptions.items()) == 1:
language, value = list(descriptions.items())[0]
self.setDescription(language, value)
else:
self.editEntity(data, **kwargs)

def editAliases(self, aliases, **kwargs):
"""
Expand Down
54 changes: 54 additions & 0 deletions pywikibot/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -7928,3 +7928,57 @@ def search_entities(self, search, language, limit=None, **kwargs):
if limit is not None:
gen.set_maximum_items(limit)
return gen

@must_be(group='user')
def setLabel(self, item, language, value, bot=True, summary=None):
"""
Set or edit a label.

@param item: Entity to modify
@type item: WikibasePage
@param language: Label language code
@type language: str
@param value: Label value
@type value: str
@param bot: Whether to mark the edit as a bot edit
@type bot: bool
@param summary: Edit summary
@type summary: str
"""
params = {'action': 'wbsetlabel', 'id': item.getID(),
'baserevid': item.latest_revision_id,
'language': language, 'value': value,
'summary': summary, 'bot': bot,
'token': self.tokens['edit']}
req = self._simple_request(**params)
data = req.submit()
# Update the item
item.labels[language] = value
item.latest_revision_id = data['entity']['lastrevid']

@must_be(group='user')
def setDescription(self, item, language, value, bot=True, summary=None):
"""
Set or edit a description.

@param item: Entity to modify
@type item: WikibasePage
@param language: Description language code
@type language: str
@param value: Description value
@type value: str
@param bot: Whether to mark the edit as a bot edit
@type bot: bool
@param summary: Edit summary
@type summary: str
"""
params = {'action': 'wbsetdescription', 'id': item.getID(),
'baserevid': item.latest_revision_id,
'language': language, 'value': value,
'summary': summary, 'bot': bot,
'token': self.tokens['edit']}
req = self._simple_request(**params)
data = req.submit()
# Update the item
item.descriptions[language] = value
item.latest_revision_id = data['entity']['lastrevid']
30 changes: 30 additions & 0 deletions tests/wikibase_edit_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ def test_label_set(self):
item.get(force=True)
self.assertEqual(item.labels['en'], 'Test123')

def test_label_set_using_wbsetlabel(self):
"""Test setting a Bokmål label using the wbsetlabel endpoint."""
item = pywikibot.ItemPage(self.get_repo(), 'Q68')
self.assertIsInstance(item, pywikibot.ItemPage)
item.setLabel('nb', 'Testetikett æøå')
self.assertEqual(item.labels['nb'], 'Testetikett æøå')
item.get(force=True)
self.assertEqual(item.labels['nb'], 'Testetikett æøå')

def test_label_set_using_wbsetlabel_with_invalid_language_code(self):
"""Test setting a Bokmål label using wbsetlabel."""
item = pywikibot.ItemPage(self.get_repo(), 'Q68')
self.assertIsInstance(item, pywikibot.ItemPage)
try:
item.setLabel('123', 'Test')
except pywikibot.exceptions.OtherPageSaveError as err:
self.assertEqual('unknown_language', err.reason.code)
self.assertEqual('Unrecognized value for parameter "language": 123.',
err.reason.info)
self.assertIsNone(item.labels.get('123'))

def test_label_remove(self):
"""Test adding a Farsi and English label and removing the Farsi one."""
testsite = self.get_repo()
Expand All @@ -59,6 +80,15 @@ def test_label_remove(self):
item.get()
self.assertNotIn('fa', item.labels.keys())

def test_description_set_using_wbsetdescription(self):
"""Test setting a Bokmål description using wbsetdescription."""
item = pywikibot.ItemPage(self.get_repo(), 'Q68')
self.assertIsInstance(item, pywikibot.ItemPage)
item.setDescription('nb', 'testbeskrivelse æøå')
self.assertEqual(item.descriptions['nb'], 'testbeskrivelse æøå')
item.get(force=True)
self.assertEqual(item.descriptions['nb'], 'testbeskrivelse æøå')

def test_alias_set(self):
"""Test setting an English alias."""
testsite = self.get_repo()
Expand Down