saas_pulse-ruby 0.1.1
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/LICENSE +20 -0
- data/README.md +76 -0
- data/lib/saas_pulse/adapter.rb +9 -0
- data/lib/saas_pulse/adapters/base.rb +41 -0
- data/lib/saas_pulse/adapters/merb.rb +15 -0
- data/lib/saas_pulse/adapters/rails.rb +15 -0
- data/lib/saas_pulse/arg_parser.rb +60 -0
- data/lib/saas_pulse/client.rb +47 -0
- data/lib/saas_pulse/resource.rb +80 -0
- data/lib/saas_pulse/tracker.rb +23 -0
- data/lib/saas_pulse/version.rb +3 -0
- data/lib/saas_pulse.rb +15 -0
- metadata +90 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jonah Honeyman
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
20
|
+
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
saas\_pulse-ruby
|
2
|
+
================
|
3
|
+
|
4
|
+
A simple API wrapper for integrating your rails application with [SaaSPulse](http://www.saaspulse.com).
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
`gem install saas_pulse-ruby`
|
10
|
+
|
11
|
+
Usage
|
12
|
+
-----
|
13
|
+
|
14
|
+
First, build your client with your API id:
|
15
|
+
|
16
|
+
SaasPulse.srv_id "YOUR_ID_GOES_HERE"
|
17
|
+
|
18
|
+
You can then interact with `SaasPulse.client` to do your bidding:
|
19
|
+
|
20
|
+
SaasPulse.client.track({
|
21
|
+
:organization => "Current organization",
|
22
|
+
:user => "Current user",
|
23
|
+
:activity => "Current activity",
|
24
|
+
:module => "Current module"
|
25
|
+
})
|
26
|
+
|
27
|
+
There is also the option for integration with different ruby frameworks.
|
28
|
+
|
29
|
+
### Rails
|
30
|
+
|
31
|
+
class ApplicationController < ActionController::Base
|
32
|
+
include SaasPulse::Adapters::Rails
|
33
|
+
|
34
|
+
#...
|
35
|
+
end
|
36
|
+
|
37
|
+
That will build your tracking code based around a couple of sane defaults. By default it will set the current module to `params[:controller]` and activity to `params[:action]`. If you wish to override the defaults you can do so in your controllers:
|
38
|
+
|
39
|
+
class MyController < ApplictationController
|
40
|
+
sp_default :activity, "Whatever you want here"
|
41
|
+
# You may also send a Proc object as the value so that it is
|
42
|
+
# evaluated in the context of the current controller. For example:
|
43
|
+
sp_default :user, proc { method_to_determine_current_user }
|
44
|
+
end
|
45
|
+
|
46
|
+
To track different actions, you must now tell SaasPulse which actions you would like to track:
|
47
|
+
|
48
|
+
class MyController < ApplictationController
|
49
|
+
track :index
|
50
|
+
track :show, "Override default activity text here"
|
51
|
+
track :edit, :user => "override other defaults in a hash"
|
52
|
+
track :destroy, :if => proc { params[:my_boolean] } # Use conditionals to only run tracking based on the eval'd code in the Proc object
|
53
|
+
end
|
54
|
+
|
55
|
+
### Rolling your own adapter
|
56
|
+
|
57
|
+
There are currently adapters for rails and merb, but it is simple to write your own adapter
|
58
|
+
|
59
|
+
module MySPAdapter
|
60
|
+
extend SaasPulse::Adapters::Base
|
61
|
+
|
62
|
+
register_adapter :my_adapter
|
63
|
+
hook_method :before_hook # Hook method name that will be called before or after each action
|
64
|
+
action_finder :action_name # Method that determines the current action being hit
|
65
|
+
|
66
|
+
# You can set defaults from here that will be set on the controller class
|
67
|
+
# that includes your adapter and all of its subclasses
|
68
|
+
sp_default :activity, proc {action_name}
|
69
|
+
sp_default :module, proc {controller_name}
|
70
|
+
end
|
71
|
+
|
72
|
+
TODO
|
73
|
+
----
|
74
|
+
|
75
|
+
* Adapter tests
|
76
|
+
* JS client integration
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
module Adapters
|
3
|
+
module Base
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set :@__current_adapter__, SaasPulse::Adapter.new
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def included(klass)
|
11
|
+
SaasPulse.adapter = adapter
|
12
|
+
klass.send(:include, SaasPulse::Resource) unless klass.include?(SaasPulse::Resource)
|
13
|
+
(@defaults || []).each do |e|
|
14
|
+
klass.sp_default *e
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def sp_default(k, v)
|
19
|
+
@defaults ||= []
|
20
|
+
@defaults << [k,v]
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_adapter(name)
|
24
|
+
adapter.name = name
|
25
|
+
end
|
26
|
+
|
27
|
+
def hook_method(name)
|
28
|
+
adapter.hook = name
|
29
|
+
end
|
30
|
+
|
31
|
+
def action_finder(name)
|
32
|
+
adapter.action_finder = name
|
33
|
+
end
|
34
|
+
|
35
|
+
def adapter
|
36
|
+
@__current_adapter__
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
module Adapters
|
3
|
+
module Merb
|
4
|
+
extend SaasPulse::Adapters::Base
|
5
|
+
|
6
|
+
register_adapter :merb
|
7
|
+
hook_method :after
|
8
|
+
action_finder :action_name
|
9
|
+
|
10
|
+
sp_default :activity, proc { action_name }
|
11
|
+
sp_default :module, proc { controller_name }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
module Adapters
|
3
|
+
module Rails
|
4
|
+
extend SaasPulse::Adapters::Base
|
5
|
+
|
6
|
+
register_adapter :rails
|
7
|
+
hook_method :after_filter
|
8
|
+
action_finder :action_name
|
9
|
+
|
10
|
+
sp_default :activity, proc { action_name }
|
11
|
+
sp_default :module, proc { controller_name }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
class InvalidParamError < StandardError; end
|
3
|
+
|
4
|
+
class ArgParser
|
5
|
+
class <<self
|
6
|
+
attr_reader :named_args
|
7
|
+
|
8
|
+
def parse(args)
|
9
|
+
new.tap do |parser|
|
10
|
+
args.each do |arg, val|
|
11
|
+
param = registered_args[arg]
|
12
|
+
raise InvalidParamError, "'#{arg}' does not map to a valid param" unless param
|
13
|
+
|
14
|
+
parser[param] = val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def parses_arg(name, *aliases)
|
22
|
+
register_named_arg! name
|
23
|
+
attr_reader name
|
24
|
+
|
25
|
+
aliases.unshift(name).each do |argname|
|
26
|
+
registered_args[argname] = name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def registered_args
|
31
|
+
@__registered_args__ ||= {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def register_named_arg!(name)
|
35
|
+
@named_args ||= []
|
36
|
+
@named_args << name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
parses_arg :sdr_a, :a, :act, :activity
|
41
|
+
parses_arg :sdr_o, :o, :org, :organization
|
42
|
+
parses_arg :sdr_m, :m, :mod, :module
|
43
|
+
parses_arg :sdr_u, :u, :user
|
44
|
+
|
45
|
+
def to_params
|
46
|
+
ArgParser.named_args.map do |arg|
|
47
|
+
[arg, CGI.escape(self[arg].to_s)].join("=")
|
48
|
+
end.join("&")
|
49
|
+
end
|
50
|
+
|
51
|
+
def [](arg)
|
52
|
+
instance_variable_get :"@#{arg}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def []=(arg, val)
|
56
|
+
instance_variable_set :"@#{arg}", val
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
BASE_URI = "http://sdr.saaspulse.com/pixel.gif/?sdr_s=".freeze unless self.const_defined?(:BASE_URI)
|
3
|
+
|
4
|
+
class NoClientError < StandardError; end
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_reader :client
|
8
|
+
|
9
|
+
def track(data)
|
10
|
+
raise NoClientError, "You must set the current client first" unless client
|
11
|
+
client.track(data)
|
12
|
+
end
|
13
|
+
|
14
|
+
def srv_id(srv_id)
|
15
|
+
@client = Client.new(srv_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def on?
|
19
|
+
!!@on
|
20
|
+
end
|
21
|
+
|
22
|
+
def on!
|
23
|
+
@on = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Client
|
28
|
+
def initialize(srv_id)
|
29
|
+
@srv_id = srv_id
|
30
|
+
end
|
31
|
+
|
32
|
+
def track(data={})
|
33
|
+
url = build_url(data)
|
34
|
+
|
35
|
+
if SaasPulse.on?
|
36
|
+
Thread.new {open(url)}
|
37
|
+
else
|
38
|
+
puts "[SaasPulse] Fake call to #{url}. To make a real call, run SaasPulse.on!"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_url(data)
|
43
|
+
[BASE_URI, @srv_id, "&", ArgParser.parse(data).to_params].join
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
class NoAdapterError < StandardError; end
|
3
|
+
|
4
|
+
module Resource
|
5
|
+
@sp_defaults = {
|
6
|
+
:organization => "Default Org",
|
7
|
+
:user => "Default User",
|
8
|
+
:activity => "Default Activity",
|
9
|
+
:module => "Default Module"
|
10
|
+
}
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def sp_default(key, val)
|
14
|
+
raise ArgumentError, "Key #{key.inspect} is not a valid option" unless @sp_defaults.keys.member?(key)
|
15
|
+
|
16
|
+
sp_defaults[key] = val
|
17
|
+
end
|
18
|
+
|
19
|
+
# action<Symbol>:: Action to track
|
20
|
+
# opts<Hash>:: Override defaults and set conditional tracking
|
21
|
+
def track(action, *opts)
|
22
|
+
tracker = SaasPulse::Tracker.new(action, *opts)
|
23
|
+
sp_trackers << tracker unless sp_trackers.find {|t| t.action.to_s == action.to_s}
|
24
|
+
end
|
25
|
+
|
26
|
+
def sp_trackers
|
27
|
+
@__sp_trackers__ ||= []
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def inherited(klass)
|
33
|
+
super(klass)
|
34
|
+
klass.instance_variable_set :@sp_defaults, @sp_defaults.dup
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.included(base)
|
39
|
+
base.extend ClassMethods
|
40
|
+
class << base; attr_reader :sp_defaults end
|
41
|
+
base.instance_variable_set :@sp_defaults, @sp_defaults.dup
|
42
|
+
base.send(SaasPulse.adapter.hook, :sp_run)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def sp_run
|
48
|
+
raise NoAdapterError, "No adapter has been set" unless SaasPulse.adapter
|
49
|
+
|
50
|
+
tracker = self.class.sp_trackers.find do |t|
|
51
|
+
t.action.to_s == send(SaasPulse.adapter.action_finder).to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
return unless tracker
|
55
|
+
|
56
|
+
if condition = tracker.opts[:if]
|
57
|
+
return unless instance_eval(&condition)
|
58
|
+
end
|
59
|
+
|
60
|
+
SaasPulse.track({
|
61
|
+
:o => sp_opt(tracker, :organization),
|
62
|
+
:a => sp_opt(tracker, :activity),
|
63
|
+
:m => sp_opt(tracker, :module),
|
64
|
+
:u => sp_opt(tracker, :user)
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
68
|
+
def sp_opt(tracker, param)
|
69
|
+
value = tracker.opts[param] || sp_defaults[param]
|
70
|
+
|
71
|
+
return instance_eval(&value) if Proc === value
|
72
|
+
value
|
73
|
+
end
|
74
|
+
|
75
|
+
def sp_defaults
|
76
|
+
self.class.sp_defaults
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SaasPulse
|
2
|
+
class Tracker
|
3
|
+
def initialize(action, *opts)
|
4
|
+
@action = action
|
5
|
+
activity = opts.shift
|
6
|
+
@opts = opts.empty? ? {} : opts.shift
|
7
|
+
|
8
|
+
return unless activity
|
9
|
+
|
10
|
+
case activity
|
11
|
+
when String
|
12
|
+
@opts[:activity] = activity
|
13
|
+
when Hash
|
14
|
+
@opts = activity
|
15
|
+
else
|
16
|
+
raise ArgumentError, "activity must be a String or Hash"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :action, :opts
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
data/lib/saas_pulse.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
lib = File.expand_path('../../lib/', __FILE__)
|
2
|
+
$:.unshift(lib) unless $:.include?(lib)
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
require 'saas_pulse/client'
|
8
|
+
require 'saas_pulse/arg_parser'
|
9
|
+
require 'saas_pulse/tracker'
|
10
|
+
require 'saas_pulse/adapter'
|
11
|
+
require 'saas_pulse/resource'
|
12
|
+
require 'saas_pulse/adapters/base'
|
13
|
+
require 'saas_pulse/adapters/merb'
|
14
|
+
require 'saas_pulse/adapters/rails'
|
15
|
+
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: saas_pulse-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- jonah honeyman
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-23 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
description: Enables easy integration of SaaSPulse tracking, with options for different ruby web frameworks
|
34
|
+
email:
|
35
|
+
- jonah@honeyman.org
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- lib/saas_pulse.rb
|
44
|
+
- lib/saas_pulse/version.rb
|
45
|
+
- lib/saas_pulse/arg_parser.rb
|
46
|
+
- lib/saas_pulse/client.rb
|
47
|
+
- lib/saas_pulse/resource.rb
|
48
|
+
- lib/saas_pulse/adapters/base.rb
|
49
|
+
- lib/saas_pulse/adapters/rails.rb
|
50
|
+
- lib/saas_pulse/adapters/merb.rb
|
51
|
+
- lib/saas_pulse/adapter.rb
|
52
|
+
- lib/saas_pulse/tracker.rb
|
53
|
+
- LICENSE
|
54
|
+
- README.md
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: https://github.com/jonuts/saas_pulse-ruby
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 3
|
80
|
+
- 6
|
81
|
+
version: 1.3.6
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: saas_pulse-ruby
|
85
|
+
rubygems_version: 1.3.7
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: API wrapper for SaaSPulse tracking integration
|
89
|
+
test_files: []
|
90
|
+
|