aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve/notifier.rb
blob: 35ac019a9c60df2b54e75f20a30b4a875e2aa079 (plain)
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
117
118
119
120
121
122
123
124
125
126
127
128
require 'mauve/mauve_thread'
require 'mauve/notifiers'
require 'mauve/notifiers/xmpp'

module Mauve

  # The Notifier is reponsible for popping notifications off the
  # notification_buffer run by the Mauve::Server instance.  This ensures that
  # notifications are sent in a separate thread to the main processing /
  # updating threads, and stops notifications delaying updates.
  #
  #
  class Notifier < MauveThread
    
    include Singleton

    # Stop the notifier thread.  This just makes sure that all the
    # notifications in the buffer have been sent before closing the XMPP
    # connection.
    #
    def stop
      super

      #
      # Flush the queue.
      #
      main_loop

      if Configuration.current.notification_methods['xmpp']
        Configuration.current.notification_methods['xmpp'].close
      end

    end
    
    #
    # This sends the notification for an alert
    #
    def notify(alert, at)
      #
      # Make sure we're looking at a fresh copy of the alert.
      #
      alert.reload

      #
      # Forces alert-group to be re-evaluated on notification.
      #
      alert.cached_alert_group = nil
      this_alert_group = alert.alert_group

      #
      # This saves without callbacks if the cached_alert_group has been
      # altered.
      #
      alert.save! if alert.dirty?

      if this_alert_group.nil?
        logger.warn "Could not notify for #{alert} since there are no matching alert groups"

      else
        this_alert_group.notify(alert, at)

      end
    end


    private

    # This is the main loop that is executed in the thread.
    #
    #
    def main_loop

      #
      # Make sure we're connected to the XMPP server if needed on every iteration.
      #
      xmpp = Configuration.current.notification_methods['xmpp']

      if xmpp and !xmpp.ready?
        #
        # Connect to XMPP server
        #
        xmpp.connect 

        #
        # Join all chats and shit.  Unless the connection failed.
        #
        Configuration.current.people.each do |username, person|
          # 
          # Ignore people without XMPP stanzas.
          #
          next unless person.respond_to?(:xmpp) and person.xmpp 

          #
          # For each JID, either ensure they're on our roster, or that we're in
          # that chat room.
          #
          jid = if xmpp.is_muc?(person.xmpp)
            xmpp.join_muc(person.xmpp)
          else
            xmpp.ensure_roster_and_subscription!(person.xmpp)
          end

          Configuration.current.people[username].xmpp = jid unless jid.nil?

        end if xmpp.ready?

      end

      # 
      # Cycle through the buffer.
      #
      sz = Server.notification_buffer_size

      logger.info "Sending #{sz} alerts" if sz > 0

      #
      # Empty the buffer, one notification at a time.
      #
      sz.times do
        notify(*Server.notification_pop)
      end
    end

  end

end