File Coverage

blib/lib/Games/EveOnline/API.pm
Criterion Covered Total %
statement 317 344 92.1
branch 46 106 43.4
condition 29 73 39.7
subroutine 30 33 90.9
pod 20 20 100.0
total 442 576 76.7


line stmt bran cond sub pod time code
1             package Games::EveOnline::API;
2 1     1   752 use Moo;
  1         2  
  1         5  
3              
4             our $VERSION = '0.10';
5              
6             =head1 NAME
7              
8             Games::EveOnline::API - A simple Perl wrapper around the EveOnline XML API. (DEPRECATED)
9              
10             =head1 SYNOPSIS
11              
12             use Games::EveOnline::API;
13             my $eapi = Games::EveOnline::API->new();
14            
15             my $skill_groups = $eapi->skill_tree();
16             my $ref_types = $eapi->ref_types();
17             my $systems = $eapi->sovereignty();
18            
19             # The rest of the methods require authentication.
20             my $eapi = Games::EveOnline::API->new( user_id => '..', api_key => '..' );
21            
22             my $characters = $eapi->characters();
23             my $sheet = $eapi->character_sheet( character_id => $character_id );
24             my $in_training = $eapi->skill_in_training( character_id => $character_id );
25              
26             =head1 DEPRECATED
27              
28             This module is no longer being maintained as the XML API is no more.
29              
30             =head1 DESCRIPTION
31              
32             This module provides a Perl wrapper around the Eve-Online API, version 2.
33             The need for the wrapper arrises for two reasons. First, the XML that
34             is provided by the API is overly complex, at least for my taste. So, other
35             than just returning you a perl data representation of the XML, it also
36             simplifies the results.
37              
38             Only a couple of the methods provided by this module can be used straight
39             away. The rest require that you get a user_id (keyID) and api_key (vCode).
40              
41             =head1 A NOTE ON CACHING
42              
43             Most of these methods return a 'cached_until' value. I've no clue if this
44             is CCP telling you how long you should cache the information before you
45             should request it again, or if this is the point at which CCP will refresh
46             their cache of this information.
47              
48             Either way, it is good etiquet to follow the cacheing guidelines of a
49             provider. If you over-use the API I'm sure you'll eventually get blocked.
50              
51             =cut
52              
53 1     1   901 use Types::Standard qw( Int Str );
  1         74731  
  1         11  
54 1     1   1370 use Type::Utils qw( class_type );
  1         4970  
  1         9  
55              
56 1     1   1125 use URI;
  1         4520  
  1         31  
57 1     1   629 use LWP::UserAgent qw();
  1         40059  
  1         28  
58 1     1   787 use XML::Simple qw();
  1         8938  
  1         30  
59 1     1   7 use Carp qw( croak );
  1         2  
  1         4675  
60              
61             =head1 ARGUMENTS
62              
63             =head2 user_id
64              
65             An Eve Online API user ID (also known as a keyID).
66              
67             =head2 api_key
68              
69             The key, as provided Eve Online, to access the API (also known
70             as a vCode).
71              
72             =head2 character_id
73              
74             Set the default C. Any methods that require
75             a characte ID, and are not given one, will use this one.
76              
77             =head2 api_url
78              
79             The URL that will be used to access the Eve Online API.
80             Defaults to L. Normally you
81             won't want to change this.
82              
83             =head2 ua
84              
85             The underlying L object. Default to a new one
86             with no special arguments. Override this if you want to, for
87             example, enable keepalive or an HTTP proxy.
88              
89             =cut
90              
91             has user_id => (is=>'ro', isa=>Int );
92             has api_key => (is=>'ro', isa=>Str );
93             has character_id => (is=>'ro', isa=>Int );
94             has api_url => (is=>'ro', isa=>Str, default=>'https://api.eveonline.com');
95             has ua => (is=>'lazy', isa=>class_type('LWP::UserAgent'));
96              
97             sub _build_ua {
98 0     0   0 return LWP::UserAgent->new;
99             }
100              
101             =head1 ANONYMOUS METHODS
102              
103             These methods may be called anonymously, without authentication.
104              
105             =head2 skill_tree
106              
107             my $skill_groups = $eapi->skill_tree();
108              
109             Returns a complex data structure containing the entire skill tree.
110             The data structure is:
111              
112             {
113             cached_until => $date_time,
114             $group_id => {
115             name => $group_name,
116             skills => {
117             $skill_id => {
118             name => $skill_name,
119             description => $skill_description,
120             rank => $skill_rank,
121             primary_attribute => $skill_primary_attribute,
122             secondary_attribute => $skill_secondary_attribute,
123             bonuses => {
124             $bonus_name => $bonus_value,
125             },
126             required_skills => {
127             $skill_id => $skill_level,
128             },
129             }
130             }
131             }
132             }
133              
134             =cut
135              
136             sub skill_tree {
137 1     1 1 7662 my ($self) = @_;
138              
139 1         8 my $data = $self->_load_xml(
140             path => 'eve/SkillTree.xml.aspx',
141             );
142              
143 1         3 my $result = {};
144              
145 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
146              
147 1         2 my $group_rows = $data->{result}->{rowset}->{row};
148 1         4 foreach my $group_id (keys %$group_rows) {
149 1   50     16 my $group_result = $result->{$group_id} ||= {};
150 1         28 $group_result->{name} = $group_rows->{$group_id}->{groupName};
151              
152 1         3 $group_result->{skills} = {};
153 1         4 my $skill_rows = $group_rows->{$group_id}->{rowset}->{row};
154 1         10 foreach my $skill_id (keys %$skill_rows) {
155 8   50     29 my $skill_result = $group_result->{skills}->{$skill_id} ||= {};
156 8         18 $skill_result->{name} = $skill_rows->{$skill_id}->{typeName};
157 8         14 $skill_result->{description} = $skill_rows->{$skill_id}->{description};
158 8         15 $skill_result->{rank} = $skill_rows->{$skill_id}->{rank};
159 8         16 $skill_result->{primary_attribute} = $skill_rows->{$skill_id}->{requiredAttributes}->{primaryAttribute};
160 8         16 $skill_result->{secondary_attribute} = $skill_rows->{$skill_id}->{requiredAttributes}->{secondaryAttribute};
161              
162 8         11 $skill_result->{bonuses} = {};
163 8         16 my $bonus_rows = $skill_rows->{$skill_id}->{rowset}->{skillBonusCollection}->{row};
164 8         19 foreach my $bonus_name (keys %$bonus_rows) {
165 8         23 $skill_result->{bonuses}->{$bonus_name} = $bonus_rows->{$bonus_name}->{bonusValue};
166             }
167              
168 8         13 $skill_result->{required_skills} = {};
169 8         14 my $required_skill_rows = $skill_rows->{$skill_id}->{rowset}->{requiredSkills}->{row};
170 8         20 foreach my $required_skill_id (keys %$required_skill_rows) {
171 8         23 $skill_result->{required_skills}->{$required_skill_id} = $required_skill_rows->{$required_skill_id}->{skillLevel};
172             }
173             }
174             }
175              
176 1         3 $result->{cached_until} = $data->{cachedUntil};
177              
178 1         24 return $result;
179             }
180              
181             =head2 ref_types
182              
183             my $ref_types = $eapi->ref_types();
184              
185             Returns a simple hash structure containing definitions of the
186             various financial transaction types. This is useful when pulling
187             wallet information. The key of the hash is the ref type's ID, and
188             the value of the title of the ref type.
189              
190             =cut
191              
192             sub ref_types {
193 1     1 1 5839 my ($self) = @_;
194              
195 1         5 my $data = $self->_load_xml(
196             path => 'eve/RefTypes.xml.aspx',
197             );
198              
199 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
200              
201 1         4 my $ref_types = {};
202              
203 1         3 my $rows = $data->{result}->{rowset}->{row};
204 1         28 foreach my $ref_type_id (keys %$rows) {
205 87         161 $ref_types->{$ref_type_id} = $rows->{$ref_type_id}->{refTypeName};
206             }
207              
208 1         6 $ref_types->{cached_until} = $data->{cachedUntil};
209              
210 1         20 return $ref_types;
211             }
212              
213             =head2 sovereignty
214              
215             my $systems = $eapi->sovereignty();
216              
217             Returns a hashref where each key is the system ID, and the
218             value is a hashref with the keys:
219              
220             name
221             faction_id
222             sovereignty_level
223             constellation_sovereignty
224             alliance_id
225              
226             =cut
227              
228             sub sovereignty {
229 1     1 1 2054 my ($self) = @_;
230              
231 1         5 my $data = $self->_load_xml(
232             path => 'map/Sovereignty.xml.aspx',
233             );
234              
235 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
236              
237 1         3 my $systems = {};
238              
239 1         4 my $rows = $data->{result}->{rowset}->{row};
240 1         10 foreach my $system_id (keys %$rows) {
241 39         65 my $system = $systems->{$system_id} = {};
242 39         75 $system->{name} = $rows->{$system_id}->{solarSystemName};
243 39         70 $system->{faction_id} = $rows->{$system_id}->{factionID};
244 39         66 $system->{sovereignty_level} = $rows->{$system_id}->{sovereigntyLevel};
245 39         64 $system->{constellation_sovereignty} = $rows->{$system_id}->{constellationSovereignty};
246 39         74 $system->{alliance_id} = $rows->{$system_id}->{allianceID};
247             }
248              
249 1         5 $systems->{cached_until} = $data->{cachedUntil};
250 1         3 $systems->{data_time} = $data->{result}->{dataTime};
251              
252 1         22 return $systems;
253             }
254              
255             =head1 RESTRICTED METHODS
256              
257             These methods require authentication to use, so you must have set
258             the L and L arguments to use them.
259              
260             =head2 characters
261              
262             my $characters = $eapi->characters();
263              
264             Returns a hashref where key is the character ID and the
265             value is a hashref with a couple bits about the character.
266             Here's a sample:
267              
268             {
269             '1972081734' => {
270             'corporation_name' => 'Bellator Apparatus',
271             'corporation_id' => '1044143901',
272             'name' => 'Ardent Dawn'
273             }
274             }
275              
276             =cut
277              
278             sub characters {
279 1     1 1 9332 my ($self) = @_;
280              
281 1         6 my $data = $self->_load_xml(
282             path => 'account/Characters.xml.aspx',
283             requires_auth => 1,
284             );
285              
286 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
287              
288 1         3 my $characters = {};
289 1         3 my $rows = $data->{result}->{rowset}->{row};
290              
291 1         4 foreach my $character_id (keys %$rows) {
292             $characters->{$character_id} = {
293             name => $rows->{$character_id}->{name},
294             corporation_name => $rows->{$character_id}->{corporationName},
295             corporation_id => $rows->{$character_id}->{corporationID},
296 1         9 };
297             }
298              
299 1         3 $characters->{cached_until} = $data->{cachedUntil};
300              
301 1         6 return $characters;
302             }
303              
304             =head2 character_sheet
305              
306             my $sheet = $eapi->character_sheet( character_id => $character_id );
307              
308             For the given character ID a hashref is returned with
309             the all the information about the character. Here's
310             a sample:
311              
312             {
313             'name' => 'Ardent Dawn',
314             'balance' => '99010910.10',
315             'race' => 'Amarr',
316             'blood_line' => 'Amarr',
317             'corporation_name' => 'Bellator Apparatus',
318             'corporation_id' => '1044143901',
319            
320             'skills' => {
321             '3455' => {
322             'level' => '2',
323             'skill_points' => '1415'
324             },
325            
326             # Removed the rest of the skills for readability.
327             },
328            
329             'attribute_enhancers' => {
330             'memory' => {
331             'value' => '3',
332             'name' => 'Memory Augmentation - Basic'
333             },
334            
335             # Removed the rest of the enhancers for readability.
336             },
337            
338             'attributes' => {
339             'memory' => '7',
340             'intelligence' => '7',
341             'perception' => '4',
342             'charisma' => '4',
343             'willpower' => '17'
344             }
345             }
346              
347             =cut
348              
349             sub character_sheet {
350 1     1 1 1114 my ($self, %args) = @_;
351              
352 1   33     21 my $character_id = $args{character_id} || $self->character_id();
353 1 50       6 croak('No character_id specified') unless $character_id;
354              
355 1         5 my $data = $self->_load_xml(
356             path => 'char/CharacterSheet.xml.aspx',
357             requires_auth => 1,
358             character_id => $character_id,
359             );
360              
361 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
362              
363 1         3 my $result = $data->{result};
364              
365 1         2 my $sheet = {};
366 1         4 my $enhancers = $sheet->{attribute_enhancers} = {};
367 1         2 my $enhancer_rows = $result->{attributeEnhancers};
368 1         4 foreach my $attribute (keys %$enhancer_rows) {
369 4         15 my ($real_attribute) = ($attribute =~ /^([a-z]+)/xm);
370 4         9 my $enhancer = $enhancers->{$real_attribute} = {};
371              
372 4         9 $enhancer->{name} = $enhancer_rows->{$attribute}->{augmentatorName};
373 4         10 $enhancer->{value} = $enhancer_rows->{$attribute}->{augmentatorValue};
374             }
375            
376             $sheet = {
377             character_id => $result->{characterID},
378             date_of_birth => $result->{DoB},
379             ancestry => $result->{ancestry},
380             gender => $result->{gender},
381             clone_name => $result->{cloneName},
382             blood_line => $result->{bloodLine},
383             name => $result->{name},
384             corporation_id => $result->{corporationID},
385             corporation_name => $result->{corporationName},
386             balance => $result->{balance},
387             race => $result->{race},
388             attributes => $result->{attributes},
389             clone_skill_points => $result->{cloneSkillPoints},
390             attribute_enhancers => $enhancers,
391             cached_until => $data->{cachedUntil},
392 1         12 };
393              
394 1         4 my $skills = $sheet->{skills} = {};
395 1         2 my $skill_rows = $result->{rowset}->{skills}->{row};
396 1         7 foreach my $skill_id (keys %$skill_rows) {
397 26         40 my $skill = $skills->{$skill_id} = {};
398              
399 26         43 $skill->{level} = $skill_rows->{$skill_id}->{level};
400 26         47 $skill->{skill_points} = $skill_rows->{$skill_id}->{skillpoints};
401             }
402              
403             # TODO: Add logic to parse next rowsets:
404             # certificates, corporationRoles, corporationRolesAtHQ,
405             # corporationRolesAtBase, corporationRolesAtOther, corporationTitles
406              
407 1         20 return $sheet;
408             }
409              
410             =head2 skill_in_training
411              
412             my $in_training = $eapi->skill_in_training( character_id => $character_id );
413              
414             Returns a hashref with the following structure:
415              
416             {
417             'current_tq_time' => {
418             'content' => '2008-05-10 04:06:35',
419             'offset' => '0'
420             },
421             'end_time' => '2008-05-10 19:23:18',
422             'start_sp' => '139147',
423             'to_level' => '5',
424             'start_time' => '2008-05-07 16:15:05',
425             'skill_id' => '3436',
426             'end_sp' => '256000'
427             }
428              
429             =cut
430              
431             sub skill_in_training {
432 1     1 1 6958 my ($self, %args) = @_;
433              
434 1   33     12 my $character_id = $args{character_id} || $self->character_id();
435 1 50       3 croak('No character_id specified') unless $character_id;
436              
437 1         4 my $data = $self->_load_xml(
438             path => 'char/SkillInTraining.xml.aspx',
439             requires_auth => 1,
440             character_id => $character_id,
441             );
442 1         3 my $result = $data->{result};
443              
444 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
445              
446             my $training = {
447             current_tq_time => $result->{currentTQTime},
448             skill_id => $result->{trainingTypeID},
449             to_level => $result->{trainingToLevel},
450             start_time => $result->{trainingStartTime},
451             end_time => $result->{trainingEndTime},
452             start_sp => $result->{trainingStartSP},
453             end_sp => $result->{trainingDestinationSP},
454 1         60 };
455              
456 1         6 $training->{cached_until} = $data->{cachedUntil};
457              
458 1         7 return $training;
459             }
460              
461             =head2 api_key_info
462              
463             my $api_info = $eapi->api_key_info();
464              
465             Returns a hashref with the following structure:
466              
467             {
468             'cached_until' => '2014-06-26 16:57:40',
469             'type' => 'Account',
470             'access_mask' => '268435455',
471             'characters' => {
472             '12345678' => {
473             'faction_id' => '0',
474             'character_name' => 'Char Name',
475             'corporation_name' => 'School of Applied Knowledge',
476             'faction_name' => '',
477             'alliance_id' => '0',
478             'corporation_id' => '1000044',
479             'alliance_name' => ''
480             },
481             '87654321' => {
482             'faction_id' => '0',
483             'character_name' => 'Char Name2',
484             'corporation_name' => 'Corp Name',
485             'faction_name' => '',
486             'alliance_id' => '1234567890',
487             'corporation_id' => '987654321',
488             'alliance_name' => 'Alliance Name'
489             }
490             },
491             'expires' => ''
492             }
493              
494             =cut
495              
496             sub api_key_info {
497 1     1 1 1044 my ($self) = @_;
498              
499 1         4 my $data = $self->_load_xml(
500             path => 'account/ApiKeyInfo.xml.aspx',
501             requires_auth => 1,
502             );
503              
504 1         3 my $result = $data->{result}->{key};
505              
506 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
507              
508 1         2 my $type = $result->{type};
509              
510             my $key_info = {
511             type => $type,
512             expires => $result->{expires},
513             access_mask => $result->{accessMask},
514 1         4 };
515              
516             # TODO: add structure for corporation and alliance API
517 1 50 33     10 if ( defined $result->{rowset}->{row} and $type and ($type eq 'Account' or $type eq 'Character') ) {
      33        
      33        
518 1         4 $key_info->{characters} = {};
519 1         2 foreach my $char_id ( keys %{ $result->{rowset}->{row} } ) {
  1         5  
520             $key_info->{characters}->{$char_id} = {
521             'character_name' => $result->{rowset}->{row}->{$char_id}->{characterName},
522             'faction_name' => $result->{rowset}->{row}->{$char_id}->{factionName} || '',
523             'corporation_id' => $result->{rowset}->{row}->{$char_id}->{corporationID},
524             'alliance_name' => $result->{rowset}->{row}->{$char_id}->{allianceName} || '',
525             'faction_id' => $result->{rowset}->{row}->{$char_id}->{factionID} || '0',
526             'corporation_name' => $result->{rowset}->{row}->{$char_id}->{corporationName},
527 2   50     31 'alliance_id' => $result->{rowset}->{row}->{$char_id}->{allianceID} || '0',
      100        
      50        
      100        
528             };
529             }
530             }
531              
532 1         3 $key_info->{cached_until} = $data->{cachedUntil};
533              
534 1         7 return $key_info;
535             }
536              
537             =head2 account_status
538              
539             my $account_status = $eapi->account_status();
540              
541             Returns a hashref with the following structure:
542              
543             {
544             'cachedUntil' => '2014-06-26 17:17:12',
545             'logon_minutes' => '79114',
546             'logon_count' => '940',
547             'create_date' => '2011-06-22 11:44:37',
548             'paid_until' => '2014-08-26 16:37:43'
549             }
550              
551             =cut
552              
553             sub account_status {
554 1     1 1 1415 my ($self) = @_;
555              
556 1         4 my $data = $self->_load_xml(
557             path => 'account/AccountStatus.xml.aspx',
558             requires_auth => 1,
559             );
560              
561 1         3 my $result = $data->{result};
562              
563 1 50       3 return $self->_get_error( $data ) if defined $data->{error};
564              
565             return {
566             paid_until => $result->{paidUntil},
567             create_date => $result->{createDate},
568             logon_count => $result->{logonCount},
569             logon_minutes => $result->{logonMinutes},
570             cached_until => $data->{cachedUntil},
571             }
572 1         9 }
573              
574             =head2 character_info
575              
576             my $character_info = $eapi->character_info( character_id => $character_id );
577              
578             Returns a hashref with the following structure:
579              
580             {
581             'character_name' => 'Char Name',
582             'alliance_id' => '1234567890',
583             'corporation_id' => '987654321',
584             'corporation' => 'Corp Name',
585             'alliance' => 'Alliance Name',
586             'race' => 'Caldari',
587             'bloodline' => 'Achura',
588             'skill_points' => '40955856',
589             'employment_history' => {
590             '23046655' => {
591             'corporation_id' => '123456789',
592             'start_date' => '2013-02-03 13:39:00',
593             'record_id' => '23046655'
594             },
595             '29131760' => {
596             'corporation_id' => '987654321',
597             'start_date' => '2013-11-04 16:40:00',
598             'record_id' => '29131760'
599             },
600             },
601             'ship_type_id' => '670',
602             'account_balance' => '38131.68',
603             'cached_until' => '2014-06-26 17:18:29',
604             'last_known_location' => 'Jita',
605             'character_id' => '12345678',
606             'alliance_date' => '2012-08-05 00:12:00',
607             'corporation_date' => '2012-09-11 20:32:00',
608             'ship_type_name' => 'Capsule',
609             'security_status' => '1.3534973114985',
610             'ship_name' => 'Char Name Capsule'
611             }
612              
613             =cut
614              
615             sub character_info {
616 1     1 1 808 my ($self, %args) = @_;
617              
618 1   33     11 my $character_id = $args{character_id} || $self->character_id();
619 1 50       6 croak('No character_id specified') unless $character_id;
620              
621 1         3 my $data = $self->_load_xml(
622             path => 'eve/CharacterInfo.xml.aspx',
623             requires_auth => 1,
624             character_id => $character_id,
625             );
626              
627 1         4 my $result = $data->{result};
628              
629 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
630              
631             my $info = {
632             character_id => $result->{characterID},
633             character_name => $result->{characterName},
634             race => $result->{race},
635             bloodline => $result->{bloodline},
636             account_balance => $result->{accountBalance},
637             skill_points => $result->{skillPoints},
638             ship_name => $result->{shipName},
639             ship_type_id => $result->{shipTypeID},
640             ship_type_name => $result->{shipTypeName},
641             corporation_id => $result->{corporationID},
642             corporation => $result->{corporation},
643             corporation_date => $result->{corporationDate},
644             alliance_id => $result->{allianceID},
645             alliance => $result->{alliance},
646             alliance_date => $result->{allianceDate},
647             last_known_location => $result->{lastKnownLocation},
648             security_status => $result->{securityStatus},
649             cached_until => $data->{cachedUntil},
650 1         16 };
651              
652 1 50       4 if ( defined $result->{rowset}->{row} ) {
653 1         3 foreach my $history_row ( @{$result->{rowset}->{row}} ) {
  1         4  
654 1         4 $info->{employment_history}->{$history_row->{recordID}}->{record_id} = $history_row->{recordID};
655 1         4 $info->{employment_history}->{$history_row->{recordID}}->{corporation_id} = $history_row->{corporationID};
656 1         3 $info->{employment_history}->{$history_row->{recordID}}->{start_date} = $history_row->{startDate};
657             }
658             }
659              
660 1         7 return $info;
661             }
662              
663             =head2 asset_list
664              
665             my $asset_list = $eapi->asset_list( character_id => $character_id );
666              
667             Returns a hashref with the following structure:
668              
669             {
670             '1014951232473' => {
671             'contents' => {
672             '1014957890964' => {
673             'type_id' => '2454',
674             'quantity' => '1',
675             'flag' => '87',
676             'raw_quantity' => '-1',
677             'singleton' => '1',
678             'item_id' => '1014957890964'
679             }
680             },
681             'quantity' => '1',
682             'flag' => '4',
683             'location_id' => '60014680',
684             'singleton' => '1',
685             'item_id' => '1014951232473',
686             'type_id' => '32880',
687             'raw_quantity' => '-1'
688             },
689             '1014951385057' => {
690             'type_id' => '1178',
691             'quantity' => '1',
692             'flag' => '4',
693             'raw_quantity' => '-2',
694             'location_id' => '60015001',
695             'singleton' => '1',
696             'item_id' => '1014951385057'
697             }
698             }
699              
700             =cut
701              
702             sub asset_list {
703 1     1 1 1385 my ($self, %args) = @_;
704              
705 1   33     9 my $character_id = $args{character_id} || $self->character_id();
706 1 50       4 croak('No character_id specified') unless $character_id;
707              
708 1         3 my $data = $self->_load_xml(
709             path => 'char/AssetList.xml.aspx',
710             requires_auth => 1,
711             character_id => $character_id,
712             );
713              
714 1         4 my $result = $data->{result};
715              
716 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
717              
718 1         17 return $self->_parse_assets( $result );
719             }
720              
721             =head2 contact_list
722              
723             my $contact_list = $eapi->contact_list( character_id => $character_id );
724              
725             Returns a hashref with the following structure:
726              
727             {
728             'contact_list' => {
729             '962693552' => {
730             'standing' => '10',
731             'contact_name' => 'Char Name',
732             'contact_id' => '962693552',
733             'in_watchlist' => undef,
734             'contact_type_id' => '1384'
735             },
736             '3019494' => {
737             'standing' => '0',
738             'contact_name' => 'Char Name 3',
739             'contact_id' => '3019494',
740             'in_watchlist' => undef,
741             'contact_type_id' => '1375'
742             },
743             '1879838281' => {
744             'standing' => '10',
745             'contact_name' => 'Char Name 2',
746             'contact_id' => '1879838281',
747             'in_watchlist' => undef,
748             'contact_type_id' => '1378'
749             }
750             }
751             }
752              
753             =cut
754              
755             sub contact_list {
756 1     1 1 8184 my ($self, %args) = @_;
757              
758 1   33     13 my $character_id = $args{character_id} || $self->character_id();
759 1 0 33     3 croak('No character_id specified') if ! $character_id && $args{type} && $args{type} ne 'corp';
      0        
760              
761 1 50 33     6 my $type = $args{type} && $args{type} eq 'corp' ? 'corp' : 'char';
762              
763 1 50       7 my $data = $self->_load_xml(
764             path => "$type/ContactList.xml.aspx",
765             requires_auth => 1,
766             character_id => $type eq 'char' ? $character_id : undef,
767             );
768              
769 1         3 my $result = $data->{result};
770              
771 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
772              
773 1         3 my $contacts;
774 1         2 foreach my $rows ( keys %{$result->{rowset}} ) {
  1         5  
775 3 100       9 next unless defined $result->{rowset}->{$rows}->{row};
776 1         2 my $key = $rows;
777 1         5 $key =~ s/L/_l/;
778 1         2 $key =~ s/C/_c/; # TODO: more correctly regexp
779 1         3 foreach my $contact_id ( keys %{ $result->{rowset}->{$rows}->{row} } ) {
  1         4  
780 4         9 $contacts->{$key}->{$contact_id}->{contact_id} = $contact_id;
781 4         9 $contacts->{$key}->{$contact_id}->{standing} = $result->{rowset}->{$rows}->{row}->{$contact_id}->{standing};
782 4         10 $contacts->{$key}->{$contact_id}->{contact_name} = $result->{rowset}->{$rows}->{row}->{$contact_id}->{contactName};
783 4         9 $contacts->{$key}->{$contact_id}->{contact_type_id} = $result->{rowset}->{$rows}->{row}->{$contact_id}->{contactTypeID};
784 4 50       9 if ( $rows eq 'contactList' ) {
785 4         10 $contacts->{$key}->{$contact_id}->{in_watchlist} = $result->{rowset}->{$rows}->{row}->{$contact_id}->{inWatchlist};
786             }
787             }
788             }
789              
790 1         3 $contacts->{cached_until} = $data->{cachedUntil};
791              
792 1         9 return $contacts;
793             }
794              
795             =head2 wallet_transactions
796              
797             my $wallet_transactions = $eapi->wallet_transactions(
798             character_id => $character_id,
799             row_count => $row_count, # optional, default is 2560
800             account_key => $account_key, # optional, default is 1000
801             from_id => $args{from_id}, # optional, need for offset
802             );
803              
804             Returns a hashref with the following structure:
805              
806             {
807             '3499165305' => {
808             'type_name' => 'Mining Frigate',
809             'quantity' => '1',
810             'client_id' => '90646537',
811             'transaction_date_time' => '2014-06-28 12:23:41',
812             'station_id' => '60015001',
813             'transaction_id' => '3499165305',
814             'transaction_for' => 'personal',
815             'type_id' => '32918',
816             'station_name' => 'Akiainavas III - School of Applied Knowledge',
817             'client_name' => 'Zeta Zhang',
818             'price' => '1201.02',
819             'transaction_type' => 'sell'
820             },
821             '3482136396' => {
822             'type_name' => 'Mining Barge',
823             'quantity' => '1',
824             'client_id' => '1000167',
825             'transaction_date_time' => '2014-06-15 20:15:26',
826             'station_id' => '60014680',
827             'transaction_id' => '3482136396',
828             'transaction_for' => 'personal',
829             'type_id' => '17940',
830             'station_name' => 'Autama V - Moon 9 - State War Academy',
831             'client_name' => 'State War Academy',
832             'price' => '500000.00',
833             'transaction_type' => 'buy'
834             }
835             }
836              
837             =cut
838              
839             sub wallet_transactions {
840 1     1 1 1861 my ($self, %args) = @_;
841              
842 1   33     10 my $character_id = $args{character_id} || $self->character_id();
843 1 50       4 croak('No character_id specified') unless $character_id;
844              
845 1   50     6 my $row_count = $args{row_count} || 2560;
846 1   50     5 my $account_key = $args{account_key} || 1000;
847              
848              
849             my $data = $self->_load_xml(
850             path => 'char/WalletTransactions.xml.aspx',
851             requires_auth => 1,
852             character_id => $character_id,
853             row_count => $row_count,
854             account_key => $account_key,
855             from_id => $args{from_id},
856 1         6 );
857              
858 1         4 my $result = $data->{result}->{rowset}->{row};
859              
860 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
861              
862 1         2 my $trans;
863 1         5 foreach my $t_id ( keys %$result ) {
864             $trans->{$t_id} = {
865             transaction_for => $result->{$t_id}->{transactionFor},
866             transaction_type => $result->{$t_id}->{transactionType},
867             station_name => $result->{$t_id}->{stationName},
868             station_id => $result->{$t_id}->{stationID},
869             client_name => $result->{$t_id}->{clientName},
870             client_id => $result->{$t_id}->{clientID},
871             price => $result->{$t_id}->{price},
872             type_id => $result->{$t_id}->{typeID},
873             type_name => $result->{$t_id}->{typeName},
874             quantity => $result->{$t_id}->{quantity},
875             transaction_id => $t_id,
876             transaction_date_time => $result->{$t_id}->{transactionDateTime},
877 9         59 };
878             }
879              
880 1         4 $trans->{cached_until} = $data->{cachedUntil};
881              
882 1         14 return $trans;
883             }
884              
885             =head2 wallet_journal
886              
887             my $wallet_journal = $eapi->wallet_journal(
888             character_id => $character_id,
889             row_count => $row_count, # optional, default is 2560
890             account_key => $account_key, # optional, default is 1000
891             from_id => $args{from_id}, # optional, need for offset
892             );
893              
894             Returns a hashref with the following structure:
895              
896             {
897             '9729070529' => {
898             'owner_name2' => 'Milolika Muvila',
899             'arg_id1' => '0',
900             'date' => '2014-07-08 19:02:53',
901             'reason' => '',
902             'tax_receiver_id' => '',
903             'owner_name1' => 'Cyno Chain',
904             'amount' => '814900000.00',
905             'owner_id1' => '93496706',
906             'tax_amount' => '',
907             'balance' => '826371087.94',
908             'arg_name1' => '3513456219',
909             'ref_id' => '9729070529',
910             'ref_type_id' => '2',
911             'owner_id2' => '94701913'
912             },
913             '9729071394' => {
914             'owner_name2' => '',
915             'arg_id1' => '0',
916             'date' => '2014-07-08 19:03:04',
917             'reason' => '',
918             'tax_receiver_id' => '',
919             'owner_name1' => 'Milolika Muvila',
920             'amount' => '-28369982.50',
921             'owner_id1' => '94701913',
922             'tax_amount' => '',
923             'balance' => '785777605.44',
924             'arg_name1' => '',
925             'ref_id' => '9729071394',
926             'ref_type_id' => '42',
927             'owner_id2' => '0'
928             }
929             }
930              
931             =cut
932              
933             sub wallet_journal {
934 1     1 1 3624 my ($self, %args) = @_;
935              
936 1   33     11 my $character_id = $args{character_id} || $self->character_id();
937 1 50       3 croak('No character_id specified') unless $character_id;
938              
939 1   50     5 my $row_count = $args{row_count} || 2560;
940 1   50     5 my $account_key = $args{account_key} || 1000;
941              
942              
943             my $data = $self->_load_xml(
944             path => 'char/WalletJournal.xml.aspx',
945             requires_auth => 1,
946             character_id => $character_id,
947             row_count => $row_count,
948             account_key => $account_key,
949             from_id => $args{from_id},
950 1         6 );
951              
952 1         4 my $result = $data->{result}->{rowset}->{row};
953              
954 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
955              
956 1         4 my $journal;
957 1         4 foreach my $r_id ( keys %$result ) {
958             $journal->{$r_id} = {
959             ref_id => $r_id,
960             date => $result->{$r_id}->{date},
961             ref_type_id => $result->{$r_id}->{refTypeID},
962             owner_name1 => $result->{$r_id}->{ownerName1},
963             owner_id1 => $result->{$r_id}->{ownerID1},
964             owner_name2 => $result->{$r_id}->{ownerName2},
965             owner_id2 => $result->{$r_id}->{ownerID2},
966             arg_name1 => $result->{$r_id}->{argName1},
967             arg_id1 => $result->{$r_id}->{argID1},
968             amount => $result->{$r_id}->{amount},
969             balance => $result->{$r_id}->{balance},
970             reason => $result->{$r_id}->{reason},
971             tax_amount => $result->{$r_id}->{taxAmount},
972             tax_receiver_id => $result->{$r_id}->{taxReceiverID},
973 10         71 };
974             }
975              
976 1         3 $journal->{cached_until} = $data->{cachedUntil};
977              
978 1         17 return $journal;
979             }
980              
981             =head2 mail_messages
982              
983             my $mail_messages = $eapi->mail_messages( character_id => $character_id );
984              
985             Returns a hashref with the following structure:
986              
987             {
988             '331477595' => {
989             'to_list_id' => '145156607',
990             'message_id' => '331477595',
991             'to_character_ids' => '',
992             'sender_id' => '91669871',
993             'sent_date' => '2013-10-08 06:30:00',
994             'to_corp_or_alliance_id' => '',
995             'title' =>
996             "\x{420}\x{430}\x{441}\x{43f}\x{440}\x{43e}\x{434}\x{430}\x{436}\x{430}",
997             'sender_name' => 'Valerii Ostudnev'
998             },
999             '336393982' => {
1000             'to_list_id' => '',
1001             'message_id' => '336393982',
1002             'to_character_ids' => '1203082547',
1003             'sender_id' => '90922771',
1004             'sent_date' => '2014-03-02 13:30:00',
1005             'to_corp_or_alliance_id' => '',
1006             'title' => 'TSG -> Z-H',
1007             'sender_name' => 'Chips Merkaba'
1008             },
1009             'cached_until' => '2014-07-10 18:33:59'
1010             }
1011              
1012             =cut
1013              
1014             sub mail_messages {
1015 1     1 1 806 my ($self, %args) = @_;
1016              
1017 1   33     10 my $character_id = $args{character_id} || $self->character_id();
1018 1 50       4 croak('No character_id specified') unless $character_id;
1019              
1020 1         4 my $data = $self->_load_xml(
1021             path => 'char/MailMessages.xml.aspx',
1022             requires_auth => 1,
1023             character_id => $character_id,
1024             );
1025              
1026 1         3 my $result = $data->{result}->{rowset}->{row};
1027              
1028 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
1029              
1030 1         2 my $messages;
1031            
1032 1         5 foreach my $mes_id ( keys %$result ) {
1033             $messages->{$mes_id} = {
1034             message_id => $mes_id,
1035             sender_id => $result->{$mes_id}->{senderID},
1036             sender_name => $result->{$mes_id}->{senderName},
1037             sent_date => $result->{$mes_id}->{sentDate},
1038             title => $result->{$mes_id}->{title},
1039             to_corp_or_alliance_id => $result->{$mes_id}->{toCorpOrAllianceID},
1040             to_character_ids => $result->{$mes_id}->{toCharacterIDs},
1041             to_list_id => $result->{$mes_id}->{toListID},
1042 2         17 };
1043             }
1044 1         3 $messages->{cached_until} = $data->{cachedUntil};
1045              
1046 1         8 return $messages;
1047             }
1048              
1049             =head2 mail_bodies
1050              
1051             my $mail_bodies = $eapi->mail_bodies( character_id => $character_id, ids => $ids );
1052              
1053             Returns a hashref with the following structure:
1054              
1055             {
1056             'cached_until' => '2024-07-07 18:13:16',
1057             'missing_message_ids' => '331477591',
1058             '331477595' =>
1059             "[Multiple Items]"
1060             }
1061              
1062             =cut
1063              
1064             sub mail_bodies {
1065 1     1 1 751 my ($self, %args) = @_;
1066              
1067 1   33     11 my $character_id = $args{character_id} || $self->character_id();
1068 1 50       4 croak('No character_id specified') unless $character_id;
1069 1 50       4 croak('No comma separated messages ids specified') unless $args{ids};
1070              
1071             my $data = $self->_load_xml(
1072             path => 'char/MailBodies.xml.aspx',
1073             requires_auth => 1,
1074             character_id => $character_id,
1075             ids => $args{ids},
1076 1         5 );
1077              
1078 1         3 my $result = $data->{result}->{rowset}->{row};
1079              
1080 1 50       14 return $self->_get_error( $data ) if defined $data->{error};
1081              
1082 1         3 my $bodies;
1083            
1084 1         4 foreach my $mes_id ( keys %$result ) {
1085 1         4 $bodies->{$mes_id} = $result->{$mes_id}->{content};
1086             }
1087              
1088 1         3 $bodies->{cached_until} = $data->{cachedUntil};
1089 1         2 $bodies->{missing_message_ids} = $data->{result}->{missingMessageIDs};
1090              
1091 1         6 return $bodies;
1092             }
1093              
1094             =head2 mail_lists
1095              
1096             my $mail_lists = $eapi->mail_lists( character_id => $character_id );
1097              
1098             Returns a hashref with the following structure:
1099              
1100             {
1101             'cached_until' => '2014-07-11 00:06:57',
1102             '145156367' => 'RAISA Shield Fits'
1103             }
1104              
1105             =cut
1106              
1107             sub mail_lists {
1108 1     1 1 4167 my ($self, %args) = @_;
1109              
1110 1   33     10 my $character_id = $args{character_id} || $self->character_id();
1111 1 50       5 croak('No character_id specified') unless $character_id;
1112              
1113 1         4 my $data = $self->_load_xml(
1114             path => 'char/mailinglists.xml.aspx',
1115             requires_auth => 1,
1116             character_id => $character_id,
1117             );
1118              
1119 1         3 my $result = $data->{result}->{rowset}->{row};
1120              
1121 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
1122              
1123 1         2 my $lists;
1124 1         4 foreach my $list_id ( keys %$result ) {
1125 1         4 $lists->{$list_id} = $result->{$list_id}->{displayName};
1126             }
1127              
1128 1         3 $lists->{cached_until} = $data->{cachedUntil};
1129            
1130 1         6 return $lists;
1131             }
1132              
1133             =head2 character_name
1134              
1135             my $character_name = $eapi->character_name( ids => '90922771,94701913' );
1136              
1137             Returns a hashref with the following structure:
1138              
1139             {
1140             '94701913' => 'Milolika Muvila',
1141             'cached_until' => '2014-08-10 20:59:55',
1142             '90922771' => 'Chips Merkaba'
1143             }
1144              
1145             =cut
1146              
1147             sub character_name {
1148 1     1 1 1309 my ($self, %args) = @_;
1149              
1150 1 50       5 croak('No comma separated character ids specified') unless $args{ids};
1151              
1152             my $data = $self->_load_xml(
1153             path => 'eve/CharacterName.xml.aspx',
1154             ids => $args{ids},
1155 1         4 );
1156              
1157 1         3 my $result = $data->{result}->{rowset}->{row};
1158              
1159 1 50       4 return $self->_get_error( $data ) if defined $data->{error};
1160              
1161 1         3 my $names;
1162 1         3 foreach my $char_id ( keys %$result ) {
1163 2         5 $names->{$char_id} = $result->{$char_id}->{name};
1164             }
1165              
1166 1         3 $names->{cached_until} = $data->{cachedUntil};
1167            
1168 1         7 return $names;
1169             }
1170              
1171             =head2 character_ids
1172              
1173             my $character_ids = $eapi->character_ids( names => 'Milolika Muvila,Chips Merkaba' );
1174              
1175             Returns a hashref with the following structure:
1176              
1177             {
1178             '94701913' => 'Milolika Muvila',
1179             'cached_until' => '2014-08-10 20:59:55',
1180             '90922771' => 'Chips Merkaba'
1181             }
1182              
1183             =cut
1184              
1185             sub character_ids {
1186 1     1 1 832 my ($self, %args) = @_;
1187              
1188 1 50       6 croak('No comma separated character names specified') unless $args{names};
1189              
1190             my $data = $self->_load_xml(
1191             path => 'eve/CharacterID.xml.aspx',
1192             names => $args{names},
1193 1         11 );
1194              
1195 1         4 my $result = $data->{result}->{rowset}->{row};
1196              
1197 1 50       6 return $self->_get_error( $data ) if defined $data->{error};
1198              
1199 1         2 my $ids;
1200 1         5 foreach my $char_id ( keys %$result ) {
1201 3         9 $ids->{$char_id} = $result->{$char_id}->{name};
1202             }
1203              
1204 1         3 $ids->{cached_until} = $data->{cachedUntil};
1205            
1206 1         7 return $ids;
1207             }
1208              
1209             =head2 station_list
1210              
1211             my $station_list = $eapi->station_list();
1212              
1213             Returns a hashref with the following structure:
1214              
1215             {
1216             '61000051' => {
1217             'station_type_id' => '21644',
1218             'corporation_name' => 'Nulli Secunda Holding',
1219             'corporation_id' => '1463841432',
1220             'station_name' => 'DB1R-4 VIII - We brought the Trash Out',
1221             'solar_system_id' => '30004470',
1222             'station_id' => '61000051'
1223             },
1224             '61000438' => {
1225             'station_type_id' => '21646',
1226             'corporation_name' => 'Greater Western Co-Prosperity Sphere Exec',
1227             'corporation_id' => '98237912',
1228             'station_name' => 'F-D49D III - Error - Clever name not found',
1229             'solar_system_id' => '30000279',
1230             'station_id' => '61000438'
1231             }
1232             }
1233              
1234             =cut
1235              
1236             sub station_list {
1237 1     1 1 831 my ($self) = @_;
1238              
1239 1         5 my $data = $self->_load_xml(
1240             path => 'eve/ConquerableStationList.xml.aspx',
1241             );
1242              
1243 1 50       5 return $self->_get_error( $data ) if defined $data->{error};
1244              
1245 1         2 my $stations = {};
1246              
1247 1         3 my $rows = $data->{result}->{rowset}->{row};
1248 1         5 foreach my $station_id (keys %$rows) {
1249             $stations->{$station_id} = {
1250             station_id => $station_id,
1251             station_name => $rows->{$station_id}->{stationName},
1252             station_type_id => $rows->{$station_id}->{stationTypeID},
1253             solar_system_id => $rows->{$station_id}->{solarSystemID},
1254             corporation_id => $rows->{$station_id}->{corporationID},
1255             corporation_name => $rows->{$station_id}->{corporationName},
1256 3         20 };
1257             }
1258              
1259 1         3 $stations->{cached_until} = $data->{cachedUntil};
1260              
1261 1         8 return $stations;
1262              
1263             }
1264              
1265             =head2 corporation_sheet
1266              
1267             my $station_list = $eapi->corporation_sheet();
1268              
1269             Returns a hashref with the following structure:
1270              
1271             {
1272             'shares' => '1000',
1273             'faction_id' => '0',
1274             'cached_until' => '2014-08-24 22:18:02',
1275             'member_count' => '43',
1276             'alliance_id' => '0',
1277             'corporation_id' => '1043735888',
1278             'description' =>
1279             "\x{418}\x{441}\x{441}\x{43b}\x{435}\x{434}\x{43e}\x{432}\x{430}\x{43d}\x{438}\x{44f} \x{438} \x{440}\x{430}\x{437}\x{440}\x{430}\x{431}\x{43e}\x{442}\x{43a}\x{438}",
1280             'station_id' => '60004861',
1281             'ceo_name' => 'Krasotulya',
1282             'logo' => {
1283             'color3' => '674',
1284             'color1' => '677',
1285             'shape3' => '415',
1286             'shape2' => '480',
1287             'graphic_id' => '0',
1288             'shape1' => '437',
1289             'color2' => '676'
1290             },
1291             'tax_rate' => '5',
1292             'corporation_name' => 'Zaporozhye Sich',
1293             'ceo_id' => '423270919',
1294             'url' => 'http://',
1295             'station_name' => 'Lasleinur V - Moon 11 - Republic Fleet Assembly Plant'
1296             }
1297              
1298             =cut
1299              
1300             sub corporation_sheet {
1301 1     1 1 1491 my ($self, %args) = @_;
1302              
1303 1 50       5 croak('No corporation_id specified') unless $args{corporation_id};
1304              
1305             my $data = $self->_load_xml(
1306             path => 'corp/CorporationSheet.xml.aspx',
1307             requires_auth => 1,
1308             corporation_id => $args{corporation_id},
1309 1         4 );
1310              
1311 1 50       6 return $self->_get_error( $data ) if defined $data->{error};
1312              
1313 1         4 my $corp_info = {};
1314              
1315 1         3 my $result = $data->{result};
1316            
1317 1         3 $corp_info->{cached_until} = $data->{cachedUntil};
1318 1         3 $corp_info->{corporation_id} = $result->{corporationID};
1319 1         2 $corp_info->{corporation_name} = $result->{corporationName};
1320 1         3 $corp_info->{ticker} = $result->{ticker};
1321 1         2 $corp_info->{ceo_id} = $result->{ceoID};
1322 1         2 $corp_info->{ceo_name} = $result->{ceoName};
1323 1         3 $corp_info->{station_id} = $result->{stationID};
1324 1         4 $corp_info->{station_name} = $result->{stationName};
1325 1         2 $corp_info->{description} = $result->{description};
1326 1         3 $corp_info->{url} = $result->{url};
1327 1         3 $corp_info->{alliance_id} = $result->{allianceID};
1328 1         3 $corp_info->{faction_id} = $result->{factionID};
1329 1         3 $corp_info->{tax_rate} = $result->{taxRate};
1330 1         3 $corp_info->{member_count} = $result->{memberCount};
1331 1         2 $corp_info->{shares} = $result->{shares};
1332 1         5 $corp_info->{logo}->{graphic_id} = $result->{logo}->{graphicID};
1333 1         4 $corp_info->{logo}->{shape1} = $result->{logo}->{shape1};
1334 1         2 $corp_info->{logo}->{shape2} = $result->{logo}->{shape2};
1335 1         3 $corp_info->{logo}->{shape3} = $result->{logo}->{shape3};
1336 1         3 $corp_info->{logo}->{color1} = $result->{logo}->{color1};
1337 1         3 $corp_info->{logo}->{color2} = $result->{logo}->{color2};
1338 1         2 $corp_info->{logo}->{color3} = $result->{logo}->{color3};
1339              
1340 1         9 return $corp_info;
1341             }
1342              
1343             # Generate error answer
1344             sub _get_error {
1345 0     0   0 my ($self, $data) = @_;
1346              
1347             return {
1348 0   0     0 error => $data->{error} || { code => 500, content => 'Unknown error' },
1349             };
1350             }
1351              
1352             # convert keys
1353             sub _parse_assets {
1354 3     3   7 my ($self, $xml) = @_;
1355              
1356 3 50       9 return () unless $xml;
1357              
1358 3         4 my $parsed;
1359 3         6 my $rows = $xml->{rowset}->{row};
1360              
1361 3         12 foreach my $id ( keys %$rows ) {
1362 29         84 $parsed->{$id}->{item_id} = $id;
1363 29 100       61 $parsed->{$id}->{location_id} = $rows->{$id}->{locationID} if $rows->{$id}->{locationID};
1364 29         47 $parsed->{$id}->{raw_quantity} = $rows->{$id}->{rawQuantity};
1365 29         58 $parsed->{$id}->{quantity} = $rows->{$id}->{quantity};
1366 29         50 $parsed->{$id}->{flag} = $rows->{$id}->{flag};
1367 29         46 $parsed->{$id}->{singleton} = $rows->{$id}->{singleton};
1368 29         46 $parsed->{$id}->{type_id} = $rows->{$id}->{typeID};
1369              
1370 29 100 66     65 if ( $rows->{$id}->{rowset} && $rows->{$id}->{rowset}->{name} eq 'contents' ) {
1371 2         7 $parsed->{$id}->{contents} = $self->_parse_assets( $rows->{$id} );
1372             }
1373             }
1374              
1375 3         30 return $parsed;
1376             }
1377              
1378             sub _load_xml {
1379 20     20   48 my $self = shift;
1380              
1381 20         80 my $xml = $self->_retrieve_xml( @_ );
1382              
1383 20         2325 my $data = $self->_parse_xml( $xml );
1384 20 50       105 die('Unsupported EveOnline API XML version (requires version 2)') if ($data->{version} != 2);
1385              
1386 20         56 return $data;
1387             }
1388              
1389             sub _retrieve_xml {
1390 0     0   0 my ($self, %args) = @_;
1391              
1392 0 0       0 croak('No feed path provided') if !$args{path};
1393              
1394 0         0 my $params = {};
1395              
1396 0 0       0 if ($args{requires_auth}) {
1397 0         0 $params->{keyID} = $self->user_id();
1398 0         0 $params->{vCode} = $self->api_key();
1399             }
1400              
1401 0 0       0 if ($args{character_id}) {
1402 0         0 $params->{characterID} = $args{character_id};
1403             }
1404 0 0       0 if ($args{row_count}) {
1405 0         0 $params->{rowCount} = $args{row_count};
1406             }
1407 0 0       0 if ($args{account_key}) {
1408 0         0 $params->{accountKey} = $args{account_key};
1409             }
1410 0 0       0 if ($args{from_id}) {
1411 0         0 $params->{fromID} = $args{from_id};
1412             }
1413 0 0       0 if ($args{ids}) {
1414 0         0 $params->{ids} = $args{ids};
1415             }
1416 0 0       0 if ($args{names}) {
1417 0         0 $params->{names} = $args{names};
1418             }
1419 0 0       0 if ($args{corporation_id}) {
1420 0         0 $params->{corporationID} = $args{corporation_id};
1421             }
1422              
1423 0         0 my $uri = URI->new( $self->api_url() . '/' . $args{path} );
1424 0         0 $uri->query_form( $params );
1425              
1426 0         0 my $xml = $self->ua->get( $uri->as_string() );
1427              
1428 0         0 return $xml->content;
1429             }
1430              
1431             sub _parse_xml {
1432 20     20   59 my ($self, $xml) = @_;
1433              
1434 20         148 my $data = XML::Simple::XMLin(
1435             $xml,
1436             ForceArray => ['row'],
1437             KeyAttr => ['characterID', 'listID', 'messageID', 'transactionID', 'refID', 'itemID', 'typeID', 'stationID', 'bonusType', 'groupID', 'refTypeID', 'solarSystemID', 'name', 'contactID'],
1438             );
1439              
1440 20         740164 return $data;
1441             }
1442              
1443             1;
1444             __END__