Commit e719603760f2de178afab4d74049696029513d3f
Exists in
master
and in
29 other branches
Merge branch 'master' of gitlab.com:noosfero/noosfero
Showing
8 changed files
with
121 additions
and
39 deletions
Show diff stats
app/models/person_notifier.rb
... | ... | @@ -22,12 +22,17 @@ class PersonNotifier |
22 | 22 | schedule_next_notification_mail |
23 | 23 | end |
24 | 24 | |
25 | + def notify_from | |
26 | + @person.last_notification || DateTime.now - @person.notification_time.hours | |
27 | + end | |
28 | + | |
25 | 29 | def notify |
26 | 30 | if @person.notification_time && @person.notification_time > 0 |
27 | - from = @person.last_notification || DateTime.now - @person.notification_time.hours | |
28 | - notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", from]) | |
31 | + notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", notify_from]) | |
32 | + tasks = Task.to(@person).without_spam.pending.where("created_at > ?", notify_from).order_by('created_at', 'asc') | |
33 | + | |
29 | 34 | Noosfero.with_locale @person.environment.default_language do |
30 | - Mailer::content_summary(@person, notifications).deliver unless notifications.empty? | |
35 | + Mailer::content_summary(@person, notifications, tasks).deliver unless notifications.empty? && tasks.empty? | |
31 | 36 | end |
32 | 37 | @person.settings[:last_notification] = DateTime.now |
33 | 38 | @person.save! |
... | ... | @@ -59,8 +64,12 @@ class PersonNotifier |
59 | 64 | end |
60 | 65 | |
61 | 66 | def failure(job) |
62 | - person = Person.find(person_id) | |
63 | - person.notifier.dispatch_notification_mail | |
67 | + begin | |
68 | + person = Person.find(person_id) | |
69 | + person.notifier.dispatch_notification_mail | |
70 | + rescue | |
71 | + Rails.logger.error "PersonNotifier::NotifyJob: Cannot recover from failure" | |
72 | + end | |
64 | 73 | end |
65 | 74 | |
66 | 75 | end |
... | ... | @@ -73,18 +82,24 @@ class PersonNotifier |
73 | 82 | {:theme => nil} |
74 | 83 | end |
75 | 84 | |
76 | - def content_summary(person, notifications) | |
85 | + def content_summary(person, notifications, tasks) | |
86 | + if person.environment | |
87 | + ActionMailer::Base.asset_host = person.environment.top_url | |
88 | + ActionMailer::Base.default_url_options[:host] = person.environment.default_hostname | |
89 | + end | |
90 | + | |
77 | 91 | @current_theme = 'default' |
78 | 92 | @profile = person |
79 | 93 | @recipient = @profile.nickname || @profile.name |
80 | 94 | @notifications = notifications |
95 | + @tasks = tasks | |
81 | 96 | @environment = @profile.environment.name |
82 | 97 | @url = @profile.environment.top_url |
83 | 98 | mail( |
84 | 99 | content_type: "text/html", |
85 | 100 | from: "#{@profile.environment.name} <#{@profile.environment.noreply_email}>", |
86 | 101 | to: @profile.email, |
87 | - subject: _("[%s] Network Activity") % [@profile.environment.name] | |
102 | + subject: _("[%s] Notifications") % [@profile.environment.name] | |
88 | 103 | ) |
89 | 104 | end |
90 | 105 | end | ... | ... |
app/views/person_notifier/mailer/_comment.html.erb
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | <span style="font-size: 12px;"><%= comment.title %></span><br/> |
20 | 20 | <% end %> |
21 | 21 | <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> |
22 | - <span style="font-size: 8px; color: #444444"><%= time_ago_as_sentence(comment.created_at) %></span> | |
22 | + <span style="font-size: 8px; color: #929292"><%= time_ago_as_sentence(comment.created_at) %></span> | |
23 | 23 | <br style="clear: both;" /> |
24 | 24 | |
25 | 25 | <% unless comment.replies.blank? %> | ... | ... |
app/views/person_notifier/mailer/_create_article.html.erb
1 | -<table> | |
2 | 1 | <tr> |
3 | - <td> | |
2 | + <td style="width: 11%"> | |
4 | 3 | <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> |
5 | 4 | </td> |
6 | 5 | <td> |
7 | - <p style="width:550px"> | |
6 | + <p> | |
8 | 7 | <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> |
9 | 8 | <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> |
10 | - <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
9 | + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
11 | 10 | </p> |
12 | 11 | <p> |
13 | 12 | <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> |
... | ... | @@ -24,4 +23,3 @@ |
24 | 23 | <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> |
25 | 24 | </td> |
26 | 25 | </tr> |
27 | -</table> | ... | ... |
app/views/person_notifier/mailer/_default_activity.html.erb
1 | -<table> | |
2 | 1 | <tr> |
3 | - <td> | |
2 | + <td style="width: 11%"> | |
4 | 3 | <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> |
5 | 4 | </td> |
6 | 5 | <td> |
7 | - <p style="width:550px"> | |
6 | + <p> | |
8 | 7 | <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> |
9 | - <span style="font-size: 10px; color: #444444; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
8 | + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
10 | 9 | </p> |
11 | 10 | </td> |
12 | 11 | </tr> |
... | ... | @@ -16,4 +15,3 @@ |
16 | 15 | <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> |
17 | 16 | </td> |
18 | 17 | </tr> |
19 | -</table> | ... | ... |
... | ... | @@ -0,0 +1,20 @@ |
1 | +<div style="border-bottom:1px solid #e2e2e2;padding:15px 0;width:600px"> | |
2 | + <table style="width:100%;"> | |
3 | + <tr> | |
4 | + <td style="width: 11%"> | |
5 | + <%= profile_image(task.requestor, :minor) %> | |
6 | + </td> | |
7 | + <td> | |
8 | + <div> | |
9 | + <strong><%= link_to task.title, url_for(:controller => 'tasks', :profile => @profile.identifier, :action => 'index', :only_path => false) %></strong> | |
10 | + </div> | |
11 | + <div style="font-size: 14px"> | |
12 | + <span style="font-size: 14px"> | |
13 | + <%= task_information(task) %> | |
14 | + </span> | |
15 | + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(task.created_at) %></span> | |
16 | + </div> | |
17 | + </td> | |
18 | + </tr> | |
19 | + </table> | |
20 | +</div> | ... | ... |
app/views/person_notifier/mailer/_upload_image.html.erb
1 | -<table> | |
2 | 1 | <tr> |
3 | - <td> | |
2 | + <td style="width: 11%"> | |
4 | 3 | <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> |
5 | 4 | </td> |
6 | 5 | <td> |
7 | - <p style="width:550px"> | |
6 | + <p> | |
8 | 7 | <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> |
9 | - <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
8 | + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
10 | 9 | </p> |
11 | 10 | </td> |
12 | 11 | </tr> |
13 | -</table> | |
14 | 12 | <div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div> |
15 | 13 | <br/> | ... | ... |
app/views/person_notifier/mailer/content_summary.html.erb
1 | -<h3><%= _("%s's network activity") % @profile.name %></h3> | |
2 | -<br/> | |
3 | -<div> | |
4 | -<% @notifications.each do |activity| %> | |
5 | - <div style="border-left:none;border-right:none;border-top:1px solid #ccc;border-bottom:none;padding:10px;width:600px"> | |
6 | - <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %> | |
7 | - </div> | |
8 | -<% end %> | |
9 | -</div> | |
1 | +<div style="background-color: #EEEEEE"> | |
2 | + <table style="width: 100%;"><tbody><tr><td align="center"> | |
3 | + <div style="display: table; background-color: white; margin: 26px 0;"> | |
4 | + <div style="padding: 25px 20px 20px 20px;text-align: left;"> | |
5 | + <%= link_to @url, :style => "text-decoration: none;" do %> | |
6 | + <span style="font-weight:bold;font-size: 28px;margin: 0;color: white;background-color: #AAAAAA;padding: 5px;"><%= @environment %></span> | |
7 | + <% end %> | |
8 | + <span style="font-weight:bold;color: #333;font-size:19px;margin-left: 8px;"><%= _("%s's Notifications") % @profile.name %></h3> | |
9 | + </div> | |
10 | + <div style="margin: 0 20px 20px 20px;border-top:1px solid #e2e2e2;"> | |
11 | + <% if @tasks.present? %> | |
12 | + <div style="border-top: 1px solid #e2e2e2;"> | |
13 | + <div style="border-bottom: 1px solid #CBCBCB;padding-top: 15px;font-weight: bold;text-align: right;color: #7c7c7c;float: right;min-width: 140px;"> | |
14 | + <%= _('Tasks') %> | |
15 | + </div> | |
16 | + <%= render :partial => 'task', :collection => @tasks %> | |
17 | + </div> | |
18 | + <% end %> | |
19 | + | |
20 | + <% if @notifications.present? %> | |
21 | + <div style="border-top: 1px solid #e2e2e2;"> | |
22 | + <div style="border-bottom: 1px solid #CBCBCB;padding-top: 15px;font-weight: bold;text-align: right;color: #7c7c7c;float: right;min-width: 140px;"> | |
23 | + <%= _('Network Activity') %> | |
24 | + </div> | |
25 | + <% @notifications.each do |activity| %> | |
26 | + <div style="border-bottom:1px solid #e2e2e2;padding:15px 0;width:600px"> | |
27 | + <table style="width:100%;"> | |
28 | + <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %> | |
29 | + </table> | |
30 | + </div> | |
31 | + <% end %> | |
32 | + </div> | |
33 | + <% end %> | |
10 | 34 | |
11 | -<div style="color:#444444;font-size:11px;"> | |
12 | -<p><%= _("Greetings,") %></p> | |
13 | -<br/> | |
14 | -<p>--</p> | |
15 | -<p><%= _('%s team.') % @environment %></p> | |
16 | -<p><%= url_for @url %></p> | |
35 | + <div style="color:#444444;font-size:11px;margin-bottom: 20px;"> | |
36 | + <p style="margin:0"><%= _("Greetings,") %></p> | |
37 | + <p style="margin:0"><%= _('%s team.') % @environment %></p> | |
38 | + <p style="margin:0"><%= link_to @url, url_for(@url) %></p> | |
39 | + </div> | |
40 | + </div> | |
41 | + </td></tr></tbody></table> | |
17 | 42 | </div> |
18 | -<br/> | ... | ... |
test/unit/person_notifier_test.rb
... | ... | @@ -225,6 +225,35 @@ class PersonNotifierTest < ActiveSupport::TestCase |
225 | 225 | assert !jobs.select {|j| !j.failed? && j.last_error.nil? }.empty? |
226 | 226 | end |
227 | 227 | |
228 | + should 'render image tags for both internal and external src' do | |
229 | + @community.add_member(@member) | |
230 | + process_delayed_job_queue | |
231 | + notify | |
232 | + sent = ActionMailer::Base.deliveries.last | |
233 | + assert_match /src="\/\/www.gravatar.com\/avatar.*"/, sent.body.to_s | |
234 | + assert_match /src="http:\/\/.*\/images\/icons-app\/community-icon.png.*"/, sent.body.to_s | |
235 | + end | |
236 | + | |
237 | + should 'do not raise errors in NotifyJob failure to avoid loop' do | |
238 | + Delayed::Worker.max_attempts = 1 | |
239 | + Delayed::Job.enqueue(PersonNotifier::NotifyJob.new(@member.id)) | |
240 | + | |
241 | + PersonNotifier.any_instance.stubs(:notify).raises('error') | |
242 | + PersonNotifier.any_instance.stubs(:dispatch_notification_mail).raises('error') | |
243 | + | |
244 | + process_delayed_job_queue | |
245 | + jobs = PersonNotifier::NotifyJob.find(@member.id) | |
246 | + assert jobs.select {|j| !j.failed? && j.last_error.nil? }.empty? | |
247 | + end | |
248 | + | |
249 | + should 'list tasks in notification mail' do | |
250 | + task = @member.tasks.create! | |
251 | + process_delayed_job_queue | |
252 | + notify | |
253 | + sent = ActionMailer::Base.deliveries.last | |
254 | + assert_match /href=".*\/myprofile\/member\/tasks"/, sent.body.to_s | |
255 | + end | |
256 | + | |
228 | 257 | private |
229 | 258 | |
230 | 259 | def notify | ... | ... |