ever seen. this will probably need to be intelligently trimmed, but will be
used for fast loading of messages from slow sources.
- moved initialization and shutdown to Redwood::start and ::finish in sup.rb.
- poll#initialize no longer automatically starts a thread. you must call
#start_thread. (because sup-import now calls Redwood::start which initializes
all managers, including pollmanager, and it certainly doesn't make sense to
have anything threaded during import)
- misc. comment improvements
git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@113
5c8cc53c-5e98-4d25-b20a-
d8db53a31250
end
module_function :start_cursing, :stop_cursing
-Redwood::SentManager.new Redwood::SENT_FN
-Redwood::ContactManager.new Redwood::CONTACT_FN
-Redwood::LabelManager.new Redwood::LABEL_FN
-Redwood::AccountManager.new $config[:accounts]
-Redwood::DraftManager.new Redwood::DRAFT_DIR
-Redwood::UpdateManager.new
-Redwood::PollManager.new
+Redwood::start
Index.new.load
log "loaded #{Index.size} messages from index"
else
Index.add_source SentManager.new_source
end
-
+
begin
log "starting curses"
start_cursing
imode.load_more_threads ibuf.content_height
reporting_thread { sleep 3; PollManager.poll }
+ PollManager.start_thread
until $exception
bm.draw_screen
end
end
bm.kill_all_buffers
- Redwood::LabelManager.save
- Redwood::ContactManager.save
rescue Exception => e
$exception ||= e
ensure
+ Redwood::finish
stop_cursing
end
educate_user
end
+Redwood::start
+
puts "loading index..."
index = Redwood::Index.new
index.load
end
ensure
index.save
+ Redwood::finish
end
if rebuild || force_rebuild
CONFIG_FN = File.join(BASE_DIR, "config.yaml")
SOURCE_FN = File.join(BASE_DIR, "sources.yaml")
LABEL_FN = File.join(BASE_DIR, "labels.txt")
+ PERSON_FN = File.join(BASE_DIR, "people.txt")
CONTACT_FN = File.join(BASE_DIR, "contacts.txt")
DRAFT_DIR = File.join(BASE_DIR, "drafts")
SENT_FN = File.join(BASE_DIR, "sent.mbox")
end
end
- module_function :register_yaml, :save_yaml_obj, :load_yaml_obj
+ def start
+ Redwood::PersonManager.new Redwood::PERSON_FN
+ Redwood::SentManager.new Redwood::SENT_FN
+ Redwood::ContactManager.new Redwood::CONTACT_FN
+ Redwood::LabelManager.new Redwood::LABEL_FN
+ Redwood::AccountManager.new $config[:accounts]
+ Redwood::DraftManager.new Redwood::DRAFT_DIR
+ Redwood::UpdateManager.new
+ Redwood::PollManager.new
+ end
+
+ def finish
+ Redwood::LabelManager.save
+ Redwood::ContactManager.save
+ Redwood::PersonManager.save
+ end
+
+ module_function :register_yaml, :save_yaml_obj, :load_yaml_obj, :start, :finish
end
## set up default configuration file
class LabelManager
include Singleton
- ## all labels that have special meaning. user will be unable to
+ ## labels that have special semantics. user will be unable to
## add/remove these via normal label mechanisms.
RESERVED_LABELS = [ :starred, :spam, :draft, :unread, :killed, :sent ]
module Redwood
+class PersonManager
+ include Singleton
+
+ def initialize fn
+ @fn = fn
+ @names = {}
+ IO.readlines(fn).map { |l| l =~ /^(.*)?:\s+(.*)$/ && @names[$1] = $2 } if File.exists? fn
+ self.class.i_am_the_instance self
+ end
+
+ def name_for email; @names[email]; end
+ def register email, name
+ return unless name
+
+ name = name.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ")
+
+ ## all else being equal, prefer longer names, unless the prior name
+ ## doesn't contain any capitalization
+ oldname = @names[email]
+ @names[email] = name if oldname.nil? || oldname.length < name.length || (oldname !~ /[A-Z]/ && name =~ /[A-Z]/)
+ end
+
+ def save; File.open(@fn, "w") { |f| @names.each { |email, name| f.puts "#{email}: #{name}" } }; end
+end
+
class Person
@@email_map = {}
def initialize name, email
raise ArgumentError, "email can't be nil" unless email
- @name =
- if name
- name.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ")
- else
- nil
- end
@email = email.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ").downcase
- @@email_map[@email] = self
+ PersonManager.register @email, name
+ @name = PersonManager.name_for @email
end
def == o; o && o.email == email; end
alias :eql? :==
-
- def hash
- [name, email].hash
- end
+ def hash; [name, email].hash; end
def shortname
case @name
when /(\S+) \S+/
$1
when nil
- @email #[0 ... 10]
+ @email
else
- @name #[0 ... 10]
+ @name
end
end
end
end
- def mediumname
- if @name
- name
- else
- @email
- end
- end
+ def mediumname; @name || @email; end
def full_address
if @name && @email
if @name =~ /"/
- "#{@name.inspect} <#@email>"
+ "#{@name.inspect} <#@email>" # escape quotes
else
"#@name <#@email>"
end
end
end
+ ## when sorting addresses, sort by this
def sort_by_me
case @name
when /^(\S+), \S+/
end.downcase
end
- def self.for_several s
- return [] if s.nil?
-
- begin
- s.split_on_commas.map { |ss| self.for ss }
- rescue StandardError => e
- raise "#{e.message}: for #{s.inspect}"
- end
- end
-
def self.for s
return nil if s.nil?
+
+ ## try and parse an email address and name
name, email =
case s
when /["'](.*?)["'] <(.*?)>/, /([^,]+) <(.*?)>/
[nil, s]
end
- if name && (p = @@email_map[email])
- ## all else being equal, prefer longer names, unless the prior name
- ## doesn't contain any capitalization
- p.name = name if (p.name.nil? || p.name.length < name.length) unless
- p.name =~ /[A-Z]/ || (AccountManager.instantiated? && AccountManager.is_account?(p))
- p
- else
- Person.new name, email
+ @@email_map[email] ||= Person.new name, email
+ end
+
+ def self.for_several s
+ return [] if s.nil?
+
+ begin
+ s.split_on_commas.map { |ss| self.for ss }
+ rescue StandardError => e
+ raise "#{e.message}: for #{s.inspect}"
end
end
end
@last_poll = nil
self.class.i_am_the_instance self
-
- Redwood::reporting_thread do
- while true
- sleep DELAY / 2
- poll if @last_poll.nil? || (Time.now - @last_poll) >= DELAY
- end
- end
end
def buffer
[num, numi]
end
+ def start_thread
+ Redwood::reporting_thread do
+ while true
+ sleep DELAY / 2
+ poll if @last_poll.nil? || (Time.now - @last_poll) >= DELAY
+ end
+ end
+ end
+
def do_poll
return [0, 0] if @polling
@polling = true
self[0 .. 0].upcase + self[1 .. -1]
end
- ## found on teh internets
+ ## a very complicated regex found on teh internets to split on
+ ## commas, unless they occurr within double quotes.
def split_on_commas
split(/,\s*(?=(?:[^"]*"[^"]*")*(?![^"]*"))/)
end