]> git.cworth.org Git - sup/blob - lib/sup/draft.rb
small gui improvements, mostly involving snippets
[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; 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 => @source, :source_info => offset, :labels => 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 < Source
40   attr_accessor :dir
41
42   def initialize cur_offset=0
43     dir = Redwood::DRAFT_DIR
44     Dir.mkdir dir unless File.exists? dir
45     super "draft://#{dir}", cur_offset, true, false
46     @dir = dir
47   end
48
49   def id; DraftManager.source_id; end
50   def to_s; DraftManager.source_name; end
51
52   def next
53     ret = nil
54     begin
55       ret = cur_offset
56       self.cur_offset = cur_offset + 1
57     end until File.exists? fn_for_offset(ret)
58     [ret, [:draft]]
59   end
60
61   def gen_offset
62     i = cur_offset
63     while File.exists? fn_for_offset(i)
64       i += 1
65     end
66     i
67   end
68
69   def fn_for_offset o; File.join(@dir, o.to_s); end
70
71   def load_header offset
72     File.open fn_for_offset(offset) do |f|
73       return MBox::read_header(f)
74     end
75   end
76   
77   def load_message offset
78     File.open fn_for_offset(offset) do |f|
79       RMail::Mailbox::MBoxReader.new(f).each_message do |input|
80         return RMail::Parser.read(input)
81       end
82     end
83   end
84
85   def raw_header offset
86     ret = ""
87     File.open fn_for_offset(offset) do |f|
88       until f.eof? || (l = f.gets) =~ /^$/
89         ret += l
90       end
91     end
92     ret
93   end
94
95   def raw_full_message offset
96     ret = ""
97     File.open fn_for_offset(offset) do |f|
98       ret += l until f.eof?
99     end
100     ret
101   end
102
103   def start_offset; 0; end
104   def end_offset; Dir.new(@dir).entries.sort.last.to_i + 1; end
105 end
106
107 Redwood::register_yaml(DraftLoader, %w(cur_offset))
108
109 end