7 class Error < StandardError; end
11 bool_reader :usual, :archived, :read, :dirty
12 attr_accessor :id, :labels
14 ## end_offset is the last offsets within the file which we've read.
15 ## everything after that is considered new messages that haven't
17 def initialize filename, end_offset=0, usual=true, archived=false, id=nil
18 @filename = filename.gsub(%r(^mbox://), "")
19 @end_offset = end_offset
25 @f = File.open @filename
28 archived ? nil : :inbox,
30 if File.dirname(filename) =~ /\b(var|usr|spool)\b/
33 [File.basename(filename).intern]
38 @end_offset = [offset, File.size(@f) - 1].min;
41 def reset!; seek_to! 0; end
42 def == o; o.is_a?(Loader) && o.filename == filename; end
43 def to_s; "mbox://#{@filename}"; end
46 @filename == s || self.to_s == s
49 def load_header offset=nil
52 @f.seek offset if offset
53 header = MBox::read_header @f
58 def load_message offset
62 RMail::Mailbox::MBoxReader.new(@f).each_message do |input|
63 return RMail::Parser.read(input)
72 until @f.eof? || (l = @f.gets) =~ /^$/
79 def raw_full_message offset
83 @f.gets # skip mbox header
84 until @f.eof? || (l = @f.gets) =~ BREAK_RE
94 next_end_offset = @end_offset
99 @f.gets # skip the From separator
100 next_end_offset = @f.tell
101 while(line = @f.gets)
102 break if line =~ BREAK_RE
103 next_end_offset = @f.tell
107 start_offset = @end_offset
108 @end_offset = next_end_offset
114 until @end_offset >= File.size(@f)
116 yield(n, labels) if n
121 each { |offset, labels| yield offset, labels, load_header(offset) }
124 def done?; @end_offset >= File.size(@f); end
125 def total; File.size @f; end
128 Redwood::register_yaml(Loader, %w(filename end_offset usual archived id))