cirandas.net

ref: master

app/models/person_notifier.rb


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# FIXME needed by test/units/application_helper.rb
require_dependency 'application_helper'

class PersonNotifier

  def initialize(person)
    @person = person
  end

  def self.schedule_all_next_notification_mail
    Delayed::Job.enqueue(NotifyAllJob.new) unless NotifyAllJob.exists?
  end

  def schedule_next_notification_mail
    dispatch_notification_mail if !NotifyJob.exists?(@person.id)
  end

  def dispatch_notification_mail
    Delayed::Job.enqueue(NotifyJob.new(@person.id), {:run_at => @person.notification_time.hours.from_now}) if @person.notification_time>0
  end

  def reschedule_next_notification_mail
    return nil unless @person.setting_changed?(:notification_time) || @person.setting_changed?(:last_notification)
    NotifyJob.find(@person.id).delete_all
    schedule_next_notification_mail
  end

  def notify_from
    @person.last_notification || DateTime.now - @person.notification_time.hours
  end

  def notify
    if @person.notification_time && @person.notification_time > 0
      notifications = @person.tracked_notifications.where("created_at > ?", notify_from)
      tasks = Task.to(@person).without_spam.pending.where("created_at > ?", notify_from).order_by('created_at', 'asc')

      Noosfero.with_locale @person.environment.default_language do
        Mailer::content_summary(@person, notifications, tasks).deliver unless notifications.empty? && tasks.empty?
      end
      @person.settings[:last_notification] = DateTime.now
      @person.save!
    end
  end

  class NotifyAllJob
    def self.exists?
      Delayed::Job.by_handler("--- !ruby/object:PersonNotifier::NotifyAllJob {}\n").count > 0
    end

    def perform
      Person.find_each {|person| person.notifier.schedule_next_notification_mail }
    end
  end

  class NotifyJob < Struct.new(:person_id)

    def self.exists?(person_id)
      !find(person_id).empty?
    end

    def self.find(person_id)
      Delayed::Job.by_handler("--- !ruby/struct:PersonNotifier::NotifyJob\nperson_id: #{person_id}\n")
    end

    def perform
      Person.find(person_id).notifier.notify
    end

    def failure(job)
      person = Person.find(person_id)
      person.notifier.dispatch_notification_mail
    end

  end

  class Mailer < ApplicationMailer

    helper ActionTrackerHelper
    helper do
      def render_activity(activity)
        begin
          render activity.verb, activity: activity
        rescue => error
          Delayed::Worker.logger.warn "PersonNotifier::NotifyJob: Cannot "\
                                      "render template for #{activity.verb} "\
                                      "notification: #{error}"
        end
      end
    end

    def session
      {:user_theme => nil}
    end

    def content_summary(person, notifications, tasks)
      if person.environment
        ApplicationMailer.asset_host = person.environment.top_url
        ApplicationMailer.default_url_options[:host] = person.environment.default_hostname
      end

      @current_theme = 'default'
      @profile = person
      @recipient = @profile.nickname || @profile.name
      @notifications = notifications
      @tasks = tasks
      @environment = @profile.environment
      @url = @profile.environment.top_url
      mail(
        content_type: "text/html",
        from: "#{@profile.environment.name} <#{@profile.environment.noreply_email}>",
        to: @profile.email,
        subject: _("[%s] Notifications") % [@profile.environment.name]
      )
    end
  end
end