beso 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/beso/csv.rb CHANGED
@@ -9,11 +9,17 @@ module Beso
9
9
  protected
10
10
 
11
11
  def csv
12
- @csv ||= if require 'csv'
13
- ::CSV
14
- else
15
- require 'fastercsv'
16
- FasterCSV
12
+ @csv ||= Object.const_get( :CSV ) || begin
13
+ if require 'csv'
14
+ ::CSV
15
+ else
16
+ begin
17
+ require 'fastercsv'
18
+ FasterCSV
19
+ rescue
20
+ raise "Ruby version #{RUBY_VERSION} users need to require 'fastercsv'"
21
+ end
22
+ end
17
23
  end
18
24
  end
19
25
 
data/lib/beso/job.rb CHANGED
@@ -5,6 +5,7 @@ module Beso
5
5
  @title = options.delete( :event ) || @event.to_s.titleize
6
6
  @table = options.delete( :table )
7
7
  @since = options.delete( :since )
8
+ @scope = options.delete( :scope ) || lambda { self }
8
9
  @props = { }
9
10
  @extra = options
10
11
  end
@@ -28,9 +29,9 @@ module Beso
28
29
  raise MissingIdentityError if @identity.nil?
29
30
  raise MissingTimestampError if @timestamp.nil?
30
31
 
31
- @since ||= options.delete :since
32
+ @since ||= options.delete( :since ) || first_timestamp
32
33
 
33
- relation = model_class.where( "#{@timestamp} >= ?", @since || first_timestamp )
34
+ relation = model_class.instance_exec( &@scope ).where( "#{@timestamp} >= ?", @since )
34
35
 
35
36
  return nil if relation.empty?
36
37
 
data/lib/beso/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Beso
2
- VERSION = "0.2.1"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1,17 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Beso::Job do
4
+ fixtures :all
4
5
 
5
- before do
6
- User.destroy_all
7
- end
6
+ let!( :foo ){ users( :foo ) }
7
+ let!( :bar ){ users( :bar ) }
8
+ let!( :baz ){ users( :baz ) }
8
9
 
9
10
  describe 'to_csv' do
10
11
  subject { Beso::Job.new :message_sent, :table => :users }
11
12
 
12
- let!( :foo ){ User.create! :name => 'Foo' }
13
- let!( :bar ){ User.create! :name => 'Bar' }
14
-
15
13
  context 'without an identity defined' do
16
14
  before do
17
15
  subject.timestamp :created_at
@@ -42,12 +40,11 @@ describe Beso::Job do
42
40
  subject.timestamp :created_at
43
41
  end
44
42
 
45
- its( :to_csv ){ should eq( <<-EOS
46
- Identity,Timestamp,Event
47
- #{foo.id},#{foo.created_at.to_i},Message Sent
48
- #{bar.id},#{bar.created_at.to_i},Message Sent
49
- EOS
50
- ) }
43
+ it 'should generate the correct to_csv' do
44
+ verify do
45
+ subject.to_csv
46
+ end
47
+ end
51
48
  end
52
49
 
53
50
  context 'with custom properties defined' do
@@ -57,12 +54,11 @@ Identity,Timestamp,Event
57
54
  subject.prop( :user_name ){ |user| user.name }
58
55
  end
59
56
 
60
- its( :to_csv ){ should eq( <<-EOS
61
- Identity,Timestamp,Event,Prop:User Name
62
- #{foo.id},#{foo.created_at.to_i},Message Sent,Foo
63
- #{bar.id},#{bar.created_at.to_i},Message Sent,Bar
64
- EOS
65
- ) }
57
+ it 'should generate the correct to_csv' do
58
+ verify do
59
+ subject.to_csv
60
+ end
61
+ end
66
62
  end
67
63
 
68
64
  context 'with literal properties defined' do
@@ -72,12 +68,11 @@ Identity,Timestamp,Event,Prop:User Name
72
68
  subject.prop :foo, 'bar'
73
69
  end
74
70
 
75
- its( :to_csv ){ should eq( <<-EOS
76
- Identity,Timestamp,Event,Prop:Foo
77
- 22,#{foo.created_at.to_i},Message Sent,bar
78
- 22,#{bar.created_at.to_i},Message Sent,bar
79
- EOS
80
- ) }
71
+ it 'should generate the correct to_csv' do
72
+ verify do
73
+ subject.to_csv
74
+ end
75
+ end
81
76
  end
82
77
 
83
78
  context 'with symbol properties defined' do
@@ -87,12 +82,11 @@ Identity,Timestamp,Event,Prop:Foo
87
82
  subject.prop :name
88
83
  end
89
84
 
90
- its( :to_csv ){ should eq( <<-EOS
91
- Identity,Timestamp,Event,Prop:Name
92
- #{foo.id},#{foo.created_at.to_i},Message Sent,#{foo.name}
93
- #{bar.id},#{bar.created_at.to_i},Message Sent,#{bar.name}
94
- EOS
95
- ) }
85
+ it 'should generate the correct to_csv' do
86
+ verify do
87
+ subject.to_csv
88
+ end
89
+ end
96
90
  end
97
91
 
98
92
  context 'with 10 custom properties defined' do
@@ -104,12 +98,11 @@ Identity,Timestamp,Event,Prop:Name
104
98
  end
105
99
  end
106
100
 
107
- its( :to_csv ){ should eq( <<-EOS
108
- Identity,Timestamp,Event,Prop:Foo 1,Prop:Foo 2,Prop:Foo 3,Prop:Foo 4,Prop:Foo 5,Prop:Foo 6,Prop:Foo 7,Prop:Foo 8,Prop:Foo 9,Prop:Foo 10
109
- 22,#{foo.created_at.to_i},Message Sent,1,2,3,4,5,6,7,8,9,10
110
- 22,#{bar.created_at.to_i},Message Sent,1,2,3,4,5,6,7,8,9,10
111
- EOS
112
- ) }
101
+ it 'should generate the correct to_csv' do
102
+ verify do
103
+ subject.to_csv
104
+ end
105
+ end
113
106
  end
114
107
 
115
108
  context 'with more than 10 custom properties defined' do
@@ -132,13 +125,10 @@ Identity,Timestamp,Event,Prop:Foo 1,Prop:Foo 2,Prop:Foo 3,Prop:Foo 4,Prop:Foo 5,
132
125
  subject.timestamp :created_at
133
126
  end
134
127
 
135
- it 'should support all options that CSV supports' do
136
- subject.to_csv( :force_quotes => true, :col_sep => ';' ).should eq( <<-EOS
137
- "Identity";"Timestamp";"Event"
138
- "#{foo.id}";"#{foo.created_at.to_i}";"Message Sent"
139
- "#{bar.id}";"#{bar.created_at.to_i}";"Message Sent"
140
- EOS
141
- )
128
+ it 'should generate the correct to_csv' do
129
+ verify do
130
+ subject.to_csv :force_quotes => true, :col_sep => ';'
131
+ end
142
132
  end
143
133
  end
144
134
 
@@ -150,12 +140,11 @@ Identity,Timestamp,Event,Prop:Foo 1,Prop:Foo 2,Prop:Foo 3,Prop:Foo 4,Prop:Foo 5,
150
140
  subject.timestamp :created_at
151
141
  end
152
142
 
153
- its( :to_csv ){ should eq( <<-EOS
154
- Identity;Timestamp;Event
155
- #{foo.id};#{foo.created_at.to_i};Message Sent
156
- #{bar.id};#{bar.created_at.to_i};Message Sent
157
- EOS
158
- ) }
143
+ it 'should generate the correct to_csv' do
144
+ verify do
145
+ subject.to_csv
146
+ end
147
+ end
159
148
  end
160
149
 
161
150
  context 'when no records match the query' do
@@ -172,9 +161,6 @@ Identity;Timestamp;Event
172
161
  end
173
162
 
174
163
  describe 'with since specified' do
175
- let!( :foo ){ User.create :name => 'Foo', :created_at => 100, :updated_at => 300 }
176
- let!( :bar ){ User.create :name => 'Bar', :created_at => 200, :updated_at => 200 }
177
- let!( :baz ){ User.create :name => 'Baz', :created_at => 300, :updated_at => 300 }
178
164
 
179
165
  context 'in the constructor' do
180
166
  context 'and the timestamp keyed on `created_at`' do
@@ -185,12 +171,11 @@ Identity;Timestamp;Event
185
171
  subject.timestamp :created_at
186
172
  end
187
173
 
188
- its( :to_csv ){ should eq( <<-EOS
189
- Identity,Timestamp,Event
190
- #{bar.id},#{bar.created_at.to_i},Message Sent
191
- #{baz.id},#{baz.created_at.to_i},Message Sent
192
- EOS
193
- ) }
174
+ it 'should generate the correct to_csv' do
175
+ verify do
176
+ subject.to_csv
177
+ end
178
+ end
194
179
  end
195
180
  end
196
181
 
@@ -203,13 +188,10 @@ Identity,Timestamp,Event
203
188
  subject.timestamp :created_at
204
189
  end
205
190
 
206
- it 'should find records after `since`' do
207
- subject.to_csv( :since => 101 ).should eq( <<-EOS
208
- Identity,Timestamp,Event
209
- #{bar.id},#{bar.created_at.to_i},Message Sent
210
- #{baz.id},#{baz.created_at.to_i},Message Sent
211
- EOS
212
- )
191
+ it 'should generate the correct to_csv' do
192
+ verify do
193
+ subject.to_csv :since => 101
194
+ end
213
195
  end
214
196
  end
215
197
  end
@@ -223,12 +205,11 @@ Identity,Timestamp,Event
223
205
  subject.timestamp :updated_at
224
206
  end
225
207
 
226
- its( :to_csv ){ should eq( <<-EOS
227
- Identity,Timestamp,Event
228
- #{foo.id},#{foo.updated_at.to_i},Message Sent
229
- #{baz.id},#{baz.updated_at.to_i},Message Sent
230
- EOS
231
- ) }
208
+ it 'should generate the correct to_csv' do
209
+ verify do
210
+ subject.to_csv
211
+ end
212
+ end
232
213
  end
233
214
  end
234
215
 
@@ -241,21 +222,16 @@ Identity,Timestamp,Event
241
222
  subject.timestamp :updated_at
242
223
  end
243
224
 
244
- it 'should find records after `since`' do
245
- subject.to_csv( :since => 201 ).should eq( <<-EOS
246
- Identity,Timestamp,Event
247
- #{foo.id},#{foo.updated_at.to_i},Message Sent
248
- #{baz.id},#{baz.updated_at.to_i},Message Sent
249
- EOS
250
- )
225
+ it 'should generate the correct to_csv' do
226
+ verify do
227
+ subject.to_csv :since => 201
228
+ end
251
229
  end
252
230
  end
253
231
  end
254
232
  end
255
233
 
256
234
  describe 'custom event names' do
257
- let!( :foo ){ User.create :name => 'Foo' }
258
-
259
235
  subject { Beso::Job.new :message_sent, :table => :users, :event => 'Messages Sent Action' }
260
236
 
261
237
  before do
@@ -263,18 +239,14 @@ Identity,Timestamp,Event
263
239
  subject.timestamp :created_at
264
240
  end
265
241
 
266
- its( :to_csv ){ should eq( <<-EOS
267
- Identity,Timestamp,Event
268
- #{foo.id},#{foo.updated_at.to_i},Messages Sent Action
269
- EOS
270
- ) }
242
+ it 'should generate the correct to_csv' do
243
+ verify do
244
+ subject.to_csv
245
+ end
246
+ end
271
247
  end
272
248
 
273
249
  describe '#last_timestamp' do
274
- let!( :foo ){ User.create :name => 'Foo', :created_at => 100, :updated_at => 301 }
275
- let!( :bar ){ User.create :name => 'Bar', :created_at => 200, :updated_at => 200 }
276
- let!( :baz ){ User.create :name => 'Baz', :created_at => 300, :updated_at => 300 }
277
-
278
250
  subject { Beso::Job.new :message_sent, :table => :users }
279
251
 
280
252
  before do
@@ -297,4 +269,36 @@ Identity,Timestamp,Event
297
269
  its( :last_timestamp ){ should eq( 301 ) }
298
270
  end
299
271
  end
272
+
273
+ describe 'scopes' do
274
+ context 'when no explicit scope is given' do
275
+ subject { Beso::Job.new :message_sent, :table => :users }
276
+
277
+ before do
278
+ subject.identity :id
279
+ subject.timestamp :updated_at
280
+ end
281
+
282
+ it 'should generate the correct to_csv' do
283
+ verify do
284
+ subject.to_csv
285
+ end
286
+ end
287
+ end
288
+
289
+ context 'overriding the default scope' do
290
+ subject { Beso::Job.new :message_sent, :table => :users, :scope => lambda { unscoped } }
291
+
292
+ before do
293
+ subject.identity :id
294
+ subject.timestamp :updated_at
295
+ end
296
+
297
+ it 'should generate the correct to_csv' do
298
+ verify do
299
+ subject.to_csv
300
+ end
301
+ end
302
+ end
303
+ end
300
304
  end
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,9 @@ Bundler.require
9
9
 
10
10
  # Boot the rails app
11
11
  require 'config/environment'
12
+ require 'rspec/rails'
13
+ require 'approvals'
14
+ require 'approvals/rspec'
12
15
 
13
16
  # Helpers
14
17
  module ConstHelper
@@ -26,6 +29,8 @@ RSpec.configure do |config|
26
29
  config.color_enabled = true
27
30
  # Change the formatter
28
31
  config.formatter = :documentation
32
+ # Change the fixture path
33
+ config.fixture_path = File.join( File.dirname( __FILE__ ), 'fixtures' )
29
34
  # Include helpers
30
35
  config.include ConstHelper
31
36
  # Reset Beso after each test
@@ -5,9 +5,19 @@ run 'rm -r README.rdoc'
5
5
  run 'rm -r vendor'
6
6
 
7
7
  # Create some models
8
- generate 'model', 'user name:string'
8
+ generate 'model', 'user name:string deleted_at:datetime'
9
+
10
+ inject_into_class 'app/models/user.rb', 'User', <<-EOS
11
+ has_many :messages
12
+ default_scope where( 'deleted_at is null' )
13
+ EOS
14
+
9
15
  generate 'model', 'message user_id:integer'
10
16
 
17
+ inject_into_class 'app/models/message.rb', 'Message', <<-EOS
18
+ belongs_to :user
19
+ EOS
20
+
11
21
  # Set up the database
12
22
  rake 'db:migrate'
13
23
  rake 'test:prepare'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-13 00:00:00.000000000Z
12
+ date: 2012-05-14 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -28,13 +28,13 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: 3.0.10
30
30
  - !ruby/object:Gem::Dependency
31
- name: fastercsv
31
+ name: fog
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 1.5.4
37
+ version: 1.3.1
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,31 +42,31 @@ dependencies:
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: 1.5.4
45
+ version: 1.3.1
46
46
  - !ruby/object:Gem::Dependency
47
- name: fog
47
+ name: sqlite3
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
51
  - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: 1.3.1
54
- type: :runtime
53
+ version: '0'
54
+ type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
- version: 1.3.1
61
+ version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: sqlite3
63
+ name: appraisal
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
67
  - - ! '>='
68
68
  - !ruby/object:Gem::Version
69
- version: '0'
69
+ version: 0.4.1
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,15 +74,15 @@ dependencies:
74
74
  requirements:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
- version: '0'
77
+ version: 0.4.1
78
78
  - !ruby/object:Gem::Dependency
79
- name: appraisal
79
+ name: approvals
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
83
  - - ! '>='
84
84
  - !ruby/object:Gem::Version
85
- version: 0.4.1
85
+ version: 0.0.4
86
86
  type: :development
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,15 +90,15 @@ dependencies:
90
90
  requirements:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
- version: 0.4.1
93
+ version: 0.0.4
94
94
  - !ruby/object:Gem::Dependency
95
- name: rspec
95
+ name: rspec-rails
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
99
  - - ! '>='
100
100
  - !ruby/object:Gem::Version
101
- version: 2.9.0
101
+ version: 2.10.1
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
@@ -106,7 +106,7 @@ dependencies:
106
106
  requirements:
107
107
  - - ! '>='
108
108
  - !ruby/object:Gem::Version
109
- version: 2.9.0
109
+ version: 2.10.1
110
110
  description: Sync your KISSmetrics history, guapo!
111
111
  email:
112
112
  - jeremy.ruppel@gmail.com
@@ -114,16 +114,6 @@ executables: []
114
114
  extensions: []
115
115
  extra_rdoc_files: []
116
116
  files:
117
- - .gitignore
118
- - .rvmrc
119
- - Appraisals
120
- - Gemfile
121
- - LICENSE
122
- - README.md
123
- - Rakefile
124
- - beso.gemspec
125
- - gemfiles/rails-3.0.10.gemfile
126
- - gemfiles/rails-3.0.10.gemfile.lock
127
117
  - lib/beso.rb
128
118
  - lib/beso/config.rb
129
119
  - lib/beso/connection.rb
@@ -131,11 +121,9 @@ files:
131
121
  - lib/beso/job.rb
132
122
  - lib/beso/railtie.rb
133
123
  - lib/beso/version.rb
134
- - lib/tasks/beso.rake
135
124
  - spec/beso/aws_spec.rb
136
125
  - spec/beso/config_spec.rb
137
126
  - spec/beso/job_spec.rb
138
- - spec/rails/.gitkeep
139
127
  - spec/spec_helper.rb
140
128
  - spec/support/rails_template.rb
141
129
  homepage: https://github.com/remind101/beso
@@ -166,6 +154,5 @@ test_files:
166
154
  - spec/beso/aws_spec.rb
167
155
  - spec/beso/config_spec.rb
168
156
  - spec/beso/job_spec.rb
169
- - spec/rails/.gitkeep
170
157
  - spec/spec_helper.rb
171
158
  - spec/support/rails_template.rb
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- spec/rails/rails-*
data/.rvmrc DELETED
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
- # development environment upon cd'ing into the directory
5
-
6
- # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
- # Only full ruby name is supported here, for short names use:
8
- # echo "rvm use 1.9.2" > .rvmrc
9
- environment_id="ruby-1.9.2-p318@beso"
10
-
11
- # Uncomment the following lines if you want to verify rvm version per project
12
- # rvmrc_rvm_version="1.10.3" # 1.10.1 seams as a safe start
13
- # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
- # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
- # return 1
16
- # }
17
-
18
- # First we attempt to load the desired environment directly from the environment
19
- # file. This is very fast and efficient compared to running through the entire
20
- # CLI and selector. If you want feedback on which environment was used then
21
- # insert the word 'use' after --create as this triggers verbose mode.
22
- if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
- && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
- then
25
- \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
- [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
- \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
- else
29
- # If the environment file has not yet been created, use the RVM CLI to select.
30
- rvm --create "$environment_id" || {
31
- echo "Failed to create RVM environment '${environment_id}'."
32
- return 1
33
- }
34
- fi
35
-
36
- # If you use bundler, this might be useful to you:
37
- # if [[ -s Gemfile ]] && {
38
- # ! builtin command -v bundle >/dev/null ||
39
- # builtin command -v bundle | grep $rvm_path/bin/bundle >/dev/null
40
- # }
41
- # then
42
- # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
- # gem install bundler
44
- # fi
45
- # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
- # then
47
- # bundle install | grep -vE '^Using|Your bundle is complete'
48
- # fi
data/Appraisals DELETED
@@ -1,3 +0,0 @@
1
- appraise 'rails-3.0.10' do
2
- gem 'rails', '3.0.10'
3
- end
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in beso.gemspec
4
- gemspec
data/LICENSE DELETED
@@ -1,22 +0,0 @@
1
- Copyright (c) 2012 Jeremy Ruppel
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md DELETED
@@ -1,135 +0,0 @@
1
- # Beso
2
-
3
- Sync your historical events to KISSmetrics via CSV.
4
-
5
- http://support.kissmetrics.com/integrations/csv-import/recurring-import
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile:
10
-
11
- gem 'beso'
12
-
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
18
-
19
- $ gem install beso
20
-
21
- Next, create an initializer for **beso**. There, you can set up your S3 bucket information and define your
22
- serialization jobs:
23
-
24
- ``` rb
25
- # config/initializers/beso.rb
26
- Beso.configure do |config|
27
-
28
- # First, set up your S3 credentials:
29
-
30
- config.access_key = '[your AWS access key]'
31
- config.secret_key = '[your AWS secret key]'
32
- config.bucket_name = 'beso' # recommended, but you can really call this anything
33
-
34
- # Then, define some jobs:
35
-
36
- config.job :message_delivered, :table => :messages do
37
- identity { |message| message.user.id }
38
- timestamp :created_at
39
- prop( :message_id ) { |message| message.id }
40
- end
41
-
42
- config.job :signed_up, :table => :users do
43
- identity { |user| user.id }
44
- timestamp :created_at
45
- prop( :age ){ |user| user.age }
46
- end
47
- end
48
- ```
49
-
50
- ## Usage
51
-
52
- ### Defining Jobs
53
-
54
- KISSmetrics events have three properties that *must* be defined:
55
-
56
- - Identity
57
- - Timestamp
58
- - Event
59
-
60
- The **Identity** field is some sort of identifier for your user. Even if your job
61
- is working on another table, you should probably have a way to tie the event back
62
- to the user who caused it. Here, you can provide one of three things:
63
-
64
- - A proc that should receive the record and return the identity value
65
- - A symbol that will get passed to `record.send`
66
- - A literal (You'll probably want to do one of the other two options)
67
-
68
- The **Timestamp** field is slightly different in that it should always be part of
69
- the table you are querying, not the user. This symbol will get sent to each record,
70
- but will also be used in determining the query for the job.
71
-
72
- The **Event** name is inferred by the name of your job. It will be provided and
73
- formatted for you.
74
-
75
- On top of this, you can specify up to **ten** custom properties. Like `identity`,
76
- you can pass either a proc, a symbol, or a literal:
77
-
78
- ``` rb
79
- config.job :signed_up, :table => :users do
80
- identity :id
81
- timestamp :created_at
82
- prop( :age ){ |user| user.age }
83
- prop( :new_user, true )
84
- end
85
- ```
86
-
87
- ### Using the rake task
88
-
89
- By requiring `beso`, you get the `beso:run` rake task. This task will do the following:
90
-
91
- - Connect to your S3 bucket
92
- - Pull down 'beso.yml' if it exists
93
-
94
- > `beso.yml` contains the timestamp of the last record queried for each job.
95
- > If it doesn't exist, it will be created after the first run.
96
-
97
- - Iterate over the jobs defined in the initializer you set up
98
- - Create a CSV representation of all records newer than the timestamp found in `beso.yml`
99
- - Upload each CSV to your S3 bucket with the event name and timestamp
100
- - Update `beso.yml` with the latest timestamp for each job
101
-
102
- The rake task is designed to be used via cron. For the moment, KISSmetrics will only process
103
- one CSV file per hour, so it makes sense that this task should be run at an interval of hours
104
- equal to the number of jobs you have defined. For example, if you have defined 4 jobs, this
105
- task should run once every 4 hours.
106
-
107
- The rake task also accepts two options that you can set via environment variables.
108
-
109
- `BESO_PREFIX` will change the prefix of the CSV filenames that get uploaded to S3. The default
110
- is 'beso', so it is recommended you use that when telling KISSmetrics what your filename
111
- pattern is. You can then adjust the prefix if you would like to upload CSV's that you don't
112
- want KISSmetrics to recognize.
113
-
114
- `BESO_ORIGIN` will change the behavior of the task when there is no previous timestamp
115
- defined for a job in `beso.yml`.
116
-
117
- > By default, the task will use the last timestamp in your table (which effectively
118
- > means the first run of this task will do nothing). This is because KISSmetrics
119
- > charges you for every event you log through their system, so you probably don't
120
- > want to upload 8 months worth of events straight away.
121
-
122
- This option will accept two values to alter the behavior:
123
-
124
- - `now` will set the first run timestamp to now, which will obviously not create any events.
125
- - `first` will set the first run timestamp to the first timestamp in each table. Use this with
126
- `BESO_PREFIX` if you want to dump an entire table's worth of events to S3 without having
127
- KISSmetrics process them.
128
-
129
- ## Contributing
130
-
131
- 1. Fork it
132
- 2. Create your feature branch (`git checkout -b my-new-feature`)
133
- 3. Commit your changes (`git commit -am 'Added some feature'`)
134
- 4. Push to the branch (`git push origin my-new-feature`)
135
- 5. Create new Pull Request
data/Rakefile DELETED
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
- require 'appraisal'
4
- require 'rspec/core/rake_task'
5
-
6
- namespace :beso do
7
-
8
- desc "Set up current environment variables"
9
- task :env do
10
- require 'rails/version'
11
- ENV[ 'BESO_RAILS_NAME' ] = "rails-#{Rails::VERSION::STRING}"
12
- ENV[ 'BESO_RAILS_PATH' ] = "spec/rails/#{ENV[ 'BESO_RAILS_NAME' ]}"
13
- end
14
-
15
- desc "Remove all test rails apps"
16
- task :clean => [ :env ] do
17
- Dir[ 'spec/rails/rails-*' ].each do |app|
18
- FileUtils.rm_rf app
19
- end
20
- end
21
-
22
- desc "Create a test rails app if necessary"
23
- task :rails do
24
- if File.exist? ENV[ 'BESO_RAILS_PATH' ]
25
- puts "Using existing #{ENV[ 'BESO_RAILS_NAME' ]} app"
26
- else
27
- sh "bundle exec rails new #{ENV[ 'BESO_RAILS_PATH' ]} -m spec/support/rails_template.rb"
28
- end
29
- end
30
- end
31
-
32
- RSpec::Core::RakeTask.new :spec => [ :'beso:env', :'beso:rails' ]
33
-
34
- desc "Run specs for all supported rails versions"
35
- task :all do
36
- exec 'rake appraisal spec'
37
- end
38
-
39
- desc "Default: Clean, install dependencies, and run specs"
40
- task :default => [ :'beso:clean', :'appraisal:install', :all ]
data/beso.gemspec DELETED
@@ -1,25 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/beso/version', __FILE__)
3
-
4
- Gem::Specification.new do |gem|
5
- gem.authors = ["Jeremy Ruppel"]
6
- gem.email = ["jeremy.ruppel@gmail.com"]
7
- gem.description = %q{Sync your KISSmetrics history, guapo!}
8
- gem.summary = %q{Sync your KISSmetrics history, guapo!}
9
- gem.homepage = "https://github.com/remind101/beso"
10
-
11
- gem.files = `git ls-files`.split($\)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
- gem.name = "beso"
15
- gem.require_paths = ["lib"]
16
- gem.version = Beso::VERSION
17
-
18
- gem.add_dependency 'rails', '>= 3.0.10'
19
- gem.add_dependency 'fastercsv', '>= 1.5.4'
20
- gem.add_dependency 'fog', '>= 1.3.1'
21
-
22
- gem.add_development_dependency 'sqlite3'
23
- gem.add_development_dependency 'appraisal', '>= 0.4.1'
24
- gem.add_development_dependency 'rspec', '>= 2.9.0'
25
- end
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "rails", "3.0.10"
6
-
7
- gemspec :path=>"../"
@@ -1,120 +0,0 @@
1
- PATH
2
- remote: /Users/jeremyruppel/Git/beso
3
- specs:
4
- beso (0.2.0)
5
- fastercsv (>= 1.5.4)
6
- fog (>= 1.3.1)
7
- rails (>= 3.0.10)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- abstract (1.0.0)
13
- actionmailer (3.0.10)
14
- actionpack (= 3.0.10)
15
- mail (~> 2.2.19)
16
- actionpack (3.0.10)
17
- activemodel (= 3.0.10)
18
- activesupport (= 3.0.10)
19
- builder (~> 2.1.2)
20
- erubis (~> 2.6.6)
21
- i18n (~> 0.5.0)
22
- rack (~> 1.2.1)
23
- rack-mount (~> 0.6.14)
24
- rack-test (~> 0.5.7)
25
- tzinfo (~> 0.3.23)
26
- activemodel (3.0.10)
27
- activesupport (= 3.0.10)
28
- builder (~> 2.1.2)
29
- i18n (~> 0.5.0)
30
- activerecord (3.0.10)
31
- activemodel (= 3.0.10)
32
- activesupport (= 3.0.10)
33
- arel (~> 2.0.10)
34
- tzinfo (~> 0.3.23)
35
- activeresource (3.0.10)
36
- activemodel (= 3.0.10)
37
- activesupport (= 3.0.10)
38
- activesupport (3.0.10)
39
- appraisal (0.4.1)
40
- bundler
41
- rake
42
- arel (2.0.10)
43
- builder (2.1.2)
44
- diff-lcs (1.1.3)
45
- erubis (2.6.6)
46
- abstract (>= 1.0.0)
47
- excon (0.13.3)
48
- fastercsv (1.5.4)
49
- fog (1.3.1)
50
- builder
51
- excon (~> 0.13.0)
52
- formatador (~> 0.2.0)
53
- mime-types
54
- multi_json (~> 1.0)
55
- net-scp (~> 1.0.4)
56
- net-ssh (>= 2.1.3)
57
- nokogiri (~> 1.5.0)
58
- ruby-hmac
59
- formatador (0.2.1)
60
- i18n (0.5.0)
61
- json (1.6.6)
62
- mail (2.2.19)
63
- activesupport (>= 2.3.6)
64
- i18n (>= 0.4.0)
65
- mime-types (~> 1.16)
66
- treetop (~> 1.4.8)
67
- mime-types (1.18)
68
- multi_json (1.2.0)
69
- net-scp (1.0.4)
70
- net-ssh (>= 1.99.1)
71
- net-ssh (2.3.0)
72
- nokogiri (1.5.2)
73
- polyglot (0.3.3)
74
- rack (1.2.5)
75
- rack-mount (0.6.14)
76
- rack (>= 1.0.0)
77
- rack-test (0.5.7)
78
- rack (>= 1.0)
79
- rails (3.0.10)
80
- actionmailer (= 3.0.10)
81
- actionpack (= 3.0.10)
82
- activerecord (= 3.0.10)
83
- activeresource (= 3.0.10)
84
- activesupport (= 3.0.10)
85
- bundler (~> 1.0)
86
- railties (= 3.0.10)
87
- railties (3.0.10)
88
- actionpack (= 3.0.10)
89
- activesupport (= 3.0.10)
90
- rake (>= 0.8.7)
91
- rdoc (~> 3.4)
92
- thor (~> 0.14.4)
93
- rake (0.9.2.2)
94
- rdoc (3.12)
95
- json (~> 1.4)
96
- rspec (2.9.0)
97
- rspec-core (~> 2.9.0)
98
- rspec-expectations (~> 2.9.0)
99
- rspec-mocks (~> 2.9.0)
100
- rspec-core (2.9.0)
101
- rspec-expectations (2.9.1)
102
- diff-lcs (~> 1.1.3)
103
- rspec-mocks (2.9.0)
104
- ruby-hmac (0.4.0)
105
- sqlite3 (1.3.5)
106
- thor (0.14.6)
107
- treetop (1.4.10)
108
- polyglot
109
- polyglot (>= 0.3.1)
110
- tzinfo (0.3.33)
111
-
112
- PLATFORMS
113
- ruby
114
-
115
- DEPENDENCIES
116
- appraisal (>= 0.4.1)
117
- beso!
118
- rails (= 3.0.10)
119
- rspec (>= 2.9.0)
120
- sqlite3
data/lib/tasks/beso.rake DELETED
@@ -1,57 +0,0 @@
1
- namespace :beso do
2
-
3
- desc "Run Beso jobs and upload to S3"
4
- task :run => :environment do
5
-
6
- raise 'Beso has no jobs to run. Please define some in the beso initializer.' if Beso.jobs.empty?
7
-
8
- puts '==> Connecting...'
9
-
10
- Beso.connect do |bucket|
11
-
12
- puts '==> Connected!'
13
-
14
- prefix = ENV[ 'BESO_PREFIX' ] || 'beso'
15
- config = YAML.load( bucket.read 'beso.yml' ) || { }
16
-
17
- puts '==> Config:'
18
- puts config.inspect
19
-
20
- Beso.jobs.each do |job|
21
-
22
- config[ job.event ] ||= begin
23
- case ENV[ 'BESO_ORIGIN' ]
24
- when 'first'
25
- job.first_timestamp
26
- when 'now'
27
- Time.now
28
- else
29
- job.last_timestamp
30
- end
31
- end
32
-
33
- puts "==> Processing job: #{job.event.inspect} since #{config[ job.event ]}"
34
-
35
- csv = job.to_csv :since => config[ job.event ]
36
-
37
- if csv
38
- filename = "#{prefix}-#{job.event}-#{config[ job.event ].to_i}.csv"
39
-
40
- bucket.write filename, csv
41
-
42
- puts " ==> #{filename} saved to S3"
43
-
44
- config[ job.event ] = job.last_timestamp
45
-
46
- puts " ==> New timestamp is #{config[ job.event ]}"
47
- else
48
- puts " ==> No records found since #{config[ job.event ]}. Skipping..."
49
- end
50
- end
51
-
52
- bucket.write 'beso.yml', config.to_yaml
53
-
54
- puts '==> Config saved. Donezo.'
55
- end
56
- end
57
- end
data/spec/rails/.gitkeep DELETED
File without changes