Class: MediaWiktory::Wikipedia::Actions::Base

Inherits:
Object
  • Object
show all
Includes:
GlobalParams
Defined in:
lib/mediawiktory/wikipedia/actions/base.rb

Overview

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 Api methods (included from 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 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:

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:

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:

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['pages'].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"

Direct Known Subclasses

Get, Post

Instance Method Summary collapse

Methods included from GlobalParams

#assert, #assertuser, #centralauthtoken, #curtimestamp, #errorformat, #errorlang, #errorsuselocal, #format, #maxage, #maxlag, #origin, #requestid, #responselanginfo, #servedby, #smaxage, #uselang

Instance Method Details

#inspectString

Returns:

  • (String)


228
229
230
# File 'lib/mediawiktory/wikipedia/actions/base.rb', line 228

def inspect
  "#<#{self.class.name} #{to_h}>"
end

#merge(hash) ⇒ Action

Make new action, with additional params passed as hash. No params validations are made.

Parameters:

  • hash (Hash)

    Params to merge. All keys and values would be stringified.

Returns:

  • (Action)

    Produced action of the same type as current action was, with all passed params applied.



237
238
239
240
241
242
243
# 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

#nameString

Action's name on MediaWiki API (e.g. "query" for Query action, "parsoid-batch" for ParsoidBatch action and so on).

Returns:

  • (String)


260
261
262
263
264
265
# 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

#performString

Performs action (through GET or POST request, depending on action's type) and returns raw body of response.

Returns:

  • (String)


296
297
298
299
# 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

#responseResponse

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 action returns absolutely different JSON structure, corresponding to global OpenSearch standard.

Note also, that on erroneous request (when response contains "error" key), this method will raise Response::Error.

Returns:



314
315
316
317
# File 'lib/mediawiktory/wikipedia/actions/base.rb', line 314

def response
  jsonable = format(:json)
  Response.parse(jsonable, jsonable.perform)
end

#to_hHash{String => String}

All action's params in a ready to passing to URL form (string keys & string values).

Examples:

api.query.titles('Argentina', 'Bolivia').format(:json).to_h
# => {"titles"=>"Argentina|Bolivia", "format"=>"json"}

Returns:

  • (Hash{String => String})


252
253
254
# File 'lib/mediawiktory/wikipedia/actions/base.rb', line 252

def to_h
  @params.dup
end

#to_paramHash{String => String}

All action's params in a ready to passing to URL form (string keys & string values). Unlike #to_h, includes also action name.

Examples:

api.query.titles('Argentina', 'Bolivia').format(:json).to_param
# => {"titles"=>"Argentina|Bolivia", "format"=>"json", "action"=>"query"}

Returns:

  • (Hash{String => String})


275
276
277
# File 'lib/mediawiktory/wikipedia/actions/base.rb', line 275

def to_param
  to_h.merge('action' => name)
end

#to_urlString

Full URL for this action invocation.

Examples:

api.query.titles('Argentina', 'Bolivia').format(:json).to_url
# => "https://en.wikipedia.org/w/api.php?action=query&format=json&titles=Argentina%7CBolivia"

Returns:

  • (String)


286
287
288
289
290
# File 'lib/mediawiktory/wikipedia/actions/base.rb', line 286

def to_url
  url = @client.url
  url.query_values = to_param
  url.to_s
end