10 ## read in stored people
11 IO.readlines(fn).map do |l|
12 l =~ /^(.*)?:\s+(\d+)\s+(.*)$/ or raise "can't parse: #{l}"
13 email, time, name = $1, $2, $3
14 @@people[email] = Person.new name, email, time, false
15 end if File.exists? fn
17 self.class.i_am_the_instance self
21 File.open(@fn, "w") do |f|
22 @@people.each do |email, p|
23 next if p.email == p.name
24 f.puts "#{p.email}: #{p.timestamp} #{p.name}"
29 def self.people_for s, opts={}
31 s.split_on_commas.map { |ss| self.person_for ss, opts }
34 def self.person_for s, opts={}
35 p = Person.from_address(s) or return nil
36 p.definitive = true if opts[:definitive]
41 oldp = @@people[p.email]
43 if oldp.nil? || p.better_than?(oldp)
47 @@people[p.email].touch!
52 ## don't create these by hand. rather, go through personmanager, to
53 ## ensure uniqueness and overriding.
55 attr_accessor :name, :email, :timestamp
56 bool_accessor :definitive
58 def initialize name, email, timestamp=0, definitive=false
59 raise ArgumentError, "email can't be nil" unless email
62 @name = name.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ")
63 if @name =~ /^(['"]\s*)(.*?)(\s*["'])$/
68 @email = email.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ").downcase
69 @definitive = definitive
70 @timestamp = timestamp
73 ## heuristic: whether the name attached to this email is "real", i.e.
74 ## we should bother to store it.
76 @email =~ /no\-?reply/
80 return false if o.definitive? || generic?
81 return true if definitive?
82 o.name.nil? || (name && name.length > o.name.length && name =~ /[a-z]/)
85 def to_s; "#@name <#@email>" end
87 def touch!; @timestamp = Time.now.to_i end
89 # def == o; o && o.email == email; end
91 # def hash; [name, email].hash; end
114 def mediumname; @name || @email; end
119 "#{@name.inspect} <#@email>" # escape quotes
128 ## when sorting addresses, sort by this
133 when /^\S+ \S+ (\S+)/
144 def self.from_address s
147 ## try and parse an email address and name
150 when /["'](.*?)["'] <(.*?)>/, /([^,]+) <(.*?)>/
152 [a.gsub('\"', '"'), b]
153 when /<((\S+?)@\S+?)>/
161 Person.new name, email
164 def eql? o; email.eql? o.email end
165 def hash; email.hash end