class MediaWiktory::Wikipedia::Actions::Base
Base
class for all {MediaWiktory::Wikipedia::Api} actions. “Actions” is MediaWiki's term for different request types. Everything you are doing with your target MediaWiki installation, you are doing by _performing actions_.
Typically, you should never instantiate this class or its descendants directly, but rather by {MediaWiktory::Wikipedia::Api Api} methods (included from {MediaWiktory::Wikipedia::Actions Actions} module).
The usual workflow with actions is:
-
Create it with `api.action_name`
-
Set action params with subsequent `paramname(paramvalue)` calls;
-
Perform action with {#perform} (returns row MediaWiki response as a string) or {#response} (returns {MediaWiktory::Wikipedia::Response} class with parsed data and helper methods).
Note that some of `paramname(value)` calls include new {Modules} into action, which provides new params & methods. For example:
“`ruby api.query.generator(:categorymembers) # includes new methods of GCategorymembers module
.title('Category:DOS_games') # one of GCategorymembers methods, adds gcmtitle=Category:DOS_games to URL .limit(20)
“`
Sometimes new modules inclusion can change a sense of already existing methods:
“`ruby api.query.titles('Argentina')
.prop(:revisions) # .prop method from Query action, adds prop=revisions to URL and includes Revisions module .prop(:content) # .prop method from Revisions module, adds rvprop=content to URL
“`
Despite of how questionable this practice looks, it provides the most obvious method chains even for most complicated cases.
Some setup methods shared between all the actions (like output format and TTL settings of response) are defined in {GlobalParams}.
Full action usage example:
“`ruby api = MediaWiktory::Wikipedia::Api.new
action = api.new.query.titles('Argentina').prop(:revisions).prop(:content).meta(:siteinfo) # => #<MediaWiktory::Wikipedia::Actions::Query {“titles”=>“Argentina”, “prop”=>“revisions”, “rvprop”=>“content”, “meta”=>“siteinfo”}> response = action.response # => #<MediaWiktory::Wikipedia::Response(query): pages, general> puts response.values # all pages…
.first['revisions'] # take revisions from first... .first['*'] # take content from first revision... .split("\n").first(3) # and first 3 paragrapahs
# {{other uses}} # {{pp-semi|small=yes}} # {{Use dmy dates|date=March 2017}} response.dig('general', 'sitename') # => “Wikipedia” “`
Attributes
@private
Public Class Methods
@private
# File lib/mediawiktory/wikipedia/actions/base.rb, line 221 def initialize(client, options = {}) @client = client @params = stringify_hash(options) @submodules = [] end
Public Instance Methods
@return [String]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 228 def inspect "#<#{self.class.name} #{to_h}>" end
Make new action, with additional params passed as `hash`. No params validations are made.
@param hash [Hash] Params to merge. All keys and values would be stringified. @return [Action] Produced action of the same type as current action was, with all passed
params applied.
# File lib/mediawiktory/wikipedia/actions/base.rb, line 237 def merge(hash) replace = hash.fetch(:replace, true) hash.delete(:replace) self.class .new(@client, @params.merge(stringify_hash(hash)) { |_, o, n| replace ? n : [o, n].compact.uniq.join('|') }) .tap { |action| @submodules.each { |sm| action.submodule(sm) } } end
Action's name on MediaWiki API (e.g. “query” for `Query` action, “parsoid-batch” for `ParsoidBatch` action and so on).
@return [String]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 260 def name # Query # => query # ParsoidBatch # => parsoid-batch self.class.name.split('::').last.gsub(/([a-z])([A-Z])/, '\1-\2').downcase or fail ArgumentError, "Can't guess action name from #{self.class.name}" end
Performs action (through `GET` or `POST` request, depending on action's type) and returns raw body of response.
@return [String]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 296 def perform fail NotImplementedError, 'Action is abstract, all actions should descend from Actions::Get or Actions::Post' end
Performs action (as in {#perform}) and returns an instance of {Response}. It is a thing wrapper around parsed action's JSON response, which separates “content” and “meta” (paging, warnings/erros) fields.
Note, that not all actions return a JSON suitable for parsing into {Response}. For example, Wikipedia's [opensearch](en.wikipedia.org/w/api.php?action=help&modules=opensearch) action returns absolutely different JSON structure, corresponding to global [OpenSearch](en.wikipedia.org/wiki/OpenSearch) standard.
Note also, that on erroneous request (when response contains `“error”` key), this method will raise {Response::Error}.
@return [Response]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 314 def response jsonable = format(:json) Response.parse(jsonable, jsonable.perform) end
All action's params in a ready to passing to URL form (string keys & string values).
@example
api.query.titles('Argentina', 'Bolivia').format(:json).to_h # => {"titles"=>"Argentina|Bolivia", "format"=>"json"}
@return [Hash{String => String}]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 252 def to_h @params.dup end
All action's params in a ready to passing to URL form (string keys & string values). Unlike {#to_h}, includes also action name.
@example
api.query.titles('Argentina', 'Bolivia').format(:json).to_param # => {"titles"=>"Argentina|Bolivia", "format"=>"json", "action"=>"query"}
@return [Hash{String => String}]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 275 def to_param to_h.merge('action' => name) end
Full URL for this action invocation.
@example
api.query.titles('Argentina', 'Bolivia').format(:json).to_url # => "https://en.wikipedia.org/w/api.php?action=query&format=json&titles=Argentina%7CBolivia"
@return [String]
# File lib/mediawiktory/wikipedia/actions/base.rb, line 286 def to_url url = @client.url url.query_values = to_param url.to_s end
Protected Instance Methods
# File lib/mediawiktory/wikipedia/actions/base.rb, line 332 def submodule(mod) extend(mod) @submodules << mod self end
Private Instance Methods
Not in indepented module to decrease generated files/modules list
# File lib/mediawiktory/wikipedia/actions/base.rb, line 324 def stringify_hash(hash, recursive: false) hash.map { |k, v| [k.to_s, v.is_a?(Hash) && recursive ? stringify_hash(v, recursive: true) : v.to_s] }.to_h end