keen 0.0.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/.gitignore +9 -0
- data/.rvmrc +2 -0
- data/Gemfile +5 -0
- data/README.md +7 -0
- data/bin/keen_send +45 -0
- data/conf/cacert.pem +3376 -0
- data/examples.rb +26 -0
- data/examples/rails_2/.rvmrc +2 -0
- data/examples/rails_2/CoolForums/README +243 -0
- data/examples/rails_2/CoolForums/Rakefile +10 -0
- data/examples/rails_2/CoolForums/app/controllers/application_controller.rb +30 -0
- data/examples/rails_2/CoolForums/app/controllers/forums_controller.rb +83 -0
- data/examples/rails_2/CoolForums/app/controllers/users_controller.rb +83 -0
- data/examples/rails_2/CoolForums/app/helpers/application_helper.rb +3 -0
- data/examples/rails_2/CoolForums/app/helpers/forums_helper.rb +2 -0
- data/examples/rails_2/CoolForums/app/helpers/users_helper.rb +2 -0
- data/examples/rails_2/CoolForums/app/models/forum.rb +2 -0
- data/examples/rails_2/CoolForums/app/models/user.rb +2 -0
- data/examples/rails_2/CoolForums/app/views/forums/edit.html.erb +16 -0
- data/examples/rails_2/CoolForums/app/views/forums/index.html.erb +20 -0
- data/examples/rails_2/CoolForums/app/views/forums/new.html.erb +15 -0
- data/examples/rails_2/CoolForums/app/views/forums/show.html.erb +8 -0
- data/examples/rails_2/CoolForums/app/views/layouts/forums.html.erb +17 -0
- data/examples/rails_2/CoolForums/app/views/layouts/users.html.erb +17 -0
- data/examples/rails_2/CoolForums/app/views/users/edit.html.erb +20 -0
- data/examples/rails_2/CoolForums/app/views/users/index.html.erb +22 -0
- data/examples/rails_2/CoolForums/app/views/users/new.html.erb +19 -0
- data/examples/rails_2/CoolForums/app/views/users/show.html.erb +13 -0
- data/examples/rails_2/CoolForums/config/boot.rb +114 -0
- data/examples/rails_2/CoolForums/config/database.yml +22 -0
- data/examples/rails_2/CoolForums/config/environment.rb +41 -0
- data/examples/rails_2/CoolForums/config/environments/development.rb +17 -0
- data/examples/rails_2/CoolForums/config/environments/production.rb +28 -0
- data/examples/rails_2/CoolForums/config/environments/test.rb +28 -0
- data/examples/rails_2/CoolForums/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/rails_2/CoolForums/config/initializers/cookie_verification_secret.rb +7 -0
- data/examples/rails_2/CoolForums/config/initializers/inflections.rb +10 -0
- data/examples/rails_2/CoolForums/config/initializers/mime_types.rb +5 -0
- data/examples/rails_2/CoolForums/config/initializers/new_rails_defaults.rb +21 -0
- data/examples/rails_2/CoolForums/config/initializers/session_store.rb +15 -0
- data/examples/rails_2/CoolForums/config/locales/en.yml +5 -0
- data/examples/rails_2/CoolForums/config/routes.rb +53 -0
- data/examples/rails_2/CoolForums/db/migrate/20120317012301_create_users.rb +15 -0
- data/examples/rails_2/CoolForums/db/migrate/20120317012444_create_forums.rb +14 -0
- data/examples/rails_2/CoolForums/db/schema.rb +28 -0
- data/examples/rails_2/CoolForums/db/seeds.rb +7 -0
- data/examples/rails_2/CoolForums/doc/README_FOR_APP +2 -0
- data/examples/rails_2/CoolForums/public/404.html +30 -0
- data/examples/rails_2/CoolForums/public/422.html +30 -0
- data/examples/rails_2/CoolForums/public/500.html +30 -0
- data/examples/rails_2/CoolForums/public/favicon.ico +0 -0
- data/examples/rails_2/CoolForums/public/images/rails.png +0 -0
- data/examples/rails_2/CoolForums/public/index.html +275 -0
- data/examples/rails_2/CoolForums/public/javascripts/application.js +2 -0
- data/examples/rails_2/CoolForums/public/javascripts/controls.js +963 -0
- data/examples/rails_2/CoolForums/public/javascripts/dragdrop.js +973 -0
- data/examples/rails_2/CoolForums/public/javascripts/effects.js +1128 -0
- data/examples/rails_2/CoolForums/public/javascripts/prototype.js +4320 -0
- data/examples/rails_2/CoolForums/public/robots.txt +5 -0
- data/examples/rails_2/CoolForums/public/stylesheets/scaffold.css +54 -0
- data/examples/rails_2/CoolForums/script/about +4 -0
- data/examples/rails_2/CoolForums/script/console +3 -0
- data/examples/rails_2/CoolForums/script/dbconsole +3 -0
- data/examples/rails_2/CoolForums/script/destroy +3 -0
- data/examples/rails_2/CoolForums/script/generate +3 -0
- data/examples/rails_2/CoolForums/script/performance/benchmarker +3 -0
- data/examples/rails_2/CoolForums/script/performance/profiler +3 -0
- data/examples/rails_2/CoolForums/script/plugin +3 -0
- data/examples/rails_2/CoolForums/script/runner +3 -0
- data/examples/rails_2/CoolForums/script/server +3 -0
- data/examples/rails_2/CoolForums/test/fixtures/forums.yml +9 -0
- data/examples/rails_2/CoolForums/test/fixtures/users.yml +11 -0
- data/examples/rails_2/CoolForums/test/functional/forums_controller_test.rb +45 -0
- data/examples/rails_2/CoolForums/test/functional/users_controller_test.rb +45 -0
- data/examples/rails_2/CoolForums/test/performance/browsing_test.rb +9 -0
- data/examples/rails_2/CoolForums/test/test_helper.rb +38 -0
- data/examples/rails_2/CoolForums/test/unit/forum_test.rb +8 -0
- data/examples/rails_2/CoolForums/test/unit/helpers/forums_helper_test.rb +4 -0
- data/examples/rails_2/CoolForums/test/unit/helpers/users_helper_test.rb +4 -0
- data/examples/rails_2/CoolForums/test/unit/user_test.rb +8 -0
- data/examples/rails_2/Gemfile +4 -0
- data/keen.gemspec +37 -0
- data/lib/keen.rb +3 -0
- data/lib/keen/client.rb +123 -0
- data/lib/keen/storage/flat_file_handler.rb +55 -0
- data/lib/keen/storage/redis_handler.rb +155 -0
- data/lib/keen/version.rb +3 -0
- data/test/keen_spec.rb +26 -0
- metadata +234 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
body { background-color: #fff; color: #333; }
|
|
2
|
+
|
|
3
|
+
body, p, ol, ul, td {
|
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
|
5
|
+
font-size: 13px;
|
|
6
|
+
line-height: 18px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
pre {
|
|
10
|
+
background-color: #eee;
|
|
11
|
+
padding: 10px;
|
|
12
|
+
font-size: 11px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
a { color: #000; }
|
|
16
|
+
a:visited { color: #666; }
|
|
17
|
+
a:hover { color: #fff; background-color:#000; }
|
|
18
|
+
|
|
19
|
+
.fieldWithErrors {
|
|
20
|
+
padding: 2px;
|
|
21
|
+
background-color: red;
|
|
22
|
+
display: table;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#errorExplanation {
|
|
26
|
+
width: 400px;
|
|
27
|
+
border: 2px solid red;
|
|
28
|
+
padding: 7px;
|
|
29
|
+
padding-bottom: 12px;
|
|
30
|
+
margin-bottom: 20px;
|
|
31
|
+
background-color: #f0f0f0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#errorExplanation h2 {
|
|
35
|
+
text-align: left;
|
|
36
|
+
font-weight: bold;
|
|
37
|
+
padding: 5px 5px 5px 15px;
|
|
38
|
+
font-size: 12px;
|
|
39
|
+
margin: -7px;
|
|
40
|
+
background-color: #c00;
|
|
41
|
+
color: #fff;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#errorExplanation p {
|
|
45
|
+
color: #333;
|
|
46
|
+
margin-bottom: 0;
|
|
47
|
+
padding: 5px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#errorExplanation ul li {
|
|
51
|
+
font-size: 12px;
|
|
52
|
+
list-style: square;
|
|
53
|
+
}
|
|
54
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class ForumsControllerTest < ActionController::TestCase
|
|
4
|
+
test "should get index" do
|
|
5
|
+
get :index
|
|
6
|
+
assert_response :success
|
|
7
|
+
assert_not_nil assigns(:forums)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "should get new" do
|
|
11
|
+
get :new
|
|
12
|
+
assert_response :success
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "should create forum" do
|
|
16
|
+
assert_difference('Forum.count') do
|
|
17
|
+
post :create, :forum => { }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
assert_redirected_to forum_path(assigns(:forum))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test "should show forum" do
|
|
24
|
+
get :show, :id => forums(:one).to_param
|
|
25
|
+
assert_response :success
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "should get edit" do
|
|
29
|
+
get :edit, :id => forums(:one).to_param
|
|
30
|
+
assert_response :success
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test "should update forum" do
|
|
34
|
+
put :update, :id => forums(:one).to_param, :forum => { }
|
|
35
|
+
assert_redirected_to forum_path(assigns(:forum))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "should destroy forum" do
|
|
39
|
+
assert_difference('Forum.count', -1) do
|
|
40
|
+
delete :destroy, :id => forums(:one).to_param
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
assert_redirected_to forums_path
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class UsersControllerTest < ActionController::TestCase
|
|
4
|
+
test "should get index" do
|
|
5
|
+
get :index
|
|
6
|
+
assert_response :success
|
|
7
|
+
assert_not_nil assigns(:users)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "should get new" do
|
|
11
|
+
get :new
|
|
12
|
+
assert_response :success
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "should create user" do
|
|
16
|
+
assert_difference('User.count') do
|
|
17
|
+
post :create, :user => { }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
assert_redirected_to user_path(assigns(:user))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test "should show user" do
|
|
24
|
+
get :show, :id => users(:one).to_param
|
|
25
|
+
assert_response :success
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "should get edit" do
|
|
29
|
+
get :edit, :id => users(:one).to_param
|
|
30
|
+
assert_response :success
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test "should update user" do
|
|
34
|
+
put :update, :id => users(:one).to_param, :user => { }
|
|
35
|
+
assert_redirected_to user_path(assigns(:user))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "should destroy user" do
|
|
39
|
+
assert_difference('User.count', -1) do
|
|
40
|
+
delete :destroy, :id => users(:one).to_param
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
assert_redirected_to users_path
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
|
3
|
+
require 'test_help'
|
|
4
|
+
|
|
5
|
+
class ActiveSupport::TestCase
|
|
6
|
+
# Transactional fixtures accelerate your tests by wrapping each test method
|
|
7
|
+
# in a transaction that's rolled back on completion. This ensures that the
|
|
8
|
+
# test database remains unchanged so your fixtures don't have to be reloaded
|
|
9
|
+
# between every test method. Fewer database queries means faster tests.
|
|
10
|
+
#
|
|
11
|
+
# Read Mike Clark's excellent walkthrough at
|
|
12
|
+
# http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
|
|
13
|
+
#
|
|
14
|
+
# Every Active Record database supports transactions except MyISAM tables
|
|
15
|
+
# in MySQL. Turn off transactional fixtures in this case; however, if you
|
|
16
|
+
# don't care one way or the other, switching from MyISAM to InnoDB tables
|
|
17
|
+
# is recommended.
|
|
18
|
+
#
|
|
19
|
+
# The only drawback to using transactional fixtures is when you actually
|
|
20
|
+
# need to test transactions. Since your test is bracketed by a transaction,
|
|
21
|
+
# any transactions started in your code will be automatically rolled back.
|
|
22
|
+
self.use_transactional_fixtures = true
|
|
23
|
+
|
|
24
|
+
# Instantiated fixtures are slow, but give you @david where otherwise you
|
|
25
|
+
# would need people(:david). If you don't want to migrate your existing
|
|
26
|
+
# test cases which use the @david style and don't mind the speed hit (each
|
|
27
|
+
# instantiated fixtures translates to a database query per test method),
|
|
28
|
+
# then set this back to true.
|
|
29
|
+
self.use_instantiated_fixtures = false
|
|
30
|
+
|
|
31
|
+
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
|
32
|
+
#
|
|
33
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
|
34
|
+
# -- they do not yet inherit this setting
|
|
35
|
+
fixtures :all
|
|
36
|
+
|
|
37
|
+
# Add more helper methods to be used by all tests here...
|
|
38
|
+
end
|
data/keen.gemspec
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "keen/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "keen"
|
|
7
|
+
s.version = Keen::VERSION
|
|
8
|
+
s.authors = ["Kyle Wild"]
|
|
9
|
+
s.email = ["kyle@keen.io"]
|
|
10
|
+
s.homepage = "https://github.com/keenlabs/KeenClient-Ruby"
|
|
11
|
+
s.summary = "A library for sending events to the keen.io API."
|
|
12
|
+
s.description = "See the github repo or examples.rb for usage information."
|
|
13
|
+
|
|
14
|
+
s.rubyforge_project = "keen"
|
|
15
|
+
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
|
+
s.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
# specify any dependencies here; for example:
|
|
22
|
+
# s.add_development_dependency "rspec"
|
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
|
24
|
+
|
|
25
|
+
s.add_dependency('multi_json', '>= 1.0.3')
|
|
26
|
+
s.add_dependency('fakeweb', '>= 1.3.0')
|
|
27
|
+
s.add_dependency('system_timer', '>= 1.2.4')
|
|
28
|
+
s.add_dependency('httparty', '>= 0.8.1')
|
|
29
|
+
s.add_dependency('redis', '>= 2.2.2')
|
|
30
|
+
|
|
31
|
+
# took these from Twilio library:
|
|
32
|
+
# TODO clean this up.
|
|
33
|
+
#s.add_development_dependency 'rake', '~> 0.9.0'
|
|
34
|
+
#s.add_development_dependency 'rspec', '~> 2.6.0'
|
|
35
|
+
#s.add_development_dependency 'fakeweb', '~> 1.3.0'
|
|
36
|
+
#s.add_development_dependency 'rack', '~> 1.3.0'
|
|
37
|
+
end
|
data/lib/keen.rb
ADDED
data/lib/keen/client.rb
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'keen/storage/redis_handler'
|
|
2
|
+
require 'json'
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "uri"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Keen
|
|
8
|
+
class Client
|
|
9
|
+
|
|
10
|
+
def self.batch_url(project_id)
|
|
11
|
+
"http://api.keen.io/1.0/projects/#{project_id}/_events"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(project_id, auth_token)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_event(collection_name, event_body)
|
|
18
|
+
validate_collection_name(collection_name)
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.process_queue(options)
|
|
23
|
+
mode = options[:storage_mode].to_sym
|
|
24
|
+
case mode
|
|
25
|
+
when :flat_file
|
|
26
|
+
self.process_queue_from_flat_file(options)
|
|
27
|
+
when :redis
|
|
28
|
+
self.process_queue_from_redis(options)
|
|
29
|
+
else
|
|
30
|
+
raise "Unknown storage_mode sent: `#{mode}`"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.process_queue_from_redis(options)
|
|
35
|
+
require 'keen/storage/redis_handler'
|
|
36
|
+
handler = Keen::Storage::RedisHandler.new
|
|
37
|
+
collated = handler.process_queue
|
|
38
|
+
|
|
39
|
+
# TODO: remove this mock:
|
|
40
|
+
collated = {
|
|
41
|
+
"4f5775ad163d666a6100000e" => {
|
|
42
|
+
"clicks" => [
|
|
43
|
+
Keen::Storage::Item.new({
|
|
44
|
+
:project_id => "4f5775ad163d666a6100000e",
|
|
45
|
+
:auth_token => "a5d4eaf432914823a94ecd7e0cb547b9",
|
|
46
|
+
:collection_name => "clicks",
|
|
47
|
+
:event_body => {:user_id => "12345"},
|
|
48
|
+
}),
|
|
49
|
+
Keen::Storage::Item.new({
|
|
50
|
+
:project_id => "4f5775ad163d666a6100000e",
|
|
51
|
+
:auth_token => "a5d4eaf432914823a94ecd7e0cb547b9",
|
|
52
|
+
:collection_name => "clicks",
|
|
53
|
+
:event_body => {:user_id => "12345"},
|
|
54
|
+
}),
|
|
55
|
+
Keen::Storage::Item.new({
|
|
56
|
+
:project_id => "4f5775ad163d666a6100000e",
|
|
57
|
+
:auth_token => "a5d4eaf432914823a94ecd7e0cb547b9",
|
|
58
|
+
:collection_name => "clicks",
|
|
59
|
+
:event_body => {:user_id => "12345"},
|
|
60
|
+
}),
|
|
61
|
+
],
|
|
62
|
+
"purchases" => [
|
|
63
|
+
Keen::Storage::Item.new({
|
|
64
|
+
:project_id => "4f5775ad163d666a6100000e",
|
|
65
|
+
:auth_token => "a5d4eaf432914823a94ecd7e0cb547b9",
|
|
66
|
+
:collection_name => "purchases",
|
|
67
|
+
:event_body => {:user_id => "12345"},
|
|
68
|
+
}),
|
|
69
|
+
Keen::Storage::Item.new({
|
|
70
|
+
:project_id => "4f5775ad163d666a6100000e",
|
|
71
|
+
:auth_token => "a5d4eaf432914823a94ecd7e0cb547b9",
|
|
72
|
+
:collection_name => "purchases",
|
|
73
|
+
:event_body => {:user_id => "12345"},
|
|
74
|
+
}),
|
|
75
|
+
Keen::Storage::Item.new({
|
|
76
|
+
:project_id => "4f5775ad163d666a6100000e",
|
|
77
|
+
:auth_token => "a5d4eaf432914823a94ecd7e0cb547b9",
|
|
78
|
+
:collection_name => "purchases",
|
|
79
|
+
:event_body => {:user_id => "12345"},
|
|
80
|
+
}),
|
|
81
|
+
],
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
collated.each do |project_id, batch|
|
|
86
|
+
self.send_batch(project_id, batch)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def self.send_batch(project_id, batch)
|
|
91
|
+
if not batch
|
|
92
|
+
return
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
first_key = batch.keys[0]
|
|
96
|
+
item_list = batch[first_key]
|
|
97
|
+
puts item_list[0].class
|
|
98
|
+
auth_token = item_list[0].auth_token
|
|
99
|
+
|
|
100
|
+
uri = URI.parse(self.batch_url(project_id))
|
|
101
|
+
|
|
102
|
+
request = Net::HTTP::Post.new(uri.path)
|
|
103
|
+
request.body = batch.to_json
|
|
104
|
+
request["Content-Type"] = "application/json"
|
|
105
|
+
request["Authorization"] = auth_token
|
|
106
|
+
|
|
107
|
+
response = Net::HTTP.start(uri.host, uri.port) {|http|
|
|
108
|
+
http.request(request)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
puts response
|
|
112
|
+
|
|
113
|
+
# TODO DK: need to send this batch of Keen::Storage::Item instances
|
|
114
|
+
# to API! we can just use the first auth_token we find on an Item.
|
|
115
|
+
# If something fails, stick the item into the prior_failures queue
|
|
116
|
+
# using push
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def self.process_queue_from_flat_file(options)
|
|
120
|
+
raise "this feature isn't supported yet!!!"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|