418 lines
15 KiB
Ruby
418 lines
15 KiB
Ruby
|
|
class UserMailer < ApplicationMailer
|
||
|
|
helper_method :current_user
|
||
|
|
helper_method :current_admin
|
||
|
|
helper_method :logged_in?
|
||
|
|
helper_method :logged_in_as_admin?
|
||
|
|
|
||
|
|
helper :application
|
||
|
|
helper :tags
|
||
|
|
helper :works
|
||
|
|
helper :users
|
||
|
|
helper :date
|
||
|
|
helper :series
|
||
|
|
include HtmlCleaner
|
||
|
|
|
||
|
|
# Send an email letting a creator know that their work has been added to a collection by an archivist
|
||
|
|
def archivist_added_to_collection_notification(user_id, work_id, collection_id)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@work = Work.find(work_id)
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: t(".subject", app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Send a request to a work owner asking that they approve the inclusion
|
||
|
|
# of their work in a collection
|
||
|
|
def invited_to_collection_notification(user_id, work_id, collection_id)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@work = Work.find(work_id)
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# We use an options hash here, instead of keyword arguments, to avoid
|
||
|
|
# compatibility issues with resque/resque_mailer.
|
||
|
|
def anonymous_or_unrevealed_notification(user_id, work_id, collection_id, options = {})
|
||
|
|
options = options.with_indifferent_access
|
||
|
|
|
||
|
|
@becoming_anonymous = options.fetch(:anonymous, false)
|
||
|
|
@becoming_unrevealed = options.fetch(:unrevealed, false)
|
||
|
|
|
||
|
|
return unless @becoming_anonymous || @becoming_unrevealed
|
||
|
|
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@work = Work.find(work_id)
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
|
||
|
|
# Symbol used to pick the appropriate translation string:
|
||
|
|
@status = if @becoming_anonymous && @becoming_unrevealed
|
||
|
|
:anonymous_unrevealed
|
||
|
|
elsif @becoming_anonymous
|
||
|
|
:anonymous
|
||
|
|
else
|
||
|
|
:unrevealed
|
||
|
|
end
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: t(".subject.#{@status}", app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends an invitation to join the archive
|
||
|
|
# Must be sent synchronously as it is rescued
|
||
|
|
# TODO refactor to make it asynchronous
|
||
|
|
def invitation(invitation_id)
|
||
|
|
@invitation = Invitation.find(invitation_id)
|
||
|
|
@user_name = (@invitation.creator.is_a?(User) ? @invitation.creator.login : "")
|
||
|
|
mail(
|
||
|
|
to: @invitation.invitee_email,
|
||
|
|
subject: t("user_mailer.invitation.subject", app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends an invitation to join the archive and claim stories that have been imported as part of a bulk import
|
||
|
|
def invitation_to_claim(invitation_id, archivist_login)
|
||
|
|
@invitation = Invitation.find(invitation_id)
|
||
|
|
@external_author = @invitation.external_author
|
||
|
|
@archivist = archivist_login || "An archivist"
|
||
|
|
@token = @invitation.token
|
||
|
|
mail(
|
||
|
|
to: @invitation.invitee_email,
|
||
|
|
subject: t("user_mailer.invitation_to_claim.subject", app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Notifies a writer that their imported works have been claimed
|
||
|
|
def claim_notification(creator_id, claimed_work_ids)
|
||
|
|
creator = User.find(creator_id)
|
||
|
|
@external_email = creator.email
|
||
|
|
@claimed_works = Work.where(id: claimed_work_ids)
|
||
|
|
mail(
|
||
|
|
to: creator.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends a batched subscription notification
|
||
|
|
def batch_subscription_notification(subscription_id, entries)
|
||
|
|
# Here we use find_by_id so that if the subscription is not found
|
||
|
|
# then the resque job does not error and we just silently fail.
|
||
|
|
@subscription = Subscription.find_by(id: subscription_id)
|
||
|
|
return if @subscription.nil?
|
||
|
|
|
||
|
|
creation_entries = JSON.parse(entries)
|
||
|
|
@creations = []
|
||
|
|
# look up all the creations that have generated updates for this subscription
|
||
|
|
creation_entries.each do |creation_info|
|
||
|
|
creation_type, creation_id = creation_info.split("_")
|
||
|
|
creation = creation_type.constantize.where(id: creation_id).first
|
||
|
|
next unless creation && creation.try(:posted)
|
||
|
|
next if creation.is_a?(Chapter) && !creation.work.try(:posted)
|
||
|
|
next if creation.try(:hidden_by_admin) || (creation.is_a?(Chapter) && creation.work.try(:hidden_by_admin))
|
||
|
|
next if creation.pseuds.any? { |p| p.user == User.orphan_account } # no notifications for orphan works
|
||
|
|
|
||
|
|
# TODO: allow subscriptions to orphan_account to receive notifications
|
||
|
|
|
||
|
|
# If the subscription notification is for a user subscription, we don't
|
||
|
|
# want to send updates about works that have recently become anonymous.
|
||
|
|
if @subscription.subscribable_type == "User"
|
||
|
|
next if Subscription.anonymous_creation?(creation)
|
||
|
|
end
|
||
|
|
|
||
|
|
@creations << creation
|
||
|
|
end
|
||
|
|
|
||
|
|
return if @creations.empty?
|
||
|
|
|
||
|
|
# make sure we only notify once per creation
|
||
|
|
@creations.uniq!
|
||
|
|
|
||
|
|
subject = @subscription.subject_text(@creations.first)
|
||
|
|
subject += " and #{@creations.count - 1} more" if @creations.count > 1
|
||
|
|
I18n.with_locale(@subscription.user.preference.locale_for_mails) do
|
||
|
|
mail(
|
||
|
|
to: @subscription.user.email,
|
||
|
|
subject: "[#{ArchiveConfig.APP_SHORT_NAME}] #{subject}"
|
||
|
|
)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
# Emails a user to say they have been given more invitations for their friends
|
||
|
|
def invite_increase_notification(user_id, total)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@total = total
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Emails a user to say that their request for invitation codes has been declined
|
||
|
|
def invite_request_declined(user_id, total, reason)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@total = total
|
||
|
|
@reason = reason
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
def collection_notification(collection_id, subject, message, email)
|
||
|
|
@message = message
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
mail(
|
||
|
|
to: email,
|
||
|
|
subject: "[#{ArchiveConfig.APP_SHORT_NAME}][#{@collection.title}] #{subject}"
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
def invalid_signup_notification(collection_id, invalid_signup_ids, email)
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
@invalid_signups = invalid_signup_ids
|
||
|
|
@is_collection_email = (email == @collection.collection_email)
|
||
|
|
mail(
|
||
|
|
to: email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# This is sent at the end of matching, i.e., after assignments are generated.
|
||
|
|
# It is also sent when assignments are regenerated.
|
||
|
|
def potential_match_generation_notification(collection_id, email)
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
@is_collection_email = (email == @collection.collection_email)
|
||
|
|
mail(
|
||
|
|
to: email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
def challenge_assignment_notification(collection_id, assigned_user_id, assignment_id)
|
||
|
|
@collection = Collection.find(collection_id)
|
||
|
|
@assigned_user = User.find(assigned_user_id)
|
||
|
|
@assignment = ChallengeAssignment.find(assignment_id)
|
||
|
|
@request = @assignment.request_signup
|
||
|
|
mail(
|
||
|
|
to: @assigned_user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Asks a user to validate and activate their new account
|
||
|
|
def signup_notification(user_id)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
I18n.with_locale(@user.preference.locale_for_mails) do
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: t("user_mailer.signup_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
# Confirms to a user that their email was changed
|
||
|
|
def change_email(user_id, old_email, new_email)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@old_email = old_email
|
||
|
|
@new_email = new_email
|
||
|
|
@pac_footer = true
|
||
|
|
mail(
|
||
|
|
to: @old_email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
def change_username(user, old_username)
|
||
|
|
@user = user
|
||
|
|
@old_username = old_username
|
||
|
|
@new_username = user.login
|
||
|
|
@next_change_time = user.renamed_at + ArchiveConfig.USER_RENAME_LIMIT_DAYS.days
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
### WORKS NOTIFICATIONS ###
|
||
|
|
|
||
|
|
# Sends email when an archivist adds someone as a co-creator.
|
||
|
|
def creatorship_notification_archivist(creatorship_id, archivist_id)
|
||
|
|
@creatorship = Creatorship.find(creatorship_id)
|
||
|
|
@archivist = User.find(archivist_id)
|
||
|
|
@user = @creatorship.pseud.user
|
||
|
|
@creation = @creatorship.creation
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: t("user_mailer.creatorship_notification_archivist.subject",
|
||
|
|
app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends email when a user is added as a co-creator
|
||
|
|
def creatorship_notification(creatorship_id, adding_user_id)
|
||
|
|
@creatorship = Creatorship.find(creatorship_id)
|
||
|
|
@adding_user = User.find(adding_user_id)
|
||
|
|
@user = @creatorship.pseud.user
|
||
|
|
@creation = @creatorship.creation
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: t("user_mailer.creatorship_notification.subject",
|
||
|
|
app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends email when a user is added as an unapproved/pending co-creator
|
||
|
|
def creatorship_request(creatorship_id, inviting_user_id)
|
||
|
|
@creatorship = Creatorship.find(creatorship_id)
|
||
|
|
@inviting_user = User.find(inviting_user_id)
|
||
|
|
@user = @creatorship.pseud.user
|
||
|
|
@creation = @creatorship.creation
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: t("user_mailer.creatorship_request.subject",
|
||
|
|
app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends emails to creators whose stories were listed as the inspiration of another work
|
||
|
|
def related_work_notification(user_id, related_work_id)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@related_work = RelatedWork.find(related_work_id)
|
||
|
|
@related_parent_link = url_for(controller: :works, action: :show, id: @related_work.parent)
|
||
|
|
@related_child_link = url_for(controller: :works, action: :show, id: @related_work.work)
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Emails a recipient to say that a gift has been posted for them
|
||
|
|
def recipient_notification(user_id, work_id, collection_id = nil)
|
||
|
|
@user = User.find(user_id)
|
||
|
|
@work = Work.find(work_id)
|
||
|
|
@collection = Collection.find(collection_id) if collection_id
|
||
|
|
subject = if @collection
|
||
|
|
t("user_mailer.recipient_notification.subject.collection",
|
||
|
|
app_name: ArchiveConfig.APP_SHORT_NAME,
|
||
|
|
collection_title: @collection.title)
|
||
|
|
else
|
||
|
|
t("user_mailer.recipient_notification.subject.no_collection",
|
||
|
|
app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
end
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: subject
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Emails a prompter to say that a response has been posted to their prompt
|
||
|
|
def prompter_notification(work_id, collection_id = nil)
|
||
|
|
@work = Work.find(work_id)
|
||
|
|
@collection = Collection.find(collection_id) if collection_id
|
||
|
|
@work.challenge_claims.each do |claim|
|
||
|
|
user = User.find(claim.request_signup.pseud.user.id)
|
||
|
|
I18n.with_locale(user.preference.locale_for_mails) do
|
||
|
|
mail(
|
||
|
|
to: user.email,
|
||
|
|
subject: "[#{ArchiveConfig.APP_SHORT_NAME}] A response to your prompt"
|
||
|
|
)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends email to creators when a creation is deleted
|
||
|
|
# NOTE: this must be sent synchronously! otherwise the work will no longer be there to send
|
||
|
|
# TODO refactor to make it asynchronous by passing the content in the method
|
||
|
|
def delete_work_notification(user, work, deleter)
|
||
|
|
@user = user
|
||
|
|
@work = work
|
||
|
|
@deleter = deleter
|
||
|
|
download = Download.new(@work, mime_type: "text/html", include_draft_chapters: true)
|
||
|
|
html = DownloadWriter.new(download).generate_html
|
||
|
|
html = ::Mail::Encodings::Base64.encode(html)
|
||
|
|
attachments["#{download.file_name}.html"] = { content: html, encoding: "base64" }
|
||
|
|
attachments["#{download.file_name}.txt"] = { content: html, encoding: "base64" }
|
||
|
|
|
||
|
|
mail(
|
||
|
|
to: user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends email to creators when a creation is deleted by an admin
|
||
|
|
# NOTE: this must be sent synchronously! otherwise the work will no longer be there to send
|
||
|
|
# TODO refactor to make it asynchronous by passing the content in the method
|
||
|
|
def admin_deleted_work_notification(user, work)
|
||
|
|
@user = user
|
||
|
|
@work = work
|
||
|
|
download = Download.new(@work, mime_type: "text/html", include_draft_chapters: true)
|
||
|
|
html = DownloadWriter.new(download).generate_html
|
||
|
|
html = ::Mail::Encodings::Base64.encode(html)
|
||
|
|
attachments["#{download.file_name}.html"] = { content: html, encoding: "base64" }
|
||
|
|
attachments["#{download.file_name}.txt"] = { content: html, encoding: "base64" }
|
||
|
|
|
||
|
|
mail(
|
||
|
|
to: user.email,
|
||
|
|
subject: t("user_mailer.admin_deleted_work_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Sends email to creators when a creation is hidden by an admin
|
||
|
|
def admin_hidden_work_notification(creation_ids, user_id)
|
||
|
|
@pac_footer = true
|
||
|
|
@user = User.find_by(id: user_id)
|
||
|
|
@works = Work.where(id: creation_ids)
|
||
|
|
return if @works.empty?
|
||
|
|
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, count: @works.size)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
def admin_spam_work_notification(creation_id, user_id)
|
||
|
|
@user = User.find_by(id: user_id)
|
||
|
|
@work = Work.find_by(id: creation_id)
|
||
|
|
|
||
|
|
mail(
|
||
|
|
to: @user.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME)
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
### OTHER NOTIFICATIONS ###
|
||
|
|
|
||
|
|
# archive feedback
|
||
|
|
def feedback(feedback_id)
|
||
|
|
feedback = Feedback.find(feedback_id)
|
||
|
|
return unless feedback.email
|
||
|
|
|
||
|
|
@summary = feedback.summary
|
||
|
|
@comment = feedback.comment
|
||
|
|
@username = feedback.username if feedback.username.present?
|
||
|
|
@language = feedback.language
|
||
|
|
mail(
|
||
|
|
to: feedback.email,
|
||
|
|
subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, summary: strip_html_breaks_simple(feedback.summary))
|
||
|
|
)
|
||
|
|
end
|
||
|
|
|
||
|
|
def abuse_report(abuse_report_id)
|
||
|
|
abuse_report = AbuseReport.find(abuse_report_id)
|
||
|
|
@username = abuse_report.username
|
||
|
|
@email = abuse_report.email
|
||
|
|
@url = abuse_report.url
|
||
|
|
@summary = abuse_report.summary
|
||
|
|
@comment = abuse_report.comment
|
||
|
|
mail(
|
||
|
|
to: abuse_report.email,
|
||
|
|
subject: t("user_mailer.abuse_report.subject", app_name: ArchiveConfig.APP_SHORT_NAME, summary: strip_html_breaks_simple(@summary))
|
||
|
|
)
|
||
|
|
end
|
||
|
|
end
|