class MediaWiki::Butt

Attributes

assertion[RW]
query_limit_default[RW]
use_continuation[RW]

Public Class Methods

new(url, opts = {}) click to toggle source

Creates a new instance of MediaWiki::Butt. @param url [String] The FULL wiki URL. api.php can be omitted, but it will make harsh assumptions about

your wiki configuration.

@param opts [Hash<Symbol, Any>] The options hash for configuring this instance of Butt. @option opts [String] :custom_agent A custom User-Agent to use. Optional. @option opts [Fixnum] :query_limit_default The query limit to use if no limit parameter is explicitly given to

the various query methods. In other words, if you pass a limit parameter to the valid query methods, it will
use that, otherwise, it will use this. Defaults to 'max' to use MW's default max for each API.

@option opts [Boolean] :use_continuation Whether to use the continuation API on queries. Defaults to true. @option opts [Symbol] :assertion If set to :user or :bot, will use the assert parameter in all requests.

Setting this will open up the possibility for NotLoggedInErrors and NotBotErrors. It is important to keep in
mind that methods that check if the user is logged in do not use the API, but check if the user has *ever*
logged in as this Butt instance. In other words, it is a safety check for performance and not a valid API check.
# File lib/mediawiki/butt.rb, line 43
def initialize(url, opts = {})
  @url = url =~ /api.php$/ ? url : "#{url}/api.php"
  @query_limit_default = opts[:query_limit_default] || 'max'
  @custom_agent = opts[:custom_agent]
  @session = Patron::Session.new
  @session.timeout = 60
  @session.handle_cookies
  @session.headers['User-Agent'] = @custom_agent if @custom_agent
  @logged_in = false
  @use_continuation = opts[:use_continuation] || true
  # Token cache, populated in #get_token and depopulated in #post. Type => Token
  @tokens = {}
  # The most recent kind of token acquired. Used in #post, set/reset in #get_token.
  @prev_token_type = ''
  # Set to prevent token cache handling from producing an infinite call loop. Defaults to true, set to false when
  # token recache is being handled.
  @first_token_try = true

  assertion = opts[:assertion]
  @assertion = assertion == :user || assertion == :bot ? assertion : nil
end

Public Instance Methods

logged_in?() click to toggle source

Checks whether this instance is logged in. @return [Boolean] true if logged in, false if not.

# File lib/mediawiki/butt.rb, line 164
def logged_in?
  post({ action: 'query', assert: 'user' })
  true
rescue MediaWiki::Butt::NotLoggedInError
  false
end
post(params) click to toggle source

Performs an HTTP POST request and provides the response. This method generally should not be used by the user, unless there is not a helper method provided by Butt for a particular action. @param params [Hash] A hash containing MediaWiki API parameters. Please see the MediaWiki API for more

information. The method automatically sets the format and assert values, unless they are specified in this
hash argument.

@since 0.1.0 @return [Hash] Parsed JSON returned by the MediaWiki API

# File lib/mediawiki/butt.rb, line 72
def post(params)
  base_params = {
    format: 'json'
  }
  base_params[:assert] = @assertion.to_s if @assertion
  params = base_params.merge(params)

  unless @custom_agent
    @session.headers['User-Agent'] = @logged_in ? "#{@name}/MediaWiki::Butt" : 'NotLoggedIn/MediaWiki::Butt'
  end

  response = JSON.parse(@session.post(@url, params).body)

  # If our tokens have expired, clear them, re-set the relevant token argument, and re-call this #post method
  if response.dig('error', 'code') == 'badtoken' && @first_token_try
    @tokens.clear
    token_param = params.keys.select { |i| i.to_s.end_with?('token') }[0]
    params[token_param] = get_token(@prev_token_type)
    # Prevent token retry attempt in next #post call
    @first_token_try = false
    return post(params)
  end
  # Reset token retry value if no badtoken error has occurred.
  @first_token_try = true

  if @assertion
    code = response.dig('error', 'code')
    fail MediaWiki::Butt::NotLoggedInError.new(response['error']['info']) if code == 'assertuserfailed'
    fail MediaWiki::Butt::NotBotError.new(response['error']['info']) if code == 'assertbotfailed'
  end
  response
end
query(params, base_return = []) { |base_return, result| ... } click to toggle source

Performs a Mediawiki API query and provides the response, dealing with continuation as necessary. @param params [Hash] A hash containing MediaWiki API parameters. @param base_return [Any] The return value to start with. Defaults to an empty array. @yield [base_return, query] Provides the value provided to the base_return parameter, and the value in the

'query' key in the API response. See the API documentation for more information on this. If the base_return
value is modified in the block, its modifications will persist across each continuation loop.

@return [Any] The base_return value as modified by the yielded block.

# File lib/mediawiki/butt.rb, line 112
def query(params, base_return = [])
  params[:action] = 'query'
  params[:continue] = ''

  loop do
    result = post(params)
    yield(base_return, result['query']) if result.key?('query')
    break unless @use_continuation
    break unless result.key?('continue')
    continue = result['continue']
    continue.each do |key, val|
      params[key.to_sym] = val
    end
  end

  base_return
end
query_ary(params, base_response_key, property_key) click to toggle source

Helper method for query methods that return an array built from the query objects. @param params [Hash] A hash containing MediaWiki API parameters. @param base_response_key [String] The key inside the “query” object to collect. @param property_key [String] The key inside the object (under the base_response_key) to collect.

# File lib/mediawiki/butt.rb, line 143
def query_ary(params, base_response_key, property_key)
  query(params) do |return_val, query|
    return_val.concat(query[base_response_key].collect { |obj| obj[property_key] })
  end
end
query_ary_irrelevant_keys(params, base_response_key, property_key) click to toggle source

Helper method for query methods that return a two-dimensional hashes in which the keys are not relevant to the

returning value. In most cases this key is a redundant page or revision ID that is also available in the object.

@param (see query_ary)

# File lib/mediawiki/butt.rb, line 133
def query_ary_irrelevant_keys(params, base_response_key, property_key)
  query(params) do |return_val, query|
    return_val.concat(query[base_response_key].values.collect { |obj| obj[property_key] })
  end
end
user_bot?() click to toggle source

Gets whether the currently logged in user is a bot. @return [Boolean] true if logged in as a bot, false if not logged in or

logged in as a non-bot

@since 0.1.0 as is_current_user_bot @since 0.3.0 as is_user_bot? @since 0.4.1 as user_bot?

# File lib/mediawiki/butt.rb, line 155
def user_bot?
  post({ action: 'query', assert: 'bot' })
  true
rescue MediaWiki::Butt::NotBotError
  false
end

Protected Instance Methods

get_limited(integer, max_user = 500, max_bot = 5000) click to toggle source

Gets the limited version of the integer, to ensure nobody provides an int that is too large. @param integer [Fixnum] The number to limit. @param max_user [Fixnum] The maximum limit for normal users. @param max_bot [Fixnum] The maximum limit for bot users. @since 0.8.0 @return [Fixnum] The capped number.

# File lib/mediawiki/butt.rb, line 179
def get_limited(integer, max_user = 500, max_bot = 5000)
  if integer.is_a?(String)
    return integer if integer == 'max'
    return 500
  end
  return integer if integer <= max_user

  if user_bot?
    integer > max_bot ? max_bot : integer
  else
    max_user
  end
end
validate_namespace(namespace) click to toggle source

Safely validates the given namespace ID, and returns 0 for the main namespace if invalid. @param namespace [Fixnum] The namespace ID. @return [Fixnum] Either the given namespace, if valid, or the main namespace ID 0 if invalid.

# File lib/mediawiki/butt.rb, line 196
def validate_namespace(namespace)
  MediaWiki::Constants::NAMESPACES.value?(namespace) ? namespace : 0
end