Legoktm has submitted this change and it was merged.
Change subject: Support to add a reference with multiple claims. ......................................................................
Support to add a reference with multiple claims.
site.editSource() accepts now either a single claim (=backward-compatible) for a single claim reference or a list of claims for a multi claim reference
page.addSources() is new and takes a list of claims in contrast to page.addSource()
Claim.sources is a list of dicts now. Thus, it is possible to check if a property is contained.
Change-Id: Iac583043531ba3f30985244ffad2aef2ad549f51 --- M pywikibot/page.py M pywikibot/site.py 2 files changed, 65 insertions(+), 34 deletions(-)
Approvals: Legoktm: Verified; Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py index 8816da2..bb87d46 100644 --- a/pywikibot/page.py +++ b/pywikibot/page.py @@ -87,8 +87,8 @@ self._revisions = {} else: raise pywikibot.Error( - "Invalid argument type '%s' in Page constructor: %s" - % (type(source), source)) + "Invalid argument type '%s' in Page constructor: %s" + % (type(source), source))
@property def site(self): @@ -2741,9 +2741,15 @@ bit differently, and require some more handling. """ - mainsnak = data['snaks'].values()[0][0] - wrap = {'mainsnak': mainsnak, 'hash': data['hash']} - return Claim.fromJSON(site, wrap) + source = {} + for prop in data['snaks'].values(): + for claimsnak in prop: + claim = Claim.fromJSON(site, {'mainsnak': claimsnak, 'hash': data['hash']}) + if claim.getID() in source: + source[claim.getID()].append(claim) + else: + source[claim.getID()] = [claim] + return source
@staticmethod def qualifierFromJSON(site, data): @@ -2754,7 +2760,6 @@ """ wrap = {'mainsnak': data} return Claim.fromJSON(site, wrap) -
def setTarget(self, value): """ @@ -2815,18 +2820,33 @@
def getSources(self): """ - Returns a list of Claims + Returns a list of sources. Each source is a list of Claims. """ return self.sources
- def addSource(self, source, **kwargs): + def addSource(self, claim, **kwargs): """ - source is a Claim. - adds it as a reference. + Adds the claim as a source. + @param claim: the claim to add + @type claim: pywikibot.Claim """ - data = self.repo.editSource(self, source, new=True, **kwargs) - source.hash = data['reference']['hash'] - self.on_item.lastrevid = data['pageinfo']['lastrevid'] + self.addSources([claim], **kwargs) + + def addSources(self, claims, **kwargs): + """ + Adds the claims as one source. + @param claims: the claims to add + @type claims: list of pywikibot.Claim + """ + data = self.repo.editSource(self, claims, new=True, **kwargs) + source = {} + for claim in claims: + claim.hash = data['reference']['hash'] + self.on_item.lastrevid = data['pageinfo']['lastrevid'] + if claim.getID() in source: + source[claim.getID()].append(claim) + else: + source[claim.getID()] = [claim] self.sources.append(source)
def _formatDataValue(self): @@ -2845,8 +2865,6 @@ else: raise NotImplementedError('%s datatype is not supported yet.' % self.getType()) return value - -
class Revision(object): diff --git a/pywikibot/site.py b/pywikibot/site.py index 4e5dfaf..2d8142e 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -3385,7 +3385,7 @@ """get the data for multiple Wikibase items""" if type(source) == int or \ isinstance(source, basestring) and source.isdigit(): - ids = 'q'+str(source) + ids = 'q' + str(source) wbrequest = api.Request(site=self, action="wbgetentities", ids=ids, **params) wbdata = wbrequest.submit() @@ -3435,7 +3435,7 @@ #Store it for 100 years req = api.CachedRequest(expiry, site=self, **params) data = req.submit() - dtype = data['entities'][prop.getID()]['datatype'] + dtype = data['entities'][prop.getID()]['datatype'] if dtype == 'globe-coordinate': dtype = 'globecoordinate' #TODO Fix this @@ -3535,25 +3535,38 @@ if bot: params['bot'] = 1 params['token'] = self.token(claim, 'edit') - if not new and hasattr(source, 'hash'): - params['reference'] = source.hash #build up the snak - if source.getType() == 'wikibase-item': - datavalue = {'type': 'wikibase-entityid', - 'value': source._formatDataValue(), - } - elif source.getType() == 'string': - datavalue = {'type': 'string', - 'value': source._formatDataValue(), - } + if isinstance(source, list): + sources = source else: - raise NotImplementedError('%s datatype is not supported yet.' % claim.getType()) - snak = {source.getID(): [{'snaktype': 'value', - 'property': source.getID(), - 'datavalue': datavalue, - }, - ], - } + sources = [source] + + snak = {} + for sourceclaim in sources: + if sourceclaim.getType() == 'wikibase-item': + datavalue = {'type': 'wikibase-entityid', + 'value': sourceclaim._formatDataValue(), + } + elif sourceclaim.getType() == 'string': + datavalue = {'type': 'string', + 'value': sourceclaim._formatDataValue(), + } + else: + raise NotImplementedError('%s datatype is not supported yet.' % sourceclaim.getType()) + valuesnaks = [] + if sourceclaim.getID() in snak: + valuesnaks = snak[sourceclaim.getID()] + valuesnaks.append({'snaktype': 'value', + 'property': sourceclaim.getID(), + 'datavalue': datavalue, + }, + ) + + snak[sourceclaim.getID()] = valuesnaks + # set the hash if the source should be changed. if present, all claims of one source have the same hash + if not new and hasattr(sourceclaim, 'hash'): + params['reference'] = sourceclaim.hash + params['snaks'] = json.dumps(snak) for arg in kwargs: if arg in ['bot', 'lastrevid']:
pywikibot-commits@lists.wikimedia.org