module MediaWiki::Gateway::Pages

Public Instance Methods

category_members(category, options = {}) click to toggle source

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)

# File lib/media_wiki/gateway/pages.rb, line 274
def category_members(category, options = {})
  iterate_query('categorymembers', '//cm', 'title', 'cmcontinue', options.merge(
    'cmtitle' => category,
    'cmlimit' => @options[:limit]
  ))
end
create(title, content, options = {}) click to toggle source

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.

# 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 = {}) click to toggle source

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

# 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 = {}) click to toggle source

Edit page

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

# 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 = {}) click to toggle source

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.

# 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
list(key, options = {}) click to toggle source

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)

# 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 = {}) click to toggle source

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

# 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 = {}) click to toggle source

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', {:action => 'edit', :group => 'all'}, {:cascade => true})

  2. prt = [{:action => 'move', :group => 'sysop', :expiry => 'never'},

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

    mw.protect('Main Page', prt, {:reason => 'awesomeness'})

# 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
redirect?(page_title) click to toggle source

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.

# File lib/media_wiki/gateway/pages.rb, line 301
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 = {}) click to toggle source

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

# 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 = {}) click to toggle source

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

# File lib/media_wiki/gateway/pages.rb, line 359
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 = {}) click to toggle source

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.

# 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 = {}) click to toggle source

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

# 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

Private Instance Methods

get_undelete_token(page_titles) click to toggle source
# File lib/media_wiki/gateway/pages.rb, line 376
def get_undelete_token(page_titles)
  res = send_request(
    'action' => 'query',
    'list'   => 'deletedrevs',
    'prop'   => 'info',
    'drprop' => 'token',
    'titles' => page_titles
  )

  if res.elements['query/deletedrevs/page']
    unless token = res.elements['query/deletedrevs/page'].attributes['token']
      raise Unauthorized.new("User is not permitted to perform this operation: #{type}")
    end

    token
  end
end