6 def to_s; sprintf '%.2f', self; end
12 sprintf "%d:%02d:%02d", i / 3600, (i / 60) % 60, i % 60
24 Loads messages into the Sup index, adding sources as needed to the
28 sup-import [options] <source>*
29 where <source>* is zero or more source descriptions (e.g., mbox
32 If the sources listed are not already in the Sup source list,
33 they will be added to it, as parameterized by the following options:
34 --archive: messages from these sources will not appear in the inbox
35 --unusual: these sources will not be polled when the flag --the-usual
38 Regardless of whether the sources are new or not, they will be polled,
39 and any new messages will be added to the index, as parameterized by
40 the following options:
41 --force-archive: regardless of the source "archive" flag, any new
42 messages found will not appear in the inbox.
43 --force-read: any messages found will not be marked as new.
45 The following options can also be specified:
46 --the-usual: import new messages from all usual sources
47 --rebuild: rebuild the index for the specified sources rather than
48 just adding new messages. Useful if the sources
49 have changed in any way *other* than new messages
51 --force-rebuild: force a rebuild of all messages in the inbox, not just
52 ones that have changed. You probably won't need this
53 unless William changes the index format.
54 --optimize: optimize the index after adding any new messages.
55 --help: don't do anything, just show this message.
61 educate_user if ARGV.member? '--help'
63 archive = ARGV.delete "--archive"
64 unusual = ARGV.delete "--unusual"
65 force_archive = ARGV.delete "--force-archive"
66 force_read = ARGV.delete "--force-read"
67 the_usual = ARGV.delete "--the-usual"
68 rebuild = ARGV.delete "--rebuild"
69 force_rebuild = ARGV.delete "--force-rebuild"
70 optimize = ARGV.delete "--optimize"
72 if(o = ARGV.find { |x| x =~ /^--/ })
73 $stderr.puts "error: unknown option #{o}"
77 puts "loading index..."
78 index = Redwood::Index.new
81 puts "loaded index of #{index.size} messages"
83 sources = ARGV.map do |fn|
84 source = index.source_for fn
86 source = Redwood::MBox::Loader.new(fn, 0, !unusual, !!archive)
87 index.add_source source
91 sources = (sources + index.usual_sources).uniq if the_usual
92 sources.each { |s| s.reset! } if rebuild || force_rebuild
97 sources.each do |source|
99 puts "loading from #{source}... "
102 source.each do |offset, labels|
103 start_offset ||= offset
104 labels -= [:inbox] if force_archive
105 labels -= [:unread] if force_read
107 m = Redwood::Message.new source, offset, labels
109 puts "skipping duplicate message #{m.id}"
115 m.remove_label :unread if m.mbox_status == "RO" unless force_read
116 if (rebuild || force_rebuild) &&
117 (docid, entry = index.load_entry_for_id(m.id)) && entry
118 if force_rebuild || entry[:source_info].to_i != offset
119 puts "replacing message #{m.id} labels #{entry[:label].inspect} (offset #{entry[:source_info]} => #{offset})"
120 m.labels = entry[:label].split.map { |l| l.intern }
121 num += 1 if index.update_message m, source, offset
124 num += 1 if index.add_message m
126 rescue Redwood::MessageFormatError => e
127 $stderr.puts "ignoring erroneous message at #{source}##{offset}: #{e.message}"
129 if num % 1000 == 0 && num > 0
130 elapsed = Time.now - start
131 pctdone = (offset.to_f - start_offset) / (source.total.to_f - start_offset)
132 remaining = (source.total.to_f - offset.to_f) * (elapsed.to_f / (offset.to_f - start_offset))
133 puts "## #{num} (#{(pctdone * 100.0)}% done) read; #{elapsed.to_time_s} elapsed; est. #{remaining.to_time_s} remaining"
136 puts "loaded #{num} messages" unless num == 0
142 if rebuild || force_rebuild
143 puts "deleting missing messages from the index..."
145 sources.each do |source|
146 raise "no source id for #{source}" unless source.id
147 index.index.search_each("source_id:#{source.id}", :limit => :all) do |docid, score|
148 mid = index.index[docid][:message_id]
150 puts "deleting #{mid}"
151 index.index.delete docid
155 puts "deleted #{numdel} messages"
159 puts "optimizing index..."
160 optt = time { index.index.optimize }
161 puts "optimized index of size #{index.size} in #{optt}s."