dash-fu 1.0.0
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/CHANGELOG +3 -0
- data/README.md +36 -0
- data/VERSION +1 -0
- data/dash-fu.gemspec +17 -0
- data/lib/dash-fu.rb +94 -0
- data/test/test.rb +62 -0
- metadata +63 -0
data/CHANGELOG
ADDED
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
Use me to push data to [Dash-fu](http://dash-fu.com) in real time.
|
2
|
+
|
3
|
+
|
4
|
+
The only configuration you need is setting the API key in
|
5
|
+
`config/environments/production.rb`:
|
6
|
+
|
7
|
+
DashFu.api_key = "<your API key>"
|
8
|
+
|
9
|
+
Your API key is available from [account settings](http://dash-fu.com/settings).
|
10
|
+
|
11
|
+
You only want to push data in production, so make sure the API key is only set
|
12
|
+
in production environment. Calls to created/active with no API key are
|
13
|
+
simply ignored.
|
14
|
+
|
15
|
+
|
16
|
+
You can send events by calling DashFu.push with UID and event, or using the
|
17
|
+
specialized created and active methods.
|
18
|
+
|
19
|
+
For example, to assign a user to a cohort, we're going to notify Dash-fu
|
20
|
+
whenever an acount gets created:
|
21
|
+
|
22
|
+
class User < ActiveRecord::Model
|
23
|
+
after_create do
|
24
|
+
DashFu.created id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
In this example, we consider a user active whenever they post a status update,
|
29
|
+
and notify Dash-fu accordingly:
|
30
|
+
|
31
|
+
class StatusUpdate < ActiveRecord::Model
|
32
|
+
after_create do
|
33
|
+
DashFu.active id
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/dash-fu.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
$: << File.dirname(__FILE__) + "/lib"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "dash-fu"
|
5
|
+
spec.version = IO.read("VERSION")
|
6
|
+
spec.author = "Assaf Arkin"
|
7
|
+
spec.email = "assaf@labnotes.org"
|
8
|
+
spec.homepage = "http://dash-fu.com"
|
9
|
+
spec.summary = "Use me to push data to Dash-fu in real time"
|
10
|
+
spec.description = ""
|
11
|
+
spec.post_install_message = IO.read("README.md")
|
12
|
+
spec.license = "Public domain"
|
13
|
+
|
14
|
+
spec.files = Dir["{bin,lib,test}/**/*", "CHANGELOG", "VERSION", "README.md", "*.gemspec"]
|
15
|
+
|
16
|
+
spec.required_ruby_version = '>= 1.8.7'
|
17
|
+
end
|
data/lib/dash-fu.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
3
|
+
|
4
|
+
# Use me to push data to Dash-fu in real time.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# The only configuration you need is setting the API key in
|
8
|
+
# config/environments/production.rb:
|
9
|
+
#
|
10
|
+
# DashFu.api_key = "<your API key>"
|
11
|
+
#
|
12
|
+
# You only want to push data in production, so make sure the API key is only set
|
13
|
+
# in production environment. Calls to created/active with no API key are
|
14
|
+
# simply ignored.
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# You can send events by calling DashFu.push with UID and event, or using the
|
18
|
+
# specialized created and active methods.
|
19
|
+
#
|
20
|
+
# For example, to assign a user to a cohort, we're going to notify Dash-fu
|
21
|
+
# whenever an acount gets created:
|
22
|
+
#
|
23
|
+
# class User < ActiveRecord::Model
|
24
|
+
# after_create do
|
25
|
+
# DashFu.created id
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# In this example, we consider a user active whenever they post a status update,
|
30
|
+
# and notify Dash-fu accordingly:
|
31
|
+
#
|
32
|
+
# class StatusUpdate < ActiveRecord::Model
|
33
|
+
# after_create do
|
34
|
+
# DashFu.active id
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
module DashFu
|
38
|
+
@mutex = Mutex.new
|
39
|
+
|
40
|
+
class << self
|
41
|
+
# DashFu.host is set by default, this is only useful for testing.
|
42
|
+
attr_accessor :host, :port
|
43
|
+
|
44
|
+
# Set the API key with:
|
45
|
+
# DashFu.api_key = "<your API key>"
|
46
|
+
attr_accessor :api_key
|
47
|
+
|
48
|
+
# Records that a user has been active in the app.
|
49
|
+
def active(uid)
|
50
|
+
push uid, "active"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Records that a new user account has been created (associate them with
|
54
|
+
# cohort).
|
55
|
+
def created(uid)
|
56
|
+
push uid, "created"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Close connection. If you like crossing your t's you can call this when the
|
60
|
+
# app shutsdown.
|
61
|
+
def close
|
62
|
+
@mutex.synchronize do
|
63
|
+
socket, @socket = @socket, nil
|
64
|
+
socket.close if socket
|
65
|
+
end
|
66
|
+
rescue Exception
|
67
|
+
end
|
68
|
+
|
69
|
+
# Push update for the specified user ID and event. Or you can use
|
70
|
+
# active/created.
|
71
|
+
def push(uid, event)
|
72
|
+
return unless @api_key
|
73
|
+
if socket = @socket
|
74
|
+
socket.sendmsg_nonblock "POST /v1/push?api_key=#{@api_key}&uid=#{uid}&event=#{event} HTTP/1.1\r\nHost: #{@host}\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n", 0
|
75
|
+
socket.recv_nonblock 512 rescue nil
|
76
|
+
else
|
77
|
+
Thread.new do
|
78
|
+
@mutex.synchronize do
|
79
|
+
@socket ||= TCPSocket.open(@host, @port || 80)
|
80
|
+
end
|
81
|
+
push uid, event
|
82
|
+
end
|
83
|
+
end
|
84
|
+
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT
|
85
|
+
close
|
86
|
+
retry
|
87
|
+
rescue Errno::ECONNREFUSED, Errno::ENETUNREACH
|
88
|
+
# No @socket so we'll try to connect next time
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Default host name.
|
93
|
+
self.host = "beta.dash-fu.com"
|
94
|
+
end
|
data/test/test.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "thread"
|
3
|
+
require "cgi"
|
4
|
+
require "webrick"
|
5
|
+
$: << File.dirname(__FILE__) + "/../lib"
|
6
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/..")
|
7
|
+
require "dash-fu"
|
8
|
+
|
9
|
+
|
10
|
+
$ready = Queue.new
|
11
|
+
$server = WEBrick::HTTPServer.new(:Port=>3001, :StartCallback=>lambda { puts "go"; $ready << "go" }, :Logger=>WEBrick::Log.new(nil, WEBrick::Log::FATAL))
|
12
|
+
servlet = lambda do |request, response|
|
13
|
+
$request = request
|
14
|
+
response.status = 200
|
15
|
+
end
|
16
|
+
$server.mount "/v1/push", WEBrick::HTTPServlet::ProcHandler.new(servlet)
|
17
|
+
trap "INT" do
|
18
|
+
$server.shutdown
|
19
|
+
end
|
20
|
+
DashFu.host = "localhost"
|
21
|
+
DashFu.port = 3001
|
22
|
+
|
23
|
+
|
24
|
+
class Test::Unit::TestCase
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Test sending live data.
|
30
|
+
class LiveTest < Test::Unit::TestCase
|
31
|
+
def setup
|
32
|
+
DashFu.api_key = "foobar"
|
33
|
+
Thread.new { $server.start }
|
34
|
+
$ready.pop
|
35
|
+
$request = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_active_request
|
39
|
+
DashFu.active "56789"
|
40
|
+
sleep 0.2
|
41
|
+
assert_equal "/v1/push", $request.path
|
42
|
+
assert_equal "POST", $request.request_method
|
43
|
+
assert $request.keep_alive?
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_active_data
|
47
|
+
DashFu.active "56789"
|
48
|
+
sleep 0.2
|
49
|
+
query = CGI.parse($request.query_string)
|
50
|
+
assert_equal ["foobar"], query["api_key"]
|
51
|
+
assert_equal ["active"], query["event"]
|
52
|
+
assert_equal ["56789"], query["uid"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def teardown
|
56
|
+
$server.shutdown
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Test Dashfu API when no API key set (e.g. test and development environments).
|
61
|
+
class InactiveTest < Test::Unit::TestCase
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dash-fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Assaf Arkin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-22 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: ''
|
15
|
+
email: assaf@labnotes.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/dash-fu.rb
|
21
|
+
- test/test.rb
|
22
|
+
- CHANGELOG
|
23
|
+
- VERSION
|
24
|
+
- README.md
|
25
|
+
- dash-fu.gemspec
|
26
|
+
homepage: http://dash-fu.com
|
27
|
+
licenses:
|
28
|
+
- Public domain
|
29
|
+
post_install_message: ! "Use me to push data to [Dash-fu](http://dash-fu.com) in real
|
30
|
+
time.\n\n\nThe only configuration you need is setting the API key in\n`config/environments/production.rb`:\n\n
|
31
|
+
\ DashFu.api_key = \"<your API key>\"\n\nYour API key is available from [account
|
32
|
+
settings](http://dash-fu.com/settings).\n\nYou only want to push data in production,
|
33
|
+
so make sure the API key is only set\nin production environment. Calls to created/active
|
34
|
+
with no API key are\nsimply ignored.\n\n\nYou can send events by calling DashFu.push
|
35
|
+
with UID and event, or using the\nspecialized created and active methods.\n\nFor
|
36
|
+
example, to assign a user to a cohort, we're going to notify Dash-fu\nwhenever an
|
37
|
+
acount gets created:\n\n class User < ActiveRecord::Model\n after_create
|
38
|
+
do\n DashFu.created id\n end\n end\n\nIn this example, we consider
|
39
|
+
a user active whenever they post a status update,\nand notify Dash-fu accordingly:\n\n
|
40
|
+
\ class StatusUpdate < ActiveRecord::Model\n after_create do\n DashFu.active
|
41
|
+
id\n end\n end\n\n"
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.8.7
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.8.8
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Use me to push data to Dash-fu in real time
|
63
|
+
test_files: []
|