]> git.cworth.org Git - sup/blob - lib/sup/source.rb
0f91cde24845a064a7493fb99415c2329188800d
[sup] / lib / sup / source.rb
1 module Redwood
2
3 class SourceError < StandardError; end
4
5 class Source
6   ## dirty? described whether cur_offset has changed, which means the
7   ## source needs to be re-saved to disk.
8   ##
9   ## broken? means no message can be loaded, e.g. IMAP server is
10   ## down, mbox file is corrupt and needs to be rescanned.
11
12   ## When writing a new source, you should implement:
13   ##
14   ## start_offset
15   ## end_offset
16   ## load_header(offset)
17   ## load_message(offset)
18   ## raw_header(offset)
19   ## raw_full_message(offset)
20   ## next (or each, if you prefer)
21
22   ## you can throw SourceErrors from any of those, but we don't catch
23   ## anything else, so make sure you catch all non-fatal errors and
24   ## reraise them as source errors.
25
26   bool_reader :usual, :archived, :dirty
27   attr_reader :cur_offset, :broken_msg
28   attr_accessor :id
29
30   def initialize uri, initial_offset=nil, usual=true, archived=false, id=nil
31     @uri = uri
32     @cur_offset = initial_offset
33     @usual = usual
34     @archived = archived
35     @id = id
36     @dirty = false
37     @broken_msg = nil
38   end
39
40   def broken?; !@broken_msg.nil?; end
41   def to_s; @uri; end
42   def seek_to! o; self.cur_offset = o; end
43   def reset!
44     return if broken?
45     begin
46       seek_to! start_offset
47     rescue SourceError
48     end
49   end
50   def == o; o.to_s == to_s; end
51   def done?;
52     return true if broken? 
53     begin
54       (self.cur_offset ||= start_offset) >= end_offset
55     rescue SourceError => e
56       true
57     end
58   end
59   def is_source_for? s; to_s == s; end
60
61   def each
62     begin
63       self.cur_offset ||= start_offset
64       until done? || broken? # just like life!
65         n, labels = self.next
66         raise "no message" unless n
67         yield n, labels
68       end
69     rescue SourceError
70       # just die
71     end
72   end
73
74 protected
75   
76   def cur_offset= o
77     @cur_offset = o
78     @dirty = true
79   end
80
81   def broken_msg= m
82     @broken_msg = m
83     Redwood::log "#{to_s}: #{m}"
84   end
85 end
86
87 Redwood::register_yaml(Source, %w(uri cur_offset usual archived id))
88
89 end