eve_online-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in eve_online-api.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011 Craig R Webster
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Eve Online API
2
+
3
+ I want to play with some of the data in EVE. CCP provide an API. Yay!
4
+
5
+ This README is a little lame because this code doesn't do much yet.
6
+ You can pull the SOV info and the skill tree. I'll (slowly) be working on exposing the other parts of the API, but of course, patches would be lovely.
7
+
8
+
9
+ ## Example use
10
+
11
+ require 'eve_online/api'
12
+
13
+ require 'logger'
14
+ logger = Logger.new STDOUT
15
+ logger.level = Logger::DEBUG
16
+
17
+ client = EveOnline::Api::Client.new :logger => logger
18
+ puts client.sovereignty.to_s
19
+ puts client.skill_tree.to_s
20
+
21
+
22
+ ## Licence
23
+
24
+ MIT. See LICENSE.
25
+
26
+
27
+ ## Authors
28
+
29
+ Craig R Webster <http://barkingiguana.com/>
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/eve_online/api/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Craig R Webster"]
6
+ gem.email = ["craig@barkingiguana.com"]
7
+ gem.description = %q{Ruby interface to the EVE Online API}
8
+ gem.summary = %q{Ruby interface to the EVE Online API}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "eve_online-api"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = EveOnline::Api::VERSION
17
+
18
+ gem.add_runtime_dependency 'null_logger'
19
+ gem.add_runtime_dependency 'active_support', '~> 3.0'
20
+ gem.add_runtime_dependency 'nokogiri', '~> 1.5'
21
+ end
@@ -0,0 +1 @@
1
+ require "eve_online/api"
@@ -0,0 +1,16 @@
1
+ require 'tmpdir'
2
+ require 'digest/sha1'
3
+ require 'null_logger'
4
+ require 'net/http'
5
+ require 'nokogiri'
6
+ require 'active_support/inflector'
7
+
8
+ require 'eve_online/api/version'
9
+ require 'eve_online/api/skill_groups'
10
+ require 'eve_online/api/skill_group'
11
+ require 'eve_online/api/skills'
12
+ require 'eve_online/api/skill'
13
+ require 'eve_online/api/solar_systems'
14
+ require 'eve_online/api/solar_system'
15
+ require 'eve_online/api/file_cache'
16
+ require 'eve_online/api/client'
@@ -0,0 +1,68 @@
1
+ module EveOnline
2
+ module Api
3
+ class Client
4
+ attr_accessor :api_base
5
+ private :api_base=, :api_base
6
+
7
+ attr_accessor :cache
8
+ private :cache=, :cache
9
+
10
+ attr_accessor :logger
11
+ private :logger=, :logger
12
+
13
+ def initialize options = {}
14
+ self.api_base = options[:api_base] || 'http://api.eve-online.com'
15
+ logger = options[:logger] || NullLogger.instance
16
+ self.cache = options[:cache] || FileCache.new(:logger => logger)
17
+ self.logger = logger
18
+ end
19
+
20
+ def skill_tree
21
+ logger.debug "Fetching skill tree"
22
+ results = get '/eve/SkillTree.xml.aspx'
23
+ end
24
+
25
+ def sovereignty
26
+ logger.debug "Fetching sovereignty information"
27
+ results = get '/map/Sovereignty.xml.aspx'
28
+ end
29
+
30
+ def get path
31
+ uri = URI.parse api_base + path
32
+ logger.debug "Asking cache for #{uri}"
33
+ cached_document = cache.get uri
34
+ logger.debug "Cache returned #{cached_document ? 'document' : 'nothing'}"
35
+ return results_from cached_document if cached_document
36
+ logger.debug "Making request to EVE API"
37
+ response = Net::HTTP.get uri
38
+ logger.debug "Parsing response"
39
+ doc = Nokogiri::XML response
40
+ expiration_string = doc.at_xpath '/eveapi/cachedUntil/text()'
41
+ expiration_date = Time.parse expiration_string.to_s
42
+ logger.debug "Told response is cached until #{expiration_date}"
43
+ cache.set uri, response, expiration_date
44
+ logger.debug "Returning response"
45
+ results_from response
46
+ end
47
+ private :get
48
+
49
+ def results_from xml
50
+ doc = Nokogiri::XML xml
51
+ result = doc.at_xpath '/eveapi/result/rowset'
52
+ evaluate_result result
53
+ end
54
+
55
+ def evaluate_result row
56
+ container_name = row['name']
57
+ container_name[0] = container_name[0].upcase
58
+ const_defined = EveOnline::Api.const_defined? container_name
59
+ logger.debug "#{const_defined ? 'Found' : 'Unknown'} container: #{container_name}"
60
+ return unless const_defined
61
+ logger.debug "Using container #{container_name}"
62
+ container_class = EveOnline::Api.const_get container_name
63
+ logger.debug "Class instance = #{container_class.inspect}"
64
+ container_class.new row
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,78 @@
1
+ module EveOnline
2
+ module Api
3
+ class FileCache
4
+ attr_accessor :directory
5
+ private :directory=, :directory
6
+
7
+ attr_accessor :logger
8
+ private :logger=, :logger
9
+
10
+ attr_accessor :boundary
11
+ private :boundary=, :boundary
12
+
13
+ def initialize options = {}
14
+ self.directory = options[:directory] || Dir.tmpdir
15
+ self.logger = options[:logger] || NullLogger.instance
16
+ self.boundary = options[:boundary] || '_FILE_CACHE_'
17
+ end
18
+
19
+ def get key
20
+ logger.debug "Cache asked for #{key}"
21
+ file = file_for key
22
+ return unless file
23
+ logger.debug "Reading from cache at #{file}"
24
+ File.read file
25
+ end
26
+
27
+ def set key, data, expiration_date
28
+ logger.debug "Asked to cache #{key} until #{expiration_date}"
29
+ request_time = Time.now
30
+ return unless expiration_date > request_time
31
+ hex = Digest::SHA1.hexdigest key.to_s
32
+ file_name = "#{expiration_date.to_i}#{boundary}#{hex}"
33
+ file_path = File.join directory, file_name
34
+ logger.debug "Realising cache instance as #{file_path}"
35
+ File.open file_path, 'w' do |file|
36
+ file.print data
37
+ end
38
+ logger.debug "Cached #{key} in #{file_path}"
39
+ end
40
+
41
+ def file_for key
42
+ logger.debug "Finding cache instances for #{key}"
43
+ hex = Digest::SHA1.hexdigest key.to_s
44
+ pattern = File.join directory, "*#{boundary}#{hex}"
45
+ logger.debug "Glob for #{pattern} on disk"
46
+ files = Dir.glob pattern
47
+ logger.debug "Found #{files.size} cache instances"
48
+ return unless files.any?
49
+ request_time = Time.now
50
+ logger.debug "Excluding expired instanced"
51
+ live = files.select { |file_name|
52
+ expiration_date = expiration_date file_name
53
+ expiration_date > request_time
54
+ }
55
+ logger.debug "Found #{live.size} live cache instances"
56
+ return unless live.any?
57
+ logger.debug "Selecting most recent live instance"
58
+ instance = live.sort_by { |file_name|
59
+ expiration_date file_name
60
+ }[-1]
61
+ expiration_date = expiration_date instance
62
+ logger.debug "Instance is #{instance}, expires = #{expiration_date}"
63
+ instance
64
+ end
65
+
66
+ def expiration_date file_path
67
+ logger.debug "Finding expiration date from #{file_path}"
68
+ file_name = File.basename file_path
69
+ logger.debug "File name = #{file_name}"
70
+ timestamp, _ = file_name.split %r{#{boundary}}, 2
71
+ logger.debug "Timestamp = #{timestamp}"
72
+ time = Time.at timestamp.to_i
73
+ logger.debug "Time = #{time}"
74
+ time
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,29 @@
1
+ module EveOnline
2
+ module Api
3
+ class Skill
4
+ attr_accessor :fragment
5
+ private :fragment=, :fragment
6
+
7
+ def initialize fragment
8
+ self.fragment = fragment
9
+ end
10
+
11
+ def id
12
+ fragment['typeID']
13
+ end
14
+
15
+ def name
16
+ fragment['typeName']
17
+ end
18
+
19
+ def <=> other
20
+ name <=> other.name
21
+ end
22
+ include Comparable
23
+
24
+ def to_s indent = 0
25
+ "#{' ' * indent}#{name} Skill (id:#{id})"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,43 @@
1
+ module EveOnline
2
+ module Api
3
+ class SkillGroup
4
+ attr_accessor :fragment
5
+ private :fragment=, :fragment
6
+
7
+ def initialize fragment
8
+ self.fragment = fragment
9
+ end
10
+
11
+ def id
12
+ fragment['groupID']
13
+ end
14
+
15
+ def name
16
+ fragment['groupName']
17
+ end
18
+
19
+ def <=> other
20
+ name <=> other.name
21
+ end
22
+ include Comparable
23
+
24
+ def merge other
25
+ other.skills_fragment.children.each do |child|
26
+ skills_fragment.add_child child
27
+ end
28
+ end
29
+
30
+ def skills
31
+ Skills.new skills_fragment
32
+ end
33
+
34
+ def skills_fragment
35
+ fragment.at_xpath './rowset'
36
+ end
37
+
38
+ def to_s indent = 0
39
+ "#{' ' * indent}#{name} Skill Group (id:#{id})\n#{skills.to_s(indent + 2)}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,36 @@
1
+ module EveOnline
2
+ module Api
3
+ class SkillGroups
4
+ attr_accessor :fragment
5
+ private :fragment=, :fragment
6
+
7
+ def initialize fragment
8
+ self.fragment = fragment
9
+ end
10
+
11
+ def each
12
+ rows = fragment.xpath './row'
13
+ skill_groups = rows.map do |row|
14
+ skill_group = SkillGroup.new row
15
+ end
16
+ skill_groups.group_by { |sg| sg.id }.each do |id, groups|
17
+ group = groups.pop
18
+ while next_group = groups.pop
19
+ group.merge next_group
20
+ end
21
+ yield group
22
+ end
23
+ end
24
+ include Enumerable
25
+
26
+ def to_s indent = 0
27
+ margin = " " * indent
28
+ ["#{margin}Skill Groups (#{to_a.size})"].tap do |s|
29
+ sort.each do |skill_group|
30
+ s << skill_group.to_s(indent + 2)
31
+ end
32
+ end.join "\n"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ module EveOnline
2
+ module Api
3
+ class Skills
4
+ attr_accessor :fragment
5
+ private :fragment=, :fragment
6
+
7
+ def initialize fragment
8
+ self.fragment = fragment
9
+ end
10
+
11
+ def each
12
+ rows = fragment.xpath './row'
13
+ rows.each do |row|
14
+ skill = Skill.new row
15
+ yield skill
16
+ end
17
+ end
18
+ include Enumerable
19
+
20
+ def to_s indent = 0
21
+ margin = " " * indent
22
+ [ "#{margin}Skills (#{to_a.size})" ].tap do |s|
23
+ sort.each do |skill|
24
+ s << skill.to_s(indent + 2)
25
+ end
26
+ end.join "\n"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module EveOnline
2
+ module Api
3
+ class SolarSystem
4
+ attr_accessor :fragment
5
+ private :fragment=, :fragment
6
+
7
+ def initialize fragment
8
+ self.fragment = fragment
9
+ end
10
+
11
+ def id
12
+ fragment['solarSystemID']
13
+ end
14
+
15
+ def name
16
+ fragment['solarSystemName']
17
+ end
18
+
19
+ def alliance_id
20
+ fragment['allianceID']
21
+ end
22
+
23
+ def corporation_id
24
+ fragment['corporationID']
25
+ end
26
+
27
+ def faction_id
28
+ fragment['factionID']
29
+ end
30
+
31
+ def <=> other
32
+ name <=> other.name
33
+ end
34
+ include Comparable
35
+
36
+ def to_s indent = 0
37
+ margin = " " * indent
38
+ "#{margin}#{name} Solar System (id:#{id}, alliance:#{alliance_id}, corporation:#{corporation_id}, faction:#{faction_id})"
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ module EveOnline
2
+ module Api
3
+ class SolarSystems
4
+ attr_accessor :fragment
5
+ private :fragment=, :fragment
6
+
7
+ def initialize fragment
8
+ self.fragment = fragment
9
+ end
10
+
11
+ def each
12
+ rows = fragment.xpath './row'
13
+ rows.each do |row|
14
+ solar_system = SolarSystem.new row
15
+ yield solar_system
16
+ end
17
+ end
18
+ include Enumerable
19
+
20
+ def to_s indent = 0
21
+ margin = " " * indent
22
+ ["#{margin}Solar Systems (#{to_a.size})"].tap do |s|
23
+ sort.each do |solar_system|
24
+ s << solar_system.to_s(indent + 2)
25
+ end
26
+ end.join "\n"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ module EveOnline
2
+ module Api
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eve_online-api
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Craig R Webster
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-12-31 00:00:00 +00:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: null_logger
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: active_support
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: "3.0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: nokogiri
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: "1.5"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ description: Ruby interface to the EVE Online API
50
+ email:
51
+ - craig@barkingiguana.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - Gemfile
61
+ - LICENSE
62
+ - README.md
63
+ - Rakefile
64
+ - eve_online-api.gemspec
65
+ - lib/eve_online-api.rb
66
+ - lib/eve_online/api.rb
67
+ - lib/eve_online/api/client.rb
68
+ - lib/eve_online/api/file_cache.rb
69
+ - lib/eve_online/api/skill.rb
70
+ - lib/eve_online/api/skill_group.rb
71
+ - lib/eve_online/api/skill_groups.rb
72
+ - lib/eve_online/api/skills.rb
73
+ - lib/eve_online/api/solar_system.rb
74
+ - lib/eve_online/api/solar_systems.rb
75
+ - lib/eve_online/api/version.rb
76
+ has_rdoc: true
77
+ homepage: ""
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options: []
82
+
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: "0"
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.6.2
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Ruby interface to the EVE Online API
104
+ test_files: []
105
+