commit 8220732408d9c0d77f1d6cb9c9986362c3bfa7f9
parent f8c0cdfa14c06f885d40c1865efc288736d2c686
Author: wmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Date: Thu, 28 Dec 2006 23:10:58 +0000
- created a PersonManager that keeps track of the names of all email addresses
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
Diffstat:
7 files changed, 83 insertions(+), 59 deletions(-)
diff --git a/bin/sup b/bin/sup
@@ -52,13 +52,7 @@ def stop_cursing
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"
@@ -74,7 +68,7 @@ if(s = Index.source_for SentManager.source_name)
else
Index.add_source SentManager.new_source
end
-
+
begin
log "starting curses"
start_cursing
@@ -123,6 +117,7 @@ begin
imode.load_more_threads ibuf.content_height
reporting_thread { sleep 3; PollManager.poll }
+ PollManager.start_thread
until $exception
bm.draw_screen
@@ -185,11 +180,10 @@ begin
end
end
bm.kill_all_buffers
- Redwood::LabelManager.save
- Redwood::ContactManager.save
rescue Exception => e
$exception ||= e
ensure
+ Redwood::finish
stop_cursing
end
diff --git a/bin/sup-import b/bin/sup-import
@@ -81,6 +81,8 @@ if(o = ARGV.find { |x| x =~ /^--/ })
educate_user
end
+Redwood::start
+
puts "loading index..."
index = Redwood::Index.new
index.load
@@ -171,6 +173,7 @@ begin
end
ensure
index.save
+ Redwood::finish
end
if rebuild || force_rebuild
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -19,6 +19,7 @@ module Redwood
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")
@@ -59,7 +60,24 @@ module Redwood
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
diff --git a/lib/sup/label.rb b/lib/sup/label.rb
@@ -3,7 +3,7 @@ module Redwood
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 ]
diff --git a/lib/sup/person.rb b/lib/sup/person.rb
@@ -1,5 +1,30 @@
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 = {}
@@ -7,22 +32,14 @@ class Person
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
@@ -31,9 +48,9 @@ class Person
when /(\S+) \S+/
$1
when nil
- @email #[0 ... 10]
+ @email
else
- @name #[0 ... 10]
+ @name
end
end
@@ -45,18 +62,12 @@ class Person
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
@@ -65,6 +76,7 @@ class Person
end
end
+ ## when sorting addresses, sort by this
def sort_by_me
case @name
when /^(\S+), \S+/
@@ -80,18 +92,10 @@ class Person
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 /["'](.*?)["'] <(.*?)>/, /([^,]+) <(.*?)>/
@@ -105,14 +109,16 @@ class Person
[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
diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
@@ -12,13 +12,6 @@ class PollManager
@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
@@ -38,6 +31,15 @@ class PollManager
[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
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
@@ -43,7 +43,8 @@ class String
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