commit 336fd01936b3c3297e575c05add1e7a7991bef9d
parent 856c0ebb8845f0658e056c889390f2c7086b35e2
Author: Rich Lane <rlane@club.cc.cmu.edu>
Date: Tue, 30 Mar 2010 23:25:29 -0700
turn each_message_from into poll_from
Diffstat:
4 files changed, 30 insertions(+), 54 deletions(-)
diff --git a/bin/sup-sync b/bin/sup-sync
@@ -114,15 +114,13 @@ begin
num_added = num_updated = num_scanned = num_restored = 0
last_info_time = start_time = Time.now
- Redwood::PollManager.each_message_from source do |action,m|
+ Redwood::PollManager.poll_from source do |action,m,old_m|
if action == :delete
puts "Deleting #{m.id}"
- next
- end
+ else
num_scanned += 1
seen[m.id] = true
- old_m = index.build_message m.id
## tweak source labels according to commandline arguments if necessary
m.labels.delete :inbox if opts[:archive]
@@ -130,11 +128,12 @@ begin
m.labels += opts[:extra_labels].to_set_of_symbols(",")
## decide what to do based on message labels and the operation we're performing
- dothis, new_labels = case
+ dothis = case
when (op == :restore) && restored_state[m.id]
if old_m && (old_m.labels != restored_state[m.id])
num_restored += 1
- [:update_message_state, restored_state[m.id]]
+ m.labels = restored_state[m.id]
+ :update_message_state
elsif old_m.nil?
num_restored += 1
m.labels = restored_state[m.id]
@@ -144,40 +143,28 @@ begin
end
when op == :discard
if old_m && (old_m.labels != m.labels)
- [:update_message_state, m.labels]
+ :update_message_state
else
# labels are the same; don't do anything
end
else
- ## duplicate behavior of poll mode: if index_state is non-nil, this is a newer
- ## version of an older message, so merge in any new labels except :unread and
- ## :inbox.
- ##
- ## TODO: refactor such that this isn't duplicated
if old_m
- m.labels = old_m.labels + (m.labels - [:unread, :inbox])
:update_message
else
:add_message
end
end
- m.locations = old_m.locations + m.locations if old_m
-
## now, actually do the operation
case dothis
when :add_message
puts "Adding new message #{source}##{m.source_info} with labels #{m.labels}" if opts[:verbose]
- index.add_message m unless opts[:dry_run]
num_added += 1
when :update_message
puts "Updating message #{source}##{m.source_info}; labels #{old_m.labels} => #{m.labels}; offset #{old_m.source_info} => #{m.source_info}" if opts[:verbose]
- index.update_message m unless opts[:dry_run]
num_updated += 1
when :update_message_state
- puts "Changing flags for #{source}##{m.source_info} from #{m.labels} to #{new_labels}" if opts[:verbose]
- m.labels = new_labels
- index.update_message_state m unless opts[:dry_run]
+ puts "Changing flags for #{source}##{m.source_info} from #{old_m.labels} to #{m.labels}" if opts[:verbose]
num_updated += 1
end
@@ -188,6 +175,9 @@ begin
remaining = (100.0 - pctdone) * (elapsed.to_f / pctdone)
printf "## read %dm (~%.0f%%) @ %.1fm/s. %s elapsed, ~%s remaining\n", num_scanned, pctdone, num_scanned / elapsed, elapsed.to_time_s, remaining.to_time_s
end
+
+ end
+ next if opts[:dry_run]
end
puts "Scanned #{num_scanned}, added #{num_added}, updated #{num_updated} messages from #{source}."
diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
@@ -103,7 +103,7 @@ class Maildir < Source
added.each do |id|
yield :add,
:info => File.join(d,id),
- :labels => @labels + maildir_labels(id),
+ :labels => @labels + maildir_labels(id) + [:inbox],
:progress => 0.0
end
diff --git a/lib/sup/mbox.rb b/lib/sup/mbox.rb
@@ -127,7 +127,7 @@ class MBox < Source
while offset and offset < end_offset
yield :add,
:info => offset,
- :labels => (labels + [:unread]),
+ :labels => (labels + [:inbox, :unread]),
:progress => 0.0
offset = next_offset offset
end
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
@@ -112,29 +112,18 @@ EOS
num = 0
numi = 0
- each_message_from source do |action,m|
+ poll_from source do |action,m,old_m|
if action == :delete
yield "Deleting #{m.id}"
- next
- end
-
- old_m = Index.build_message m.id
+ else
if old_m
if not old_m.locations.member? [source, m.source_info]
- ## here we merge labels between new and old versions, but we don't let the new
- ## message add :unread or :inbox labels. (they can exist in the old version,
- ## just not be added.)
- new_labels = old_m.labels + (m.labels - [:unread, :inbox])
- yield "Message at #{m.source_info} is an updated of an old message. Updating labels from #{m.labels.to_a * ','} => #{new_labels.to_a * ','}"
- m.labels = new_labels
- m.locations = old_m.locations + m.locations
- Index.update_message m
+ yield "Message at #{m.source_info} is an updated of an old message. Updating labels from #{old_m.labels.to_a * ','} => #{m.labels.to_a * ','}"
else
yield "Skipping already-imported message at #{m.source_info}"
end
else
yield "Found new message at #{m.source_info} with labels #{m.labels.to_a * ','}"
- add_new_message m
loaded_labels.merge m.labels
num += 1
from_and_subj << [m.from && m.from.longname, m.subj]
@@ -143,7 +132,7 @@ EOS
numi += 1
end
end
- m
+ end
end
yield "Found #{num} messages, #{numi} to inbox." unless num == 0
total_num += num
@@ -158,11 +147,10 @@ EOS
[total_num, total_numi, from_and_subj, from_and_subj_inbox, loaded_labels]
end
- ## like Source#each, but yields successive Message objects, which have their
- ## labels and offsets set correctly.
- ##
- ## this is the primary mechanism for iterating over messages from a source.
- def each_message_from source, opts={}
+ ## like Source#poll, but yields successive Message objects, which have their
+ ## labels and locations set correctly. The Messages are saved to or removed
+ ## from the index after being yielded.
+ def poll_from source, opts={}
begin
return if source.has_errors?
@@ -175,15 +163,23 @@ EOS
case sym
when :add
m = Message.build_from_source source, args[:info]
+ old_m = Index.build_message m.id
m.labels += args[:labels]
m.labels.delete :unread if source.read?
m.labels.delete :unread if m.source_marked_read? # preserve read status if possible
m.labels.each { |l| LabelManager << l }
+ m.labels = old_m.labels + (m.labels - [:unread, :inbox]) if old_m
+ m.locations = old_m.locations + m.locations if old_m
HookManager.run "before-add-message", :message => m
- yield :add, m
+ yield :add, m, old_m if block_given?
+ Index.sync_message m, true
+ UpdateManager.relay self, :added, m
when :delete
Index.each_message :location => [source.id, args[:info]] do |m|
- yield :delete, m
+ m.locations.delete [source,args[:info]]
+ yield :delete, m, [source,args[:info]] if block_given?
+ Index.sync_message m, false
+ UpdateManager.relay self, :deleted, m
end
end
end
@@ -202,16 +198,6 @@ EOS
end
end
- ## TODO: see if we can do this within PollMode rather than by calling this
- ## method.
- ##
- ## a wrapper around Index.add_message that calls the proper hooks,
- ## does the gui callback stuff, etc.
- def add_new_message m
- Index.add_message m
- UpdateManager.relay self, :added, m
- end
-
def handle_idle_update sender, idle_since; @should_clear_running_totals = false; end
def handle_unidle_update sender, idle_since; @should_clear_running_totals = true; clear_running_totals; end
def clear_running_totals; @running_totals = {:num => 0, :numi => 0, :loaded_labels => Set.new}; end