lib/infoboxer/media_wiki.rb in infoboxer-0.2.8 vs lib/infoboxer/media_wiki.rb in infoboxer-0.3.0.pre

- old
+ new

@@ -45,19 +45,18 @@ # Creating new MediaWiki client. {Infoboxer.wiki} provides shortcut # for it, as well as shortcuts for some well-known wikis, like # {Infoboxer.wikipedia}. # - # @param api_base_url URL of `api.php` file in your MediaWiki + # @param api_base_url [String] URL of `api.php` file in your MediaWiki # installation. Typically, its `<domain>/w/api.php`, but can vary # in different wikis. - # @param options Only one option is currently supported: - # * `:user_agent` (also aliased as `:ua`) -- custom User-Agent header. - def initialize(api_base_url, options = {}) + # @param user_agent [String] (also aliased as `:ua`) Custom User-Agent header. + def initialize(api_base_url, ua: nil, user_agent: ua) @api_base_url = Addressable::URI.parse(api_base_url) - @client = MediaWiktory::Wikipedia::Api.new(api_base_url, user_agent: user_agent(options)) - @traits = Traits.get(@api_base_url.host, namespaces: extract_namespaces) + @client = MediaWiktory::Wikipedia::Api.new(api_base_url, user_agent: user_agent(user_agent)) + @traits = Traits.get(@api_base_url.host, siteinfo) end # Receive "raw" data from Wikipedia (without parsing or wrapping in # classes). # @@ -121,11 +120,13 @@ # infobox.fetch('some value') # ``` # and obtain meaningful results instead of `NoMethodError` or # `SomethingNotFound`. # - def get(*titles, prop: []) + def get(*titles, prop: [], interwiki: nil) + return interwikis(interwiki).get(*titles, prop: prop) if interwiki + pages = get_h(*titles, prop: prop).values.compact titles.count == 1 ? pages.first : Tree::Nodes[*pages] end # Same as {#get}, but returns hash of `{requested title => page}`. @@ -249,19 +250,28 @@ namespace ||= traits.category_namespace.first [namespace, titl].join(':') end - def user_agent(options) - options[:user_agent] || options[:ua] || self.class.user_agent || UA + def user_agent(custom) + custom || self.class.user_agent || UA end - def extract_namespaces - siteinfo = @client.query.meta(:siteinfo).prop(:namespaces, :namespacealiases).response - siteinfo['namespaces'].map do |_, namespace| - aliases = - siteinfo['namespacealiases'].select { |a| a['id'] == namespace['id'] }.map { |a| a['*'] } - namespace.merge('aliases' => aliases) - end + def siteinfo + @siteinfo ||= @client.query.meta(:siteinfo).prop(:namespaces, :namespacealiases, :interwikimap).response.to_h + end + + def interwikis(prefix) + @interwikis ||= Hash.new { |h, pre| + interwiki = siteinfo['interwikimap'].detect { |iw| iw['prefix'] == prefix } or + fail ArgumentError, "Undefined interwiki: #{prefix}" + + # FIXME: fragile, but what can we do?.. + m = interwiki['url'].match(%r{^(.+)/wiki/\$1$}) or + fail ArgumentError, "Interwiki #{interwiki} seems not to be a MediaWiki instance" + h[pre] = self.class.new("#{m[1]}/w/api.php") # TODO: copy useragent + } + + @interwikis[prefix] end end end