forked from wikimedia/pywikibot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclaimit.py
executable file
·159 lines (120 loc) · 5.19 KB
/
claimit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/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 Q456
You can use any typical pagegenerator (like categories) to provide with a
list 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.0001
By default, claimit.py does not add a claim if one with the same property
already exists on the page. To override this behavior, use the 'exists' option:
python pwb.py claimit [pagegenerators] P246 "string example" -exists:p
Suppose the claim you want to add has the same property as an existing claim
and the "-exists:p" argument is used. Now, claimit.py will not add the claim
if 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 same
property and target and some qualifiers already exists:
python pwb.py claimit [pagegenerators] P246 "string example" -exists:ptq
Note that the ordering of the letters in the 'exists' argument does not matter,
but 'p' must be included.
"""
#
# (C) Pywikibot team, 2013-2023
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
import pywikibot
from pywikibot import WikidataBot, pagegenerators
from pywikibot.backports import batched, 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
class ClaimRobot(WikidataBot):
"""A bot to add Wikidata claims."""
use_from_page = None
def __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'] = True
super().__init__(**kwargs)
self.claims = claims
self.exists_arg = ''.join(x for x in exists_arg.lower() if x in 'pqst')
self.cacheSources()
if self.exists_arg:
pywikibot.info(f"'exists' argument set to '{self.exists_arg}'")
def treat_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
"""
for claim in self.claims:
# The generator might yield pages from multiple sites
site = page.site if page is not None else None
self.user_add_claim_unless_exists(
item, claim.copy(), self.exists_arg, site)
def main(*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 parser
local_args = pywikibot.handle_args(args)
gen = pagegenerators.GeneratorFactory()
for arg in local_args:
# Handle args specifying how to handle duplicate claims
if arg.startswith('-exists:'):
exists_arg = removeprefix(arg, '-exists:')
continue
# Handle page generator args
if gen.handle_arg(arg):
continue
commandline_claims.append(arg)
if len(commandline_claims) % 2:
pywikibot.error('Incomplete command line property-value pair.')
return
claims = []
repo = pywikibot.Site().data_repository()
for property_id, target_str in batched(commandline_claims, 2):
claim = pywikibot.Claim(repo, property_id)
if claim.type == 'wikibase-item':
target = pywikibot.ItemPage(repo, target_str)
elif claim.type == 'string':
target = target_str
elif claim.type == 'globe-coordinate':
coord_args = [
float(c) for c in target_str.split(',')]
precision = coord_args[2] if len(coord_args) >= 3 else 0.0001
target = pywikibot.Coordinate(
coord_args[0], coord_args[1], precision=precision)
else:
raise NotImplementedError(
f'{claim.type} datatype is not yet supported by claimit.py')
claim.setTarget(target)
claims.append(claim)
generator = gen.getCombinedGenerator()
if not generator:
pywikibot.bot.suggest_help(missing_generator=True)
return
bot = ClaimRobot(claims, exists_arg, generator=generator)
bot.run()
if __name__ == '__main__':
main()