Class: Mournmail::Summary

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/mournmail/summary.rb

Constant Summary collapse

LOCK_OPERATIONS =
Hash.new(:unknown_mode)
DUMPABLE_VARIABLES =
[
  :@mailbox,
  :@items,
  :@message_id_table,
  :@uid_table,
  :@last_uid,
  :@uidvalidity
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mailbox) ⇒ Summary

Returns a new instance of Summary.



53
54
55
56
57
58
59
60
61
# File 'lib/mournmail/summary.rb', line 53

def initialize(mailbox)
  super()
  @mailbox = mailbox
  @items = []
  @message_id_table = {}
  @uid_table = {}
  @last_uid = nil
  @uidvalidity = nil
end

Instance Attribute Details

#itemsObject (readonly)

Returns the value of attribute items.



7
8
9
# File 'lib/mournmail/summary.rb', line 7

def items
  @items
end

#last_uidObject (readonly)

Returns the value of attribute last_uid.



7
8
9
# File 'lib/mournmail/summary.rb', line 7

def last_uid
  @last_uid
end

#mailboxObject (readonly)

Returns the value of attribute mailbox.



7
8
9
# File 'lib/mournmail/summary.rb', line 7

def mailbox
  @mailbox
end

#uidvalidityObject

Returns the value of attribute uidvalidity.



8
9
10
# File 'lib/mournmail/summary.rb', line 8

def uidvalidity
  @uidvalidity
end

Class Method Details

.cache_lock_path(mailbox) ⇒ Object



27
28
29
# File 'lib/mournmail/summary.rb', line 27

def self.cache_lock_path(mailbox)
  cache_path(mailbox) + ".lock"
end

.cache_old_path(mailbox) ⇒ Object



35
36
37
# File 'lib/mournmail/summary.rb', line 35

def self.cache_old_path(mailbox)
  cache_path(mailbox) + ".old"
end

.cache_path(mailbox) ⇒ Object



23
24
25
# File 'lib/mournmail/summary.rb', line 23

def self.cache_path(mailbox)
  File.join(Mournmail.mailbox_cache_path(mailbox), ".summary")
end

.cache_tmp_path(mailbox) ⇒ Object



31
32
33
# File 'lib/mournmail/summary.rb', line 31

def self.cache_tmp_path(mailbox)
  cache_path(mailbox) + ".tmp"
end

.load(mailbox) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/mournmail/summary.rb', line 39

def self.load(mailbox)
  lock_cache(mailbox, :shared) do
    File.open(cache_path(mailbox)) do |f|
      Marshal.load(f)
    end
  end
end

.load_or_new(mailbox) ⇒ Object



47
48
49
50
51
# File 'lib/mournmail/summary.rb', line 47

def self.load_or_new(mailbox)
  load(mailbox)
rescue Errno::ENOENT
  new(mailbox)
end

.lock_cache(mailbox, mode) ⇒ Object



16
17
18
19
20
21
# File 'lib/mournmail/summary.rb', line 16

def self.lock_cache(mailbox, mode)
  File.open(Summary.cache_lock_path(mailbox), "w", 0600) do |f|
    f.flock(LOCK_OPERATIONS[mode])
    yield
  end
end

Instance Method Details

#[](uid) ⇒ Object



116
117
118
119
120
# File 'lib/mournmail/summary.rb', line 116

def [](uid)
  synchronize do
    @uid_table[uid]
  end
end

#add_item(item, message_id, in_reply_to) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/mournmail/summary.rb', line 85

def add_item(item, message_id, in_reply_to)
  synchronize do
# Disable threads
#        parent = @message_id_table[in_reply_to]
#        if parent
#          parent.add_reply(item)
#        else
#          @items.push(item)
#        end
    @items.push(item)
    if message_id
      @message_id_table[message_id] = item
    end
    @uid_table[item.uid] = item
    @last_uid = item.uid
  end
end

#delete_item_if(&block) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/mournmail/summary.rb', line 103

def delete_item_if(&block)
  synchronize do
    @items = @items.flat_map { |item|
      item.delete_reply_if(&block)
      if yield(item)
        item.replies
      else
        [item]
      end
    }
  end
end

#marshal_dumpObject



72
73
74
75
76
# File 'lib/mournmail/summary.rb', line 72

def marshal_dump
  DUMPABLE_VARIABLES.each_with_object({}) { |var, h|
    h[var] = instance_variable_get(var)
  }
end

#marshal_load(data) ⇒ Object



78
79
80
81
82
83
# File 'lib/mournmail/summary.rb', line 78

def marshal_load(data)
  mon_initialize
  data.each do |var, val|
    instance_variable_set(var, val)
  end
end

#read_mail(uid) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/mournmail/summary.rb', line 128

def read_mail(uid)
  synchronize do
    item = @uid_table[uid]
    if item.cache_id
      File.open(Mournmail.mail_cache_path(item.cache_id)) do |f|
        [Mournmail.parse_mail(f.read), false]
      end
    else
      Mournmail.imap_connect do |imap|
        imap.select(@mailbox)
        data = imap.uid_fetch(uid, "BODY[]")
        if data.nil? || data.empty?
          raise EditorError, "No such mail: #{uid}"
        end
        s = data[0].attr["BODY[]"]
        mail = Mournmail.parse_mail(s)
        spam_mailbox = Mournmail.[:spam_mailbox]
        if spam_mailbox.nil? || 
            @mailbox != Net::IMAP.encode_utf7(spam_mailbox)
          item.cache_id = Mournmail.write_mail_cache(s)
          Mournmail.index_mail(item.cache_id, mail)
        end
        [mail, true]
      end
    end
  end
end

#saveObject



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/mournmail/summary.rb', line 156

def save
  synchronize do
    path = Summary.cache_path(@mailbox)
    FileUtils.mkdir_p(File.dirname(path))
    Summary.lock_cache(@mailbox, :exclusive) do
      cache_path = Summary.cache_path(@mailbox)
      tmp_path = Summary.cache_tmp_path(@mailbox)
      old_path = Summary.cache_old_path(@mailbox)
      File.open(tmp_path, "w", 0600) do |f|
        Marshal.dump(self, f)
      end
      begin
        File.rename(cache_path, old_path)
      rescue Errno::ENOENT
      end
      File.rename(tmp_path, cache_path)
    end
  end
end

#to_sObject



176
177
178
179
180
181
182
# File 'lib/mournmail/summary.rb', line 176

def to_s
  synchronize do
    items.each_with_object(+"") do |item, s|
      s << item.to_s
    end
  end
end

#uidsObject



122
123
124
125
126
# File 'lib/mournmail/summary.rb', line 122

def uids
  synchronize do
    @uid_table.keys
  end
end