diff --git a/app/jobs/send_summary_emails_job.rb b/app/jobs/send_summary_emails_job.rb new file mode 100644 index 000000000..1cb8d6ba3 --- /dev/null +++ b/app/jobs/send_summary_emails_job.rb @@ -0,0 +1,19 @@ +class SendSummaryEmailsJob < ApplicationJob + queue_as :default + + def perform + staff = User.where(staff: true) + posts = Post.unscoped.qa_only.where(created_at: SummaryMailer::TIMEFRAME.ago..DateTime.now) + .includes(:community, :user) + flags = Flag.unscoped.where(created_at: SummaryMailer::TIMEFRAME.ago..DateTime.now) + .includes(:post, :community, :user) + comments = Comment.unscoped.where(created_at: SummaryMailer::TIMEFRAME.ago..DateTime.now) + .includes(:user, :post, :comment_thread, post: :community) + users = User.where(created_at: SummaryMailer::TIMEFRAME.ago..DateTime.now).includes(:community_users) + staff.each do |u| + SummaryMailer.with(to: u.email, posts: posts.to_a, flags: flags.to_a, comments: comments.to_a, users: users.to_a) + .content_summary + .deliver_later + end + end +end diff --git a/app/mailers/summary_mailer.rb b/app/mailers/summary_mailer.rb new file mode 100644 index 000000000..cf6722db0 --- /dev/null +++ b/app/mailers/summary_mailer.rb @@ -0,0 +1,16 @@ +class SummaryMailer < ApplicationMailer + TIMEFRAME = 30.minutes + + helper :application, :post_types, :users + + def content_summary + @posts = params[:posts] + @flags = params[:flags] + @comments = params[:comments] + @users = params[:users] + + mail(from: "#{SiteSetting['NoReplySenderName']} <#{SiteSetting['NoReplySenderEmail']}>", + subject: 'Codidact Content Summary', + to: params[:to]) + end +end diff --git a/app/views/summary_mailer/content_summary.html.erb b/app/views/summary_mailer/content_summary.html.erb new file mode 100644 index 000000000..d53898987 --- /dev/null +++ b/app/views/summary_mailer/content_summary.html.erb @@ -0,0 +1,76 @@ +

Codidact Content Summary

+

+ Covering + <%= SummaryMailer::TIMEFRAME.ago.strftime '%a %d %b, %H:%M' %> + to + <%= DateTime.now.strftime '%a %d %b, %H:%M' %> +

+ +

New Posts

+<% if @posts.any? %> + <% @posts.first(10).each do |p| %> +

+ <%= link_to p.title, generic_share_link(p, host: p.community.host) %>
+ by <%= user_link p.user, { host: p.community.host } %> on <%= p.community.name %> +

+ <% end %> + <% if @posts.size > 10 %> +

and <%= @posts.size - 10 %> more

+ <% end %> +<% else %> +

No new posts in this timeframe.

+<% end %> + +

New Flags

+<% if @flags.any? %> + <% @flags.first(10).each do |f| %> +

+ <%= f.post_flag_type&.name || 'other' %> + flag: <%= f.reason.present? ? "\"#{f.reason}\"" : "" %> + <% status_colors = { helpful: 'is-green', declined: 'is-red', pending: 'is-muted' } %> + + <%= f.status || 'pending' %> +
+ by <%= user_link f.user, { host: f.community.host } %> + on <%= link_to f.post.title, generic_share_link(f.post, host: f.community.host) %> + on <%= f.community.name %>
+

+ <% end %> + <% if @flags.size > 10 %> +

and <%= @flags.size - 10 %> more

+ <% end %> +<% else %> +

No new flags in this timeframe

+<% end %> + +

New Comments

+<% if @comments.any? %> + <% @comments.first(10).each do |c| %> +
<%= c.content %>
+

+ by <%= user_link c.user, { host: c.post.community.host } %> + on <%= link_to c.post.title, generic_share_link(c.post, host: c.post.community.host) %> + on <%= c.post.community.name %> +

+ <% end %> + <% if @comments.size > 10 %> +

and <%= @comments.size - 10 %> more

+ <% end %> +<% else %> +

No new comments in this timeframe

+<% end %> + +

New Users

+<% if @users.any? %> + <% @users.first(10).each do |u| %> +

+ <%= user_link u, { host: u.community_users.unscoped.first.community.host } %> + on <%= u.community_users.unscoped.first.community.name %> +

+ <% end %> + <% if @users.size > 10 %> +

and <%= @users.size - 10 %> more

+ <% end %> +<% else %> +

No new users in this timeframe

+<% end %> diff --git a/config/schedule.rb b/config/schedule.rb index 1b1c9c343..35d707b38 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -25,3 +25,7 @@ every 6.hours do runner 'scripts/recalc_abilities.rb' end + +every 30.minutes do + runner 'scripts/run_summary_mailer.rb' +end diff --git a/scripts/run_summary_mailer.rb b/scripts/run_summary_mailer.rb new file mode 100644 index 000000000..ce82f1544 --- /dev/null +++ b/scripts/run_summary_mailer.rb @@ -0,0 +1 @@ +SendSummaryEmailsJob.perform_later diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 82cd00ba7..ad5463bc6 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -93,6 +93,16 @@ global_admin: is_global_moderator: false confirmed_at: 2020-01-01T00:00:00.000000Z +staff: + email: staff@qpixel-test.net + encrypted_password: '$2a$11$roUHXKxecjyQ72Qn7DWs3.9eRCCoRn176kX/UNb/xiue3aGqf7xEW' + sign_in_count: 42 + username: staff + is_global_admin: true + is_global_moderator: true + staff: true + confirmed_at: 2020-01-01T00:00:00.000000Z + no_community_user: email: no_community_user@qpixel-test.net encrypted_password: '$2a$11$roUHXKxecjyQ72Qn7DWs3.9eRCCoRn176kX/UNb/xiue3aGqf7xEW' diff --git a/test/jobs/send_summary_emails_job_test.rb b/test/jobs/send_summary_emails_job_test.rb new file mode 100644 index 000000000..3207ff816 --- /dev/null +++ b/test/jobs/send_summary_emails_job_test.rb @@ -0,0 +1,21 @@ +require 'test_helper' + +class SendSummaryEmailsJobTest < ActiveJob::TestCase + include ActionMailer::TestCase::ClearTestDeliveries + + test 'should correctly send summary emails' do + perform_enqueued_jobs do + SendSummaryEmailsJob.perform_later + end + + assert_performed_jobs(2) + + delivered = SummaryMailer.deliveries.first + + to_email = users(:staff).email + + assert_equal 1, delivered.recipients.size + assert delivered.recipients.include?(to_email), + "Expected #{to_email} to be a recipient, actual: #{delivered.recipients.join(', ')}" + end +end diff --git a/test/mailers/previews/summary_mailer_preview.rb b/test/mailers/previews/summary_mailer_preview.rb new file mode 100644 index 000000000..6bf5e4afd --- /dev/null +++ b/test/mailers/previews/summary_mailer_preview.rb @@ -0,0 +1,17 @@ +# Preview all emails at http://localhost:3000/rails/mailers/summary_mailer +class SummaryMailerPreview < ActionMailer::Preview + def content_summary + test_timeframe = 1.year + staff = User.where(staff: true) + posts = Post.unscoped.qa_only.where(created_at: test_timeframe.ago..DateTime.now) + .includes(:community, :user) + flags = Flag.unscoped.where(created_at: test_timeframe.ago..DateTime.now) + .includes(:post, :community, :user) + comments = Comment.unscoped.where(created_at: test_timeframe.ago..DateTime.now) + .includes(:user, :post, :comment_thread, post: :community) + users = User.where(created_at: test_timeframe.ago..DateTime.now).includes(:community_users) + + SummaryMailer.with(to: staff.first.email, posts: posts.to_a, flags: flags.to_a, comments: comments.to_a, users: users.to_a) + .content_summary + end +end diff --git a/test/mailers/summary_mailer_test.rb b/test/mailers/summary_mailer_test.rb new file mode 100644 index 000000000..c52ffc1a6 --- /dev/null +++ b/test/mailers/summary_mailer_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class SummaryMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end