lib/media_wiki/gateway.rb in mediawiki-gateway-0.5.0 vs lib/media_wiki/gateway.rb in mediawiki-gateway-0.5.1

- old
+ new

@@ -36,11 +36,11 @@ } @options = default_options.merge(options) @wiki_url = url @log = Logger.new(@options[:logdevice]) @log.level = @options[:loglevel] - @headers = { "User-Agent" => "MediaWiki::Gateway/#{MediaWiki::VERSION}" } + @headers = { "User-Agent" => "MediaWiki::Gateway/#{MediaWiki::VERSION}", "Accept-Encoding" => "gzip" } @cookies = {} end attr_reader :base_url, :cookies @@ -348,10 +348,55 @@ titles += REXML::XPath.match(res, "//p").map { |x| x.attributes["title"] } end while offset titles end + # Get a list of users + # + # [options] Optional hash of options, eg. { 'augroup' => 'sysop' }. See http://www.mediawiki.org/wiki/API:Allusers + # + # Returns array of user names (empty if no matches) + def users(options = {}) + names = [] + aufrom = nil + begin + form_data = options.merge( + {'action' => 'query', + 'list' => 'allusers', + 'aufrom' => aufrom, + 'aulimit' => @options[:limit]}) + res, aufrom = make_api_request(form_data, '//query-continue/allusers/@aufrom') + names += REXML::XPath.match(res, "//u").map { |x| x.attributes["name"] } + end while aufrom + names + end + + # Get user contributions + # + # user: The user name + # count: Maximum number of contributions to retreive, or nil for all + # [options] Optional hash of options, eg. { 'ucnamespace' => 4 }. See http://www.mediawiki.org/wiki/API:Usercontribs + # + # Returns array of hashes containing the "item" attributes defined here: http://www.mediawiki.org/wiki/API:Usercontribs + def contributions(user, count = nil, options = {}) + result = [] + ucstart = nil + begin + limit = [count, @options[:limit]].compact.min + form_data = options.merge( + {'action' => 'query', + 'list' => 'usercontribs', + 'ucuser' => user, + 'ucstart' => ucstart, + 'uclimit' => limit}) + res, ucstart = make_api_request(form_data, '//query-continue/usercontribs/@ucstart') + result += REXML::XPath.match(res, "//item").map { |x| x.attributes.inject({}) { |hash, data| hash[data.first] = data.last; hash } } + break if count and result.size >= count + end while ucstart + result + end + # Upload a file, or get the status of pending uploads. Several # methods are available: # # * Upload file contents directly. # * Have the MediaWiki server fetch a file from a URL, using the @@ -548,21 +593,45 @@ extensions[name] = extension.attributes["version"] extensions end end + # Sends e-mail to a user + # + # [user] Username to send mail to (name only: eg. 'Bob', not 'User:Bob') + # [subject] Subject of message + # [content] Content of message + # + # Will raise a 'noemail' APIError if the target user does not have a confirmed email address, see http://www.mediawiki.org/wiki/API:E-mail for details. + def email_user(user, subject, text) + form_data = { 'action' => 'emailuser', 'target' => user, 'subject' => subject, 'text' => text, 'token' => get_token('email', "User:" + user) } + res, dummy = make_api_request(form_data) + res.elements['emailuser'].attributes['result'] == 'Success' + end + # Execute Semantic Mediawiki query # # [query] Semantic Mediawiki query # [params] Array of additional parameters or options, eg. mainlabel=Foo or ?Place (optional) # # Returns result as an HTML string def semantic_query(query, params = []) - params << "format=list" - form_data = { 'action' => 'parse', 'prop' => 'text', 'text' => "{{#ask:#{query}|#{params.join('|')}}}" } - xml, dummy = make_api_request(form_data) - return xml.elements["parse/text"].text + if extensions.include? 'Semantic MediaWiki' + smw_version = extensions['Semantic MediaWiki'].to_f + if smw_version >= 1.7 + form_data = { 'action' => 'ask', 'query' => "#{query}|#{params.join('|')}"} + xml, dummy = make_api_request(form_data) + return xml + else + params << "format=list" + form_data = { 'action' => 'parse', 'prop' => 'text', 'text' => "{{#ask:#{query}|#{params.join('|')}}}" } + xml, dummy = make_api_request(form_data) + return xml.elements["parse/text"].text + end + else + raise MediaWiki::Exception.new "Semantic MediaWiki extension not installed." + end end # Set groups for a user # # [user] Username of user to modify @@ -586,11 +655,11 @@ res end private - # Fetch token (type 'delete', 'edit', 'import', 'move', 'protect') + # Fetch token (type 'delete', 'edit', 'email', '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? @@ -642,9 +711,35 @@ 'reason' => reason } res, dummy = make_api_request(form_data) res end + + + # Make a custom query + # + # [options] query options + # + # Returns the REXML::Element object as result + # + # Example: + # def creation_time(pagename) + # res = bot.custom_query(:prop => :revisions, + # :titles => pagename, + # :rvprop => :timestamp, + # :rvdir => :newer, + # :rvlimit => 1) + # timestr = res.get_elements('*/*/*/rev')[0].attribute('timestamp').to_s + # time.parse(timestr) + # end + # + def custom_query(options) + form_data = {} + options.each {|k,v| form_data[k.to_s] = v.to_s } + form_data['action'] = 'query' + make_api_request(form_data).first.elements['query'] + end + # Make generic request to API # # [form_data] hash or string of attributes to post # [continue_xpath] XPath selector for query continue parameter