eaal 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/History.txt
    CHANGED
    
    
    
        data/Manifest.txt
    CHANGED
    
    | 
         @@ -1,19 +1,22 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            History.txt
         
     | 
| 
      
 2 
     | 
    
         
            +
            LICENSE.txt
         
     | 
| 
       2 
3 
     | 
    
         
             
            Manifest.txt
         
     | 
| 
       3 
4 
     | 
    
         
             
            README.rdoc
         
     | 
| 
       4 
     | 
    
         
            -
            LICENSE.txt
         
     | 
| 
       5 
5 
     | 
    
         
             
            Rakefile
         
     | 
| 
       6 
6 
     | 
    
         
             
            lib/eaal.rb
         
     | 
| 
       7 
     | 
    
         
            -
            lib/eaal/ 
     | 
| 
       8 
     | 
    
         
            -
            lib/eaal/ 
     | 
| 
       9 
     | 
    
         
            -
            lib/eaal/ 
     | 
| 
       10 
     | 
    
         
            -
            lib/eaal/ 
     | 
| 
       11 
     | 
    
         
            -
            lib/eaal/ 
     | 
| 
      
 7 
     | 
    
         
            +
            lib/eaal/api.rb
         
     | 
| 
      
 8 
     | 
    
         
            +
            lib/eaal/cache/base.rb
         
     | 
| 
      
 9 
     | 
    
         
            +
            lib/eaal/cache/file.rb
         
     | 
| 
      
 10 
     | 
    
         
            +
            lib/eaal/cache/memcached.rb
         
     | 
| 
      
 11 
     | 
    
         
            +
            lib/eaal/exception.rb
         
     | 
| 
      
 12 
     | 
    
         
            +
            lib/eaal/result.rb
         
     | 
| 
      
 13 
     | 
    
         
            +
            lib/eaal/rowset.rb
         
     | 
| 
       12 
14 
     | 
    
         
             
            script/console
         
     | 
| 
       13 
15 
     | 
    
         
             
            script/destroy
         
     | 
| 
       14 
16 
     | 
    
         
             
            script/generate
         
     | 
| 
       15 
     | 
    
         
            -
            test/test_helper.rb
         
     | 
| 
       16 
     | 
    
         
            -
            test/test_eaal.rb
         
     | 
| 
       17 
17 
     | 
    
         
             
            test/fixtures/test/test/account/Characters/Request_.xml
         
     | 
| 
       18 
     | 
    
         
            -
            test/fixtures/test/test/char/Killlog/Request_characterID:12345.xml
         
     | 
| 
       19 
18 
     | 
    
         
             
            test/fixtures/test/test/char/Killlog/Request_.xml
         
     | 
| 
      
 19 
     | 
    
         
            +
            test/fixtures/test/test/char/Killlog/Request_characterID:12345.xml
         
     | 
| 
      
 20 
     | 
    
         
            +
            test/fixtures/test/test/eve/AllianceList/Request_.xml
         
     | 
| 
      
 21 
     | 
    
         
            +
            test/test_eaal.rb
         
     | 
| 
      
 22 
     | 
    
         
            +
            test/test_helper.rb
         
     | 
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -88,6 +88,10 @@ the XML file will be load. 
     | 
|
| 
       88 
88 
     | 
    
         | 
| 
       89 
89 
     | 
    
         
             
            * sudo gem install eaal
         
     | 
| 
       90 
90 
     | 
    
         | 
| 
      
 91 
     | 
    
         
            +
            == THANKS:
         
     | 
| 
      
 92 
     | 
    
         
            +
            special thanks go to James "Ix_Forres" Harrison for his code cleanups and 
         
     | 
| 
      
 93 
     | 
    
         
            +
            his memcache cache handler
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
       91 
95 
     | 
    
         
             
            == LICENSE:
         
     | 
| 
       92 
96 
     | 
    
         | 
| 
       93 
97 
     | 
    
         
             
            (The MIT License)
         
     | 
| 
         @@ -111,4 +115,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
     | 
|
| 
       111 
115 
     | 
    
         
             
            IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
         
     | 
| 
       112 
116 
     | 
    
         
             
            CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
         
     | 
| 
       113 
117 
     | 
    
         
             
            TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
         
     | 
| 
       114 
     | 
    
         
            -
            SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 118 
     | 
    
         
            +
            SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,27 +1,27 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
         
     | 
| 
       2 
     | 
    
         
            -
            require File.dirname(__FILE__) + '/lib/eaal.rb'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            # Generate all the Rake tasks
         
     | 
| 
       5 
     | 
    
         
            -
            # Run 'rake -T' to see list of generated tasks (from gem root directory)
         
     | 
| 
       6 
     | 
    
         
            -
            $hoe = Hoe.new('eaal', EAAL.version) do |p|
         
     | 
| 
       7 
     | 
    
         
            -
              p.developer('Peter Petermann', 'PeterPetermann@gmx.net')
         
     | 
| 
       8 
     | 
    
         
            -
              p.changes              = p.paragraphs_of("History.txt", 0..1).join("\n\n")
         
     | 
| 
       9 
     | 
    
         
            -
              p.rubyforge_name       = p.name # TODO this is default value
         
     | 
| 
       10 
     | 
    
         
            -
              p.extra_deps         = [
         
     | 
| 
       11 
     | 
    
         
            -
                ['activesupport','>= 2.0.2'], ['hpricot', '>= 0.6']
         
     | 
| 
       12 
     | 
    
         
            -
              ]
         
     | 
| 
       13 
     | 
    
         
            -
              p.extra_dev_deps = [
         
     | 
| 
       14 
     | 
    
         
            -
                ['newgem', ">= #{::Newgem::VERSION}"]
         
     | 
| 
       15 
     | 
    
         
            -
              ]
         
     | 
| 
       16 
     | 
    
         
            -
              
         
     | 
| 
       17 
     | 
    
         
            -
              p.clean_globs |= %w[**/.DS_Store tmp *.log]
         
     | 
| 
       18 
     | 
    
         
            -
              path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
         
     | 
| 
       19 
     | 
    
         
            -
              p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
         
     | 
| 
       20 
     | 
    
         
            -
              p.rsync_args = '-av --delete --ignore-errors'
         
     | 
| 
       21 
     | 
    
         
            -
            end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            require 'newgem/tasks' # load /tasks/*.rake
         
     | 
| 
       24 
     | 
    
         
            -
            Dir['tasks/**/*.rake'].each { |t| load t }
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            # TODO - want other tests/tasks run by default? Add them to the list
         
     | 
| 
      
 1 
     | 
    
         
            +
            %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
         
     | 
| 
      
 2 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/lib/eaal.rb'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # Generate all the Rake tasks
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Run 'rake -T' to see list of generated tasks (from gem root directory)
         
     | 
| 
      
 6 
     | 
    
         
            +
            $hoe = Hoe.new('eaal', EAAL.version) do |p|
         
     | 
| 
      
 7 
     | 
    
         
            +
              p.developer('Peter Petermann', 'PeterPetermann@gmx.net')
         
     | 
| 
      
 8 
     | 
    
         
            +
              p.changes              = p.paragraphs_of("History.txt", 0..1).join("\n\n")
         
     | 
| 
      
 9 
     | 
    
         
            +
              p.rubyforge_name       = p.name # TODO this is default value
         
     | 
| 
      
 10 
     | 
    
         
            +
              p.extra_deps         = [
         
     | 
| 
      
 11 
     | 
    
         
            +
                ['activesupport','>= 2.0.2'], ['hpricot', '>= 0.6'], ['memcache-client','>= 1.7.1']
         
     | 
| 
      
 12 
     | 
    
         
            +
              ]
         
     | 
| 
      
 13 
     | 
    
         
            +
              p.extra_dev_deps = [
         
     | 
| 
      
 14 
     | 
    
         
            +
                ['newgem', ">= #{::Newgem::VERSION}"]
         
     | 
| 
      
 15 
     | 
    
         
            +
              ]
         
     | 
| 
      
 16 
     | 
    
         
            +
              
         
     | 
| 
      
 17 
     | 
    
         
            +
              p.clean_globs |= %w[**/.DS_Store tmp *.log]
         
     | 
| 
      
 18 
     | 
    
         
            +
              path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
         
     | 
| 
      
 19 
     | 
    
         
            +
              p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
         
     | 
| 
      
 20 
     | 
    
         
            +
              p.rsync_args = '-av --delete --ignore-errors'
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            require 'newgem/tasks' # load /tasks/*.rake
         
     | 
| 
      
 24 
     | 
    
         
            +
            Dir['tasks/**/*.rake'].each { |t| load t }
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            # TODO - want other tests/tasks run by default? Add them to the list
         
     | 
| 
       27 
27 
     | 
    
         
             
            # task :default => [:spec, :features]
         
     | 
    
        data/lib/eaal.rb
    CHANGED
    
    | 
         @@ -1,6 +1,45 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            +
            # Neat little hack to get around path issues on require
         
     | 
| 
      
 19 
     | 
    
         
            +
            $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            # External libs
         
     | 
| 
      
 22 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'hpricot'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'activesupport'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'net/http'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
      
 28 
     | 
    
         
            +
            # And now EAAL stuff
         
     | 
| 
      
 29 
     | 
    
         
            +
            require 'eaal/cache/base'
         
     | 
| 
      
 30 
     | 
    
         
            +
            require 'eaal/cache/file'
         
     | 
| 
      
 31 
     | 
    
         
            +
            require 'eaal/cache/memcached'
         
     | 
| 
      
 32 
     | 
    
         
            +
            require 'eaal/exception'
         
     | 
| 
      
 33 
     | 
    
         
            +
            require 'eaal/result'
         
     | 
| 
      
 34 
     | 
    
         
            +
            require 'eaal/rowset'
         
     | 
| 
      
 35 
     | 
    
         
            +
            module EAAL
         
     | 
| 
      
 36 
     | 
    
         
            +
              mattr_reader :version_string, :version
         
     | 
| 
      
 37 
     | 
    
         
            +
              @@version = "0.1.5"
         
     | 
| 
      
 38 
     | 
    
         
            +
              @@version_string = "EAAL" +  EAAL.version # the version string, used as client name in http requests
         
     | 
| 
      
 39 
     | 
    
         
            +
                
         
     | 
| 
      
 40 
     | 
    
         
            +
              mattr_accessor :api_base, :additional_request_parameters, :cache
         
     | 
| 
      
 41 
     | 
    
         
            +
              @@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
         
     | 
| 
      
 42 
     | 
    
         
            +
              @@additional_request_parameters = {}       # hash, if :key => value pairs are added those will be added to each request    
         
     | 
| 
      
 43 
     | 
    
         
            +
              @@cache = EAAL::Cache::NoCache.new         # caching object, see EAAL::Cache::FileCache for an Example
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
            require 'eaal/api'
         
     | 
    
        data/lib/eaal/api.rb
    ADDED
    
    | 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            # EAAL::API class
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Usage Example:
         
     | 
| 
      
 4 
     | 
    
         
            +
            #  api = EAAL::API.new("my userid", "my API key")
         
     | 
| 
      
 5 
     | 
    
         
            +
            #  result = api.Characters
         
     | 
| 
      
 6 
     | 
    
         
            +
            #  result.characters.each{|character|
         
     | 
| 
      
 7 
     | 
    
         
            +
            #      puts character.name
         
     | 
| 
      
 8 
     | 
    
         
            +
            #  }
         
     | 
| 
      
 9 
     | 
    
         
            +
            class EAAL::API
         
     | 
| 
      
 10 
     | 
    
         
            +
              attr_accessor :userid, :key, :scope
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
              # constructor
         
     | 
| 
      
 13 
     | 
    
         
            +
              # Expects:
         
     | 
| 
      
 14 
     | 
    
         
            +
              # * userid (String | Integer) the users id
         
     | 
| 
      
 15 
     | 
    
         
            +
              # * key (String) the apikey Full or Restricted
         
     | 
| 
      
 16 
     | 
    
         
            +
              # * scope (String) defaults to account
         
     | 
| 
      
 17 
     | 
    
         
            +
              def initialize(userid, key, scope="account")
         
     | 
| 
      
 18 
     | 
    
         
            +
                self.userid = userid.to_s
         
     | 
| 
      
 19 
     | 
    
         
            +
                self.key = key.to_s
         
     | 
| 
      
 20 
     | 
    
         
            +
                self.scope = scope.to_s
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
              
         
     | 
| 
      
 23 
     | 
    
         
            +
              # create an xml request according to the method called
         
     | 
| 
      
 24 
     | 
    
         
            +
              # this is used to dynamicaly create api calls and 
         
     | 
| 
      
 25 
     | 
    
         
            +
              # should usually not be called directly
         
     | 
| 
      
 26 
     | 
    
         
            +
              # * method (const) 
         
     | 
| 
      
 27 
     | 
    
         
            +
              # * args 
         
     | 
| 
      
 28 
     | 
    
         
            +
              def method_missing(method, *args)
         
     | 
| 
      
 29 
     | 
    
         
            +
                scope = self.scope
         
     | 
| 
      
 30 
     | 
    
         
            +
                args_hash = args.first
         
     | 
| 
      
 31 
     | 
    
         
            +
                args_hash = {} unless args_hash
         
     | 
| 
      
 32 
     | 
    
         
            +
                self.request_xml(scope, method.id2name, args_hash)
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
                
         
     | 
| 
      
 35 
     | 
    
         
            +
              # make a request to the api. will use cache if set.
         
     | 
| 
      
 36 
     | 
    
         
            +
              # usually not called by the user directly
         
     | 
| 
      
 37 
     | 
    
         
            +
              # * scope (String)
         
     | 
| 
      
 38 
     | 
    
         
            +
              # * name (String)
         
     | 
| 
      
 39 
     | 
    
         
            +
              # * opts (Hash)
         
     | 
| 
      
 40 
     | 
    
         
            +
              def request_xml(scope, name, opts)
         
     | 
| 
      
 41 
     | 
    
         
            +
                opts = EAAL.additional_request_parameters.merge(opts)
         
     | 
| 
      
 42 
     | 
    
         
            +
                xml = EAAL.cache.load(self.userid, self.key, scope, name,opts)
         
     | 
| 
      
 43 
     | 
    
         
            +
                if not xml
         
     | 
| 
      
 44 
     | 
    
         
            +
                  source = URI.parse(EAAL.api_base + scope + '/' + name +'.xml.aspx')
         
     | 
| 
      
 45 
     | 
    
         
            +
                  req_path = source.path + format_url_request(opts.merge({
         
     | 
| 
      
 46 
     | 
    
         
            +
                    :userid => self.userid, 
         
     | 
| 
      
 47 
     | 
    
         
            +
                    :apikey => self.key}))
         
     | 
| 
      
 48 
     | 
    
         
            +
                  req = Net::HTTP::Get.new(req_path)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  req[EAAL.version_string]
         
     | 
| 
      
 50 
     | 
    
         
            +
                  res = Net::HTTP.new(source.host, source.port).start {|http| http.request(req) } #one request for now  
         
     | 
| 
      
 51 
     | 
    
         
            +
                  case res
         
     | 
| 
      
 52 
     | 
    
         
            +
                  when Net::HTTPOK
         
     | 
| 
      
 53 
     | 
    
         
            +
                  when Net::HTTPNotFound
         
     | 
| 
      
 54 
     | 
    
         
            +
                    raise EAAL::Exception::APINotFoundError.new("The requested API (#{scope} / #{name}) could not be found.")
         
     | 
| 
      
 55 
     | 
    
         
            +
                  else 
         
     | 
| 
      
 56 
     | 
    
         
            +
                    raise EAAL::Exception::HTTPError.new("An HTTP Error occured, body: " + res.body)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  EAAL.cache.save(self.userid, self.key, scope,name,opts, res.body)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  xml = res.body
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
                doc = Hpricot.XML(xml)
         
     | 
| 
      
 62 
     | 
    
         
            +
                result = EAAL::Result.new(scope.capitalize + name, doc)
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
                          
         
     | 
| 
      
 65 
     | 
    
         
            +
              # Turns a hash into ?var=baz&bam=boo
         
     | 
| 
      
 66 
     | 
    
         
            +
              # stolen from Reve (thx lisa)
         
     | 
| 
      
 67 
     | 
    
         
            +
              # * opts (Hash)
         
     | 
| 
      
 68 
     | 
    
         
            +
              def format_url_request(opts)
         
     | 
| 
      
 69 
     | 
    
         
            +
                req = "?"
         
     | 
| 
      
 70 
     | 
    
         
            +
                opts.stringify_keys!
         
     | 
| 
      
 71 
     | 
    
         
            +
                opts.keys.sort.each do |key|
         
     | 
| 
      
 72 
     | 
    
         
            +
                  req += "#{CGI.escape(key.to_s)}=#{CGI.escape(opts[key].to_s)}&" if opts[key]
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
                req.chop # We are lazy and append a & to each pair even if it's the last one. FIXME: Don't do this.
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
                # NoCache class
         
     | 
| 
      
 16 
     | 
    
         
            +
                # dummy class which is used for non-caching behaviour (default)
         
     | 
| 
      
 17 
     | 
    
         
            +
                class NoCache
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def load(userid, apikey, scope, name, args)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    false
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def save(userid, apikey, scope, name, args, xml)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,62 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # EAAL::Cache::FileCache
         
     | 
| 
      
 2 
     | 
    
         
            +
            # File based xml cache which respects the cachedUntil of the Eve API
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Usage:
         
     | 
| 
      
 4 
     | 
    
         
            +
            #  EAAL.cache = EAAL::Cache::FileCache.new
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Or
         
     | 
| 
      
 6 
     | 
    
         
            +
            #  EAAL.cache = EAAL::Cache::FileCache.new("/path/to/place/to/store/xml/data")
         
     | 
| 
      
 7 
     | 
    
         
            +
            class EAAL::Cache::FileCache
         
     | 
| 
      
 8 
     | 
    
         
            +
              attr_accessor :basepath
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              # constructor, takes one argument which is the path
         
     | 
| 
      
 11 
     | 
    
         
            +
              # where files should be written
         
     | 
| 
      
 12 
     | 
    
         
            +
              # * basepath (String) path which should be used to store cached data. defaults to $HOME/.eaal/cache/
         
     | 
| 
      
 13 
     | 
    
         
            +
              def initialize(basepath = "#{ENV['HOME']}/.eaal/cache")
         
     | 
| 
      
 14 
     | 
    
         
            +
                if basepath[(basepath.length) -1, basepath.length] != "/"
         
     | 
| 
      
 15 
     | 
    
         
            +
                  basepath += "/" 
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
                @basepath = basepath
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              
         
     | 
| 
      
 20 
     | 
    
         
            +
              # create the path/filename for the cache file
         
     | 
| 
      
 21 
     | 
    
         
            +
              def filename(userid, apikey, scope, name, args)
         
     | 
| 
      
 22 
     | 
    
         
            +
                ret =""
         
     | 
| 
      
 23 
     | 
    
         
            +
                args.delete_if { |k,v| (v || "").to_s.length == 0 }
         
     | 
| 
      
 24 
     | 
    
         
            +
                h = args.stringify_keys
         
     | 
| 
      
 25 
     | 
    
         
            +
                ret += h.sort.flatten.collect{ |e| e.to_s }.join(':')
         
     | 
| 
      
 26 
     | 
    
         
            +
                hash = ret.gsub(/:$/,'')
         
     | 
| 
      
 27 
     | 
    
         
            +
                "#{@basepath}#{userid}/#{apikey}/#{scope}/#{name}/Request_#{hash}.xml"
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
      
 30 
     | 
    
         
            +
              # load xml if available, return false if not available, or cachedUntil ran out
         
     | 
| 
      
 31 
     | 
    
         
            +
              def load(userid, apikey, scope, name, args)
         
     | 
| 
      
 32 
     | 
    
         
            +
                filename = self.filename(userid, apikey,scope,name,args)
         
     | 
| 
      
 33 
     | 
    
         
            +
                if not File.exist?(filename)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  ret = false
         
     | 
| 
      
 35 
     | 
    
         
            +
                else
         
     | 
| 
      
 36 
     | 
    
         
            +
                  xml = File.open(filename).read
         
     | 
| 
      
 37 
     | 
    
         
            +
                  if self.validate_cache(xml, name)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    ret = xml
         
     | 
| 
      
 39 
     | 
    
         
            +
                  else
         
     | 
| 
      
 40 
     | 
    
         
            +
                    ret = false
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
                ret
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
              
         
     | 
| 
      
 46 
     | 
    
         
            +
              # validate cached datas cachedUntil
         
     | 
| 
      
 47 
     | 
    
         
            +
              def validate_cache(xml, name)
         
     | 
| 
      
 48 
     | 
    
         
            +
                doc = Hpricot.XML(xml)
         
     | 
| 
      
 49 
     | 
    
         
            +
                if name == "WalletJournal"
         
     | 
| 
      
 50 
     | 
    
         
            +
                        Time.at((doc/"/eveapi/cachedUntil").inner_html.to_time.to_i + 3600) > Time.now
         
     | 
| 
      
 51 
     | 
    
         
            +
                      else 
         
     | 
| 
      
 52 
     | 
    
         
            +
                  (doc/"/eveapi/cachedUntil").inner_html.to_time > Time.now
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
              
         
     | 
| 
      
 56 
     | 
    
         
            +
              # save xml data to file
         
     | 
| 
      
 57 
     | 
    
         
            +
              def save(userid, apikey, scope, name, args, xml)
         
     | 
| 
      
 58 
     | 
    
         
            +
                filename = self.filename(userid, apikey,scope,name,args)
         
     | 
| 
      
 59 
     | 
    
         
            +
                FileUtils.mkdir_p(File.dirname(filename))
         
     | 
| 
      
 60 
     | 
    
         
            +
                File.open(filename,'w') { |f| f.print xml }        
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # EAAL::Cache::Memcached
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Cache class to allow use of Memcached server(s) as a local cache option.
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'memcache'
         
     | 
| 
      
 4 
     | 
    
         
            +
            class EAAL::Cache::MemcachedCache
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(servers="localhost:11211",options={})
         
     | 
| 
      
 7 
     | 
    
         
            +
                o = {:namespace => 'eaal'}.merge(options)
         
     | 
| 
      
 8 
     | 
    
         
            +
                $cache = MemCache.new(servers,o)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Returns the memcached key for a given set of args.
         
     | 
| 
      
 11 
     | 
    
         
            +
              # Does not use the full API key string as the risk of a collision is astronomically high.
         
     | 
| 
      
 12 
     | 
    
         
            +
              def key(userid, apikey, scope, name, args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                "#{userid}#{apikey[0..25]}#{scope}#{name}#{args}"
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              # Saves to cache. It is worth noting that memcached handles expiry for us unlike FileCache
         
     | 
| 
      
 16 
     | 
    
         
            +
              # as a result, there is no requirement for a validate_cache method- we just get MC to expire
         
     | 
| 
      
 17 
     | 
    
         
            +
              # the key when we can go get a new copy.
         
     | 
| 
      
 18 
     | 
    
         
            +
              def save(userid, apikey, scope, name, args, xml)
         
     | 
| 
      
 19 
     | 
    
         
            +
                k = key(userid, apikey, scope, name, args)
         
     | 
| 
      
 20 
     | 
    
         
            +
                cached_until = xml.match(/<cachedUntil>(.+)<\/cachedUntil>/)[1].to_time
         
     | 
| 
      
 21 
     | 
    
         
            +
                expires_in = (name=='WalletJournal' ? cached_until.to_i+3600 : cached_until.to_i )-Time.now.to_i
         
     | 
| 
      
 22 
     | 
    
         
            +
                $cache.delete(k)
         
     | 
| 
      
 23 
     | 
    
         
            +
                $cache.add(k,xml,expires_in)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              # Loads from the cache if there's a value for it.
         
     | 
| 
      
 26 
     | 
    
         
            +
              def load(userid, apikey, scope, name, args)
         
     | 
| 
      
 27 
     | 
    
         
            +
                k = key(userid, apikey, scope, name, args)
         
     | 
| 
      
 28 
     | 
    
         
            +
                ($cache.get(k,xml,expires_in) or false) rescue false
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 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::Exception
         
     | 
| 
      
 7 
     | 
    
         
            +
              # creates the class for an EveAPIException
         
     | 
| 
      
 8 
     | 
    
         
            +
              def self.EveAPIException(nr)
         
     | 
| 
      
 9 
     | 
    
         
            +
                classname = "EveAPIException#{nr}" 
         
     | 
| 
      
 10 
     | 
    
         
            +
                if not Object.const_defined? classname
         
     | 
| 
      
 11 
     | 
    
         
            +
                  klass = Object.const_set(classname, Class.new(EAAL::Exception::EveAPIException))
         
     | 
| 
      
 12 
     | 
    
         
            +
                else
         
     | 
| 
      
 13 
     | 
    
         
            +
                  klass = Object.const_get(classname)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
                klass
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              # raise the eve API exceptions, class will be dynamicaly created by classname
         
     | 
| 
      
 19 
     | 
    
         
            +
              # EveAPIException followed by the APIs exception Number
         
     | 
| 
      
 20 
     | 
    
         
            +
              def self.raiseEveAPIException(nr, msg)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  raise EAAL::Exception.EveAPIException(nr).new(msg)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
              
         
     | 
| 
      
 24 
     | 
    
         
            +
              # all EAAL exceptions should extend this.
         
     | 
| 
      
 25 
     | 
    
         
            +
              class EAALError < StandardError
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              # Used when an http error is encountered
         
     | 
| 
      
 29 
     | 
    
         
            +
              class HTTPError < EAALError
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              # Used when the Eve API returns a 404
         
     | 
| 
      
 33 
     | 
    
         
            +
              class APINotFoundError < HTTPError
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
              
         
     | 
| 
      
 36 
     | 
    
         
            +
              # All API Errors should be derived from this
         
     | 
| 
      
 37 
     | 
    
         
            +
              class EveAPIException < EAALError
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
         @@ -1,123 +1,123 @@ 
     | 
|
| 
       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 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                module Result
         
     | 
| 
       9 
     | 
    
         
            -
                  
         
     | 
| 
       10 
     | 
    
         
            -
                    # base class for automated result class creation
         
     | 
| 
       11 
     | 
    
         
            -
                    class ResultBase
         
     | 
| 
       12 
     | 
    
         
            -
                        attr_accessor :request_time, :cached_until
         
     | 
| 
       13 
     | 
    
         
            -
                    end
         
     | 
| 
       14 
     | 
    
         
            -
                    
         
     | 
| 
       15 
     | 
    
         
            -
                    # Result Container class, ...  
         
     | 
| 
       16 
     | 
    
         
            -
                    class ResultContainer
         
     | 
| 
       17 
     | 
    
         
            -
                        attr_accessor :container
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                        def initialize
         
     | 
| 
       20 
     | 
    
         
            -
                            self.container = {}
         
     | 
| 
       21 
     | 
    
         
            -
                        end
         
     | 
| 
       22 
     | 
    
         
            -
                        
         
     | 
| 
       23 
     | 
    
         
            -
                        def add_element(key, val)
         
     | 
| 
       24 
     | 
    
         
            -
                            self.container.merge!({key => val})
         
     | 
| 
       25 
     | 
    
         
            -
                        end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                        def method_missing(method, *args)
         
     | 
| 
       28 
     | 
    
         
            -
                            self.container[method.id2name]
         
     | 
| 
       29 
     | 
    
         
            -
                        end
         
     | 
| 
       30 
     | 
    
         
            -
                    end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                    # result element
         
     | 
| 
       33 
     | 
    
         
            -
                    class ResultElement
         
     | 
| 
       34 
     | 
    
         
            -
                        attr_accessor :name, :value, :attribs
         
     | 
| 
       35 
     | 
    
         
            -
                        def initialize(name, value)
         
     | 
| 
       36 
     | 
    
         
            -
                            self.name = name
         
     | 
| 
       37 
     | 
    
         
            -
                            self.value = value     
         
     | 
| 
       38 
     | 
    
         
            -
                            self.attribs = {}
         
     | 
| 
       39 
     | 
    
         
            -
                        end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                        def add_attrib(key, val)
         
     | 
| 
       42 
     | 
    
         
            -
                            self.attribs.merge!({key => val})
         
     | 
| 
       43 
     | 
    
         
            -
                        end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                        def method_missing(method, *args)
         
     | 
| 
       46 
     | 
    
         
            -
                            if self.attribs.has_key?(method.id2name)
         
     | 
| 
       47 
     | 
    
         
            -
                                self.attribs[method.id2name]
         
     | 
| 
       48 
     | 
    
         
            -
                            else
         
     | 
| 
       49 
     | 
    
         
            -
                                self.value.send(method, *args)                    
         
     | 
| 
       50 
     | 
    
         
            -
                            end
         
     | 
| 
       51 
     | 
    
         
            -
                            
         
     | 
| 
       52 
     | 
    
         
            -
                        end
         
     | 
| 
       53 
     | 
    
         
            -
                                
         
     | 
| 
       54 
     | 
    
         
            -
                        # parses an xml element to create either the ResultElement, ResultContainer or Rowset 
         
     | 
| 
       55 
     | 
    
         
            -
                        # necessary
         
     | 
| 
       56 
     | 
    
         
            -
                        def self.parse_element(prefix, element)
         
     | 
| 
       57 
     | 
    
         
            -
                            if element.name == "rowset"
         
     | 
| 
       58 
     | 
    
         
            -
                                re = EAAL::Rowset.new(prefix, element)
         
     | 
| 
       59 
     | 
    
         
            -
                            else
         
     | 
| 
       60 
     | 
    
         
            -
                                key = element.name
         
     | 
| 
       61 
     | 
    
         
            -
                                if element.children && element.containers.length > 0
         
     | 
| 
       62 
     | 
    
         
            -
                                    container = ResultContainer.new
         
     | 
| 
       63 
     | 
    
         
            -
                                    element.containers.each { |celement|
         
     | 
| 
       64 
     | 
    
         
            -
                                        cel = EAAL::Result::ResultElement.parse_element(prefix, celement)
         
     | 
| 
       65 
     | 
    
         
            -
                                        if element.attributes.length > 0
         
     | 
| 
       66 
     | 
    
         
            -
                                            container.add_element(cel.name, cel)
         
     | 
| 
       67 
     | 
    
         
            -
                                        else 
         
     | 
| 
       68 
     | 
    
         
            -
                                            container.add_element(cel.name, cel.value)
         
     | 
| 
       69 
     | 
    
         
            -
                                        end
         
     | 
| 
       70 
     | 
    
         
            -
                                    }
         
     | 
| 
       71 
     | 
    
         
            -
                                    value = container
         
     | 
| 
       72 
     | 
    
         
            -
                                else
         
     | 
| 
       73 
     | 
    
         
            -
                                    value = element.inner_html
         
     | 
| 
       74 
     | 
    
         
            -
                                end
         
     | 
| 
       75 
     | 
    
         
            -
                                re = ResultElement.new(key, value)
         
     | 
| 
       76 
     | 
    
         
            -
                                if element.attributes.length > 0
         
     | 
| 
       77 
     | 
    
         
            -
                                    re.attribs.merge!(element.attributes)
         
     | 
| 
       78 
     | 
    
         
            -
                                end
         
     | 
| 
       79 
     | 
    
         
            -
                            end
         
     | 
| 
       80 
     | 
    
         
            -
                            re
         
     | 
| 
       81 
     | 
    
         
            -
                        end
         
     | 
| 
       82 
     | 
    
         
            -
                    end
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
            	# create a new result derived from ResultBase
         
     | 
| 
       85 
     | 
    
         
            -
                    def self.new(prefix, xml)
         
     | 
| 
       86 
     | 
    
         
            -
                        classname = prefix + 'Result'
         
     | 
| 
       87 
     | 
    
         
            -
                        members = []
         
     | 
| 
       88 
     | 
    
         
            -
                        values = {}
         
     | 
| 
       89 
     | 
    
         
            -
                        if (xml/"eveapi/error").length > 0
         
     | 
| 
       90 
     | 
    
         
            -
                          error = (xml/"eveapi/error").first
         
     | 
| 
       91 
     | 
    
         
            -
                          raise EAAL::Exception.raiseEveAPIException(error["code"], error.inner_html)
         
     | 
| 
       92 
     | 
    
         
            -
                        end
         
     | 
| 
       93 
     | 
    
         
            -
                        if (xml/"eveapi/result").length < 1
         
     | 
| 
       94 
     | 
    
         
            -
                          raise EAAL::Exception::EAALError.new("Unknown API error, no result element was found")
         
     | 
| 
       95 
     | 
    
         
            -
                        end
         
     | 
| 
       96 
     | 
    
         
            -
                        elements = (xml/"eveapi/result").first.containers
         
     | 
| 
       97 
     | 
    
         
            -
                        elements.each {|element|
         
     | 
| 
       98 
     | 
    
         
            -
                            el = EAAL::Result::ResultElement.parse_element(prefix, element)
         
     | 
| 
       99 
     | 
    
         
            -
                            members << el.name
         
     | 
| 
       100 
     | 
    
         
            -
                            if el.kind_of? EAAL::Rowset::RowsetBase
         
     | 
| 
       101 
     | 
    
         
            -
                                values.merge!({el.name => el})
         
     | 
| 
       102 
     | 
    
         
            -
                            else
         
     | 
| 
       103 
     | 
    
         
            -
                                values.merge!({el.name => el.value})
         
     | 
| 
       104 
     | 
    
         
            -
                            end
         
     | 
| 
       105 
     | 
    
         
            -
                        }
         
     | 
| 
       106 
     | 
    
         
            -
                        if not Object.const_defined? classname
         
     | 
| 
       107 
     | 
    
         
            -
                            klass = Object.const_set(classname, Class.new(EAAL::Result::ResultBase))    
         
     | 
| 
       108 
     | 
    
         
            -
                            klass.class_eval do
         
     | 
| 
       109 
     | 
    
         
            -
                                attr_accessor 
     | 
| 
       110 
     | 
    
         
            -
                            end
         
     | 
| 
       111 
     | 
    
         
            -
                        else
         
     | 
| 
       112 
     | 
    
         
            -
                            klass = Object.const_get(classname)
         
     | 
| 
       113 
     | 
    
         
            -
                        end
         
     | 
| 
       114 
     | 
    
         
            -
                        result = klass.new
         
     | 
| 
       115 
     | 
    
         
            -
                        result.request_time = (xml/"eveapi/currentTime").first.inner_html
         
     | 
| 
       116 
     | 
    
         
            -
                        result.cached_until = (xml/"eveapi/cachedUntil").first.inner_html
         
     | 
| 
       117 
     | 
    
         
            -
                        values.each { |key,value|
         
     | 
| 
       118 
     | 
    
         
            -
                            result.send(key + "=", value)
         
     | 
| 
       119 
     | 
    
         
            -
                        }
         
     | 
| 
       120 
     | 
    
         
            -
                        result
         
     | 
| 
       121 
     | 
    
         
            -
                    end
         
     | 
| 
       122 
     | 
    
         
            -
                end
         
     | 
| 
       123 
     | 
    
         
            -
            end
         
     | 
| 
      
 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 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                module Result
         
     | 
| 
      
 9 
     | 
    
         
            +
                  
         
     | 
| 
      
 10 
     | 
    
         
            +
                    # base class for automated result class creation
         
     | 
| 
      
 11 
     | 
    
         
            +
                    class ResultBase
         
     | 
| 
      
 12 
     | 
    
         
            +
                        attr_accessor :request_time, :cached_until
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
                    
         
     | 
| 
      
 15 
     | 
    
         
            +
                    # Result Container class, ...  
         
     | 
| 
      
 16 
     | 
    
         
            +
                    class ResultContainer
         
     | 
| 
      
 17 
     | 
    
         
            +
                        attr_accessor :container
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                        def initialize
         
     | 
| 
      
 20 
     | 
    
         
            +
                            self.container = {}
         
     | 
| 
      
 21 
     | 
    
         
            +
                        end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        
         
     | 
| 
      
 23 
     | 
    
         
            +
                        def add_element(key, val)
         
     | 
| 
      
 24 
     | 
    
         
            +
                            self.container.merge!({key => val})
         
     | 
| 
      
 25 
     | 
    
         
            +
                        end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                        def method_missing(method, *args)
         
     | 
| 
      
 28 
     | 
    
         
            +
                            self.container[method.id2name]
         
     | 
| 
      
 29 
     | 
    
         
            +
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    # result element
         
     | 
| 
      
 33 
     | 
    
         
            +
                    class ResultElement
         
     | 
| 
      
 34 
     | 
    
         
            +
                        attr_accessor :name, :value, :attribs
         
     | 
| 
      
 35 
     | 
    
         
            +
                        def initialize(name, value)
         
     | 
| 
      
 36 
     | 
    
         
            +
                            self.name = name
         
     | 
| 
      
 37 
     | 
    
         
            +
                            self.value = value     
         
     | 
| 
      
 38 
     | 
    
         
            +
                            self.attribs = {}
         
     | 
| 
      
 39 
     | 
    
         
            +
                        end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                        def add_attrib(key, val)
         
     | 
| 
      
 42 
     | 
    
         
            +
                            self.attribs.merge!({key => val})
         
     | 
| 
      
 43 
     | 
    
         
            +
                        end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                        def method_missing(method, *args)
         
     | 
| 
      
 46 
     | 
    
         
            +
                            if self.attribs.has_key?(method.id2name)
         
     | 
| 
      
 47 
     | 
    
         
            +
                                self.attribs[method.id2name]
         
     | 
| 
      
 48 
     | 
    
         
            +
                            else
         
     | 
| 
      
 49 
     | 
    
         
            +
                                self.value.send(method, *args)                    
         
     | 
| 
      
 50 
     | 
    
         
            +
                            end
         
     | 
| 
      
 51 
     | 
    
         
            +
                            
         
     | 
| 
      
 52 
     | 
    
         
            +
                        end
         
     | 
| 
      
 53 
     | 
    
         
            +
                                
         
     | 
| 
      
 54 
     | 
    
         
            +
                        # parses an xml element to create either the ResultElement, ResultContainer or Rowset 
         
     | 
| 
      
 55 
     | 
    
         
            +
                        # necessary
         
     | 
| 
      
 56 
     | 
    
         
            +
                        def self.parse_element(prefix, element)
         
     | 
| 
      
 57 
     | 
    
         
            +
                            if element.name == "rowset"
         
     | 
| 
      
 58 
     | 
    
         
            +
                                re = EAAL::Rowset.new(prefix, element)
         
     | 
| 
      
 59 
     | 
    
         
            +
                            else
         
     | 
| 
      
 60 
     | 
    
         
            +
                                key = element.name
         
     | 
| 
      
 61 
     | 
    
         
            +
                                if element.children && element.containers.length > 0
         
     | 
| 
      
 62 
     | 
    
         
            +
                                    container = ResultContainer.new
         
     | 
| 
      
 63 
     | 
    
         
            +
                                    element.containers.each { |celement|
         
     | 
| 
      
 64 
     | 
    
         
            +
                                        cel = EAAL::Result::ResultElement.parse_element(prefix, celement)
         
     | 
| 
      
 65 
     | 
    
         
            +
                                        if element.attributes.length > 0
         
     | 
| 
      
 66 
     | 
    
         
            +
                                            container.add_element(cel.name, cel)
         
     | 
| 
      
 67 
     | 
    
         
            +
                                        else 
         
     | 
| 
      
 68 
     | 
    
         
            +
                                            container.add_element(cel.name, cel.value)
         
     | 
| 
      
 69 
     | 
    
         
            +
                                        end
         
     | 
| 
      
 70 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 71 
     | 
    
         
            +
                                    value = container
         
     | 
| 
      
 72 
     | 
    
         
            +
                                else
         
     | 
| 
      
 73 
     | 
    
         
            +
                                    value = element.inner_html
         
     | 
| 
      
 74 
     | 
    
         
            +
                                end
         
     | 
| 
      
 75 
     | 
    
         
            +
                                re = ResultElement.new(key, value)
         
     | 
| 
      
 76 
     | 
    
         
            +
                                if element.attributes.length > 0
         
     | 
| 
      
 77 
     | 
    
         
            +
                                    re.attribs.merge!(element.attributes)
         
     | 
| 
      
 78 
     | 
    
         
            +
                                end
         
     | 
| 
      
 79 
     | 
    
         
            +
                            end
         
     | 
| 
      
 80 
     | 
    
         
            +
                            re
         
     | 
| 
      
 81 
     | 
    
         
            +
                        end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            	# create a new result derived from ResultBase
         
     | 
| 
      
 85 
     | 
    
         
            +
                    def self.new(prefix, xml)
         
     | 
| 
      
 86 
     | 
    
         
            +
                        classname = prefix + 'Result'
         
     | 
| 
      
 87 
     | 
    
         
            +
                        members = []
         
     | 
| 
      
 88 
     | 
    
         
            +
                        values = {}
         
     | 
| 
      
 89 
     | 
    
         
            +
                        if (xml/"eveapi/error").length > 0
         
     | 
| 
      
 90 
     | 
    
         
            +
                          error = (xml/"eveapi/error").first
         
     | 
| 
      
 91 
     | 
    
         
            +
                          raise EAAL::Exception.raiseEveAPIException(error["code"], error.inner_html)
         
     | 
| 
      
 92 
     | 
    
         
            +
                        end
         
     | 
| 
      
 93 
     | 
    
         
            +
                        if (xml/"eveapi/result").length < 1
         
     | 
| 
      
 94 
     | 
    
         
            +
                          raise EAAL::Exception::EAALError.new("Unknown API error, no result element was found")
         
     | 
| 
      
 95 
     | 
    
         
            +
                        end
         
     | 
| 
      
 96 
     | 
    
         
            +
                        elements = (xml/"eveapi/result").first.containers
         
     | 
| 
      
 97 
     | 
    
         
            +
                        elements.each {|element|
         
     | 
| 
      
 98 
     | 
    
         
            +
                            el = EAAL::Result::ResultElement.parse_element(prefix, element)
         
     | 
| 
      
 99 
     | 
    
         
            +
                            members << el.name
         
     | 
| 
      
 100 
     | 
    
         
            +
                            if el.kind_of? EAAL::Rowset::RowsetBase
         
     | 
| 
      
 101 
     | 
    
         
            +
                                values.merge!({el.name => el})
         
     | 
| 
      
 102 
     | 
    
         
            +
                            else
         
     | 
| 
      
 103 
     | 
    
         
            +
                                values.merge!({el.name => el.value})
         
     | 
| 
      
 104 
     | 
    
         
            +
                            end
         
     | 
| 
      
 105 
     | 
    
         
            +
                        }
         
     | 
| 
      
 106 
     | 
    
         
            +
                        if not Object.const_defined? classname
         
     | 
| 
      
 107 
     | 
    
         
            +
                            klass = Object.const_set(classname, Class.new(EAAL::Result::ResultBase))    
         
     | 
| 
      
 108 
     | 
    
         
            +
                            klass.class_eval do
         
     | 
| 
      
 109 
     | 
    
         
            +
                                attr_accessor(*members)
         
     | 
| 
      
 110 
     | 
    
         
            +
                            end
         
     | 
| 
      
 111 
     | 
    
         
            +
                        else
         
     | 
| 
      
 112 
     | 
    
         
            +
                            klass = Object.const_get(classname)
         
     | 
| 
      
 113 
     | 
    
         
            +
                        end
         
     | 
| 
      
 114 
     | 
    
         
            +
                        result = klass.new
         
     | 
| 
      
 115 
     | 
    
         
            +
                        result.request_time = (xml/"eveapi/currentTime").first.inner_html
         
     | 
| 
      
 116 
     | 
    
         
            +
                        result.cached_until = (xml/"eveapi/cachedUntil").first.inner_html
         
     | 
| 
      
 117 
     | 
    
         
            +
                        values.each { |key,value|
         
     | 
| 
      
 118 
     | 
    
         
            +
                            result.send(key + "=", value)
         
     | 
| 
      
 119 
     | 
    
         
            +
                        }
         
     | 
| 
      
 120 
     | 
    
         
            +
                        result
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
            end
         
     |