]> git.notmuchmail.org Git - sup/blob - lib/sup/draft.rb
moved evertying to devel
[sup] / lib / sup / draft.rb
1 module Redwood
2
3 class DraftManager
4   include Singleton
5
6   attr_accessor :source
7   def initialize dir
8     @dir = dir
9     @source = nil
10     self.class.i_am_the_instance self
11   end
12
13   def self.source_name; "drafts"; end
14   def self.source_id; 9999; end
15   def new_source; @source = DraftLoader.new @dir; end
16
17   def write_draft
18     offset = @source.gen_offset
19     fn = @source.fn_for_offset offset
20     File.open(fn, "w") { |f| yield f }
21
22     @source.each do |offset, labels|
23       m = Message.new @source, offset, labels
24       Index.add_message m
25       UpdateManager.relay :add, m
26     end
27   end
28
29   def discard mid
30     docid, entry = Index.load_entry_for_id mid
31     raise ArgumentError, "can't find entry for draft: #{mid.inspect}" unless entry
32     raise ArgumentError, "not a draft: source id #{entry[:source_id].inspect}, should be #{DraftManager.source_id.inspect} for #{mid.inspect} / docno #{docid}" unless entry[:source_id].to_i == DraftManager.source_id
33     Index.drop_entry docid
34     File.delete @source.fn_for_offset(entry[:source_info])
35     UpdateManager.relay :delete, mid
36   end
37 end
38
39 class DraftLoader
40   attr_accessor :dir, :end_offset
41   bool_reader :dirty
42
43   def initialize dir, end_offset=0
44     Dir.mkdir dir unless File.exists? dir
45     @dir = dir
46     @end_offset = end_offset
47     @dirty = false
48   end
49
50   def done?; !File.exists? fn_for_offset(@end_offset); end
51   def usual?; true; end
52   def id; DraftManager.source_id; end
53   def to_s; DraftManager.source_name; end
54   def is_source_for? x; x == DraftManager.source_name; end
55
56   def gen_offset
57     i = @end_offset
58     while File.exists? fn_for_offset(i)
59       i += 1
60     end
61     i
62   end
63
64   def fn_for_offset o; File.join(@dir, o.to_s); end
65
66   def load_header offset
67     File.open fn_for_offset(offset) do |f|
68       return MBox::read_header(f)
69     end
70   end
71   
72   def load_message offset
73     File.open fn_for_offset(offset) do |f|
74       RMail::Mailbox::MBoxReader.new(f).each_message do |input|
75         return RMail::Parser.read(input)
76       end
77     end
78   end
79
80   ## load the full header text
81   def load_header_text offset
82     ret = ""
83     File.open fn_for_offset(offset) do |f|
84       until f.eof? || (l = f.gets) =~ /^$/
85         ret += l
86       end
87     end
88     ret
89   end
90
91   def each
92     while File.exists?(fn = File.join(@dir, @end_offset.to_s))
93       yield @end_offset, [:draft, :inbox]
94       @end_offset += 1
95       @dirty = true
96     end
97   end
98
99   def total; Dir[File.join(@dir, "*")].sort.last.to_i; end
100   def reset!; @end_offset = 0; @dirty = true; end
101 end
102
103 Redwood::register_yaml(DraftLoader, %w(dir end_offset))
104
105 end