aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/ruby-msg/lib/mapi/convert/contact.rb
blob: 838ae6498a7aea35452a92842a2076e9e9f586da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
require 'rubygems'
require 'vpim/vcard'

# patch Vpim. TODO - fix upstream, or verify old behaviour was ok
def Vpim.encode_text v
	# think the regexp was wrong
	v.to_str.gsub(/(.)/m) do
		case $1
		when "\n"
			"\\n"
		when "\\", ",", ";"
			"\\#{$1}"
		else
			$1
		end
	end
end

module Mapi
	class Message
		class VcardConverter
			include Vpim

			# a very incomplete mapping, but its a start...
			# can't find where to set a lot of stuff, like zipcode, jobtitle etc
			VCARD_MAP = {
				# these are all standard mapi properties
				:name => [
					{
						:given		=> :given_name,
						:family		=> :surname,
						:fullname	=> :subject
					}
				],
				# outlook seems to eschew the mapi properties this time,
				# like postal_address, street_address, home_address_city
				# so we use the named properties
				:addr => [
					{
						:location	=> 'work',
						:street		=> :business_address_street,
						:locality	=> proc do |props|
							[props.business_address_city, props.business_address_state].compact * ', '
						end
					}
				],

				# right type? maybe date
				:birthday	=> :birthday,
				:nickname	=> :nickname

				# photo available?
				# FIXME finish, emails, telephones etc
			}

			attr_reader :msg
			def initialize msg
				@msg = msg
			end

			def field name, *args
				DirectoryInfo::Field.create name, Vpim.encode_text_list(args)
			end

			def get_property key
				if String === key
					return key
				elsif key.respond_to? :call
					value = key.call msg.props
				else
					value = msg.props[key]
				end
				if String === value and value.empty?
					nil
				else
					value
				end
			end

			def get_properties hash
				constants = {}
				others = {}
				hash.each do |to, from|
					if String === from
						constants[to] = from
					else
						value = get_property from
						others[to] = value if value
					end
				end
				return nil if others.empty?
				others.merge constants
			end

			def convert
				Vpim::Vcard::Maker.make2 do |m|
					# handle name
					[:name, :addr].each do |type|
						VCARD_MAP[type].each do |hash|
							next unless props = get_properties(hash)
							m.send "add_#{type}" do |n|
								props.each { |key, value| n.send "#{key}=", value }
							end
						end
					end

					(VCARD_MAP.keys - [:name, :addr]).each do |key|
						value = get_property VCARD_MAP[key]
						m.send "#{key}=", value if value
					end

					# the rest of the stuff is custom

					url = get_property(:webpage) || get_property(:business_home_page)
					m.add_field field('URL', url) if url
					m.add_field field('X-EVOLUTION-FILE-AS', get_property(:file_under)) if get_property(:file_under)

					addr = get_property(:email_email_address) || get_property(:email_original_display_name)
					if addr
						m.add_email addr do |e|
							e.format ='x400' unless msg.props.email_addr_type == 'SMTP'
						end
					end

					if org = get_property(:company_name)
						m.add_field field('ORG', get_property(:company_name))
					end

					# TODO: imaddress
				end
			end
		end

		def to_vcard
			#p props.raw.reject { |key, value| key.guid.inspect !~ /00062004-0000-0000-c000-000000000046/ }.
			#	map { |key, value| [key.to_sym, value] }.reject { |a, b| b.respond_to? :read }
			#y props.to_h.reject { |a, b| b.respond_to? :read }
			VcardConverter.new(self).convert
		end
	end
end