newsly 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/newsly/newsletters_controller.rb +11 -1
- data/app/models/newsly/newsletter.rb +11 -0
- data/app/views/newsly/newsletters/_sidebar.html.erb +17 -8
- data/app/views/newsly/newsletters/index.html.erb +4 -2
- data/app/workers/newsly/newsletter_batch_sender.rb +11 -0
- data/app/workers/newsly/newsletter_sender.rb +1 -1
- data/config/routes.rb +1 -0
- data/db/migrate/20111004085523_add_fields_to_newsletter.rb +5 -0
- data/lib/newsly.rb +1 -0
- data/lib/newsly/version.rb +1 -1
- data/public/javascripts/newsletters.js +127 -54
- data/public/stylesheets/application.css +26 -1
- metadata +29 -16
@@ -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 %> (
|
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
|
-
|
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.
|
8
|
+
<td class="<%= newsletter.status%>"><%= newsletter.status %></td>
|
9
9
|
<td class="title"><%= link_to newsletter.title, newsletter %></td>
|
10
|
-
<td class="action"
|
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)
|
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
data/lib/newsly.rb
CHANGED
data/lib/newsly/version.rb
CHANGED
@@ -1,68 +1,141 @@
|
|
1
1
|
jQuery(document).ready(function($) {
|
2
2
|
|
3
|
-
|
4
3
|
if (top.Mercury) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
$('#
|
26
|
-
|
27
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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.
|
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-
|
13
|
+
date: 2011-10-04 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
17
|
-
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: *
|
25
|
+
version_requirements: *2153344680
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: resque
|
28
|
-
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: *
|
36
|
+
version_requirements: *2153344200
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: liquid
|
39
|
-
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: *
|
47
|
+
version_requirements: *2153343700
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: jquery-rails
|
50
|
-
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: *
|
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: &
|
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: *
|
80
|
+
version_requirements: *2153342360
|
70
81
|
- !ruby/object:Gem::Dependency
|
71
82
|
name: letter_opener
|
72
|
-
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: *
|
91
|
+
version_requirements: *2153341920
|
81
92
|
- !ruby/object:Gem::Dependency
|
82
93
|
name: unicorn
|
83
|
-
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: *
|
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
|