8 HookManager.register "before-add-message", <<EOS
9 Executes immediately before a message is added to the index.
11 message: the new message
14 HookManager.register "after-add-message", <<EOS
15 Executes after all messages are added to the index.
17 messages: an array of the new messages added
20 HookManager.register "before-poll", <<EOS
21 Executes immediately before a poll for new messages commences.
25 HookManager.register "after-poll", <<EOS
26 Executes immediately after a poll for new messages completes.
28 num: the total number of new messages added in this poll
29 num_inbox: the number of new messages added in this poll which
30 appear in the inbox (i.e. were not auto-archived).
31 num_inbox_total_unread: the total number of unread messages in the inbox
32 from_and_subj: an array of (from email address, subject) pairs
33 from_and_subj_inbox: an array of (from email address, subject) pairs for
34 only those messages appearing in the inbox
50 @mode ||= PollMode.new
51 HookManager.run "before-poll"
53 BufferManager.flash "Polling for new messages..."
54 num, numi, from_and_subj, from_and_subj_inbox = @mode.poll
56 BufferManager.flash "Loaded #{num.pluralize 'new message'}, #{numi} to inbox."
58 BufferManager.flash "No new messages."
61 HookManager.run "after-poll", :num => num, :num_inbox => numi, :from_and_subj => from_and_subj, :from_and_subj_inbox => from_and_subj_inbox, :num_inbox_total_unread => lambda { Index.num_results_for :labels => [:inbox, :unread] }
68 @thread = Redwood::reporting_thread("periodic poll") do
71 poll if @last_poll.nil? || (Time.now - @last_poll) >= DELAY
77 @thread.kill if @thread
82 total_num = total_numi = 0
84 from_and_subj_inbox = []
87 SourceManager.usual_sources.each do |source|
88 # yield "source #{source} is done? #{source.done?} (cur_offset #{source.cur_offset} >= #{source.end_offset})"
90 yield "Loading from #{source}... " unless source.done? || (source.respond_to?(:has_errors?) && source.has_errors?)
91 rescue SourceError => e
92 warn "problem getting messages from #{source}: #{e.message}"
93 Redwood::report_broken_sources :force_to_top => true
99 each_message_from source do |m|
100 yield "Found message at #{m.source_info} with labels {#{m.labels.to_a * ', '}}"
101 old_m = Index.build_message m.id
103 if old_m.source.id != source.id || old_m.source_info != m.source_info
104 ## here we merge labels between new and old versions, but we don't let the new
105 ## message add :unread or :inbox labels. (they can exist in the old version,
106 ## just not be added.)
107 new_labels = old_m.labels + (m.labels - [:unread, :inbox])
108 yield "Message at #{m.source_info} is an updated of an old message. Updating labels from #{m.labels.to_a * ','} => #{new_labels.to_a * ','}"
109 m.labels = new_labels
110 Index.update_message m
112 yield "Skipping already-imported message at #{m.source_info}"
115 yield "Found new message at #{m.source_info} with labels #{m.labels.to_a * ','}"
118 from_and_subj << [m.from && m.from.longname, m.subj]
119 if (m.labels & [:inbox, :spam, :deleted, :killed]) == Set.new([:inbox])
120 from_and_subj_inbox << [m.from && m.from.longname, m.subj]
126 yield "Found #{num} messages, #{numi} to inbox." unless num == 0
131 yield "Done polling; loaded #{total_num} new messages total"
132 @last_poll = Time.now
135 [total_num, total_numi, from_and_subj, from_and_subj_inbox]
138 ## like Source#each, but yields successive Message objects, which have their
139 ## labels and offsets set correctly.
141 ## this is the primary mechanism for iterating over messages from a source.
142 def each_message_from source, opts={}
144 return if source.done? || source.has_errors?
147 source.each do |offset, source_labels|
148 if source.has_errors?
149 warn "error loading messages from #{source}: #{source.error.message}"
153 m = Message.build_from_source source, offset
154 m.labels += source_labels + (source.archived? ? [] : [:inbox])
155 m.labels.delete :unread if m.source_marked_read? # preserve read status if possible
156 m.labels.each { |l| LabelManager << l }
159 HookManager.run "before-add-message", :message => m
162 HookManager.run "after-add-message", :messages => messages
164 rescue SourceError => e
165 warn "problem getting messages from #{source}: #{e.message}"
166 Redwood::report_broken_sources :force_to_top => true
170 ## TODO: see if we can do this within PollMode rather than by calling this
173 ## a wrapper around Index.add_message that calls the proper hooks,
174 ## does the gui callback stuff, etc.
175 def add_new_message m
177 UpdateManager.relay self, :added, m