ruby-iactionable 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. data/.gitignore +4 -0
  2. data/.rvmrc +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +43 -0
  6. data/README.md +49 -0
  7. data/Rakefile +1 -0
  8. data/lib/iactionable/api.rb +170 -0
  9. data/lib/iactionable/connection.rb +114 -0
  10. data/lib/iactionable/error.rb +17 -0
  11. data/lib/iactionable/objects/achievement.rb +29 -0
  12. data/lib/iactionable/objects/awardable.rb +50 -0
  13. data/lib/iactionable/objects/challenge.rb +27 -0
  14. data/lib/iactionable/objects/goal.rb +30 -0
  15. data/lib/iactionable/objects/i_actionable_object.rb +36 -0
  16. data/lib/iactionable/objects/identifier.rb +17 -0
  17. data/lib/iactionable/objects/leaderboard.rb +15 -0
  18. data/lib/iactionable/objects/leaderboard_report.rb +30 -0
  19. data/lib/iactionable/objects/level.rb +24 -0
  20. data/lib/iactionable/objects/level_type.rb +15 -0
  21. data/lib/iactionable/objects/point_type.rb +15 -0
  22. data/lib/iactionable/objects/profile_achievements.rb +20 -0
  23. data/lib/iactionable/objects/profile_challenges.rb +20 -0
  24. data/lib/iactionable/objects/profile_goals.rb +20 -0
  25. data/lib/iactionable/objects/profile_level.rb +20 -0
  26. data/lib/iactionable/objects/profile_notifications.rb +29 -0
  27. data/lib/iactionable/objects/profile_points.rb +29 -0
  28. data/lib/iactionable/objects/profile_summary.rb +32 -0
  29. data/lib/iactionable/objects/progress.rb +46 -0
  30. data/lib/iactionable/objects.rb +27 -0
  31. data/lib/iactionable/settings.rb +30 -0
  32. data/lib/iactionable/version.rb +3 -0
  33. data/lib/iactionable.rb +9 -0
  34. data/ruby_iactionable.gemspec +28 -0
  35. data/spec/api/get_achievements_api_response_spec.rb +46 -0
  36. data/spec/api/get_challenges_api_response_spec.rb +42 -0
  37. data/spec/api/get_goals_api_response_spec.rb +46 -0
  38. data/spec/api/get_leaderboard_api_response_spec.rb +76 -0
  39. data/spec/api/get_profile_achievements_api_response_spec.rb +99 -0
  40. data/spec/api/get_profile_api_response_spec.rb +103 -0
  41. data/spec/api/get_profile_challenges_api_response_spec.rb +85 -0
  42. data/spec/api/get_profile_goals_api_response_spec.rb +89 -0
  43. data/spec/api/get_profile_notifications_api_response_spec.rb +75 -0
  44. data/spec/api/get_profile_points_api_response_spec.rb +67 -0
  45. data/spec/api_spec.rb +314 -0
  46. data/spec/connection_spec.rb +111 -0
  47. data/spec/settings_spec.rb +52 -0
  48. data/spec/spec_helper.rb +1 -0
  49. metadata +163 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ .bundle
3
+ .DS_Store
4
+ .rvmrc
data/.rvmrc ADDED
@@ -0,0 +1,3 @@
1
+ rvm_gemset_create_on_use_flag=1
2
+ rvm use ruby-1.9.2-p136@ruby_iactionable
3
+ rvm wrapper ruby-1.9.2-p136@ruby_iactionable textmate
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # CHANGELOG #
2
+
3
+ ## 0.0.1 ##
4
+
5
+ * Pulling API wrapper out as separate gem (this).
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ruby_iactionable.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ Ruby IActionable (0.0.1)
5
+ activesupport (>= 3.0.0)
6
+ faraday
7
+ faraday-stack
8
+ rake
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ activesupport (3.2.1)
14
+ i18n (~> 0.6)
15
+ multi_json (~> 1.0)
16
+ addressable (2.2.6)
17
+ diff-lcs (1.1.3)
18
+ faraday (0.7.6)
19
+ addressable (~> 2.2)
20
+ multipart-post (~> 1.1)
21
+ rack (~> 1.1)
22
+ faraday-stack (0.1.5)
23
+ faraday (>= 0.6, < 0.8)
24
+ i18n (0.6.0)
25
+ multi_json (1.0.4)
26
+ multipart-post (1.1.4)
27
+ rack (1.4.1)
28
+ rake (0.9.2.2)
29
+ rspec (2.7.0)
30
+ rspec-core (~> 2.7.0)
31
+ rspec-expectations (~> 2.7.0)
32
+ rspec-mocks (~> 2.7.0)
33
+ rspec-core (2.7.1)
34
+ rspec-expectations (2.7.0)
35
+ diff-lcs (~> 1.1.2)
36
+ rspec-mocks (2.7.0)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ Ruby IActionable!
43
+ rspec (>= 2.6)
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Overview #
2
+
3
+ Ruby IActionable is a straightforward wrapper for IActionable's restful API. The JSON-encoded responses from IActionable are wrapped in objects that provide a few extra functions here and there, but are mostly just a representation of the API response.
4
+
5
+ # How To Use #
6
+
7
+ ## Installation ##
8
+
9
+ gem install ruby-iactionable
10
+
11
+ ## IRB ##
12
+
13
+ require 'iactionable'
14
+
15
+ ## Bundler ##
16
+
17
+ gem 'ruby-iactionable', :require => 'iactionable'
18
+
19
+ ## API Credentials And Initialization ##
20
+
21
+ Before the API wrapper can be instantiated or used it must be pre-initialized with your IActionable credentials and version number (IActionable supports older versions but recommends staying up to date):
22
+
23
+ IActionable::Api.init_settings( :app_key => "12345",
24
+ :api_key => "abcde",
25
+ :version => 3 )
26
+ @api = IActionable::Api.new
27
+
28
+ The responses for each of the endpoints of IActionable's API are described through example by [their documentation](http://www.iactionable.com/api/). Here is an example of the response from a [profile summary](http://iactionable.com/api/profiles/#getprofilesummary) returned as an object by the wrapper.
29
+
30
+ profile_summary = @api.get_profile_summary("user", "username", "zortnac", 10)
31
+ profile_summary.display_name # => "Chris Eberz"
32
+ profile_summary.identifiers.first # => instance of IActionable::Objects::Identifier
33
+ profile_summary.identifiers.first.id_type # => "username"
34
+ profile_summary.identifiers.first.id # => "zortnac"
35
+
36
+ Each object can be dumped back in to its original form of arrays and key/value pairs:
37
+
38
+ profile_summary.to_hash # => { "DisplayName" => "Chris Eberz", "Identifiers" => [ {"ID" => "zortnac", "IDType" => "username", ...} ] ... }
39
+ # (not shown in entirety)
40
+
41
+ ----------------
42
+
43
+ ## IActionable ##
44
+
45
+ [Visit their website!](http://www.iactionable.com)
46
+
47
+ ## Author ##
48
+
49
+ Christopher Eberz; chris@chriseberz.com; @zortnac
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,170 @@
1
+ require 'iactionable/connection.rb'
2
+ require 'iactionable/settings.rb'
3
+ require 'iactionable/objects.rb'
4
+
5
+ module IActionable
6
+
7
+ class Api
8
+ attr :connection
9
+ @@settings = nil
10
+
11
+ def initialize
12
+ if @@settings
13
+ @connection = IActionable::Connection.new(@@settings)
14
+ else
15
+ raise IActionable::ConfigError.new("IActionable::Api cannot be initialized without credentials being set in IActionable::Api.init_settings()")
16
+ end
17
+ end
18
+
19
+ def self.init_settings(values)
20
+ @@settings = IActionable::Settings.new(values)
21
+ rescue IActionable::ConfigError => e
22
+ raise e
23
+ end
24
+
25
+ def self.settings
26
+ @@settings
27
+ end
28
+
29
+ # =================
30
+ # = Event Logging =
31
+ # =================
32
+
33
+ def log_event(profile_type, id_type, id, event_key, event_attrs = {})
34
+ response = @connection.request.with_app_key.with_api_key.to("/#{profile_type}/#{id_type}/#{id}/events/#{event_key}").with_params(event_attrs).post
35
+ end
36
+
37
+ # =====================
38
+ # = Profile API calls =
39
+ # =====================
40
+
41
+ def get_profile_summary(profile_type, id_type, id, achievement_count = nil)
42
+ request = @connection.request.with_app_key.to("/#{profile_type}/#{id_type}/#{id}")
43
+ request.with_params(:achievementCount => achievement_count) unless achievement_count.blank?
44
+ response = request.get
45
+ IActionable::Objects::ProfileSummary.new(response)
46
+ end
47
+
48
+ def create_profile(profile_type, id_type, id, display_name = nil)
49
+ request = @connection.request.with_app_key.with_api_key.to("/#{profile_type}/#{id_type}/#{id}")
50
+ request.with_params(:displayName => display_name) unless display_name.blank?
51
+ request.post
52
+ end
53
+ alias_method :update_profile, :create_profile
54
+
55
+ def add_profile_identifier(profile_type, id_type, id, alt_id_type, alt_id)
56
+ @connection.request.with_app_key.with_api_key.to("/#{profile_type}/#{id_type}/#{id}/identifiers/#{alt_id_type}/#{alt_id}").post
57
+ end
58
+
59
+ # ====================
60
+ # = Points API calls =
61
+ # ====================
62
+
63
+ def get_profile_points(profile_type, id_type, id, point_type)
64
+ response = @connection.request.with_app_key.to("/#{profile_type}/#{id_type}/#{id}/points/#{point_type}").get
65
+ IActionable::Objects::ProfilePoints.new(response)
66
+ end
67
+
68
+ def update_profile_points(profile_type, id_type, id, point_type, amount, reason = nil)
69
+ request = @connection.request.with_app_key.with_api_key.to("/#{profile_type}/#{id_type}/#{id}/points/#{point_type}").with_params(:value => amount)
70
+ request.with_params(:description => reason) unless reason.blank?
71
+ response = request.post
72
+ IActionable::Objects::ProfilePoints.new(response)
73
+ end
74
+
75
+ # =========================
76
+ # = Achievement API calls =
77
+ # =========================
78
+
79
+ def get_profile_achievements(profile_type, id_type, id, filter_type = nil)
80
+ request = @connection.request.with_app_key
81
+ case filter_type
82
+ when :completed
83
+ request.to("/#{profile_type}/#{id_type}/#{id}/achievements/Completed")
84
+ when :available
85
+ request.to("/#{profile_type}/#{id_type}/#{id}/achievements/Available")
86
+ else
87
+ request.to("/#{profile_type}/#{id_type}/#{id}/achievements")
88
+ end
89
+ IActionable::Objects::ProfileAchievements.new(request.get)
90
+ end
91
+
92
+ def get_achievements()
93
+ response = @connection.request.with_app_key.to("/achievements").get
94
+ response.map{|achievement_json| IActionable::Objects::Achievement.new(achievement_json)}
95
+ rescue NoMethodError => e
96
+ []
97
+ end
98
+
99
+ # ========================
100
+ # = Challenges API calls =
101
+ # ========================
102
+
103
+ def get_profile_challenges(profile_type, id_type, id, filter_type = nil)
104
+ request = @connection.request.with_app_key
105
+ case filter_type
106
+ when :completed
107
+ request.to("/#{profile_type}/#{id_type}/#{id}/challenges/Completed")
108
+ when :available
109
+ request.to("/#{profile_type}/#{id_type}/#{id}/challenges/Available")
110
+ else
111
+ request.to("/#{profile_type}/#{id_type}/#{id}/challenges")
112
+ end
113
+ IActionable::Objects::ProfileChallenges.new(request.get)
114
+ end
115
+
116
+ def get_challenges()
117
+ response = @connection.request.with_app_key.to("/challenges").get
118
+ response.map{|challenge_json| IActionable::Objects::Challenge.new(challenge_json)}
119
+ rescue NoMethodError => e
120
+ []
121
+ end
122
+
123
+ # ===================
124
+ # = Goals API calls =
125
+ # ===================
126
+
127
+ def get_profile_goals(profile_type, id_type, id, filter_type = nil)
128
+ request = @connection.request.with_app_key
129
+ case filter_type
130
+ when :completed
131
+ request.to("/#{profile_type}/#{id_type}/#{id}/goals/Completed")
132
+ when :available
133
+ request.to("/#{profile_type}/#{id_type}/#{id}/goals/Available")
134
+ else
135
+ request.to("/#{profile_type}/#{id_type}/#{id}/goals")
136
+ end
137
+ IActionable::Objects::ProfileGoals.new(request.get)
138
+ end
139
+
140
+ def get_goals()
141
+ response = @connection.request.with_app_key.to("/goals").get
142
+ response.map{|goal_json| IActionable::Objects::Goal.new(goal_json)}
143
+ rescue NoMethodError => e
144
+ []
145
+ end
146
+
147
+ # =========================
148
+ # = Leaderboard API calls =
149
+ # =========================
150
+
151
+ def get_leaderboard(profile_type, point_type, leaderboard, page_number=nil, page_count=nil, id=nil, id_type=nil)
152
+ request = @connection.request.with_app_key.to("/#{profile_type}/leaderboards/points/#{point_type}/#{leaderboard}")
153
+ request.with_params(:pageNumber => page_number) unless page_number.blank?
154
+ request.with_params(:pageCount => page_count) unless page_count.blank?
155
+ request.with_params(:id => id) unless id.blank? || id_type.blank?
156
+ request.with_params(:idType => id_type) unless id.blank? || id_type.blank?
157
+ response = request.get
158
+ IActionable::Objects::LeaderboardReport.new(response)
159
+ end
160
+
161
+ # ===================================
162
+ # = Profile Notifications API calls =
163
+ # ===================================
164
+
165
+ def get_profile_notifications(profile_type, id_type, id)
166
+ response = @connection.request.with_app_key.to("/#{profile_type}/#{id_type}/#{id}/notifications").get
167
+ IActionable::Objects::ProfileNotifications.new(response)
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,114 @@
1
+ require 'faraday'
2
+ require 'faraday_stack'
3
+ require 'iactionable/error'
4
+
5
+ module IActionable
6
+ class Request < Struct.new(:path, :params, :headers, :body)
7
+ attr :settings
8
+
9
+ def initialize(settings)
10
+ @settings = settings
11
+ self.path = nil
12
+ self.params = {}
13
+ self.headers = {}
14
+ self.body = {}
15
+ end
16
+
17
+ def to(path)
18
+ self.path = path unless path.nil? || path.empty?
19
+ self
20
+ end
21
+
22
+ def with_api_key
23
+ (self.headers[:Authorization] = @settings.api_key) and self
24
+ end
25
+
26
+ def with_app_key
27
+ (self.params[:appKey] = @settings.app_key) and self
28
+ end
29
+
30
+ def with_params(params={})
31
+ self.params.merge!(params) and self
32
+ end
33
+
34
+ def with_body(body={})
35
+ self.body.merge!(body) and self
36
+ end
37
+ end
38
+
39
+ class Connection
40
+ attr :connection
41
+ attr :settings
42
+ attr :request
43
+ attr_accessor :response
44
+
45
+ def initialize(settings)
46
+ @settings = settings
47
+
48
+ @connection = Faraday.new api_url(@settings.version) do |builder|
49
+ builder.use FaradayStack::ResponseJSON, content_type: 'application/json'
50
+ builder.use Faraday::Response::RaiseError
51
+ builder.use Faraday::Adapter::NetHttp
52
+ end
53
+
54
+ @request = nil
55
+ end
56
+
57
+ def request
58
+ (@request = Request.new(@settings)) and self
59
+ end
60
+
61
+ def get(path=nil, query_params={})
62
+ @request ||= Request.new(@settings)
63
+ @request.to(path).with_params(query_params)
64
+ @response = @connection.get do |req|
65
+ req.headers.merge! @request.headers
66
+ req.url @request.path, @request.params
67
+ end
68
+ @response.body
69
+ rescue Faraday::Error::ClientError => e
70
+ handle_client_error e
71
+ ensure
72
+ @request = nil
73
+ end
74
+
75
+ def post(path=nil, query_params={}, body_params={})
76
+ @request ||= Request.new(@settings)
77
+ @request.to(path).with_params(query_params)
78
+ @response = @connection.post do |req|
79
+ req.headers.merge! @request.headers
80
+ req.url @request.path, @request.params
81
+ req.body = @request.body unless @request.body.empty?
82
+ end
83
+ @response.body
84
+ rescue Exception => e
85
+ handle_client_error e
86
+ ensure
87
+ @request = nil
88
+ end
89
+
90
+ private
91
+
92
+ def method_missing(symbol, *args)
93
+ @request.send(symbol, *args) and self
94
+ rescue NoMethodError => e
95
+ raise e
96
+ end
97
+
98
+ def api_url(version)
99
+ "http://api.iactionable.com/v#{version}/"
100
+ end
101
+
102
+ def handle_client_error(e)
103
+ # http://iactionable.com/api/response-codes/
104
+ case e.response[:status]
105
+ when 400
106
+ raise IActionable::Error::BadRequest.new(e.response)
107
+ when 401
108
+ raise IActionable::Error::Unauthorized.new(e.response)
109
+ when 500
110
+ raise IActionable::Error::Internal.new(e.response)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,17 @@
1
+ module IActionable
2
+ module Error
3
+ class Error < StandardError
4
+ attr_accessor :response
5
+
6
+ def initialize(response)
7
+ @response = response
8
+ super
9
+ end
10
+ end
11
+
12
+ # http://iactionable.com/api/response-codes/
13
+ class BadRequest < Error; end
14
+ class Unauthorized < Error; end
15
+ class Internal < Error; end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ module IActionable
2
+ module Objects
3
+ class Achievement < IActionableObject
4
+ attr_accessor :key
5
+ attr_accessor :description
6
+ attr_accessor :image_url
7
+ attr_accessor :name
8
+
9
+ def initialize(key_values={})
10
+ initialize_awardable(key_values)
11
+ super(key_values)
12
+ end
13
+
14
+ awardable
15
+
16
+ def to_hash
17
+ hash = {
18
+ "Key" => @key,
19
+ "Description" => @description,
20
+ "ImageURL" => @image_url,
21
+ "Name" => @name
22
+ }
23
+ hash.merge!(awardable_hash) unless @progress.empty?
24
+ hash.delete("AwardDate") if @award_date.nil?
25
+ hash
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ module IActionable
2
+ module Objects
3
+ module Awardable
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def awardable
10
+ attr_accessor :award_date
11
+ attr_accessor :original_award_date
12
+ attr_accessor :progress
13
+ include IActionable::Objects::Awardable::InstanceMethods
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ def initialize_awardable(key_values={})
19
+ @progress = extract_many_as(key_values, "Progress", IActionable::Objects::Progress)
20
+ # convert the miliseconds within the date string to seconds (per ruby)
21
+ # "/Date(1275706032317-0600)/" => "1275706032-0600"
22
+ @original_award_date = @award_date = key_values.delete("AwardDate")
23
+ @award_date = IActionableObject.timestamp_to_seconds(@award_date) unless @award_date.blank?
24
+ end
25
+
26
+ def complete?
27
+ @progress.any? && @progress.all?
28
+ end
29
+
30
+ def percent_complete
31
+ Integer(Float(@progress.select{|p| p.complete?}.size) / @progress.size * 100)
32
+ rescue TypeError => e
33
+ 0
34
+ end
35
+
36
+ def awarded_on
37
+ # bug in ruby 1.9.2 where Time.strptime does not support seconds-since-epoch format, but Date.strptime does, so we'll use that for now
38
+ Date.strptime(@award_date, "%s%z").to_time unless @award_date.blank?
39
+ end
40
+
41
+ def awardable_hash
42
+ {
43
+ "AwardDate" => @original_award_date,
44
+ "Progress" => @progress.map{|prog| prog.to_hash}
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,27 @@
1
+ module IActionable
2
+ module Objects
3
+ class Challenge < IActionableObject
4
+ awardable
5
+
6
+ attr_accessor :key
7
+ attr_accessor :description
8
+ attr_accessor :name
9
+
10
+ def initialize(key_values={})
11
+ initialize_awardable(key_values)
12
+ super(key_values)
13
+ end
14
+
15
+ def to_hash
16
+ hash = {
17
+ "Key" => @key,
18
+ "Description" => @description,
19
+ "Name" => @name
20
+ }
21
+ hash.merge!(awardable_hash) unless @progress.empty?
22
+ hash.delete("AwardDate") if @award_date.nil?
23
+ hash
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ module IActionable
2
+ module Objects
3
+ class Goal < IActionableObject
4
+ awardable
5
+
6
+ attr_accessor :key
7
+ attr_accessor :description
8
+ attr_accessor :name
9
+ attr_accessor :interval
10
+
11
+ def initialize(key_values={})
12
+ initialize_awardable(key_values)
13
+ super(key_values)
14
+ end
15
+
16
+ def to_hash
17
+ hash = {
18
+ "Key" => @key,
19
+ "Description" => @description,
20
+ "Name" => @name,
21
+ "Interval" => @interval
22
+ }
23
+ hash.merge!(awardable_hash) unless @progress.empty?
24
+ hash.delete("AwardDate") if @award_date.nil?
25
+ hash.delete("Interval") if @interval.nil?
26
+ hash
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,36 @@
1
+ module IActionable
2
+ module Objects
3
+ class IActionableObject
4
+ def initialize(key_values={})
5
+ key_values.each_pair do |key, value|
6
+ instance_variable_set "@#{key.camelize.underscore}".to_sym, value
7
+ end
8
+ end
9
+
10
+ def self.timestamp_regexp
11
+ /\/Date\((\d+)((\-|\+)\d{4})\)\//
12
+ end
13
+
14
+ def self.timestamp_to_seconds(timestamp)
15
+ milliseconds = timestamp[timestamp_regexp, 1]
16
+ tz = timestamp[timestamp_regexp, 2]
17
+ "#{Integer(milliseconds)/1000}#{tz}"
18
+ end
19
+
20
+ private
21
+
22
+ def extract_many_as(key_values, field, klass)
23
+ if key_values.fetch(field, nil).respond_to?(:inject)
24
+ loaded = []
25
+ content = key_values.delete(field)
26
+ content.each do |c|
27
+ loaded << klass.new(c)
28
+ end
29
+ loaded
30
+ else
31
+ []
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module IActionable
2
+ module Objects
3
+ class Identifier < IActionableObject
4
+ attr_accessor :id
5
+ attr_accessor :id_hash
6
+ attr_accessor :id_type
7
+
8
+ def to_hash
9
+ {
10
+ "ID" => @id,
11
+ "IDHash" => @id_hash,
12
+ "IDType" => @id_type
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module IActionable
2
+ module Objects
3
+ class Leaderboard < IActionableObject
4
+ attr_accessor :key
5
+ attr_accessor :name
6
+
7
+ def to_hash
8
+ {
9
+ "Key" => @key,
10
+ "Name" => @name
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ module IActionable
2
+ module Objects
3
+ class LeaderboardReport < IActionableObject
4
+ attr_accessor :page_count
5
+ attr_accessor :page_number
6
+ attr_accessor :total_count
7
+ attr_accessor :leaderboard
8
+ attr_accessor :point_type
9
+ attr_accessor :profiles
10
+
11
+ def initialize(key_values={})
12
+ @leaderboard = IActionable::Objects::PointType.new(key_values.delete("Leaderboard"))
13
+ @point_type = IActionable::Objects::PointType.new(key_values.delete("PointType"))
14
+ @profiles = extract_many_as(key_values, "Profiles", IActionable::Objects::ProfileSummary)
15
+ super(key_values)
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ "PageCount" => @page_count,
21
+ "PageNumber" => @page_number,
22
+ "TotalCount" => @total_count,
23
+ "Leaderboard" => @leaderboard.to_hash,
24
+ "PointType" => @point_type.to_hash,
25
+ "Profiles" => @profiles.map{|profile| profile.to_hash}
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ module IActionable
2
+ module Objects
3
+ class Level < IActionableObject
4
+ attr_accessor :name
5
+ attr_accessor :number
6
+ attr_accessor :required_points
7
+ attr_accessor :level_type
8
+
9
+ def initialize(key_values={})
10
+ @level_type = IActionable::Objects::LevelType.new(key_values.delete("LevelType"))
11
+ super(key_values)
12
+ end
13
+
14
+ def to_hash
15
+ {
16
+ "Name" => @name,
17
+ "Number" => @number,
18
+ "RequiredPoints" => @required_points,
19
+ "LevelType" => @level_type.to_hash
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end