beso 0.2.1 → 0.3.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/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