eve 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +174 -0
  3. data/PostInstall.txt +6 -0
  4. data/README.rdoc +126 -0
  5. data/Rakefile +128 -0
  6. data/features/support/env.rb +1 -0
  7. data/lib/eve.rb +31 -0
  8. data/lib/eve/api.rb +247 -0
  9. data/lib/eve/api/connectivity.rb +39 -0
  10. data/lib/eve/api/request.rb +74 -0
  11. data/lib/eve/api/response.rb +100 -0
  12. data/lib/eve/api/response/inspection.rb +62 -0
  13. data/lib/eve/api/response/rowset.rb +56 -0
  14. data/lib/eve/api/response/rowsets.rb +42 -0
  15. data/lib/eve/api/response/wrap_object.rb +15 -0
  16. data/lib/eve/api/services.rb +20 -0
  17. data/lib/eve/api/services/account.rb +12 -0
  18. data/lib/eve/api/services/character.rb +96 -0
  19. data/lib/eve/api/services/corporation.rb +150 -0
  20. data/lib/eve/api/services/eve.rb +76 -0
  21. data/lib/eve/api/services/map.rb +45 -0
  22. data/lib/eve/api/services/misc.rb +24 -0
  23. data/lib/eve/api/services/server.rb +20 -0
  24. data/lib/eve/core_extensions.rb +3 -0
  25. data/lib/eve/core_extensions/hash.rb +51 -0
  26. data/lib/eve/core_extensions/string.rb +11 -0
  27. data/lib/eve/dependencies.rb +18 -0
  28. data/lib/eve/errors.rb +129 -0
  29. data/lib/eve/errors/authentication_errors.rb +33 -0
  30. data/lib/eve/errors/internal_errors.rb +64 -0
  31. data/lib/eve/errors/miscellaneous_errors.rb +19 -0
  32. data/lib/eve/errors/user_input_errors.rb +62 -0
  33. data/lib/eve/helpers.rb +12 -0
  34. data/lib/eve/helpers/javascript_helper.rb +198 -0
  35. data/lib/eve/helpers/view_helper.rb +13 -0
  36. data/lib/eve/trust.rb +88 -0
  37. data/lib/eve/trust/controller_helpers.rb +90 -0
  38. data/lib/eve/trust/igb_interface.rb +88 -0
  39. data/lib/eve/trust/mime_types.rb +4 -0
  40. data/script/console +10 -0
  41. data/script/console.cmd +1 -0
  42. data/script/destroy +14 -0
  43. data/script/destroy.cmd +1 -0
  44. data/script/generate +14 -0
  45. data/script/generate.cmd +1 -0
  46. data/spec/lib/eve/api/calls/account/characters_spec.rb +22 -0
  47. data/spec/lib/eve/api/calls/character/account_balance_spec.rb +21 -0
  48. data/spec/lib/eve/api/calls/character/asset_list_spec.rb +23 -0
  49. data/spec/lib/eve/api/calls/character/character_sheet_spec.rb +51 -0
  50. data/spec/lib/eve/api/calls/character/fac_war_stats_spec.rb +31 -0
  51. data/spec/lib/eve/api/calls/character/industry_jobs_spec.rb +27 -0
  52. data/spec/lib/eve/api/calls/character/kill_log_spec.rb +27 -0
  53. data/spec/lib/eve/api/calls/character/mail_messages_spec.rb +21 -0
  54. data/spec/lib/eve/api/calls/character/mailing_lists_spec.rb +21 -0
  55. data/spec/lib/eve/api/calls/character/market_orders_spec.rb +21 -0
  56. data/spec/lib/eve/api/calls/character/medals_spec.rb +24 -0
  57. data/spec/lib/eve/api/calls/character/research_spec.rb +21 -0
  58. data/spec/lib/eve/api/calls/character/skill_in_training_spec.rb +44 -0
  59. data/spec/lib/eve/api/calls/character/skill_queue_spec.rb +21 -0
  60. data/spec/lib/eve/api/calls/character/standings_spec.rb +26 -0
  61. data/spec/lib/eve/api/calls/character/wallet_journal_spec.rb +21 -0
  62. data/spec/lib/eve/api/calls/character/wallet_transactions_spec.rb +21 -0
  63. data/spec/lib/eve/api/calls/character_portrait_spec.rb +17 -0
  64. data/spec/lib/eve/api/calls/corporation/account_balances_spec.rb +21 -0
  65. data/spec/lib/eve/api/calls/corporation/asset_list_spec.rb +25 -0
  66. data/spec/lib/eve/api/calls/corporation/container_log_spec.rb +23 -0
  67. data/spec/lib/eve/api/calls/corporation/corporation_sheet_spec.rb +36 -0
  68. data/spec/lib/eve/api/calls/corporation/fac_war_stats_spec.rb +23 -0
  69. data/spec/lib/eve/api/calls/corporation/industry_jobs_spec.rb +30 -0
  70. data/spec/lib/eve/api/calls/corporation/kill_log_spec.rb +27 -0
  71. data/spec/lib/eve/api/calls/corporation/market_orders_spec.rb +22 -0
  72. data/spec/lib/eve/api/calls/corporation/medals_spec.rb +21 -0
  73. data/spec/lib/eve/api/calls/corporation/member_medals_spec.rb +21 -0
  74. data/spec/lib/eve/api/calls/corporation/member_security_log_spec.rb +24 -0
  75. data/spec/lib/eve/api/calls/corporation/member_security_spec.rb +25 -0
  76. data/spec/lib/eve/api/calls/corporation/member_tracking_spec.rb +22 -0
  77. data/spec/lib/eve/api/calls/corporation/shareholders_spec.rb +23 -0
  78. data/spec/lib/eve/api/calls/corporation/standings_spec.rb +30 -0
  79. data/spec/lib/eve/api/calls/corporation/starbase_detail_spec.rb +32 -0
  80. data/spec/lib/eve/api/calls/corporation/starbase_list_spec.rb +22 -0
  81. data/spec/lib/eve/api/calls/corporation/titles_spec.rb +26 -0
  82. data/spec/lib/eve/api/calls/corporation/wallet_journal_spec.rb +22 -0
  83. data/spec/lib/eve/api/calls/corporation/wallet_transactions_spec.rb +22 -0
  84. data/spec/lib/eve/api/calls/empty_call_spec.rb +29 -0
  85. data/spec/lib/eve/api/calls/eve/alliance_list_spec.rb +26 -0
  86. data/spec/lib/eve/api/calls/eve/certificate_tree_spec.rb +18 -0
  87. data/spec/lib/eve/api/calls/eve/character_id_spec.rb +27 -0
  88. data/spec/lib/eve/api/calls/eve/conquerable_station_list_spec.rb +11 -0
  89. data/spec/lib/eve/api/calls/eve/error_list_spec.rb +21 -0
  90. data/spec/lib/eve/api/calls/eve/fac_war_stats_spec.rb +25 -0
  91. data/spec/lib/eve/api/calls/eve/fac_war_top_stats_spec.rb +54 -0
  92. data/spec/lib/eve/api/calls/eve/ref_types_spec.rb +11 -0
  93. data/spec/lib/eve/api/calls/eve/skill_tree_spec.rb +17 -0
  94. data/spec/lib/eve/api/calls/map/fac_war_systems_spec.rb +11 -0
  95. data/spec/lib/eve/api/calls/map/jumps_spec.rb +11 -0
  96. data/spec/lib/eve/api/calls/map/kills_spec.rb +15 -0
  97. data/spec/lib/eve/api/calls/map/sovereignty_spec.rb +11 -0
  98. data/spec/lib/eve/api/calls/server_status_spec.rb +24 -0
  99. data/spec/lib/eve/api/request_spec.rb +17 -0
  100. data/spec/lib/eve/api/response/error_spec.rb +13 -0
  101. data/spec/lib/eve/api/response/rowset_spec.rb +28 -0
  102. data/spec/lib/eve/api/response_spec.rb +79 -0
  103. data/spec/lib/eve/api_spec.rb +13 -0
  104. data/spec/lib/eve/core_extensions/hash_spec.rb +23 -0
  105. data/spec/lib/eve/core_extensions/string_spec.rb +8 -0
  106. data/spec/lib/eve/helpers/javascript_helper_spec.rb +80 -0
  107. data/spec/lib/eve/helpers/view_helper_spec.rb +12 -0
  108. data/spec/lib/eve/trust/controller_helpers_spec.rb +70 -0
  109. data/spec/lib/eve/trust/igb_interface_spec.rb +102 -0
  110. data/spec/rcov.opts +2 -0
  111. data/spec/readme_spec.rb +36 -0
  112. data/spec/sample_api_key.yml +20 -0
  113. data/spec/spec.opts +4 -0
  114. data/spec/spec_helper.rb +22 -0
  115. data/spec/support/behaves_like_rowset.rb +50 -0
  116. data/spec/support/controllers/trust_controller.rb +7 -0
  117. data/spec/support/jpg/mock_portrait.jpg +0 -0
  118. data/spec/support/mock_api_helpers.rb +41 -0
  119. data/spec/support/xml/account/characters.xml +15 -0
  120. data/spec/support/xml/character/account_balance.xml +10 -0
  121. data/spec/support/xml/character/asset_list.xml +50 -0
  122. data/spec/support/xml/character/character_sheet.xml +65 -0
  123. data/spec/support/xml/character/fac_war_stats.xml +20 -0
  124. data/spec/support/xml/character/industry_jobs.xml +70 -0
  125. data/spec/support/xml/character/kill_log.xml +51 -0
  126. data/spec/support/xml/character/mail_messages.xml +12 -0
  127. data/spec/support/xml/character/mailing_lists.xml +12 -0
  128. data/spec/support/xml/character/market_orders.xml +11 -0
  129. data/spec/support/xml/character/medals.xml +13 -0
  130. data/spec/support/xml/character/research.xml +13 -0
  131. data/spec/support/xml/character/skill_in_training.xml +14 -0
  132. data/spec/support/xml/character/skill_not_in_training.xml +7 -0
  133. data/spec/support/xml/character/skill_queue.xml +11 -0
  134. data/spec/support/xml/character/standings.xml +32 -0
  135. data/spec/support/xml/character/wallet_journal.xml +39 -0
  136. data/spec/support/xml/character/wallet_transactions.xml +44 -0
  137. data/spec/support/xml/corporation/account_balance.xml +15 -0
  138. data/spec/support/xml/corporation/asset_list.xml +50 -0
  139. data/spec/support/xml/corporation/container_log.xml +32 -0
  140. data/spec/support/xml/corporation/fac_war_stats.xml +19 -0
  141. data/spec/support/xml/corporation/industry_jobs.xml +70 -0
  142. data/spec/support/xml/corporation/kill_log.xml +51 -0
  143. data/spec/support/xml/corporation/market_orders.xml +37 -0
  144. data/spec/support/xml/corporation/medals.xml +8 -0
  145. data/spec/support/xml/corporation/member_corporation_sheet.xml +51 -0
  146. data/spec/support/xml/corporation/member_medals.xml +10 -0
  147. data/spec/support/xml/corporation/member_security.xml +21 -0
  148. data/spec/support/xml/corporation/member_security_log.xml +55 -0
  149. data/spec/support/xml/corporation/member_tracking.xml +18 -0
  150. data/spec/support/xml/corporation/non_member_corporation_sheet.xml +30 -0
  151. data/spec/support/xml/corporation/shareholders.xml +11 -0
  152. data/spec/support/xml/corporation/standings.xml +33 -0
  153. data/spec/support/xml/corporation/starbase_detail.xml +33 -0
  154. data/spec/support/xml/corporation/starbase_list.xml +17 -0
  155. data/spec/support/xml/corporation/titles.xml +34 -0
  156. data/spec/support/xml/corporation/wallet_journal.xml +40 -0
  157. data/spec/support/xml/corporation/wallet_transactions.xml +12 -0
  158. data/spec/support/xml/errors/106.xml +5 -0
  159. data/spec/support/xml/errors/516.xml +5 -0
  160. data/spec/support/xml/eve/alliance_list.xml +22 -0
  161. data/spec/support/xml/eve/certificate_tree.xml +49 -0
  162. data/spec/support/xml/eve/character_id.xml +15 -0
  163. data/spec/support/xml/eve/conquerable_station_list.xml +24 -0
  164. data/spec/support/xml/eve/error_list.xml +78 -0
  165. data/spec/support/xml/eve/fac_war_stats.xml +31 -0
  166. data/spec/support/xml/eve/fac_war_top_stats.xml +238 -0
  167. data/spec/support/xml/eve/ref_types.xml +105 -0
  168. data/spec/support/xml/eve/skill_tree.xml +52 -0
  169. data/spec/support/xml/map/fac_war_systems.xml +180 -0
  170. data/spec/support/xml/map/jumps.xml +166 -0
  171. data/spec/support/xml/map/kills.xml +191 -0
  172. data/spec/support/xml/map/sovereignty.xml +20 -0
  173. data/spec/support/xml/rowset_with_mismatched_attributes.xml +6 -0
  174. data/spec/support/xml/server/server_status.xml +9 -0
  175. metadata +364 -0
@@ -0,0 +1,247 @@
1
+ require 'eve/api/request'
2
+ require 'eve/api/response'
3
+ require 'eve/api/services'
4
+ require 'eve/api/connectivity'
5
+
6
+ module Eve
7
+ # = Eve API Libraries
8
+ #
9
+ # EVE Online has made available various APIs which allow for querying the server for information about the server's
10
+ # current status, general game information such as skill and certificate trees, top player rankings, and the players
11
+ # and characters themselves. This library interfaces with that API to provide an intuitive way of retrieving this
12
+ # data.
13
+ #
14
+ # == The Basics
15
+ #
16
+ # There are two forms of authentication that the API uses: a limited API key and a full API key. For some information,
17
+ # such as the server's current status, no API key at all is required; for other information, such as which characters
18
+ # are owned by a particular user account, a limited API key will suffice. For more personal information, such as
19
+ # a character's transaction history, a full API key is required. Using an inappropriate or missing API key will result
20
+ # in an error being raised.
21
+ #
22
+ # === Instantiation & [Re]Configuration
23
+ # To interface with the Eve API, you need to instantiate the API object. This is simple:
24
+ # api = Eve::API.new
25
+ #
26
+ # If you plan to make use of information requiring an API key, you'll need to pass in those options:
27
+ # api = Eve::API.new(:user_id => 'a_user_id', :api_key => 'an_api_key')
28
+ #
29
+ # If you need to make use of Character-specific API calls, then you should also pass a +:character_id+ key. Same goes
30
+ # for Corporation-specific API calls: pass a +corporation_id+ key. If you don't know those yet (for instance, because
31
+ # you need the user to make a selection), then don't fret. You can always instantiate a new API object, or simply
32
+ # set the option directly on the API object you've already got:
33
+ # api.set(:character_id => 'a_character_id')
34
+ # # -or-
35
+ # api[:character_id] = 'a_character_id'
36
+ #
37
+ # === Making API Calls
38
+ # Actually retrieving information is just as straightforward as instantiation of the API object was, though the syntax
39
+ # does sometimes vary from one call to the next. Here's how to get the current server status:
40
+ # status = api.server_status
41
+ #
42
+ # And retrieving the list of characters belonging to :user_id is done like so:
43
+ # charlist = api.account.characters
44
+ #
45
+ # === List of API Calls
46
+ # This section is split into 3 subsections, one for each level of API key required for the call in question. This
47
+ # table assumes the presence of an "api" object, which is an instantiation of the API object as shown above. For
48
+ # more information on a particular subset of calls, including the exact return values, click on the corresponding
49
+ # class name to the left.
50
+ #
51
+ # ==== No API Key
52
+ # Eve::API::Services::Corporation:: api.corporation.corporation_sheet
53
+ # Eve::API::Services::Eve:: api.eve.alliance_list
54
+ # Eve::API::Services::Eve:: api.eve.certificate_tree
55
+ # Eve::API::Services::Eve:: api.eve.conquerable_station_list
56
+ # Eve::API::Services::Eve:: api.eve.error_list
57
+ # Eve::API::Services::Eve:: api.eve.fac_war_stats / api.eve.factional_warfare_stats
58
+ # Eve::API::Services::Eve:: api.eve.fac_war_top_stats / api.eve.factional_warfare_top100
59
+ # Eve::API::Services::Eve:: api.eve.character_name(*ids)
60
+ # Eve::API::Services::Eve:: api.eve.character_id(*names)
61
+ # Eve::API::Services::Eve:: api.eve.corporation_name(*ids)
62
+ # Eve::API::Services::Eve:: api.eve.corporation_id(*names)
63
+ # Eve::API::Services::Eve:: api.eve.alliance_name(*ids)
64
+ # Eve::API::Services::Eve:: api.eve.alliance_id(*names)
65
+ # Eve::API::Services::Eve:: api.eve.ref_types
66
+ # Eve::API::Services::Eve:: api.eve.skill_tree
67
+ # Eve::API::Services::Map:: api.map.fac_war_systems / api.map.contested_systems
68
+ # Eve::API::Services::Map:: api.map.sovereignty
69
+ # Eve::API::Services::Map:: api.map.kills
70
+ # Eve::API::Services::Map:: api.map.jumps
71
+ # Eve::API::Services::Misc:: api.misc.character_portrait
72
+ # Eve::API::Services::Server:: api.server.server_status
73
+ #
74
+ # ==== Limited API Key
75
+ # Eve::API::Services::Account:: api.account.characters
76
+ # Eve::API::Services::Character:: api.character.character_sheet
77
+ # Eve::API::Services::Character:: api.character.fac_war_stats
78
+ # Eve::API::Services::Character:: api.character.medals
79
+ # Eve::API::Services::Character:: api.character.skill_in_training
80
+ # Eve::API::Services::Character:: api.character.skill_queue
81
+ # Eve::API::Services::Character:: api.character.standings
82
+ # Eve::API::Services::Corporation:: api.corporation.corporation_sheet
83
+ # Eve::API::Services::Corporation:: api.corporation.fac_war_stats
84
+ # Eve::API::Services::Corporation:: api.corporation.medals
85
+ # Eve::API::Services::Corporation:: api.corporation.member_medals
86
+ #
87
+ # ==== Full API Key
88
+ # Eve::API::Services::Character:: api.character.account_balance
89
+ # Eve::API::Services::Character:: api.character.asset_list(version = nil)
90
+ # Eve::API::Services::Character:: api.character.industry_jobs
91
+ # Eve::API::Services::Character:: api.character.kill_log(options = {})
92
+ # Eve::API::Services::Character:: api.character.mailing_lists
93
+ # Eve::API::Services::Character:: api.character.mail_messages
94
+ # Eve::API::Services::Character:: api.character.market_orders
95
+ # Eve::API::Services::Character:: api.character.notifications
96
+ # Eve::API::Services::Character:: api.character.research
97
+ # Eve::API::Services::Character:: api.character.wallet_journal(account_key = 1000, options = {})
98
+ # Eve::API::Services::Character:: api.character.journal_entries(account_key = 1000, options = {})
99
+ # Eve::API::Services::Character:: api.character.wallet_transactions(options = {})
100
+ # Eve::API::Services::Corporation:: api.corporation.account_balance
101
+ # Eve::API::Services::Corporation:: api.corporation.asset_list
102
+ # Eve::API::Services::Corporation:: api.corporation.container_log
103
+ # Eve::API::Services::Corporation:: api.corporation.corporation_sheet(corporation_id = nil)
104
+ # Eve::API::Services::Corporation:: api.corporation.fac_war_stats
105
+ # Eve::API::Services::Corporation:: api.corporation.industry_jobs
106
+ # Eve::API::Services::Corporation:: api.corporation.kill_log(options = {})
107
+ # Eve::API::Services::Corporation:: api.corporation.market_orders
108
+ # Eve::API::Services::Corporation:: api.corporation.member_security
109
+ # Eve::API::Services::Corporation:: api.corporation.member_security_log
110
+ # Eve::API::Services::Corporation:: api.corporation.member_tracking
111
+ # Eve::API::Services::Corporation:: api.corporation.starbase_detail(item_id, version = 2)
112
+ # Eve::API::Services::Corporation:: api.corporation.starbase_list
113
+ # Eve::API::Services::Corporation:: api.corporation.shareholders
114
+ # Eve::API::Services::Corporation:: api.corporation.standings
115
+ # Eve::API::Services::Corporation:: api.corporation.titles
116
+ # Eve::API::Services::Corporation:: api.corporation.wallet_journal(account_key = 1000, options = {})
117
+ # Eve::API::Services::Corporation:: api.corporation.wallet_transactions(account_key = 1000, options = {})
118
+ #
119
+ # === Interpreting Responses
120
+ # Response objects are generated automatically, and should be able to accommodate any changes in the API reasonably
121
+ # well.
122
+ #
123
+ # The classes listed above attempt to document the API calls. However, if you are unsure of
124
+ # how to process the return value of a particular API call, don't be afraid to check it out directly:
125
+ # irb(main):004:0> puts api.server_status.to_yaml
126
+ # ---
127
+ # current_time: 2010-03-14T04:41:51+00:00
128
+ # cached_until: 2010-03-14T04:44:51+00:00
129
+ # online_players: 30694
130
+ # server_open: true
131
+ # api_version: "2"
132
+ #
133
+ # In this example, #server_status provides 5 fields: #api_version, #cached_until, #current_time, #online_players,
134
+ # and #server_open.
135
+ #
136
+ # Some fields in a given response are essentially arrays with some additional fields. These are called Rowsets. For
137
+ # instance, the call to +api.account.characters+, above, returned a response with a #characters method, which
138
+ # contained up to 3 characters. Each element, or Row, in a Rowset has in turn its own fields and/or Rowsets. Each
139
+ # character in this example includes a #character_id, #corporation_id, and #corporation_name.
140
+ #
141
+ # Additionally, all responses always have a #name field. For basic responses, the #name is "(Response)", and
142
+ # probably doesn't mean much to you. For Rowsets, the #name is the name of the Rowset (for example, "characters").
143
+ # For individual Rows, the #name might mean something more useful -- the name of a character, for instance.
144
+ #
145
+ class API
146
+ include Eve::API::Connectivity
147
+ include Eve::API::Services
148
+ attr_reader :options
149
+ attr_reader :map
150
+
151
+ def initialize(options = {})
152
+ @options = default_options.merge(options)
153
+ send_includes
154
+ instantiate_submodules
155
+ end
156
+
157
+ def set(key, value = nil)
158
+ raise "Key can't be nil" unless key
159
+ if key.kind_of?(Hash)
160
+ key.each { |k, v| set(k, v) }
161
+ else
162
+ if value then @options[key] = value
163
+ else @options.delete key
164
+ end
165
+ [@options[:submodules]].flatten.each do |sub|
166
+ self.send(sub).set(key, value) if sub
167
+ end
168
+ end
169
+ end
170
+
171
+ def [](key); @options[key]; end
172
+ def []=(key, value); set(key, value); end
173
+
174
+ private
175
+ class << self
176
+ def validate_credentials(key_type, *args)
177
+ case key_type
178
+ when :limited, :full
179
+ args.flatten!
180
+ options = args.extract_options!
181
+ method_names = options.delete(:for)
182
+ raise ArgumentError, "Unexpected options: #{options.keys.inspect}" unless options.empty?
183
+
184
+ method_names.each do |method_name|
185
+ define_method "#{method_name}_with_credential_validation" do |*a|
186
+ validate_credentials(key_type, *args)
187
+ send("#{method_name}_without_credential_validation", *a)
188
+ end
189
+ alias_method_chain method_name, :credential_validation
190
+ end
191
+
192
+ else raise ArgumentError, "Expected :limited or :full credential type"
193
+ end
194
+ end
195
+ end
196
+
197
+ def validate_credentials(type, *additional_requirements)
198
+ raise ArgumentError, "user_id is required" unless options[:user_id]
199
+ raise ArgumentError, "api_key is required" unless options[:api_key]
200
+ additional_requirements.each do |r|
201
+ raise ArgumentError, "#{r} is required" unless options[r]
202
+ end
203
+
204
+ case type
205
+ when :limited, :full # currently no difference. Wish we could validate on this.
206
+ else raise ArgumentError, "Expected :limited or :full credential type"
207
+ end
208
+ end
209
+
210
+ def validate_options(options, *keys)
211
+ options.keys.each do |key|
212
+ raise ArgumentError, "Options should only include #{keys.inspect}" unless keys.include?(key)
213
+ end
214
+ end
215
+
216
+ def send_includes
217
+ [@options[:includes]].flatten.each do |mod|
218
+ next unless mod
219
+ mod = mod.to_s unless mod.kind_of?(String)
220
+ eigenclass.send(:include, "::Eve::API::Services::#{mod.camelize}".constantize)
221
+ end
222
+ end
223
+
224
+ def instantiate_submodules
225
+ [@options[:submodules]].flatten.each do |mod|
226
+ next unless mod
227
+ instance_variable_set("@#{mod}", ::Eve::API.new(options.merge(:includes => mod, :submodules => nil)))
228
+ eigenclass.send(:attr_reader, mod)
229
+ end
230
+ end
231
+
232
+ def eigenclass
233
+ class << self; self; end
234
+ end
235
+
236
+ def default_options
237
+ {
238
+ :submodules => [:map, :eve, :account, :character, :corporation],
239
+ :cache => true
240
+ }
241
+ end
242
+
243
+ def cache_namespace
244
+ self.class.name.underscore
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,39 @@
1
+ module Eve
2
+ class API
3
+ module Connectivity
4
+ MAX_JOURNAL_ENTRIES = 1000
5
+
6
+ def walk(walk_id, walk_association, options = {}, &block)
7
+ raise ArgumentError, "Requires :walk_id" if walk_id.blank?
8
+ raise ArgumentError, "Requires :walk_association" if walk_association.blank?
9
+ options[walk_id] ||= 0
10
+ return_value = yield options
11
+ array = return_value.send(walk_association)
12
+ if array.size >= MAX_JOURNAL_ENTRIES
13
+ begin
14
+ min_id = nil
15
+ primary_key = array.primary_key
16
+ array.each { |txn| min_id = txn.send(primary_key) if min_id.nil? || min_id > txn.send(primary_key) }
17
+ array.concat walk(walk_id, options.merge(walk_id => min_id), &block).send(walk_association)
18
+ rescue Eve::Errors::UserInputErrors::InvalidBeforeTransID, Eve::Errors::UserInputErrors::InvalidBeforeRefID,
19
+ Eve::Errors::UserInputErrors::InvalidBeforeKillID
20
+ # walking is internal, so we should catch the error internally too.
21
+ end
22
+ end
23
+ return_value
24
+ end
25
+
26
+ def request(namespace, service_name, options = {})
27
+ walk_id = options.delete(:walk_id) # we don't want these being sent to the server; it messes with the cache.
28
+ walk_association = options.delete(:walk_association)
29
+ if options.delete(:walk)
30
+ walk(walk_id.to_s, walk_association, options) do |walk_options|
31
+ Eve::API::Request.new(namespace, service_name, self.options.merge(walk_options)).dispatch
32
+ end
33
+ else
34
+ Eve::API::Request.new(namespace, service_name, self.options.merge(options)).dispatch
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,74 @@
1
+ module Eve
2
+ class API
3
+ class Request
4
+ extend ActiveSupport::Memoizable
5
+ attr_reader :response, :uri, :options, :namespace, :service
6
+
7
+ def initialize(namespace, service, options = {})
8
+ options.reverse_merge! default_options
9
+ namespace = namespace.to_s if namespace.is_a?(Symbol)
10
+ service = service.to_s if service.is_a?(Symbol)
11
+
12
+ unless [:xml,:string].include? options[:response_type]
13
+ raise ArgumentError, "Expected :response_type to be :xml or :string"
14
+ end
15
+
16
+ @options = options.dup
17
+ @service = options[:camelize] ? service.camelize : service
18
+ @namespace = namespace
19
+ @response_type = options[:response_type]
20
+
21
+ @uri = File.join(@options.delete(:base_uri), @namespace, "#{@service}.#{options[:extension]}")
22
+ end
23
+
24
+ def dispatch
25
+ r = (cached_response || cache_response(Net::HTTP.post_form(URI.parse(uri), post_options).body))
26
+ if r.respond_to?(:error) && r.error
27
+ Eve::Errors.raise(:code => r.error.code, :message => r.error)
28
+ end
29
+ r
30
+ end
31
+
32
+ def cached_response
33
+ if xml = (options[:cache] ? Eve.cache.read(cache_key) : nil)
34
+ potential_response = response_for(xml)
35
+ if !potential_response.respond_to?(:cached_until) || potential_response.cached_until >= Time.now
36
+ return potential_response
37
+ end
38
+ end
39
+ nil
40
+ end
41
+
42
+ def response_for(body)
43
+ @response_type == :xml ? Eve::API::Response.new(body, options) : body
44
+ end
45
+
46
+ def cache_response(xml)
47
+ Eve.cache.write(cache_key, xml) if options[:cache]
48
+ response_for xml
49
+ end
50
+
51
+ def cache_key
52
+ ActiveSupport::Cache.expand_cache_key(post_options, @uri)
53
+ end
54
+
55
+ memoize :cache_key
56
+
57
+ private
58
+ def post_options
59
+ options.without(default_options.keys).camelize_keys
60
+ end
61
+
62
+ def default_options
63
+ {
64
+ :base_uri => "http://api.eve-online.com",
65
+ :extension => "xml.aspx",
66
+ :camelize => true,
67
+ :response_type => :xml,
68
+ :column_mapping => nil,
69
+ :cache => true
70
+ }
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,100 @@
1
+ require 'eve/api/response/inspection'
2
+ require 'eve/api/response/wrap_object'
3
+ require 'eve/api/response/rowsets'
4
+ require 'eve/api/response/rowset'
5
+
6
+ module Eve
7
+ class API
8
+ class Response
9
+ include Eve::API::Response::WrapObject
10
+ include Eve::API::Response::Rowsets
11
+ include Eve::API::Response::Inspection
12
+ attr_reader :api_version, :content
13
+
14
+ def initialize(xml, options = {})
15
+ @options = options
16
+ xml = Hpricot::XML(xml).root if xml.kind_of?(String)
17
+ @xml = xml
18
+ #@attributes = {}
19
+
20
+ parse_xml unless options[:process_xml] == false
21
+ end
22
+
23
+ def to_hash
24
+ hash = {}
25
+ (instance_variables - protected_instance_variables + (@name.blank? ? [] : ["@name"])).each do |ivar|
26
+ value = instance_variable_get(ivar)
27
+ value = case value
28
+ when Rowset then value.to_a
29
+ when Response then value.to_hash
30
+ else value
31
+ end
32
+ hash[ivar[1..-1]] = value
33
+ end
34
+ hash
35
+ end
36
+
37
+ def to_yaml(*args)
38
+ to_hash.to_yaml(*args)
39
+ end
40
+
41
+ def [](key)
42
+ key = key.to_s if !key.kind_of?(String)
43
+ key = key.underscore
44
+ instance_variable_get("@#{key}") ||
45
+ raise(ArgumentError, "No attribute called '#{key}' seems to exist in #{self.inspect}")
46
+ end
47
+
48
+ protected
49
+ def parse_xml(node = @xml)
50
+ case node
51
+ when Hpricot::Elem
52
+ parse_elem(node)
53
+ end
54
+ end
55
+
56
+ def check_for_datetime(value)
57
+ if value =~ /\A[0-9]{4}\-[0-9]{2}\-[0-9]{2} [0-9]{2}\:[0-9]{2}\:[0-9]{2}\z/
58
+ DateTime.parse(value)
59
+ else
60
+ value
61
+ end
62
+ end
63
+
64
+ def wrap_method_around_node(node = @xml)
65
+ # TODO: refactor me.
66
+ if !node.children || !node.children.select { |c| c.is_a?(Hpricot::Elem) }.empty?
67
+ @content = node.inner_text.strip if !node.children
68
+ value = Eve::API::Response.new(node, @options.merge(:process_xml => false))
69
+ value.send(:copy_attributes, node.attributes.to_hash.keys, node)
70
+ value.parse_children
71
+ else
72
+ value = value_for(node.inner_text)
73
+ value = check_for_datetime(value)
74
+ # now define any attributes as methods on the resultant object
75
+ node_attributes = node.attributes.to_hash
76
+ copy_attributes(node_attributes.keys, node, value)
77
+ end
78
+
79
+ wrap_object(node.name, value)
80
+ end
81
+
82
+ def parse_elem(node = @xml)
83
+ case node.name
84
+ when 'eveapi' then
85
+ @api_version = node['version']
86
+ parse_children(node)
87
+ when 'result' then
88
+ parse_children(node)
89
+ when 'rowset' then
90
+ add_rowset Rowset.new(node, @options)
91
+ else wrap_method_around_node(node)
92
+ end
93
+ end
94
+
95
+ def parse_children(node = @xml)
96
+ node.children.each { |child| parse_xml(child) } if node.children
97
+ end
98
+ end
99
+ end
100
+ end