eve_app 0.1.0
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/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +21 -0
- data/app/controllers/eve_app/application_controller.rb +5 -0
- data/app/controllers/eve_app/regions_controller.rb +3 -0
- data/app/controllers/eve_app/simple_resource_controller.rb +38 -0
- data/app/controllers/eve_app/solar_systems_controller.rb +2 -0
- data/app/controllers/eve_app/types_controller.rb +3 -0
- data/app/helpers/eve_app/entity_helper.rb +15 -0
- data/app/helpers/eve_app/output_helper.rb +25 -0
- data/app/models/eve_app/activity.rb +26 -0
- data/app/models/eve_app/activity_material.rb +11 -0
- data/app/models/eve_app/activity_product.rb +8 -0
- data/app/models/eve_app/activity_skill.rb +5 -0
- data/app/models/eve_app/application_record.rb +5 -0
- data/app/models/eve_app/category.rb +27 -0
- data/app/models/eve_app/concerns/activity_relation.rb +26 -0
- data/app/models/eve_app/group.rb +3 -0
- data/app/models/eve_app/market_group.rb +25 -0
- data/app/models/eve_app/region.rb +3 -0
- data/app/models/eve_app/solar_system.rb +14 -0
- data/app/models/eve_app/station.rb +9 -0
- data/app/models/eve_app/type.rb +57 -0
- data/app/serializers/eve_app/application_serializer.rb +2 -0
- data/app/serializers/eve_app/region_serializer.rb +5 -0
- data/app/serializers/eve_app/solar_system_serializer.rb +8 -0
- data/app/serializers/eve_app/type_serializer.rb +11 -0
- data/config/routes.rb +5 -0
- data/lib/eve_app/engine.rb +6 -0
- data/lib/eve_app/eve_central.rb +78 -0
- data/lib/eve_app/item_parser.rb +112 -0
- data/lib/eve_app/sde/data_importer.rb +43 -0
- data/lib/eve_app/sde/downloader.rb +53 -0
- data/lib/eve_app/sde/normalizer.rb +106 -0
- data/lib/eve_app/sde.rb +27 -0
- data/lib/eve_app/version.rb +3 -0
- data/lib/eve_app/xml_api/calls.rb +197 -0
- data/lib/eve_app/xml_api/classes.rb +260 -0
- data/lib/eve_app/xml_api/client.rb +86 -0
- data/lib/eve_app/xml_api.rb +10 -0
- data/lib/eve_app.rb +35 -0
- data/lib/table-list.yml +88 -0
- data/lib/table-map.yml +177 -0
- data/lib/tasks/eve_app.rake +30 -0
- metadata +186 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require "sshkit"
|
2
|
+
|
3
|
+
module EveApp
|
4
|
+
module SDE
|
5
|
+
class DataImporter < SSHKit::Backend::Local
|
6
|
+
include Downloader
|
7
|
+
include Normalizer
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
execute :mkdir, '-p', SDE.config.tmp_path
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def db_config
|
17
|
+
ActiveRecord::Base.connection_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def sql(sql)
|
21
|
+
log "[SQL] #{sql}"
|
22
|
+
db.execute(sql)
|
23
|
+
end
|
24
|
+
|
25
|
+
def db
|
26
|
+
ActiveRecord::Base.connection
|
27
|
+
end
|
28
|
+
|
29
|
+
def table_list
|
30
|
+
@_table_list ||= begin
|
31
|
+
whitelist = Array[SDE.config.table_whitelist].flatten.compact.map(&:to_s)
|
32
|
+
tables = SDE.table_list
|
33
|
+
tables = whitelist.any? ? tables & whitelist : tables
|
34
|
+
Hash[tables.map { |name| [name, normalize_table_name(name)] }]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def normalize_table_name(name)
|
39
|
+
(SDE.config.table_prefix.to_s + name.gsub(/^#{SDE::PREFIXES.join('|')}/, '')).pluralize.underscore
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module EveApp
|
2
|
+
module SDE
|
3
|
+
module Downloader
|
4
|
+
def download
|
5
|
+
within SDE.config.tmp_path do
|
6
|
+
execute :wget, '-q', download_uri + '{,.md5}'
|
7
|
+
verify!
|
8
|
+
execute :bunzip2, SDE.config.archive
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def restore
|
13
|
+
table_list.each do |table_name,normalized_name|
|
14
|
+
sql %Q(DROP TABLE IF EXISTS "#{table_name}")
|
15
|
+
sql %Q(DROP TABLE IF EXISTS "#{normalized_name}")
|
16
|
+
end
|
17
|
+
|
18
|
+
options = ['-x -O']
|
19
|
+
options << "-h #{db_config[:host]}" if db_config[:host]
|
20
|
+
options << "-U #{db_config[:username]}" if db_config[:username]
|
21
|
+
options << "-d #{db_config[:database]}"
|
22
|
+
options += table_list.keys.map { |name| "-t #{name}" }
|
23
|
+
options << local_archive.gsub('.bz2', '')
|
24
|
+
|
25
|
+
execute :pg_restore, *options
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def local_archive
|
31
|
+
@_local_archive ||= [SDE.config.tmp_path, SDE.config.archive].join('/')
|
32
|
+
end
|
33
|
+
|
34
|
+
def download_uri
|
35
|
+
@_download_url ||= begin
|
36
|
+
uri = URI(SDE.config.download_host)
|
37
|
+
uri.path = [uri.path, SDE.config.archive].join('/')
|
38
|
+
uri.to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def verify!
|
43
|
+
md5 = capture :md5, '-q', local_archive
|
44
|
+
md5_file = local_archive + '.md5'
|
45
|
+
if md5 == open(md5_file).read.split(' ').first
|
46
|
+
execute :rm, '-f', md5_file
|
47
|
+
else
|
48
|
+
raise "Downloaded data dump is invalid (MD5 hash verification failed)"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module EveApp
|
2
|
+
module SDE
|
3
|
+
module Normalizer
|
4
|
+
def normalize
|
5
|
+
table_names
|
6
|
+
column_names
|
7
|
+
missing_relations
|
8
|
+
indexes
|
9
|
+
end
|
10
|
+
|
11
|
+
def table_names
|
12
|
+
table_list.each do |table_name, normalized_name|
|
13
|
+
sql %Q(ALTER TABLE IF EXISTS "#{table_name}" RENAME TO "#{normalized_name}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def column_names
|
18
|
+
columns.each do |row|
|
19
|
+
resource_name = row[:table_name].singularize.gsub('eve_', '')
|
20
|
+
row[:target_column_name] = row[:column_name].underscore
|
21
|
+
if row[:target_column_name].starts_with?(resource_name)
|
22
|
+
row[:target_column_name] = row[:target_column_name].gsub("#{resource_name}_", "")
|
23
|
+
end
|
24
|
+
|
25
|
+
if row[:column_name] != row[:target_column_name]
|
26
|
+
sql %Q(ALTER TABLE "#{row[:table_name]}" RENAME COLUMN "#{row[:column_name]}" TO "#{row[:target_column_name]}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def indexes
|
32
|
+
columns.each do |row|
|
33
|
+
if (row[:column_name].ends_with?('id') || row[:column_name] == 'name') && !has_index?(db, row[:table_name], row[:column_name])
|
34
|
+
sql %Q(CREATE INDEX IF NOT EXISTS idx_#{row[:table_name]}_#{row[:column_name]} ON #{row[:table_name]} (#{row[:column_name]});)
|
35
|
+
end
|
36
|
+
if row[:column_name] == 'id'
|
37
|
+
sql %Q(ALTER TABLE #{row[:table_name]} DROP CONSTRAINT IF EXISTS #{row[:table_name]}_pkey)
|
38
|
+
|
39
|
+
if complex_id_index?(row[:table_name])
|
40
|
+
sql %Q(ALTER TABLE #{row[:table_name]} ADD PRIMARY KEY (id, type_id))
|
41
|
+
else
|
42
|
+
sql %Q(ALTER TABLE #{row[:table_name]} ADD PRIMARY KEY (id))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def missing_relations
|
49
|
+
sql %Q(ALTER TABLE #{table_list['invTypes']} ADD IF NOT EXISTS category_id integer)
|
50
|
+
sql %Q(ALTER TABLE #{table_list['invMarketGroups']} ADD root_group_id INTEGER DEFAULT NULL)
|
51
|
+
sql %Q(ALTER TABLE #{table_list['invTypes']} ADD market_group_root_id integer)
|
52
|
+
sql %Q(UPDATE #{table_list['invTypes']} SET category_id = (SELECT category_id FROM #{table_list['invGroups']} WHERE id = #{table_list['invTypes']}.group_id))
|
53
|
+
sql %Q(
|
54
|
+
WITH RECURSIVE mg_roots(id, root_id) AS (
|
55
|
+
SELECT mg.id, mg.id AS root_id FROM #{table_list['invMarketGroups']} AS mg WHERE mg.parent_group_id IS NULL
|
56
|
+
UNION ALL
|
57
|
+
SELECT c.id, p.root_id FROM mg_roots AS p, #{table_list['invMarketGroups']} AS c WHERE c.parent_group_id = p.id
|
58
|
+
)
|
59
|
+
UPDATE #{table_list['invMarketGroups']} SET root_group_id = mg_roots.root_id FROM (
|
60
|
+
SELECT id, root_id FROM mg_roots WHERE root_id != id
|
61
|
+
) AS mg_roots WHERE #{table_list['invMarketGroups']}.id = mg_roots.id;
|
62
|
+
)
|
63
|
+
sql %Q(UPDATE #{table_list['invTypes']} SET market_group_root_id = (SELECT root_group_id FROM #{table_list['invMarketGroups']} WHERE id = #{table_list['invTypes']}.market_group_id))
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def complex_id_index?(table_name)
|
69
|
+
SDE::ID_TYPE_INDEX.include?(table_name.gsub("#{SDE.config.table_prefix.to_s}_", ''))
|
70
|
+
end
|
71
|
+
|
72
|
+
def columns
|
73
|
+
query = %Q(
|
74
|
+
SELECT table_name, column_name, ordinal_position
|
75
|
+
FROM information_schema.columns
|
76
|
+
WHERE
|
77
|
+
table_catalog = '#{db_config[:database]}' AND
|
78
|
+
table_schema = 'public' AND
|
79
|
+
table_name IN(#{table_list.values.map { |n| "'#{n}'" }.join(', ')})
|
80
|
+
)
|
81
|
+
db.select_all(query).map(&:symbolize_keys)
|
82
|
+
end
|
83
|
+
|
84
|
+
def has_index?(db, table, column)
|
85
|
+
count = db.select_value %Q(
|
86
|
+
select
|
87
|
+
COUNT(*)
|
88
|
+
from
|
89
|
+
pg_class t,
|
90
|
+
pg_class i,
|
91
|
+
pg_index ix,
|
92
|
+
pg_attribute a
|
93
|
+
where
|
94
|
+
t.oid = ix.indrelid
|
95
|
+
and i.oid = ix.indexrelid
|
96
|
+
and a.attrelid = t.oid
|
97
|
+
and a.attnum = ANY(ix.indkey)
|
98
|
+
and t.relkind = 'r'
|
99
|
+
and t.relname = '#{table}'
|
100
|
+
and a.attname = '#{column}';
|
101
|
+
)
|
102
|
+
count.to_i > 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/eve_app/sde.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module EveApp
|
2
|
+
module SDE
|
3
|
+
autoload :DataImporter, 'eve_app/sde/data_importer'
|
4
|
+
autoload :Downloader, 'eve_app/sde/downloader'
|
5
|
+
autoload :Normalizer, 'eve_app/sde/normalizer'
|
6
|
+
|
7
|
+
DEFAULT_CONFIG = {
|
8
|
+
table_prefix: :eve,
|
9
|
+
download_host: 'https://www.fuzzwork.co.uk/dump',
|
10
|
+
archive: 'postgres-latest.dmp.bz2',
|
11
|
+
tmp_path: Rails.root.join('tmp', 'eve-sde'),
|
12
|
+
table_list_file: EveApp.root.join('lib', 'table-list.yml')
|
13
|
+
}
|
14
|
+
PREFIXES = %w(agt dgm map trn inv sta industry)
|
15
|
+
ID_TYPE_INDEX = %w(activities)
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def config
|
19
|
+
@_config ||= OpenStruct.new(DEFAULT_CONFIG)
|
20
|
+
end
|
21
|
+
|
22
|
+
def table_list
|
23
|
+
@_table_list ||= YAML::load_file(config.table_list_file)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module EveApp
|
2
|
+
module XmlApi
|
3
|
+
class Calls
|
4
|
+
class Base
|
5
|
+
class_attribute :endpoint
|
6
|
+
class_attribute :selector
|
7
|
+
class_attribute :class_name
|
8
|
+
|
9
|
+
self.selector = '//rowset/row'
|
10
|
+
|
11
|
+
attr_reader :xml, :results
|
12
|
+
attr_accessor :cached_until
|
13
|
+
|
14
|
+
delegate :blank?, :present?, :any?, to: :results
|
15
|
+
|
16
|
+
def initialize(xml=nil)
|
17
|
+
if xml
|
18
|
+
@xml = xml
|
19
|
+
@results = xml.search(selector).map { |row| class_name.new(row) }
|
20
|
+
@cached_until = (xml.search('cachedUntil').text + 'Z').to_time
|
21
|
+
else
|
22
|
+
@results = []
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def merge(call)
|
27
|
+
@results += call.results
|
28
|
+
end
|
29
|
+
|
30
|
+
def ids
|
31
|
+
@results.map(&:id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def error?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Characters < Base
|
40
|
+
self.class_name = Classes::Characters
|
41
|
+
self.endpoint = '/account/Characters.xml.aspx'
|
42
|
+
end
|
43
|
+
|
44
|
+
class Sheet < Base
|
45
|
+
attr_reader :sheet
|
46
|
+
|
47
|
+
def initialize(xml)
|
48
|
+
@xml = xml
|
49
|
+
@sheet = class_name.new(xml)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
class CharacterSheet < Sheet
|
53
|
+
self.class_name = Classes::CharacterSheet
|
54
|
+
self.endpoint = '/char/CharacterSheet.xml.aspx'
|
55
|
+
end
|
56
|
+
class CorporationSheet < Sheet
|
57
|
+
self.class_name = Classes::CorporationSheet
|
58
|
+
self.endpoint = '/corp/CorporationSheet.xml.aspx'
|
59
|
+
end
|
60
|
+
|
61
|
+
class AccountBalance < Base
|
62
|
+
self.class_name = Classes::AccountBalance
|
63
|
+
end
|
64
|
+
class PersonalAccountBalance < AccountBalance
|
65
|
+
self.endpoint = '/char/AccountBalance.xml.aspx'
|
66
|
+
end
|
67
|
+
class CorporateAccountBalance < AccountBalance
|
68
|
+
self.endpoint = '/corp/AccountBalance.xml.aspx'
|
69
|
+
end
|
70
|
+
|
71
|
+
class WalletTransactions < Base
|
72
|
+
self.class_name = Classes::WalletTransaction
|
73
|
+
end
|
74
|
+
class PersonalWalletTransactions < WalletTransactions
|
75
|
+
self.endpoint = '/char/WalletTransactions.xml.aspx'
|
76
|
+
end
|
77
|
+
class CorporateWalletTransactions < WalletTransactions
|
78
|
+
self.endpoint = '/corp/WalletTransactions.xml.aspx'
|
79
|
+
end
|
80
|
+
|
81
|
+
class WalletJournals < Base
|
82
|
+
self.class_name = Classes::WalletJournal
|
83
|
+
end
|
84
|
+
class PersonalWalletJournals < WalletJournals
|
85
|
+
self.endpoint = '/char/WalletJournal.xml.aspx'
|
86
|
+
end
|
87
|
+
class CorporateWalletJournals < WalletJournals
|
88
|
+
self.endpoint = '/corp/WalletJournal.xml.aspx'
|
89
|
+
end
|
90
|
+
|
91
|
+
class Blueprints < Base
|
92
|
+
self.class_name = Classes::Blueprint
|
93
|
+
end
|
94
|
+
class PersonalBlueprints < Blueprints
|
95
|
+
self.endpoint = '/char/Blueprints.xml.aspx'
|
96
|
+
end
|
97
|
+
class CorporateBlueprints < Blueprints
|
98
|
+
self.endpoint = '/corp/Blueprints.xml.aspx'
|
99
|
+
end
|
100
|
+
|
101
|
+
class MarketOrders < Base
|
102
|
+
self.class_name = Classes::MarketOrder
|
103
|
+
end
|
104
|
+
class PersonalMarketOrders < MarketOrders
|
105
|
+
self.endpoint = '/char/MarketOrders.xml.aspx'
|
106
|
+
end
|
107
|
+
class CorporateMarketOrders < MarketOrders
|
108
|
+
self.endpoint = '/corp/MarketOrders.xml.aspx'
|
109
|
+
end
|
110
|
+
|
111
|
+
class IndustryJobs < Base
|
112
|
+
self.class_name = Classes::IndustryJob
|
113
|
+
end
|
114
|
+
class PersonalIndustryJobs < IndustryJobs
|
115
|
+
self.endpoint = '/char/IndustryJobs.xml.aspx'
|
116
|
+
end
|
117
|
+
class CorporateIndustryJobs < IndustryJobs
|
118
|
+
self.endpoint = '/corp/IndustryJobs.xml.aspx'
|
119
|
+
end
|
120
|
+
class PersonalIndustryJobHistory < IndustryJobs
|
121
|
+
self.endpoint = '/char/IndustryJobsHistory.xml.aspx'
|
122
|
+
end
|
123
|
+
class CorporateIndustryJobHistory < IndustryJobs
|
124
|
+
self.endpoint = '/corp/IndustryJobsHistory.xml.aspx'
|
125
|
+
end
|
126
|
+
|
127
|
+
class AssetList < Base
|
128
|
+
attr_reader :assets
|
129
|
+
|
130
|
+
def initialize(xml)
|
131
|
+
@assets = []
|
132
|
+
parse_rows(xml.search("//rowset[@name='assets']/row"))
|
133
|
+
@cached_until = (xml.search('cachedUntil').text + 'Z').to_time
|
134
|
+
end
|
135
|
+
|
136
|
+
def parse_rows(rows, parent=nil)
|
137
|
+
rows.each do |container|
|
138
|
+
asset = Classes::Asset.new(container)
|
139
|
+
asset.container = container.children.any?
|
140
|
+
asset.parent = parent if parent
|
141
|
+
parse_rows(container.search("rowset/row"), asset) if asset.container?
|
142
|
+
@assets << asset
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
class PersonalAssetList < AssetList
|
147
|
+
self.endpoint = '/char/AssetList.xml.aspx'
|
148
|
+
end
|
149
|
+
class CorporateAssetList < AssetList
|
150
|
+
self.endpoint = '/corp/AssetList.xml.aspx'
|
151
|
+
end
|
152
|
+
|
153
|
+
class CorporateMemberTracking < Base
|
154
|
+
self.class_name = Classes::CorporateMemberTracking
|
155
|
+
self.endpoint = '/corp/MemberTracking.xml.aspx'
|
156
|
+
end
|
157
|
+
|
158
|
+
class CorporateMemberSecurity < Base
|
159
|
+
self.class_name = Classes::CorporateMemberSecurity
|
160
|
+
self.endpoint = '/corp/MemberSecurity.xml.aspx'
|
161
|
+
end
|
162
|
+
|
163
|
+
class CorporateTitles < Base
|
164
|
+
self.class_name = Classes::CorporateTitle
|
165
|
+
self.endpoint = '/corp/Titles.xml.aspx'
|
166
|
+
end
|
167
|
+
|
168
|
+
class ErrorResponse < Base
|
169
|
+
attr_reader :exception, :call, :params
|
170
|
+
|
171
|
+
def initialize(exception, call=nil, params={})
|
172
|
+
@exception = exception
|
173
|
+
@call = call
|
174
|
+
@params = params
|
175
|
+
end
|
176
|
+
|
177
|
+
def error?
|
178
|
+
true
|
179
|
+
end
|
180
|
+
|
181
|
+
def title
|
182
|
+
exception.http_body.scan(/<title>(.+?)<\/title>/).flatten[0]
|
183
|
+
end
|
184
|
+
|
185
|
+
def to_s
|
186
|
+
puts "================================"
|
187
|
+
puts "API Error: #{exception.class}"
|
188
|
+
puts "title: #{title}"
|
189
|
+
puts "body: #{exception.http_body}"
|
190
|
+
puts "call: #{call}"
|
191
|
+
puts "params: #{params.inspect}"
|
192
|
+
puts "================================"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
module EveApp
|
2
|
+
module XmlApi
|
3
|
+
class Classes
|
4
|
+
class Base
|
5
|
+
protected
|
6
|
+
|
7
|
+
def parse_time(value)
|
8
|
+
!value || value.starts_with?('0001') ? nil : "#{value}Z".to_time
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Characters < Base
|
13
|
+
attr_reader :id, :name, :corporation_id, :corporation_name, :alliance_id, :alliance_name, :faction_id, :faction_name
|
14
|
+
|
15
|
+
def initialize(elem)
|
16
|
+
@id = elem['characterID'].to_i
|
17
|
+
@name = elem['name']
|
18
|
+
@corporation_id = elem['corporationID'].to_i
|
19
|
+
@corporation_name = elem['corporationName']
|
20
|
+
@alliance_id = elem['allianceID'].to_i
|
21
|
+
@alliance_name = elem['allianceName']
|
22
|
+
@faction_id = elem['factionID'].to_i
|
23
|
+
@faction_name = elem['factionName']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class AccountBalance < Base
|
28
|
+
attr_reader :id, :key, :balance
|
29
|
+
|
30
|
+
def initialize(elem)
|
31
|
+
@id = elem['accountID'].to_i
|
32
|
+
@key = elem['accountKey'].to_i
|
33
|
+
@balance = elem['balance'].to_f
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class CharacterSheet < Base
|
38
|
+
attr_reader :id, :name, :corporation_id
|
39
|
+
|
40
|
+
def initialize(xml)
|
41
|
+
@id = xml.search('//result/characterID[1]').text.to_i
|
42
|
+
@name = xml.search('//result/name[1]').text
|
43
|
+
@corporation_id = xml.search('//result/corporationID[1]').text.to_i
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class CorporationSheet < Base
|
48
|
+
attr_reader :id, :name, :alliance_id
|
49
|
+
|
50
|
+
def initialize(xml)
|
51
|
+
@id = xml.search('//result/corporationID[1]').text.to_i
|
52
|
+
@name = xml.search('//result/corporationName[1]').text
|
53
|
+
@alliance_id = xml.search('//result/allianceID[1]').text.to_i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class WalletTransaction < Base
|
58
|
+
attr_reader :created_at, :id, :quantity, :type_name, :type_id, :price,
|
59
|
+
:client_id, :client_name, :character_id, :station_id, :station_name, :type,
|
60
|
+
:transaction_for, :character_name
|
61
|
+
|
62
|
+
def initialize(elem)
|
63
|
+
@created_at = parse_time(elem['transactionDateTime'])
|
64
|
+
@id = elem['transactionID'].to_i
|
65
|
+
@quantity = elem['quantity'].to_i
|
66
|
+
@type_name = elem['typeName']
|
67
|
+
@type_id = elem['typeID'].to_i
|
68
|
+
@price = elem['price'].to_f
|
69
|
+
@client_id = elem['clientID'].to_i if elem['clientID']
|
70
|
+
@client_name = elem['clientName']
|
71
|
+
@character_name = elem['characterName']
|
72
|
+
@station_id = elem['stationID'].to_i
|
73
|
+
@station_name = elem['stationName']
|
74
|
+
@character_id = elem['characterID'].to_i if elem['characterID'] && elem['characterID'] != '0'
|
75
|
+
@type = elem['transactionType']
|
76
|
+
@transaction_for = elem['transactionFor']
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class WalletJournal < Base
|
81
|
+
attr_reader :created_at, :id, :ref_type_id, :owner1_name, :owner1_id, :owner1_type_id,
|
82
|
+
:owner2_name, :owner2_id, :owner2_type_id, :arg_name, :arg_id, :amount, :balance, :reason
|
83
|
+
|
84
|
+
def initialize(elem)
|
85
|
+
@created_at = parse_time(elem['date'])
|
86
|
+
@id = elem['refID'].to_i
|
87
|
+
@ref_type_id = elem['refTypeID'].to_i
|
88
|
+
@owner1_id = elem['ownerID1'].to_i if elem['ownerID1']
|
89
|
+
@owner1_name = elem['ownerName1']
|
90
|
+
@owner1_type = elem['owner1TypeID']
|
91
|
+
@owner2_id = elem['ownerID2'].to_i if elem['ownerID2']
|
92
|
+
@owner2_name = elem['ownerName2']
|
93
|
+
@owner2_type = elem['owner2TypeID']
|
94
|
+
@arg_name = elem['argName1']
|
95
|
+
@arg_id = elem['argID1'].to_i if elem['argID1']
|
96
|
+
@amount = elem['amount'].to_f
|
97
|
+
@balance = elem['balance'].to_f
|
98
|
+
@reason = elem['reason']
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Blueprint < Base
|
103
|
+
attr_reader :item_id, :location_id, :type_id, :type_name, :flag, :quantity, :te, :me, :runs
|
104
|
+
|
105
|
+
def initialize(elem)
|
106
|
+
@item_id = elem['itemID'].to_i
|
107
|
+
@location_id = elem['locationID']
|
108
|
+
@type_id = elem['typeID'].to_i
|
109
|
+
@type_name = elem['typeName']
|
110
|
+
@flag = elem['flagID'].to_i
|
111
|
+
@quantity = elem['quantity'].to_i
|
112
|
+
@te = elem['timeEfficiency'].to_i
|
113
|
+
@me = elem['materialEfficiency'].to_i
|
114
|
+
@runs = elem['runs'].to_i
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class Asset < Base
|
119
|
+
attr_accessor :container, :parent
|
120
|
+
attr_reader :item_id, :type_id, :location_id, :quantity, :flag, :repacked, :raw_quantity
|
121
|
+
|
122
|
+
def initialize(elem)
|
123
|
+
@container = false
|
124
|
+
@parent = nil
|
125
|
+
@item_id = elem['itemID'].to_i
|
126
|
+
@type_id = elem['typeID'].to_i
|
127
|
+
@location_id = elem['locationID'].to_i
|
128
|
+
@quantity = elem['quantity'].to_i
|
129
|
+
@flag = elem['flag'].to_i
|
130
|
+
@repacked = elem['singleton'].to_i
|
131
|
+
@raw_quantity = elem['rawQuantity'].to_i
|
132
|
+
end
|
133
|
+
|
134
|
+
def container?
|
135
|
+
!!container
|
136
|
+
end
|
137
|
+
|
138
|
+
def parent?
|
139
|
+
!!parent
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class MarketOrder < Base
|
144
|
+
attr_reader :order_id, :character_id, :station_id, :volume_entered, :volume_remaining, :minimum_volume,
|
145
|
+
:state, :type_id, :range, :account_key, :duration, :escrow, :price, :bid, :issued_at
|
146
|
+
|
147
|
+
def initialize(elem) #:nodoc:
|
148
|
+
@order_id = elem['orderID'].to_i
|
149
|
+
@character_id = elem['charID'].to_i
|
150
|
+
@station_id = elem['stationID'].to_i
|
151
|
+
@volume_entered = elem['volEntered'].to_i
|
152
|
+
@volume_remaining = elem['volRemaining'].to_i
|
153
|
+
@minimum_volume = elem['minVolume'].to_i
|
154
|
+
@state = case elem['orderState'].to_i
|
155
|
+
when 0
|
156
|
+
'Active'
|
157
|
+
when 1
|
158
|
+
'Closed'
|
159
|
+
when 2
|
160
|
+
'Expired'
|
161
|
+
when 3
|
162
|
+
'Cancelled'
|
163
|
+
when 4
|
164
|
+
'Pending'
|
165
|
+
when 5
|
166
|
+
'Character Deleted'
|
167
|
+
end
|
168
|
+
@type_id = elem['typeID'].to_i
|
169
|
+
@range = elem['range'].to_i
|
170
|
+
@account_key = elem['accountKey'].to_i
|
171
|
+
@escrow = elem['escrow'].to_f
|
172
|
+
@price = elem['price'].to_f
|
173
|
+
@bid = elem['bid'] == '1'
|
174
|
+
@duration = elem['duration'].to_i
|
175
|
+
@issued_at = parse_time(elem['issued'])
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class IndustryJob < Base
|
180
|
+
attr_reader :job_id, :installer_id, :installer_name, :facility_id, :system_id, :system_name,
|
181
|
+
:station_id, :activity_id, :blueprint_id, :blueprint_type_id, :blueprint_type_name,
|
182
|
+
:blueprint_location_id, :output_location_id, :runs, :cost, :team_id, :licensed_runs,
|
183
|
+
:probability, :product_type_id, :product_type_name, :status, :duration, :start_date,
|
184
|
+
:end_date, :pause_date, :completed_date, :completed_character_id, :successful_runs
|
185
|
+
|
186
|
+
def initialize(elem)
|
187
|
+
@job_id = elem['jobID'].to_i # "306488326"
|
188
|
+
@installer_id = elem['installerID'].to_i # "1663516939"
|
189
|
+
@installer_name = elem['installerName'] # "GaIIente Slave"
|
190
|
+
@facility_id = elem['facilityID'].to_i # "1022215707239"
|
191
|
+
@system_id = elem['solarSystemID'].to_i # "30001363"
|
192
|
+
@system_name = elem['solarSystemName'] # "Sobaseki"
|
193
|
+
@station_id = elem['stationID'].to_i # "1022182744039"
|
194
|
+
@activity_id = elem['activityID'].to_i # "1"
|
195
|
+
@blueprint_id = elem['blueprintID'].to_i # "1022215694764"
|
196
|
+
@blueprint_type_id = elem['blueprintTypeID'].to_i # "22545"
|
197
|
+
@blueprint_type_name = elem['blueprintTypeName'] # "Hulk Blueprint"
|
198
|
+
@blueprint_location_id = elem['blueprintLocationID'].to_i # "1022215707239"
|
199
|
+
@output_location_id = elem['outputLocationID'].to_i # "1022215707239"
|
200
|
+
@runs = elem['runs'].to_i # "1"
|
201
|
+
@cost = elem['cost'].to_f # "8920512.00"
|
202
|
+
@team_id = elem['teamID'].to_i # "0"
|
203
|
+
@licensed_runs = elem['licensedRuns'].to_i # "1"
|
204
|
+
@probability = elem['probability'].to_f # "1"
|
205
|
+
@product_type_id = elem['productTypeID'].to_i
|
206
|
+
@product_type_name = elem['productTypeName']
|
207
|
+
@status = elem['status'].to_i
|
208
|
+
@duration = elem['timeInSeconds'].to_i
|
209
|
+
@start_date = parse_time(elem['startDate'])
|
210
|
+
@end_date = parse_time(elem['endDate'])
|
211
|
+
@pause_date = parse_time(elem['pauseDate'])
|
212
|
+
@completed_date = parse_time(elem['completedDate'])
|
213
|
+
@completed_character_id = elem['completedCharacterID'].to_i
|
214
|
+
@successful_runs = elem['successfulRuns'].to_i
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class CorporateMemberTracking < Base
|
219
|
+
attr_reader :character_id, :name, :start_date, :base_id, :base, :title, :logon_date, :logoff_date, :location_id, :location, :ship_type_id, :ship_type, :roles, :grantable_roles
|
220
|
+
|
221
|
+
def initialize(elem)
|
222
|
+
@character_id = elem['characterID'].to_i
|
223
|
+
@name = elem['name']
|
224
|
+
@start_date = parse_time(elem['startDateTime'])
|
225
|
+
@base_id = elem['baseID'].to_i
|
226
|
+
@base = elem['base']
|
227
|
+
@title = elem['title']
|
228
|
+
@logon_date = parse_time(elem['logonDateTime'])
|
229
|
+
@logoff_date = parse_time(elem['logoffDateTime'])
|
230
|
+
@location_id = elem['locationID'].to_i > 0 ? elem['locationID'].to_i : nil
|
231
|
+
@location = elem['location'].presence
|
232
|
+
@ship_type_id = elem['shipTypeID'].to_i
|
233
|
+
@ship_type = elem['shipType']
|
234
|
+
@roles = elem['roles']
|
235
|
+
@grantable_roles = elem['grantableRoles']
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
class CorporateMemberSecurity < Base
|
240
|
+
attr_reader :character_id, :name, :titles
|
241
|
+
|
242
|
+
def initialize(elem)
|
243
|
+
@character_id = elem['characterID'].to_i
|
244
|
+
@name = elem['name']
|
245
|
+
@titles = elem.search('rowset[@name="titles"]/row').map { |t| t['titleName'] }
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
class CorporateTitle < Base
|
250
|
+
attr_reader :id, :name, :description
|
251
|
+
|
252
|
+
def initialize(elem)
|
253
|
+
@id = elem['roleID'].to_i
|
254
|
+
@name = elem['roleName']
|
255
|
+
@description = elem['roleDescription']
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|