bin/sup-import-dump (2984B) - raw
1 #!/usr/bin/env ruby
2
3 $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
5 require 'uri'
6 require 'optimist'
7 require "sup"
8
9 PROGRESS_UPDATE_INTERVAL = 15 # seconds
10
11 class AbortExecution < SystemExit
12 end
13
14 opts = Optimist::options do
15 version "sup-import-dump (sup #{Redwood::VERSION})"
16 banner <<EOS
17 Imports message state previously exported by sup-dump into the index.
18 sup-import-dump operates on the index only, so the messages must have already
19 been added using sup-sync. If you need to recreate the index, see sup-sync
20 --restore <filename> instead.
21
22 Messages not mentioned in the dump file will not be modified.
23
24 Usage:
25 sup-import-dump [options] <dump file>
26
27 Options:
28 EOS
29 opt :verbose, "Print message ids as they're processed."
30 opt :ignore_missing, "Silently skip over messages that are not in the index."
31 opt :warn_missing, "Warn about messages that are not in the index, but continue."
32 opt :abort_missing, "Abort on encountering messages that are not in the index. (default)"
33 opt :atomic, "Use transaction to apply all changes atomically."
34 opt :dry_run, "Don't actually modify the index. Probably only useful with --verbose.", :short => "-n"
35 opt :version, "Show version information", :short => :none
36
37 conflicts :ignore_missing, :warn_missing, :abort_missing
38 end
39 Optimist::die "No dump file given" if ARGV.empty?
40 Optimist::die "Extra arguments given" if ARGV.length > 1
41 dump_name = ARGV.shift
42 missing_action = [:ignore_missing, :warn_missing, :abort_missing].find { |x| opts[x] } || :abort_missing
43
44 Redwood::start
45 index = Redwood::Index.init
46
47 index.lock_interactively or exit
48 begin
49 num_read = 0
50 num_changed = 0
51 index.load
52 index.begin_transaction if opts[:atomic]
53
54 IO.foreach dump_name do |l|
55 l =~ /^(\S+) \((.*?)\)$/ or raise "Can't read dump line: #{l.inspect}"
56 mid, labels = $1, $2
57 num_read += 1
58
59 unless index.contains_id? mid
60 if missing_action == :abort_missing
61 $stderr.puts "Message #{mid} not found in index, aborting."
62 raise AbortExecution, 10
63 elsif missing_action == :warn_missing
64 $stderr.puts "Message #{mid} not found in index, skipping."
65 end
66
67 next
68 end
69
70 m = index.build_message mid
71 new_labels = labels.to_set_of_symbols
72
73 if m.labels == new_labels
74 puts "#{mid} unchanged" if opts[:verbose]
75 next
76 end
77
78 puts "Changing flags for #{mid} from '#{m.labels.to_a * ' '}' to '#{new_labels.to_a * ' '}'" if opts[:verbose]
79 num_changed += 1
80
81 next if opts[:dry_run]
82
83 m.labels = new_labels
84 index.update_message_state [m, false]
85 end
86
87 index.commit_transaction if opts[:atomic]
88 puts "Updated #{num_changed} of #{num_read} messages."
89 rescue AbortExecution
90 index.cancel_transaction if opts[:atomic]
91 raise
92 rescue Exception => e
93 index.cancel_transaction if opts[:atomic]
94 File.open("sup-exception-log.txt", "w") { |f| f.puts e.backtrace }
95 raise
96 ensure
97 index.save_index unless opts[:atomic]
98 Redwood::finish
99 index.unlock
100 end