sift 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ **.swp
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sift.gemspec
4
+ gemspec
data/HISTORY ADDED
@@ -0,0 +1,3 @@
1
+
2
+ === 1.0 2012-05-02
3
+ * Initial release
@@ -0,0 +1,41 @@
1
+ = Sift Science Ruby bindings
2
+
3
+ == Installation
4
+
5
+ If you want to build the gem from source:
6
+
7
+ $ gem build sift.gemspec
8
+
9
+ Alternatively, you can install the gem from Rubyforge:
10
+
11
+ $ gem install sift
12
+
13
+ == Requirements
14
+
15
+ * Ruby 1.8.7 or above. (Ruby 1.8.6 might work if you load ActiveSupport.)
16
+ * HTTParty, 0.8.3 or greater
17
+
18
+ For development only:
19
+ * bundler
20
+ * rspec, 2.9 or greater
21
+ * fakeweb, 1.3 or greater
22
+
23
+ == Building
24
+
25
+ Building and publishing the gem is captured by the following steps:
26
+
27
+ $ gem build sift.gemspec
28
+ $ gem push sift-<current version>.gem
29
+
30
+ $ bundle
31
+ $ rake -T
32
+ $ rake build
33
+ $ rake install
34
+ $ rake release
35
+
36
+ == Testing
37
+
38
+ To run the various tests use the rake command as follows:
39
+
40
+ $ rake spec:unit
41
+ $ rake spec:integration
@@ -0,0 +1,14 @@
1
+ begin
2
+ require "bundler/gem_tasks"
3
+ Bundler::GemHelper.install_tasks
4
+ rescue LoadError => e
5
+ warn "It is recommended that you use bundler during development: gem install bundler"
6
+ end
7
+
8
+ require "rspec/core/rake_task"
9
+
10
+ desc "Run tests"
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+ task :default => :spec
14
+ task :test => :spec
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # A simple example of how to use the API.
4
+
5
+ require 'rubygems'
6
+ require 'sift'
7
+ require 'multi_json'
8
+
9
+ api_key = "" # TODO: Set your API key here
10
+
11
+ class MyLogger
12
+ def warn(e)
13
+ puts "[WARN] " + e.to_s
14
+ end
15
+
16
+ def error(e)
17
+ puts "[ERROR] " + e.to_s
18
+ end
19
+
20
+ def fatal(e)
21
+ puts "[FATAL] " + e.to_s
22
+ end
23
+
24
+ def info(e)
25
+ puts "[INFO] " + e.to_s
26
+ end
27
+ end
28
+
29
+ Sift.logger = MyLogger.new
30
+
31
+ client = Sift::Client.new(api_key)
32
+ event = "my_custom_event"
33
+ properties = {
34
+ "my_custom_field1" => "my custom value 1",
35
+ "my_custom_field2" => "my custom value 2",
36
+ "$user_id" => "3",
37
+ "$time" => Time.now.to_i,
38
+ }
39
+
40
+ response = client.track(event, properties)
41
+ if response.nil?
42
+ puts 'Error: there was an HTTP error calling through the API'
43
+ else
44
+ puts 'Successfully sent request; was ok? : ' + response.ok?.to_s
45
+ puts 'API error message : ' + response.api_error_message.to_s
46
+ puts 'API status code : ' + response.api_status.to_s
47
+ puts 'HTTP status code : ' + response.http_status_code.to_s
48
+ puts 'original request : ' + response.original_request.to_s
49
+ end
50
+
@@ -0,0 +1,33 @@
1
+ require "sift/version"
2
+ require "sift/client"
3
+
4
+ module Sift
5
+
6
+ # Returns the path for the current API version
7
+ def self.current_rest_api_path
8
+ "/v202/events"
9
+ end
10
+
11
+ # Sets the Output logger to use within the client. This can be left uninitializaed
12
+ # but is useful for debugging.
13
+ def self.logger=(logger)
14
+ @logger = logger
15
+ end
16
+
17
+ def self.info(msg)
18
+ @logger.info(msg) if @logger
19
+ end
20
+
21
+ def self.warn(msg)
22
+ @logger.warn(msg) if @logger
23
+ end
24
+
25
+ def self.error(msg)
26
+ @logger.error(msg) if @logger
27
+ end
28
+
29
+ def self.fatal(msg)
30
+ @logger.fatal(msg) if @logger
31
+ end
32
+
33
+ end
@@ -0,0 +1,108 @@
1
+ require 'httparty'
2
+ require 'multi_json'
3
+
4
+ module Sift
5
+
6
+ # Represents the payload returned from a call through the track API
7
+ #
8
+ class Response
9
+ attr_reader :json
10
+ attr_reader :http_status_code
11
+ attr_reader :api_status
12
+ attr_reader :api_error_message
13
+ attr_reader :original_request
14
+
15
+ # Constructor
16
+ #
17
+ # == Parameters:
18
+ # http_response
19
+ # The HTTP body text returned from the API call. The body is expected to be
20
+ # a JSON object that can be decoded into status, message and request
21
+ # sections.
22
+ #
23
+ def initialize(http_response, http_response_code)
24
+ @json = MultiJson.load(http_response)
25
+ @original_request = MultiJson.load(@json["request"].to_s) if @json["request"]
26
+ @http_status_code = http_response_code
27
+ @api_status = @json["status"].to_i
28
+ @api_error_message = @json["error_message"].to_s
29
+ end
30
+
31
+ # Helper method returns true if and only if the response from the API call was
32
+ # successful
33
+ #
34
+ # == Returns:
35
+ # true on success; false otherwise
36
+ def ok?
37
+ 0 == @api_status.to_i
38
+ end
39
+ end
40
+
41
+ # This class wraps accesses through the API
42
+ #
43
+ class Client
44
+ API_ENDPOINT = "https://api.siftscience.com"
45
+ API_TIMEOUT = 2
46
+
47
+ include HTTParty
48
+ base_uri API_ENDPOINT
49
+ default_timeout API_TIMEOUT
50
+
51
+ # Constructor
52
+ #
53
+ # == Parameters:
54
+ # api_key
55
+ # The Sift Science API key associated with your customer account. This parameter
56
+ # cannot be nil or blank.
57
+ # path
58
+ # The path to the event API, e.g., "/v201/events"
59
+ #
60
+ def initialize(api_key, path = Sift.current_rest_api_path)
61
+ @api_key = api_key.to_s
62
+ @path = path
63
+ raise(RuntimeError, "api_key is required") if @api_key.nil? || @api_key.empty?
64
+ end
65
+
66
+ # Tracks an event and associated properties through the Sift Science API. This call
67
+ # is blocking.
68
+ #
69
+ # == Parameters:
70
+ # event
71
+ # The name of the event to send. This can be either a reserved event name, like
72
+ # $transaction or $label or a custom event name (that does not start with a $).
73
+ # This parameter must be specified.
74
+ #
75
+ # properties
76
+ # A hash of name-value pairs that specify the event-specific attributes to track.
77
+ # This parameter must be specified.
78
+ #
79
+ # timeout
80
+ # The number of seconds to wait before failing the request. By default this is
81
+ # configured to 2 seconds (see above). This parameter is optional.
82
+ #
83
+ # == Returns:
84
+ # In the case of an HTTP error (timeout, broken connection, etc.), this
85
+ # method returns nil; otherwise, a Response object is returned and captures
86
+ # the status message and status code. In general, you can ignore the returned
87
+ # result, though.
88
+ #
89
+ def track(event, properties = {}, timeout = nil)
90
+
91
+ raise(RuntimeError, "event must be a string") if event.nil? || event.to_s.empty?
92
+ raise(RuntimeError, "properties cannot be empty") if properties.empty?
93
+
94
+ options = {
95
+ :body => MultiJson.dump(properties.merge({"$type" => event,
96
+ "$api_key" => @api_key})),
97
+ }
98
+ options.merge!(:timeout => timeout) unless timeout.nil?
99
+ begin
100
+ response = self.class.post(@path, options)
101
+ Response.new(response.body, response.code)
102
+ rescue StandardError => e
103
+ Sift.warn("Failed to track event: " + e.to_s)
104
+ Sift.warn(e.backtrace)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ module Sift
2
+ VERSION = "1.0.5"
3
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sift/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sift"
7
+ s.version = Sift::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Fred Sadaghiani"]
10
+ s.email = ["freds@siftscience.com"]
11
+ s.homepage = "http://siftscience.com"
12
+ s.summary = %q{Sift Science Ruby API Gem}
13
+ s.description = %q{Sift Science Ruby API. Please see http://siftscience.com for more details.}
14
+
15
+ s.rubyforge_project = "sift"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ # Gems that must be intalled for sift to compile and build
23
+ s.add_development_dependency "rspec", "~> 2.9.0"
24
+ s.add_development_dependency "fakeweb", "~> 1.3.0"
25
+
26
+ # Gems that must be intalled for sift to work
27
+ s.add_dependency "httparty", ">= 0.8.3"
28
+ s.add_dependency "multi_json", ">= 1.3.4"
29
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe Sift do
4
+
5
+
6
+
7
+ end
@@ -0,0 +1,10 @@
1
+
2
+ require "bundler/setup"
3
+ require "sift"
4
+ require "fakeweb"
5
+
6
+ # Setup Fakeweb
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ RSpec.configure do |config|
10
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe Sift::Client do
4
+
5
+ def valid_transaction_properties
6
+ {
7
+ :$buyer_user_id => "123456",
8
+ :$seller_user_id => "654321",
9
+ :$amount => 1253200,
10
+ :$currency_code => "USD",
11
+ :$time => Time.now.to_i,
12
+ :$transaction_id => "my_transaction_id",
13
+ :$billing_name => "Mike Snow",
14
+ :$billing_bin => "411111",
15
+ :$billing_last4 => "1111",
16
+ :$billing_address1 => "123 Main St.",
17
+ :$billing_city => "San Francisco",
18
+ :$billing_region => "CA",
19
+ :$billing_country => "US",
20
+ :$billing_zip => "94131",
21
+ :$buyer_email => "mike@example.com"
22
+ }
23
+ end
24
+
25
+ def fully_qualified_api_endpoint
26
+ Sift::Client::API_ENDPOINT + Sift.current_rest_api_path
27
+ end
28
+
29
+ it "Cannot instantiate client with nil or blank api key" do
30
+ lambda { Sift::Client.new(nil) }.should raise_error
31
+ lambda { Sift::Client.new("") }.should raise_error
32
+ end
33
+
34
+ it "Track call must specify an event name" do
35
+ lambda { Sift::Client.new("foo").track(nil) }.should raise_error
36
+ lambda { Sift::Client.new("foo").track("") }.should raise_error
37
+ end
38
+
39
+ it "Must specify an event name" do
40
+ lambda { Sift::Client.new("foo").track(nil) }.should raise_error
41
+ lambda { Sift::Client.new("foo").track("") }.should raise_error
42
+ end
43
+
44
+ it "Must specify properties" do
45
+ event = "custom_event_name"
46
+ lambda { Sift::Client.new("foo").track(event) }.should raise_error
47
+ end
48
+
49
+ it "Doesn't raise an exception on Net/HTTP errors" do
50
+
51
+ FakeWeb.register_uri(:post, fully_qualified_api_endpoint,
52
+ :body => nil, :exception => Net::HTTPError)
53
+
54
+ api_key = "foobar"
55
+ event = "$transaction"
56
+ properties = valid_transaction_properties
57
+
58
+ # This method should just return false -- the track call failed because
59
+ # of an HTTP error
60
+ Sift::Client.new(api_key).track(event, properties).should eq(nil)
61
+ end
62
+
63
+ it "Successfuly handles an event and returns OK" do
64
+
65
+ response_json = { :status => 0, :error_message => "OK" }
66
+
67
+ FakeWeb.register_uri(:post, fully_qualified_api_endpoint,
68
+ :body => MultiJson.dump(response_json),
69
+ :status => [Net::HTTPOK, "OK"],
70
+ :content_type => "text/json")
71
+
72
+ api_key = "foobar"
73
+ event = "$transaction"
74
+ properties = valid_transaction_properties
75
+
76
+ response = Sift::Client.new(api_key).track(event, properties)
77
+ response.ok?.should eq(true)
78
+ response.api_status.should eq(0)
79
+ response.api_error_message.should eq("OK")
80
+ end
81
+
82
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe Sift do
4
+
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sift
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fred Sadaghiani
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-02 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70093902351140 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.9.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70093902351140
25
+ - !ruby/object:Gem::Dependency
26
+ name: fakeweb
27
+ requirement: &70093902438840 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70093902438840
36
+ - !ruby/object:Gem::Dependency
37
+ name: httparty
38
+ requirement: &70093902565360 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.8.3
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70093902565360
47
+ - !ruby/object:Gem::Dependency
48
+ name: multi_json
49
+ requirement: &70093902656720 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.4
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70093902656720
58
+ description: Sift Science Ruby API. Please see http://siftscience.com for more details.
59
+ email:
60
+ - freds@siftscience.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - HISTORY
68
+ - README.rdoc
69
+ - Rakefile
70
+ - examples/simple.rb
71
+ - lib/sift.rb
72
+ - lib/sift/client.rb
73
+ - lib/sift/version.rb
74
+ - sift.gemspec
75
+ - spec/integration/sift_spec.rb
76
+ - spec/spec_helper.rb
77
+ - spec/unit/client_spec.rb
78
+ - spec/unit/sift_spec.rb
79
+ homepage: http://siftscience.com
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project: sift
99
+ rubygems_version: 1.8.10
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Sift Science Ruby API Gem
103
+ test_files:
104
+ - spec/integration/sift_spec.rb
105
+ - spec/spec_helper.rb
106
+ - spec/unit/client_spec.rb
107
+ - spec/unit/sift_spec.rb