Class: Redwood::Thread
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Enumerable
#argfind, #argmin, #between, #map_to_hash, #map_with_index, #max_of, #shared_prefix, #sum
Constructor Details
#initialize ⇒ Thread
Returns a new instance of Thread.
37
38
39
40
41
42
|
# File 'lib/sup/thread.rb', line 37
def initialize
raise "wrong Thread class, buddy!" if block_given?
@containers = []
end
|
Instance Attribute Details
#containers ⇒ Object
Returns the value of attribute containers.
36
37
38
|
# File 'lib/sup/thread.rb', line 36
def containers
@containers
end
|
Instance Method Details
44
45
46
|
# File 'lib/sup/thread.rb', line 44
def << c
@containers << c
end
|
#apply_label(t) ⇒ Object
103
|
# File 'lib/sup/thread.rb', line 103
def apply_label t; each { |m, *| m && m.add_label(t) }; end
|
101
|
# File 'lib/sup/thread.rb', line 101
def authors; map { |m, *| m.from if m }.compact.uniq; end
|
92
|
# File 'lib/sup/thread.rb', line 92
def date; map { |m, *| m.date if m }.compact.max; end
|
#direct_participants ⇒ Object
120
121
122
|
# File 'lib/sup/thread.rb', line 120
def direct_participants
map { |m, *| [m.from] + m.to if m }.flatten.compact.uniq
end
|
#dirty? ⇒ Boolean
91
|
# File 'lib/sup/thread.rb', line 91
def dirty?; any? { |m, *| m && m.dirty? }; end
|
50
|
# File 'lib/sup/thread.rb', line 50
def drop c; @containers.delete(c) or raise "bad drop"; end
|
#dump(f = $stdout) ⇒ Object
53
54
55
56
57
|
# File 'lib/sup/thread.rb', line 53
def dump f=$stdout
f.puts "=== start thread with #{@containers.length} trees ==="
@containers.each { |c| c.dump_recursive f; f.puts }
f.puts "=== end thread ==="
end
|
#each(fake_root = false) ⇒ Object
yields each message, its depth, and its parent. the message yield parameter can be a Message object, or :fake_root, or nil (no message found but the presence of one deduced from other messages).
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/sup/thread.rb', line 63
def each fake_root=false
adj = 0
root = @containers.find_all { |c| c.message && !Message.subj_is_reply?(c.message.subj) }.argmin { |c| c.date }
if root
adj = 1
root.first_useful_descendant.each_with_stuff do |c, d, par|
yield c.message, d, (par ? par.message : nil)
end
elsif @containers.length > 1 && fake_root
adj = 1
yield :fake_root, 0, nil
end
@containers.each do |cont|
next if cont == root
fud = cont.first_useful_descendant
fud.each_with_stuff do |c, d, par|
yield c.message, d + adj, (par ? par.message : nil) unless
fake_root && c.message.nil? && root.nil? && c == fud
end
end
end
|
#each_dirty_message ⇒ Object
118
|
# File 'lib/sup/thread.rb', line 118
def each_dirty_message; each { |m, *| m && m.dirty? && yield(m) }; end
|
49
|
# File 'lib/sup/thread.rb', line 49
def empty!; @containers.clear; end
|
#empty? ⇒ Boolean
48
|
# File 'lib/sup/thread.rb', line 48
def empty?; @containers.empty?; end
|
89
|
# File 'lib/sup/thread.rb', line 89
def first; each { |m, *| return m if m }; nil; end
|
#has_label?(t) ⇒ Boolean
117
|
# File 'lib/sup/thread.rb', line 117
def has_label? t; any? { |m, *| m && m.has_label?(t) }; end
|
#has_message? ⇒ Boolean
90
|
# File 'lib/sup/thread.rb', line 90
def has_message?; any? { |m, *| m.is_a? Message }; end
|
130
|
# File 'lib/sup/thread.rb', line 130
def labels; inject(Set.new) { |s, (m, *)| m ? s | m.labels : s } end
|
#labels=(l) ⇒ Object
131
132
133
134
|
# File 'lib/sup/thread.rb', line 131
def labels= l
raise ArgumentError, "not a set" unless l.is_a?(Set)
each { |m, *| m && m.labels = l.dup }
end
|
#latest_message ⇒ Object
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/sup/thread.rb', line 136
def latest_message
inject(nil) do |a, b|
b = b.first
if a.nil?
b
elsif b.nil?
a
else
b.date > a.date ? b : a
end
end
end
|
#participants ⇒ Object
124
125
126
|
# File 'lib/sup/thread.rb', line 124
def participants
map { |m, *| [m.from] + m.to + m.cc + m.bcc if m }.flatten.compact.uniq
end
|
#remove_label(t) ⇒ Object
104
|
# File 'lib/sup/thread.rb', line 104
def remove_label t; each { |m, *| m && m.remove_label(t) }; end
|
#set_labels(l) ⇒ Object
116
|
# File 'lib/sup/thread.rb', line 116
def set_labels l; each { |m, *| m && m.labels = l }; end
|
128
|
# File 'lib/sup/thread.rb', line 128
def size; map { |m, *| m ? 1 : 0 }.sum; end
|
93
94
95
96
97
98
99
100
|
# File 'lib/sup/thread.rb', line 93
def snippet
with_snippets = select { |m, *| m && m.snippet && !m.snippet.empty? }
first_unread, * = with_snippets.select { |m, *| m.has_label?(:unread) }.sort_by { |m, *| m.date }.first
return first_unread.snippet if first_unread
last_read, * = with_snippets.sort_by { |m, *| m.date }.last
return last_read.snippet if last_read
""
end
|
153
154
155
156
|
# File 'lib/sup/thread.rb', line 153
def sort_key
m = latest_message
m ? [-m.date.to_i, m.id] : [-Time.now.to_i, ""]
end
|
129
|
# File 'lib/sup/thread.rb', line 129
def subj; argfind { |m, *| m && m.subj }; end
|
149
150
151
|
# File 'lib/sup/thread.rb', line 149
def to_s
"<thread containing: #{@containers.join ', '}>"
end
|
#toggle_label(label) ⇒ Object
106
107
108
109
110
111
112
113
114
|
# File 'lib/sup/thread.rb', line 106
def toggle_label label
if has_label? label
remove_label label
false
else
apply_label label
true
end
end
|