Class: Tilia::VObject::Component::VCard
- Inherits:
-
Document
- Object
- Node
- Tilia::VObject::Component
- Document
- Tilia::VObject::Component::VCard
- Defined in:
- lib/tilia/v_object/component/v_card.rb
Overview
The VCard component.
This component represents the BEGIN:VCARD and END:VCARD found in every vcard.
Constant Summary collapse
- DEFAULT_VERSION =
VCards with version 2.1, 3.0 and 4.0 are found.
If the VCARD doesn’t know its version, 2.1 is assumed.
VCARD21
Constants inherited from Document
Document::ICALENDAR20, Document::UNKNOWN, Document::VCALENDAR10, Document::VCARD21, Document::VCARD30, Document::VCARD40
Constants inherited from Node
Node::PROFILE_CALDAV, Node::PROFILE_CARDDAV, Node::REPAIR
Instance Attribute Summary
Attributes inherited from Tilia::VObject::Component
Attributes inherited from Node
Instance Method Summary collapse
-
#class_name_for_property_name(property_name) ⇒ String
Returns the default class for a property name.
-
#convert(target) ⇒ VCard
Converts the document to a different vcard version.
-
#document_type ⇒ Fixnum
Returns the current document type.
-
#initialize(*args) ⇒ VCard
constructor
sets instance variables.
-
#json_serialize ⇒ Array
This method returns an array, with the representation as it should be encoded in json.
-
#preferred(property_name) ⇒ Property?
Returns a preferred field.
-
#validate(options = 0) ⇒ array
Validates the node for correctness.
-
#validation_rules ⇒ array
A simple list of validation rules.
-
#xml_serialize(writer) ⇒ void
This method serializes the data into XML.
Methods inherited from Document
#class_name_for_property_value, #create, #create_component, #create_property
Methods inherited from Tilia::VObject::Component
#[], #[]=, #add, #children, #components, #delete, #destroy, #initialize_copy, #key?, #remove, #select, #serialize, #to_s
Methods inherited from Node
#==, #[], #[]=, #delete, #destroy, #each, #key?, #serialize, #size
Constructor Details
#initialize(*args) ⇒ VCard
sets instance variables
423 424 425 426 |
# File 'lib/tilia/v_object/component/v_card.rb', line 423 def initialize(*args) super @version = nil end |
Instance Method Details
#class_name_for_property_name(property_name) ⇒ String
Returns the default class for a property name.
411 412 413 414 415 416 417 418 419 420 |
# File 'lib/tilia/v_object/component/v_card.rb', line 411 def class_name_for_property_name(property_name) class_name = super(property_name) # In vCard 4, BINARY no longer exists, and we need URI instead. if class_name == Property::Binary && document_type == VCARD40 return Property::Uri end class_name end |
#convert(target) ⇒ VCard
Converts the document to a different vcard version.
Use one of the VCARD constants for the target. This method will return a copy of the vcard in the new version.
At the moment the only supported conversion is from 3.0 to 4.0.
If input and output version are identical, a clone is returned.
150 151 152 153 |
# File 'lib/tilia/v_object/component/v_card.rb', line 150 def convert(target) converter = VCardConverter.new converter.convert(self, target) end |
#document_type ⇒ Fixnum
Returns the current document type.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/tilia/v_object/component/v_card.rb', line 117 def document_type unless @version version = self['VERSION'].to_s case version when '2.1' @version = VCARD21 when '3.0' @version = VCARD30 when '4.0' @version = VCARD40 else # We don't want to cache the version if it's unknown, # because we might get a version property in a bit. return UNKNOWN end end @version end |
#json_serialize ⇒ Array
This method returns an array, with the representation as it should be encoded in json. This is used to create jCard or jCal documents.
351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/tilia/v_object/component/v_card.rb', line 351 def json_serialize # A vcard does not have sub-components, so we're overriding this # method to remove that array element. properties = [] children.each do |child| properties << child.json_serialize end [@name.downcase, properties] end |
#preferred(property_name) ⇒ Property?
Returns a preferred field.
VCards can indicate wether a field such as ADR, TEL or EMAIL is preferred by specifying TYPE=PREF (vcard 2.1, 3) or PREF=x (vcard 4, x being a number between 1 and 100).
If neither of those parameters are specified, the first is returned, if a field with that name does not exist, null is returned.
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/tilia/v_object/component/v_card.rb', line 311 def preferred(property_name) preferred = nil last_pref = 101 select(property_name).each do |field| pref = 101 if field.key?('TYPE') && field['TYPE'].has('PREF') pref = 1 elsif field.key?('PREF') pref = field['PREF'].value.to_i end if pref < last_pref || preferred.nil? preferred = field last_pref = pref end end preferred end |
#validate(options = 0) ⇒ array
Validates the node for correctness.
The following options are supported:
Node::REPAIR - May attempt to automatically repair the problem.
Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
This method returns an array with detected problems. Every element has the following properties:
* level - problem level.
* message - A human-readable string describing the issue.
* node - A reference to the problematic node.
The level means:
1 - The issue was repaired (only happens if REPAIR was turned on).
2 - A warning.
3 - An error.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/tilia/v_object/component/v_card.rb', line 161 def validate( = 0) warnings = [] version_map = { VCARD21 => '2.1', VCARD30 => '3.0', VCARD40 => '4.0' } version = select('VERSION') if version.size == 1 version = self['VERSION'].to_s unless ['2.1', '3.0', '4.0'].include?(version) warnings << { 'level' => 3, 'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.', 'node' => self } if & REPAIR > 0 self['VERSION'] = version_map[DEFAULT_VERSION] end end if version == '2.1' && & PROFILE_CARDDAV > 0 warnings << { 'level' => 3, 'message' => 'CardDAV servers are not allowed to accept vCard 2.1.', 'node' => self } end end uid = select('UID') if uid.size == 0 if & PROFILE_CARDDAV > 0 # Required for CardDAV warning_level = 3 = 'vCards on CardDAV servers MUST have a UID property.' else # Not required for regular vcards warning_level = 2 = 'Adding a UID to a vCard property is recommended.' end if & REPAIR > 0 self['UID'] = UuidUtil.uuid warning_level = 1 end warnings << { 'level' => warning_level, 'message' => , 'node' => self } end fn = select('FN') if fn.size != 1 repaired = false if & REPAIR > 0 && fn.size == 0 # We're going to try to see if we can use the contents of the # N property. if key?('N') value = self['N'].to_s.split(';') if value[1] self['FN'] = value[1] + ' ' + value[0] else self['FN'] = value[0] end repaired = true # Otherwise, the ORG property may work elsif key?('ORG') self['FN'] = self['ORG'].to_s repaired = true end end warnings << { 'level' => repaired ? 1 : 3, 'message' => 'The FN property must appear in the VCARD component exactly 1 time', 'node' => self } end w = super() w.concat warnings w end |
#validation_rules ⇒ array
A simple list of validation rules.
This is simply a list of properties, and how many times they either must or must not appear.
Possible values per property:
* 0 - Must not appear.
* 1 - Must appear exactly once.
* + - Must appear at least once.
* * - Can appear any number of times.
* ? - May appear, but not more than once.
It is also possible to specify defaults and severity levels for violating the rule.
See the VEVENT implementation for getValidationRules for a more complex example.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/tilia/v_object/component/v_card.rb', line 255 def validation_rules { 'ADR' => '*', 'ANNIVERSARY' => '?', 'BDAY' => '?', 'CALADRURI' => '*', 'CALURI' => '*', 'CATEGORIES' => '*', 'CLIENTPIDMAP' => '*', 'EMAIL' => '*', 'FBURL' => '*', 'IMPP' => '*', 'GENDER' => '?', 'GEO' => '*', 'KEY' => '*', 'KIND' => '?', 'LANG' => '*', 'LOGO' => '*', 'MEMBER' => '*', 'N' => '?', 'NICKNAME' => '*', 'NOTE' => '*', 'ORG' => '*', 'PHOTO' => '*', 'PRODID' => '?', 'RELATED' => '*', 'REV' => '?', 'ROLE' => '*', 'SOUND' => '*', 'SOURCE' => '*', 'TEL' => '*', 'TITLE' => '*', 'TZ' => '*', 'URL' => '*', 'VERSION' => '1', 'XML' => '*', # FN is commented out, because it's already handled by the # validate function, which may also try to repair it. # 'FN' => '+', 'UID' => '?' } end |
#xml_serialize(writer) ⇒ void
This method returns an undefined value.
This method serializes the data into XML. This is used to create xCard or xCal documents.
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/tilia/v_object/component/v_card.rb', line 369 def xml_serialize(writer) properties_by_group = {} children.each do |property| group = property.group properties_by_group[group] = [] unless properties_by_group[group] properties_by_group[group] << property end writer.start_element(@name.downcase) properties_by_group.each do |group, properties| unless group.blank? writer.start_element('group') writer.write_attribute('name', group.downcase) end properties.each do |property| case property.name when 'VERSION' next when 'XML' value = property.parts fragment = Tilia::Xml::Element::XmlFragment.new(value[0]) writer.write(fragment) else property.xml_serialize(writer) end end writer.end_element unless group.blank? end writer.end_element end |