Closed hubearth closed 7 years ago
Although I don't understand this part of the code, this behaviour is rooted in base.py in this function:
def add(self, objOrName, group=None):
if isinstance(objOrName, VBase):
obj = objOrName
if self.behavior:
obj.parentBehavior = self.behavior
obj.autoBehavior(True)
else:
name = objOrName.upper()
try:
id = self.behavior.knownChildren[name][2]
behavior = getBehavior(name, id)
if behavior.isComponent:
obj = Component(name)
else:
obj = ContentLine(name, [], '', group)
obj.parentBehavior = self.behavior
obj.behavior = behavior
obj = obj.transformToNative()
except (KeyError, AttributeError):
obj = ContentLine(objOrName, [], '', group)
if obj.behavior is None and self.behavior is not None:
if isinstance(obj, ContentLine):
obj.behavior = self.behavior.defaultBehavior
self.contents.setdefault(obj.name.lower(), []).append(obj)
return obj
With j.add('title'), it runs into try: and breaks on the first line
id = self.behavior.knownChildren[name][2]
so it jumps on the except statement.
With j.add('org'), it continues in the try without error.
I did a pull request thinking that it would solve the problem, but it seems that I have a more complexe issue, maybe related to my IDE. I need to re-evaluate j.serialize() before running the line. Any idea if it's a problem with my setting or the library?
I'm seeing this issue too
Well, the cardinality of ORG is *, so I think that the max parameter is correctly None
. I'll look into it.
Yeah, after looking at the specs and some of the examples that Jeffery wrote, it looks like because ORG can have zero or more values (up to an infinite number) you want to always make it a list. To assign a single value to this list I would suggest using something like
j.org.value = ["My organization"]
where you give the org the value of your organization name as a single-element list.
Okay, so after digging in the spec for a little while, I finally figured out why it behaves like this. When you add an ORG ContentLine, it is supposed to be a list, because each element of the list is supposed to be a more specific distinction within the organization.
From RFC 6350 Section 6.6.4:
Example: A property value consisting of an organizational name, organizational unit #1 name, and organizational unit #2 name.
ORG:ABC\, Inc.;North American Division;Marketing
So I could create a vCard for myself using the following organizational distinctions:
>>> c = vobject.vCard()
>>> c.add('fn').value = "Will"
>>> c.add('org').value = ['Eventable', 'Engineering Team', 'Backend']
>>> print c.serialize()
BEGIN:VCARD
VERSION:3.0
FN:Will
ORG:Eventable;Engineering Team;Backend
END:VCARD
This is mildly inconvenient, but I believe it's necessary in order to match the spec.
It's also worth noting that if you have someone who is a member of multiple organizations, you should create multiple content lines according to RFC 5545 Section 3.1.2:
>>> c = vobject.vCard()
>>> c.add('fn').value = "Will"
>>> c.add('org').value = ['Eventable', 'Engineering Team', 'Backend']
>>> c.add('org').value = ['CalConnect']
>>> print c.serialize()
BEGIN:VCARD
VERSION:3.0
FN:Will
ORG:Eventable;Engineering Team;Backend
ORG:CalConnect
END:VCARD
Little Tip:
that kind of script is pretty good if you are working with constant :
c.add('org').value = ['Eventable', 'Engineering Team', 'Backend']
If you want to set your first 'org' with variables you can do like this :
c.add('org').value[0] = myVar
Hope this helps.
When creating a 'title' entry, for exemple,
j.add('title')
creates an object defined as this:But, when creating a 'org' entry,
j.add('org')
creates an array like this:So, this means that doing this:
j.org.value = "My organization"
you will get this:j.org.value -> <class 'list'>: ['M', 'y', ' ', 'o', 'r', 'g', 'a', 'n', 'i', 'z', 'a', 't', 'i', 'o', 'n']
I'm using python 3.4 vobject 0.9.4.1 IDE: LiClipse 3.3 running over Eclipse 4.6.1 OS: Debian 8.0