class Redwood::Thread

Attributes

containers[R]

Public Class Methods

new() click to toggle source
# File lib/sup/thread.rb, line 36
def initialize
  ## ah, the joys of a multithreaded application with a class called
  ## "Thread". i keep instantiating the wrong one...
  raise "wrong Thread class, buddy!" if block_given?
  @containers = []
end

Public Instance Methods

<<(c) click to toggle source
# File lib/sup/thread.rb, line 43
def << c
  @containers << c
end
apply_label(t;) click to toggle source
# File lib/sup/thread.rb, line 102
def apply_label t; each { |m, *o| m && m.add_label(t) }; end
authors() click to toggle source
# File lib/sup/thread.rb, line 100
def authors; map { |m, *o| m.from if m }.compact.uniq; end
date() click to toggle source
# File lib/sup/thread.rb, line 91
def date; map { |m, *o| m.date if m }.compact.max; end
direct_participants() click to toggle source
# File lib/sup/thread.rb, line 119
def direct_participants
  map { |m, *o| [m.from] + m.to if m }.flatten.compact.uniq
end
dirty?() click to toggle source
# File lib/sup/thread.rb, line 90
def dirty?; any? { |m, *o| m && m.dirty? }; end
drop(c;) click to toggle source
# File lib/sup/thread.rb, line 49
def drop c; @containers.delete(c) or raise "bad drop"; end
dump(f=$stdout) click to toggle source

unused

# File lib/sup/thread.rb, line 52
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) { |message, d, (par ? message : nil)| ... } click to toggle source

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).

# File lib/sup/thread.rb, line 62
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|
      ## special case here: if we're an empty root that's already
      ## been joined by a fake root, don't emit
      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() { |m| ... } click to toggle source
# File lib/sup/thread.rb, line 117
def each_dirty_message; each { |m, *o| m && m.dirty? && yield(m) }; end
empty!() click to toggle source
# File lib/sup/thread.rb, line 48
def empty!; @containers.clear; end
empty?() click to toggle source
# File lib/sup/thread.rb, line 47
def empty?; @containers.empty?; end
first() click to toggle source
# File lib/sup/thread.rb, line 88
def first; each { |m, *o| return m if m }; nil; end
has_label?(t;) click to toggle source
# File lib/sup/thread.rb, line 116
def has_label? t; any? { |m, *o| m && m.has_label?(t) }; end
has_message?() click to toggle source
# File lib/sup/thread.rb, line 89
def has_message?; any? { |m, *o| m.is_a? Message }; end
labels() click to toggle source
# File lib/sup/thread.rb, line 129
def labels; inject(Set.new) { |s, (m, *o)| m ? s | m.labels : s } end
labels=(l) click to toggle source
# File lib/sup/thread.rb, line 130
def labels= l
  raise ArgumentError, "not a set" unless l.is_a?(Set)
  each { |m, *o| m && m.labels = l.dup }
end
latest_message() click to toggle source
# File lib/sup/thread.rb, line 135
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() click to toggle source
# File lib/sup/thread.rb, line 123
def participants
  map { |m, *o| [m.from] + m.to + m.cc + m.bcc if m }.flatten.compact.uniq
end
remove_label(t;) click to toggle source
# File lib/sup/thread.rb, line 103
def remove_label t; each { |m, *o| m && m.remove_label(t) }; end
set_labels(l;) click to toggle source
# File lib/sup/thread.rb, line 115
def set_labels l; each { |m, *o| m && m.labels = l }; end
size() click to toggle source
# File lib/sup/thread.rb, line 127
def size; map { |m, *o| m ? 1 : 0 }.sum; end
snippet() click to toggle source
# File lib/sup/thread.rb, line 92
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
sort_key() click to toggle source
# File lib/sup/thread.rb, line 152
def sort_key
  m = latest_message
  m ? [-m.date.to_i, m.id] : [-Time.now.to_i, ""]
end
subj() click to toggle source
# File lib/sup/thread.rb, line 128
def subj; argfind { |m, *o| m && m.subj }; end
to_s() click to toggle source
# File lib/sup/thread.rb, line 148
def to_s
  "<thread containing: #{@containers.join ', '}>"
end
toggle_label(label) click to toggle source
# File lib/sup/thread.rb, line 105
def toggle_label label
  if has_label? label
    remove_label label
    false
  else
    apply_label label
    true
  end
end