17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/maildir/keywords.rb', line 17
def read_keywords
messages = (list(:cur) + list(:new)).inject({}) { |m, msg| m[msg.unique_name] = msg ; m }
t = Time.now.to_i / 300
keywords = []
state = :head
list_file = File.join(keyword_dir, ':list')
File.open(list_file).each_line do |line|
line.strip!
if state == :head
if line.empty?
state = :messages
next
end
keywords << line
else
key, ids = line.split(':')
if msg = messages[key]
msg.set_keywords(ids.split(/\s/).map {|id| keywords[id.to_i - 1] })
end
end
end if File.exist?(list_file)
keyword_files = (Dir.entries(keyword_dir) - %w(. .. :list)).inject({}) do |keyword_files, file|
if file =~ /^\.(\d+)\.(.*)$/
n = $1
key = $2
else
n = t + 1
key = file
FileUtils.mv(File.join(keyword_dir, file), File.join(keyword_dir, ".#{n}.#{key}"))
end
if msg = messages[key]
(keyword_files[key] ||= []) << [n, key]
else fname = File.join(keyword_dir, file)
if File.stat(fname).ctime < (Time.now - (15 * 60))
FileUtils.rm(fname)
end
end
next(keyword_files)
end
keyword_files.each_pair do |key, files|
files.sort! { |a, b| a[0] <=> b[0] }
files[0..-2].each { |f| FileUtils.rm(File.join(keyword_dir, ".#{f.join('.')}")) } if files.last[0] < t
msg = messages[key]
file = (File.exist?(File.join(keyword_dir, files.last[1])) ? files.last[1] : ".#{files.last.join('.')}")
current_keywords = File.read(File.join(keyword_dir, file)).split(/\s+/)
msg.set_keywords(current_keywords)
if (add = (current_keywords - keywords)).any?
keywords += add
end
end
@keywords = {}
tmp_file = File.join(path, 'tmp', ':list')
File.open(tmp_file, 'w') { |f|
f.write(keywords.join("\n")+"\n\n")
messages.each_pair do |key, msg|
next unless msg.keywords
f.puts([key, msg.keywords.map{|kw| keywords.index(kw) + 1 }.sort.join(' ')].join(':'))
@keywords[key] = msg.keywords
end
}
FileUtils.mv(tmp_file, list_file)
end
|