tilia-vobject 4.0.0.pre.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +32 -0
  4. data/.simplecov +4 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.sabre.md +626 -0
  7. data/CONTRIBUTING.md +25 -0
  8. data/Gemfile +17 -0
  9. data/Gemfile.lock +68 -0
  10. data/LICENSE +27 -0
  11. data/LICENSE.sabre +27 -0
  12. data/README.md +63 -0
  13. data/Rakefile +17 -0
  14. data/bin/vobject +7 -0
  15. data/lib/tilia/v_object/birthday_calendar_generator.rb +142 -0
  16. data/lib/tilia/v_object/cli.rb +582 -0
  17. data/lib/tilia/v_object/component/available.rb +107 -0
  18. data/lib/tilia/v_object/component/v_alarm.rb +114 -0
  19. data/lib/tilia/v_object/component/v_availability.rb +128 -0
  20. data/lib/tilia/v_object/component/v_calendar.rb +468 -0
  21. data/lib/tilia/v_object/component/v_card.rb +457 -0
  22. data/lib/tilia/v_object/component/v_event.rb +127 -0
  23. data/lib/tilia/v_object/component/v_free_busy.rb +81 -0
  24. data/lib/tilia/v_object/component/v_journal.rb +75 -0
  25. data/lib/tilia/v_object/component/v_time_zone.rb +51 -0
  26. data/lib/tilia/v_object/component/v_todo.rb +147 -0
  27. data/lib/tilia/v_object/component.rb +591 -0
  28. data/lib/tilia/v_object/date_time_parser.rb +486 -0
  29. data/lib/tilia/v_object/document.rb +218 -0
  30. data/lib/tilia/v_object/element_list.rb +18 -0
  31. data/lib/tilia/v_object/eof_exception.rb +8 -0
  32. data/lib/tilia/v_object/free_busy_data.rb +149 -0
  33. data/lib/tilia/v_object/free_busy_generator.rb +465 -0
  34. data/lib/tilia/v_object/i_tip/broker.rb +909 -0
  35. data/lib/tilia/v_object/i_tip/i_tip_exception.rb +9 -0
  36. data/lib/tilia/v_object/i_tip/message.rb +109 -0
  37. data/lib/tilia/v_object/i_tip/same_organizer_for_all_components_exception.rb +13 -0
  38. data/lib/tilia/v_object/i_tip.rb +10 -0
  39. data/lib/tilia/v_object/node.rb +192 -0
  40. data/lib/tilia/v_object/parameter.rb +327 -0
  41. data/lib/tilia/v_object/parse_exception.rb +7 -0
  42. data/lib/tilia/v_object/parser/json.rb +149 -0
  43. data/lib/tilia/v_object/parser/mime_dir.rb +543 -0
  44. data/lib/tilia/v_object/parser/parser.rb +61 -0
  45. data/lib/tilia/v_object/parser/xml/element/key_value.rb +60 -0
  46. data/lib/tilia/v_object/parser/xml/element.rb +11 -0
  47. data/lib/tilia/v_object/parser/xml.rb +322 -0
  48. data/lib/tilia/v_object/parser.rb +10 -0
  49. data/lib/tilia/v_object/property/binary.rb +96 -0
  50. data/lib/tilia/v_object/property/boolean.rb +57 -0
  51. data/lib/tilia/v_object/property/flat_text.rb +52 -0
  52. data/lib/tilia/v_object/property/float_value.rb +107 -0
  53. data/lib/tilia/v_object/property/i_calendar/cal_address.rb +49 -0
  54. data/lib/tilia/v_object/property/i_calendar/date.rb +15 -0
  55. data/lib/tilia/v_object/property/i_calendar/date_time.rb +330 -0
  56. data/lib/tilia/v_object/property/i_calendar/duration.rb +65 -0
  57. data/lib/tilia/v_object/property/i_calendar/period.rb +124 -0
  58. data/lib/tilia/v_object/property/i_calendar/recur.rb +173 -0
  59. data/lib/tilia/v_object/property/i_calendar.rb +14 -0
  60. data/lib/tilia/v_object/property/integer_value.rb +60 -0
  61. data/lib/tilia/v_object/property/text.rb +352 -0
  62. data/lib/tilia/v_object/property/time.rb +85 -0
  63. data/lib/tilia/v_object/property/unknown.rb +30 -0
  64. data/lib/tilia/v_object/property/uri.rb +78 -0
  65. data/lib/tilia/v_object/property/utc_offset.rb +56 -0
  66. data/lib/tilia/v_object/property/v_card/date.rb +31 -0
  67. data/lib/tilia/v_object/property/v_card/date_and_or_time.rb +343 -0
  68. data/lib/tilia/v_object/property/v_card/date_time.rb +22 -0
  69. data/lib/tilia/v_object/property/v_card/language_tag.rb +41 -0
  70. data/lib/tilia/v_object/property/v_card/time_stamp.rb +74 -0
  71. data/lib/tilia/v_object/property/v_card.rb +13 -0
  72. data/lib/tilia/v_object/property.rb +532 -0
  73. data/lib/tilia/v_object/reader.rb +73 -0
  74. data/lib/tilia/v_object/recur/event_iterator.rb +417 -0
  75. data/lib/tilia/v_object/recur/no_instances_exception.rb +11 -0
  76. data/lib/tilia/v_object/recur/r_date_iterator.rb +138 -0
  77. data/lib/tilia/v_object/recur/r_rule_iterator.rb +717 -0
  78. data/lib/tilia/v_object/recur.rb +10 -0
  79. data/lib/tilia/v_object/settings.rb +32 -0
  80. data/lib/tilia/v_object/splitter/i_calendar.rb +95 -0
  81. data/lib/tilia/v_object/splitter/splitter_interface.rb +31 -0
  82. data/lib/tilia/v_object/splitter/v_card.rb +56 -0
  83. data/lib/tilia/v_object/splitter.rb +9 -0
  84. data/lib/tilia/v_object/string_util.rb +58 -0
  85. data/lib/tilia/v_object/time_zone_data/exchange_zones.rb +96 -0
  86. data/lib/tilia/v_object/time_zone_data/lotus_zones.rb +104 -0
  87. data/lib/tilia/v_object/time_zone_data/php_zones.rb +49 -0
  88. data/lib/tilia/v_object/time_zone_data/windows_zones.rb +121 -0
  89. data/lib/tilia/v_object/time_zone_data.rb +10 -0
  90. data/lib/tilia/v_object/time_zone_util.rb +213 -0
  91. data/lib/tilia/v_object/uuid_util.rb +51 -0
  92. data/lib/tilia/v_object/v_card_converter.rb +354 -0
  93. data/lib/tilia/v_object/version.rb +9 -0
  94. data/lib/tilia/v_object/writer.rb +56 -0
  95. data/lib/tilia/v_object.rb +45 -0
  96. data/lib/tilia/vobject.rb +1 -0
  97. data/resources/schema/xcal.rng +1192 -0
  98. data/resources/schema/xcard.rng +388 -0
  99. data/test/test_helper.rb +56 -0
  100. data/test/v_object/attach_issue_test.rb +19 -0
  101. data/test/v_object/birthday_calendar_generator_test.rb +463 -0
  102. data/test/v_object/cli_mock.rb +19 -0
  103. data/test/v_object/cli_test.rb +460 -0
  104. data/test/v_object/component/available_test.rb +59 -0
  105. data/test/v_object/component/v_alarm_test.rb +160 -0
  106. data/test/v_object/component/v_availability_test.rb +388 -0
  107. data/test/v_object/component/v_calendar_test.rb +646 -0
  108. data/test/v_object/component/v_card_test.rb +258 -0
  109. data/test/v_object/component/v_event_test.rb +85 -0
  110. data/test/v_object/component/v_free_busy_test.rb +59 -0
  111. data/test/v_object/component/v_journal_test.rb +85 -0
  112. data/test/v_object/component/v_time_zone_test.rb +47 -0
  113. data/test/v_object/component/v_todo_test.rb +172 -0
  114. data/test/v_object/component_test.rb +419 -0
  115. data/test/v_object/date_time_parser_test.rb +526 -0
  116. data/test/v_object/document_test.rb +71 -0
  117. data/test/v_object/element_list_test.rb +27 -0
  118. data/test/v_object/em_client_test.rb +53 -0
  119. data/test/v_object/empty_parameter_test.rb +65 -0
  120. data/test/v_object/empty_value_issue_test.rb +25 -0
  121. data/test/v_object/fake_component.rb +21 -0
  122. data/test/v_object/free_busy_data_test.rb +285 -0
  123. data/test/v_object/free_busy_generator_test.rb +637 -0
  124. data/test/v_object/google_colon_escaping_test.rb +27 -0
  125. data/test/v_object/i_calendar/attach_parse_test.rb +24 -0
  126. data/test/v_object/i_tip/broker_attendee_reply_test.rb +1042 -0
  127. data/test/v_object/i_tip/broker_delete_event_test.rb +175 -0
  128. data/test/v_object/i_tip/broker_new_event_test.rb +440 -0
  129. data/test/v_object/i_tip/broker_process_message_test.rb +153 -0
  130. data/test/v_object/i_tip/broker_process_reply_test.rb +402 -0
  131. data/test/v_object/i_tip/broker_tester.rb +71 -0
  132. data/test/v_object/i_tip/broker_update_event_test.rb +763 -0
  133. data/test/v_object/i_tip/evolution_test.rb +2644 -0
  134. data/test/v_object/i_tip/message_test.rb +25 -0
  135. data/test/v_object/issue153.vcf +352 -0
  136. data/test/v_object/issue153_test.rb +12 -0
  137. data/test/v_object/issue26_test.rb +25 -0
  138. data/test/v_object/issue36_work_around_test.rb +37 -0
  139. data/test/v_object/issue40_test.rb +26 -0
  140. data/test/v_object/issue64.vcf +351 -0
  141. data/test/v_object/issue64_test.rb +17 -0
  142. data/test/v_object/issue96_test.rb +22 -0
  143. data/test/v_object/issue_undefined_index_test.rb +24 -0
  144. data/test/v_object/j_cal_test.rb +150 -0
  145. data/test/v_object/j_card_test.rb +192 -0
  146. data/test/v_object/line_folding_issue_test.rb +19 -0
  147. data/test/v_object/mock_document.rb +6 -0
  148. data/test/v_object/parameter_test.rb +109 -0
  149. data/test/v_object/parser/json_test.rb +370 -0
  150. data/test/v_object/parser/mime_dir_test.rb +14 -0
  151. data/test/v_object/parser/quoted_printable_test.rb +78 -0
  152. data/test/v_object/parser/xml_test.rb +2563 -0
  153. data/test/v_object/property/binary_test.rb +12 -0
  154. data/test/v_object/property/boolean_test.rb +18 -0
  155. data/test/v_object/property/compound_test.rb +43 -0
  156. data/test/v_object/property/float_test.rb +20 -0
  157. data/test/v_object/property/i_calendar/cal_address_test.rb +26 -0
  158. data/test/v_object/property/i_calendar/date_time_test.rb +303 -0
  159. data/test/v_object/property/i_calendar/duration_test.rb +14 -0
  160. data/test/v_object/property/i_calendar/recur_test.rb +39 -0
  161. data/test/v_object/property/text_test.rb +81 -0
  162. data/test/v_object/property/v_card/date_and_or_time_test.rb +205 -0
  163. data/test/v_object/property/v_card/language_tag_test.rb +35 -0
  164. data/test/v_object/property_test.rb +338 -0
  165. data/test/v_object/reader_test.rb +403 -0
  166. data/test/v_object/recur/event_iterator/by_month_in_daily_test.rb +52 -0
  167. data/test/v_object/recur/event_iterator/by_set_pos_hang_test.rb +55 -0
  168. data/test/v_object/recur/event_iterator/expand_floating_times_test.rb +109 -0
  169. data/test/v_object/recur/event_iterator/fifth_tuesday_problem_test.rb +45 -0
  170. data/test/v_object/recur/event_iterator/incorrect_expand_test.rb +53 -0
  171. data/test/v_object/recur/event_iterator/infinite_loop_problem_test.rb +75 -0
  172. data/test/v_object/recur/event_iterator/issue48_test.rb +43 -0
  173. data/test/v_object/recur/event_iterator/issue50_test.rb +123 -0
  174. data/test/v_object/recur/event_iterator/main_test.rb +1222 -0
  175. data/test/v_object/recur/event_iterator/missing_overridden_test.rb +55 -0
  176. data/test/v_object/recur/event_iterator/no_instances_test.rb +32 -0
  177. data/test/v_object/recur/event_iterator/override_first_event_test.rb +106 -0
  178. data/test/v_object/recur/r_date_iterator_test.rb +44 -0
  179. data/test/v_object/recur/r_rule_iterator_test.rb +608 -0
  180. data/test/v_object/recurrence_iterator/UntilRespectsTimezoneTest.ics +39 -0
  181. data/test/v_object/slash_r_test.rb +15 -0
  182. data/test/v_object/splitter/i_calendar_test.rb +299 -0
  183. data/test/v_object/splitter/v_card_test.rb +173 -0
  184. data/test/v_object/string_util_test.rb +37 -0
  185. data/test/v_object/test_case.rb +42 -0
  186. data/test/v_object/time_zone_util_test.rb +271 -0
  187. data/test/v_object/uuid_util_test.rb +18 -0
  188. data/test/v_object/v_card21_test.rb +43 -0
  189. data/test/v_object/v_card_converter_test.rb +419 -0
  190. data/test/v_object/version_test.rb +15 -0
  191. data/test/v_object/writer_test.rb +33 -0
  192. data/tilia-vobject.gemspec +17 -0
  193. metadata +308 -0
@@ -0,0 +1,354 @@
1
+ require 'base64'
2
+ module Tilia
3
+ module VObject
4
+ # This utility converts vcards from one version to another.
5
+ class VCardConverter
6
+ # Converts a vCard object to a new version.
7
+ #
8
+ # targetVersion must be one of:
9
+ # Document::VCARD21
10
+ # Document::VCARD30
11
+ # Document::VCARD40
12
+ #
13
+ # Currently only 3.0 and 4.0 as input and output versions.
14
+ #
15
+ # 2.1 has some minor support for the input version, it's incomplete at the
16
+ # moment though.
17
+ #
18
+ # If input and output version are identical, a clone is returned.
19
+ #
20
+ # @param Component\VCard input
21
+ # @param int target_version
22
+ def convert(input, target_version)
23
+ input_version = input.document_type
24
+ return input.dup if input_version == target_version
25
+
26
+ unless [Tilia::VObject::Document::VCARD21, Tilia::VObject::Document::VCARD30, Tilia::VObject::Document::VCARD40].include? input_version
27
+ fail ArgumentError, 'Only vCard 2.1, 3.0 and 4.0 are supported for the input data'
28
+ end
29
+ unless [Tilia::VObject::Document::VCARD30, Tilia::VObject::Document::VCARD40].include? target_version
30
+ fail ArgumentError, 'You can only use vCard 3.0 or 4.0 for the target version'
31
+ end
32
+
33
+ new_version = target_version == Tilia::VObject::Document::VCARD40 ? '4.0' : '3.0'
34
+
35
+ output = Tilia::VObject::Component::VCard.new('VERSION' => new_version)
36
+
37
+ input.children.each do |property|
38
+ convert_property(input, output, property, target_version)
39
+ end
40
+
41
+ output
42
+ end
43
+
44
+ protected
45
+
46
+ # Handles conversion of a single property.
47
+ #
48
+ # @param Component\VCard input
49
+ # @param Component\VCard output
50
+ # @param Property property
51
+ # @param int target_version
52
+ #
53
+ # @return void
54
+ def convert_property(input, output, property, target_version)
55
+ # Skipping these, those are automatically added.
56
+ return nil if %w(VERSION PRODID).include?(property.name)
57
+
58
+ parameters = property.parameters
59
+ value_type = nil
60
+ if parameters.key?('VALUE')
61
+ value_type = parameters['VALUE'].value
62
+ parameters.delete('VALUE')
63
+ end
64
+
65
+ value_type = property.value_type unless value_type
66
+
67
+ new_property = output.create_property(
68
+ property.name,
69
+ property.parts,
70
+ {}, # parameters will get added a bit later.
71
+ value_type
72
+ )
73
+
74
+ if target_version == Tilia::VObject::Document::VCARD30
75
+ if property.is_a?(Tilia::VObject::Property::Uri) && %w(PHOTO LOGO SOUND).include?(property.name)
76
+ new_property = convert_uri_to_binary(output, new_property)
77
+ elsif property.is_a? Tilia::VObject::Property::VCard::DateAndOrTime
78
+ # In vCard 4, the birth year may be optional. This is not the
79
+ # case for vCard 3. Apple has a workaround for this that
80
+ # allows applications that support Apple's extension still
81
+ # omit birthyears in vCard 3, but applications that do not
82
+ # support this, will just use a random birthyear. We're
83
+ # choosing 1604 for the birthyear, because that's what apple
84
+ # uses.
85
+ parts = Tilia::VObject::DateTimeParser.parse_v_card_date_time(property.value)
86
+ if parts['year'].nil?
87
+ new_value = format('1604-%02i-%02i', parts['month'].to_i, parts['date'].to_i)
88
+ new_property.value = new_value
89
+ new_property['X-APPLE-OMIT-YEAR'] = '1604'
90
+ end
91
+
92
+ if new_property.name == 'ANNIVERSARY'
93
+ # Microsoft non-standard anniversary
94
+ new_property.name = 'X-ANNIVERSARY'
95
+
96
+ # We also need to add a new apple property for the same
97
+ # purpose. This apple property needs a 'label' in the same
98
+ # group, so we first need to find a groupname that doesn't
99
+ # exist yet.
100
+ x = 1
101
+ loop do
102
+ break if output.select("ITEM#{x}.").empty?
103
+ x += 1
104
+ end
105
+ output.add("ITEM#{x}.X-ABDATE", new_property.value, 'VALUE' => 'DATE-AND-OR-TIME')
106
+ output.add("ITEM#{x}.X-ABLABEL", '_$!<Anniversary>!$_')
107
+ end
108
+ elsif property.name == 'KIND'
109
+ case property.value.downcase
110
+ when 'org'
111
+ # vCard 3.0 does not have an equivalent to KIND:ORG,
112
+ # but apple has an extension that means the same
113
+ # thing.
114
+ new_property = output.create_property('X-ABSHOWAS', 'COMPANY')
115
+ when 'individual'
116
+ # Individual is implicit, so we skip it.
117
+ return nil
118
+ when 'group'
119
+ # OS X addressbook property
120
+ new_property = output.create_property('X-ADDRESSBOOKSERVER-KIND', 'GROUP')
121
+ end
122
+ end
123
+ elsif target_version == Tilia::VObject::Document::VCARD40
124
+ # These properties were removed in vCard 4.0
125
+ return nil if %w(NAME MAILER LABEL CLASS).include?(property.name)
126
+
127
+ if property.is_a?(Tilia::VObject::Property::Binary)
128
+ new_property = convert_binary_to_uri(output, new_property, parameters)
129
+ elsif property.is_a?(Tilia::VObject::Property::VCard::DateAndOrTime) && parameters.key?('X-APPLE-OMIT-YEAR')
130
+ # If a property such as BDAY contained 'X-APPLE-OMIT-YEAR',
131
+ # then we're stripping the year from the vcard 4 value.
132
+ parts = Tilia::VObject::DateTimeParser.parse_v_card_date_time(property.value)
133
+ if parts['year'] == property['X-APPLE-OMIT-YEAR'].value.to_i
134
+ new_value = format('--%02i-%02i', parts['month'], parts['date'])
135
+ new_property.value = new_value
136
+ end
137
+
138
+ # Regardless if the year matched or not, we do need to strip
139
+ # X-APPLE-OMIT-YEAR.
140
+ parameters.delete('X-APPLE-OMIT-YEAR')
141
+ end
142
+
143
+ case property.name
144
+ when 'X-ABSHOWAS'
145
+ if property.value.upcase == 'COMPANY'
146
+ new_property = output.create_property('KIND', 'ORG')
147
+ end
148
+ when 'X-ADDRESSBOOKSERVER-KIND'
149
+ if property.value.upcase == 'GROUP'
150
+ new_property = output.create_property('KIND', 'GROUP')
151
+ end
152
+ when 'X-ANNIVERSARY'
153
+ new_property.name = 'ANNIVERSARY'
154
+ # If we already have an anniversary property with the same
155
+ # value, ignore.
156
+ output.select('ANNIVERSARY').each do |anniversary|
157
+ return nil if anniversary.value == new_property.value
158
+ end
159
+ when 'X-ABDATE'
160
+ # Find out what the label was, if it exists.
161
+ label = input["#{property.group}.X-ABLABEL"]
162
+
163
+ # We only support converting anniversaries.
164
+ if property.group && label && label.value == '_$!<Anniversary>!$_'
165
+ # If we already have an anniversary property with the same
166
+ # value, ignore.
167
+ output.select('ANNIVERSARY').each do |anniversary|
168
+ return nil if anniversary.value == new_property.value
169
+ end
170
+ new_property.name = 'ANNIVERSARY'
171
+ end
172
+ # Apple's per-property label system.
173
+ when 'X-ABLABEL'
174
+ if new_property.value == '_$!<Anniversary>!$_'
175
+ # We can safely remove these, as they are converted to
176
+ # ANNIVERSARY properties.
177
+ return nil
178
+ end
179
+ end
180
+ end
181
+
182
+ # set property group
183
+ new_property.group = property.group
184
+
185
+ if target_version == Tilia::VObject::Document::VCARD40
186
+ convert_parameters40(new_property, parameters)
187
+ else
188
+ convert_parameters30(new_property, parameters)
189
+ end
190
+
191
+ # Lastly, we need to see if there's a need for a VALUE parameter.
192
+ #
193
+ # We can do that by instantating a empty property with that name, and
194
+ # seeing if the default valueType is identical to the current one.
195
+ temp_property = output.create_property(new_property.name)
196
+ if temp_property.value_type != new_property.value_type
197
+ new_property['VALUE'] = new_property.value_type
198
+ end
199
+
200
+ output.add(new_property)
201
+ end
202
+
203
+ # Converts a BINARY property to a URI property.
204
+ #
205
+ # vCard 4.0 no longer supports BINARY properties.
206
+ #
207
+ # @param Component\VCard output
208
+ # @param Tilia::VObject::Property::Uri property The input property.
209
+ # @param parameters List of parameters that will eventually be added to
210
+ # the new property.
211
+ #
212
+ # @return Tilia::VObject::Property::Uri
213
+ def convert_binary_to_uri(output, new_property, parameters)
214
+ value = new_property.value
215
+ new_property = output.create_property(
216
+ new_property.name,
217
+ nil, # no value
218
+ {}, # no parameters yet
219
+ 'URI' # Forcing the BINARY type
220
+ )
221
+
222
+ mime_type = 'application/octet-stream'
223
+
224
+ # See if we can find a better mimetype.
225
+ if parameters.key?('TYPE')
226
+ new_types = []
227
+ parameters['TYPE'].parts.each do |type_part|
228
+ if %w(JPEG PNG GIF).include?(type_part.upcase)
229
+ mime_type = "image/#{type_part.downcase}"
230
+ else
231
+ new_types << type_part
232
+ end
233
+ end
234
+
235
+ # If there were any parameters we're not converting to a
236
+ # mime-type, we need to keep them.
237
+ if new_types.any?
238
+ parameters['TYPE'].parts = new_types
239
+ else
240
+ parameters.delete('TYPE')
241
+ end
242
+ end
243
+
244
+ new_property.value = "data:#{mime_type};base64,#{Base64.strict_encode64(value)}"
245
+ new_property
246
+ end
247
+
248
+ # Converts a URI property to a BINARY property.
249
+ #
250
+ # In vCard 4.0 attachments are encoded as data: uri. Even though these may
251
+ # be valid in vCard 3.0 as well, we should convert those to BINARY if
252
+ # possible, to improve compatibility.
253
+ #
254
+ # @param Component\VCard output
255
+ # @param Tilia::VObject::Property::Uri property The input property.
256
+ #
257
+ # @return Tilia::VObject::Property::Binary|null
258
+ def convert_uri_to_binary(output, new_property)
259
+ value = new_property.value
260
+
261
+ # Only converting data: uris
262
+ return new_property if value[0...5] != 'data:'
263
+
264
+ new_property = output.create_property(
265
+ new_property.name,
266
+ nil, # no value
267
+ {}, # no parameters yet
268
+ 'BINARY'
269
+ )
270
+
271
+ mime_type = value[5...value.index(',')]
272
+ if mime_type.index(';')
273
+ mime_type = mime_type[0...mime_type.index(';')]
274
+ new_property.value = Base64.decode64(value[value.index(',') + 1..-1])
275
+ else
276
+ new_property.value = value[value.index(',') + 1..-1]
277
+ end
278
+
279
+ new_property['ENCODING'] = 'b'
280
+ case mime_type
281
+ when 'image/jpeg'
282
+ new_property['TYPE'] = 'JPEG'
283
+ when 'image/png'
284
+ new_property['TYPE'] = 'PNG'
285
+ when 'image/gif'
286
+ new_property['TYPE'] = 'GIF'
287
+ end
288
+
289
+ new_property
290
+ end
291
+
292
+ # Adds parameters to a new property for vCard 4.0.
293
+ #
294
+ # @param Property new_property
295
+ # @param array parameters
296
+ #
297
+ # @return void
298
+ def convert_parameters40(new_property, parameters)
299
+ # Adding all parameters.
300
+ parameters.each do |_, param|
301
+ # vCard 2.1 allowed parameters with no name
302
+ param.no_name = false if param.no_name
303
+
304
+ case param.name
305
+ # We need to see if there's any TYPE=PREF, because in vCard 4
306
+ # that's now PREF=1.
307
+ when 'TYPE'
308
+ param.parts.each do |param_part|
309
+ if param_part.upcase == 'PREF'
310
+ new_property.add('PREF', '1')
311
+ else
312
+ new_property.add(param.name, param_part)
313
+ end
314
+ end
315
+ when 'ENCODING', 'CHARSET'
316
+ # These no longer exist in vCard 4
317
+ else
318
+ new_property.add(param.name, param.parts)
319
+ end
320
+ end
321
+ end
322
+
323
+ # Adds parameters to a new property for vCard 3.0.
324
+ #
325
+ # @param Property new_property
326
+ # @param array parameters
327
+ #
328
+ # @return void
329
+ def convert_parameters30(new_property, parameters)
330
+ # Adding all parameters.
331
+ parameters.each do |_, param|
332
+ # vCard 2.1 allowed parameters with no name
333
+ param.no_name = false if param.no_name
334
+
335
+ case param.name
336
+ when 'ENCODING'
337
+ # This value only existed in vCard 2.1, and should be
338
+ # removed for anything else.
339
+ if param.value.upcase != 'QUOTED-PRINTABLE'
340
+ new_property.add(param.name, param.parts)
341
+ end
342
+ # Converting PREF=1 to TYPE=PREF.
343
+ #
344
+ # Any other PREF numbers we'll drop.
345
+ when 'PREF'
346
+ new_property.add('TYPE', 'PREF') if param.value == '1'
347
+ else
348
+ new_property.add(param.name, param.parts)
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end
@@ -0,0 +1,9 @@
1
+ module Tilia
2
+ module VObject
3
+ # This class contains the version number for the VObject package.
4
+ class Version
5
+ # Full version number.
6
+ VERSION = '4.0.0-alpha2'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ require 'json'
2
+ module Tilia
3
+ module VObject
4
+ # iCalendar/vCard/jCal/jCard/xCal/xCard writer object.
5
+ #
6
+ # This object provides a few (static) convenience methods to quickly access
7
+ # the serializers.
8
+ class Writer
9
+ # Serializes a vCard or iCalendar object.
10
+ #
11
+ # @param Component component
12
+ #
13
+ # @return string
14
+ def self.write(component)
15
+ component.serialize
16
+ end
17
+
18
+ # Serializes a jCal or jCard object.
19
+ #
20
+ # @param Component component
21
+ # @param int options
22
+ #
23
+ # @return string
24
+ def self.write_json(component)
25
+ component.json_serialize.to_json
26
+ end
27
+
28
+ # Serializes a xCal or xCard object.
29
+ #
30
+ # @param Component component
31
+ #
32
+ # @return string
33
+ def self.write_xml(component)
34
+ writer = Tilia::Xml::Writer.new
35
+ writer.open_memory
36
+ writer.set_indent(true)
37
+
38
+ writer.start_document(encoding: LibXML::XML::Encoding::UTF_8)
39
+
40
+ if component.is_a? Tilia::VObject::Component::VCalendar
41
+ writer.start_element('icalendar')
42
+ writer.write_attribute('xmlns', Tilia::VObject::Parser::Xml::XCAL_NAMESPACE)
43
+ else
44
+ writer.start_element('vcards')
45
+ writer.write_attribute('xmlns', Tilia::VObject::Parser::Xml::XCARD_NAMESPACE)
46
+ end
47
+
48
+ component.xml_serialize(writer)
49
+
50
+ writer.end_element
51
+
52
+ writer.output_memory
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,45 @@
1
+ # Namespace for Tilia library
2
+ module Tilia
3
+ # Load active support core extensions
4
+ require 'active_support'
5
+ require 'active_support/core_ext'
6
+
7
+ # Mail encoding stuff
8
+ require 'mail'
9
+
10
+ # Char detecting functions
11
+ require 'rchardet'
12
+
13
+ # Our XML stuff
14
+ require 'tilia/xml'
15
+
16
+ # Namespace of tilia_vobject library
17
+ module VObject
18
+ require 'tilia/v_object/version'
19
+ require 'tilia/v_object/element_list'
20
+ require 'tilia/v_object/node'
21
+ require 'tilia/v_object/parameter'
22
+ require 'tilia/v_object/property'
23
+ require 'tilia/v_object/date_time_parser'
24
+ require 'tilia/v_object/uuid_util'
25
+ require 'tilia/v_object/component'
26
+ require 'tilia/v_object/document'
27
+ require 'tilia/v_object/parse_exception'
28
+ require 'tilia/v_object/eof_exception'
29
+ require 'tilia/v_object/reader'
30
+ require 'tilia/v_object/settings'
31
+ require 'tilia/v_object/string_util'
32
+ require 'tilia/v_object/time_zone_util'
33
+ require 'tilia/v_object/writer'
34
+ require 'tilia/v_object/i_tip'
35
+ require 'tilia/v_object/parser'
36
+ require 'tilia/v_object/recur'
37
+ require 'tilia/v_object/splitter'
38
+ require 'tilia/v_object/time_zone_data'
39
+ require 'tilia/v_object/v_card_converter'
40
+ require 'tilia/v_object/birthday_calendar_generator'
41
+ require 'tilia/v_object/free_busy_data'
42
+ require 'tilia/v_object/free_busy_generator'
43
+ require 'tilia/v_object/cli'
44
+ end
45
+ end
@@ -0,0 +1 @@
1
+ require 'tilia/v_object'