]> git.cworth.org Git - sup/blob - lib/sup/draft.rb
'A' archives and kills buffer in thread-view-mode (required significant updatedes...
[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; "sup://drafts"; end
14   def self.source_id; 9999; end
15   def new_source; @source = DraftLoader.new; 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     my_message = nil
23     @source.each do |thisoffset, theselabels|
24       m = Message.new :source => @source, :source_info => thisoffset, :labels => theselabels
25       Index.add_message m
26       UpdateManager.relay self, :add, m
27       my_message = m if thisoffset == offset
28     end
29
30     my_message
31   end
32
33   def discard mid
34     docid, entry = Index.load_entry_for_id mid
35     raise ArgumentError, "can't find entry for draft: #{mid.inspect}" unless entry
36     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
37     Index.drop_entry docid
38     File.delete @source.fn_for_offset(entry[:source_info])
39     UpdateManager.relay self, :delete, mid
40   end
41 end
42
43 class DraftLoader < Source
44   attr_accessor :dir
45
46   def initialize cur_offset=0
47     dir = Redwood::DRAFT_DIR
48     Dir.mkdir dir unless File.exists? dir
49     super "draft://#{dir}", cur_offset, true, false
50     @dir = dir
51   end
52
53   def id; DraftManager.source_id; end
54   def to_s; DraftManager.source_name; end
55   def uri; DraftManager.source_name; end
56
57   def each
58     ids = get_ids
59     ids.each do |id|
60       if id >= cur_offset
61         self.cur_offset = id + 1
62         yield [id, [:draft, :inbox]]
63       end
64     end
65   end
66
67   def gen_offset
68     i = cur_offset
69     while File.exists? fn_for_offset(i)
70       i += 1
71     end
72     i
73   end
74
75   def fn_for_offset o; File.join(@dir, o.to_s); end
76
77   def load_header offset
78     File.open fn_for_offset(offset) do |f|
79       return MBox::read_header(f)
80     end
81   end
82   
83   def load_message offset
84     File.open fn_for_offset(offset) do |f|
85       RMail::Mailbox::MBoxReader.new(f).each_message do |input|
86         return RMail::Parser.read(input)
87       end
88     end
89   end
90
91   def raw_header offset
92     ret = ""
93     File.open fn_for_offset(offset) do |f|
94       until f.eof? || (l = f.gets) =~ /^$/
95         ret += l
96       end
97     end
98     ret
99   end
100
101   def raw_full_message offset
102     ret = ""
103     File.open fn_for_offset(offset) do |f|
104       ret += l until f.eof?
105     end
106     ret
107   end
108
109   def start_offset; 0; end
110   def end_offset
111     ids = get_ids
112     ids.empty? ? 0 : (ids.last + 1)
113   end
114
115 private
116
117   def get_ids
118     Dir.entries(@dir).select { |x| x =~ /^\d+$/ }.map { |x| x.to_i }.sort
119   end
120 end
121
122 Redwood::register_yaml(DraftLoader, %w(cur_offset))
123
124 end