eaal 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +12 -9
- data/README.rdoc +5 -1
- data/Rakefile +26 -26
- data/lib/eaal.rb +45 -6
- data/lib/eaal/api.rb +77 -0
- data/lib/eaal/cache/base.rb +27 -0
- data/lib/eaal/cache/file.rb +62 -0
- data/lib/eaal/cache/memcached.rb +30 -0
- data/lib/eaal/exception.rb +40 -0
- data/lib/eaal/{eaal_result.rb → result.rb} +123 -123
- data/lib/eaal/{eaal_rowset.rb → rowset.rb} +69 -69
- data/test/fixtures/test/test/account/Characters/Request_.xml +10 -10
- data/test/fixtures/test/test/char/Killlog/Request_.xml +5 -5
- data/test/fixtures/test/test/char/Killlog/Request_characterID:12345.xml +18 -18
- data/test/fixtures/test/test/eve/AllianceList/Request_.xml +10523 -0
- data/test/test_eaal.rb +53 -42
- metadata +25 -12
- data/lib/eaal/eaal.rb +0 -114
- data/lib/eaal/eaal_cache.rb +0 -90
- data/lib/eaal/eaal_exception.rb +0 -42
data/test/test_eaal.rb
CHANGED
@@ -1,42 +1,53 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
-
|
3
|
-
class TestEaal < Test::Unit::TestCase
|
4
|
-
|
5
|
-
# prepare the api object. sets EAAL to use FileCache to load fixtures
|
6
|
-
def setup
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
# test if we realy got an API Object
|
11
|
-
def test_api_class
|
12
|
-
assert_instance_of EAAL::API, @api
|
13
|
-
end
|
14
|
-
|
15
|
-
# some random tests if parsing the xml builds the right class
|
16
|
-
def test_api_classes
|
17
|
-
@api.scope = "char"
|
18
|
-
assert_raise (EAAL::Exception.EveAPIException(105)) { @api.Killlog }
|
19
|
-
assert_equal @api.Killlog(:characterID => 12345).class.name, "CharKilllogResult"
|
20
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.class.name, "CharKilllogRowsetKills"
|
21
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.first.class.name, "CharKilllogRowsetKillsRow"
|
22
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.first.victim.class.name, "EAAL::Result::ResultElement"
|
23
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.first.attackers.first.class.name, "CharKilllogRowsetKillsRowRowsetAttackersRow"
|
24
|
-
end
|
25
|
-
|
26
|
-
# some random data checks to ensure stuff can be read
|
27
|
-
def test_api_parse_data
|
28
|
-
@api.scope = "account"
|
29
|
-
assert_equal @api.Characters.characters.first.name, "Test Tester"
|
30
|
-
assert_equal @api.Characters.characters.second.corporationID, "7890"
|
31
|
-
@api.scope = "char"
|
32
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.length, 1
|
33
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.first.victim.characterName, "Peter Powers"
|
34
|
-
assert_equal @api.Killlog(:characterID => 12345).kills.first.attackers.first.characterID, "12345"
|
35
|
-
end
|
36
|
-
|
37
|
-
# test to check if bug 23177 is fixed. that bug lead to RowSets beeing encapsulated in ResultElements.
|
38
|
-
def test_bug_23177
|
39
|
-
@api.scope = "eve"
|
40
|
-
assert_kind_of EAAL::Rowset::RowsetBase, @api.AllianceList.alliances.first.memberCorporations
|
41
|
-
end
|
42
|
-
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestEaal < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# prepare the api object. sets EAAL to use FileCache to load fixtures
|
6
|
+
def setup
|
7
|
+
EAAL.cache = EAAL::Cache::FileCache.new(File.dirname(__FILE__) + '/fixtures/')
|
8
|
+
@api = EAAL::API.new('test','test')
|
9
|
+
end
|
10
|
+
# test if we realy got an API Object
|
11
|
+
def test_api_class
|
12
|
+
assert_instance_of EAAL::API, @api
|
13
|
+
end
|
14
|
+
|
15
|
+
# some random tests if parsing the xml builds the right class
|
16
|
+
def test_api_classes
|
17
|
+
@api.scope = "char"
|
18
|
+
assert_raise (EAAL::Exception.EveAPIException(105)) { @api.Killlog }
|
19
|
+
assert_equal @api.Killlog(:characterID => 12345).class.name, "CharKilllogResult"
|
20
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.class.name, "CharKilllogRowsetKills"
|
21
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.first.class.name, "CharKilllogRowsetKillsRow"
|
22
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.first.victim.class.name, "EAAL::Result::ResultElement"
|
23
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.first.attackers.first.class.name, "CharKilllogRowsetKillsRowRowsetAttackersRow"
|
24
|
+
end
|
25
|
+
|
26
|
+
# some random data checks to ensure stuff can be read
|
27
|
+
def test_api_parse_data
|
28
|
+
@api.scope = "account"
|
29
|
+
assert_equal @api.Characters.characters.first.name, "Test Tester"
|
30
|
+
assert_equal @api.Characters.characters.second.corporationID, "7890"
|
31
|
+
@api.scope = "char"
|
32
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.length, 1
|
33
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.first.victim.characterName, "Peter Powers"
|
34
|
+
assert_equal @api.Killlog(:characterID => 12345).kills.first.attackers.first.characterID, "12345"
|
35
|
+
end
|
36
|
+
|
37
|
+
# test to check if bug 23177 is fixed. that bug lead to RowSets beeing encapsulated in ResultElements.
|
38
|
+
def test_bug_23177
|
39
|
+
@api.scope = "eve"
|
40
|
+
assert_kind_of EAAL::Rowset::RowsetBase, @api.AllianceList.alliances.first.memberCorporations
|
41
|
+
end
|
42
|
+
# Test to ensure Memcached works
|
43
|
+
def test_memcached
|
44
|
+
# TODO: API needs mocking properly instead of depending on file cache for test loading.
|
45
|
+
EAAL.cache = EAAL::Cache::MemcachedCache.new
|
46
|
+
@api.scope = "account"
|
47
|
+
# Should store to cache
|
48
|
+
assert_equal @api.Characters.characters.first.name, "Test Tester"
|
49
|
+
# Should get from cache
|
50
|
+
assert_equal @api.Characters.characters.first.name, "Test Tester"
|
51
|
+
# TODO: Needs some better tests here.
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eaal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Petermann
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-10 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,16 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: "0.6"
|
34
34
|
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: memcache-client
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.7.1
|
44
|
+
version:
|
35
45
|
- !ruby/object:Gem::Dependency
|
36
46
|
name: newgem
|
37
47
|
type: :development
|
@@ -61,29 +71,32 @@ extensions: []
|
|
61
71
|
|
62
72
|
extra_rdoc_files:
|
63
73
|
- History.txt
|
74
|
+
- LICENSE.txt
|
64
75
|
- Manifest.txt
|
65
76
|
- README.rdoc
|
66
|
-
- LICENSE.txt
|
67
77
|
files:
|
68
78
|
- History.txt
|
79
|
+
- LICENSE.txt
|
69
80
|
- Manifest.txt
|
70
81
|
- README.rdoc
|
71
|
-
- LICENSE.txt
|
72
82
|
- Rakefile
|
73
83
|
- lib/eaal.rb
|
74
|
-
- lib/eaal/
|
75
|
-
- lib/eaal/
|
76
|
-
- lib/eaal/
|
77
|
-
- lib/eaal/
|
78
|
-
- lib/eaal/
|
84
|
+
- lib/eaal/api.rb
|
85
|
+
- lib/eaal/cache/base.rb
|
86
|
+
- lib/eaal/cache/file.rb
|
87
|
+
- lib/eaal/cache/memcached.rb
|
88
|
+
- lib/eaal/exception.rb
|
89
|
+
- lib/eaal/result.rb
|
90
|
+
- lib/eaal/rowset.rb
|
79
91
|
- script/console
|
80
92
|
- script/destroy
|
81
93
|
- script/generate
|
82
|
-
- test/test_helper.rb
|
83
|
-
- test/test_eaal.rb
|
84
94
|
- test/fixtures/test/test/account/Characters/Request_.xml
|
85
|
-
- test/fixtures/test/test/char/Killlog/Request_characterID:12345.xml
|
86
95
|
- test/fixtures/test/test/char/Killlog/Request_.xml
|
96
|
+
- test/fixtures/test/test/char/Killlog/Request_characterID:12345.xml
|
97
|
+
- test/fixtures/test/test/eve/AllianceList/Request_.xml
|
98
|
+
- test/test_eaal.rb
|
99
|
+
- test/test_helper.rb
|
87
100
|
has_rdoc: true
|
88
101
|
homepage: " http://eaal.rubyforge.org"
|
89
102
|
post_install_message:
|
data/lib/eaal/eaal.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# EAAL by Peter Petermann <PeterPetermann@gmx.net>
|
3
|
-
# This library is licensed under the terms found in
|
4
|
-
# the LICENSE file distributed with it
|
5
|
-
#
|
6
|
-
# TODO:
|
7
|
-
# - more documenation
|
8
|
-
# - write tests (i know, i know, i fail badly)
|
9
|
-
# - more error handling (im certain i missed a few possibles)
|
10
|
-
# - cleanup (you can see that this is my first project in ruby, cant you?)
|
11
|
-
#
|
12
|
-
# THANKS:
|
13
|
-
# thanks go to all people on irc.coldfront.net, channel #eve-dev
|
14
|
-
# special thanks go to lisa (checkout her eve api library, reve,
|
15
|
-
# much more mature then mine) for answering my endless questions
|
16
|
-
# about ruby stuff (and for one or two snippets i stole from reve)
|
17
|
-
#++
|
18
|
-
|
19
|
-
require 'rubygems'
|
20
|
-
require 'hpricot'
|
21
|
-
require 'activesupport'
|
22
|
-
|
23
|
-
require 'net/http'
|
24
|
-
require 'uri'
|
25
|
-
require 'cgi'
|
26
|
-
|
27
|
-
module EAAL
|
28
|
-
|
29
|
-
mattr_reader :version_string, :version
|
30
|
-
|
31
|
-
@@version = "0.1.4"
|
32
|
-
@@version_string = "EAAL" + EAAL.version # the version string, used as client name in http requests
|
33
|
-
|
34
|
-
mattr_accessor :api_base, :additional_request_parameters, :cache
|
35
|
-
@@api_base = "http://api.eve-online.com/" # the url used as basis for all requests, you might want to use gatecamper url or a personal proxy instead
|
36
|
-
@@additional_request_parameters = {} # hash, if :key => value pairs are added those will be added to each request
|
37
|
-
@@cache = EAAL::Cache::NoCache.new # caching object, see EAAL::Cache::FileCache for an Example
|
38
|
-
|
39
|
-
# EAAL::API class
|
40
|
-
# Usage Example:
|
41
|
-
# api = EAAL::API.new("my userid", "my API key")
|
42
|
-
# result = api.Characters
|
43
|
-
# result.characters.each{|character|
|
44
|
-
# puts character.name
|
45
|
-
# }
|
46
|
-
class API
|
47
|
-
attr_accessor :userid, :key, :scope
|
48
|
-
|
49
|
-
# constructor
|
50
|
-
# Expects:
|
51
|
-
# * userid (String | Integer) the users id
|
52
|
-
# * key (String) the apikey Full or Restricted
|
53
|
-
# * scope (String) defaults to account
|
54
|
-
def initialize(userid, key, scope="account")
|
55
|
-
self.userid = userid.to_s
|
56
|
-
self.key = key.to_s
|
57
|
-
self.scope = scope.to_s
|
58
|
-
end
|
59
|
-
|
60
|
-
# create an xml request according to the method called
|
61
|
-
# this is used to dynamicaly create api calls and
|
62
|
-
# should usually not be called directly
|
63
|
-
# * method (const)
|
64
|
-
# * args
|
65
|
-
def method_missing(method, *args)
|
66
|
-
scope = self.scope
|
67
|
-
args_hash = args.first
|
68
|
-
args_hash = {} unless args_hash
|
69
|
-
self.request_xml(scope, method.id2name, args_hash)
|
70
|
-
end
|
71
|
-
|
72
|
-
# make a request to the api. will use cache if set.
|
73
|
-
# usually not called by the user directly
|
74
|
-
# * scope (String)
|
75
|
-
# * name (String)
|
76
|
-
# * opts (Hash)
|
77
|
-
def request_xml(scope, name, opts)
|
78
|
-
opts = EAAL.additional_request_parameters.merge(opts)
|
79
|
-
xml = EAAL.cache.load(self.userid, self.key, scope, name,opts)
|
80
|
-
if not xml
|
81
|
-
source = URI.parse(EAAL.api_base + scope + '/' + name +'.xml.aspx')
|
82
|
-
req_path = source.path + format_url_request(opts.merge({
|
83
|
-
:userid => self.userid,
|
84
|
-
:apikey => self.key}))
|
85
|
-
req = Net::HTTP::Get.new(req_path)
|
86
|
-
req[EAAL.version_string]
|
87
|
-
res = Net::HTTP.new(source.host, source.port).start {|http| http.request(req) } #one request for now
|
88
|
-
case res
|
89
|
-
when Net::HTTPOK
|
90
|
-
when Net::HTTPNotFound
|
91
|
-
raise EAAL::Exception::APINotFoundError.new("The requested API (#{scope} / #{name}) could not be found.")
|
92
|
-
else
|
93
|
-
raise EAAL::Exception::HTTPError.new("An HTTP Error occured, body: " + res.body)
|
94
|
-
end
|
95
|
-
EAAL.cache.save(self.userid, self.key, scope,name,opts, res.body)
|
96
|
-
xml = res.body
|
97
|
-
end
|
98
|
-
doc = Hpricot.XML(xml)
|
99
|
-
result = EAAL::Result.new(scope.capitalize + name, doc)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Turns a hash into ?var=baz&bam=boo
|
103
|
-
# stolen from Reve (thx lisa)
|
104
|
-
# * opts (Hash)
|
105
|
-
def format_url_request(opts)
|
106
|
-
req = "?"
|
107
|
-
opts.stringify_keys!
|
108
|
-
opts.keys.sort.each do |key|
|
109
|
-
req += "#{CGI.escape(key.to_s)}=#{CGI.escape(opts[key].to_s)}&" if opts[key]
|
110
|
-
end
|
111
|
-
req.chop # We are lazy and append a & to each pair even if it's the last one. FIXME: Don't do this.
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
data/lib/eaal/eaal_cache.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# EAAL by Peter Petermann <PeterPetermann@gmx.net>
|
3
|
-
# This library is licensed under the terms found in
|
4
|
-
# the LICENSE file distributed with it
|
5
|
-
#++
|
6
|
-
require 'fileutils'
|
7
|
-
|
8
|
-
module EAAL
|
9
|
-
# The Classes in this module are objects that may be used as value
|
10
|
-
# of EAAL.cache.
|
11
|
-
# By default EAAL uses the NoCache class, where no caching is done.
|
12
|
-
# If a working cache class is used it will store the xml data
|
13
|
-
# and return it, so no requests to the API are done (as long as valid xml is available)
|
14
|
-
module Cache
|
15
|
-
|
16
|
-
# EAAL::Cache::FileCache
|
17
|
-
# File based xml cache which respects the cachedUntil of the Eve API
|
18
|
-
# Usage:
|
19
|
-
# EAAL.cache = EAAL::Cache::FileCache.new
|
20
|
-
# Or
|
21
|
-
# EAAL.cache = EAAL::Cache::FileCache.new("/path/to/place/to/store/xml/data")
|
22
|
-
class FileCache
|
23
|
-
attr_accessor :basepath
|
24
|
-
|
25
|
-
# constructor, takes one argument which is the path
|
26
|
-
# where files should be written
|
27
|
-
# * basepath (String) path which should be used to store cached data. defaults to $HOME/.eaal/cache/
|
28
|
-
def initialize(basepath = "#{ENV['HOME']}/.eaal/cache")
|
29
|
-
if basepath[(basepath.length) -1, basepath.length] != "/"
|
30
|
-
basepath += "/"
|
31
|
-
end
|
32
|
-
@basepath = basepath
|
33
|
-
end
|
34
|
-
|
35
|
-
# create the path/filename for the cache file
|
36
|
-
def filename(userid, apikey, scope, name, args)
|
37
|
-
ret =""
|
38
|
-
args.delete_if { |k,v| (v || "").to_s.length == 0 }
|
39
|
-
h = args.stringify_keys
|
40
|
-
ret += h.sort.flatten.collect{ |e| e.to_s }.join(':')
|
41
|
-
hash = ret.gsub(/:$/,'')
|
42
|
-
"#{@basepath}#{userid}/#{apikey}/#{scope}/#{name}/Request_#{hash}.xml"
|
43
|
-
end
|
44
|
-
|
45
|
-
# load xml if available, return false if not available, or cachedUntil ran out
|
46
|
-
def load(userid, apikey, scope, name, args)
|
47
|
-
filename = self.filename(userid, apikey,scope,name,args)
|
48
|
-
if not File.exist?(filename)
|
49
|
-
ret = false
|
50
|
-
else
|
51
|
-
xml = File.open(filename).read
|
52
|
-
if self.validate_cache(xml, name)
|
53
|
-
ret = xml
|
54
|
-
else
|
55
|
-
ret = false
|
56
|
-
end
|
57
|
-
end
|
58
|
-
ret
|
59
|
-
end
|
60
|
-
|
61
|
-
# validate cached datas cachedUntil
|
62
|
-
def validate_cache(xml, name)
|
63
|
-
doc = Hpricot.XML(xml)
|
64
|
-
if name == "WalletJournal"
|
65
|
-
Time.at((doc/"/eveapi/cachedUntil").inner_html.to_time.to_i + 3600) > Time.now
|
66
|
-
else
|
67
|
-
(doc/"/eveapi/cachedUntil").inner_html.to_time > Time.now
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# save xml data to file
|
72
|
-
def save(userid, apikey, scope, name, args, xml)
|
73
|
-
filename = self.filename(userid, apikey,scope,name,args)
|
74
|
-
FileUtils.mkdir_p(File.dirname(filename))
|
75
|
-
File.open(filename,'w') { |f| f.print xml }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# NoCache class
|
80
|
-
# dummy class which is used for non-caching behaviour (default)
|
81
|
-
class NoCache
|
82
|
-
def load(userid, apikey, scope, name, args)
|
83
|
-
false
|
84
|
-
end
|
85
|
-
def save(userid, apikey, scope, name, args, xml)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|
data/lib/eaal/eaal_exception.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# EAAL by Peter Petermann <PeterPetermann@gmx.net>
|
3
|
-
# This library is licensed under the terms found in
|
4
|
-
# the LICENSE file distributed with it
|
5
|
-
#++
|
6
|
-
module EAAL
|
7
|
-
module Exception
|
8
|
-
# creates the class for an EveAPIException
|
9
|
-
def self.EveAPIException(nr)
|
10
|
-
classname = "EveAPIException#{nr}"
|
11
|
-
if not Object.const_defined? classname
|
12
|
-
klass = Object.const_set(classname, Class.new(EAAL::Exception::EveAPIException))
|
13
|
-
else
|
14
|
-
klass = Object.const_get(classname)
|
15
|
-
end
|
16
|
-
klass
|
17
|
-
end
|
18
|
-
|
19
|
-
# raise the eve API exceptions, class will be dynamicaly created by classname
|
20
|
-
# EveAPIException followed by the APIs exception Number
|
21
|
-
def self.raiseEveAPIException(nr, msg)
|
22
|
-
raise EAAL::Exception.EveAPIException(nr).new(msg)
|
23
|
-
end
|
24
|
-
|
25
|
-
# all EAAL exceptions should extend this.
|
26
|
-
class EAALError < StandardError
|
27
|
-
end
|
28
|
-
|
29
|
-
# Used when an http error is encountered
|
30
|
-
class HTTPError < EAALError
|
31
|
-
end
|
32
|
-
|
33
|
-
# Used when the Eve API returns a 404
|
34
|
-
class APINotFoundError < HTTPError
|
35
|
-
end
|
36
|
-
|
37
|
-
# All API Errors should be derived from this
|
38
|
-
class EveAPIException < EAALError
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|