#!/usr/bin/env python3"""A script that adds claims to Wikidata items based on a list of pages.These command line parameters can be used to specify which pages to work on:¶ms;Usage: python pwb.py claimit [pagegenerators] P1 Q2 P123 Q456You can use any typical pagegenerator (like categories) to provide with alist of pages. Then list the property-->target pairs to add.For geographic coordinates: python pwb.py claimit [pagegenerators] P625 [lat-dec],[long-dec],[prec][lat-dec] and [long-dec] represent the latitude and longitude respectively,and [prec] represents the precision. All values are in decimal degrees,not DMS. If [prec] is omitted, the default precision is 0.0001 degrees.Example: python pwb.py claimit [pagegenerators] P625 -23.3991,-52.0910,0.0001By default, claimit.py does not add a claim if one with the same propertyalready exists on the page. To override this behavior, use the 'exists' option: python pwb.py claimit [pagegenerators] P246 "string example" -exists:pSuppose the claim you want to add has the same property as an existing claimand the "-exists:p" argument is used. Now, claimit.py will not add the claimif it has the same target, source, and/or the existing claim has qualifiers.To override this behavior, add 't' (target), 's' (sources), or 'q' (qualifiers)to the 'exists' argument.For instance, to add the claim to each page even if one with the sameproperty and target and some qualifiers already exists: python pwb.py claimit [pagegenerators] P246 "string example" -exists:ptqNote that the ordering of the letters in the 'exists' argument does not matter,but 'p' must be included."""## (C) Pywikibot team, 2013-2024## Distributed under the terms of the MIT license.#from__future__importannotationsimportpywikibotfrompywikibotimportWikidataBot,pagegeneratorsfrompywikibot.backportsimportbatched,removeprefix# This is required for the text that is shown when you run this script# with the parameter -help or without parameters.docuReplacements={'¶ms;':pagegenerators.parameterHelp}# noqa: N816
[docs]classClaimRobot(WikidataBot):"""A bot to add Wikidata claims."""use_from_page=Nonedef__init__(self,claims,exists_arg:str='',**kwargs)->None:"""Initializer. :param claims: A list of wikidata claims :type claims: list :param exists_arg: String specifying how to handle duplicate claims """self.available_options['always']=Truesuper().__init__(**kwargs)self.claims=claimsself.exists_arg=''.join(xforxinexists_arg.lower()ifxin'pqst')self.cacheSources()ifself.exists_arg:pywikibot.info(f"'exists' argument set to '{self.exists_arg}'")
[docs]deftreat_page_and_item(self,page,item)->None:"""Treat each page. :param page: The page to update and change :type page: pywikibot.page.BasePage :param item: The item to treat :type item: pywikibot.page.ItemPage """forclaiminself.claims:# The generator might yield pages from multiple sitessite=page.siteifpageisnotNoneelseNoneself.user_add_claim_unless_exists(item,claim.copy(),self.exists_arg,site)
[docs]defmain(*args:str)->None:""" Process command line arguments and invoke bot. If args is an empty list, sys.argv is used. :param args: command line arguments """exists_arg=''commandline_claims=[]# Process global args and prepare generator args parserlocal_args=pywikibot.handle_args(args)gen=pagegenerators.GeneratorFactory()forarginlocal_args:# Handle args specifying how to handle duplicate claimsifarg.startswith('-exists:'):exists_arg=removeprefix(arg,'-exists:')continue# Handle page generator argsifgen.handle_arg(arg):continuecommandline_claims.append(arg)iflen(commandline_claims)%2:pywikibot.error('Incomplete command line property-value pair.')returnclaims=[]repo=pywikibot.Site().data_repository()forproperty_id,target_strinbatched(commandline_claims,2):claim=pywikibot.Claim(repo,property_id)ifclaim.type=='wikibase-item':target=pywikibot.ItemPage(repo,target_str)elifclaim.type=='string':target=target_strelifclaim.type=='globe-coordinate':coord_args=[float(c)forcintarget_str.split(',')]# Default value 0.0001 ~10 m at equatorprecision=coord_args[2]iflen(coord_args)>=3else0.0001target=pywikibot.Coordinate(coord_args[0],coord_args[1],precision=precision)else:raiseNotImplementedError(f'{claim.type} datatype is not yet supported by claimit.py')claim.setTarget(target)claims.append(claim)generator=gen.getCombinedGenerator()bot=ClaimRobot(claims,exists_arg,generator=generator)bot.run()