mailcannon 0.0.8.pre.1 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailcannon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8.pre.1
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Martins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-05 00:00:00.000000000 Z
11
+ date: 2014-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: librato-metrics
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: airbrake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: vcr
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -278,20 +306,16 @@ files:
278
306
  - lib/mailcannon.rb
279
307
  - lib/mailcannon/adapter.rb
280
308
  - lib/mailcannon/adapters/sendgrid_web.rb
309
+ - lib/mailcannon/airbrake.rb
281
310
  - lib/mailcannon/envelope.rb
282
311
  - lib/mailcannon/envelope_bag.rb
283
- - lib/mailcannon/envelope_bag_map_reduce.rb
284
- - lib/mailcannon/envelope_bag_statistic.rb
285
312
  - lib/mailcannon/event.rb
286
313
  - lib/mailcannon/hash.rb
314
+ - lib/mailcannon/librato.rb
287
315
  - lib/mailcannon/mail.rb
288
- - lib/mailcannon/reduces/envelope_bag_map.js
289
- - lib/mailcannon/reduces/envelope_bag_reduce.js
290
- - lib/mailcannon/sendgrid_event.rb
291
316
  - lib/mailcannon/stamp.rb
292
317
  - lib/mailcannon/version.rb
293
318
  - lib/mailcannon/workers/barrel.rb
294
- - lib/mailcannon/workers/envelope_bag_reduce_job.rb
295
319
  - mailcannon.gemspec
296
320
  - spec/factories/envelope.rb
297
321
  - spec/factories/envelope_bag.rb
@@ -300,16 +324,14 @@ files:
300
324
  - spec/fixtures/cassettes/mailcannon_adapter_sendgrid_send_bulk.yml
301
325
  - spec/fixtures/cassettes/mailcannon_integration_1k.yml
302
326
  - spec/integration/1k_spec.rb
303
- - spec/integration/full_stack_stats_spec.rb
304
327
  - spec/integration/xsmtpapi_spec.rb
305
328
  - spec/mailcannon/adapters/sendgrid_spec.rb
306
- - spec/mailcannon/envelope_bag_map_reduce_spec.rb
329
+ - spec/mailcannon/airbrake_spec.rb
307
330
  - spec/mailcannon/envelope_bag_spec.rb
308
- - spec/mailcannon/envelope_bag_statistic_spec.rb
309
331
  - spec/mailcannon/envelope_spec.rb
332
+ - spec/mailcannon/librato_spec.rb
310
333
  - spec/mailcannon/stamp_spec.rb
311
334
  - spec/mailcannon/workers/barrel_spec.rb
312
- - spec/mailcannon/workers/envelope_bag_reduce_job_spec.rb
313
335
  - spec/mailcannon_spec.rb
314
336
  - spec/spec_helper.rb
315
337
  - spec/support/mongoid.yml
@@ -330,9 +352,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
330
352
  version: 1.9.3
331
353
  required_rubygems_version: !ruby/object:Gem::Requirement
332
354
  requirements:
333
- - - '>'
355
+ - - '>='
334
356
  - !ruby/object:Gem::Version
335
- version: 1.3.1
357
+ version: '0'
336
358
  requirements: []
337
359
  rubyforge_project:
338
360
  rubygems_version: 2.0.14
@@ -347,16 +369,14 @@ test_files:
347
369
  - spec/fixtures/cassettes/mailcannon_adapter_sendgrid_send_bulk.yml
348
370
  - spec/fixtures/cassettes/mailcannon_integration_1k.yml
349
371
  - spec/integration/1k_spec.rb
350
- - spec/integration/full_stack_stats_spec.rb
351
372
  - spec/integration/xsmtpapi_spec.rb
352
373
  - spec/mailcannon/adapters/sendgrid_spec.rb
353
- - spec/mailcannon/envelope_bag_map_reduce_spec.rb
374
+ - spec/mailcannon/airbrake_spec.rb
354
375
  - spec/mailcannon/envelope_bag_spec.rb
355
- - spec/mailcannon/envelope_bag_statistic_spec.rb
356
376
  - spec/mailcannon/envelope_spec.rb
377
+ - spec/mailcannon/librato_spec.rb
357
378
  - spec/mailcannon/stamp_spec.rb
358
379
  - spec/mailcannon/workers/barrel_spec.rb
359
- - spec/mailcannon/workers/envelope_bag_reduce_job_spec.rb
360
380
  - spec/mailcannon_spec.rb
361
381
  - spec/spec_helper.rb
362
382
  - spec/support/mongoid.yml
@@ -1,106 +0,0 @@
1
- module MailCannon::EnvelopeBagMapReduce
2
- module ClassMethods
3
-
4
- def find_gem_root_path
5
- path = ""
6
- begin
7
- spec = Gem::Specification.find_by_name("mailcannon")
8
- path = spec.gem_dir
9
- rescue LoadError => e
10
- raise unless e.message =~ /mailcannon/
11
- puts 'mailcannon gem path not found'
12
- end
13
- path
14
- end
15
-
16
- def reduce_statistics_for_envelope_bag(id)
17
- events = change_events_status_for_envelope_bag(id, nil, :lock)
18
- result = events.map_reduce(self.js_map, self.js_reduce).out(merge: "mail_cannon_envelope_bag_statistics")
19
- set_events_to(events,:processed)
20
- {raw: result.raw, count: events.count}
21
- end
22
-
23
- def statistics_for_envelope(id)
24
- self.stats
25
- end
26
-
27
- def js_map
28
- root_path = find_gem_root_path
29
- root_path += "/" unless root_path.empty?
30
- @js_map ||= File.read("#{root_path}lib/mailcannon/reduces/envelope_bag_map.js")
31
- #TODO cache this
32
- @js_map
33
- end
34
-
35
- def js_reduce
36
- root_path = find_gem_root_path
37
- root_path += "/" unless root_path.empty?
38
- @js_reduce ||= File.read("#{root_path}lib/mailcannon/reduces/envelope_bag_reduce.js")
39
- #TODO cache this
40
- @js_reduce
41
- end
42
-
43
- # [from|to]sym = :new, :lock, :processed
44
- def change_events_status_for_envelope_bag(id, from_sym, to_sym)
45
- from_status = processed_status_for(from_sym)
46
- to_status = processed_status_for(to_sym)
47
- if from_sym
48
- query = MailCannon::SendgridEvent.where(envelope_bag_id: id, processed: from_status)
49
- else
50
- query = MailCannon::SendgridEvent.where(envelope_bag_id: id)
51
- end
52
- if query.kind_of?(Mongoid::Criteria)
53
- query.update_all(processed: to_status)
54
- else
55
- query.processed=to_status
56
- query.save
57
- end
58
- query
59
- end
60
-
61
- #private
62
- def set_events_to(events,status)
63
- status = processed_status_for(status)
64
- if events.kind_of?(Mongoid::Criteria)
65
- events.update_all(processed: status)
66
- else
67
- events.processed=status
68
- events.save
69
- end
70
- end
71
-
72
- def processed_status_for(input)
73
- status_map = {
74
- lock: false,
75
- processed: true,
76
- new: nil
77
- }
78
- if [false,true,nil].include?(input)
79
- status_map = status_map.invert
80
- raise "Unexpected input(#{input})" unless status_map.has_key?(input)
81
- end
82
- status_map[input]
83
- end
84
-
85
- end
86
-
87
- module InstanceMethods
88
- def reduce_statistics
89
- self.class.reduce_statistics_for_envelope_bag(self.id)
90
- end
91
-
92
- def statistics
93
- self.class.statistics_for_envelope(self.id)
94
- end
95
-
96
- def change_events_status(from_sym, to_sym)
97
- self.set_processed_status_for_envelope(self.id, from_sym, to_sym)
98
- end
99
- end
100
-
101
- def self.included(receiver)
102
- receiver.extend ClassMethods
103
- receiver.send :include, InstanceMethods
104
- end
105
- end
106
-
@@ -1,5 +0,0 @@
1
- # Holds information about a recipient's email event, like deliveries and bounces.
2
- class MailCannon::EnvelopeBagStatistic
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
- end
@@ -1,3 +0,0 @@
1
- function () {
2
- emit(this.envelope_bag_id, { target_id: this.target_id, event: this.event, type: this.type });
3
- }
@@ -1,116 +0,0 @@
1
- function (key, values) {
2
- var result = {
3
- 'posted': {
4
- 'count': 0,
5
- 'targets': []
6
- },
7
- 'processed': {
8
- 'count': 0,
9
- 'targets': []
10
- },
11
- 'delivered': {
12
- 'count': 0,
13
- 'targets': []
14
- },
15
- 'open': {
16
- 'count': 0,
17
- 'targets': []
18
- },
19
- 'click': {
20
- 'count': 0,
21
- 'targets': []
22
- },
23
- 'deferred': {
24
- 'count': 0,
25
- 'targets': []
26
- },
27
- 'spam_report': {
28
- 'count': 0,
29
- 'targets': []
30
- },
31
- 'spam': {
32
- 'count': 0,
33
- 'targets': []
34
- },
35
- 'unsubscribe': {
36
- 'count': 0,
37
- 'targets': []
38
- },
39
- 'drop': {
40
- 'count': 0,
41
- 'targets': []
42
- },
43
- 'hard_bounce': {
44
- 'count': 0,
45
- 'targets': []
46
- },
47
- 'soft_bounce': {
48
- 'count': 0,
49
- 'targets': []
50
- },
51
- 'unknown': {
52
- 'count': 0,
53
- 'targets': []
54
- }
55
- };
56
-
57
- values.forEach(function(value) {
58
- switch (value['event']) {
59
- case 'posted':
60
- result['posted']['count']++;
61
- result['posted']['targets'].push(value['target_id']);
62
- break;
63
- case 'processed':
64
- result['processed']['count']++;
65
- result['processed']['targets'].push(value['target_id']);
66
- break;
67
- case 'delivered':
68
- result['delivered']['count']++;
69
- result['delivered']['targets'].push(value['target_id']);
70
- break;
71
- case 'open':
72
- result['open']['count']++;
73
- result['open']['targets'].push(value['target_id']);
74
- break;
75
- case 'click':
76
- result['click']['count']++;
77
- result['click']['targets'].push(value['target_id']);
78
- break;
79
- case 'deferred':
80
- result['deferred']['count']++;
81
- result['deferred']['targets'].push(value['target_id']);
82
- break;
83
- case 'spam_report':
84
- result['spam_report']['count']++;
85
- result['spam_report']['targets'].push(value['target_id']);
86
- break;
87
- case 'spam':
88
- result['spam']['count']++;
89
- result['spam']['targets'].push(value['target_id']);
90
- break;
91
- case 'unsubscribe':
92
- result['unsubscribe']['count']++;
93
- result['unsubscribe']['targets'].push(value['target_id']);
94
- break;
95
- case 'drop':
96
- result['drop']['count']++;
97
- result['drop']['targets'].push(value['target_id']);
98
- break;
99
- case 'bounce':
100
- if(value['type'] == "bounce"){
101
- result['hard_bounce']['count']++;
102
- result['hard_bounce']['targets'].push(value['target_id']);
103
- }
104
- else {
105
- result['soft_bounce']['count']++;
106
- result['soft_bounce']['targets'].push(value['target_id']);
107
- }
108
- break;
109
- default:
110
- result['unknown']['count']++;
111
- result['unknown']['targets'].push(value['target_id']);
112
- break;
113
- }
114
- });
115
- return result;
116
- }
@@ -1,18 +0,0 @@
1
- class MailCannon::SendgridEvent
2
- include Mongoid::Document
3
- field :envelope_id, type: String
4
- field :envelope_bag_id, type: String
5
- field :email, type: String
6
- field :timestamp, type: String
7
- field :unique_arg, type: String
8
- field :event, type: String
9
- field :type, type: String
10
- field :processed, type: Boolean, default: nil
11
-
12
- belongs_to :envelope
13
- belongs_to :envelope_bag
14
-
15
- def self.insert_bulk(tha_huge_string)
16
- MailCannon::SendgridEvent.collection.insert(tha_huge_string)
17
- end
18
- end
@@ -1,11 +0,0 @@
1
- class MailCannon::EnvelopeBagReduceJob
2
- include Sidekiq::Worker
3
-
4
- def perform(envelope_bag_ids)
5
- envelope_bag_ids.each do |id|
6
- id = id['$oid'] if id['$oid']
7
- MailCannon::EnvelopeBag.reduce_statistics_for_envelope_bag(id)
8
- end
9
- end
10
-
11
- end
@@ -1,118 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe 'full stack test' do
4
- describe "should send 2 envelopes, receive correct statistics and map/reduce data correctly" do
5
-
6
- let(:expected_hash_a){
7
- {
8
- "posted"=>{"count"=>1.0, "targets"=>["1"]},
9
- "processed"=>{"count"=>1.0, "targets"=>["2"]},
10
- "delivered"=>{"count"=>1.0, "targets"=>["3"]},
11
- "open" => {"count"=>1.0, "targets"=>["4"]},
12
- "click"=>{"count"=>1.0, "targets"=>["5"]},
13
- "deferred"=>{"count"=>1.0, "targets"=>["6"]},
14
- "spam_report"=>{"count"=>1.0, "targets"=>["7"]},
15
- "spam"=>{"count"=>1.0, "targets"=>["8"]},
16
- "unsubscribe"=>{"count"=>1.0, "targets"=>["9"]},
17
- "drop"=>{"count"=>1.0, "targets"=>["10"]},
18
- "hard_bounce" => {"count"=>1.0, "targets"=>["11"]},
19
- "soft_bounce"=>{"count"=>1.0, "targets"=>["12"]},
20
- "unknown"=>{"count"=>1.0, "targets"=>["13"]}
21
- }
22
- }
23
-
24
- let(:expected_hash_b){
25
- {
26
- "posted"=>{"count"=>2.0, "targets"=>["1", "1" ]},
27
- "processed"=>{"count"=>2.0, "targets"=>["2", "2"]},
28
- "delivered"=>{"count"=>2.0, "targets"=>["3", "3"]},
29
- "open" => {"count"=>2.0, "targets"=>["4", "4"]},
30
- "click"=>{"count"=>2.0, "targets"=>["5","5"]},
31
- "deferred"=>{"count"=>2.0, "targets"=>["6", "6"]},
32
- "spam_report"=>{"count"=>2.0, "targets"=>["7", "7"]},
33
- "spam"=>{"count"=>2.0, "targets"=>["8", "8"]},
34
- "unsubscribe"=>{"count"=>2.0, "targets"=>["9", "9"]},
35
- "drop"=>{"count"=>2.0, "targets"=>["10", "10"]},
36
- "hard_bounce" => {"count"=>2.0, "targets"=>["11", "11"]},
37
- "soft_bounce"=>{"count"=>2.0, "targets"=>["12", "12"]},
38
- "unknown"=>{"count"=>2.0, "targets"=>["13", "13"]}
39
- }
40
- }
41
-
42
- context "send emails and map reduce" do
43
- let(:envelope_bag) { build(:empty_envelope_bag)}
44
- let!(:envelope_a) { build(:envelope_multi) }
45
- let!(:envelope_b) { build(:envelope_multi) }
46
-
47
- it "sends http request for Sendgrid web API" do
48
- envelope_bag.save
49
- envelope_bag.envelopes << envelope_a
50
- envelope_bag.envelopes << envelope_b
51
- VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
52
- Sidekiq::Testing.inline! do
53
- bm = Benchmark.measure do
54
- envelope_a.send_bulk!
55
- end
56
- end
57
- end
58
-
59
- envelope_a_hash = [
60
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'posted', target_id: '1'},
61
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'processed', target_id: '2'},
62
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'delivered', target_id: '3'},
63
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'open', target_id: '4'},
64
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'click', type: 'bounce', target_id: '5'},
65
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'deferred', type: 'expected', target_id: '6'},
66
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'spam_report', target_id: '7'},
67
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'spam', target_id: '8'},
68
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'unsubscribe', target_id: '9'},
69
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'drop', target_id: '10'},
70
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'bounce', type: 'bounce', target_id: '11'},
71
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'bounce', type: 'expected', target_id: '12'},
72
- {envelope_id: envelope_a.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'gfyigad', target_id: '13'},
73
- ]
74
- MailCannon::SendgridEvent.insert_bulk(envelope_a_hash)
75
-
76
- Sidekiq::Testing.inline! do
77
- MailCannon::EnvelopeBagReduceJob.perform_async([envelope_bag.id])
78
- end
79
-
80
- expect(envelope_a.reload.sendgrid_events.where(processed: true).count).to eq(13)
81
- expect(envelope_bag.stats).to eq(expected_hash_a)
82
-
83
- VCR.use_cassette('mailcannon_adapter_sendgrid_send_bulk') do
84
- Sidekiq::Testing.inline! do
85
- bm = Benchmark.measure do
86
- envelope_b.send_bulk!
87
- end
88
- end
89
- end
90
-
91
- envelope_b_hash = [
92
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'posted', target_id: '1'},
93
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'processed', target_id: '2'},
94
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'delivered', target_id: '3'},
95
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'open', target_id: '4'},
96
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'click', type: 'bounce', target_id: '5'},
97
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'deferred', type: 'expected', target_id: '6'},
98
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'spam_report', target_id: '7'},
99
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'spam', target_id: '8'},
100
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo1@bar.com', timestamp: 1322000092, unique_arg: 'my unique arg', event: 'unsubscribe', target_id: '9'},
101
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo2@bar.com', timestamp: 1322000093, unique_arg: 'my unique arg', event: 'drop', target_id: '10'},
102
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'bounce', type: 'bounce', target_id: '11'},
103
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'bounce', type: 'expected', target_id: '12'},
104
- {envelope_id: envelope_b.id, envelope_bag_id: envelope_bag.id, email: 'foo3@bar.com', timestamp: 1322000094, unique_arg: 'my unique arg', event: 'gfyigad', target_id: '13'},
105
- ]
106
- MailCannon::SendgridEvent.insert_bulk(envelope_b_hash)
107
-
108
- Sidekiq::Testing.inline! do
109
- MailCannon::EnvelopeBagReduceJob.perform_async([envelope_bag.id])
110
- end
111
-
112
- expect(envelope_b.reload.sendgrid_events.where(processed: true).count).to eq(13)
113
- expect(envelope_bag.stats).to eq(expected_hash_b)
114
- end
115
- end
116
-
117
- end
118
- end