diff --git a/lib/asin.rb b/lib/asin.rb index 3058445..72006a4 100644 --- a/lib/asin.rb +++ b/lib/asin.rb @@ -6,6 +6,7 @@ require 'asin/item' require 'asin/version' +require 'asin/configuration' # ASIN (Amazon Simple INterface) is a gem for easy access of the Amazon E-Commerce-API. # It is simple to configure and use. Since it's very small and flexible, it is easy to extend it to your needs. @@ -73,13 +74,7 @@ module ASIN # [logger] a different logger than logging to STDERR # def configure(options={}) - @options = { - :secret => '', - :key => '', - :host => 'webservices.amazon.com', - :logger => Logger.new(STDERR), - } if @options.nil? - @options.merge! options + Configuration.configure(options) end # Performs an +ItemLookup+ REST call against the Amazon API. @@ -124,14 +119,18 @@ def search(search_string, params={:SearchIndex => :Books}) private + def credentials_valid? + !Configuration.secret.nil? && !Configuration.key.nil? + end + def call(params) - raise "you have to configure ASIN: 'configure :secret => 'your-secret', :key => 'your-key''" if @options.nil? + raise "you have to configure ASIN: 'configure :secret => 'your-secret', :key => 'your-key''" unless credentials_valid? log(:debug, "calling with params=#{params}") signed = create_signed_query_string(params) - url = "http://#{@options[:host]}#{PATH}?#{signed}" - log(:info, "performing rest call to url='#{url}' with client='#{@options[:client]}'") + url = "http://#{Configuration.host}#{PATH}?#{signed}" + log(:info, "performing rest call to url='#{url}'") response = HTTPI.get(url) if response.code == 200 @@ -149,7 +148,7 @@ def call(params) def create_signed_query_string(params) # nice tutorial http://cloudcarpenters.com/blog/amazon_products_api_request_signing/ params[:Service] = :AWSECommerceService - params[:AWSAccessKeyId] = @options[:key] + params[:AWSAccessKeyId] = Configuration.key # utc timestamp needed for signing params[:Timestamp] = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ') @@ -157,8 +156,8 @@ def create_signed_query_string(params) query = params.map{|key, value| "#{key}=#{CGI.escape(value.to_s)}" }.sort.join('&').gsub('+','%20') # yeah, you really need to sign the get-request not the query - request_to_sign = "GET\n#{@options[:host]}\n#{PATH}\n#{query}" - hmac = OpenSSL::HMAC.digest(DIGEST, @options[:secret], request_to_sign) + request_to_sign = "GET\n#{Configuration.host}\n#{PATH}\n#{query}" + hmac = OpenSSL::HMAC.digest(DIGEST, Configuration.secret, request_to_sign) # don't forget to remove the newline from base64 signature = CGI.escape(Base64.encode64(hmac).chomp) @@ -166,7 +165,7 @@ def create_signed_query_string(params) end def log(severity, message) - @options[:logger].send severity, message if @options[:logger] + Configuration.logger.send severity, message if Configuration.logger end -end \ No newline at end of file +end diff --git a/lib/asin/configuration.rb b/lib/asin/configuration.rb new file mode 100644 index 0000000..0bae394 --- /dev/null +++ b/lib/asin/configuration.rb @@ -0,0 +1,48 @@ +module ASIN + class Configuration + class << self + + attr_accessor :secret, :key, :host, :logger + + # Rails initializer configuration. + # + # Expects at least +secret+ and +key+ for the API call: + # + # ASIN::Configuration.configure do |config| + # config.secret = 'your-secret' + # config.key = 'your-key' + # end + # + # ==== Options: + # + # [secret] the API secret key + # [key] the API access key + # [host] the host, which defaults to 'webservices.amazon.com' + # [logger] a different logger than logging to STDERR + # + def configure(options={}) + init_config + if block_given? + yield self + else + options.each do |key, value| + send(:"#{key}=", value) + end + end + self + end + + private + + def init_config(force=false) + return if @init && !force + @init = true + @secret = '' + @key = '' + @host = 'webservices.amazon.com' + @logger = Logger.new(STDERR) + end + end + end +end + diff --git a/spec/asin_spec.rb b/spec/asin_spec.rb index 2084450..f9a98e3 100644 --- a/spec/asin_spec.rb +++ b/spec/asin_spec.rb @@ -16,14 +16,25 @@ it "should fail without secret and key" do lambda { @helper.lookup ANY_ASIN }.should raise_error(RuntimeError) end + + it "should fail with wrong configuration key" do + lambda { @helper.configure :wrong => 'key' }.should raise_error(NoMethodError) + end it "should not override the configuration" do - config = @helper.configure :something => 'wont get overridden' - config[:something].should_not be_nil + config = @helper.configure :key => 'wont get overridden' + config.key.should_not be_nil + + config = @helper.configure :secret => 'is also set' + config.key.should_not be_nil + config.secret.should_not be_nil + end - config = @helper.configure :different => 'is also set' - config[:something].should_not be_nil - config[:different].should_not be_nil + it "should work with a configuration block" do + config = ASIN::Configuration.configure do |config| + config.key = 'bla' + end + config.key.should eql('bla') end end