lib/media_wiki/gateway.rb in mediawiki-gateway-0.5.2 vs lib/media_wiki/gateway.rb in mediawiki-gateway-0.6.0
- old
+ new
@@ -130,12 +130,21 @@
#
# 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 http://www.mediawiki.org/wiki/API:Edit#Parameters). Defaults to false.
def create(title, content, options={})
form_data = {'action' => 'edit', 'title' => title, 'text' => content, 'summary' => (options[:summary] || ""), 'token' => get_token('edit', title)}
+ if @options[:bot] or options[:bot]
+ form_data['bot'] = '1'
+ form_data['assert'] = 'bot'
+ end
+ form_data['minor'] = '1' if options[:minor]
+ form_data['notminor'] = '1' if options[:minor] == false or options[:notminor]
form_data['createonly'] = "" unless options[:overwrite]
form_data['section'] = options[:section].to_s if options[:section]
make_api_request(form_data)
end
@@ -505,10 +514,56 @@
end
else
nil
end
end
+
+ # Get list of interlanguage links for given article[s]. 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)
+ #
+ # Example:
+ # langlinks = mw.langlinks('Jerusalem')
+ def langlinks(article_or_pageid, lllimit = 500)
+ form_data = {'action' => 'query', 'prop' => 'langlinks', 'lllimit' => lllimit, 'redirects' => true}
+ case article_or_pageid
+ when Fixnum
+ form_data['pageids'] = article_or_pageid
+ else
+ form_data['titles'] = article_or_pageid
+ end
+ xml, dummy = make_api_request(form_data)
+ page = xml.elements["query/pages/page"]
+ if valid_page? page
+ if xml.elements["query/redirects/r"]
+ # We're dealing with the redirect here.
+ langlinks(page.attributes["pageid"].to_i, lllimit)
+ else
+ langl = REXML::XPath.match(page, 'langlinks/ll')
+ if langl.nil?
+ nil
+ else
+ links = {}
+ langl.each{ |ll| links[ll.attributes["lang"]] = ll.children[0].to_s }
+ return links
+ end
+ end
+ else
+ nil
+ end
+ 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')
+ def langlink_for_lang(article_or_pageid, lang)
+ return langlinks(article_or_pageid)[lang]
+ end
+
# Requests image info from MediaWiki. Follows redirects.
#
# _file_name_or_page_id_ should be either:
# * a file name (String) you want info about without File: prefix.
# * or a Fixnum page id you of the file.
@@ -663,10 +718,44 @@
else
raise MediaWiki::Exception.new "Semantic MediaWiki extension not installed."
end
end
+ # Create a new account
+ #
+ # [options] is +Hash+ passed as query arguments. See https://www.mediawiki.org/wiki/API:Account_creation#Parameters for more information.
+ def create_account(options)
+ form_data = options.merge({ 'action' => 'createaccount' })
+ res, dummy = make_api_request(form_data)
+ res
+ end
+
+ # Sets options for currenlty logged in user
+ #
+ # [changes] a +Hash+ that will be transformed into an equal sign and pipe-separated key value parameter
+ # [optionname] a +String+ indicating which option to change (optional)
+ # [optionvalue] the new value for optionname - allows pipe characters (optional)
+ # [reset] a +Boolean+ indicating if all preferences should be reset to site defaults (optional)
+ def options(changes = {}, optionname = nil, optionvalue = nil, reset = false)
+ form_data = { 'action' => 'options', 'token' => get_options_token }
+
+ if changes.present?
+ form_data['change'] = changes.map { |key, value| "#{key}=#{value}" }.join('|')
+ end
+
+ if optionname.present?
+ form_data[optionname] = optionvalue
+ end
+
+ if reset
+ form_data['reset'] = true
+ end
+
+ res, dummy = make_api_request(form_data)
+ res
+ end
+
# Set groups for a user
#
# [user] Username of user to modify
# [groups_to_add] Groups to add user to, as an array or a string if a single group (optional)
# [groups_to_remove] Groups to remove user from, as an array or a string if a single group (optional)
@@ -727,10 +816,16 @@
end
token
end
+ def get_options_token
+ form_data = { 'action' => 'tokens', 'type' => 'options' }
+ res, dummy = make_api_request(form_data)
+ res.elements['tokens'].attributes['optionstoken']
+ end
+
def userrights(user, token, groups_to_add, groups_to_remove, reason)
# groups_to_add and groups_to_remove can be a string or an array. Turn them into MediaWiki's pipe-delimited list format.
if groups_to_add.is_a? Array
groups_to_add = groups_to_add.join('|')
end
@@ -782,29 +877,45 @@
# 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
http_send(@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.")
sleep @options[:retry_delay]
make_api_request(form_data, continue_xpath, retry_count + 1)
end
# Check response for errors and return XML
raise MediaWiki::Exception.new "Bad response: #{response}" unless response.code >= 200 and response.code < 300
doc = get_response(response.dup)
- if(form_data['action'] == 'login')
- login_result = doc.elements["login"].attributes['result']
+ action = form_data['action']
+
+ # login and createaccount actions require a second request with a token received on the first request
+ if %w(login createaccount).include?(action)
+ action_result = doc.elements[action].attributes['result']
@cookies.merge!(response.cookies)
- case login_result
- when "Success" then # do nothing
- when "NeedToken" then make_api_request(form_data.merge('lgtoken' => doc.elements["login"].attributes["token"]))
- else raise Unauthorized.new "Login failed: " + login_result
- end
+
+ case action_result.downcase
+ when "success" then
+ return [doc, false]
+ when "needtoken"
+ token = doc.elements[action].attributes["token"]
+ if action == 'login'
+ return make_api_request(form_data.merge('lgtoken' => token))
+ elsif action == 'createaccount'
+ return make_api_request(form_data.merge('token' => token))
+ end
+ else
+ if action == 'login'
+ raise Unauthorized.new("Login failed: #{action_result}")
+ elsif action == 'createaccount'
+ raise Unauthorized.new("Account creation failed: #{action_result}")
+ end
+ end
end
+
continue = (continue_xpath and doc.elements['query-continue']) ? REXML::XPath.first(doc, continue_xpath).value : nil
return [doc, continue]
end
end