reve 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f791f5b67b627b79b4791339bc3c693b28822e4
4
+ data.tar.gz: d7f8b73f32992bd46f360df441ed714491b7f112
5
+ SHA512:
6
+ metadata.gz: 053385d07e36ef01a9b16a467609def1fa136750703f066b36dc20c9b4de83c6cb1b361b9d05fa3234c88f463a3bb049e3b607d07e83f2d7d498f9a182a25794
7
+ data.tar.gz: d30853a03669ea1f8be250015fccfee75e1722593666a1eb684e1e4e2ede7cc23e2dea2f8ed6613abfb04444079f9f6801cebf974bac7ee5ce7d04c0f4189fd4
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
- require 'rake/rdoctask'
3
+ require 'rdoc/task'
4
4
 
5
5
  task :default => :redoc
6
6
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.3
@@ -11,7 +11,7 @@ rescue LoadError
11
11
  require 'rubygems'
12
12
  require 'hpricot'
13
13
  end
14
- require 'net/http'
14
+ require 'net/https'
15
15
  require 'uri'
16
16
  require 'cgi'
17
17
  require 'digest'
@@ -23,6 +23,7 @@ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) ||
23
23
  require 'reve/exceptions'
24
24
  require 'reve/extensions'
25
25
  require 'reve/classes'
26
+ require 'reve/processing_helpers'
26
27
 
27
28
 
28
29
  module Reve
@@ -45,58 +46,67 @@ module Reve
45
46
  # All API methods have the functionality to read XML from an arbitrary location. This could be another webserver, or a XML file on disk.
46
47
  # 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.
47
48
  class API
49
+ BASE_URL = 'https://api.eveonline.com'
50
+
51
+ @@characters_url = BASE_URL + '/account/Characters.xml.aspx'
52
+ @@account_status_url = BASE_URL + '/account/AccountStatus.xml.aspx'
53
+
54
+ @@research_url = BASE_URL + '/char/Research.xml.aspx'
55
+ @@contracts_url = BASE_URL + '/char/Contracts.xml.aspx'
56
+ @@personal_notification_url = BASE_URL + '/char/Notifications.xml.aspx'
57
+ @@personal_mailing_lists_url = BASE_URL + '/char/mailinglists.xml.aspx'
58
+ @@personal_mail_messages_url = BASE_URL + '/char/MailMessages.xml.aspx'
59
+ @@personal_mail_message_bodies_url= BASE_URL + '/char/MailBodies.xml.aspx'
60
+ @@personal_contacts_url = BASE_URL + '/char/ContactList.xml.aspx'
61
+ @@personal_wallet_balance_url = BASE_URL + '/char/AccountBalance.xml.aspx'
62
+ @@personal_wallet_trans_url = BASE_URL + '/char/WalletTransactions.xml.aspx'
63
+ @@personal_wallet_journal_url = BASE_URL + '/char/WalletJournal.xml.aspx'
64
+ @@training_skill_url = BASE_URL + '/char/SkillInTraining.xml.aspx'
65
+ @@skill_queue_url = BASE_URL + '/char/SkillQueue.xml.aspx'
66
+ @@character_sheet_url = BASE_URL + '/char/CharacterSheet.xml.aspx'
67
+ @@personal_market_orders_url = BASE_URL + '/char/MarketOrders.xml.aspx'
68
+ @@personal_industry_jobs_url = BASE_URL + '/char/IndustryJobs.xml.aspx'
69
+ @@personal_assets_url = BASE_URL + '/char/AssetList.xml.aspx'
70
+ @@personal_kills_url = BASE_URL + '/char/KillLog.xml.aspx'
71
+ @@personal_faction_war_stats_url = BASE_URL + '/char/FacWarStats.xml.aspx'
72
+ @@character_medals_url = BASE_URL + '/char/Medals.xml.aspx'
73
+ @@upcoming_calendar_events_url = BASE_URL + '/char/UpcomingCalendarEvents.xml.aspx'
74
+
75
+ @@member_tracking_url = BASE_URL + '/corp/MemberTracking.xml.aspx'
76
+ @@corporate_wallet_balance_url = BASE_URL + '/corp/AccountBalance.xml.aspx'
77
+ @@corporate_wallet_trans_url = BASE_URL + '/corp/WalletTransactions.xml.aspx'
78
+ @@corporate_wallet_journal_url = BASE_URL + '/corp/WalletJournal.xml.aspx'
79
+ @@starbases_url = BASE_URL + '/corp/StarbaseList.xml.aspx'
80
+ @@starbasedetail_url = BASE_URL + '/corp/StarbaseDetail.xml.aspx'
81
+ @@corporation_sheet_url = BASE_URL + '/corp/CorporationSheet.xml.aspx'
82
+ @@corporation_member_security_url = BASE_URL + '/corp/MemberSecurity.xml.aspx'
83
+ @@corporate_market_orders_url = BASE_URL + '/corp/MarketOrders.xml.aspx'
84
+ @@corporate_industry_jobs_url = BASE_URL + '/corp/IndustryJobs.xml.aspx'
85
+ @@corporate_assets_url = BASE_URL + '/corp/AssetList.xml.aspx'
86
+ @@corporate_kills_url = BASE_URL + '/corp/KillLog.xml.aspx'
87
+ @@corporate_faction_war_stats_url = BASE_URL + '/corp/FacWarStats.xml.aspx'
88
+ @@corporate_medals_url = BASE_URL + '/corp/Medals.xml.aspx'
89
+ @@corp_member_medals_url = BASE_URL + '/corp/MemberMedals.xml.aspx'
90
+ @@corporate_contacts_url = BASE_URL + '/corp/ContactList.xml.aspx'
48
91
 
49
- @@alliances_url = 'http://api.eve-online.com/eve/AllianceList.xml.aspx'
50
- @@sovereignty_url = 'http://api.eve-online.com/map/Sovereignty.xml.aspx'
51
- @@reftypes_url = 'http://api.eve-online.com/eve/RefTypes.xml.aspx'
52
- @@skill_tree_url = 'http://api.eve-online.com/eve/SkillTree.xml.aspx'
53
- @@member_tracking_url = 'http://api.eve-online.com/corp/MemberTracking.xml.aspx'
54
- @@corporate_wallet_balance_url = 'http://api.eve-online.com/corp/AccountBalance.xml.aspx'
55
- @@personal_wallet_balance_url = 'http://api.eve-online.com/char/AccountBalance.xml.aspx'
56
- @@corporate_wallet_trans_url = 'http://api.eve-online.com/corp/WalletTransactions.xml.aspx'
57
- @@personal_wallet_trans_url = 'http://api.eve-online.com/char/WalletTransactions.xml.aspx'
58
- @@corporate_wallet_journal_url = 'http://api.eve-online.com/corp/WalletJournal.xml.aspx'
59
- @@personal_wallet_journal_url = 'http://api.eve-online.com/char/WalletJournal.xml.aspx'
60
- @@characters_url = 'http://api.eve-online.com/account/Characters.xml.aspx'
61
- @@training_skill_url = 'http://api.eve-online.com/char/SkillInTraining.xml.aspx'
62
- @@skill_queue_url = 'http://api.eve-online.com/char/SkillQueue.xml.aspx'
63
- @@character_sheet_url = 'http://api.eve-online.com/char/CharacterSheet.xml.aspx'
64
- @@starbases_url = 'http://api.eve-online.com/corp/StarbaseList.xml.aspx'
65
- @@starbasedetail_url = 'http://api.eve-online.com/corp/StarbaseDetail.xml.aspx'
66
- @@conqurable_outposts_url = 'http://api.eve-online.com/eve/ConquerableStationList.xml.aspx'
67
- @@corporation_sheet_url = 'http://api.eve-online.com/corp/CorporationSheet.xml.aspx'
68
- @@corporation_member_security_url = 'http://api.eve-online.com/corp/MemberSecurity.xml.aspx'
69
- @@errors_url = 'http://api.eve-online.com/eve/ErrorList.xml.aspx'
70
- @@map_jumps_url = 'http://api.eve-online.com/map/Jumps.xml.aspx'
71
- @@map_kills_url = 'http://api.eve-online.com/map/Kills.xml.aspx'
72
- @@personal_market_orders_url = 'http://api.eve-online.com/char/MarketOrders.xml.aspx'
73
- @@corporate_market_orders_url = 'http://api.eve-online.com/corp/MarketOrders.xml.aspx'
74
- @@personal_industry_jobs_url = 'http://api.eve-online.com/char/IndustryJobs.xml.aspx'
75
- @@corporate_industry_jobs_url = 'http://api.eve-online.com/corp/IndustryJobs.xml.aspx'
76
- @@personal_assets_url = 'http://api.eve-online.com/char/AssetList.xml.aspx'
77
- @@corporate_assets_url = 'http://api.eve-online.com/corp/AssetList.xml.aspx'
78
- @@personal_kills_url = 'http://api.eve-online.com/char/KillLog.xml.aspx'
79
- @@corporate_kills_url = 'http://api.eve-online.com/corp/KillLog.xml.aspx'
80
- @@character_id_url = 'http://api.eve-online.com/eve/CharacterID.xml.aspx' # ?names=CCP%20Garthagk
81
- @@character_name_url = 'http://api.eve-online.com/eve/CharacterName.xml.aspx' # ?ids=797400947
82
- @@personal_faction_war_stats_url= 'http://api.eve-online.com/char/FacWarStats.xml.aspx'
83
- @@corporate_faction_war_stats_url= 'http://api.eve-online.com/corp/FacWarStats.xml.aspx'
84
- @@general_faction_war_stats_url= 'http://api.eve-online.com/eve/FacWarStats.xml.aspx'
85
- @@top_faction_war_stats_url = 'http://api.eve-online.com/eve/FacWarTopStats.xml.aspx'
86
- @@faction_war_occupancy_url = 'http://api.eve-online.com/map/FacWarSystems.xml.aspx'
87
- @@certificate_tree_url = 'http://api.eve-online.com/eve/CertificateTree.xml.aspx'
88
- @@character_medals_url = 'http://api.eve-online.com/char/Medals.xml.aspx'
89
- @@corporate_medals_url = 'http://api.eve-online.com/corp/Medals.xml.aspx'
90
- @@corp_member_medals_url = 'http://api.eve-online.com/corp/MemberMedals.xml.aspx'
91
- @@server_status_url = 'http://api.eve-online.com/Server/ServerStatus.xml.aspx'
92
- @@research_url = 'http://api.eve-online.com/char/Research.xml.aspx'
93
- @@personal_notification_url = 'http://api.eve-online.com/char/Notifications.xml.aspx'
94
- @@personal_mailing_lists_url = 'http://api.eve-online.com/char/mailinglists.xml.aspx'
95
- @@personal_mail_messages_url = 'http://api.eve-online.com/char/MailMessages.xml.aspx'
96
- @@personal_contacts_url = 'http://api.eve-online.com/char/ContactList.xml.aspx'
97
- @@corporate_contacts_url = 'http://api.eve-online.com/corp/ContactList.xml.aspx'
98
- @@account_status_url = 'http://api.eve-online.com/account/AccountStatus.xml.aspx'
99
- @@character_info_url = 'http://api.eve-online.com/eve/CharacterInfo.xml.aspx'
92
+ @@alliances_url = BASE_URL + '/eve/AllianceList.xml.aspx'
93
+ @@reftypes_url = BASE_URL + '/eve/RefTypes.xml.aspx'
94
+ @@skill_tree_url = BASE_URL + '/eve/SkillTree.xml.aspx'
95
+ @@conqurable_outposts_url = BASE_URL + '/eve/ConquerableStationList.xml.aspx'
96
+ @@errors_url = BASE_URL + '/eve/ErrorList.xml.aspx'
97
+ @@character_id_url = BASE_URL + '/eve/CharacterID.xml.aspx' # ?names=CCP%20Garthagk
98
+ @@general_faction_war_stats_url = BASE_URL + '/eve/FacWarStats.xml.aspx'
99
+ @@top_faction_war_stats_url = BASE_URL + '/eve/FacWarTopStats.xml.aspx'
100
+ @@certificate_tree_url = BASE_URL + '/eve/CertificateTree.xml.aspx'
101
+ @@character_name_url = BASE_URL + '/eve/CharacterName.xml.aspx' # ?ids=797400947
102
+ @@character_info_url = BASE_URL + '/eve/CharacterInfo.xml.aspx'
103
+
104
+ @@sovereignty_url = BASE_URL + '/map/Sovereignty.xml.aspx'
105
+ @@map_jumps_url = BASE_URL + '/map/Jumps.xml.aspx'
106
+ @@map_kills_url = BASE_URL + '/map/Kills.xml.aspx'
107
+ @@faction_war_occupancy_url = BASE_URL + '/map/FacWarSystems.xml.aspx'
108
+
109
+ @@server_status_url = BASE_URL + '/Server/ServerStatus.xml.aspx'
100
110
 
101
111
  cattr_accessor :character_sheet_url, :training_skill_url, :characters_url, :personal_wallet_journal_url,
102
112
  :corporate_wallet_journal_url, :personal_wallet_trans_url, :corporate_wallet_trans_url,
@@ -111,15 +121,14 @@ module Reve
111
121
  :certificate_tree_url, :character_medals_url, :corporate_medals_url,
112
122
  :corp_member_medals_url, :server_status_url, :skill_queue_url, :corporation_member_security_url,
113
123
  :personal_notification_url, :personal_mailing_lists_url, :personal_mail_messages_url,
114
- :research_url, :personal_contacts_url, :corporate_contacts_url,
115
- :account_status_url, :character_info_url
116
-
124
+ :personal_mail_message_bodies_url, :research_url, :personal_contacts_url, :corporate_contacts_url,
125
+ :account_status_url, :character_info_url, :upcoming_calendar_events_url
117
126
 
118
127
  attr_accessor :key, :keyid, :cak, :charid
119
128
  alias :userid :keyid
120
129
  alias :userid= :keyid=
121
130
  attr_accessor :http_user_agent, :save_path, :timeout
122
- attr_reader :current_time, :cached_until, :last_hash, :reve_version
131
+ attr_reader :current_time, :cached_until, :last_hash, :last_xml, :reve_version
123
132
 
124
133
  # Create a new API instance.
125
134
  # current_time and cached_until are meaningful only for the LAST call made.
@@ -145,6 +154,7 @@ module Reve
145
154
  @current_time = nil
146
155
  @cached_until = nil
147
156
  @last_hash = nil
157
+ @last_xml = nil
148
158
  @reve_version = File.read(File.join(File.dirname(__FILE__),'../','VERSION')).chomp
149
159
  @http_user_agent = "Reve v#{@reve_version}; http://github.com/lisa/reve"
150
160
  end
@@ -196,14 +206,24 @@ module Reve
196
206
  # Expects a Hash as a parameter with these keys:
197
207
  # * ids ( Array ) - An Array of Character IDs to fetch the names of.
198
208
  # See Also: character_name, Reve::Classes::Character, character_sheet
199
- def character_name(opts = {})
209
+
210
+ def ids_to_names(opts = {})
200
211
  ids = opts[:ids] || []
201
- return [] if ids.empty?
212
+ return [] if ids.empty? #No ids where passed
202
213
  opts[:ids] = ids.join(',')
203
- compute_hash( opts.merge(:url => @@character_name_url) ) ||
204
- process_query(Reve::Classes::Character,opts[:url] || @@character_name_url,false,opts)
205
- end
206
-
214
+ args = postfields(opts)
215
+ h = compute_hash( opts.merge(:url => @@character_name_url) )
216
+ return h if h
217
+ xml = process_query(nil,opts[:url] || @@character_name_url, true,opts)
218
+ ret = []
219
+ xml.search("//rowset/row").each do |elem|
220
+ ret << Reve::Classes::Character.new(elem)
221
+ end
222
+ ret
223
+ end
224
+
225
+ alias_method :character_name, :ids_to_names
226
+
207
227
  # Return a list of Alliances and member Corporations from
208
228
  # http://api.eve-online.com/eve/AllianceList.xml.aspx
209
229
  # Use the corporation_sheet method to get information for each member
@@ -394,6 +414,20 @@ module Reve
394
414
  process_query(Reve::Classes::Research,opts[:url] || @@research_url,false,args)
395
415
  end
396
416
 
417
+ #
418
+ #gets contracts
419
+ # http://api.eve-online/char/Contracts.xml.aspx
420
+ # * characterid ( Integer | String ) - Get stats for this Character
421
+ # See also: Reve::Classes::Contract
422
+
423
+ def contracts(opts = { :characterid => nil })
424
+ args = postfields(opts)
425
+ h = compute_hash(args.merge(:url => @@contracts_url))
426
+ return h if h
427
+ process_query(Reve::Classes::Contracts,opts[:url] || @@contracts_url,false,args)
428
+ end
429
+
430
+
397
431
  # Gets one's own personal WalletBalance from
398
432
  # http://api.eve-online.com/char/AccountBalance.xml.aspx
399
433
  # Expects:
@@ -953,12 +987,63 @@ module Reve
953
987
  # * characterid ( Integer | String ) - Get the MailMessages for this Character
954
988
  # See also: Reve::Classes::MailMessage
955
989
  def personal_mail_messages(opts = { :characterid => nil })
990
+ with_bodies = opts.include?(:with_bodies) ? opts.delete(:with_bodies) : false
956
991
  args = postfields(opts)
957
992
  h = compute_hash(args.merge(:url => @@personal_mail_messages_url))
958
993
  return h if h
959
- process_query(Reve::Classes::MailMessage, opts[:url] || @@personal_mail_messages_url,false,args)
994
+ messages = process_query(Reve::Classes::MailMessage, opts[:url] || @@personal_mail_messages_url,false,args)
995
+ if with_bodies
996
+ ids = messages.collect{|m| m.id }
997
+ bodies = personal_mail_message_bodies(:ids => ids)
998
+ messages.each do |msg|
999
+ # For now we are ignoring messages that come back saying
1000
+ # body is missing. So use fetch to assign body to message
1001
+ msg.body = bodies.fetch(msg.id.to_s, nil)
1002
+ end
1003
+ end
1004
+ messages
1005
+ end
1006
+
1007
+ # Gets the bodies for mail messages. NB this API call does not
1008
+ # return objects. It returns a hash with messageID strings as the keys -
1009
+ # suitable for merging into a Reve::Classes::MailMessage object
1010
+ #
1011
+ # Note from the Eve API docs:
1012
+ # Bodies cannot be accessed if you have not called for their headers recently.
1013
+ #
1014
+ # Expects:
1015
+ # * ids ( List of Integers ) - List of message ids for which we want bodies
1016
+ # See also: Reve::Classes::MailMessage
1017
+ def personal_mail_message_bodies(opts = { :ids => [] })
1018
+ args = postfields(opts)
1019
+ h = compute_hash(args.merge(:url => @@personal_mail_message_bodies_url))
1020
+ return h if h
1021
+ just_xml = true
1022
+ xml = process_query(Reve::Classes::MailMessage, opts[:url] || @@personal_mail_message_bodies_url,just_xml,args)
1023
+ results = {}
1024
+ xml.search("//rowset/row").each do |el|
1025
+ results[el.attributes['messageID']] = el.inner_text
1026
+ end
1027
+ results
1028
+ end
1029
+
1030
+
1031
+
1032
+
1033
+ #Gets upcoming calendar events
1034
+ #Reve::Classes::UpcomingCalendarEvents
1035
+ def upcoming_calendar_events(opts = { :characterid => nil })
1036
+ args = postfields(opts)
1037
+ h = compute_hash(args.merge(:url => @@upcoming_calendar_events_url))
1038
+ return h if h
1039
+ process_query(Reve::Classes::UpcomingCalendarEvents, opts[:url] || @@upcoming_calendar_events_url,false,args)
960
1040
  end
961
1041
 
1042
+
1043
+
1044
+
1045
+
1046
+
962
1047
  # Gets the status of the selected account. Returns
963
1048
  # Reve::Classes::AccountStatus
964
1049
  def account_status(opts = {})
@@ -979,196 +1064,7 @@ module Reve
979
1064
  Reve::Classes::CharacterInfo.new(xml.search('//result').first)
980
1065
  end
981
1066
 
982
- protected
983
- # Helper method to handle nested assets
984
- def recur_through_assets(rows)
985
- assets = []
986
- rows.each do |container|
987
- unless container.empty?
988
- asset_container = Reve::Classes::AssetContainer.new(container)
989
- asset_container.assets = self.recur_through_assets(container.search("/rowset/row"))
990
- assets << asset_container
991
- else
992
- assets << Reve::Classes::Asset.new(container)
993
- end
994
- end
995
- assets
996
- end
997
-
998
- # Sets up the post fields for Net::HTTP::Get hash for process_query method.
999
- # See also format_url_request
1000
- # TODO: Consider moving this whole thing into process_query to avoid
1001
- # calling this in every method!
1002
- def postfields(opts = {})
1003
- baseargs = { :characterid => @charid }
1004
- if @cak
1005
- baseargs[:keyid] = @keyid
1006
- baseargs[:vcode] = @key
1007
- else
1008
- baseargs[:userid] = @keyid
1009
- baseargs[:apikey] = @key
1010
- end
1011
- ret = opts.clone
1012
- baseargs.each do |k,v|
1013
- if ret[k].nil?
1014
- ret[k] = v
1015
- end
1016
- end
1017
- ret.inject({}) do |n, (k,v)|
1018
- n[k.downcase] = v.to_s if v
1019
- n
1020
- end
1021
- end
1022
-
1023
- # Creates a hash for some hash of postfields. For each API method pass
1024
- # :just_hash => to something to return a hash that can be matched to
1025
- # the last_hash instance method created in process_query.
1026
- # This method is called in each API method before process_query and if
1027
- # :just_hash was passed in args then a String will be returned, otherwise
1028
- # nil will be returned
1029
- # TODO: Consider moving this whole thing into process_query before the URI parsing
1030
- def compute_hash(args = {})
1031
- args.stringify_keys!
1032
- return nil unless args.include?('just_hash')
1033
- args.delete('just_hash')
1034
- url = args['url'].kind_of?(URI) ? args['url'].path : args['url']
1035
- args.delete('url')
1036
- spl = url.split '/'
1037
- ret = (spl[-2] + '/' + spl[-1]) + ':'
1038
- args.delete_if { |k,v| (v || "").to_s.length == 0 } # Delete keys if the value is nil
1039
- h = args.stringify_keys
1040
- ret += h.sort.flatten.collect{ |e| e.to_s }.join(':')
1041
- ret.gsub(/:$/,'')
1042
- end
1043
-
1044
- # Processes a URL and for simple <rowset><row /><row /></rowset> results
1045
- # create an array of objects of type klass. Or just return the XML if
1046
- # just_xml is set true. args is from postfields
1047
- # This method will call check_exception to see if an Exception came from
1048
- # CCP.
1049
- # Expects:
1050
- # * klass ( Class ) - The class container for parsing. An array of these is returned in default behaviour.
1051
- # * url ( String ) - API URL
1052
- # * just_xml ( Boolean ) - Return only the XML and not attempt to parse //rowset/row. Useful if the XML is not in that form.
1053
- # * args ( Hash ) - Hash of arguments for the request. See postfields method.
1054
- def process_query(klass, url, just_xml = false, opts = {})
1055
-
1056
- #args = postfields(opts)
1057
- #h = compute_hash(args.merge(:url => url))
1058
- #return h if h
1059
-
1060
- @last_hash = compute_hash(opts.merge({:url => url, :just_hash => true })) # compute hash
1061
-
1062
-
1063
- xml = check_exception(get_xml(url,opts))
1064
- save_xml(xml) if @save_path
1065
-
1066
- return xml if just_xml
1067
- return [] if xml.nil? # No XML document returned. We should panic.
1068
-
1069
- # Create the array of klass objects to return, assume we start with an empty set from the XML search for rows
1070
- # and build from there.
1071
- xml.search("//rowset/row").inject([]) { |ret,elem| ret << klass.new(elem) }
1072
- end
1073
-
1074
- # Turns a hash into ?var=baz&bam=boo
1075
- def format_url_request(opts)
1076
- req = "?"
1077
-
1078
- opts.stringify_keys!
1079
- opts.keys.sort.each do |key|
1080
- req += "#{CGI.escape(key.to_s)}=#{CGI.escape(opts[key].to_s)}&" if opts[key]
1081
- end
1082
- req.chop # We are lazy and append a & to each pair even if it's the last one. FIXME: Don't do this.
1083
- end
1084
-
1085
-
1086
- # Gets the XML from a source.
1087
- # Expects:
1088
- # * 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.
1089
- # * opts ( Hash ) - Hash of parameters for the request, such as keyid, vcode and such.
1090
- # NOTE: To override the lowercase http -> URI rule make the HTTP part uppercase.
1091
- def get_xml(source,opts)
1092
- xml = ""
1093
-
1094
- # Let people still pass Strings starting with http.
1095
- if source =~ /^http/
1096
- source = URI.parse(source)
1097
- end
1098
-
1099
- if source.kind_of?(URI)
1100
- opts.merge({ :version => 2, :url => nil }) #the uri bit will now ignored in format_url_request
1101
- req_args = format_url_request(opts)
1102
- req = Net::HTTP::Get.new(source.path + req_args)
1103
- req['User-Agent'] = @http_referer_agent || "Reve v#{@reve_version}; http://github.com/lisa/reve"
1104
-
1105
- res = nil
1106
- response = nil
1107
- 1.upto(@max_tries) do |try|
1108
- begin
1109
- # ||= to prevent making a new Net::HTTP object, the res = nil above should reset this for the next request.
1110
- # the request needs to be here to rescue exceptions from it.
1111
- http ||= Net::HTTP.new(source.host, source.port)
1112
- http.open_timeout = 3
1113
- http.read_timeout = @timeout
1114
- res = http.start {|http| http.request(req) }
1115
- case res
1116
- when Net::HTTPSuccess, Net::HTTPRedirection
1117
- response = res.body
1118
- end
1119
- rescue Exception
1120
- sleep 5
1121
- next
1122
- end
1123
- break if response
1124
- end
1125
- raise Reve::Exceptions::ReveNetworkStatusException.new( (res.body rescue "No Response Body!") ) unless response
1126
-
1127
- xml = response
1128
-
1129
- # here ends test for URI
1130
- elsif source.kind_of?(String)
1131
- xml = File.open(source).read
1132
- else
1133
- raise Reve::Exceptions::ReveNetworkStatusException.new("Don't know how to deal with a #{source.class} XML source. I expect a URI or String")
1134
- end
1135
- xml
1136
- end
1137
-
1138
- # Raises the proper exception (if there is one), otherwise it returns the
1139
- # XML response.
1140
- def check_exception(xml)
1141
- x = Hpricot::XML(xml)
1142
- begin
1143
- out = x.search("//error") # If this fails then there are some big problems with Hpricot#search ?
1144
- rescue Exception => e
1145
- $stderr.puts "Fatal error ((#{e.to_s})): Couldn't search the XML document ((#{xml})) for any potential error messages! Is your Hpricot broken?"
1146
- exit 1
1147
- end
1148
- @current_time = (x/:currentTime).inner_html.to_time rescue Time.now.utc # Shouldn't need to rescue this but one never knows
1149
- @cached_until = (x/:cachedUntil).inner_html.to_time rescue nil # Errors aren't always cached
1150
- return x if out.size < 1
1151
- code = out.first['code'].to_i
1152
- str = out.first.inner_html
1153
- Reve::Exceptions.raise_it(code,str)
1154
- end
1155
-
1156
- def save_xml(xml)
1157
- path = build_save_filename
1158
- FileUtils.mkdir_p(File.dirname(path))
1159
- File.open(path,'w') { |f| f.print xml.to_original_html }
1160
- end
1161
- def build_save_filename
1162
- method = caller(3).first.match(/\`(.+)'/)[1] # Get the API method that's being called. This is called from save_xml -> process_query -> :real_method
1163
- File.join(@save_path,@keyid.to_s,method,( @cached_until || Time.now.utc).to_i.to_s + '.xml')
1164
- end
1165
-
1166
- # Returns an array of +klass+
1167
- def pull_out_top_10_data(xml,klass,kind,field)
1168
- xml.search("/eveapi/result/#{kind}/rowset[@name='#{field}']/row").inject([]) do |all,row|
1169
- all << klass.new(row)
1170
- all
1171
- end
1172
- end
1067
+ #protected
1068
+ include ProcessingHelpers
1173
1069
  end
1174
1070
  end