reparty 0.2.1 → 0.3.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/History.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.3.1
2
+
3
+ - Total graphs were off by one day
4
+
5
+ ## 0.3.0
6
+
7
+ - Add Sendgrid report
8
+ - A few more possibly timezone fixes
9
+ - Add HTTParty as a dependency. (Great library name, by the way!)
10
+
1
11
  ## 0.2.1
2
12
 
3
13
  - Timezone fix (ActiveRecord always saves in UTC)
@@ -0,0 +1,10 @@
1
+ <table width="545" cellpadding="0" cellspacing="25" border="0">
2
+ <tr>
3
+ <td align="left">
4
+ <h3><%= report.title %></h3>
5
+ </td>
6
+ </tr>
7
+ <tr>
8
+ <td align="center"><%= image_tag attachments["#{report.hash}.png"].url, border: 0, align: "center" %></td>
9
+ </tr>
10
+ </table>
@@ -36,7 +36,7 @@ module Reparty
36
36
 
37
37
  def daily_dataset
38
38
  if @operation == :total
39
- 7.downto(1).map { |x| @model.where("#{@field.to_s} < ?", DateTime.now.utc.at_midnight-x).send(:count, @field) }
39
+ 6.downto(0).map { |x| @model.where("#{@field.to_s} < ?", DateTime.now.utc.at_midnight-x).send(:count, @field) }
40
40
  else
41
41
  7.downto(1).map { |x| @model.where("DATE(#{@field.to_s}) = ?", DateTime.now.utc.to_date-x).send(@operation, @field) }
42
42
  end
@@ -44,7 +44,7 @@ module Reparty
44
44
 
45
45
  def yesterday
46
46
  op = @operation == :total ? :count : @operation
47
- @model.where("DATE(#{@field.to_s}) = ?", DateTime.now-1).send(op, @field)
47
+ @model.where("DATE(#{@field.to_s}) = ?", DateTime.now.utc.to_date-1).send(op, @field)
48
48
  end
49
49
 
50
50
  def total
@@ -0,0 +1,46 @@
1
+ require 'httparty'
2
+
3
+ module Reparty
4
+ class Report
5
+ class Sendgrid < Report
6
+ include HTTParty
7
+ format :json
8
+ headers 'Content-Type' => 'application/json', 'Accept' => 'application/json'
9
+
10
+ attr_reader :api_user, :api_key
11
+
12
+ def initialize(*args, &block)
13
+ super(args.shift)
14
+
15
+ @api_user = args.shift
16
+ @api_key = args.shift
17
+
18
+ @color = "#287abe"
19
+ end
20
+
21
+ def attach(attachments)
22
+ @graph = build_daily_graph
23
+
24
+ %W{requests delivered bounces spamreports}.each do |stat|
25
+ @graph.data(stat.capitalize, stats.map{|s| s.fetch(stat,0)})
26
+ end
27
+
28
+ attachments.inline["#{self.hash}.png"] = @graph.to_blob
29
+ end
30
+
31
+ def stats(today=DateTime.now)
32
+ @stats ||= self.class.get(
33
+ "https://sendgrid.com/api/stats.get.json?" +
34
+ "api_user=" + @api_user +
35
+ "&api_key=" + @api_key +
36
+ "&start_date=" + (today.utc.to_date - 1).strftime("%Y-%m-%d") +
37
+ "&days=7",
38
+ options: { format: 'json' }
39
+ )
40
+
41
+ @stats.pop if @stats.size == 8
42
+ @stats
43
+ end
44
+ end
45
+ end
46
+ end
@@ -16,10 +16,10 @@ module Reparty
16
16
 
17
17
  protected
18
18
 
19
- def build_daily_graph
19
+ def build_daily_graph(start_date=DateTime.now.utc)
20
20
  g = Gruff::Line.new(545)
21
21
  g.title = @title
22
- g.labels = Hash[*(1..7).map{|x| [x-1, (DateTime.now - (8-x)).strftime("%-m/%-d")] }.flatten]
22
+ g.labels = Hash[*(1..7).map{|x| [x-1, (start_date - (8-x)).strftime("%-m/%-d")] }.flatten]
23
23
  g
24
24
  end
25
25
  end
@@ -1,3 +1,3 @@
1
1
  module Reparty
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/reparty.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  require "reparty/version"
2
2
 
3
3
  require "reparty/config"
4
+ require "reparty/email"
5
+
4
6
  require "reparty/report"
5
7
  require "reparty/report/active_record"
6
- require "reparty/email"
8
+ require "reparty/report/sendgrid"
7
9
 
8
10
  require "reparty/engine"
9
11
 
data/reparty.gemspec CHANGED
@@ -24,10 +24,13 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "rmagick"
25
25
  spec.add_dependency "gruff"
26
26
  spec.add_dependency "roadie"
27
+ spec.add_dependency "httparty"
27
28
 
28
29
  spec.add_development_dependency "bundler", "~> 1.3"
29
30
  spec.add_development_dependency "rake"
30
31
  spec.add_development_dependency "rspec"
31
- spec.add_development_dependency "sqlite3"
32
32
  spec.add_development_dependency "letter_opener"
33
+ spec.add_development_dependency "webmock"
34
+ spec.add_development_dependency "vcr"
35
+ spec.add_development_dependency "sqlite3"
33
36
  end
@@ -0,0 +1,65 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sendgrid.com/api/stats.get.json?api_key=<SENDGRID_PASSWORD>&api_user=<SENDGRID_USER>&days=7&start_date=2013-04-30
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Server:
20
+ - nginx/1.3.14
21
+ Date:
22
+ - Wed, 01 May 2013 07:04:44 GMT
23
+ Content-Type:
24
+ - text/html
25
+ Transfer-Encoding:
26
+ - chunked
27
+ Connection:
28
+ - keep-alive
29
+ body:
30
+ encoding: US-ASCII
31
+ string: ! '[{"delivered": 2363, "unsubscribes": 0, "invalid_email": 2, "bounces":
32
+ 18, "repeat_unsubscribes": 0, "unique_clicks": 0, "blocked": 2, "spam_drop":
33
+ 0, "repeat_bounces": 37, "repeat_spamreports": 0, "date": "2013-04-24", "requests":
34
+ 2419, "spamreports": 0, "clicks": 0, "opens": 0, "unique_opens": 0},{"delivered":
35
+ 3059, "unsubscribes": 0, "invalid_email": 2, "bounces": 31, "repeat_unsubscribes":
36
+ 0, "unique_clicks": 0, "blocked": 2, "spam_drop": 0, "repeat_bounces": 45,
37
+ "repeat_spamreports": 0, "date": "2013-04-25", "requests": 3133, "spamreports":
38
+ 0, "clicks": 0, "opens": 1, "unique_opens": 0},{"delivered": 3856, "unsubscribes":
39
+ 0, "invalid_email": 3, "bounces": 29, "repeat_unsubscribes": 0, "unique_clicks":
40
+ 0, "blocked": 2, "spam_drop": 0, "repeat_bounces": 78, "repeat_spamreports":
41
+ 0, "date": "2013-04-26", "requests": 3961, "spamreports": 0, "clicks": 0,
42
+ "opens": 0, "unique_opens": 0},{"delivered": 3784, "unsubscribes": 0, "invalid_email":
43
+ 3, "bounces": 5, "repeat_unsubscribes": 0, "unique_clicks": 0, "blocked":
44
+ 3, "spam_drop": 0, "repeat_bounces": 104, "repeat_spamreports": 0, "date":
45
+ "2013-04-27", "requests": 3899, "spamreports": 3, "clicks": 0, "opens": 0,
46
+ "unique_opens": 0},{"delivered": 2945, "unsubscribes": 0, "invalid_email":
47
+ 3, "bounces": 5, "repeat_unsubscribes": 0, "unique_clicks": 0, "blocked":
48
+ 6, "spam_drop": 0, "repeat_bounces": 78, "repeat_spamreports": 1, "date":
49
+ "2013-04-28", "requests": 3035, "spamreports": 0, "clicks": 0, "opens": 0,
50
+ "unique_opens": 0},{"delivered": 3218, "unsubscribes": 0, "invalid_email":
51
+ 3, "bounces": 2, "repeat_unsubscribes": 0, "unique_clicks": 0, "blocked":
52
+ 6, "spam_drop": 0, "repeat_bounces": 90, "repeat_spamreports": 0, "date":
53
+ "2013-04-29", "requests": 3317, "spamreports": 0, "clicks": 0, "opens": 0,
54
+ "unique_opens": 0},{"delivered": 4056, "unsubscribes": 0, "invalid_email":
55
+ 3, "bounces": 2, "repeat_unsubscribes": 0, "unique_clicks": 0, "blocked":
56
+ 5, "spam_drop": 0, "repeat_bounces": 115, "repeat_spamreports": 1, "date":
57
+ "2013-04-30", "requests": 4183, "spamreports": 0, "clicks": 0, "opens": 0,
58
+ "unique_opens": 0},{"delivered": 2, "unsubscribes": 0, "invalid_email": 0,
59
+ "bounces": 0, "repeat_unsubscribes": 0, "unique_clicks": 0, "blocked": 0,
60
+ "spam_drop": 0, "repeat_bounces": 0, "repeat_spamreports": 0, "date": "2013-05-01",
61
+ "requests": 2, "spamreports": 0, "clicks": 0, "opens": 0, "unique_opens":
62
+ 0}]'
63
+ http_version:
64
+ recorded_at: Wed, 01 May 2013 07:04:44 GMT
65
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,25 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Reparty::Report::Sendgrid, vcr: { cassette_name: "sendgrid" } do
4
+ let(:sendgrid_user) { ENV.fetch("SENDGRID_USER","admin@someplace.com") }
5
+ let(:sendgrid_pass) { ENV.fetch("SENDGRID_PASSWORD","asdfasdf") }
6
+
7
+ subject do
8
+ Reparty.config do |config|
9
+ config.add_report Reparty::Report::Sendgrid, "Sendgrid Emails", sendgrid_user, sendgrid_pass
10
+ end
11
+ Reparty.reports.last
12
+ end
13
+
14
+ it { should be_kind_of(Reparty::Report::Sendgrid) }
15
+ its(:api_user) { should == sendgrid_user }
16
+ its(:api_key) { should == sendgrid_pass }
17
+ its(:color) { should == "#287abe" }
18
+
19
+ it "gets stats" do
20
+ stats = subject.stats(DateTime.new(2013,5,1))
21
+ stats.size.should == 7
22
+ stats.first.should be_kind_of(Hash)
23
+ stats.first["delivered"].should == 2363
24
+ end
25
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'reparty'
3
+ require 'vcr_helper'
3
4
 
4
5
  Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
5
6
 
@@ -41,6 +41,11 @@ describe "reparty:email" do
41
41
  {:name => "Someone", :score => 1, :created_at => DateTime.now - 8},
42
42
  ].each{|u| User.create!(u) }
43
43
 
44
+ Reparty.config do |config|
45
+ config.add_report Reparty::Report::ActiveRecord, "New User Signups", :user
46
+ config.add_report Reparty::Report::Sendgrid, "Sendgrid Emails", ENV["SENDGRID_USER"], ENV["SENDGRID_PASSWORD"]
47
+ end
48
+
44
49
  subject.invoke("test@test.com")
45
50
  end
46
51
  end
@@ -0,0 +1,13 @@
1
+ require "webmock/rspec"
2
+ require "vcr"
3
+
4
+ VCR.configure do |c|
5
+ c.cassette_library_dir = "spec/cassettes"
6
+ c.default_cassette_options = { :record => :new_episodes }
7
+ c.hook_into :webmock
8
+ c.configure_rspec_metadata!
9
+ c.allow_http_connections_when_no_cassette = true
10
+
11
+ c.filter_sensitive_data("<SENDGRID_USER>") { ENV.fetch("SENDGRID_USER","admin@someplace.com") }
12
+ c.filter_sensitive_data("<SENDGRID_PASSWORD>") { ENV.fetch("SENDGRID_PASSWORD","asdfasdf") }
13
+ end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: reparty
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.1
5
+ version: 0.3.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tim Dorr
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-01 00:00:00.000000000 Z
12
+ date: 2013-05-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -107,6 +107,22 @@ dependencies:
107
107
  version: '0'
108
108
  none: false
109
109
  prerelease: false
110
+ - !ruby/object:Gem::Dependency
111
+ name: httparty
112
+ type: :runtime
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ none: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ none: false
125
+ prerelease: false
110
126
  - !ruby/object:Gem::Dependency
111
127
  name: bundler
112
128
  type: :development
@@ -156,7 +172,7 @@ dependencies:
156
172
  none: false
157
173
  prerelease: false
158
174
  - !ruby/object:Gem::Dependency
159
- name: sqlite3
175
+ name: letter_opener
160
176
  type: :development
161
177
  requirement: !ruby/object:Gem::Requirement
162
178
  requirements:
@@ -172,7 +188,39 @@ dependencies:
172
188
  none: false
173
189
  prerelease: false
174
190
  - !ruby/object:Gem::Dependency
175
- name: letter_opener
191
+ name: webmock
192
+ type: :development
193
+ requirement: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ none: false
199
+ version_requirements: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ none: false
205
+ prerelease: false
206
+ - !ruby/object:Gem::Dependency
207
+ name: vcr
208
+ type: :development
209
+ requirement: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ! '>='
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ none: false
215
+ version_requirements: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ! '>='
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ none: false
221
+ prerelease: false
222
+ - !ruby/object:Gem::Dependency
223
+ name: sqlite3
176
224
  type: :development
177
225
  requirement: !ruby/object:Gem::Requirement
178
226
  requirements:
@@ -206,6 +254,7 @@ files:
206
254
  - app/assets/images/spacer.gif
207
255
  - app/mailers/report_mailer.rb
208
256
  - app/views/report_mailer/_active_record.html.erb
257
+ - app/views/report_mailer/_sendgrid.html.erb
209
258
  - app/views/report_mailer/daily.html.erb
210
259
  - lib/reparty.rb
211
260
  - lib/reparty/config.rb
@@ -213,16 +262,20 @@ files:
213
262
  - lib/reparty/engine.rb
214
263
  - lib/reparty/report.rb
215
264
  - lib/reparty/report/active_record.rb
265
+ - lib/reparty/report/sendgrid.rb
216
266
  - lib/reparty/version.rb
217
267
  - lib/tasks/reparty.rake
218
268
  - reparty.gemspec
269
+ - spec/cassettes/sendgrid.yml
219
270
  - spec/email_spec.rb
220
271
  - spec/reparty_spec.rb
221
272
  - spec/report/active_record_spec.rb
273
+ - spec/report/sendgrid_spec.rb
222
274
  - spec/report_spec.rb
223
275
  - spec/spec_helper.rb
224
276
  - spec/support/shared_contexts/rake.rb
225
277
  - spec/tasks/reparty_task_spec.rb
278
+ - spec/vcr_helper.rb
226
279
  homepage: https://github.com/timdorr/reparty
227
280
  licenses:
228
281
  - MIT
@@ -236,7 +289,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
236
289
  - !ruby/object:Gem::Version
237
290
  segments:
238
291
  - 0
239
- hash: 1402825386359699857
292
+ hash: 1855217469676328277
240
293
  version: '0'
241
294
  none: false
242
295
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -245,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
298
  - !ruby/object:Gem::Version
246
299
  segments:
247
300
  - 0
248
- hash: 1402825386359699857
301
+ hash: 1855217469676328277
249
302
  version: '0'
250
303
  none: false
251
304
  requirements: []
@@ -255,10 +308,13 @@ signing_key:
255
308
  specification_version: 3
256
309
  summary: Stupid easy business analytics
257
310
  test_files:
311
+ - spec/cassettes/sendgrid.yml
258
312
  - spec/email_spec.rb
259
313
  - spec/reparty_spec.rb
260
314
  - spec/report/active_record_spec.rb
315
+ - spec/report/sendgrid_spec.rb
261
316
  - spec/report_spec.rb
262
317
  - spec/spec_helper.rb
263
318
  - spec/support/shared_contexts/rake.rb
264
319
  - spec/tasks/reparty_task_spec.rb
320
+ - spec/vcr_helper.rb