Skip to content
Browse files

rest of app

  • Loading branch information...
1 parent 2b6d794 commit 58bd1ad64b8c3c961d2cc8f8685ab60dbb6fe925 lisa committed Aug 28, 2008
Showing with 5,438 additions and 0 deletions.
  1. +155 −0 ChangeLog
  2. +22 −0 LICENSE
  3. +54 −0 Rakefile
  4. +1 −0 init.rb
  5. +897 −0 lib/reve.rb
  6. +1,055 −0 lib/reve/classes.rb
  7. +343 −0 lib/reve/exceptions.rb
  8. +108 −0 lib/reve/extensions.rb
  9. +1 −0 reve.rb
  10. +63 −0 test/test_extensions.rb
  11. +1,040 −0 test/test_reve.rb
  12. +171 −0 test/xml/alliances.xml
  13. +32 −0 test/xml/assets.xml
  14. +6 −0 test/xml/badxml.xml
  15. +18 −0 test/xml/char_facwarstats.xml
  16. +37 −0 test/xml/character_sheet.xml
  17. +11 −0 test/xml/characterid.xml
  18. +11 −0 test/xml/charactername.xml
  19. +13 −0 test/xml/characters.xml
  20. +11 −0 test/xml/conqurable_stations.xml
  21. +17 −0 test/xml/corp_facwarstats.xml
  22. +16 −0 test/xml/corporate_assets_list.xml
  23. +10 −0 test/xml/corporate_market_orders.xml
  24. +16 −0 test/xml/corporate_wallet_balance.xml
  25. +11 −0 test/xml/corporate_wallet_journal.xml
  26. +10 −0 test/xml/corporate_wallet_transactions.xml
  27. +52 −0 test/xml/corporation_sheet.xml
  28. +70 −0 test/xml/errors.xml
  29. +5 −0 test/xml/errors/error_100.xml
  30. +5 −0 test/xml/errors/error_101.xml
  31. +5 −0 test/xml/errors/error_102.xml
  32. +5 −0 test/xml/errors/error_103.xml
  33. +5 −0 test/xml/errors/error_104.xml
  34. +5 −0 test/xml/errors/error_105.xml
  35. +5 −0 test/xml/errors/error_106.xml
  36. +5 −0 test/xml/errors/error_107.xml
  37. +5 −0 test/xml/errors/error_108.xml
  38. +5 −0 test/xml/errors/error_109.xml
  39. +5 −0 test/xml/errors/error_110.xml
  40. +5 −0 test/xml/errors/error_111.xml
  41. +5 −0 test/xml/errors/error_112.xml
  42. +5 −0 test/xml/errors/error_113.xml
  43. +5 −0 test/xml/errors/error_114.xml
  44. +5 −0 test/xml/errors/error_115.xml
  45. +5 −0 test/xml/errors/error_116.xml
  46. +5 −0 test/xml/errors/error_117.xml
  47. +5 −0 test/xml/errors/error_118.xml
  48. +5 −0 test/xml/errors/error_119.xml
  49. +5 −0 test/xml/errors/error_120.xml
  50. +5 −0 test/xml/errors/error_121.xml
  51. +5 −0 test/xml/errors/error_122.xml
  52. +5 −0 test/xml/errors/error_123.xml
  53. +5 −0 test/xml/errors/error_124.xml
  54. +5 −0 test/xml/errors/error_125.xml
  55. +5 −0 test/xml/errors/error_200.xml
  56. +5 −0 test/xml/errors/error_201.xml
  57. +5 −0 test/xml/errors/error_202.xml
  58. +5 −0 test/xml/errors/error_203.xml
  59. +5 −0 test/xml/errors/error_204.xml
  60. +5 −0 test/xml/errors/error_205.xml
  61. +5 −0 test/xml/errors/error_206.xml
  62. +5 −0 test/xml/errors/error_207.xml
  63. +5 −0 test/xml/errors/error_208.xml
  64. +5 −0 test/xml/errors/error_209.xml
  65. +5 −0 test/xml/errors/error_210.xml
  66. +5 −0 test/xml/errors/error_211.xml
  67. +5 −0 test/xml/errors/error_212.xml
  68. +5 −0 test/xml/errors/error_213.xml
  69. +5 −0 test/xml/errors/error_214.xml
  70. +5 −0 test/xml/errors/error_500.xml
  71. +5 −0 test/xml/errors/error_501.xml
  72. +5 −0 test/xml/errors/error_502.xml
  73. +5 −0 test/xml/errors/error_503.xml
  74. +5 −0 test/xml/errors/error_504.xml
  75. +5 −0 test/xml/errors/error_505.xml
  76. +5 −0 test/xml/errors/error_506.xml
  77. +5 −0 test/xml/errors/error_507.xml
  78. +5 −0 test/xml/errors/error_508.xml
  79. +5 −0 test/xml/errors/error_509.xml
  80. +5 −0 test/xml/errors/error_510.xml
  81. +5 −0 test/xml/errors/error_511.xml
  82. +5 −0 test/xml/errors/error_512.xml
  83. +5 −0 test/xml/errors/error_513.xml
  84. +5 −0 test/xml/errors/error_514.xml
  85. +5 −0 test/xml/errors/error_515.xml
  86. +5 −0 test/xml/errors/error_516.xml
  87. +5 −0 test/xml/errors/error_517.xml
  88. +5 −0 test/xml/errors/error_518.xml
  89. +5 −0 test/xml/errors/error_519.xml
  90. +5 −0 test/xml/errors/error_520.xml
  91. +5 −0 test/xml/errors/error_521.xml
  92. +5 −0 test/xml/errors/error_522.xml
  93. +5 −0 test/xml/errors/error_523.xml
  94. +5 −0 test/xml/errors/error_524.xml
  95. +5 −0 test/xml/errors/error_900.xml
  96. +5 −0 test/xml/errors/error_901.xml
  97. +5 −0 test/xml/errors/error_902.xml
  98. +5 −0 test/xml/errors/error_903.xml
  99. +5 −0 test/xml/errors/error_999.xml
  100. +35 −0 test/xml/eve_facwarstats.xml
  101. +178 −0 test/xml/eve_facwartopstats.xml
  102. +11 −0 test/xml/industryjobs.xml
  103. +167 −0 test/xml/kills.xml
  104. +13 −0 test/xml/map_facwarsystems.xml
  105. +15 −0 test/xml/mapjumps.xml
  106. +16 −0 test/xml/mapkills.xml
  107. +79 −0 test/xml/market_transactions.xml
  108. +43 −0 test/xml/marketorders.xml
  109. +22 −0 test/xml/member_tracking.xml
  110. +30 −0 test/xml/nonmember_corpsheet.xml
  111. +14 −0 test/xml/reftypes.xml
  112. +15 −0 test/xml/skill_in_training-amarr-titan.xml
  113. +7 −0 test/xml/skill_in_training-none.xml
  114. +41 −0 test/xml/skilltree.xml
  115. +29 −0 test/xml/sovereignty.xml
  116. +23 −0 test/xml/starbase_fuel.xml
  117. +12 −0 test/xml/starbases.xml
  118. +17 −0 test/xml/wallet_balance.xml
  119. +48 −0 test/xml/wallet_journal.xml
  120. +17 −0 tester.rb
View
155 ChangeLog
@@ -0,0 +1,155 @@
+Revision 61: 2008-01-13
+ Please see http://revetrac.crudvision.com/log/trunk?action=stop_on_copy&rev=61&stop_rev=40&mode=stop_on_copy&verbose=on
+ for ChangeLog
+
+Revision 41: 2007-12-19
+ Add support for the nesting of Corporation under Alliance in
+ Reve::API#alliances
+ Added missing tests
+
+Revisions 31-37: December 2007
+ Add support for version 2 API stuff.
+
+Revision 30: 2007-11-15
+ Added initial support for the API version 2 CorporationSheet method.
+
+Revision 29: 2007-09-19
+ Removed rolldocs.rake and just put the documentation building into the
+ Rakefile. To build docs just use `rake doc`.
+ Added some rescue statements the internal Reve::API#check_exception to try
+ and handle problems when some things aren't found in the XML document.
+
+Revision 28: 2007-09-09
+ Fixed typos that made the library, uh, not work.
+
+Revision 27: 2007-09-08 21:29:07 +0100 (Sat, 08 Sep 2007)
+ Added preliminary support for the ConqurableStation API, see
+ Reve::Clases::ConqurableStation class.
+ Migrated subversion to a traditional trunk directory for my sanity. Expect
+ future releases to also be in the tags directory.
+
+Revision 21: 2007-08-28 02:45 (Tue, 28 Augu 2007)
+ Changed all methods to require a Hash of parameters. Please refer to the
+ documentation <http://docs.crudvision.com/reve/> for new method signatures,
+ especially Reve::API main documentation.
+ Add a protected method 'compute_hash' which every other public method calls,
+ using this new Hash parameter system, to construct a hash to represent the
+ call uniquely. The result of this method should be suitable to store in a
+ database so it can be used in conjunction with the cached_until variable.
+ This hash is computed after each call and is available through the
+ last_hash instance variable (like cached_until)
+ Updated the test suite for these changes
+
+Revision 20: 2007-08-22 23:36:00 +0100 (Wed, 22 Aug 2007)
+ Added this ChangeLog
+
+Revision 19: 2007-08-22 23:33:57 +0100 (Wed, 22 Aug 2007)
+ docs in svn removed. Roll docs with rake -f rolldocs.rake doc
+
+Revision 18: 2007-08-21 09:19:16 +0100 (Tue, 21 Aug 2007)
+ Add Reve::API.cached_until. Users of Reve PLEASE obey this setting! It will
+ be set (overwritten) after each call and should be copied somewhere before
+ another call is made.
+ Change tester.rb to print the cached_until response for each test call.
+ Change Reve::API#postfields to take a hash of post fields and change each
+ Reve::API method accordingly.
+
+Revision 17: 2007-08-16 23:07:00 +0100 (Thu, 16 Aug 2007)
+ RDoc update
+
+Revision 16: 2007-08-16 23:04:56 +0100 (Thu, 16 Aug 2007)
+ Add preliminary support for Reve::API#starbases and Reve::API#starbase_fuel
+ Modify Reve::API#postfields to allow for item_id for Reve::API#starbase_fuel
+ Add Reve::Classes::Starbase and Reve::Classes::StarbaseFuel
+ Add new exceptions: Reve::Exceptions::VersionMismatchException,
+ Reve::Exceptions::InvalidItemIDProvided,
+ Reve::Exceptions::MustBeDirectorOrCEO,
+ Reve::Exceptions::StarbaseDetailFetchFailure,
+ Reve::Exceptions::EveDatabaseConnectionFailure
+
+Revision 15: 2007-08-16 21:23:08 +0100 (Thu, 16 Aug 2007)
+ Add Reve::Exceptions::VersionEscalationException
+
+Revision 14: 2007-08-15 21:58:20 +0100 (Wed, 15 Aug 2007)
+ Fix badxml xml file to actually break it
+ Fix class attributes in Reve::API (wallet transactions) to point to the right
+ place
+ Add a warning to Reve::Exceptions#raise_it for
+ Reve::Exceptions::SecurityLevelNotHighEnough to warn the user that maybe
+ they don't have the full API key
+
+Revision 13: 2007-08-14 22:36:50 +0100 (Tue, 14 Aug 2007)
+ Global attempts to fix when to_time can be nil
+ Add a check in Reve::Classes::WalletTransaction#new to check for the presence
+ of character_id in the return data before trying to use it
+
+Revision 12: 2007-08-14 21:10:26 +0100 (Tue, 14 Aug 2007)
+ Add a test for malformed XML input
+ Subclass Reve::Classes::WalletTransaction for Personal and Corporate
+ wallet transactions ('transactionFor' in the XML) as per
+ http://myeve.eve-online.com/ingameboard.asp?a=topic&threadID=575626&page=1#1
+ Removed characterID and characterName attributes frm WalletTransaction as
+ per the above link
+
+Revision 11: 2007-08-10 22:13:46 +0100 (Fri, 10 Aug 2007)
+ Add alliances test xml for test suite
+
+Revision 10: 2007-08-10 22:12:59 +0100 (Fri, 10 Aug 2007)
+ Add a test suite
+ Add Reve::Exceptions::WebsiteOffline
+ Reve::Classes::WalletBalance.account_key now works
+ Reve::Classes::CharacterSheet.skill_in_training is boolean (and now works)
+ Reve::Classes::SkillTree.description now works
+
+
+Revision 9: 2007-08-07 07:22:42 +0100 (Tue, 07 Aug 2007)
+ Add Reve::Exceptions::EveDatabaseOffline for when the Eve DB is offline
+
+Revision 8: 2007-08-01 22:30:57 +0100 (Wed, 01 Aug 2007)
+ First tarball release
+ Remove Curl dependency in favour of Ruby's built-in Net::HTTP
+ Change Reve::API#postfields and Reve::API#process_query for Curl removal
+ RDoc has inline source with line numbers
+ Document existance of Reve::Classes::PrimaryAttribute,
+ Reve::Classes::SecondaryAttribute, Reve::Classes::WillpowerEnhancer,
+ Reve::Classes::IntelligenceEnhancer, Reve::Classes::MemoryEnhancer,
+ Reve::Classes::PerceptionEnhancer, Reve::Classes::CharismaEnhancer
+ Add Reve::Exceptions::ReveNetworkStatusException for when the network times
+ out.
+
+Revision 7: 2007-08-01 19:28:52 +0100 (Wed, 01 Aug 2007)
+ Finish the Reve::API#character_sheet method
+ Add Reve::Classes::AttributeEnhancer (and IntelligenceEnhancer,
+ MemoryEnhancer, PerceptionEnhancer, CharismaEnhancer and WillpowerEnhancer
+ subclasses, for implants)
+ Add enhancers (Array) attribute to Reve::Classes::CharacterSheet
+ Add Reve::Extensions::String#to_i in an attempt to make an integer from a
+ String when possible. See the docs for the method for details.
+ Update RDoc
+
+Revision 6: 2007-08-01 08:04:33 +0100 (Wed, 01 Aug 2007)
+ Remove some pretty print debug info.
+
+Revision 5: 2007-07-29 23:08:45 +0100 (Sun, 29 Jul 2007)
+ Change Reve::Classes::Sovereignty to use nil (not 0) for alliance_id and
+ faction_id where applicable.
+
+Revision 4: 2007-07-26 20:07:30 +0100 (Thu, 26 Jul 2007)
+ Add Copyright notice
+ More documentation with brief sample usage in the Reve::API class
+ Change Reve::Extensions::String#to_date to use :utc instead of :local for
+ conversions
+
+Revision 3: 2007-07-22 15:18:06 +0100 (Sun, 22 Jul 2007)
+ Add better 'require reve' support ($:.unshift fun)
+ Add Documentation (RDoc)
+
+Revision 2:2007-07-22 10:06:11 +0100 (Sun, 22 Jul 2007)
+ Add sample "tester.rb"
+ Add Reve::Classes::RequiredAttribute and Primary/Secondary subclass
+ for skill_tree
+ Change Reve::Classes::Alliance's attribute alliance_id to plain id
+ Fix Reve::API.current_time assignment in Reve::API#check_exception
+
+Revision 1: 2007-07-22 02:02:33 +0100 (Sun, 22 Jul 2007)
+ Initial Import
View
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2007, 2008 Lisa Seelye <lisa@thedoh.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
View
54 Rakefile
@@ -0,0 +1,54 @@
+STATS_DIRECTORIES = [
+ %w(Libraries lib/),
+ %w(tests test/)
+]
+require 'rubygems'
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+require 'rake/packagetask'
+require 'rake/gempackagetask'
+
+task :default => :redoc
+
+desc "Code Statistics"
+task :stats do
+ require 'code_statistics'
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
+end
+
+
+REVE_RELEASE=`svn up &>/dev/null && svn info|grep ^Revision| cut -d ' ' -f 2`
+
+desc "Generate Docs"
+Rake::RDocTask.new("doc") { |rdoc|
+ rdoc.rdoc_dir = 'doc'
+ rdoc.title = 'Reve API Documentation'
+ rdoc.options << '--line-numbers' << '--inline-source' << '--all'
+ rdoc.rdoc_files.include('./ChangeLog')
+ rdoc.rdoc_files.include('*.rb')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+ rdoc.rdoc_files.include('test/**/*')
+}
+
+spec = Gem::Specification.new do |s|
+ s.name = "reve"
+ s.version = "0.0.#{REVE_RELEASE.chomp || '1'}"
+ s.author = "Lisa Seelye"
+ s.email = "lisa@thedoh.com"
+ s.homepage = "http://revetrac.crudvision.com"
+ s.platform = Gem::Platform::RUBY
+ s.summary = "Reve is a Ruby library to interface with the Eve Online API"
+ s.files = FileList["Rakefile","lib/**/*.rb","reve.rb","tester.rb","init.rb"].to_a
+ s.require_path = "lib"
+ s.test_files = FileList["test/test_reve.rb","test/xml/**/*.xml"].to_a
+ s.has_rdoc = true
+ s.extra_rdoc_files = ["ChangeLog"]
+ s.add_dependency("hpricot",">= 0.6")
+end rescue nil
+
+Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.need_tar = true
+end rescue nil
View
1 init.rb
@@ -0,0 +1 @@
+require 'reve'
View
897 lib/reve.rb
@@ -0,0 +1,897 @@
+#--
+# Code copyright Lisa Seelye, 2007-2008. www.crudvision.com
+# This library is licensed under the terms of the MIT license. For full text
+# see the LICENSE file distributed with this package.
+# (Also, send Raquel Smith some ISK if you would like to show appreciation ;-)
+#++
+
+begin
+ require 'hpricot'
+rescue LoadError
+ require 'rubygems'
+ require 'hpricot'
+end
+require 'net/http'
+require 'uri'
+require 'cgi'
+require 'fileutils'
+
+$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
+
+require 'reve/exceptions'
+require 'reve/extensions'
+require 'reve/classes'
+
+
+module Reve
+ # API Class.
+ # Basic Usage:
+ # api = Reve::API.new('my_UserID', 'my_apiKey')
+ # alliances = api.alliances # Returns an array of Reve::Classes::Alliance
+ #
+ # api.personal_wallet_blanace(:characterid => 892008733) # Returns an array of
+ # Reve::Classes::WalletBalance. Note that the CharacterID Number is required
+ # here.
+ #
+ # api.sovereignty :just_hash => true # Returns the hash for this call with no
+ # Alliance data with it.
+ #
+ # As of Revision 22 (28 August 2007) all API calls take a parameter,
+ # :just_hash, to just get the hash that represents that particular API call;
+ # No data related to the call is returned if :just_hash is present
+ #
+ # All API methods have the functionality to read XML from an arbitrary location. This could be another webserver, or a XML file on disk.
+ # To use this pass the hash option :url => +location+ where +location+ is a String or URI class. See format_url_request documentation for more details.
+ class API
+
+ @@alliances_url = 'http://api.eve-online.com/eve/AllianceList.xml.aspx'
+ @@sovereignty_url = 'http://api.eve-online.com/map/Sovereignty.xml.aspx'
+ @@reftypes_url = 'http://api.eve-online.com/eve/RefTypes.xml.aspx'
+ @@skill_tree_url = 'http://api.eve-online.com/eve/SkillTree.xml.aspx'
+ @@member_tracking_url = 'http://api.eve-online.com/corp/MemberTracking.xml.aspx'
+ @@corporate_wallet_balance_url = 'http://api.eve-online.com/corp/AccountBalance.xml.aspx'
+ @@personal_wallet_balance_url = 'http://api.eve-online.com/char/AccountBalance.xml.aspx'
+ @@corporate_wallet_trans_url = 'http://api.eve-online.com/corp/WalletTransactions.xml.aspx'
+ @@personal_wallet_trans_url = 'http://api.eve-online.com/char/WalletTransactions.xml.aspx'
+ @@corporate_wallet_journal_url = 'http://api.eve-online.com/corp/WalletJournal.xml.aspx'
+ @@personal_wallet_journal_url = 'http://api.eve-online.com/char/WalletJournal.xml.aspx'
+ @@characters_url = 'http://api.eve-online.com/account/Characters.xml.aspx'
+ @@training_skill_url = 'http://api.eve-online.com/char/SkillInTraining.xml.aspx'
+ @@character_sheet_url = 'http://api.eve-online.com/char/CharacterSheet.xml.aspx'
+ @@starbases_url = 'http://api.eve-online.com/corp/StarbaseList.xml.aspx'
+ @@starbasedetail_url = 'http://api.eve-online.com/corp/StarbaseDetail.xml.aspx'
+ @@conqurable_outposts_url = 'http://api.eve-online.com/eve/ConquerableStationList.xml.aspx'
+ @@corporation_sheet_url = 'http://api.eve-online.com/corp/CorporationSheet.xml.aspx'
+ @@errors_url = 'http://api.eve-online.com/eve/ErrorList.xml.aspx'
+ @@map_jumps_url = 'http://api.eve-online.com/map/Jumps.xml.aspx'
+ @@map_kills_url = 'http://api.eve-online.com/map/Kills.xml.aspx'
+ @@personal_market_orders_url = 'http://api.eve-online.com/char/MarketOrders.xml.aspx'
+ @@corporate_market_orders_url = 'http://api.eve-online.com/corp/MarketOrders.xml.aspx'
+ @@personal_industry_jobs_url = 'http://api.eve-online.com/char/IndustryJobs.xml.aspx'
+ @@corporate_industry_jobs_url = 'http://api.eve-online.com/corp/IndustryJobs.xml.aspx'
+ @@personal_assets_url = 'http://api.eve-online.com/char/AssetList.xml.aspx'
+ @@corporate_assets_url = 'http://api.eve-online.com/corp/AssetList.xml.aspx'
+ @@personal_kills_url = 'http://api.eve-online.com/char/KillLog.xml.aspx'
+ @@corporate_kills_url = 'http://api.eve-online.com/corp/KillLog.xml.aspx'
+ @@character_id_url = 'http://api.eve-online.com/eve/CharacterID.xml.aspx' # ?names=CCP%20Garthagk,Raquel%20Smith
+ @@character_name_url = 'http://api.eve-online.com/eve/CharacterName.xml.aspx' # ?ids=797400947,892008733
+ @@personal_faction_war_stats_url= 'http://api.eve-online.com/char/FacWarStats.xml.aspx'
+ @@corporate_faction_war_stats_url= 'http://api.eve-online.com/corp/FacWarStats.xml.aspx'
+ @@general_faction_war_stats_url= 'http://api.eve-online.com/eve/FacWarStats.xml.aspx'
+ @@top_faction_war_stats_url = 'http://api.eve-online.com/eve/FacWarTopStats.xml.aspx'
+ @@faction_war_occupancy_url = 'http://api.eve-online.com/map/FacWarSystems.xml.aspx'
+
+ cattr_accessor :character_sheet_url, :training_skill_url, :characters_url, :personal_wallet_journal_url,
+ :corporate_wallet_journal_url, :personal_wallet_trans_url, :corporate_wallet_trans_url,
+ :personal_wallet_balance_url, :corporate_wallet_balance_url, :member_tracking_url,
+ :skill_tree_url, :reftypes_url, :sovereignty_url, :alliances_url, :starbases_url,
+ :starbasedetail_url, :conqurable_outposts_url, :corporation_sheet_url, :map_jumps_url,
+ :map_kills_url, :personal_market_orders_url, :corporate_market_orders_url,
+ :personal_industry_jobs_url, :corporate_industry_jobs_url, :personal_assets_url,
+ :corporate_assets_url, :personal_kills_url, :corporate_kills_url,
+ :personal_faction_war_stats_url, :corporate_faction_war_stats_url,
+ :general_faction_war_stats_url, :top_faction_war_stats_url, :faction_war_occupancy_url
+
+
+
+ attr_accessor :key, :userid, :charid
+ attr_accessor :http_user_agent, :save_path
+ attr_reader :current_time, :cached_until, :last_hash
+
+ # Create a new API instance.
+ # current_time and cached_until are meaningful only for the LAST call made.
+ # Expects:
+ # * userid ( Integer | String ) - Your API userID
+ # * key ( String ) - Your API key (Full key or restricted key)
+ # * charid ( Integer | String ) - Default characterID for calls requiring it.
+ # NOTE: All values passed to the constructor are typecasted to a String for safety.
+ def initialize(userid = "", key = "", charid = "")
+ @userid = (userid || "").to_s
+ @key = (key || "").to_s
+ @charid = (charid || "").to_s
+
+ @save_path = nil
+
+ @http_user_agent = "Reve"
+ @max_tries = 3
+
+ @current_time = nil
+ @cached_until = nil
+ @last_hash = nil
+ end
+ # Save XML to this directory with the format:
+ # :save_path/:userid/:method/:expires_at_in_unixtime.xml
+ # eg: ./xml/12345/characters/1200228878.xml
+ # or: ./xml/alliances/1200228878.xml
+ # If @save_path is nil then XML is not saved.
+ def save_path=(p)
+ @save_path = p
+ end
+
+ # Convert Character names to Character ids.
+ # Expects a Hash as a parameter with these keys:
+ # * names ( Array ) - An Array of Character names to fetch the IDs of.
+ # See Also: character_name, Reve::Classes::Character, character_sheet
+ #--
+ # This is an odd method because the XML from this looks like:
+ # <rowset ...>
+ # <row:name name="CCP Garthagk" characterID="797400947" xmlns:row="characterID" />
+ # </rowset>
+ # I have to hack the Hpricot::Doc document coming from process_query to
+ # gsub out the row:name -> row to make the XPath work. Hope it doesn't
+ # perform too slowly! (We don't, of course, care about the xmlns:row bit)
+ #++
+ def character_id(opts = {} )
+ names = opts[:names] || []
+ return [] if names.empty? # No names were passed.
+ opts[:names] = names.join(',')
+ args = postfields(opts)
+ h = compute_hash( opts.merge(:url => @@character_id_url) )
+ return h if h
+ xml = process_query(nil,opts[:url] || @@character_id_url, true,opts)
+ xml = Hpricot::XML(xml.to_s.gsub('row:name','row')) # Namespaces are evil!!
+ ret = []
+ xml.search("//rowset/row").each do |elem|
+ ret << Reve::Classes::Character.new(elem)
+ end
+ ret
+ end
+
+ # Convert Character names to Character names.
+ # Expects a Hash as a parameter with these keys:
+ # * ids ( Array ) - An Array of Character IDs to fetch the names of.
+ # See Also: character_name, Reve::Classes::Character, character_sheet
+ def character_name(opts = {})
+ ids = opts[:ids] || []
+ return [] if ids.empty?
+ opts[:ids] = ids.join(',')
+ compute_hash( opts.merge(:url => @@character_name_url) ) ||
+ process_query(Reve::Classes::Character,opts[:url] || @@character_name_url,false,opts)
+ end
+
+ # Return a list of Alliances and member Corporations from
+ # http://api.eve-online.com/eve/AllianceList.xml.aspx
+ # Use the corporation_sheet method to get information for each member
+ # Corporation
+ # See also: Reve::Classes::Alliance, Reve::Classes::Corporation and
+ # corporation_sheet
+ def alliances(opts = {})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@alliances_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@alliances_url,true,args)
+ alliances = []
+ xml.search("/eveapi/result/rowset[@name='alliances']/row").each do |alliance|
+ alliance_obj = Reve::Classes::Alliance.new(alliance)
+ alliance.search("rowset[@name='memberCorporations']/row").each do |corporation|
+ alliance_obj.member_corporations << Reve::Classes::Corporation.new(corporation)
+ end
+ alliances << alliance_obj
+ end
+ alliances
+ end
+
+ # Returns a list of the number of jumps for each system. If there are no
+ # jumps for a system it will not be included. See also Reve::Classes::MapJump
+ def map_jumps(opts = {})
+ compute_hash( opts.merge(:url => @@map_jumps_url) ) ||
+ process_query(Reve::Classes::MapJump,opts[:url] || @@map_jumps_url,false)
+ end
+
+ # Returns a list of the number of kills for each system. If there are no
+ # kills for a system it will not be included. See also Reve::Classes::MapKill
+ def map_kills(opts = {})
+ compute_hash( opts.merge(:url => @@map_kills_url) ) ||
+ process_query(Reve::Classes::MapKill,opts[:url] || @@map_kills_url,false)
+ end
+
+ # Returns a list of API Errors
+ def errors(opts = {})
+ compute_hash( opts.merge(:url => @@errors_url) ) ||
+ process_query(Reve::Classes::APIError,opts[:url] || @@errors_url,false)
+ end
+
+ # Returns the Sovereignty list from
+ # http://api.eve-online.com/map/Sovereignty.xml.aspx
+ # See also: Reve::Classes::Sovereignty
+ def sovereignty(opts = {})
+ compute_hash( opts.merge(:url => @@sovereignty_url) ) ||
+ process_query(Reve::Classes::Sovereignty,opts[:url] || @@sovereignty_url,false)
+ end
+
+ # Returns a RefType list (whatever they are) from
+ # http://api.eve-online.com/eve/RefTypes.xml.aspx
+ # See also: Reve::Classes::RefType
+ def ref_types(opts = {})
+ compute_hash( opts.merge(:url => @@reftypes_url) ) ||
+ process_query(Reve::Classes::RefType,opts[:url] || @@reftypes_url,false)
+ end
+
+ # Returns a list of ConqurableStations and outposts from
+ # http://api.eve-online.com/eve/ConquerableStationList.xml.aspx
+ # See also: Reve::Classes::ConqurableStation
+ def conqurable_stations(opts = {})
+ compute_hash( opts.merge(:url => @@conqurable_outposts_url) ) ||
+ process_query(Reve::Classes::ConqurableStation, opts[:url] || @@conqurable_outposts_url, false)
+ end
+
+ # Returns a list of Reve::Classes::MarketOrder objects for market orders that are up
+ # Pass the characterid of the Character to check for
+ def personal_market_orders(opts = {:characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_market_orders_url))
+ return h if h
+ process_query(Reve::Classes::PersonalMarketOrder, opts[:url] || @@personal_market_orders_url, false, args)
+ end
+
+ # Returns a list of Reve::Classes::MarketOrder objects for market orders that are up on behalf of a Corporation
+ # Pass the characterid of the Character of whose corporation to check for
+ def corporate_market_orders(opts = {:characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_market_orders_url))
+ return h if h
+ process_query(Reve::Classes::CorporateMarketOrder, opts[:url] || @@corporate_market_orders_url, false, args)
+ end
+
+ # Returns a list of Reve::Classes::PersonalIndustryJob objects.
+ def personal_industry_jobs(opts = {:characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_industry_jobs_url))
+ return h if h
+ process_query(Reve::Classes::PersonalIndustryJob, opts[:url] || @@personal_industry_jobs_url,false,args)
+ end
+
+ # Returns a list of Reve::Classes::CorporateIndustryJob objects.
+ def corporate_industry_jobs(opts = {:characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_industry_jobs_url))
+ return h if h
+ process_query(Reve::Classes::CorporateIndustryJob, opts[:url] || @@corporate_industry_jobs_url,false,args)
+ end
+
+ # Returns the SkillTree from
+ # http://api.eve-online.com/eve/SkillTree.xml.aspx
+ # See also: Reve::Classes::SkillTree
+ # NOTE: This doesn't actually return a 'tree' yet.
+ def skill_tree(opts = {})
+ h = compute_hash(opts.merge(:url => @@skill_tree_url) )
+ return h if h
+ doc = process_query(nil,opts[:url] || @@skill_tree_url,true)
+ skills = []
+ (doc/'rowset[@name=skills]/row').each do |skill|
+ name = skill['typeName']
+ type_id = skill['typeID']
+ group_id = skill['groupID']
+ rank = (skill/:rank).inner_html
+ desc = (skill/:description).inner_html
+ required_skills = []
+ reqs = (skill/'rowset@name=[requiredskills]/row')
+ reqs.each do |required|
+ next if required.kind_of? Hpricot::Text # why is this needed? Why is this returned? How can I only get stuff with typeid and skilllevel?
+ required_skills << Reve::Classes::SkillRequirement.new(required) if required['typeID'] && required['skillLevel']
+ end
+ required_attribs = []
+ (skill/'requiredAttributes').each do |req|
+ pri = doc.at(req.xpath + "/primaryAttribute")
+ sec = doc.at(req.xpath + "/secondaryAttribute")
+ required_attribs << Reve::Classes::PrimaryAttribute.new(pri.inner_html)
+ required_attribs << Reve::Classes::SecondaryAttribute.new(sec.inner_html)
+ end
+ bonuses = []
+ res = (skill/'rowset@name=[skillBonusCollection]/row')
+ res.each do |bonus|
+ next if bonus.kind_of? Hpricot::Text
+ bonuses << Reve::Classes::SkillBonus.new(bonus) if bonus['bonusType'] && bonus['bonusValue']
+ end
+ skills << Reve::Classes::SkillTree.new(name,type_id,group_id,desc,rank,required_attribs,required_skills,bonuses)
+ end
+ skills
+ end
+
+ # Does big brother tracking from
+ # http://api.eve-online.com/corp/MemberTracking.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Look at players in this Character's Corporation
+ # See also: Reve::Classes::MemberTracking
+ def member_tracking(opts = {:characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@member_tracking_url))
+ return h if h
+ process_query(Reve::Classes::MemberTracking,opts[:url] || @@member_tracking_url,false,args)
+ end
+
+ # Gets one's own personal WalletBalance from
+ # http://api.eve-online.com/char/AccountBalance.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Look at this player's WalletBalance
+ # See also: Reve::Classes::WalletBalance and corporate_wallet_balance
+ def personal_wallet_balance(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_wallet_balance_url))
+ return h if h
+ process_query(Reve::Classes::WalletBalance,opts[:url] || @@personal_wallet_balance_url,false,args)
+ end
+
+ # Gets one's corporate WalletBalance from
+ # http://api.eve-online.com/corp/AccountBalance.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Look at WalletBalance objects from this Character's Corporation
+ # See also: Reve::Classes::WalletBalance and personal_wallet_balance
+ def corporate_wallet_balance(opts = { :characterd => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_wallet_balance_url))
+ return h if h
+ process_query(Reve::Classes::WalletBalance,opts[:url] || @@corporate_wallet_balance_url,false,args)
+ end
+
+ # Gets one's own personal WalletTransaction list from
+ # http://api.eve-online.com/char/WalletTransactions.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Look at this player's WalletTransaction list
+ # * before_trans_id ( Integer | String ) - Gets a list of WalletTransaction objects from before this Transaction ID.
+ # See also: Reve::Classes::WalletTransaction and
+ # corporate_wallet_transactions
+ def personal_wallet_transactions(opts = { :characterid => nil, :before_trans_id => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_wallet_trans_url) )
+ return h if h
+ process_query(Reve::Classes::PersonalWalletTransaction,opts[:url] || @@personal_wallet_trans_url,false,args)
+ end
+
+ # Gets one's corporate WalletTransaction list from
+ # http://api.eve-online.com/corp/WalletTransactions.xml.aspx
+ # Expects:
+ # * account_key ( Integer | String ) - Account key (1000-1006) to look at.
+ # * characterid ( Integer | String ) - Look at WalletTransaction objects from this Character's Corporation
+ # * before_trans_id ( Integer | String ) - Gets a list of WalletTransaction objects from before this Transaction ID.
+ # See also: Reve::Classes::WalletTransaction and
+ # personal_wallet_transactions
+ def corporate_wallet_transactions(opts = {:accountkey => nil, :characterid => nil, :beforerefid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_wallet_trans_url))
+ return h if h
+ process_query(Reve::Classes::CorporateWalletTransaction,opts[:url] || @@corporate_wallet_trans_url,false,args)
+ end
+
+ # Gets one's own corporate WalletJournal list from
+ # http://api.eve-online.com/corp/WalletJournal.xml.aspx
+ # Expects:
+ # * account_key ( Integer | String ) - Account key (1000-1006) to look at.
+ # * characterid ( Integer | String ) - Look at WalletJournal objects from this Character's Corporation
+ # * before_ref_id ( Integer | String ) - Gets a list of WalletTransaction objects from before this RefID.
+ # See also: Reve::Classes::WalletJournal and personal_wallet_journal
+ def corporate_wallet_journal(opts = {:accountkey => nil, :characterid => nil, :beforerefid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_wallet_journal_url))
+ return h if h
+ process_query(Reve::Classes::WalletJournal,opts[:url] || @@corporate_wallet_journal_url,false,args)
+ end
+
+ # Gets one's own personal WalletJournal list from
+ # http://api.eve-online.com/char/WalletJournal.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Look at this player's WalletJournal list
+ # * before_ref_id ( Integer | String ) - Gets a list of WalletJournal objects from before this RefID.
+ # See also: Reve::Classes::WalletJournal and corporate_wallet_journal
+ def personal_wallet_journal(opts = { :characterid => nil, :beforerefid => nil} )
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_wallet_journal_url))
+ return h if h
+ process_query(Reve::Classes::WalletJournal,opts[:url] || @@personal_wallet_journal_url,false,args)
+ end
+
+ # Gets the PersonalFactionWarStat for a character.
+ # Expects:
+ # * characterid ( Integer | String ) - Get this character's PersonalFactionWarStat.
+ # See Also Reve::Classes::PersonalFactionWarStat and corporate_faction_war_stats
+ def personal_faction_war_stats(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_faction_war_stats_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@personal_faction_war_stats_url,true,args)
+ elems = {}
+ [ :factionID, :factionName, :enlisted, :currentRank, :highestRank,
+ :killsYesterday, :killsLastWeek, :killsTotal, :victoryPointsYesterday,
+ :victoryPointsLastWeek, :victoryPointsTotal ].each do |elem|
+ elems[elem.to_s] = xml.search("/eveapi/result/" + elem.to_s).first.inner_html
+ end
+ Reve::Classes::PersonalFactionWarParticpant.new(elems)
+ end
+
+ # Gets the CorporateFactionWarStat for the Corporation a Character belongs to.
+ # Expects:
+ # * characterid ( Integer | String ) - Get this character's corp's CorporateFactionWarStat.
+ # See Also Reve::Classes::CorporateFactionWarStat and personal_faction_war_stats
+ def corporate_faction_war_stats(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_faction_war_stats_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@corporate_faction_war_stats_url,true,args)
+ elems = {}
+ [ :factionID, :factionName, :enlisted, :pilots,
+ :killsYesterday, :killsLastWeek, :killsTotal, :victoryPointsYesterday,
+ :victoryPointsLastWeek, :victoryPointsTotal ].each do |elem|
+ elems[elem.to_s] = xml.search("/eveapi/result/" + elem.to_s).first.inner_html
+ end
+ Reve::Classes::CorporateFactionWarParticpant.new(elems)
+ end
+
+ # Gets Faction-wide war stats.
+ # See also: Reve::Classes::EveFactionWarStat, Reve::Classes::FactionwideFactionWarParticpant,
+ # Reve::Classes::FactionWar
+ def faction_war_stats(opts = {} )
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@general_faction_war_stats_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@general_faction_war_stats_url,true,args)
+ participants = xml.search("/eveapi/result/rowset[@name='factions']/row").collect do |faction|
+ Reve::Classes::FactionwideFactionWarParticpant.new(faction)
+ end
+ wars = xml.search("/eveapi/result/rowset[@name='factionWars']/row").collect do |faction_war|
+ Reve::Classes::FactionWar.new(faction_war)
+ end
+ totals = {}
+ [ :killsYesterday, :killsLastWeek, :killsTotal, :victoryPointsYesterday,
+ :victoryPointsLastWeek, :victoryPointsTotal ].each do |elem|
+ totals[elem.to_s] = xml.search("/eveapi/result/totals/" + elem.to_s).first.inner_html
+ end
+ Reve::Classes::EveFactionWarStat.new(totals, wars, participants)
+ end
+
+ # Returns the occupancy data for each System.
+ # See also: Reve::Classes::FactionWarSystemStatus
+ def faction_war_system_stats(opts = {})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@faction_war_occupancy_url))
+ return h if h
+ process_query(Reve::Classes::FactionWarSystemStatus,opts[:url] || @@faction_war_occupancy_url,false,args)
+ end
+ alias_method :faction_war_occupancy, :faction_war_system_stats
+
+ # Gets a list of the top 10 statistics for Characters, Corporations and
+ # Factions in factional warfare. Read the notes on Reve::Classes::FactionWarTopStats.
+ def faction_war_top_stats(opts = {})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@top_faction_war_stats_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@top_faction_war_stats_url,true,args)
+ template = { :yesterday_kills => "KillsYesterday", :last_week_kills => "KillsLastWeek", :total_kills => "KillsTotal",
+ :yesterday_victory_points => 'VictoryPointsYesterday', :last_week_victory_points => 'VictoryPointsLastWeek', :total_victory_points => 'VictoryPointsTotal' }
+ # Inject here to save 60 lines.
+ characters = template.inject({}) do |h,(key,val)|
+ klass = key.to_s =~ /kills/ ? Reve::Classes::CharacterFactionKills : Reve::Classes::CharacterFactionVictoryPoints
+ h[key] = pull_out_top_10_data(xml,klass,'characters',val)
+ h
+ end
+ corporations = template.inject({}) do |h,(key,val)|
+ klass = key.to_s =~ /kills/ ? Reve::Classes::CorporationFactionKills : Reve::Classes::CorporationFactionVictoryPoints
+ h[key] = pull_out_top_10_data(xml,klass,'corporations',val)
+ h
+ end
+ factions = template.inject({}) do |h,(key,val)|
+ klass = key.to_s =~ /kills/ ? Reve::Classes::FactionKills : Reve::Classes::FactionVictoryPoints
+ h[key] = pull_out_top_10_data(xml,klass,'factions',val)
+ h
+ end
+ Reve::Classes::FactionWarTopStats.new(characters,corporations,factions)
+ end
+
+ # Get a list of personal assets for the characterid.
+ # See the Reve::Classes::Asset and Reve::Classes::AssetContainer classes
+ # for attributes available.
+ def personal_assets_list(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_assets_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@personal_assets_url,true,args)
+ assets = []
+ xml.search("/eveapi/result/rowset[@name='assets']/row").each do |container|
+ asset_container = Reve::Classes::AssetContainer.new(container)
+ container.search("rowset[@name='contents']/row").each do |asset|
+ asset_container.assets << Reve::Classes::Asset.new(asset)
+ end
+ assets << asset_container
+ end
+ assets
+ end
+
+ # Get a list of the Corporate Assets. Pass the characterid of the Corporate member See also assets_list method
+ def corporate_assets_list(opts = { :characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_assets_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@corporate_assets_url,true,args)
+ assets = []
+ xml.search("/eveapi/result/rowset/row").each do |container|
+ asset_container = Reve::Classes::AssetContainer.new(container)
+ container.search("rowset[@name='contents']/row").each do |asset|
+ asset_container.assets << Reve::Classes::Asset.new(asset)
+ end
+ assets << asset_container
+ end
+ assets
+ end
+
+ # Returns a Character list for the associated key and userid from
+ # http://api.eve-online.com/account/Characters.xml.aspx
+ # See also: Reve::Classes::Character
+ def characters(opts = {})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@characters_url))
+ return h if h
+ process_query(Reve::Classes::Character,opts[:url] || @@characters_url,false,args)
+ end
+
+ # Gets the SkillInTraining from
+ # http://api.eve-online.com/char/SkillInTraining.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Get the SkillInTraining for this Character
+ # See also: Reve::Classes::SkillInTraining
+ def skill_in_training(opts = {:characterid => nil})
+ args = postfields(opts)
+ ch = compute_hash(args.merge(:url => @@training_skill_url))
+ return ch if ch
+ h = {}
+ xml = process_query(nil,opts[:url] || @@training_skill_url,true,args)
+ xml.search("//result").each do |elem|
+ for field in [ 'currentTQTime', 'trainingEndTime','trainingStartTime','trainingTypeID','trainingStartSP','trainingDestinationSP','trainingToLevel','skillInTraining' ]
+ h[field] = (elem/field.intern).inner_html
+ end
+ end
+ Reve::Classes::SkillInTraining.new(h)
+ end
+
+ # Returns a list of Reve::Classes::Starbase for characterid's Corporation.
+ # http://api.eve-online.com/corp/StarbaseList.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Get the Starbase list for this character's Corporation
+ # See also Reve::Classes::Starbase
+ def starbases(opts = { :characterid => nil})
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@starbases_url))
+ return h if h
+ process_query(Reve::Classes::Starbase,opts[:url] || @@starbases_url,false,args)
+ end
+
+ # Returns the fuel status for the Starbase whose item id is starbase_id
+ # http://api.eve-online.com/corp/StarbaseDetail.xml.aspx
+ # Expects:
+ # * characterid ( Integer | String ) - Get the Starbase associated wih this character's Corporation
+ # * starbase_id ( Integer ) - Get the fuel for this Starbase. This is the Starbase's itemid.
+ # See also Reve::Classes::StarbaseFuel
+ def starbase_fuel(opts = { :characterid => nil, :starbaseid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@starbasedetail_url))
+ return h if h
+ ret = process_query(Reve::Classes::StarbaseFuel,opts[:url] || @@starbasedetail_url, false, args)
+ ret.each { |r| r.starbase_id = opts[:starbaseid] }
+ ret
+ end
+
+
+ # Get the last kills for the characterid passed.
+ # Expects:
+ # * Hash of arguments
+ # * * characterid ( Integer ) - The Character whose Kills to retrieve
+ # * * beforekillid ( Integer ) - (Optional) - Return the most recent kills before this killid.
+ def personal_kills(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@personal_kills_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@personal_kills_url,true,args)
+ kills = []
+ xml.search("/eveapi/result/rowset/row").each do |e|
+ victim = Reve::Classes::KillVictim.new(e.search("victim").first) rescue next # cant find victim
+ attackers = []
+ losses = []
+ e.search("rowset[@name='attackers']/row").each do |attacker|
+ attackers << Reve::Classes::KillAttacker.new(attacker)
+ end
+ e.search("rowset[@name='items']/row").each do |lost_item|
+ lost = Reve::Classes::KillLoss.new(lost_item)
+ lost_item.search("rowset[@name='items']/row").each do |contained|
+ lost.contained_losses << Reve::Classes::KillLoss.new(contained)
+ end
+ losses << lost
+ end
+ kills << Reve::Classes::Kill.new(e, victim, attackers, losses)
+ end
+ kills
+ end
+
+ # See the options for personal_kills
+ def corporate_kills(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporate_kills_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@corporate_kills_url,true,args)
+ kills = []
+ xml.search("/eveapi/result/rowset/row").each do |e|
+ victim = Reve::Classes::KillVictim.new(e.search("victim").first) rescue next # cant find victim
+ attackers = []
+ losses = []
+ e.search("rowset[@name='attackers']/row").each do |attacker|
+ attackers << Reve::Classes::KillAttacker.new(attacker)
+ end
+ e.search("rowset[@name='items']/row").each do |lost_item|
+ lost = Reve::Classes::KillLoss.new(lost_item)
+ lost_item.search("rowset[@name='items']/row").each do |contained|
+ lost.contained_losses << Reve::Classes::KillLoss.new(contained)
+ end
+ losses << lost
+ end
+ kills << Reve::Classes::Kill.new(e, victim, attackers, losses)
+ end
+ kills
+ end
+
+ # Gets the CorporationSheet from http://api.eve-online.com/corp/CorporationSheet.xml.aspx
+ # Expects:
+ # * Hash of arguments:
+ # * * characterid ( Integer | String ) - Gets the CorporationSheet for this Character
+ # * * corporationid ( Integer ) - If the characterid isn't passed then send the corporation's id
+ # (See the alliances method for a list) to get the details of a Corporation that belongs to an Alliance.
+ # See also: Reve::Classes::CorporationSheet
+ def corporation_sheet(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@corporation_sheet_url))
+ return h if h
+ xml = process_query(nil,opts[:url] || @@corporation_sheet_url,true,args)
+
+ h = { 'graphicid' => 0, 'shape1' => 0, 'shape2' => 0, 'shape3' => 0, 'color1' => 0, 'color2' => 0, 'color3' => 0, }
+ h.keys.each { |k| h[k] = xml.search("//result/logo/" + k + "/").to_s.to_i }
+ corporate_logo = Reve::Classes::CorporateLogo.new h
+
+ wallet_divisions = xml.search("//result/rowset[@name='walletDivisions']/").collect { |k| k if k.kind_of? Hpricot::Elem } - [ nil ]
+ divisions = xml.search("//result/rowset[@name='divisions']/").collect { |k| k if k.kind_of? Hpricot::Elem } - [ nil ]
+ divisions.collect! { |d| Reve::Classes::CorporateDivision.new(d) }
+ wallet_divisions.collect! { |w| Reve::Classes::WalletDivision.new(w) }
+
+ # Map the XML names to our own names and assign them to the temporary
+ # hash +res+ to pass to Reve::Classes::CorporationSheet#new
+ res = Hash.new
+ { :corporationid => :id, :corporationname => :name, :ticker => :ticker, :ceoid => :ceo_id,
+ :ceoname => :ceo_name, :stationid => :station_id, :stationname => :station_name,
+ :description => :description, :url => :url, :allianceid => :alliance_id,
+ :alliancename => :alliance_name, :taxrate => :tax_rate, :membercount => :member_count,
+ :memberlimit => :member_limit, :shares => :shares }.each do |k,v|
+ res[v] = xml.search("//result/#{k.to_s}/").first.to_s.strip
+ end
+
+ Reve::Classes::CorporationSheet.new res, divisions, wallet_divisions, corporate_logo
+ end
+
+ # Gets the CharacterSheet from
+ # http://api.eve-online.com/char/CharacterSheet.xml.aspx
+ # Expects:
+ # * characterid ( Fixnum ) - Get the CharacterSheet for this Character
+ # See also: Reve::Classes::CharacterSheet
+ def character_sheet(opts = { :characterid => nil })
+ args = postfields(opts)
+ h = compute_hash(args.merge(:url => @@character_sheet_url))
+ return h if h
+
+ xml = process_query(nil,opts[:url] || @@character_sheet_url,true,args)
+ cs = Reve::Classes::CharacterSheet.new
+
+ xml.search("//result/attributeEnhancers").each do |enh|
+ for kind in ['intelligenceBonus', 'memoryBonus', 'charismaBonus', 'perceptionBonus','willpowerBonus']
+ thing = nil
+ case kind
+ when 'intelligenceBonus'
+ thing = Reve::Classes::IntelligenceEnhancer
+ when 'memoryBonus'
+ thing = Reve::Classes::MemoryEnhancer
+ when 'charismaBonus'
+ thing = Reve::Classes::CharismaEnhancer
+ when 'perceptionBonus'
+ thing = Reve::Classes::PerceptionEnhancer
+ when 'willpowerBonus'
+ thing = Reve::Classes::WillpowerEnhancer
+ end
+ (enh/kind).each do |b|
+ name = (b/:augmentatorname).inner_html
+ value = (b/:augmentatorvalue).inner_html
+ cs.enhancers << thing.new(name,value)
+ end
+ end
+ end
+
+ (xml/:result).each do |elem|
+ for field in [ 'characterID', 'name', 'race', 'bloodLine', 'gender','corporationName','corporationID','balance' ]
+ cs.send("#{field.downcase}=",(elem/field.intern).first.inner_html)
+ end
+ end
+ (xml/:result/:attributes).each do |elem|
+ for attrib in [ 'intelligence','memory','charisma','perception','willpower' ]
+ cs.send("#{attrib}=",(elem/attrib.intern).first.inner_html)
+ end
+ end
+ (xml/:result/:rowset/:row).each do |elem|
+ cs.skills << Reve::Classes::Skill.new(elem)
+ end
+ cs
+ end
+
+
+ protected
+ # Sets up the post fields for Net::HTTP::Get hash for process_query method.
+ # See also format_url_request
+ # TODO: Consider moving this whole thing into process_query to avoid
+ # calling this in every method!
+ def postfields(opts = {})
+ ret = { "userid" => @userid, "apikey" => @key, "characterid" => @charid }.merge(opts.stringify_keys)
+ ret.inject({}) do |n, (k,v)|
+ n[k.downcase] = v.to_s if v
+ n
+ end
+ end
+
+ # Creates a hash for some hash of postfields. For each API method pass
+ # :just_hash => to something to return a hash that can be matched to
+ # the last_hash instance method created in process_query.
+ # This method is called in each API method before process_query and if
+ # :just_hash was passed in args then a String will be returned, otherwise
+ # nil will be returned
+ # TODO: Consider moving this whole thing into process_query before the URI parsing
+ def compute_hash(args = {})
+ args.stringify_keys!
+ return nil unless args.include?('just_hash')
+ args.delete('just_hash')
+ url = args['url'].kind_of?(URI) ? args['url'].path : args['url']
+ args.delete('url')
+ spl = url.split '/'
+ ret = (spl[-2] + '/' + spl[-1]) + ':'
+ args.delete_if { |k,v| (v || "").to_s.length == 0 } # Delete keys if the value is nil
+ h = args.stringify_keys
+ ret += h.sort.flatten.collect{ |e| e.to_s }.join(':')
+ ret.gsub(/:$/,'')
+ end
+
+ # Processes a URL and for simple <rowset><row /><row /></rowset> results
+ # create an array of objects of type klass. Or just return the XML if
+ # just_xml is set true. args is from postfields
+ # This method will call check_exception to see if an Exception came from
+ # CCP.
+ # Expects:
+ # * klass ( Class ) - The class container for parsing. An array of these is returned in default behaviour.
+ # * url ( String ) - API URL
+ # * just_xml ( Boolean ) - Return only the XML and not attempt to parse //rowset/row. Useful if the XML is not in that form.
+ # * args ( Hash ) - Hash of arguments for the request. See postfields method.
+ def process_query(klass, url, just_xml = false, opts = {})
+
+ #args = postfields(opts)
+ #h = compute_hash(args.merge(:url => url))
+ #return h if h
+
+ @last_hash = compute_hash(opts.merge({:url => url, :just_hash => true })) # compute hash
+
+ xml = check_exception(get_xml(url,opts))
+ save_xml(xml) if @save_path
+
+ return xml if just_xml
+ return [] if xml.nil? # No XML document returned. We should panic.
+
+ # Create the array of klass objects to return, assume we start with an empty set from the XML search for rows
+ # and build from there.
+ xml.search("//rowset/row").inject([]) { |ret,elem| ret << klass.new(elem) }
+ end
+
+ # Turns a hash into ?var=baz&bam=boo
+ def format_url_request(opts)
+ req = "?"
+
+ opts.stringify_keys!
+ opts.keys.sort.each do |key|
+ req += "#{CGI.escape(key.to_s)}=#{CGI.escape(opts[key].to_s)}&" if opts[key]
+ end
+ req.chop # We are lazy and append a & to each pair even if it's the last one. FIXME: Don't do this.
+ end
+
+
+ # Gets the XML from a source.
+ # Expects:
+ # * source ( String | URI ) - If the +source+ is a String Reve will attempt to load the XML file from the local filesystem by the path specified as +source+. If the +source+ is a URI or is a String starting with http (lowercase) Reve will fetch it from that URI on the web.
+ # * opts ( Hash ) - Hash of parameters for the request, such as userid, apikey and such.
+ # NOTE: To override the lowercase http -> URI rule make the HTTP part uppercase.
+ def get_xml(source,opts)
+ xml = ""
+
+ # Let people still pass Strings starting with http.
+ if source =~ /^http/
+ source = URI.parse(source)
+ end
+
+ if source.kind_of?(URI)
+ opts.merge({ :version => 2, :url => nil }) #the uri bit will now ignored in format_url_request
+ req_args = format_url_request(opts)
+ req = Net::HTTP::Get.new(source.path + req_args)
+ req['User-Agent'] = @http_referer_agent || "Reve"
+
+ res = nil
+ response = nil
+ 1.upto(@max_tries) do |try|
+ begin
+ # ||= to prevent making a new Net::HTTP object, the res = nil above should reset this for the next request.
+ # the request needs to be here to rescue exceptions from it.
+ res ||= Net::HTTP.new(source.host, source.port).start {|http| http.request(req) }
+ case res
+ when Net::HTTPSuccess, Net::HTTPRedirection
+ response = res.body
+ end
+ rescue Exception
+ sleep 5
+ next
+ end
+ break if response
+ end
+ raise Reve::Exceptions::ReveNetworkStatusException.new( (res.body rescue "No Response Body!") ) unless response
+
+ xml = response
+
+ # here ends test for URI
+ elsif source.kind_of?(String)
+ xml = File.open(source).read
+ else
+ raise Reve::Exceptions::ReveNetworkStatusException.new("Don't know how to deal with a #{source.class} XML source. I expect a URI or String")
+ end
+ xml
+ end
+
+ # Raises the proper exception (if there is one), otherwise it returns the
+ # XML response.
+ def check_exception(xml)
+ x = Hpricot::XML(xml)
+ begin
+ out = x.search("//error") # If this fails then there are some big problems with Hpricot#search ?
+ rescue Exception => e
+ $stderr.puts "Fatal error ((#{e.to_s})): Couldn't search the XML document ((#{xml})) for any potential error messages! Is your Hpricot broken?"
+ exit 1
+ end
+ @current_time = (x/:currentTime).inner_html.to_time rescue Time.now.utc # Shouldn't need to rescue this but one never knows
+ @cached_until = (x/:cachedUntil).inner_html.to_time rescue nil # Errors aren't always cached
+ return x if out.size < 1
+ code = out.first['code'].to_i
+ str = out.first.inner_html
+ Reve::Exceptions.raise_it(code,str)
+ end
+
+ def save_xml(xml)
+ path = build_save_filename
+ FileUtils.mkdir_p(File.dirname(path))
+ File.open(path,'w') { |f| f.print xml.to_original_html }
+ end
+ def build_save_filename
+ method = caller(3).first.match(/\`(.+)'/)[1] # Get the API method that's being called. This is called from save_xml -> process_query -> :real_method
+ File.join(@save_path,@userid.to_s,method,( @cached_until || Time.now.utc).to_i.to_s + '.xml')
+ end
+
+ # Returns an array of +klass+
+ def pull_out_top_10_data(xml,klass,kind,field)
+ xml.search("/eveapi/result/#{kind}/rowset[@name='#{field}']/row").inject([]) do |all,row|
+ all << klass.new(row)
+ all
+ end
+ end
+ end
+end
View
1,055 lib/reve/classes.rb
@@ -0,0 +1,1055 @@
+#--
+# Code copyright Lisa Seelye, 2007-2008. www.crudvision.com
+# Reve is not licensed for commercial use. For other uses there are no
+# restrictions.
+#
+# The author is not adverse to tokens of appreciation in the form of Eve ISK,
+# ships, and feedback. Please use
+# http://www.crudvision.com/reve-ruby-eve-online-api-library/ to provide
+# feedback or send ISK to Raquel Smith in Eve. :-)
+#++
+module Reve #:nodoc:
+ module Classes #:nodoc:
+
+ # Represents an Alliance as it appears in the Reve::API#alliances call.
+ # Attributes
+ # * name ( String ) - Full Name of the Alliance
+ # * short_name ( String ) - Short name (ticker) of the Alliance
+ # * id ( Fixnum ) - The Alliance's Eve-Online ID
+ # * executor_corp_id ( Fixnum ) - ID of the Corporation that's in charge of the Alliance
+ # * member_count ( Fixnum ) - The number of members that are in the Alliance
+ # * start_date ( Time ) - When the Alliance was formed.
+ # * member_corporations ( [Corporation] ) - Array of the Corporation objects that belong to the Alliance.
+ class Alliance
+ attr_reader :name, :short_name, :id, :executor_corp_id, :member_count, :start_date
+ attr_accessor :member_corporations
+ def initialize(elem) #:nodoc:
+ @name = elem['name']
+ @short_name = elem['shortName']
+ @id = elem['allianceID'].to_i
+ @executor_corp_id = elem['executorCorpID'].to_i
+ @member_count = elem['memberCount'].to_i
+ @start_date = elem['startDate'].to_time
+ @member_corporations = []
+ end
+ end
+
+ # Only for use in Alliance class (member_corporations array) from the Reve::API#alliances call
+ # Attributes
+ # * id ( Fixnum ) - ID of the Corporation (use this in the Reve::API#corporation_sheet call)
+ # * start_date ( Time ) - When the Corporation was started?
+ class Corporation
+ attr_reader :id, :start_date
+ def initialize(elem) #:nodoc:
+ @id = elem['corporationID'].to_i
+ @start_date = elem['startDate'].to_time
+ end
+ end
+
+ class EveFactionWarStat
+ attr_accessor :faction_participants, :faction_wars
+ attr_reader :kills_yesterday, :kills_last_week, :kills_total,
+ :victory_points_yesterday, :victory_points_last_week,
+ :victory_points_total
+ def initialize(elem,wars,participants) #:nodoc:
+ @faction_wars = wars
+ @faction_participants = participants
+ @kills_yesterday = elem['killsYesterday'].to_i
+ @kills_last_week = elem['killsLastWeek'].to_i
+ @kills_total = elem['killsTotal'].to_i
+ @victory_points_yesterday = elem['victoryPointsYesterday'].to_i
+ @victory_points_last_week = elem['victoryPointsLastWeek'].to_i
+ @victory_points_total = elem['victoryPointsTotal'].to_i
+ end
+ end
+
+ # Maps a participant in a FactionWar. Can be a:
+ # * PersonalFactionWarParticpant
+ # * CorporateFactionWarParticpant
+ # * FactionwideFactionWarParticpant
+ # Attributes:
+ # * faction_id ( Fixnum ) - ID of the Faction to which the participant belongs
+ # * faction_name ( String ) - Name of the Faction
+ # * kills_yesterday ( Fixnum )
+ # * kills_last_week ( Fixnum )
+ # * kills_total ( Fixnum )
+ # * victory_points_yesterday ( Fixnum )
+ # * victory_points_last_week ( Fixnum )
+ # * victory_points_total ( Fixnum )
+ class FactionWarParticpant
+ attr_reader :faction_id, :faction_name, :enlisted_at, :kills_yesterday,
+ :kills_last_week, :kills_total, :victory_points_yesterday,
+ :victory_points_last_week, :victory_points_total
+ def initialize(elem) #:nodoc:
+ @faction_id = elem['factionID'].to_i
+ @faction_name = elem['factionName']
+ @kills_yesterday = elem['killsYesterday'].to_i
+ @kills_last_week = elem['killsLastWeek'].to_i
+ @kills_total = elem['killsTotal'].to_i
+ @victory_points_yesterday = elem['victoryPointsYesterday'].to_i
+ @victory_points_last_week = elem['victoryPointsLastWeek'].to_i
+ @victory_points_total = elem['victoryPointsTotal'].to_i
+ end
+ end
+
+ # Represents a Character's stats as a FactionWarParticpant.
+ # Attributes:
+ # * (See FactionWarParticpant for more)
+ # * current_rank ( Fixnum ) - Current Rank
+ # * highest_rank ( Fixnum ) - Highest Rank
+ # * enlisted_at ( Time ) - When the participant enlisted into the Faction
+ class PersonalFactionWarParticpant < FactionWarParticpant
+ attr_reader :current_rank, :highest_rank
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @current_rank = elem['currentRank'].to_i
+ @highest_rank = elem['highestRank'].to_i
+ @enlisted_at = elem['enlisted'].to_time
+ end
+ end
+
+ # Represents a Corpration's stats as a FactionWarParticpant.
+ # Attributes:
+ # * (See FactionWarParticpant for more)
+ # * pilots ( Fixnum ) - Number of pilots (Characters) in the Corporation
+ # * enlisted_at ( Time ) - When the participant enlisted into the Faction
+ class CorporateFactionWarParticpant < FactionWarParticpant
+ attr_reader :pilots
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @pilots = elem['pilots'].to_i
+ @enlisted_at = elem['enlisted'].to_time
+ end
+ end
+
+ # Represents an entire Faction's stats as a FactionWarParticpant.
+ # Attributes:
+ # * (See FactionWarParticpant for more)
+ # * pilots ( Fixnum ) - Number of pilots (Characters) in the Corporation
+ class FactionwideFactionWarParticpant < FactionWarParticpant
+ attr_reader :pilots, :systems_controlled
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @pilots = elem['pilots'].to_i
+ @systems_controlled = elem['systemsControlled'].to_i
+ end
+ end
+
+ # Represents a single FactionWar between two Factions (e.g., Gallente v. Caldari)
+ # Attributes:
+ # * faction_id ( Fixnum ) - ID of the belligerant Faction
+ # * faction_name ( String ) - Name of the belligerant Faction.
+ # * against_id ( Fixnum ) - ID of the Faction that this war is against.
+ # * against_name ( String ) - Name of the Faction that this war is against.
+ class FactionWar
+ attr_reader :faction_id, :faction_name, :against_id, :against_name
+ def initialize(elem) #:nodoc:
+ @faction_id = elem['factionID'].to_i
+ @faction_name = elem['factionName']
+ @against_id = elem['againstID'].to_i
+ @against_name = elem['againstName']
+ end
+ end
+
+ # The status of a System with regards to a FactionWar. Who controls what
+ # and what System is contested
+ # Attributes:
+ # * system_id ( Fixnum ) - ID of the System
+ # * system_name ( String ) - Name of the System
+ # * faction_id ( Fixnum | NilClass ) - ID of the Faction that is occupying this System. If no Faction controls this System this will be nil.
+ # * faction_name ( String | NilClass ) - Name of the Faction that is occupying this System. If no Faction controls this System this will be nil.
+ # * contested ( Boolean ) - Is this System contested?
+ class FactionWarSystemStatus
+ attr_reader :system_id, :system_name, :faction_id, :faction_name, :contested
+ def initialize(elem) #:nodoc:
+ @system_id = elem['solarSystemID'].to_i
+ @system_name = elem['solarSystemName']
+ @faction_id = elem['occupyingFactionID'].to_i
+ @faction_name = elem['occupyingFactionName']
+ @contested = elem['contested'] == 'True'
+ if @faction_id == 0
+ @faction_id = nil
+ @faction_name = nil
+ end
+ end
+ end
+
+ class FactionWarKills
+ attr_reader :kills
+ def initialize(elem) #:nodoc:
+ @kills = elem['kills'].to_i
+ end
+ end
+
+ class CharacterFactionKills < FactionWarKills
+ attr_reader :name, :id
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @name = elem['characterName']
+ @id = elem['characterID'].to_i
+ end
+ end
+ class CorporationFactionKills < FactionWarKills
+ attr_reader :name, :id
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @name = elem['corporationName']
+ @id = elem['corporationID'].to_i
+ end
+ end
+ class FactionKills < FactionWarKills
+ attr_reader :name, :id
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @name = elem['factionName']
+ @id = elem['factionID'].to_i
+ end
+ end
+
+ class FactionWarVictoryPoints
+ attr_reader :victory_points
+ def initialize(elem) #:nodoc:
+ @victory_points = elem['victoryPoints'].to_i
+ end
+ end
+ class CharacterFactionVictoryPoints < FactionWarVictoryPoints
+ attr_reader :name, :id
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @name = elem['characterName']
+ @id = elem['characterID'].to_i
+ end
+ end
+ class CorporationFactionVictoryPoints < FactionWarVictoryPoints
+ attr_reader :name, :id
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @name = elem['corporationName']
+ @id = elem['corporationID'].to_i
+ end
+ end
+ class FactionVictoryPoints < FactionWarVictoryPoints
+ attr_reader :name, :id
+ def initialize(elem) #:nodoc:
+ super(elem)
+ @name = elem['factionName']
+ @id = elem['factionID'].to_i
+ end
+ end
+
+ # Faction War Top Stats. This is different than the rest of the classes.
+ # Each attribute on this class is a Hash with the following keys:
+ # * yesterday_kills ( Array )
+ # * yesterday_victory_points ( Array )
+ # * last_week_kills ( Array )
+ # * last_week_victory_points ( Array )
+ # * total_kills ( Array )
+ # * total_victory_points ( Array )
+ # The value of each key is an Array whose class is specified below (under 'Attributes' list) for each Attribute.
+ # Attributes:
+ # * characters ( Hash ) - CharacterFactionVictoryPoints, CharacterFactionKills
+ # * corporations ( Hash ) - CorporationFactionVictoryPoints, CorporationFactionKills
+ # * factions ( Hash ) - FactionVictoryPoints, FactionWarKills
+ # Access: Reve::API#faction_war_top_stats.characters[:yesterday_kills] => array of CharacterFactionKills objects.
+ class FactionWarTopStats
+ attr_reader :characters, :corporations, :factions
+ def initialize(characters, corporations, factions) #:nodoc:
+ @characters = characters
+ @corporations = corporations
+ @factions = factions
+ end
+
+ end
+
+ # A Skill has a RequiredAttribute, either a PrimaryAttribute or SecondaryAttribute, which both derrive from this.
+ # Attributes
+ # * name ( String ) - Name of the required Attribute
+ # See Also: PrimaryAttribute, SecondaryAttribute, Skill, Reve::API#skill_tree
+ class RequiredAttribute
+ attr_reader :name
+ def initialize(attrib) #:nodoc:
+ @name = attrib
+ end
+ end
+ # Denotes the PrimaryAttribute of the RequiredAttribute pair for a Skill. See also
+ # SecondaryAttribute and RequiredAttribute
+ class PrimaryAttribute < RequiredAttribute
+ end
+ # Denotes the SecondaryAttribute of the RequiredAttribute pair for a Skill. See also
+ # PrimaryAttribute and RequiredAttribute
+ class SecondaryAttribute < RequiredAttribute
+ end
+
+ # Represents the victim of a Kill.
+ # Attributes:
+ # * id ( Fixnum ) - ID of the Character that was killed.
+ # * name ( String ) - The name of the Character that was killed.
+ # * corporation_id ( Fixnum ) - The ID of the Corporation that the victim belongs to.
+ # * alliance_id ( Fixnum | NilClass ) - The ID of the Alliance that the victim belongs to, if applicable. Will be nil unless the victim was in an Alliance
+ # * damage_taken ( Fixnum ) - The amount of damage the victim took before being killed.
+ # * ship_type_id ( Fixnum ) - ID of the ship type (references CCP data dump) that the victim was flying.
+ # See Also: KillAttacker, Kill, KillLoss, Reve::API#personal_kills, Reve::API#corporate_kills
+ class KillVictim
+ attr_reader :id, :name, :corporation_id, :corporation_name, :alliance_id, :damage_taken, :ship_type_id
+ def initialize(elem) #:nodoc:
+ @id = elem['characterID'].to_i
+ @name = elem['characterName']
+ @corporation_id = elem['corporationName']
+ @alliance_id = elem['allianceID'] == "0" ? nil : elem['allianceID'].to_i
+ @damage_taken = elem['damageTaken'].to_i
+ @ship_type_id = elem['shipTypeID'].to_i
+ end
+ end
+
+ # It's possible to be killed/attacked by an NPC. In this case character_id, character_name,
+ # alliance_id, alliance_name and weapon_type_id will be nil
+ # Represents an attacker (attacking a KillVictim) in a Kill
+ # Attributes
+ # * id ( Fixnum | NilClass ) - ID of the attacker; nil if the attacker was an NPC or not a Character
+ # * name ( String | NilClass ) - Name of the attacker; nil if the attacker was an NPC or not a Character
+ # * corporation_id ( Fixnum ) - ID of the Corporation that the Character belongs to (could be NPC Corporation!)
+ # * corporation_name ( String ) - Name of the Corporation that the Character belongs to (could be NPC Corporation!)
+ # * alliance_id ( Fixnum | NilClass ) - ID of the Alliance that the Character belongs to (nil if the KillAttacker doesn't belong to an Alliance)
+ # * security_status ( Float ) - Security status of the KillAttacker
+ # * damage_done ( Fixnum ) - How much damage the KillAttacker did.
+ # * final_blow ( Boolean ) - True if this KillAttacker got the final blow to kill the KillVictim
+ # * weapon_type_id ( Fixnum | NilClass ) - Type ID of the (a?) weapon the KillAttacker was firing. (Refer to CCP database dump invtypes)
+ # * ship_type_id ( Fixnum ) - Type ID of the ship the KillAttacker was flying. (Refer to CCP database dump invtypes)
+ # See Also: Kill, KillLoss, KillVictim, Reve::API#personal_kills, Reve::API#corporate_kills
+ class KillAttacker
+ attr_reader :id, :name, :corporation_id, :corporation_name, :alliance_id, :alliance_name,
+ :security_status, :damage_done, :final_blow, :weapon_type_id, :ship_type_id
+ def initialize(elem) #:nodoc:
+ @id = elem['characterID'] == "0" ? nil : elem['characterID'].to_i
+ @name = elem['characterName'].empty? ? nil : elem['characterName']
+ @corporation_id = elem['corporationID'].to_i
+ @corporation_name = elem['corporationName']
+ @alliance_id = elem['allianceID'] == "0" ? nil : elem['allianceID'].to_i
+ @alliance_name = elem['allianceName'].empty? ? nil : elem['allianceName']
+ @security_status = elem['securityStatus'].to_f
+ @damage_done = elem['damageDone'].to_i
+ @final_blow = elem['finalBlow'] == "1"
+ @weapon_type_id = elem['weaponTypeID'] == "0" ? nil : elem['weaponTypeID'].to_i
+ @ship_type_id = elem['shipTypeID'].to_i
+ end
+ end
+
+ # A model to represent losses from being killed.
+ # Attributes
+ # * type_id ( Fixnum ) - Type ID of the KillLoss. (Refer to CCP database dump invtypes)
+ # * flag ( Fixnum ) - A flag to denoe some special qualities of the KillLoss such as where it was mounted or if it was in a container. Refer to http://wiki.eve-dev.net/API_Inventory_Flags
+ # * quantity_dropped ( Fixnum ) - The number of +type_id+ that were dropped for looting - e.g., not destroyed.
+ # * quantity_destroyed ( Fixnum ) - The number of +type_id+ that were destroyed in the Kill.
+ # * contained_losses ( [KillLoss] ) - If the KillLoss was a container (refer to +type_id+) then this array will be populated with a list of KillLoss objects that were inside the container.
+ # See Also: Kill, KillAttacker, KillVictim, Reve::API#personal_kills, Reve::API#corporate_kills
+ class KillLoss
+ attr_reader :type_id, :flag, :quantity_dropped, :quantity_destroyed
+ attr_accessor :contained_losses
+ def initialize(elem)
+ @type_id = elem['typeID'].to_i
+ @flag = elem['flag'].to_i
+ @quantity_dropped = elem['qtyDropped'].to_i
+ @quantity_destroyed = elem['qtyDestroyed'].to_i
+ @contained_losses = []
+ end
+ end
+
+
+ # Simple class to contain the information relevant to a single Kill.
+ # Comprised of an array of KillLoss, an array of KillAttacker and one KillVictim
+ # Attributes
+ # * victim ( KillVictim ) - Instance of the KillVictim class to represent the victim of the Kill.
+ # * attackers ( [KillAttacker] ) - Array of KillAttacker objects that represent the people who killed the +victim+.
+ # * losses ( [KillLoss] ) - Array of KillLoss objects that represents the +victim+'s items destroyed in the Kill.
+ # * system_id ( Fixnum ) - The ID of the System that the Kill took place in.
+ # * id ( Fixnum ) - The ID of this specific Kill
+ # * moon_id ( Fixnum | NilClass ) - The ID of the Moon that this kill happened at (due to a POS?), if any; nil otherwise.
+ # See Also: KillAttacker, KillVictim, KillLoss, Reve::API#personal_kills, Reve::API#corporate_kills
+ class Kill
+ attr_reader :victim, :attackers, :losses
+ attr_reader :system_id, :created_at, :id, :moon_id
+ def initialize(elem, victim, attackers, losses) #:nodoc:
+ @victim, @attackers, @losses = victim, attackers, losses
+ @system_id = elem['solarSystemID'].to_i
+ @created_at = elem['killTime'].to_time
+ @id = elem['killID'].to_i
+ @moon_id = elem['moonID'] == "0" ? nil : elem['moonID'].to_i
+ end
+ end
+
+
+ # A container or singleton (unpackaged thing).
+ # Attributes
+ # * item_id ( Fixnum ) - A CCP-specific ID for the Asset/AssetContainer
+ # * location_id ( Fixnum ) - The ID of the Station (or POS?) that the Asset/AssetContainer is at.
+ # * type_id ( Fixnum ) - Type ID of the Asset/AssetContainer. (Refer to CCP database dump invtypes)
+ # * quantity ( Fixnum ) - The number of Asset/AssetContainer at this +location_id+
+ # * flag ( Fixnum ) - Inventory flag, refer to http://wiki.eve-dev.net/API_Inventory_Flags (See also KillLoss's flag)
+ # * singleton ( Boolean ) - True if the Asset/AssetContainer is not packaged up.
+ # * assets ( [Asset] ) - A list of Asset objects that are contained in this AssetContainer.
+ # See Also: Asset, Reve::API#corporate_assets_list, Reve::API#personal_assets_list
+ class AssetContainer
+ attr_reader :item_id, :location_id, :type_id, :quantity, :flag, :singleton
+ attr_accessor :assets
+ def initialize(elem)
+ @item_id = elem['itemID'].to_i
+ @location_id = elem['locationID'].to_i
+ @type_id = elem['typeID'].to_i
+ @quantity = elem['quantity'].to_i
+ @flag = elem['flag'].to_i
+ @singleton = elem['singleton'] == "1"
+ @assets = []
+ end
+ end
+
+ # An item contained within an AssetContainer (ship, or container)
+ # Attributes
+ # * item_id ( Fixnum ) - A CCP-specific ID for the Asset/AssetContainer
+ # * type_id ( Fixnum ) - Type ID of the Asset/AssetContainer. (Refer to CCP database dump invtypes)
+ # * quantity ( Fixnum ) - The number of Asset/AssetContainer at this +location_id+
+ # * flag ( Fixnum ) - Inventory flag, refer to http://wiki.eve-dev.net/API_Inventory_Flags (See also KillLoss's flag)
+ # See Also: AssetContainer, Reve::API#corporate_assets_list, Reve::API#personal_assets_list
+ class Asset
+ attr_reader :item_id, :type_id, :quantity, :flag, :singleton
+ def initialize(elem) #:nodoc:
+ @item_id = elem['itemID'].to_i
+ @type_id = elem['typeID'].to_i
+ @quantity = elem['quantity'].to_i
+ @flag = elem['flag'].to_i
+ @singleton = elem['singleton'].to_i
+ end
+ end
+
+ # Used for attribute enhancers (in-game Implants)
+ # IntelligenceEnhancer, MemoryEnhancer, PerceptionEnhancer, CharismaEnhancer
+ # and WillpowerEnhancer all subclass this class as this AttributeEnhancer
+ # class is never used (except in a fault-case). Use the kind_of? method
+ # to determine what kind of AttributeEnhancer one is dealing with.
+ # Attributes
+ # * name ( String ) - The name of the AttributeEnhancer (implant)
+ # * value ( Fixnum ) - How much the +name+ implant boosts.
+ # See Also: CharacterSheet, Reve::API#character_sheet
+ class AttributeEnhancer
+ attr_accessor :name, :value
+ def initialize(name = "", value = 0) #:nodoc:
+ @name = name
+ @value = value.to_i
+ end
+ end
+ class IntelligenceEnhancer < AttributeEnhancer; end
+ class MemoryEnhancer < AttributeEnhancer; end
+ class PerceptionEnhancer < AttributeEnhancer; end
+ class CharismaEnhancer < AttributeEnhancer; end
+ class WillpowerEnhancer < AttributeEnhancer; end
+
+ # Represents a Character for the Reve::API#characters, Reve::API#character_name and Reve::API#character_id calls.
+ # Attributes
+ # * name ( String ) - Name of the Character
+ # * id ( Fixnum ) - ID of the Character (use this for Reve::API method calls)
+ # * corporation_name ( String | NilClass ) - Name of the Corporation the Character belongs to. Nil if being used for Reve::API#character_name or Reve::API#character_id
+ # * corporation_id ( Fixnum | NilClass ) - ID of the Corporation the Character belongs to. Nil if being used for Reve::API#character_name or Reve::API#character_id
+ # See Also: Reve::API
+ class Character
+ attr_reader :name, :id, :corporation_name, :corporation_id
+ def initialize(elem) #:nodoc:
+ @id = elem['characterID'].to_i
+ @name = elem['name']
+ @corporation_name = elem['corporationName']
+ @corporation_id = elem['corporationID'].to_i
+ end
+ end
+
+ # Holds the result of the Reve::API#character_sheet call.
+ # This has all of the stuff that appears in the in-game 'character sheet'
+ # screen.
+ # The skills array is a Skill list (no name is stored in it)
+ # The enhancers array is an AttributeEnhancer derrived list
+ # Attributes
+ # * name ( String ) - Name of the Character
+ # * race ( String ) - Race of the Character
+ # * gender ( String ) - Gender of the Character
+ # * id ( Fixnum ) - ID of the Character
+ # * corporation_name ( String ) - Name of the Corporation the Character is in
+ # * corporation_id ( Fixnum ) - ID of the Corporation the Character is in
+ # * balance ( Float ) - How much ISK the Character has
+ # * intelligence ( Fixnum ) - Character's Intelligence level
+ # * memory ( Fixnum ) -
+ # * charisma ( Fixnum ) -
+ # * perception ( Fixnum ) -
+ # * willpower ( Fixnum ) -
+ # * skills ( [Skill] ) - An Array of Skill objects that the Character has trained.
+ # * enhancers ( [AttributeEnhancer] ) - An Array of any implants (AttributeEnhancer) the Character has in its head.
+ # See Also: Reve::API#character_sheet, AttributeEnhancer (and subclasses), Skill
+ class CharacterSheet
+ attr_accessor :name, :race, :bloodline, :gender, :id, :corporation_name, :corporation_id, :balance
+ attr_accessor :intelligence, :memory, :charisma, :perception, :willpower
+ attr_accessor :skills, :enhancers
+ def initialize #:nodoc:
+ @skills = []
+ @enhancers = []
+ end
+ def characterid=(i) #:nodoc:
+ @id = i.to_i
+ end
+ def corporationname=(i) #:nodoc:
+ @corporation_name = i
+ end
+ def corporationid=(i) #:nodoc:
+ @corporation_id = i.to_i
+ end
+ end
+
+ # Holds the result of the Reve::API#conqurable_stations call.
+ # Attributes
+ # * id ( Fixnum ) - ID of the ConqurableStation
+ # * name ( String ) - Name of the ConqurableStation
+ # * type_id ( Fixnum ) - What kind of ConqurableStation Station it is (Refer to CCP database dump invtypes).
+ # * type_name ( String ) - Name of the kind of Station this ConqurableStation is. (May not be present??)
+ # * corporation_id ( Fixnum ) - ID of the Corporation that owns the ConqurableStation
+ # * corporation_name ( String ) - Name of the Corporation that owns the ConqurableStation.
+ # See Also: Sovereignty, Reve::API#conqurable_stations, Reve::API#sovereignty, Reve::API#corporation_sheet, CorporationSheet
+ class ConqurableStation
+ attr_reader :id, :name, :type_id, :type_name, :system_id, :system_name, :corporation_id, :corporation_name
+ def initialize(elem) #:nodoc:
+ @id = elem['stationID'].to_i
+ @name = elem['stationName']
+ @type_id = elem['stationTypeID'].to_i
+ @type_name = elem['stationTypeName']
+ @corporation_id = elem['corporationID'].to_i
+ @corporation_name = elem['corporationName']
+ end
+ end
+
+ # Part of the CorporationSheet; represnets a Corporation's in-game logo
+ # All of these values are internal to CCP; +shape_1+ matches with +color_1+ and so on.
+ # Attributes
+ # * graphic_id ( Fixnum )
+ # * shape_1 ( Fixnum )
+ # * shape_2 ( Fixnum )
+ # * shape_3 ( Fixnum )
+ # * color_1 ( Fixnum )
+ # * color_2 ( Fixnum )
+ # * color_3 ( Fixnum )
+ class CorporateLogo
+ attr_reader :graphic_id, :shape_1, :shape_2, :shape_3, :color_1, :color_2, :color_3
+ def initialize(elem) #:nodoc:
+ @graphic_id = elem['graphicID'].to_i
+ @shape_1 = elem['shape1'].to_i
+ @shape_2 = elem['shape2'].to_i
+ @shape_3 = elem['shape3'].to_i
+ @color_1 = elem['color1'].to_i
+ @color_2 = elem['color2'].to_i
+ @color_3 = elem['color3'].to_i
+ end
+ end
+
+ # Part of the CorporationSheet. Describes a division in the wallet
+ # Attributes
+ # * key ( Fixnum ) - Account key. Used for things like WalletBalance and such.
+ # * description ( String ) - Description of the WalletDivision
+ # See Also CorporationSheet
+ class WalletDivision
+ attr_reader :key, :description
+ def initialize(elem) #:nodoc:
+ @key = elem['accountKey'].to_i
+ @description = elem['description'].split(/\n/).collect { |s| s.strip }.join(' ') # newlines to spaces
+ end
+ end
+
+ # Part of the CorporationSheet. Describes a division of the Corporation
+ # Attributes
+ # * key ( Fixnum ) - Account key.
+ # * description ( String ) - Description of the CorporateDivision
+ # See Also CorporationSheet
+ class CorporateDivision
+ attr_reader :key, :description
+ def initialize(elem) #:nodoc:
+ @key = elem['accountKey'].to_i
+ @description = elem['description'].split(/\n/).collect { |s| s.strip }.join(' ') # newlines to spaces
+ end
+ end
+
+ # Describes a Corporation. The public listing when a Corporation is in an Alliance is limited. When the requestor is in the Corporation for which the CorporationSheet is for then the details are full.
+ # Attributes
+ # * id ( Fixnum ) - ID of the Corporation
+ # * name ( String ) - Name of the Corporation
+ # * ticker ( String ) - Ticker (short name) of the Corporation
+ # * ceo_id ( Fixnum ) - The ID of the Character who is the CEO of the Corporation
+ # * ceo_name ( String ) - The name of the Character whois he CEO of the Corporation
+ # * station_id ( Fixnum ) - The ID of the Corporation's home Station
+ # * station_name ( Station ) - The name of the Corporation's home Station
+ # * description ( String ) - Corporation's description
+ # * url ( String ) - URL of the Corporation's website. If none is set the value is an empty String
+ # * alliance_id ( Fixnum | NilClass ) - ID of the Alliance that this Corporation belongs to; nil if no membership
+ # * alliance_name ( String | NilClass ) - Name of the Alliance that this Corporation belongs to; nil if no membership
+ # * tax_rate ( Float ) - Tax rate for the Corporation
+ # * member_count ( Fixnum ) - How many Characters are in the Corporation
+ # * member_limit ( Fixnum ) - Member limit (Max number of Characters allowed in?)
+ # * shares ( Fixnum ) - Number of shares available for the Corporation
+ # * divisions ( [CorporateDivision] ) - Array of CorporateDivision objects representing the differet divisions in the Corporation
+ # * wallet_divisions ( [WalletDivision] ) - Array of WalletDivision objects representing the different divisions in the wallet for the Corporation
+ # * logo ( CorporateLogo ) - An object to represent the Corporation's logo.
+ # See Also: CorporateLogo, WalletDivision, CorporateDivision, Corporation, Reve::API#corporation_sheet
+ class CorporationSheet
+ attr_reader :id, :name, :ticker, :ceo_id, :ceo_name, :station_id, :station_name, :description, :url,
+ :alliance_id, :alliance_name, :tax_rate, :member_count, :member_limit, :shares
+ attr_accessor :divisions, :wallet_divisions, :logo
+
+ # Call it +h+ here cos it's a Hash and not any Hpricot object like in other constructors
+ def initialize(h, divisions = [],wallet_divisions = [], logo =Reve::Classes::CorporateLogo.new(Hash.new(0)) ) #:nodoc:
+ @divisions = divisions
+ @wallet_divisions = wallet_divisions
+ @logo = logo
+ @id = h[:id].to_i
+ @name = h[:name]
+ @ticker = h[:ticker]
+ @ceo_id = h[:ceo_id].to_i
+ @ceo_name = h[:ceo_name]
+ @station_id = h[:station_id].to_i
+ @station_name = h[:station_name]
+ @description = h[:description].split(/\n/).collect { |s| s.strip }.join(' ') # newlines to spaces
+ @url = h[:url] || ""
+ @alliance_id = h[:alliance_id].to_i rescue nil
+ @alliance_name = h[:alliance_name] rescue nil
+ @tax_rate = h[:tax_rate].to_f
+ @member_count = h[:member_count].to_i
+ @member_limit = h[:member_limit].to_i
+ @shares = h[:shares].to_i
+ end
+ end
+
+ # This is just for getting the list and writing to test/xml/errors
+ class APIError #:nodoc:
+ attr_reader :code, :text
+ def initialize(elem)
+ @code = elem['errorCode'].to_i
+ @text = elem['errorText']
+ end
+ end
+
+ # Used for the Reve::API#map_jumps method. If there are no jumps it is not listed.
+ # Attributes
+ # * system_id ( Fixnum ) - ID of the System
+ # * jumps ( Fixnum ) - Number of jumps through the System
+ # See Also: MapKill, Reve::API#map_jumps
+ class MapJump
+ attr_reader :system_id, :jumps
+ def initialize(elem) #:nodoc:
+ @system_id = elem['solarSystemID'].to_i
+ @jumps = elem['shipJumps'].to_i
+ end
+ end
+
+ # Used for the Reve::API#personal_market_orders and Reve::API#corporate_market_orders
+ # Each of those derrive from this parent class.
+ # Attributes
+ # * id ( Fixnum ) - ID of the MarketOrder. This is a CCP internal ID and is not guaranteed to always be unique! You may want to generate your own globally unique ID for this.
+ # * character_id ( Fixnum ) - ID of the Character who set this MarketOrder up
+ # * station_id ( Fixnum ) - ID of the Station where the MarketOrder is
+ # * volume_entered ( Fixnum ) - How many of +type_id+ was initially entered in the MarketOrder
+ # * volume_remaining ( Fixnum ) - How many of +type_id+ is left in the MarketOrder
+ # * minimum_volume ( Fixnum ) - How much of +type_id+ can be transacted (as a minimum) at once
+ # * order_state ( String ) - String representation of the MarketOrder's current state. Options are: Active, Closed, Expired, Cancelled, Pending, Character Deleted
+ # * type_id ( Fixnum ) - Type ID of item for which the MarketOrder was created. (Refer to CCP database dump invtypes)
+ # * range ( Fixnum ) - Range of the MarketOrder. For sell orders it is always 32767 (Entire Region), for sell orders the values are -1 (Station only), 0 (Solar system), 1..40 (Number of jumps away from the Station), 32767 (Region wide)
+ # * account_key ( Fixnum ) - For a CorporateMarketOrder the account key (see WalletDivision and CorporationSheet) that was used as the source/destination.
+ # * duration ( Fixnum ) - Duration of the MarketOrder in days from when it was +created_at+
+ # * escrow ( Float ) - How much ISK is held in escrow for the MarketOrder
+ # * price ( Float ) - Unit price of the item in the MarketOrder
+ # * bid ( Boolean ) - True if this MarketOrder is a sell order, false otherwise
+ # * created_at ( Time ) - When the MarketOrder was created
+ # See Also: CorporationSheet, WalletDivision, CorporateDivision, Reve::API#personal_market_orders, Reve::API#corporate_market_orders
+ class MarketOrder
+ attr_reader :id, :character_id, :station_id, :volume_entered, :volume_remaining, :minimum_volume,
+ :order_state, :type_id, :range, :account_key, :duration, :escrow, :price, :bid, :created_at
+ def initialize(elem) #:nodoc:
+ @id = elem['orderID'].to_i
+ @character_id = elem['charID'].to_i
+ @station_id = elem['stationID'].to_i
+ @volume_entered = elem['volEntered'].to_i
+ @volume_remaining = elem['volRemaining'].to_i
+ @minimum_volume = elem['minVolume'].to_i
+ @order_state = case elem['orderState'].to_i
+ when 0
+ 'Active'
+ when 1
+ 'Closed'
+ when 2
+ 'Expired'
+ when 3
+ 'Cancelled'
+ when 4
+ 'Pending'
+ when 5
+ 'Character Deleted'
+ end
+ @type_id = elem['typeID'].to_i
+ @range = elem['range'].to_i
+ @account_key = elem['accountKey'].to_i
+ @escrow = elem['escrow'].to_f
+ @price = elem['price'].to_f
+ @bid = elem['bid'] == '1'
+ @duration = elem['duration'].to_i
+ @created_at = elem['issued'].to_time
+ end
+ end
+ class PersonalMarketOrder < MarketOrder; end
+ class CorporateMarketOrder < MarketOrder; end
+
+
+ # Used in Reve::API#personal_industry_jobs and Reve::API#corporate_industry_jobs. PersonalIndustryJob and CorporateIndustryJob
+ # subclass this for more logical containment.
+ # These attributes should be largely self-explanatory. There are so many of them that it's soulcrushing to document each one! (Sorry ;)
+ # For further information please see: http://wiki.eve-dev.net/APIv2_Char_IndustryJobs_XML especially about +completed_status+ and +completed+
+ class IndustryJob
+ attr_reader :id, :assembly_line_id, :container_id, :installed_item_id, :installed_item_location_id,
+ :installed_item_quantity, :installed_item_productivity_level, :installed_item_material_level,
+ :installed_item_licensed_production_runs_remaining, :output_location_id, :installer_id, :runs,
+ :licensed_production_runs, :installed_system_id, :container_location_id, :material_multiplier,
+ :char_material_multiplier, :time_multiplier, :char_time_multiplier, :installed_item_type_id,
+ :output_type_id, :container_type_id, :installed_item_copy, :completed, :completed_successfully,
+ :installed_item_flag, :output_flag, :activity_id, :completed_status, :installed_at,
+ :begin_production_at, :end_production_at, :pause_production_time
+ def initialize(elem) #:nodoc:
+ @id = elem['jobID'].to_i; @assembly_line_id = elem['assemblyLineID'].to_i ; @container_id = elem['containerID'].to_i
+ @installed_item_id = elem['installedItemID'].to_i ; @installed_item_location_id = elem['installedItemLocationID'].to_i
+ @installed_item_quantity = elem['installedItemQuantity'].to_i
+ @installed_item_productivity_level = elem['installedItemProductivityLevel'].to_i
+ @installed_item_material_level = elem['installedItemMaterialLevel'].to_i
+ @installed_item_licensed_production_runs_remaining = elem['installedItemLicensedProductionRunsRemaining'].to_i
+ @output_location_id = elem['outputLocationID'].to_i ; @installer_id = elem['installerID'].to_i; @runs = elem['runs'].to_i
+ @licensed_production_runs = elem['licensedProductionRuns'].to_i ; @installed_system_id = elem['installedSolarSystemID'].to_i
+ @container_location_id = elem['containerLocationID'].to_i ; @material_multiplier = elem['materialMultiplier'].to_f
+ @char_material_multiplier = elem['charMaterialMultiplier'].to_f; @time_multiplier = elem['timeMultiplier'].to_f
+ @char_time_multiplier = elem['charTimeMultiplier'].to_f ; @installed_item_type_id = elem['installedItemTypeID'].to_i
+ @output_type_id = elem['outputTypeID'].to_i ; @container_type_id = elem['containerTypeID'].to_i
+ @installed_item_copy = (elem['installedItemCopy'] == "1") ; @completed = (elem['completed'] == "1")
+ @completed_successfully = (elem['completedSuccessfully'] == "1")
+ @installed_item_flag = elem['installedItemFlag'].to_i ; @output_flag = elem['outputFlag'].to_i
+ @activity_id = elem['activityID'].to_i ; @completed_status = elem['completedStatus'].to_i
+ @installed_at = elem['installTime'].to_time ; @begin_production_at = elem['beginProductionTime'].to_time
+ @end_production_at = elem['endProductionTime'].to_time
+ @pause_production_time = elem['pauseProductionTime'].to_time
+ end
+ end
+ class PersonalIndustryJob < IndustryJob; end
+ class CorporateIndustryJob < IndustryJob; end
+
+ # Used for the Reve::API#map_kills method. If there are no kills it's not listed.
+ # Attributes
+ # * system_id ( Fixnum ) - ID of the System
+ # * ship_kills ( Fixnum ) - Number of ships killed
+ # * faction_kills ( Fixnum ) - Number of faction ships killed (NPC Pirates)
+ # * pod_kills ( Fixnum ) - Number of podkills
+ # See also Reve::API#map_kills, MapJump
+ class MapKill
+ attr_reader :system_id, :ship_kills, :faction_kills, :pod_kills
+ def initialize(elem) #:nodoc:
+ @system_id = elem['solarSystemID'].to_i
+ @ship_kills = elem['shipKills'].to_i
+ @faction_kills = elem['factionKills'].to_i
+ @pod_kills = elem['podKills'].to_i
+ end
+ end
+
+ # Holds the result of the Reve::API#member_tracking call for big brother.
+ # * character_id ( Fixnum ) - ID of the Character
+ # * character_name ( String ) - Name of the Character
+ # * start_time ( Time ) - When the Character joined the Corporation
+ # * base_id ( Fixnum ) - ID of the Station (Starbase too?) where the Character calls home
+ # * base ( String ) - Name of the Station (Starbase?) where the Character calls home
+ # * title ( String ) - Title of the Character
+ # * logon_time ( Time | NilClass ) - When the Character last logged on (or nil for non-CEOs)
+ # * logoff_time ( Time | NilClass ) - When the Character last logged off (or nil for non-CEOs)
+ # * location_id ( Fixnum ) - ID of the Station (Starbase too?) where the Character last/currently is
+ # * location ( String ) - Name of the Station (Starbase?) where the Character last/currently is
+ # * ship_type_id ( Fixnum ) - Type ID of the ship the Character is flying. (Refer to CCP database dump invtypes)
+ # * ship_type ( String ) - Name of the type of ship the Character is flying
+ # * roles ( String ) - List of roles for the Character
+ # * grantable_roles ( String ) - List of grantable roles for the Character
+ # See Also: Reve::API#member_tracking
+ class MemberTracking
+ attr_reader :character_id, :character_name, :start_time, :base_id, :base, :title, :logon_time, :logoff_time,
+ :location_id, :location, :ship_type_id, :ship_type, :roles, :grantable_roles
+ def initialize(elem) #:nodoc:
+ @character_id = elem['characterID'].to_i
+ @character_name = elem['name']
+ @start_time = elem['startDateTime'].to_time
+ @base_id = elem['baseID'].to_i
+ @base = elem['base']
+ @title = elem['title']
+ @logon_time = elem['logonDateTime'].to_time rescue nil # can be nil for non CEOs
+ @logoff_time = elem['logoffDateTime'].to_time rescue nil # Can be nil for non CEOs
+ @location_id = elem['locationID']
+ @location = elem['location']
+ @ship_type_id = elem['shipTypeID'].to_i
+ @ship_type = elem['shipType']
+ @roles = elem['roles']
+ @grantable_roles = elem['grantableRoles']
+ end
+ end
+
+ # Represents Reve::API#ref_types return. Used in WalletTransaction and WalletJournal, among others to qualify the "type" of the entry
+ # Attributes
+ # * id ( Fixnum ) - CCP's ID for the RefType
+ # * name ( String ) - CCP's name for the RefType
+ # See Also: Reve::API#ref_types, WalletJournal, WalletTransaction
+ class RefType
+ attr_reader :id, :name
+ def initialize(elem) #:nodoc:
+ @id = elem['refTypeID'].to_i
+ @name = elem['refTypeName']
+ end
+ end
+
+ # A Skill is used in the CharacterSheet for Reve::API#character_sheet call.
+ # Attributes
+ # * id ( Fixnum ) - Type ID of the Skill. (Refer to CCP database dump invtypes)
+ # * skillpoints ( Fixnum ) - Number of skill points invested in this skill
+ # * level ( Fixnum ) - Level of the Skill
+ # See Also: CharacterSheet, Reve::API#character_sheet
+ class Skill
+ attr_accessor :id, :unpublished, :skillpoints, :level
+ def initialize(elem) #:nodoc:
+ @id = elem['typeID'].to_i
+ @skillpoints = elem['skillpoints'].to_i
+ @level = elem['level'].to_i
+ end
+ end
+
+ # A SkillBonus, for SkillTree and Reve::API#skill_tree.
+ # Bear in mind that "SkillBonus" doesn't always mean anything useful or beneficial
+ # * type ( String ) - Name of the bonus
+ # * value ( String ) - Value of the bonus. This is may be Fixnum or Float or Boolean but is left as a String
+ # See Also: SkillTree, Reve::API#skill_tree
+ class SkillBonus
+ attr_reader :type, :value
+ def initialize(elem) #:nodoc:
+ @type = elem['bonusType']
+ @value = elem['bonusValue']
+ end
+ end
+
+ # A SkillRequirement, for SkillTree and Reve::API#skill_tree
+ # Attributes
+ # * type_id ( Fixnum ) - ID of the Skill that is the SkillRequirement (Refer to CCP database dump invtypes)
+ # * level ( Fixnum ) - What level of the Skill is required
+ # See Also: SkillTree, Reve::API#skill_tree
+ class SkillRequirement
+ attr_reader :type_id, :level
+ alias_method :id, :type_id
+ def initialize(elem)
+ @type_id = elem['typeID'].to_i
+ @level = elem['skillLevel'].to_i
+ end
+ end
+
+ # Holds the result of the Reve::API#skill_tree call. Currently this is not
+ # nested based on group_id in each individual skill.
+ # Attributes
+ # * name ( String ) - Name of a Skill
+ # * type_id ( Fixnum ) - ID of the Skill (Refer to CCP database dump invtypes)
+ # * group_id ( Fixnum ) - Group ID of the Skill (Refer to CCP database dump invgroups)
+ # * description ( Skill ) - Description of the Skill
+ # * rank ( Fixnum ) - Rank of the skill
+ # * attribs ( [RequiredAttribute] ) - Two-element array with the PrimaryAttribute and SecondaryAttribute for the Skill
+ # * skills ( [SkillTree] ) - Nested Skills under this group. NOT USED
+ # * bonuses ( [SkillBonus] ) - Bonuses given by this Skill
+ # See Also: SkillBonus, RequiredAttribute, Reve::API#skill_tree
+ class SkillTree
+ attr_reader :name, :type_id, :group_id, :description, :rank, :attribs, :required_skills, :bonuses
+ def initialize(name, typeid, groupid, desc, rank, attribs = [], skills = [], bonuses = []) #:nodoc:
+ @name = name
+ @type_id = typeid.to_i
+ @group_id = groupid.to_i
+ @rank = rank.to_i
+ @attribs = attribs
+ @required_skills = skills
+ @bonuses = bonuses
+ # turn multiline literals (embedded \n and lot of white space) into one
+ # line!
+ @description = desc.split(/\n/).collect { |s| s.strip }.join(' ')
+ end
+ end
+
+ # Holds the result of the Reve::API#skill_in_training call.
+ # Note: When a Character finishes training the API will not be updated until the Character next logs into the game.
+ # Attributes
+ # * tranquility_time ( Time ) - The current time on Tranquility
+ # * end_time ( Time ) - When the Skill is due to end
+ # * start_time ( Time ) - When the Skill training was started
+ # * type_id ( Fixnum ) - ID of the Skill (Refer to CCP database dump invtypes)
+ # * start_sp ( Fixnum ) - How many SP did the Character have before training was started
+ # * end_sp ( Fixnum ) - How many SP will the Character have after training finishes
+ # * to_level ( Fixnum ) - This is the level the Skill will be at when training is completed
+ # * skill_in_training ( Boolean ) - Is there actually a skill in training? (Check this first before doing anything)
+ # See Also: CharacterSheet, Reve::API#skill_in_training
+ class SkillInTraining
+ attr_reader :tranquility_time, :end_time, :start_time, :type_id, :start_sp, :end_sp, :to_level, :skill_in_training
+ def initialize(elem) #:nodoc:
+ @tranquility_time = elem['currentTQTime'].to_time
+ @end_time = elem['trainingEndTime'].to_time
+ @start_time = elem['trainingStartTime'].to_time
+ @type_id = elem['trainingTypeID'].to_i
+ @start_sp = elem['trainingStartSP'].to_i
+ @end_sp = elem['trainingDestinationSP'].to_i
+ @to_level = elem['trainingToLevel'].to_i
+ @skill_in_training= elem['skillInTraining'] == '1'
+ end
+ end