Class: Smiten::Core

Inherits:
OpenStruct
  • Object
show all
Defined in:
lib/smiten/core.rb,
lib/smiten/api.rb

Overview

The Core class implements those calls that are common to both the Smite and Paladins endpoints

Direct Known Subclasses

Paladins, Smite

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Core

Creates a new connection to the Hirez API end points It takes a single hash parameter which must contain the following two keys

:developerId
:authKey

These can be requested from the Hirez development team



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/smiten/core.rb', line 46

def initialize(options)
  # We default to talking to the paladins endpoint
  options.merge!(headers: { 'Content-Type' => 'application/json' })
  options.merge!(url: PaladinsEndpoint) unless options[:url]
  @developerId = options.delete(:developerId)
  @authKey = options.delete(:authKey)
  @language_code = LanguageCode[:english]
  @portal_id = nil
  @session_id = nil
  @connector = Faraday.new(options) do |f|
    f.request :json # encode req bodies as JSON
    f.request :retry # retry transient failures
    f.response :json # decode response bodies as JSON
  end
  @calls = {}
  build_apis
  super
end

Instance Attribute Details

#authKeyObject

Returns the value of attribute authKey.



21
22
23
# File 'lib/smiten/core.rb', line 21

def authKey
  @authKey
end

#callsObject (readonly)

Returns the value of attribute calls.



20
21
22
# File 'lib/smiten/core.rb', line 20

def calls
  @calls
end

#connectorObject (readonly)

Returns the value of attribute connector.



20
21
22
# File 'lib/smiten/core.rb', line 20

def connector
  @connector
end

#developerIdObject

Returns the value of attribute developerId.



21
22
23
# File 'lib/smiten/core.rb', line 21

def developerId
  @developerId
end

#language_codeObject (readonly)

Returns the value of attribute language_code.



20
21
22
# File 'lib/smiten/core.rb', line 20

def language_code
  @language_code
end

#portal_idObject

Returns the value of attribute portal_id.



21
22
23
# File 'lib/smiten/core.rb', line 21

def portal_id
  @portal_id
end

Instance Method Details

#boilerplate(meth) ⇒ Object

:nodoc:



86
87
88
# File 'lib/smiten/core.rb', line 86

def boilerplate(meth) #:nodoc:
  "#{meth}#{ResponseFormat}/#{developerId}/#{signature(meth)}/#{session_id}/#{timestamp}"
end

#build_apisObject

:nodoc:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/smiten/core.rb', line 23

def build_apis # :nodoc:
  @calls.merge!(core_api).freeze
  calls.each_key do |api|
    next if self.class.method_defined?(api)

    self.class.define_method(api) do |args = {}|
      args.each_pair do |key, value|
        send("#{key}=", value)
      end
      @url = calls[api][1].call
      payload = get
      { kind: calls[api][0], payload: payload }
    end
  end
end

#core_apiObject

Returns a hash containing the API signatures keyed by ruby method name



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/smiten/api.rb', line 4

def core_api
  { ping:                                   [nil,      -> { "ping#{ResponseFormat}" }],
    create_session:                         [nil,      -> { "#{boilerplate('createsession')}/#{timestamp}" }],
    test_session:                           [nil,      -> { "#{boilerplate('testsession')}" }],
    get_data_used:                          [nil,      -> { "#{boilerplate('getdataused')}" }],
    get_hirez_server_status:                [nil,      -> { "#{boilerplate('gethirezserverstatus')}" }],
    get_patch_info:                         [nil,      -> { "#{boilerplate('getpatchinfo')}" }],
    get_items:                              ['Item',   -> { "#{boilerplate('getitems')}/#{language_code}" }],
    get_bounty_items:                       [nil,      -> { "#{boilerplate('getbountyitems')}" }],
    get_player:                             ['Player', -> { "#{boilerplate('getplayer')}/#{player}#{"/#{portal_id}" if portal_id }"}],
    get_player_batch:                       ['Player', -> { "#{boilerplate('getplayerbatch')}/#{player_ids.map(&:to_s).join(',')}" }],
    get_player_id_by_name:                  [nil,      -> { "#{boilerplate('getplayeridbyname')}/#{player_name}" }],
    get_player_id_by_portal_user_id:        [nil,      -> { "#{boilerplate('getplayeridbyportaluserid')}/#{portal_id}/#{portal_user_id}" }],
    get_player_ids_by_gamer_tag:            [nil,      -> { "#{boilerplate('getplayeridsbygamertag')}/#{portal_id}/#{gamer_tag}" }],
    get_friends:                            [nil,      -> { "#{boilerplate('getfriends')}/#{player_id}" }],
    get_player_status:                      [nil,      -> { "#{boilerplate('getplayerstatus')}/#{player_id}" }],
    get_match_history:                      [nil,      -> { "#{boilerplate('getmatchhistory')}/#{player_id}" }],
    get_queue_stats:                        [nil,      -> { "#{boilerplate('getqueuestats')}/#{player_id}/#{queue_id}" }],
    search_players:                         [nil,      -> { "#{boilerplate('searchplayers')}/#{search_string}" }],
    get_demo_details:                       [nil,      -> { "#{boilerplate('getdemodetails')}/#{match_id}" }],
    get_match_details:                      [nil,      -> { "#{boilerplate('getmatchdetails')}/#{match_id}" }],
    get_match_details_batch:                [nil,      -> { "#{boilerplate('getmatchdetailsbatch')}/#{match_ids.map(&:to_s).join(',')}" }],
    get_match_ids_by_queue:                 [nil,      -> { "#{boilerplate('getmatchidsbyqueue')}/#{queue_id}/#{date}/#{hour}" }],
    get_match_player_details:               [nil,      -> { "#{boilerplate('getmatchplayerdetails')}/#{match_id}" }],
    get_top_matches:                        [nil,      -> { "#{boilerplate('gettopmatches')}" }],
    get_league_leaderboard:                 [nil,      -> { "#{boilerplate('getleagueleaderboard')}/#{queue_id}/#{tier}/#{round}" }],
    get_league_seasons:                     [nil,      -> { "#{boilerplate('getleagueseasons')}/#{queue_id}" }],
    get_team_details:                       [nil,      -> { "#{boilerplate('getteamdetails')}/#{team_id}" }],
    get_team_players:                       [nil,      -> { "#{boilerplate('getteamplayers')}/#{team_id}" }],
    get_esports_proleague_details:          [nil,      -> { "#{boilerplate('getesportsproleaguedetails')}" }],
    get_motd:                               [nil,      -> { "#{boilerplate('getmotd')}"}]
  }
end

#for_champion(id) {|_self| ... } ⇒ Object

Sets the champion_id on the connection and returns the connection

Yields:

  • (_self)

Yield Parameters:

  • _self (Smiten::Core)

    the object that the method was called on



91
92
93
94
# File 'lib/smiten/core.rb', line 91

def for_champion(id)
  self.champion_id = id
  yield(self)
end

#getObject

Synchronously retrieve the response from the Hirez WEB API



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/smiten/core.rb', line 111

def get
  # NOTE: The html error page returned from Hirez breaks the json parser. I just ignore that and
  # retrieve the original response
  start = Time.now
  5.times do
    begin
      result = connector.get(@url)
    rescue Faraday::ParsingError => e
      result = e.response
    end
    case
    when (200..300).include?(result.status)
      return result.body
    when result.status == 408
      puts '* Server Timeout detected... Retrying'
    when result.status == 504
      puts '* Gateway Timeout detected... Retrying'
    else
      raise(Error, "API Response Error:#{textify(result.body)}")
    end
  end
  puts "* Timeout detected... Terminating after #{Time.now - start} seconds"
  nil
end

#in_language(name_or_id) {|_self| ... } ⇒ Object

Sets the language on the connection and returns the connection Accepts either a language_code or the language name as a symbol

Yields:

  • (_self)

Yield Parameters:

  • _self (Smiten::Core)

    the object that the method was called on



98
99
100
101
# File 'lib/smiten/core.rb', line 98

def in_language(name_or_id)
  self.language_code = name_or_id.is_a?(Numeric) ? name_or_id : LanguageCode[name_or_id]
  yield(self)
end

#inceptObject

:nodoc:



65
66
67
# File 'lib/smiten/core.rb', line 65

def incept # :nodoc:
  @incept ||= Time.now
end

#session_idObject

:nodoc:



77
78
79
80
81
82
83
84
# File 'lib/smiten/core.rb', line 77

def session_id # :nodoc:
  return @session_id if @session_id && (incept + FifteenMins > Time.now)

  response = connector.get("createsession#{ResponseFormat}/#{developerId}/#{signature('createsession')}/#{timestamp}")
  raise Error("Failed to retrieve a session ID from #{connector.url}") unless response.status == 200

  @session_id = response.body['session_id']
end

#signature(api_call) ⇒ Object

:nodoc:



73
74
75
# File 'lib/smiten/core.rb', line 73

def signature(api_call) # :nodoc:
  Digest::MD5.hexdigest(developerId + api_call.to_s + authKey + timestamp)
end

#textify(html) ⇒ Object

:nodoc:



136
137
138
139
140
141
# File 'lib/smiten/core.rb', line 136

def textify(html) # :nodoc:
  return html unless html =~ /<head>/

  body = html[%r{<body>(.*)</body>}m,1]
  body.split(/<p[^>]*>/)[1..-1].map { |txt| txt.sub(%r{</p>.*}m, "") }.join(": ")
end

#timestampObject

:nodoc:



69
70
71
# File 'lib/smiten/core.rb', line 69

def timestamp # :nodoc:
  @timestamp ||= incept.getutc.strftime('%Y%m%d%H%M%S')
end