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.
- 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
|