-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathtemplatecount.py
executable file
·186 lines (146 loc) · 5.97 KB
/
templatecount.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/env python3
"""Display the list of pages transcluding a given list of templates.
It can also be used to simply count the number of pages (rather than
listing each individually).
Syntax:
python pwb.py templatecount options templates
Command line options:
-count Counts the number of times each template (passed in as an
argument) is transcluded.
-list Gives the list of all of the pages transcluding the templates
(rather than just counting them).
-namespace: Filters the search to a given namespace. If this is specified
multiple times it will search all given namespaces
Examples
--------
Counts how many times {{ref}} and {{note}} are transcluded in articles:
python pwb.py templatecount -count -namespace:0 ref note
Lists all the category pages that transclude {{cfd}} and {{cfdu}}:
python pwb.py templatecount -list -namespace:14 cfd cfdu
"""
#
# (C) Pywikibot team, 2006-2024
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
import pywikibot
from pywikibot.backports import Generator
class TemplateCountRobot:
"""Template count bot."""
@classmethod
def count_templates(cls, templates, namespaces) -> None:
"""Display number of transclusions for a list of templates.
Displays the number of transcluded page in the given 'namespaces' for
each template given by 'templates' list.
:param templates: list of template names
:type templates: list
:param namespaces: list of namespace numbers
:type namespaces: list
"""
formatstr = '{0:<10}: {1:>5}'
template_dict = cls.template_dict(templates, namespaces)
pywikibot.stdout('\nNumber of transclusions per template')
pywikibot.stdout('-' * 36)
total = 0
for key in template_dict:
count = len(template_dict[key])
pywikibot.stdout(formatstr.format(key, count))
total += count
pywikibot.stdout(formatstr.format('TOTAL', total))
pywikibot.stdout(
f'Report generated on {pywikibot.Timestamp.nowutc().isoformat()}')
@classmethod
def list_templates(cls, templates, namespaces) -> None:
"""Display transcluded pages for a list of templates.
Displays each transcluded page in the given 'namespaces' for
each template given by 'templates' list.
:param templates: list of template names
:type templates: list
:param namespaces: list of namespace numbers
:type namespaces: list
"""
template_dict = cls.template_dict(templates, namespaces)
pywikibot.stdout('\nList of pages transcluding templates:')
for key in templates:
pywikibot.info('* ' + key)
pywikibot.stdout('-' * 36)
total = 0
for key in template_dict:
for page in template_dict[key]:
pywikibot.stdout(page.title())
total += 1
pywikibot.info(f'Total page count: {total}')
pywikibot.stdout(
f'Report generated on {pywikibot.Timestamp.nowutc().isoformat()}')
@classmethod
def template_dict(cls, templates, namespaces) -> dict[
str, list[pywikibot.Page]]:
"""Create a dict of templates and its transcluded pages.
The names of the templates are the keys, and lists of pages
transcluding templates in the given namespaces are the values.
:param templates: list of template names
:type templates: list
:param namespaces: list of namespace numbers
:type namespaces: list
"""
return dict(cls.template_dict_generator(templates, namespaces))
@staticmethod
def template_dict_generator(templates, namespaces) -> Generator[
tuple[str, list[pywikibot.Page]], None, None]:
"""Yield transclusions of each template in 'templates'.
For each template in 'templates', yield a tuple
(template, transclusions), where 'transclusions' is a list of all pages
in 'namespaces' where the template has been transcluded.
:param templates: list of template names
:type templates: list
:param namespaces: list of namespace numbers
:type namespaces: list
"""
mysite = pywikibot.Site()
mytpl = mysite.namespaces.TEMPLATE
for template in templates:
gen = pywikibot.Page(mysite, template, ns=mytpl).getReferences(
namespaces=namespaces, only_template_inclusion=True)
yield template, list(gen)
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
"""
operation = None
args_list = []
namespaces = []
for arg in pywikibot.handle_args(args):
if arg in ('-count', '-list'):
operation = arg[1:]
elif arg.startswith('-namespace:'):
try:
namespaces.append(int(arg[len('-namespace:'):]))
except ValueError:
namespaces.append(arg[len('-namespace:'):])
else:
args_list.append(arg)
if not operation:
pywikibot.bot.suggest_help(missing_parameters=['operation'])
return
robot = TemplateCountRobot()
if not args_list:
args_list = ['ref', 'note', 'ref label', 'note label', 'reflist']
if 'reflist' in args_list:
pywikibot.info(
'NOTE: it will take a long time to count "reflist".')
choice = pywikibot.input_choice(
'Proceed anyway?',
[('yes', 'y'), ('no', 'n'), ('skip', 's')], 'y',
automatic_quit=False)
if choice == 's':
args_list.remove('reflist')
elif choice == 'n':
return
if operation == 'count':
robot.count_templates(args_list, namespaces)
elif operation == 'list':
robot.list_templates(args_list, namespaces)
if __name__ == '__main__':
main()