Module: MediaWiki::Gateway::Pages

Included in:
MediaWiki::Gateway
Defined in:
lib/media_wiki/gateway/pages.rb

Instance Method Summary collapse

Instance Method Details

Get a list of pages that link to a target page

title

Link target page

filter

‘all’ links (default), ‘redirects’ only, or ‘nonredirects’ (plain links only)

options

Hash of additional options

Returns array of page titles (empty if no matches)



289
290
291
292
293
294
295
# File 'lib/media_wiki/gateway/pages.rb', line 289

def backlinks(title, filter = 'all', options = {})
  iterate_query('backlinks', '//bl', 'title', 'blcontinue', options.merge(
    'bltitle'       => title,
    'blfilterredir' => filter,
    'bllimit'       => @options[:limit]
  ))
end

#category_members(category, options = {}) ⇒ Object

Get a list of pages that are members of a category

category

Name of the category

options

Optional hash of additional options. See www.mediawiki.org/wiki/API:Categorymembers

Returns array of page titles (empty if no matches)



274
275
276
277
278
279
280
# File 'lib/media_wiki/gateway/pages.rb', line 274

def category_members(category, options = {})
  iterate_query('categorymembers', '//cm', 'title', 'cmcontinue', options.merge(
    'cmtitle' => category,
    'continue' => '', # new format, per https://www.mediawiki.org/wiki/API:Query#Continuing_queries
    'cmlimit' => @options[:limit]
  ))
end

#create(title, content, options = {}) ⇒ Object

Create a new page, or overwrite an existing one

title

Page title to create or overwrite, string

content

Content for the page, string

options

Hash of additional options

Options:

  • :overwrite

    Allow overwriting existing pages

  • :summary

    Edit summary for history, string

  • :token

    Use this existing edit token instead requesting a new one (useful for bulk loads)

  • :minor

    Mark this edit as “minor” if true, mark this edit as “major” if false, leave major/minor status by default if not specified

  • :notminor

    Mark this edit as “major” if true

  • :bot

    Set the bot parameter (see www.mediawiki.org/wiki/API:Edit#Parameters). Defaults to false.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/media_wiki/gateway/pages.rb', line 93

def create(title, content, options = {})
  form_data = {
    'action'  => 'edit',
    'title'   => title,
    'text'    => content,
    'summary' => options[:summary] || '',
    'token'   => get_token('edit', title)
  }

  if @options[:bot] || options[:bot]
    form_data.update('bot' => '1', 'assert' => 'bot')
  end

  form_data['minor']      = '1' if options[:minor]
  form_data['notminor']   = '1' if options[:minor] == false || options[:notminor]
  form_data['createonly'] = '' unless options[:overwrite]
  form_data['section']    = options[:section].to_s if options[:section]

  send_request(form_data)
end

#delete(title, options = {}) ⇒ Object

Delete one page. (MediaWiki API does not support deleting multiple pages at a time.)

title

Title of page to delete

options

Hash of additional options



224
225
226
227
228
229
230
# File 'lib/media_wiki/gateway/pages.rb', line 224

def delete(title, options = {})
  send_request(options.merge(
    'action' => 'delete',
    'title'  => title,
    'token'  => get_token('delete', title)
  ))
end

#edit(title, content, options = {}) ⇒ Object

Edit page

Same options as create, but always overwrites existing pages (and creates them if they don’t exist already).



117
118
119
# File 'lib/media_wiki/gateway/pages.rb', line 117

def edit(title, content, options = {})
  create(title, content, { overwrite: true }.merge(options))
end

#get(page_title, options = {}) ⇒ Object

Fetch MediaWiki page in MediaWiki format. Does not follow redirects.

page_title

Page title to fetch

options

Hash of additional options

Returns content of page as string, nil if the page does not exist.



13
14
15
16
17
18
19
20
21
22
# File 'lib/media_wiki/gateway/pages.rb', line 13

def get(page_title, options = {})
  page = send_request(options.merge(
    'action' => 'query',
    'prop'   => 'revisions',
    'rvprop' => 'content',
    'titles' => page_title
  )).elements['query/pages/page']

  page.elements['revisions/rev'].text || '' if valid_page?(page)
end

Convenience wrapper for langlinks returning the title in language lang (ISO code) for a given article of pageid, if it exists, via the interlanguage link

Example:

langlink = mw.langlink_for_lang('Tycho Brahe', 'de')


363
364
365
# File 'lib/media_wiki/gateway/pages.rb', line 363

def langlink_for_lang(article_or_pageid, lang)
  langlinks(article_or_pageid)[lang]
end

Get list of interlanguage links for given article. Follows redirects. Returns a hash like { ‘id’ => ‘Yerusalem’, ‘en’ => ‘Jerusalem’, … }

article_or_pageid is the title or pageid of a single article lllimit is the maximum number of langlinks to return (defaults to 500, the maximum) options is the hash of additional options

Example:

langlinks = mw.langlinks('Jerusalem')


320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/media_wiki/gateway/pages.rb', line 320

def langlinks(article_or_pageid, lllimit = 500, options = {})
  form_data = options.merge(
    'action'    => 'query',
    'prop'      => 'langlinks',
    'lllimit'   => lllimit,
    'redirects' => true
  )

  form_data[article_or_pageid.is_a?(Fixnum) ?
    'pageids' : 'titles'] = article_or_pageid

  xml = send_request(form_data)

  if valid_page?(page = xml.elements['query/pages/page'])
    if xml.elements['query/redirects/r']
      # We're dealing with the redirect here.
      langlinks(page.attributes['pageid'].to_i, lllimit)
    elsif langl = REXML::XPath.match(page, 'langlinks/ll')
      langl.each_with_object({}) { |ll, links|
        links[ll.attributes['lang']] = ll.children[0].to_s
      }
    end
  end
end

#list(key, options = {}) ⇒ Object

Get a list of matching page titles in a namespace

key

Search key, matched as a prefix (^key.*). May contain or equal a namespace, defaults to main (namespace 0) if none given.

options

Optional hash of additional options, eg. { ‘apfilterredir’ => ‘nonredirects’ }. See www.mediawiki.org/wiki/API:Allpages

Returns array of page titles (empty if no matches)



256
257
258
259
260
261
262
263
264
265
266
# File 'lib/media_wiki/gateway/pages.rb', line 256

def list(key, options = {})
  key, namespace = key.split(':', 2).reverse
  namespace = namespaces_by_prefix[namespace] || 0

  iterate_query('allpages', '//p', 'title', 'apfrom', options.merge(
    'list'        => 'allpages',
    'apprefix'    => key,
    'apnamespace' => namespace,
    'aplimit'     => @options[:limit]
  ))
end

#move(from, to, options = {}) ⇒ Object

Move a page to a new title

from

Old page name

to

New page name

options

Hash of additional options

Options:

  • :movesubpages

    Move associated subpages

  • :movetalk

    Move associated talkpages

  • :noredirect

    Do not create a redirect page from old name. Requires the ‘suppressredirect’ user right, otherwise MW will silently ignore the option and create the redirect anyway.

  • :reason

    Reason for move

  • :watch

    Add page and any redirect to watchlist

  • :unwatch

    Remove page and any redirect from watchlist



209
210
211
212
213
214
215
216
217
218
# File 'lib/media_wiki/gateway/pages.rb', line 209

def move(from, to, options = {})
  validate_options(options, %w[movesubpages movetalk noredirect reason watch unwatch])

  send_request(options.merge(
    'action' => 'move',
    'from'   => from,
    'to'     => to,
    'token'  => get_token('move', from)
  ))
end

#protect(title, protections, options = {}) ⇒ Object

Protect/unprotect a page

Arguments:

  • title

    Page title to protect, string

  • protections

    Protections to apply, hash or array of hashes

    Protections:

    • :action

      (required) The action to protect, string

    • :group

      (required) The group allowed to perform the action, string

    • :expiry

      The protection expiry as a GNU timestamp, string

  • options

    Hash of additional options

    Options:

    • :cascade

      Protect pages included in this page, boolean

    • :reason

      Reason for protection, string

Examples:

  1. mw.protect(‘Main Page’, => ‘edit’, :group => ‘all’, => true)

  2. prt = [=> ‘move’, :group => ‘sysop’, :expiry => ‘never’,

    {:action => 'edit', :group => 'autoconfirmed', :expiry => 'next Monday 16:04:57'}]
    

    mw.protect(‘Main Page’, prt, => ‘awesomeness’)



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
187
188
189
190
191
192
193
194
# File 'lib/media_wiki/gateway/pages.rb', line 144

def protect(title, protections, options = {})
  case protections
    when Array
      # ok
    when Hash
      protections = [protections]
    else
      raise ArgumentError, "Invalid type '#{protections.class}' for protections"
  end

  valid_prt_options    = %w[action group expiry]
  required_prt_options = %w[action group]

  p, e = [], []

  protections.each { |prt|
    existing_prt_options = []

    prt.each_key { |opt|
      if valid_prt_options.include?(opt.to_s)
        existing_prt_options << opt.to_s
      else
        raise ArgumentError, "Unknown option '#{opt}' for protections"
      end
    }

    required_prt_options.each { |opt|
      unless existing_prt_options.include?(opt)
        raise ArgumentError, "Missing required option '#{opt}' for protections"
      end
    }

    p << "#{prt[:action]}=#{prt[:group]}"
    e << (prt.key?(:expiry) ? prt[:expiry].to_s : 'never')
  }

  validate_options(options, %w[cascade reason])

  form_data = {
    'action'      => 'protect',
    'title'       => title,
    'token'       => get_token('protect', title),
    'protections' => p.join('|'),
    'expiry'      => e.join('|')
  }

  form_data['cascade'] = '' if options[:cascade] == true
  form_data['reason']  = options[:reason].to_s if options[:reason]

  send_request(form_data)
end

#purge(page_titles, options = {}) ⇒ Object

Purge MediaWiki page. Does not follow redirects.

page_titles

Page titles to purge

options

Hash of additional options

Returns purge object



351
352
353
354
355
356
# File 'lib/media_wiki/gateway/pages.rb', line 351

def purge(page_titles, options = {})
  page = send_request(options.merge(
    'action' => 'purge',
    'titles' => page_titles
  ))
end

#redirect?(page_title) ⇒ Boolean

Checks if page is a redirect.

page_title

Page title to fetch

Returns true if the page is a redirect, false if it is not or the page does not exist.

Returns:

  • (Boolean)


302
303
304
305
306
307
308
309
310
# File 'lib/media_wiki/gateway/pages.rb', line 302

def redirect?(page_title)
  page = send_request(
    'action' => 'query',
    'prop'   => 'info',
    'titles' => page_title
  ).elements['query/pages/page']

  !!(valid_page?(page) && page.attributes['redirect'])
end

#render(page_title, options = {}) ⇒ Object

Render a MediaWiki page as HTML

page_title

Page title to fetch

options

Hash of additional options

Options:

  • :linkbase

    supply a String to prefix all internal (relative) links with. ‘/wiki/’ is assumed to be the base of a relative link

  • :noeditsections

    strips all edit-links if set to true

  • :noimages

    strips all img tags from the rendered text if set to true

Returns rendered page as string, or nil if the page does not exist



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
# File 'lib/media_wiki/gateway/pages.rb', line 53

def render(page_title, options = {})
  form_data = { 'action' => 'parse', 'page' => page_title }

  validate_options(options, %w[linkbase noeditsections noimages])

  rendered, parsed = nil, send_request(form_data).elements['parse']

  if parsed.attributes['revid'] != '0'
    rendered = parsed.elements['text'].text.gsub(/<!--(.|\s)*?-->/, '')

    # OPTIMIZE: unifiy the keys in +options+ like symbolize_keys! but w/o
    if linkbase = options['linkbase'] || options[:linkbase]
      rendered = rendered.gsub(/\shref="\/wiki\/([\w\(\)\-\.%:,]*)"/, ' href="' + linkbase + '/wiki/\1"')
    end

    if options['noeditsections'] || options[:noeditsections]
      rendered = rendered.gsub(/<span class="editsection">\[.+\]<\/span>/, '')
    end

    if options['noimages'] || options[:noimages]
      rendered = rendered.gsub(/<img.*\/>/, '')
    end
  end

  rendered
end

#review(title, flags, comment = 'Reviewed by MediaWiki::Gateway', options = {}) ⇒ Object

Review current revision of an article (requires FlaggedRevisions extension, see www.mediawiki.org/wiki/Extension:FlaggedRevs)

title

Title of article to review

flags

Hash of flags and values to set, eg. { ‘accuracy’ => ‘1’, ‘depth’ => ‘2’ }

comment

Comment to add to review (optional)

options

Hash of additional options

Raises:



373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/media_wiki/gateway/pages.rb', line 373

def review(title, flags, comment = 'Reviewed by MediaWiki::Gateway', options = {})
  raise APIError.new('missingtitle', "Article #{title} not found") unless revid = revision(title)

  form_data = options.merge(
    'action'  => 'review',
    'revid'   => revid,
    'token'   => get_token('edit', title),
    'comment' => comment
  )

  flags.each { |k, v| form_data["flag_#{k}"] = v }

  send_request(form_data)
end

#revision(page_title, options = {}) ⇒ Object

Fetch latest revision ID of a MediaWiki page. Does not follow redirects.

page_title

Page title to fetch

options

Hash of additional options

Returns revision ID as a string, nil if the page does not exist.



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/media_wiki/gateway/pages.rb', line 30

def revision(page_title, options = {})
  page = send_request(options.merge(
    'action'  => 'query',
    'prop'    => 'revisions',
    'rvprop'  => 'ids',
    'rvlimit' => 1,
    'titles'  => page_title
  )).elements['query/pages/page']

  page.elements['revisions/rev'].attributes['revid'] if valid_page?(page)
end

#undelete(title, options = {}) ⇒ Object

Undelete all revisions of one page.

title

Title of page to undelete

options

Hash of additional options

Returns number of revisions undeleted, or zero if nothing to undelete



238
239
240
241
242
243
244
245
246
247
248
# File 'lib/media_wiki/gateway/pages.rb', line 238

def undelete(title, options = {})
  if token = get_undelete_token(title)
    send_request(options.merge(
      'action' => 'undelete',
      'title'  => title,
      'token'  => token
    )).elements['undelete'].attributes['revisions'].to_i
  else
    0 # No revisions to undelete
  end
end