lib/media_wiki/gateway.rb in mediawiki-gateway-0.4.4 vs lib/media_wiki/gateway.rb in mediawiki-gateway-0.4.5
- old
+ new
@@ -14,10 +14,11 @@
#
# [url] Path to API of target MediaWiki (eg. "http://en.wikipedia.org/w/api.php")
# [options] Hash of options
#
# Options:
+ # [:bot] When set to true, executes API queries with the bot parameter (see http://www.mediawiki.org/wiki/API:Edit#Parameters). Defaults to false.
# [:ignorewarnings] Log API warnings and invalid page titles, instead throwing MediaWiki::APIError
# [:limit] Maximum number of results returned per search (see http://www.mediawiki.org/wiki/API:Query_-_Lists#Limits), defaults to the MediaWiki default of 500.
# [:loglevel] Log level to use, defaults to Logger::WARN. Set to Logger::DEBUG to dump every request and response to the log.
# [:maxlag] Maximum allowed server lag (see http://www.mediawiki.org/wiki/Manual:Maxlag_parameter), defaults to 5 seconds.
# [:retry_count] Number of times to try before giving up if MediaWiki returns 503 Service Unavailable, defaults to 3 (original request plus two retries).
@@ -26,11 +27,12 @@
default_options = {
:limit => 500,
:loglevel => Logger::WARN,
:maxlag => 5,
:retry_count => 3,
- :retry_delay => 10
+ :retry_delay => 10,
+ :bot => false
}
@options = default_options.merge(options)
@wiki_url = url
@log = Logger.new(STDERR)
@log.level = @options[:loglevel]
@@ -139,10 +141,71 @@
# Same options as create, but always overwrites existing pages (and creates them if they don't exist already).
def edit(title, content, options={})
create(title, content, {:overwrite => true}.merge(options))
end
+ # 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'})
+ #
+ def protect(title, protections, options={})
+ # validate and format protections
+ protections = [protections] if protections.is_a?(Hash)
+ raise ArgumentError.new("Invalid type '#{protections.class}' for protections") unless protections.is_a?(Array)
+ valid_prt_options = %w(action group expiry)
+ required_prt_options = %w(action group)
+ p,e = [],[]
+ protections.each do |prt|
+ existing_prt_options = []
+ prt.keys.each do |opt|
+ if valid_prt_options.include?(opt.to_s)
+ existing_prt_options.push(opt.to_s)
+ else
+ raise ArgumentError.new("Unknown option '#{opt}' for protections")
+ end
+ end
+ required_prt_options.each{|opt| raise ArgumentError.new("Missing required option '#{opt}' for protections") unless existing_prt_options.include?(opt)}
+ p.push("#{prt[:action]}=#{prt[:group]}")
+ if prt.has_key?(:expiry)
+ e.push(prt[:expiry].to_s)
+ else
+ e.push('never')
+ end
+ end
+
+ # validate options
+ valid_options = %w(cascade reason)
+ options.keys.each{|opt| raise ArgumentError.new("Unknown option '#{opt}'") unless valid_options.include?(opt.to_s)}
+
+ # make API request
+ form_data = {'action' => 'protect', 'title' => title, 'token' => get_token('protect', title)}
+ form_data['protections'] = p.join('|')
+ form_data['expiry'] = e.join('|')
+ form_data['cascade'] = '' if options[:cascade] === true
+ form_data['reason'] = options[:reason].to_s if options[:reason]
+ make_api_request(form_data)
+ end
+
# Move a page to a new title
#
# [from] Old page name
# [to] New page name
# [options] Hash of additional options
@@ -499,11 +562,11 @@
res
end
private
- # Fetch token (type 'delete', 'edit', 'import', 'move')
+ # Fetch token (type 'delete', 'edit', 'import', 'move', 'protect')
def get_token(type, page_titles)
form_data = {'action' => 'query', 'prop' => 'info', 'intoken' => type, 'titles' => page_titles}
res, dummy = make_api_request(form_data)
token = res.elements["query/pages/page"].attributes[type + "token"]
raise Unauthorized.new "User is not permitted to perform this operation: #{type}" if token.nil?
@@ -567,9 +630,10 @@
# Returns XML document
def make_api_request(form_data, continue_xpath=nil, retry_count=1)
if form_data.kind_of? Hash
form_data['format'] = 'xml'
form_data['maxlag'] = @options[:maxlag]
+ form_data['bot']="1" if @options[:bot]
end
log.debug("REQ: #{form_data.inspect}, #{@cookies.inspect}")
RestClient.post(@wiki_url, form_data, @headers.merge({:cookies => @cookies})) do |response, &block|
if response.code == 503 and retry_count < @options[:retry_count]
log.warn("503 Service Unavailable: #{response.body}. Retry in #{@options[:retry_delay]} seconds.")