rbmediawiki 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ require 'page'
2
+ require 'generator'
3
+
4
+ class Page_generator
5
+ def initialize(site)
6
+ @site = site
7
+ end
8
+
9
+ #gets pages alphabetically from a certain start point
10
+ # * from: starting point (Default starts from the beginning)
11
+ # * limit: pages to get per query (default: 500)
12
+ # * prefix: Only list titles that start with this value
13
+ # * namespace: The namespace to enumerate. By default, the main namespace will be enumerated
14
+ # * How to filter redirects
15
+ # * all: List all pages regardless of their redirect flag (default)
16
+ # * redirects: Only list redirects
17
+ # * nonredirects: Don't list redirects
18
+ # * minsize: Only list pages that are at least this many bytes in size
19
+ # * maxsize: Only list pages that are at most this many bytes in size
20
+ # * prtype: Only list pages that have been protected from this type of action
21
+ # * edit: Only list edit-protected pages
22
+ # * move: Only list move-protected pages
23
+ # * prleve: Only list pages that have been protected at this level. Cannot be used without prtype
24
+ # * autoconfirmed: Only autoconfirmed users can edit/move/whatever
25
+ # * sysop: Only sysops can edit/move/whatever
26
+ # * Empty: Everyone can edit/move/whatever
27
+ # * prfiltercascade: Filter protections based on cascadingness (ignored when apprtype isn't set)
28
+ # * One value: cascading, noncascading, all
29
+ # * Default: all
30
+ # *filterlanglinks: Filter based on whether a page has langlinks
31
+ # * One value: withlanglinks, withoutlanglinks, all
32
+ # * Default: all
33
+ def all_pages(from = "!", limit = "500", prefix = nil, namespace = nil, filterredir = nil, minsize = nil, maxsize = nil, prtype = nil, prlevel = nil, prfiltercascade = nil, filterlanglinks = nil)
34
+ g = Generator.new { |g|
35
+ pages = Hash.new
36
+ count = 0
37
+ finish = false
38
+ while !finish
39
+ result = @site.query_list_allpages(nil, from, prefix, namespace, filterredir, minsize, maxsize, prtype, prlevel, prfiltercascade, limit, nil, filterlanglinks)
40
+ result['query']['allpages']['p'].each {|page|
41
+ g.yield Page.new(page['title'], @site)
42
+ }
43
+ if result.key?('query-continue')
44
+ from = result['query-continue']['allpages']['apfrom']
45
+ else
46
+ finish = true
47
+ end
48
+ end
49
+ }
50
+ end
51
+
52
+ def linksearch(euquery, eulimit = 500, eunamespace = 0)
53
+ g = Generator.new { |g|
54
+ pages = Hash.new
55
+ count = 0
56
+ finish = false
57
+ euoffset = nil
58
+ while !finish
59
+ result = @site.query_list_exturlusage(nil, nil, euoffset, nil, euquery, eunamespace, eulimit)
60
+ result['query']['exturlusage']['eu'].each {|page|
61
+ g.yield Page.new(page['title'], @site)
62
+ }
63
+ if result.key?('query-continue')
64
+ euoffset = result['query-continue']['exturlusage']['euoffset']
65
+ else
66
+ finish = true
67
+ end
68
+ end
69
+ }
70
+ end
71
+ def templateusage(eititle, eilimit = 500, einamespace = nil)
72
+ g = Generator.new { |g|
73
+ pages = Hash.new
74
+ finish = false
75
+ eioffset = nil
76
+ while !finish
77
+ result = @site.query_list_embeddedin(nil, eititle, eioffset, einamespace, nil, eilimit)
78
+ result['query']['embeddedin']['ei'].each {|page|
79
+ g.yield Page.new(page['title'], @site)
80
+ }
81
+ if result.key?('query-continue')
82
+ euoffset = result['query-continue']['embeddedin']['eioffset']
83
+ else
84
+ finish = true
85
+ end
86
+ end
87
+ }
88
+ end
89
+ def alllinks(alprefix, allimit = 500, alnamespace = nil)
90
+ g = Generator.new { |g|
91
+ pages = Hash.new
92
+ finish = false
93
+ aloffset = nil
94
+ while !finish
95
+ result = @site.query_list_alllinks(nil, aloffset, nil, alprefix, nil, nil, nil, alnamespace, allimit, nil, nil, true)
96
+ result['query']['alllinks']['l'].each {|page|
97
+ g.yield Page.new(page['title'], @site)
98
+ }
99
+ if result.key?('query-continue')
100
+ euoffset = result['query-continue']['alllinks']['alcontinue']
101
+ else
102
+ finish = true
103
+ end
104
+ end
105
+ }
106
+ end
107
+ def backlinks(bltitle, bllimit = 500, blnamespace = nil, blfilterredir = nil)
108
+ g = Generator.new { |g|
109
+ pages = Hash.new
110
+ finish = false
111
+ bloffset = nil
112
+ while !finish
113
+ result = @site.query_list_backlinks(nil, bltitle, bloffset, blnamespace, blfilterredir, bllimit, true )
114
+ result['query']['backlinks']['bl'].each {|page|
115
+ if page.key?('redirect')
116
+ page['redirlinks']['bl'].each {|page2|
117
+ g.yield Page.new(page2['title'], @site)
118
+ }
119
+ else
120
+ g.yield Page.new(page['title'], @site)
121
+ end
122
+ }
123
+ if result.key?('query-continue')
124
+ euoffset = result['query-continue']['backlinks']['blcontinue']
125
+ else
126
+ finish = true
127
+ end
128
+ end
129
+ }
130
+ end
131
+
132
+ #TODO
133
+ #opensearch
134
+ #prop links
135
+ #prop langlinks?
136
+ #prop images
137
+ #prop templates
138
+ #prop categories
139
+ #prop extlinks
140
+ #list allimages
141
+ #list allcategories
142
+ #list allusers
143
+ #list blocks
144
+ #list categorymembers
145
+ #list deletedrevs
146
+ #list imageusage
147
+ #list logevents
148
+ #list recentchanges
149
+ #list search
150
+ #list usercontribs
151
+ #list watchlist
152
+ #list exturlusage
153
+ #list users
154
+ #list random
155
+ #list protectedtitles
156
+ #list globalblocks
157
+ end
@@ -0,0 +1,6 @@
1
+ require 'api'
2
+ require 'page'
3
+ require 'category'
4
+ require 'user'
5
+ require 'page_generator'
6
+ require 'misc_generator'
data/lib/user.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'deep_merge'
2
+
3
+ require 'api'
4
+ require 'page'
5
+
6
+ class User
7
+ attr_reader :name
8
+ def initialize(name = nil, site = nil)
9
+ @username = name.gsub(" ","_")
10
+ @site = site
11
+ end
12
+
13
+ #blocks the user with the given reason
14
+ #the params are the usual block options
15
+ def block(expiry, reason, anononly = true, nocreate = true, autoblock = true, noemail = false, allowusertalk = true, reblock = false)
16
+ #require login
17
+ @site.login
18
+ result = @site.query_prop_info(@username, nil, 'block')
19
+ token = result['query']['pages']['page']['blocktoken']
20
+ result = @site.block(@username, token, nil, expiry, reason, anononly, nocreate, autoblock, noemail, nil, allowusertalk, reblock)
21
+ if result.key?('error')
22
+ raise RbykimediaError, "#{@username}: "+result['error']['code']
23
+ else
24
+ return true
25
+ end
26
+ end
27
+
28
+ #unblocks the user
29
+ def unblock(reason)
30
+ #require login
31
+ @site.login
32
+ result = @site.query_prop_info(@username, nil, 'unblock')
33
+ token = result['query']['pages']['page']['unblocktoken']
34
+ result = @site.unblock(nil, @username, token, nil, reason)
35
+ if result.key?('error')
36
+ raise RbykimediaError, "#{@username}: "+result['error']['code']
37
+ else
38
+ return true
39
+ end
40
+ end
41
+
42
+ #write a message in the user's talk page
43
+ def write_msg(msg, summary = nil)
44
+ page = Page.new("User talk:"+@username, @site)
45
+ return page.append(msg, summary, false)
46
+ end
47
+
48
+ #write an email to the user
49
+ def write_email(subject, text, ccme = nil)
50
+ #require login
51
+ @site.login
52
+ result = @site.query_prop_info(@username, nil, 'email')
53
+ puts result
54
+ token = result['query']['pages']['page']['emailtoken']
55
+ result = @site.emailuser(@username, subject, text, token, ccme)
56
+ if result.key?('error')
57
+ raise RbykimediaError, "#{@username}: "+result['error']['code']
58
+ else
59
+ return true
60
+ end
61
+ end
62
+
63
+ #info about the user
64
+ def info
65
+ result = @site.query_list_users(nil, "blockinfo|groups|editcount|registration|emailable", @username)
66
+ if result.key?('error')
67
+ raise RbykimediaError, "#{@username}: "+result['error']['code']
68
+ else
69
+ return result
70
+ end
71
+ end
72
+
73
+ #get user contributions
74
+ #returns false if there aren't any
75
+ def get_usercontribs(uclimit = 500, ucstart = nil, ucnamespace = nil)
76
+ uccontinue = nil
77
+ ucs = Hash.new
78
+ puts ucstart
79
+ loop {
80
+ result = @site.query_list_usercontribs(nil, uclimit, ucstart, nil, uccontinue, @username, nil, "newer", ucnamespace)
81
+ ucs.deep_merge!(result['query'])
82
+ if result.key?('query-continue')
83
+ ucstart = result['query-continue']['usercontribs']['ucstart']
84
+ else
85
+ break
86
+ end
87
+ }
88
+ if ucs['usercontribs'].key?('item')
89
+ return ucs['usercontribs']['item']
90
+ else
91
+ return false
92
+ end
93
+ end
94
+
95
+ #rollbacks (reverts) all edits by the user since a given time.
96
+ #"since" is a timestamp. Default will rollback everything.
97
+ #"namespace", if set, restricts the rollback to the given namespace
98
+ def rollback(since = nil, namespace = nil)
99
+ contribs = get_usercontribs(nil, since, nil)
100
+ array_c = Array.new
101
+ puts array_c
102
+ contribs.each{|c| array_c.push(c['title'])}
103
+ array_c.uniq!
104
+ puts array_c
105
+ array_c.each{|p|
106
+ page = Page.new(p, @site)
107
+ begin
108
+ page.rollback(@username, "desde aquí", false)
109
+ rescue RbykimediaError => error
110
+ puts error
111
+ end
112
+ }
113
+ end
114
+ end
data/util/desc ADDED
@@ -0,0 +1,308 @@
1
+ * action=expandtemplates *
2
+ This module expand all templates in wikitext
3
+
4
+ This module requires read rights.
5
+ Parameters:
6
+ title - Title of page
7
+ Default: API
8
+ text - Wikitext to convert
9
+ generatexml - Generate XML parse tree
10
+ Example:
11
+ api.php?action=expandtemplates&text={{Project:Sandbox}}
12
+
13
+ * action=parse *
14
+ This module parses wikitext and returns parser output
15
+
16
+ This module requires read rights.
17
+ Parameters:
18
+ title - Title of page the text belongs to
19
+ Default: API
20
+ text - Wikitext to parse
21
+ page - Parse the content of this page. Cannot be used together with text and title
22
+ redirects - If the page parameter is set to a redirect, resolve it
23
+ oldid - Parse the content of this revision. Overrides page
24
+ prop - Which pieces of information to get.
25
+ NOTE: Section tree is only generated if there are more than 4 sections, or if the __TOC__ keyword is present
26
+ Values (separate with '|'): text, langlinks, categories, links, templates, images, externallinks, sections, revid, displaytitle
27
+ Default: text|langlinks|categories|links|templates|images|externallinks|sections|revid|displaytitle
28
+ pst - Do a pre-save transform on the input before parsing it.
29
+ Ignored if page or oldid is used.
30
+ onlypst - Do a PST on the input, but don't parse it.
31
+ Returns PSTed wikitext. Ignored if page or oldid is used.
32
+ Example:
33
+ api.php?action=parse&text={{Project:Sandbox}}
34
+
35
+ * action=feedwatchlist *
36
+ This module returns a watchlist feed
37
+
38
+ This module requires read rights.
39
+ Parameters:
40
+ feedformat - The format of the feed
41
+ One value: rss, atom
42
+ Default: rss
43
+ hours - List pages modified within this many hours from now
44
+ The value must be between 1 and 72
45
+ Default: 24
46
+ allrev - Include multiple revisions of the same page within given timeframe.
47
+ Example:
48
+ api.php?action=feedwatchlist
49
+
50
+ * action=help *
51
+ Display this help screen.
52
+
53
+ * action=paraminfo *
54
+ Obtain information about certain API parameters
55
+ Parameters:
56
+ modules - List of module names (value of the action= parameter)
57
+ querymodules - List of query module names (value of prop=, meta= or list= parameter)
58
+ mainmodule - Get information about the main (top-level) module as well
59
+ pagesetmodule - Get information about the pageset module (providing titles= and friends) as well
60
+ Example:
61
+ api.php?action=paraminfo&modules=parse&querymodules=allpages|siteinfo
62
+
63
+ * action=purge *
64
+ Purge the cache for the given titles.
65
+
66
+ This module requires read rights.
67
+ This module requires write rights.
68
+ Parameters:
69
+ titles - A list of titles
70
+ Example:
71
+ api.php?action=purge&titles=Main_Page|API
72
+
73
+ * action=rollback *
74
+ Undo the last edit to the page. If the last user who edited the page made multiple edits in a row,
75
+ they will all be rolled back.
76
+
77
+ This module requires read rights.
78
+ This module requires write rights.
79
+ This module only accepts POST requests.
80
+ Parameters:
81
+ title - Title of the page you want to rollback.
82
+ user - Name of the user whose edits are to be rolled back. If set incorrectly, you'll get a badtoken error.
83
+ token - A rollback token previously retrieved through prop=revisions
84
+ summary - Custom edit summary. If not set, default summary will be used.
85
+ markbot - Mark the reverted edits and the revert as bot edits
86
+ Examples:
87
+ api.php?action=rollback&title=Main%20Page&user=Catrope&token=123ABC
88
+ api.php?action=rollback&title=Main%20Page&user=217.121.114.116&token=123ABC&summary=Reverting%20vandalism&markbot=1
89
+
90
+ * action=delete *
91
+ Delete a page.
92
+
93
+ This module requires read rights.
94
+ This module requires write rights.
95
+ This module only accepts POST requests.
96
+ Parameters:
97
+ title - Title of the page you want to delete. Cannot be used together with pageid
98
+ pageid - Page ID of the page you want to delete. Cannot be used together with title
99
+ token - A delete token previously retrieved through prop=info
100
+ reason - Reason for the deletion. If not set, an automatically generated reason will be used.
101
+ watch - Add the page to your watchlist
102
+ unwatch - Remove the page from your watchlist
103
+ oldimage - The name of the old image to delete as provided by iiprop=archivename
104
+ Examples:
105
+ api.php?action=delete&title=Main%20Page&token=123ABC
106
+ api.php?action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move
107
+
108
+ * action=undelete *
109
+ Restore certain revisions of a deleted page. A list of deleted revisions (including timestamps) can be
110
+ retrieved through list=deletedrevs
111
+
112
+ This module requires read rights.
113
+ This module requires write rights.
114
+ This module only accepts POST requests.
115
+ Parameters:
116
+ title - Title of the page you want to restore.
117
+ token - An undelete token previously retrieved through list=deletedrevs
118
+ reason - Reason for restoring (optional)
119
+ Default:
120
+ timestamps - Timestamps of the revisions to restore. If not set, all revisions will be restored.
121
+ Examples:
122
+ api.php?action=undelete&title=Main%20Page&token=123ABC&reason=Restoring%20main%20page
123
+ api.php?action=undelete&title=Main%20Page&token=123ABC&timestamps=20070703220045|20070702194856
124
+
125
+ * action=protect *
126
+ Change the protection level of a page.
127
+
128
+ This module requires read rights.
129
+ This module requires write rights.
130
+ This module only accepts POST requests.
131
+ Parameters:
132
+ title - Title of the page you want to (un)protect.
133
+ token - A protect token previously retrieved through prop=info
134
+ protections - Pipe-separated list of protection levels, formatted action=group (e.g. edit=sysop)
135
+ expiry - Expiry timestamps. If only one timestamp is set, it'll be used for all protections.
136
+ Use 'infinite', 'indefinite' or 'never', for a neverexpiring protection.
137
+ Default: infinite
138
+ reason - Reason for (un)protecting (optional)
139
+ Default:
140
+ cascade - Enable cascading protection (i.e. protect pages included in this page)
141
+ Ignored if not all protection levels are 'sysop' or 'protect'
142
+ watch - If set, add the page being (un)protected to your watchlist
143
+ Examples:
144
+ api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=sysop|move=sysop&cascade&expiry=20070901163000|never
145
+ api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=all|move=all&reason=Lifting%20restrictions
146
+
147
+ * action=block *
148
+ Block a user.
149
+
150
+ This module requires read rights.
151
+ This module requires write rights.
152
+ This module only accepts POST requests.
153
+ Parameters:
154
+ user - Username, IP address or IP range you want to block
155
+ token - A block token previously obtained through the gettoken parameter or prop=info
156
+ gettoken - If set, a block token will be returned, and no other action will be taken
157
+ expiry - Relative expiry time, e.g. '5 months' or '2 weeks'. If set to 'infinite', 'indefinite' or 'never', the block will never expire.
158
+ Default: never
159
+ reason - Reason for block (optional)
160
+ anononly - Block anonymous users only (i.e. disable anonymous edits for this IP)
161
+ nocreate - Prevent account creation
162
+ autoblock - Automatically block the last used IP address, and any subsequent IP addresses they try to login from
163
+ noemail - Prevent user from sending e-mail through the wiki. (Requires the "blockemail" right.)
164
+ hidename - Hide the username from the block log. (Requires the "hideuser" right.)
165
+ allowusertalk - Allow the user to edit their own talk page (depends on $wgBlockAllowsUTEdit)
166
+ reblock - If the user is already blocked, overwrite the existing block
167
+ Examples:
168
+ api.php?action=block&user=123.5.5.12&expiry=3%20days&reason=First%20strike
169
+ api.php?action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate&autoblock&noemail
170
+
171
+ * action=unblock *
172
+ Unblock a user.
173
+
174
+ This module requires read rights.
175
+ This module requires write rights.
176
+ This module only accepts POST requests.
177
+ Parameters:
178
+ id - ID of the block you want to unblock (obtained through list=blocks). Cannot be used together with user
179
+ user - Username, IP address or IP range you want to unblock. Cannot be used together with id
180
+ token - An unblock token previously obtained through the gettoken parameter or prop=info
181
+ gettoken - If set, an unblock token will be returned, and no other action will be taken
182
+ reason - Reason for unblock (optional)
183
+ Examples:
184
+ api.php?action=unblock&id=105
185
+ api.php?action=unblock&user=Bob&reason=Sorry%20Bob
186
+
187
+ * action=move *
188
+ Move a page.
189
+
190
+ This module requires read rights.
191
+ This module requires write rights.
192
+ This module only accepts POST requests.
193
+ Parameters:
194
+ from - Title of the page you want to move. Cannot be used together with fromid.
195
+ fromid - Page ID of the page you want to move. Cannot be used together with from.
196
+ to - Title you want to rename the page to.
197
+ token - A move token previously retrieved through prop=info
198
+ reason - Reason for the move (optional).
199
+ movetalk - Move the talk page, if it exists.
200
+ movesubpages - Move subpages, if applicable
201
+ noredirect - Don't create a redirect
202
+ watch - Add the page and the redirect to your watchlist
203
+ unwatch - Remove the page and the redirect from your watchlist
204
+ Example:
205
+ api.php?action=move&from=Exampel&to=Example&token=123ABC&reason=Misspelled%20title&movetalk&noredirect
206
+
207
+ * action=edit *
208
+ Create and edit pages.
209
+
210
+ This module requires read rights.
211
+ This module requires write rights.
212
+ This module only accepts POST requests.
213
+ Parameters:
214
+ title - Page title
215
+ section - Section number. 0 for the top section, 'new' for a new section
216
+ text - Page content
217
+ token - Edit token. You can get one of these through prop=info
218
+ summary - Edit summary. Also section title when section=new
219
+ minor - Minor edit
220
+ notminor - Non-minor edit
221
+ bot - Mark this edit as bot
222
+ basetimestamp - Timestamp of the base revision (gotten through prop=revisions&rvprop=timestamp).
223
+ Used to detect edit conflicts; leave unset to ignore conflicts.
224
+ starttimestamp - Timestamp when you obtained the edit token.
225
+ Used to detect edit conflicts; leave unset to ignore conflicts.
226
+ recreate - Override any errors about the article having been deleted in the meantime
227
+ createonly - Don't edit the page if it exists already
228
+ nocreate - Throw an error if the page doesn't exist
229
+ captchaword - Answer to the CAPTCHA
230
+ captchaid - CAPTCHA ID from previous request
231
+ watch - Add the page to your watchlist
232
+ unwatch - Remove the page from your watchlist
233
+ md5 - The MD5 hash of the text parameter, or the prependtext and appendtext parameters concatenated.
234
+ If set, the edit won't be done unless the hash is correct
235
+ prependtext - Add this text to the beginning of the page. Overrides text.
236
+ Don't use together with section: that won't do what you expect.
237
+ appendtext - Add this text to the end of the page. Overrides text
238
+ undo - Undo this revision. Overrides text, prependtext and appendtext
239
+ undoafter - Undo all revisions from undo to this one. If not set, just undo one revision
240
+ Examples:
241
+ Edit a page (anonymous user):
242
+ api.php?action=edit&title=Test&summary=test%20summary&text=article%20content&basetimestamp=20070824123454&token=%2B\
243
+ Prepend __NOTOC__ to a page (anonymous user):
244
+ api.php?action=edit&title=Test&summary=NOTOC&minor&prependtext=__NOTOC__%0A&basetimestamp=20070824123454&token=%2B\
245
+ Undo r13579 through r13585 with autosummary(anonymous user):
246
+ api.php?action=edit&title=Test&undo=13585&undoafter=13579&basetimestamp=20070824123454&token=%2B\
247
+
248
+ * action=emailuser *
249
+ Email a user.
250
+
251
+ This module requires read rights.
252
+ This module requires write rights.
253
+ This module only accepts POST requests.
254
+ Parameters:
255
+ target - User to send email to
256
+ subject - Subject header
257
+ text - Mail body
258
+ token - A token previously acquired via prop=info
259
+ ccme - Send a copy of this mail to me
260
+ Example:
261
+ api.php?action=emailuser&target=WikiSysop&text=Content
262
+
263
+ * action=watch *
264
+ Add or remove a page from/to the current user's watchlist
265
+
266
+ This module requires read rights.
267
+ This module requires write rights.
268
+ Parameters:
269
+ title - The page to (un)watch
270
+ unwatch - If set the page will be unwatched rather than watched
271
+ Examples:
272
+ api.php?action=watch&title=Main_Page
273
+ api.php?action=watch&title=Main_Page&unwatch
274
+
275
+ * action=patrol *
276
+ Patrol a page or revision.
277
+
278
+ This module requires read rights.
279
+ This module requires write rights.
280
+ Parameters:
281
+ token - Patrol token obtained from list=recentchanges
282
+ rcid - Recentchanges ID to patrol
283
+ Example:
284
+ api.php?action=patrol&token=123abc&rcid=230672766
285
+
286
+ * action=import *
287
+ Import a page from another wiki, or an XML file
288
+
289
+ This module requires read rights.
290
+ This module requires write rights.
291
+ This module only accepts POST requests.
292
+ Parameters:
293
+ token - Import token obtained through prop=info
294
+ summary - Import summary
295
+ xml - Uploaded XML file
296
+ interwikisource - For interwiki imports: wiki to import from
297
+ One value:
298
+ interwikipage - For interwiki imports: page to import
299
+ fullhistory - For interwiki imports: import the full history, not just the current version
300
+ templates - For interwiki imports: import all included templates as well
301
+ namespace - For interwiki imports: import to this namespace
302
+ One value: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 100, 101
303
+ Examples:
304
+ Import [[meta:Help:Parserfunctions]] to namespace 100 with full history:
305
+ api.php?action=import&interwikisource=meta&interwikipage=Help:ParserFunctions&namespace=100&fullhistory&token=123ABC
306
+
307
+
308
+