]> git.cworth.org Git - sup/blob - lib/sup/draft.rb
Merge branch 'hook-local-vars'
[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   end
11
12   def self.source_name; "sup://drafts"; end
13   def self.source_id; 9999; end
14   def new_source; @source = Recoverable.new DraftLoader.new; end
15
16   def write_draft
17     offset = @source.gen_offset
18     fn = @source.fn_for_offset offset
19     File.open(fn, "w") { |f| yield f }
20
21     my_message = nil
22     PollManager.each_message_from(@source) do |m|
23       PollManager.add_new_message m
24       my_message = m
25     end
26
27     my_message
28   end
29
30   def discard m
31     raise ArgumentError, "not a draft: source id #{m.source.id.inspect}, should be #{DraftManager.source_id.inspect} for #{m.id.inspect}" unless m.source.id.to_i == DraftManager.source_id
32     Index.delete m.id
33     File.delete @source.fn_for_offset(m.source_info)
34     UpdateManager.relay self, :single_message_deleted, m
35   end
36 end
37
38 class DraftLoader < Source
39   attr_accessor :dir
40   yaml_properties :cur_offset
41
42   def initialize cur_offset=0
43     dir = Redwood::DRAFT_DIR
44     Dir.mkdir dir unless File.exists? dir
45     super DraftManager.source_name, 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   def uri; DraftManager.source_name; end
52
53   def each
54     ids = get_ids
55     ids.each do |id|
56       if id >= cur_offset
57         self.cur_offset = id + 1
58         yield [id, [:draft, :inbox]]
59       end
60     end
61   end
62
63   def gen_offset
64     i = cur_offset
65     while File.exists? fn_for_offset(i)
66       i += 1
67     end
68     i
69   end
70
71   def fn_for_offset o; File.join(@dir, o.to_s); end
72
73   def load_header offset
74     File.open(fn_for_offset(offset)) { |f| parse_raw_email_header f }
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 each_raw_message_line offset
96     File.open(fn_for_offset(offset)) do |f|
97       yield f.gets until f.eof?
98     end
99   end
100
101   def raw_message offset
102     IO.read(fn_for_offset(offset))
103   end
104
105   def start_offset; 0; end
106   def end_offset
107     ids = get_ids
108     ids.empty? ? 0 : (ids.last + 1)
109   end
110
111 private
112
113   def get_ids
114     Dir.entries(@dir).select { |x| x =~ /^\d+$/ }.map { |x| x.to_i }.sort
115   end
116 end
117
118 end