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.
35
36
37
38
39
40
|
# File 'lib/sup/thread.rb', line 35
def initialize
raise "wrong Thread class, buddy!" if block_given?
@containers = []
end
|
Instance Attribute Details
#containers ⇒ Object
Returns the value of attribute containers.
34
35
36
|
# File 'lib/sup/thread.rb', line 34
def containers
@containers
end
|
Instance Method Details
42
43
44
|
# File 'lib/sup/thread.rb', line 42
def << c
@containers << c
end
|
#apply_label(t) ⇒ Object
101
|
# File 'lib/sup/thread.rb', line 101
def apply_label t; each { |m, *o| m && m.add_label(t) }; end
|
99
|
# File 'lib/sup/thread.rb', line 99
def authors; map { |m, *o| m.from if m }.compact.uniq; end
|
90
|
# File 'lib/sup/thread.rb', line 90
def date; map { |m, *o| m.date if m }.compact.max; end
|
#direct_participants ⇒ Object
118
119
120
|
# File 'lib/sup/thread.rb', line 118
def direct_participants
map { |m, *o| [m.from] + m.to if m }.flatten.compact.uniq
end
|
#dirty? ⇒ Boolean
89
|
# File 'lib/sup/thread.rb', line 89
def dirty?; any? { |m, *o| m && m.dirty? }; end
|
48
|
# File 'lib/sup/thread.rb', line 48
def drop c; @containers.delete(c) or raise "bad drop"; end
|
#dump(f = $stdout) ⇒ Object
51
52
53
54
55
|
# File 'lib/sup/thread.rb', line 51
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).
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/sup/thread.rb', line 61
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
116
|
# File 'lib/sup/thread.rb', line 116
def each_dirty_message; each { |m, *o| m && m.dirty? && yield(m) }; end
|
47
|
# File 'lib/sup/thread.rb', line 47
def empty!; @containers.clear; end
|
#empty? ⇒ Boolean
46
|
# File 'lib/sup/thread.rb', line 46
def empty?; @containers.empty?; end
|
87
|
# File 'lib/sup/thread.rb', line 87
def first; each { |m, *o| return m if m }; nil; end
|
#has_label?(t) ⇒ Boolean
115
|
# File 'lib/sup/thread.rb', line 115
def has_label? t; any? { |m, *o| m && m.has_label?(t) }; end
|
#has_message? ⇒ Boolean
88
|
# File 'lib/sup/thread.rb', line 88
def has_message?; any? { |m, *o| m.is_a? Message }; end
|
128
|
# File 'lib/sup/thread.rb', line 128
def labels; inject(Set.new) { |s, (m, *o)| m ? s | m.labels : s } end
|
#labels=(l) ⇒ Object
129
130
131
132
|
# File 'lib/sup/thread.rb', line 129
def labels= l
raise ArgumentError, "not a set" unless l.is_a?(Set)
each { |m, *o| m && m.labels = l.dup }
end
|
#latest_message ⇒ Object
134
135
136
137
138
139
140
141
142
143
144
145
|
# File 'lib/sup/thread.rb', line 134
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
122
123
124
|
# File 'lib/sup/thread.rb', line 122
def participants
map { |m, *o| [m.from] + m.to + m.cc + m.bcc if m }.flatten.compact.uniq
end
|
#remove_label(t) ⇒ Object
102
|
# File 'lib/sup/thread.rb', line 102
def remove_label t; each { |m, *o| m && m.remove_label(t) }; end
|
#set_labels(l) ⇒ Object
114
|
# File 'lib/sup/thread.rb', line 114
def set_labels l; each { |m, *o| m && m.labels = l }; end
|
126
|
# File 'lib/sup/thread.rb', line 126
def size; map { |m, *o| m ? 1 : 0 }.sum; end
|
91
92
93
94
95
96
97
98
|
# File 'lib/sup/thread.rb', line 91
def snippet
with_snippets = select { |m, *o| m && m.snippet && !m.snippet.empty? }
first_unread, * = with_snippets.select { |m, *o| m.has_label?(:unread) }.sort_by { |m, *o| m.date }.first
return first_unread.snippet if first_unread
last_read, * = with_snippets.sort_by { |m, *o| m.date }.last
return last_read.snippet if last_read
""
end
|
151
152
153
154
|
# File 'lib/sup/thread.rb', line 151
def sort_key
m = latest_message
m ? [-m.date.to_i, m.id] : [-Time.now.to_i, ""]
end
|
127
|
# File 'lib/sup/thread.rb', line 127
def subj; argfind { |m, *o| m && m.subj }; end
|
147
148
149
|
# File 'lib/sup/thread.rb', line 147
def to_s
"<thread containing: #{@containers.join ', '}>"
end
|
#toggle_label(label) ⇒ Object
104
105
106
107
108
109
110
111
112
|
# File 'lib/sup/thread.rb', line 104
def toggle_label label
if has_label? label
remove_label label
false
else
apply_label label
true
end
end
|