]> git.cworth.org Git - sup/blob - lib/sup/person.rb
Fix uninitialized @name member in person.rb.
[sup] / lib / sup / person.rb
1 module Redwood
2
3 class Person 
4   attr_accessor :name, :email
5
6   def initialize name, email
7     raise ArgumentError, "email can't be nil" unless email
8     
9     if name
10       @name = name.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ")
11       if @name =~ /^(['"]\s*)(.*?)(\s*["'])$/
12         @name = $2
13       end
14     else
15       @name = nil
16     end
17
18     @email = email.gsub(/^\s+|\s+$/, "").gsub(/\s+/, " ").downcase
19   end
20
21   def to_s; "#@name <#@email>" end
22
23 #   def == o; o && o.email == email; end
24 #   alias :eql? :==
25 #   def hash; [name, email].hash; end
26
27   def shortname
28     case @name
29     when /\S+, (\S+)/
30       $1
31     when /(\S+) \S+/
32       $1
33     when nil
34       @email
35     else
36       @name
37     end
38   end
39
40   def longname
41     if @name && @email
42       "#@name <#@email>"
43     else
44       @email
45     end
46   end
47
48   def mediumname; @name || @email; end
49
50   def full_address
51     if @name && @email
52       if @name =~ /[",@]/
53         "#{@name.inspect} <#{@email}>" # escape quotes
54       else
55         "#{@name} <#{@email}>"
56       end
57     else
58       email
59     end
60   end
61
62   ## when sorting addresses, sort by this 
63   def sort_by_me
64     case @name
65     when /^(\S+), \S+/
66       $1
67     when /^\S+ \S+ (\S+)/
68       $1
69     when /^\S+ (\S+)/
70       $1
71     when nil
72       @email
73     else
74       @name
75     end.downcase
76   end
77
78   def self.from_address s
79     return nil if s.nil?
80
81     ## try and parse an email address and name
82     name, email = case s
83       when /(.+?) ((\S+?)@\S+) \3/
84         ## ok, this first match cause is insane, but bear with me.  email
85         ## addresses are stored in the to/from/etc fields of the index in a
86         ## weird format: "name address first-part-of-address", i.e.  spaces
87         ## separating those three bits, and no <>'s. this is the output of
88         ## #indexable_content. here, we reverse-engineer that format to extract
89         ## a valid address.
90         ##
91         ## we store things this way to allow searches on a to/from/etc field to
92         ## match any of those parts. a more robust solution would be to store a
93         ## separate, non-indexed field with the proper headers. but this way we
94         ## save precious bits, and it's backwards-compatible with older indexes.
95         [$1, $2]
96       when /["'](.*?)["'] <(.*?)>/, /([^,]+) <(.*?)>/
97         a, b = $1, $2
98         [a.gsub('\"', '"'), b]
99       when /<((\S+?)@\S+?)>/
100         [$2, $1]
101       when /((\S+?)@\S+)/
102         [$2, $1]
103       else
104         [nil, s]
105       end
106
107     Person.new name, email
108   end
109
110   def self.from_address_list ss
111     return [] if ss.nil?
112     ss.split_on_commas.map { |s| self.from_address s }
113   end
114
115   ## see comments in self.from_address
116   def indexable_content
117     [name, email, email.split(/@/).first].join(" ")
118   end
119
120   def eql? o; email.eql? o.email end
121   def hash; email.hash end
122 end
123
124 end