reve 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/reve.rb +150 -254
- data/lib/reve/classes.rb +199 -131
- data/test/test_reve.rb +98 -29
- data/test/xml/mail_messages.xml +9 -9
- metadata +162 -47
checksums.yaml
ADDED
@@ -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
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/lib/reve.rb
CHANGED
@@ -11,7 +11,7 @@ rescue LoadError
|
|
11
11
|
require 'rubygems'
|
12
12
|
require 'hpricot'
|
13
13
|
end
|
14
|
-
require 'net/
|
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
|
50
|
-
@@
|
51
|
-
@@
|
52
|
-
@@
|
53
|
-
@@
|
54
|
-
@@
|
55
|
-
@@
|
56
|
-
@@
|
57
|
-
@@
|
58
|
-
@@
|
59
|
-
@@
|
60
|
-
|
61
|
-
@@
|
62
|
-
@@
|
63
|
-
@@
|
64
|
-
@@
|
65
|
-
|
66
|
-
@@
|
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
|
-
|
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
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
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
|