newsly 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.
@@ -34,7 +34,6 @@ module Newsly
34
34
 
35
35
  def deliver
36
36
  if params[:answer] == "DELIVER"
37
- #Newsly::NewsletterSender.perform(@newsletter.id, params[:recipient_groups])
38
37
  Resque.enqueue(Newsly::NewsletterSender, @newsletter.id, params[:recipient_groups])
39
38
  @newsletter.sent = true
40
39
  @newsletter.save
@@ -44,6 +43,17 @@ module Newsly
44
43
  end
45
44
  end
46
45
 
46
+ def deliver_batch
47
+ if params[:answer] == "BATCH"
48
+ Resque.enqueue(Newsly::NewsletterBatchSender, @newsletter.id, params[:recipient_group], params[:batch_size])
49
+ @newsletter.batch_sent = true
50
+ @newsletter.save
51
+ render :text => "BATCH DELIVERED"
52
+ else
53
+ render :text => "WARNING! Not sent, did you answer correctly?"
54
+ end
55
+ end
56
+
47
57
  def destroy
48
58
  @newsletter.destroy
49
59
  redirect_to newsletters_url
@@ -6,6 +6,17 @@ module Newsly
6
6
  def render(options={})
7
7
  Liquid::Template.parse(self.body).render options
8
8
  end
9
+
10
+ def draft?
11
+ self.sent? || self.batch_sent? ? false : true
12
+ end
13
+
14
+ #TODO, make nicer!
15
+ def status
16
+ return "draft" if self.draft?
17
+ return "sent" if self.sent?
18
+ return "batch" if self.batch_sent?
19
+ end
9
20
 
10
21
  end
11
22
  end
@@ -1,28 +1,37 @@
1
1
  <div id="sidebar">
2
2
  <ul class="links">
3
+ <li><%= link_to '<em>☜</em> Back'.html_safe, newsletters_path %></li>
4
+ <li class="button">
5
+ <%= link_to "<em>❖</em>Send test".html_safe, send_test_newsletter_path(@newsletter), :id => "send_test"%>
6
+ </li>
3
7
  <% if !@newsletter.sent? and @newsletter.persisted?%>
4
- <li class="button">
5
- <%= link_to "<em>❖</em>Send test".html_safe, send_test_newsletter_path(@newsletter), :id => "send_test"%>
6
- </li>
7
8
  <% if Newsly.recipient_groups.count > 0 %>
8
9
  <li class="groups">
9
10
  <form id="groupform" class="groupform">
11
+ <h3>Recipient Groups</h3>
10
12
  <ul>
13
+ <% @max_batch_size = 0 %>
11
14
  <% for group in Newsly.recipient_groups %>
15
+ <% @group_count = group[1].call.count %>
16
+ <% @max_batch_size = @max_batch_size + @group_count %>
12
17
  <li>
13
- <input type="checkbox" name="<%=group[0].to_s%>" value="<%=group[0].to_s%>" id="group_<%=group[0].to_s%>" />
14
- <label for="group_<%=group[0].to_s%>"><%= group[0].to_s.humanize %> (<%= group[1].call.count %>)</label>
18
+ <input type="checkbox" name="<%=group[0].to_s%>" value="<%=group[0].to_s%>" id="group_<%=group[0].to_s%>" data-max="<%= @group_count %>"/>
19
+ <label for="group_<%=group[0].to_s%>"><%= group[0].to_s.humanize %> (<span class="count"><%= @group_count %></span>)</label>
15
20
  </li>
16
21
  <% end %>
17
22
  </ul>
18
23
  </form>
19
24
  </li>
20
- <li class="button">
21
- <%= link_to "<em>✈</em>Deliver!".html_safe, deliver_newsletter_path(@newsletter), :id => "deliver"%>
25
+ <li class="button range deliverbutton">
26
+ <span id="batch_size_preview"></span>
27
+ <input type="range" min="0" value="0" max="<%= @max_batch_size %>" id="batch_size" />
28
+ <%= link_to "<em>✈</em>Deliver Batch!".html_safe, deliver_batch_newsletter_path(@newsletter), :id => "deliver_batch"%>
29
+ </li>
30
+ <li class="button deliverbutton">
31
+ <%= link_to "<em>✈</em>Deliver All!".html_safe, deliver_newsletter_path(@newsletter), :id => "deliver"%>
22
32
  </li>
23
33
  <% end %>
24
34
  <% end %>
25
- <li><%= link_to '<em>☜</em> Back'.html_safe, newsletters_path %></li>
26
35
  </ul>
27
36
  <div id="saved"></div>
28
37
  </div>
@@ -5,9 +5,11 @@
5
5
  <tbody>
6
6
  <% @newsletters.each do |newsletter| %>
7
7
  <tr>
8
- <td class="<%= newsletter.sent? ? "sent": "draft" %>"><%= newsletter.sent? ? t("sent"): t("draft") %></td>
8
+ <td class="<%= newsletter.status%>"><%= newsletter.status %></td>
9
9
  <td class="title"><%= link_to newsletter.title, newsletter %></td>
10
- <td class="action"><%= link_to 'Destroy', newsletter, confirm: 'Are you sure?', method: :delete if !newsletter.sent?%></td>
10
+ <td class="action">
11
+ <%= link_to 'Destroy', newsletter, confirm: 'Are you sure?', method: :delete if newsletter.draft? %>
12
+ </td>
11
13
  </tr>
12
14
  <% end %>
13
15
  </tbody>
@@ -0,0 +1,11 @@
1
+ module Newsly
2
+ class NewsletterBatchSender
3
+ @queue = :newsletter
4
+ def self.perform(newsletter_id, recipient_group, batch_size)
5
+ Newsly.get_newsletter_receipient_group(recipient_group.to_sym).call.limit(batch_size).each do |resource|
6
+ Newsly::Mailer.async_deliver.build_newsletter(newsletter_id, resource.send(Newsly.resource_email_column), resource.to_liquid)
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -4,7 +4,7 @@ module Newsly
4
4
  def self.perform(newsletter_id, recipient_groups)
5
5
  for group in recipient_groups
6
6
  Newsly.get_newsletter_receipient_group(group.to_sym).call.find_each(:batch_size => 1000) do |resource|
7
- Newsly::Mailer.build_newsletter(newsletter_id, resource.send(Newsly.resource_email_column), resource.to_liquid).deliver
7
+ Newsly::Mailer.async_deliver.build_newsletter(newsletter_id, resource.send(Newsly.resource_email_column), resource.to_liquid)
8
8
  end
9
9
  end
10
10
 
data/config/routes.rb CHANGED
@@ -4,6 +4,7 @@ Newsly::Engine.routes.draw do
4
4
  member do
5
5
  put 'send_test'
6
6
  put 'deliver'
7
+ put 'deliver_batch'
7
8
  end
8
9
  end
9
10
 
@@ -0,0 +1,5 @@
1
+ class AddFieldsToNewsletter < ActiveRecord::Migration
2
+ def change
3
+ add_column :newsly_newsletters, :batch_sent, :integer
4
+ end
5
+ end
data/lib/newsly.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "newsly/engine"
2
2
  require "resque"
3
3
  require "liquid"
4
+ require "resque-async_deliver"
4
5
 
5
6
  module Newsly
6
7
 
@@ -1,3 +1,3 @@
1
1
  module Newsly
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,68 +1,141 @@
1
1
  jQuery(document).ready(function($) {
2
2
 
3
-
4
3
  if (top.Mercury) {
5
- window.Mercury = top.Mercury;
6
- Mercury.PageEditor.prototype.save = function() {
7
- var data = this.serialize();
8
- var newsletter_id = $("#newsletter").attr('data-id');
9
- $.ajax({
10
- url: $("#newsletter").attr('data-url'),
11
- type: 'POST',
12
- data: {newsletter: {title: data.title.value, body: data.body.value}, '_method': 'PUT'},
13
- success: function(data){
14
- $('#saved').html(data);
4
+ window.Mercury = top.Mercury;
5
+ Mercury.PageEditor.prototype.save = function() {
6
+ var data = this.serialize();
7
+ var newsletter_id = $("#newsletter").attr('data-id');
8
+ $.ajax({
9
+ url: $("#newsletter").attr('data-url'),
10
+ type: 'POST',
11
+ data: {newsletter: {title: data.title.value, body: data.body.value}, '_method': 'PUT'},
12
+ success: function(data){
13
+ $('#saved').html(data);
14
+ }
15
+ });
16
+ }
17
+
18
+
19
+ $('a#deliver_batch').click(function(e){
20
+ e.preventDefault();
21
+ top.Mercury.trigger('action', {action: 'save'});
22
+ var url = $(this).attr('href');
23
+ var recipient_groups = get_recipient_groups();
24
+ if($('#batch_size').val() <= 0){ alert('Batch size cant be 0!'); return false;}
25
+ if(recipient_groups.length == 1){
26
+ var newsletter_id = $("#newsletter").attr('data-id');
27
+ var answer = prompt('Are you sure? Type "BATCH"');
28
+ var batch_size = parseInt($('#batch_size').val());
29
+ if(answer == "BATCH"){
30
+ $.ajax({
31
+ url: url,
32
+ type: 'POST',
33
+ data: {'_method': 'PUT', 'answer': answer, 'recipient_group': recipient_groups[0], 'batch_size': batch_size},
34
+ success: function(data){
35
+ $("#flash").html(data).show().hide("fade", {}, 1000);
36
+ calculate_group_count(recipient_groups[0], batch_size);
37
+ }
38
+ });
39
+ }
40
+ } else{
41
+ alert('You have to select 1 (one) group to send to!');
15
42
  }
16
43
  });
17
- }};
18
44
 
19
- $('a#deliver').click(function(e){
20
- e.preventDefault();
21
- top.Mercury.trigger('action', {action: 'save'});
22
-
23
- var recipient_groups = [];
45
+ $('a#deliver').click(function(e){
46
+ e.preventDefault();
47
+ top.Mercury.trigger('action', {action: 'save'});
48
+ var url = $(this).attr('href');
49
+ var recipient_groups = get_recipient_groups();
50
+ if(recipient_groups.length > 0){
51
+ var newsletter_id = $("#newsletter").attr('data-id');
52
+ var answer = prompt('Are you sure? Type "DELIVER"');
53
+ if(answer == "DELIVER"){
54
+ $.ajax({
55
+ url: url,
56
+ type: 'POST',
57
+ data: {'_method': 'PUT', 'answer': answer, 'recipient_groups[]': recipient_groups},
58
+ success: function(data){
59
+ $("#flash").html(data).show().hide("fade", {}, 1000);
60
+ $(".deliverbutton").remove();
61
+ $('.groups').remove();
62
+ }
63
+ });
64
+ }
65
+ } else{
66
+ alert('You have to select atleast one group to send to!');
67
+ }
68
+ });
24
69
 
25
- $('#groupform input[type=checkbox]').each(function(){
26
- if($(this).is(':checked')){
27
- recipient_groups.push($(this).val());
70
+ $('a#send_test').click(function(e){
71
+ e.preventDefault();
72
+ top.Mercury.trigger('action', {action: 'save'});
73
+ var newsletter_id = $("#newsletter").attr('data-id');
74
+ var url = $(this).attr('href');
75
+ var to = prompt('to what email?');
76
+ $.ajax({
77
+ url: url,
78
+ type: 'POST',
79
+ data: {'_method': "PUT", 'to': to},
80
+ success: function(data){
81
+ $("#flash").html(data).show().hide("fade", {}, 1000);
82
+ }
83
+ });
84
+ });
85
+
86
+ $('#groupform input[type=checkbox]').change(function(){
87
+ if(get_recipient_groups().length > 0){
88
+ $('.deliverbutton').show();
89
+ set_batch_size();
90
+ } else {
91
+ $('.deliverbutton').hide();
28
92
  }
29
93
  });
30
-
31
- if(recipient_groups.length > 0){
32
- var newsletter_id = $("#newsletter").attr('data-id');
33
- var answer = prompt('Are you sure? Type "DELIVER"');
34
- var url = $(this).attr('href');
35
- if(answer == "DELIVER"){
36
- $.ajax({
37
- url: url,
38
- type: 'POST',
39
- data: {'_method': 'PUT', 'answer': answer, 'recipient_groups[]': recipient_groups},
40
- success: function(data){
41
- $("#flash").html(data).show().hide("fade", {}, 1000);
42
- $("#deliver").remove();
43
- $('.groups').remove();
44
- }
45
- });
46
- }
47
- } else{
48
- alert('You have to select atleast one group to send to!');
94
+
95
+ $('#batch_size').change(function(e){
96
+ $('#batch_size_preview').html($(this).val());
97
+ });
98
+
99
+ set_batch_size();
100
+ };
101
+
102
+ });
103
+
104
+
105
+ var set_batch_size = function(){
106
+ max_batch_size = get_maximum_batch_size();
107
+ $('#batch_size').val(0);
108
+ $('#batch_size_preview').html($('#batch_size').val());
109
+ $('#batch_size').attr('max', max_batch_size);
110
+ $('#batch_size').attr('min', 0);
111
+ $('#batch_size').val(0);
112
+ }
113
+
114
+ var get_recipient_groups = function(){
115
+ var recipient_groups = [];
116
+
117
+ $('#groupform input[type=checkbox]').each(function(){
118
+ if($(this).is(':checked')){
119
+ recipient_groups.push($(this).val());
49
120
  }
50
121
  });
122
+ return recipient_groups;
123
+ }
51
124
 
52
- $('a#send_test').click(function(e){
53
- e.preventDefault();
54
- top.Mercury.trigger('action', {action: 'save'});
55
- var newsletter_id = $("#newsletter").attr('data-id');
56
- var url = $(this).attr('href');
57
- var to = prompt('to what email?');
58
- $.ajax({
59
- url: url,
60
- type: 'POST',
61
- data: {'_method': "PUT", 'to': to},
62
- success: function(data){
63
- $("#flash").html(data).show().hide("fade", {}, 1000);
64
- }
65
- });
125
+ var get_maximum_batch_size = function(){
126
+ var max_size = 0;
127
+ $('#groupform input[type=checkbox]').each(function(){
128
+ if($(this).is(':checked')){
129
+ max_size = max_size + parseInt($(this).attr('data-max'));
130
+ }
66
131
  });
132
+ console.log('MAXIMUM SIZE '+ max_size);
133
+ return max_size;
134
+ }
67
135
 
68
- });
136
+ var calculate_group_count = function(groupname, batch_size){
137
+ new_max_size = parseInt($('#group_'+groupname).attr('data-max')) - batch_size;
138
+ $('#group_'+groupname).attr('data-max', new_max_size);
139
+ $('label[for=group_'+groupname+'] .count').html(new_max_size);
140
+ set_batch_size();
141
+ }
@@ -72,7 +72,7 @@ a:hover {
72
72
  table{
73
73
  width: 100%;
74
74
  }
75
- td.draft, td.sent{
75
+ td.draft, td.sent, td.batch{
76
76
  width: 20px;
77
77
  }
78
78
  td.action{
@@ -95,6 +95,11 @@ td.sent{
95
95
  background: green;
96
96
  font-size: 11px;
97
97
  }
98
+ td.batch{
99
+ color: #fff;
100
+ background: orange;
101
+ font-size: 11px;
102
+ }
98
103
  table tr:nth-child(2n+2){
99
104
  background: #eee;
100
105
  }
@@ -250,4 +255,24 @@ form{
250
255
  text-align: center;
251
256
  padding: 10px 0;
252
257
  display: none;
258
+ }
259
+
260
+ #batch_size_preview{
261
+ float: left;
262
+ background: #feb;
263
+ padding: 1px 5px;
264
+ border-radius: 5px;
265
+ font-size: 0.85em;
266
+ margin-bottom: 10px;
267
+ width: 20%;
268
+ text-align: center;
269
+ }
270
+ #batch_size{
271
+ float: right;
272
+ width: 70%;
273
+ padding: 0;
274
+ margin-top: 5px;
275
+ }
276
+ li.deliverbutton{
277
+ display: none;
253
278
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newsly
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:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-10-03 00:00:00.000000000Z
13
+ date: 2011-10-04 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &2161779420 !ruby/object:Gem::Requirement
17
+ requirement: &2153344680 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - =
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 3.1.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2161779420
25
+ version_requirements: *2153344680
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: resque
28
- requirement: &2161778980 !ruby/object:Gem::Requirement
28
+ requirement: &2153344200 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2161778980
36
+ version_requirements: *2153344200
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: liquid
39
- requirement: &2161778160 !ruby/object:Gem::Requirement
39
+ requirement: &2153343700 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *2161778160
47
+ version_requirements: *2153343700
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: jquery-rails
50
- requirement: &2161777640 !ruby/object:Gem::Requirement
50
+ requirement: &2153343260 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,21 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *2161777640
58
+ version_requirements: *2153343260
59
+ - !ruby/object:Gem::Dependency
60
+ name: resque-async_deliver
61
+ requirement: &2153342800 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *2153342800
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: sqlite3
61
- requirement: &2161776020 !ruby/object:Gem::Requirement
72
+ requirement: &2153342360 !ruby/object:Gem::Requirement
62
73
  none: false
63
74
  requirements:
64
75
  - - ! '>='
@@ -66,10 +77,10 @@ dependencies:
66
77
  version: '0'
67
78
  type: :development
68
79
  prerelease: false
69
- version_requirements: *2161776020
80
+ version_requirements: *2153342360
70
81
  - !ruby/object:Gem::Dependency
71
82
  name: letter_opener
72
- requirement: &2161775600 !ruby/object:Gem::Requirement
83
+ requirement: &2153341920 !ruby/object:Gem::Requirement
73
84
  none: false
74
85
  requirements:
75
86
  - - ! '>='
@@ -77,10 +88,10 @@ dependencies:
77
88
  version: '0'
78
89
  type: :development
79
90
  prerelease: false
80
- version_requirements: *2161775600
91
+ version_requirements: *2153341920
81
92
  - !ruby/object:Gem::Dependency
82
93
  name: unicorn
83
- requirement: &2161775180 !ruby/object:Gem::Requirement
94
+ requirement: &2153341460 !ruby/object:Gem::Requirement
84
95
  none: false
85
96
  requirements:
86
97
  - - ! '>='
@@ -88,7 +99,7 @@ dependencies:
88
99
  version: '0'
89
100
  type: :development
90
101
  prerelease: false
91
- version_requirements: *2161775180
102
+ version_requirements: *2153341460
92
103
  description: Manage mailer templates via wysiwyg and liquid. Uses mercury editor for
93
104
  now. And send out newsletters.
94
105
  email:
@@ -115,6 +126,7 @@ files:
115
126
  - app/views/newsly/snippets/index.html.erb
116
127
  - app/views/newsly/templates/index.html.erb
117
128
  - app/views/newsly/templates/show.html.erb
129
+ - app/workers/newsly/newsletter_batch_sender.rb
118
130
  - app/workers/newsly/newsletter_sender.rb
119
131
  - config/routes.rb
120
132
  - db/migrate/20110907161522_create_newsly_newsletters.rb
@@ -122,6 +134,7 @@ files:
122
134
  - db/migrate/20110926113235_add_draft_column_to_templates.rb
123
135
  - db/migrate/20110927120903_add_text_body_fields.rb
124
136
  - db/migrate/20110929142039_remove_text_body_fields.rb
137
+ - db/migrate/20111004085523_add_fields_to_newsletter.rb
125
138
  - lib/newsly/engine.rb
126
139
  - lib/newsly/version.rb
127
140
  - lib/newsly.rb