newsly 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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