class Float
def to_s; sprintf '%.2f', self; end
+ def to_time_s
+ infinite? ? "unknown" : super
+ end
end
class Numeric
sup-sync [options] <source>*
where <source>* is zero or more source URIs. If no sources are given,
-sync from all usual sources. All supported source URI schemes can
-be seen by running "sup-add --help".
+sync from all usual sources. Supported source URI schemes can be seen
+by running "sup-add --help".
Options controlling WHICH messages sup-sync operates on:
EOS
Redwood::start
index = Redwood::Index.new
-index.load
restored_state =
if opts[:restore]
{}
end
-sources = ARGV.map do |uri|
- index.source_for uri or Trollop::die "Unknown source: #{uri}. Did you add it with sup-add first?"
-end
-
-sources = index.usual_sources if sources.empty?
-sources = index.sources if opts[:all_sources]
-
seen = {}
+index.lock_or_die
begin
+ index.load
+
+ sources = ARGV.map do |uri|
+ index.source_for uri or Trollop::die "Unknown source: #{uri}. Did you add it with sup-add first?"
+ end
+
+ sources = index.usual_sources if sources.empty?
+ sources = index.sources if opts[:all_sources]
+
unless target == :new
if opts[:start_at]
sources.each { |s| s.seek_to! opts[:start_at] }
## skip if we're operating on restored messages, and this one
## ain't.
- next if target == :restored && (!restored_state[m.id] || restored_state[m.id].sort_by { |s| s.to_s } == index_state.sort_by { |s| s.to_s })
+ next if target == :restored && (!restored_state[m.id] || (index_state && restored_state[m.id].sort_by { |s| s.to_s } == index_state.sort_by { |s| s.to_s }))
## m.labels is the default source labels. tweak these according
## to default source state modification flags.
elapsed = last_info_time - start_time
pctdone = source.respond_to?(:pct_done) ? source.pct_done : 100.0 * (source.cur_offset.to_f - source.start_offset).to_f / (source.end_offset - source.start_offset).to_f
remaining = (100.0 - pctdone) * (elapsed.to_f / pctdone)
- $stderr.puts "## #{num_added + num_updated} (#{pctdone}% done) read; #{elapsed.to_time_s} elapsed; est. #{remaining.to_time_s} remaining (for this source)"
+ $stderr.puts "## #{num_scanned} (#{pctdone}%) read; #{elapsed.to_time_s} elapsed; #{remaining.to_time_s} remaining"
end
if index_state.nil?
$stderr.puts "Scanned #{num_scanned}, added #{num_added}, updated #{num_updated} messages from #{source}."
$stderr.puts "Restored state on #{num_restored} (#{100.0 * num_restored / num_scanned}%) messages." if num_restored > 0
end
-rescue Exception => e
- File.open("sup-exception-log.txt", "w") { |f| f.puts e.backtrace }
- raise
-ensure
- index.save
- Redwood::finish
-end
-## delete any messages in the index that claim they're from one of
-## these sources, but that we didn't see.
-##
-## kinda crappy code here, because we delve directly into the Ferret
-## API.
-##
-## TODO: move this to Index, i suppose.
-if target == :all || target == :changed
- $stderr.puts "Deleting missing messages from the index..."
- num_del, num_scanned = 0, 0
- sources.each do |source|
- raise "no source id for #{source}" unless source.id
- q = "+source_id:#{source.id}"
- q += " +source_info: >= #{opts[:start_at]}" if opts[:start_at]
- index.index.search_each(q, :limit => :all) do |docid, score|
- num_scanned += 1
- mid = index.index[docid][:message_id]
- unless seen[mid]
- puts "Deleting #{mid}" if opts[:verbose]
- index.index.delete docid unless opts[:dry_run]
- num_del += 1
+ ## delete any messages in the index that claim they're from one of
+ ## these sources, but that we didn't see.
+ ##
+ ## kinda crappy code here, because we delve directly into the Ferret
+ ## API.
+ ##
+ ## TODO: move this to Index, i suppose.
+
+
+ if target == :all || target == :changed
+ $stderr.puts "Deleting missing messages from the index..."
+ num_del, num_scanned = 0, 0
+ sources.each do |source|
+ raise "no source id for #{source}" unless source.id
+ q = "+source_id:#{source.id}"
+ q += " +source_info: >= #{opts[:start_at]}" if opts[:start_at]
+ index.index.search_each(q, :limit => :all) do |docid, score|
+ num_scanned += 1
+ mid = index.index[docid][:message_id]
+ unless seen[mid]
+ puts "Deleting #{mid}" if opts[:verbose]
+ index.index.delete docid unless opts[:dry_run]
+ num_del += 1
+ end
end
end
+ $stderr.puts "Deleted #{num_del} / #{num_scanned} messages"
end
- $stderr.puts "Deleted #{num_del} / #{num_scanned} messages"
-end
-if opts[:optimize]
- $stderr.puts "Optimizing index..."
- optt = time { index.index.optimize unless opts[:dry_run] }
- $stderr.puts "Optimized index of size #{index.size} in #{optt}s."
+ index.save
+
+ if opts[:optimize]
+ $stderr.puts "Optimizing index..."
+ optt = time { index.index.optimize unless opts[:dry_run] }
+ $stderr.puts "Optimized index of size #{index.size} in #{optt}s."
+ end
+rescue Redwood::FatalSourceError => e
+ $stderr.puts "Sorry, I couldn't communicate with a source: #{e.message}"
+rescue Exception => e
+ File.open("sup-exception-log.txt", "w") { |f| f.puts e.backtrace }
+ raise
+ensure
+ Redwood::finish
+ index.unlock
end