lib/sup/person.rb in sup-0.0.2 vs lib/sup/person.rb in sup-0.0.3

- old
+ new

@@ -1,41 +1,59 @@ module Redwood +class PersonManager + include Singleton + + def initialize fn + @fn = fn + @names = {} + IO.readlines(fn).map { |l| l =~ /^(.*)?:\s+(\d+)\s+(.*)$/ && @names[$1] = [$2.to_i, $3] } if File.exists? fn + self.class.i_am_the_instance self + end + + def name_for email; @names.member?(email) && @names[email][1]; 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 + oldcount, oldname = @names[email] + @names[email] = [0, name] if oldname.nil? || oldname.length < name.length || (oldname !~ /[A-Z]/ && name =~ /[A-Z]/) + @names[email][0] = Time.now.to_i + end + + def save; File.open(@fn, "w") { |f| @names.each { |email, (time, name)| f.puts "#{email}: #{time} #{name}" } }; end +end + class Person @@email_map = {} attr_accessor :name, :email 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 /(\S+) \S+/ $1 when nil - @email #[0 ... 10] + @email else - @name #[0 ... 10] + @name end end def longname if @name && @email @@ -43,30 +61,25 @@ else @email 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 else @email end end + ## when sorting addresses, sort by this def sort_by_me case @name when /^(\S+), \S+/ $1 when /^\S+ \S+ (\S+)/ @@ -78,22 +91,14 @@ else @name 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 /["'](.*?)["'] <(.*?)>/, /([^,]+) <(.*?)>/ a, b = $1, $2 [a.gsub('\"', '"'), b] @@ -103,18 +108,16 @@ [$2, $1] else [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 - end + @@email_map[email] ||= Person.new name, email + end + + def self.for_several s + return [] if s.nil? + + s.split_on_commas.map { |ss| self.for ss } end end end