Re: [os-libsynthesis] vCard group tags
On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote: On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote: I noticed another problem with the use X-ABLabel parameter approach: storing complex strings (spaces, quotation marks) in a parameter value is harder. That's probably why Apple chose the X-ABLabel property approach. An unparseable parameter could ruin the real data, a unknown property is less dangerous. The EDS vCard parser gets it wrong and fails to parse: X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner That is valid according to http://tools.ietf.org/html/rfc2425#page-5 because the space is a SAFE-CHAR and thus may appear in a ptext, but the EDS parser does not expect the space. To work around this, we could voluntarily quote the string even though it is not required. Now, the conceptual problem with X-ABLabel parameter is that a quoted string cannot contain double quotes. It is probably rare that a user enters double quotes as part of a label, but it cannot be ruled out either. Line breaks are also only allowed in property values and not parameter values. I've looked into TMimeDirProfileHandler::generateValue() some more to understand under which circumstances libsynthesis uses quoted strings (with double quotes at start and end) as parameter value. At first glance it doesn't seem to do that at all. Instead special values are escaped with backslash. item29.X-ABLabel:custom-label5\nUmlaut-ä\nSemicolon\; - X-ABRELATEDNAMES;X-ABLabel=custom-label5\nUmlaut-ä\nSemicolon\;:custom relationship Where is it specified that the backslash escape mechanism can be used in parameter values? http://tools.ietf.org/html/rfc2425#page-5 says: param= param-name = param-value *(, param-value) param-name = x-name / iana-token param-value = ptext / quoted-string ptext = *SAFE-CHAR SAFE-CHAR= WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII ; Any character except CTLs, DQUOTE, ;, :, , My reading of that is that special characters must not appear in a ptext at all, not even when escaped with backslash. One has to use a quoted string, which (unfortunately) cannot hold all characters either. IMHO libsynthesis is currently producing broken vCards. I consider changing the code so that it uses quoted strings if it detects unsafe characters in the value and filters out invalid ones. unsafe would be more conservative than in the RFC itself and also include spaces, to work around the EDS parser bug. -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter. ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
Re: [os-libsynthesis] vCard group tags
Hello Patrick, On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote: What do you mean by independent properties? For example, ADR and TEL are independent in the sense that their values are stored in different field arrays. Sharing the LABEL field for the new parameter creates a dependency (or risk of collision) that did not exist before. But how can this work at all? The index in the field arrays is what relates the components (e.g. TEL, TEL_FLAGS and LABEL) to each other. This would mean all of the field arrays would need to have rows for the *sum* of all the TEL+ADR+EMAIL+URL+xxx, with most rows empty, to be able to share a single LABEL array. Now I see why you want to check the availability of LABEL row even if assigned via a property parameter. Hmmm - indeed this might work, at the expense of a lot of empty elements in the actual property field arrays. I'm just not sure right now if the generator part of MimeProfile is prepared for properly skipping entirely empty rows to avoid generating empty property lines in the vCard output. But that would be fixable as well. [...] It's simpler. TEL;X-ABLabel=labelTel:123456789 ADR;X-ABLabel=labelAdr:xxx stores only the second label at position #0 = LABEL = [ 'labelAdr' ] Understood now. Yes, because the only thing TEL and ADR have in common is the LABEL, and this is not checked. That's because the code which checks where to store the ADR value does not check whether the LABEL at the position is available. There's another problem: TEL:123456789 ADR;X-ABLabel=labelAdr:xxx A simplistic check LABEL[0] empty will accept position #0 for ADR. But doing so will add the labelAdr also to the TEL, which was previously created at position #0. That means that the check has to be LABEL[0] does not exist. Yes. Fortunately, TItemField differentiates between empty and unassigned; the check needs to be for the latter. Similar to for (sInt16 e=0; eaPropP-numValues; e++) { the code would also need to iterate over aPropP-parameterDefs. Yes. This helped, but so far I have only implemented the too simplistic check. I noticed another problem with the use X-ABLabel parameter approach: storing complex strings (spaces, quotation marks) in a parameter value is harder. That's probably why Apple chose the X-ABLabel property approach. An unparseable parameter could ruin the real data, a unknown property is less dangerous. The EDS vCard parser gets it wrong and fails to parse: X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner That is valid according to http://tools.ietf.org/html/rfc2425#page-5 because the space is a SAFE-CHAR and thus may appear in a ptext, but the EDS parser does not expect the space. To work around this, we could voluntarily quote the string even though it is not required. Now, the conceptual problem with X-ABLabel parameter is that a quoted string cannot contain double quotes. It is probably rare that a user enters double quotes as part of a label, but it cannot be ruled out either. Line breaks are also only allowed in property values and not parameter values. I'm undecided now how to proceed. Simplify X-ABLabel property values so that they can be stored as parameter? Use the more complex X-ABLabel property and grouping? Bummer. Really hard to say :-( I'd say it depends on how important these ABLabels are (outside of Apple devices, that is. In iOS's Addressbook (AB), the Label IS important and actually represents the standard TYPE of a TEL, EMAIL or ADR as well, by using cryptic internal string constants like _$!Work!$_ or _$!HomeFAX!$_). Best Regards, Lukas signature.asc Description: Message signed with OpenPGP using GPGMail ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
Re: [os-libsynthesis] vCard group tags
On Fri, 2014-05-02 at 11:59 +0200, Lukas Zeller wrote: Hello Patrick, On 02.05.2014, at 10:38, Patrick Ohly patrick.o...@intel.com wrote: What do you mean by independent properties? For example, ADR and TEL are independent in the sense that their values are stored in different field arrays. Sharing the LABEL field for the new parameter creates a dependency (or risk of collision) that did not exist before. But how can this work at all? The index in the field arrays is what relates the components (e.g. TEL, TEL_FLAGS and LABEL) to each other. This would mean all of the field arrays would need to have rows for the *sum* of all the TEL+ADR+EMAIL+URL+xxx, with most rows empty, to be able to share a single LABEL array. Now I see why you want to check the availability of LABEL row even if assigned via a property parameter. Hmmm - indeed this might work, at the expense of a lot of empty elements in the actual property field arrays. Exactly, that's what I need and get with the patch. I suspect that a groupfield would cause less empty elements if (and only if) no groups are used, because then values from different properties can use the same UNASSIGNED entry in the group field. But I haven't checked whether that's really how it works; it is not very relevant with Google because Google uses many group tags, even if the label is just Other. If different properties end up sharing the same UNASSIGNED group tag, then adding labels is harder in scripts (must move entries before setting the tag), but that's not necessary at the moment. I'm just not sure right now if the generator part of MimeProfile is prepared for properly skipping entirely empty rows to avoid generating empty property lines in the vCard output. But that would be fixable as well. That part already works. That's because the code which checks where to store the ADR value does not check whether the LABEL at the position is available. There's another problem: TEL:123456789 ADR;X-ABLabel=labelAdr:xxx A simplistic check LABEL[0] empty will accept position #0 for ADR. But doing so will add the labelAdr also to the TEL, which was previously created at position #0. That means that the check has to be LABEL[0] does not exist. Yes. Fortunately, TItemField differentiates between empty and unassigned; the check needs to be for the latter. Unassigned is not good enough. If the LABEL array gets extended at the end (for example, because the third ADR had a X-ABLabel parameter), then I have unassigned entries at the beginning of the array which must not be used, because there are already other properties associated with them. Here's the patch: diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp index 5b0ecc7..3699ad0 100644 --- a/src/sysync/mimedirprofile.cpp +++ b/src/sysync/mimedirprofile.cpp @@ -4154,6 +4154,35 @@ bool TMimeDirProfileHandler::parseProperty( else dostore = true; // at least one field exists, we might store } +// - check if fields used for parameters are empty +const TParameterDefinition *paramP = aPropP-parameterDefs; +while (paramP) { + if (mimeModeMatch(paramP-modeDependency) +#ifndef NO_REMOTE_RULES + (!paramP-ruleDependency || isActiveRule(paramP-ruleDependency)) +#endif + ) { +if (paramP-convdef.fieldid==FID_NOT_SUPPORTED) + continue; // no field, no need to check it +sInt16 e_fid = paramP-convdef.fieldid /* +baseoffset */; +sInt16 e_rep = repoffset; +aItem.adjustFidAndIndex(e_fid,e_rep); +// - get base field +TItemField *e_basefldP = aItem.getField(e_fid); +TItemField *e_fldP = NULL; +if (e_basefldP) + e_fldP=e_basefldP-getArrayField(e_rep,true); // get leaf field, if it exists +if (!e_basefldP || e_fldP) { + // base field of one of the main fields does not exist or leaf field is already in use + // (unassigned is not good enough, otherwise we might end up adding information + // to some other, previously parsed property using the same array field) + // - skip that repetition + dostore=false; + break; +} + } + paramP=paramP-next; +} // check if we can test more repetitions if (!dostore) { if (aRepArray[repid]+1maxrep || maxrep==REP_ARRAY) { I'm undecided now how to proceed. Simplify X-ABLabel property values so that they can be stored as parameter? Use the more complex X-ABLabel property and grouping?
Re: [os-libsynthesis] vCard group tags
On Tue, 2014-04-29 at 18:00 +0200, Lukas Zeller wrote: Hi Patrick, you are faster in understanding the details than I could look them up :-) Live and learn. Or use the source, Luke ;-) However, it helps to spell out observations and thoughts occasionally, so let me continue with a related problem. I decided that a separate X-ABLabel for every TEL, ADR, X-ABDate, X-ABRELATEDNAMES, etc. is too verbose and too different from traditional usage of vCard. Recipients of such a vCard must be able to understand and support groups, which is not guaranteed. For example, the Evolution vCard parser supports groups, but the higher level of abstraction does not (or not easily). I also don't see what advantage X-ABLabel as property has over X-ABLabel as parameter. I understand that a property could itself have parameters or complex values, but that's not the case here. A simple string might just as well be attached as parameter. So that's what I am trying to do: 1. Parse with groups: X-ABLabel property enabled. 2. Throw away group tags. 3. Generate with parameter: X-ABLabel parameter enabled. This direction works. What fails is reading such a generated vCard, because different properties store their X-ABLabel parameter in the same LABEL field array, overwriting each others' values. The logic for choosing a position must now also (or instead?!) check whether the LABEL position is unused when adding a new ADR. In other words, when parsing an ADR, look at LABEL to determine the position. I thought I could achieve that with: property name=X-ABLabel suppressempty=yes groupfield=GROUP_TAG rule=HAVE-ABLABEL-PROPERTY value field=LABEL repeat=array increment=1 minshow=0/ position field=LABEL repeat=array increment=1 minshow=1/ /property property name=ADR values=7 groupfield=GROUP_TAG value index=0 field=ADR_POBOX/ value index=1 field=ADR_ADDTL/ value index=2 field=ADR_STREET/ value index=3 field=ADR_CITY/ value index=4 field=ADR_REG/ value index=5 field=ADR_ZIP/ value index=6 field=ADR_COUNTRY/ position field=LABEL repeat=array increment=1 minshow=1/ parameter name=TYPE default=yes positional=no show=yes value field=ADR_STREET_FLAGS conversion=multimix combine=, enum name=HOME value=B0/ enum name=WORK value=B1/ enum mode=ignore value=B2/ !-- OTHER -- !-- enum mode=prefix name=X-CustomLabel- value=1.L/ -- !-- enum mode=prefix name=X-Synthesis-Ref value=2.L/ -- /value /parameter parameter name=X-ABLabel rule=HAVE-ABLABEL-PARAMETER value field=LABEL/ /parameter /property However, when parsing a vCard with HAVE-ABLABEL-PARAMETER unset and HAVE-ABLABEL-PROPERTY set, sysync::TMimeDirProfileHandler::parseProperty() goes into an endless loop involving sysync::TMultiFieldItem::adjustFidAndIndex() directly on the first ADR: ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country It's permanently increasing repoffset. I've not looked further, but I suspect that this is because of using LABEL twice, once indirectly via the group field and once via the position field. I'll try applying different property elements, even if that means more duplication in the profile. -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter. ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
Re: [os-libsynthesis] vCard group tags
On Wed, 2014-04-30 at 18:22 +0200, Lukas Zeller wrote: What you have here is probably the most elaborate profile ever specified for libsynthesis :-) , but I see no reason why it should not work once the position is correct. That's what I had tried earlier. It leads to the situation where the labels of independent properties overwrite labels of other, earlier properties. That's because the position checking seems to focus exclusively on property values and ignores property parameters. Here's an example: BEGIN:VCARD VERSION:3.0 PRODID:-//Synthesis AG//NONSGML SyncML Engine V3.4.0.47//EN REV:20140430T170257Z N:Doe;John;1;Mr.;Sr. FN:Mr. John 1 Doe Sr. X-EVOLUTION-FILE-AS:Doe\, John X-GENDER: NICKNAME:Johnny TITLE:tester ORG:at company;;; ROLE: TEL;TYPE=WORK:business 1 TEL;TYPE=CELL:mobile TEL;TYPE=HOME:home TEL:main TEL;TYPE=WORK,FAX:work fax TEL;TYPE=HOME,FAX:home fax TEL;X-ABLabel=Google Voice:google voice TEL;TYPE=PAGER:pager TEL;X-ABLabel=custom-label4:custom EMAIL;TYPE=HOME:john@home.com EMAIL;TYPE=WORK:d...@work.com EMAIL;X-ABLabel=custom-label2:j...@custom.com URL;X-ABLabel=Profile:http://profile.com URL;X-ABLabel=Blog:http://blog.com URL;X-ABLabel=HomePage:http://homepage.com URL;X-ABLabel=Work:http://company.com URL;X-ABLabel=Custom-label6:http://custom.com X-EVOLUTION-MANAGER:manager X-MANAGER:manager X-EVOLUTION-ASSISTANT:assistant X-ASSISTANT:assistant X-ABRELATEDNAMES;X-ABLabel=Child:child X-ABRELATEDNAMES;X-ABLabel=Mother:mother X-ABRELATEDNAMES;X-ABLabel=Father:father X-ABRELATEDNAMES;X-ABLabel=Parent:parent X-ABRELATEDNAMES;X-ABLabel=Brother:brother X-ABRELATEDNAMES;X-ABLabel=Sister:sister X-ABRELATEDNAMES;X-ABLabel=Friend:friend X-ABRELATEDNAMES;X-ABLabel=relative:relative X-ABRELATEDNAMES;X-ABLabel=referred by:referred-by X-ABRELATEDNAMES;X-ABLabel=Partner:partner X-ABRELATEDNAMES;X-ABLabel=domestic partner:domestic partner X-ABRELATEDNAMES;X-ABLabel=custom-label5:custom relationship X-EVOLUTION-SPOUSE:spouse X-SPOUSE:spouse X-EVOLUTION-ANNIVERSARY:19710101 X-ANNIVERSARY:19710101 X-ABDate;X-ABLabel=custom-label3:2201 IMPP;X-ABLabel=Other:xmpp:google%20talk IMPP;X-ABLabel=Other:aim:aim IMPP;X-ABLabel=Other:ymsgr:yahoo IMPP;X-ABLabel=Other:skype:skype IMPP;X-ABLabel=Other:x-apple:QQ IMPP;X-ABLabel=Other:msnim:MSN IMPP;X-ABLabel=Other:aim:ICQ IMPP;X-ABLabel=Other:xmpp:Jabber IMPP;X-ABLabel=Other:x-apple:custom%20chat X-MOZILLA-HTML:FALSE ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country ADR;TYPE=WORK:;;work address ADR:;;custom address BDAY:19701230 NOTE:A test contact. PHOTO;ENCODING=B:iVBORw0KGgoNSUhEUgAAACQXCAYAAABj7u2bBmJLR0QA/wD/AP+gvaeTCXBIWXMAAAsTAAALEwEAmpwYB3RJTUUH1gEICjgdiWkBOQAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu0tcURAG8F98gRKTYGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWPsAU6wPxHW6aWbgsu+ve3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6THlejbWSt0Bv8QBXX2MF7jKU4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkFjQX9g5e4ykGUcBm+FaDexx2MUQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOcBHcEv7FvyN8xxqmeynovA1Baf4UVvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdNowXWEQlOBXMYyI4j3EavqFUzpOYl4OTqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6Bb/Ae0cnahfg6KuAElFTkSuQmCC GEO:; X-PHONETIC-FIRST-NAME:John X-PHONETIC-LAST-NAME:Doe END:VCARD * [2014-04-30 19:03:12.551] parseMimeDir: property X-EVOLUTION-MANAGER parsing delayed, rank=1 * [2014-04-30 19:03:12.551] parseMimeDir: property X-EVOLUTION-ASSISTANT parsing delayed, rank=1 * [2014-04-30 19:03:12.551] parseMimeDir: property X-EVOLUTION-SPOUSE parsing delayed, rank=1 * [2014-04-30 19:03:12.551] parseMimeDir: property X-EVOLUTION-ANNIVERSARY parsing delayed, rank=1 * [2014-04-30 19:03:12.551] parseMimeDir: now parsing delayed property rank=1: :manager X-MANAGER:manager X * [2014-04-30 19:03:12.552] parseMimeDir: now parsing delayed property rank=1: :assistant X-ASSISTANT:assist * [2014-04-30 19:03:12.552] parseMimeDir: now parsing delayed property rank=1: :spouse X-SPOUSE:spouse X-EV * [2014-04-30 19:03:12.552] parseMimeDir: now parsing delayed property rank=1: :19710101 X-ANNIVERSARY:19710 * [2014-04-30 19:03:12.552] Successfully parsed: * [2014-04-30 19:03:12.552] Item LocalID='', RemoteID='1a1d5ecf8e36d276', operation=add, size: [maxlocal,maxremote,actual] * [2014-04-30 19:03:12.552] - 0 :integer SYNCLVL [ n/a, 0, 0] : unassigned - 1 : timestamp REV [ 0, 0, 0] : 2014-04-30T17:02:57Z (TZ: UTC) - 2 : string UID [ n/a, 0, 0] : unassigned - 3 : string GROUP_TAG [ n/a, 0, 0] : array with 12 elements -- element0 : empty -- element1 : empty -- element2 : empty -- element3 : empty
Re: [os-libsynthesis] vCard group tags
On Wed, 2014-04-16 at 17:34 +0200, Lukas Zeller wrote: Hello Patrick, On 11.04.2014, at 12:18, Patrick Ohly patrick.o...@intel.com wrote: Google CardDAV and iOS/OS X use group tags to represent custom labels in vCards. Attached is an example. Note that the Google vCard format used by CardDAV is not the same as the one used by Gmail's export feature. The example is from CardDAV. I am trying to understand how I can support that using libsynthesis. The doc mentions: groupfield [...] Is there an example using this feature? I implemented that feature back at Synthesis in 2010 for Beat's Android client, and what is shown in the docs (the TITLE/ORG case) is in fact taken from that client's config. Is the following field list and profile correct? Field list: field name=TITLE array=yes type=string/ field name=ORG_NAME array=yes type=string/ field name=ORG_DIVISION array=yes type=string/ field name=ORG_OFFICE tarray=yes ype=string/ field name=ORG_TEAM array=yes type=string/ field name=ROLE array=yes type=string/ field name=GROUP-TAG-TITLE-ORG array=yes type=string/ Profile: property name=TITLE grouptag=GROUP-TAG-TITLE-ORG value field=TITLE/ /property property name=ORG values=4 grouptag=GROUP-TAG-TITLE-ORG value index=0 field=ORG_NAME/ value index=1 field=ORG_DIVISION/ value index=2 field=ORG_OFFICE/ value index=3 field=ORG_TEAM/ /property My understanding is that parsing the example from the documentation will lead to: ORG = [ myOwnCompany, myEmployer ] TITLE = [ boss, employee ] GROUP-TAG-TITLE-ORG = [ A, B ] Yes, that's excactly what is supposed to happen. Unfortunately I am not getting the group-tag field populated. I'm attaching my field list and profile. When parsing, I get: [2014-04-28 19:31:37.575] Parsing: * [2014-04-28 19:31:37.575] BEGIN:VCARD VERSION:3.0 N:Doe;John;1;Mr.;Sr. FN:Mr. John 1 Doe Sr. NICKNAME:Johnny TITLE:tester ORG:at company REV:2014-04-28T17:31:23Z UID:6a5bd79f8b1cdd58 BDAY;VALUE=DATE:1970-12-30 ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country ADR;TYPE=WORK:;;work address ADR;TYPE=OTHER:;;custom address TEL;TYPE=WORK:business 1 TEL;TYPE=CELL:mobile TEL;TYPE=HOME:home TEL:main TEL;TYPE=FAX,WORK:work fax TEL;TYPE=FAX,HOME:home fax item13.TEL:google voice TEL;TYPE=PAGER:pager item14.TEL:custom EMAIL;TYPE=HOME,PREF:john@home.com EMAIL;TYPE=WORK:d...@work.com item1.EMAIL:j...@custom.com NOTE:A test contact. PHOTO;ENCODING=B:iVBORw0KGgoNSUhEUgAAACQXCAYAAABj7u2bBmJLR0QA/w D/AP+gvaeTCXBIWXMAAAsTAAALEwEAmpwYB3RJTUUH1gEICjgdiWkBOQAAAB10RVh0Q 29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu0tcURAG8F98gRKT YGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWPsAU6wPxHW6aWbgsu+v e3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6THlejbWSt0Bv8QBXX2MF7jK U4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkFjQX9g5e4ykGUcBm+FaDexx2M UQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOcBHcEv7FvyN8xxqmeynovA1Baf4U VvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdNowXWEQlOBXMYyI4j3EavqFUzpOYl4O TqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6B b/Ae0cnahfg6KuAElFTkSuQmCC item4.IMPP;X-SERVICE-TYPE=GoogleTalk:xmpp:google%20talk item5.IMPP;X-SERVICE-TYPE=AIM:aim:aim item6.IMPP;X-SERVICE-TYPE=Yahoo:ymsgr:yahoo item7.IMPP;X-SERVICE-TYPE=Skype:skype:skype item8.IMPP;X-SERVICE-TYPE=QQ:x-apple:QQ item9.IMPP;X-SERVICE-TYPE=MSN:msnim:MSN item10.IMPP;X-SERVICE-TYPE=ICQ:aim:ICQ item11.IMPP;X-SERVICE-TYPE=Jabber:xmpp:Jabber item12.IMPP;X-SERVICE-TYPE=Chat-label:x-apple:custom%20chat X-EVOLUTION-FILE-AS:Doe\, John X-MOZILLA-HTML:FALSE X-ABLABEL:custom-label X-PHONETIC-FIRST-NAME:John X-PHONETIC-LAST-NAME:Doe item1.X-ABLabel:custom-label item2.X-ABDATE:1971-01-01 item2.X-ABLabel:Anniversary item3.X-ABDATE:2000-02-01 item3.X-ABLabel:custom-label item4.X-ABLabel:Other item5.X-ABLabel:Other item6.X-ABLabel:Other item7.X-ABLabel:Other item8.X-ABLabel:Other item9.X-ABLabel:Other item10.X-ABLabel:Other item11.X-ABLabel:Other item12.X-ABLabel:Other item13.X-ABLabel:Google Voice item14.X-ABLabel:custom-label item15.X-ABRELATEDNAMES:spouse item15.X-ABLabel:Spouse item16.X-ABRELATEDNAMES:child item16.X-ABLabel:Child item17.X-ABRELATEDNAMES:mother item17.X-ABLabel:Mother item18.X-ABRELATEDNAMES:father item18.X-ABLabel:Father item19.X-ABRELATEDNAMES:parent item19.X-ABLabel:Parent item20.X-ABRELATEDNAMES:brother item20.X-ABLabel:Brother item21.X-ABRELATEDNAMES:sister item21.X-ABLabel:Sister item22.X-ABRELATEDNAMES:friend item22.X-ABLabel:Friend item23.X-ABRELATEDNAMES:relative item23.X-ABLabel:relative item24.X-ABRELATEDNAMES:manager item24.X-ABLabel:Manager item25.X-ABRELATEDNAMES:assistant item25.X-ABLabel:Assistant item26.X-ABRELATEDNAMES:referred-by item26.X-ABLabel:referred by item27.X-ABRELATEDNAMES:partner
Re: [os-libsynthesis] vCard group tags
On Mon, 2014-04-28 at 23:18 +0200, Lukas Zeller wrote: Hi Patrick, Unfortunately I am not getting the group-tag field populated. I'm attaching my field list and profile. small oversight on my and your part :-) The attribute to be added to property is called groupfield, not grouptag... I fixed that (see attached profile + field list). It fills the GROUP_TAG array now, but the LABEL array only has one entry, apparently the last one. The array positions also don't match: item34.URL:http\://custom.com item34.X-ABLabel:Custom-label - 3 : string GROUP_TAG [ 0, n/a, 0] : array with 19 elements -- element0 : item34 - 4 : string LABEL [ 0, 0, 0] : array with 1 elements -- element0 : Custom-label - 34 : string WEB [ 0, 0, 0] : array with 19 elements -- element0 : unassigned ... -- element 18 : http://custom.com; Note that we now have multiple properties sharing the same group tag, not just two (ORG and TITLE in the example). It is not clear to me how groupfield interacts with the repeat parameter. Do I need repeat=array increment=1 despite groupfield overriding the choice of the position? What happens if the two don't agree? Suppose URL is used without group tag, then followed by an URL with group tag: URL:http://foo.com item1.X-ABLabel:custom-label item1.URL:http://custom.com First this adds http://foo.com at postion 0 of the WEB field = WEB = [ 'http://foo.com' ] GROUP_TAG = [] LABEL = [] Then the first label and tag are parsed: WEB = [ 'http://foo.com' ] GROUP_TAG = [ 'item1' ] LABEL = [ 'custom-label' ] Now we have a problem. Based on GROUP_TAG, item1.URL must be at position 0, but that position in WEB is already taken. Or is the second step creating an empty (or unassigned) GROUP_TAG entry, with the special semantic that empty group tags are never matched against each other? Anyway, here's the full parse log: [2014-04-29 09:30:09.811] Parsing: * [2014-04-29 09:30:09.811] BEGIN:VCARD VERSION:3.0 N:Doe;John;1;Mr.;Sr. FN:Mr. John 1 Doe Sr. NICKNAME:Johnny TITLE:tester ORG:at company REV:2014-04-28T17:31:23Z UID:6a5bd79f8b1cdd58 BDAY;VALUE=DATE:1970-12-30 ADR;TYPE=HOME:PO;neighborhood;home address\n;City;State;ZIP;Country ADR;TYPE=WORK:;;work address ADR;TYPE=OTHER:;;custom address TEL;TYPE=WORK:business 1 TEL;TYPE=CELL:mobile TEL;TYPE=HOME:home TEL:main TEL;TYPE=FAX,WORK:work fax TEL;TYPE=FAX,HOME:home fax item13.TEL:google voice TEL;TYPE=PAGER:pager item14.TEL:custom EMAIL;TYPE=HOME,PREF:john@home.com EMAIL;TYPE=WORK:d...@work.com item1.EMAIL:j...@custom.com NOTE:A test contact. PHOTO;ENCODING=B:iVBORw0KGgoNSUhEUgAAACQXCAYAAABj7u2bBmJLR0QA/w D/AP+gvaeTCXBIWXMAAAsTAAALEwEAmpwYB3RJTUUH1gEICjgdiWkBOQAAAB10RVh0Q 29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAABaElEQVRIx+3Wu0tcURAG8F98gRKT YGORRqwksJV/QOqFFIFgKgsRYbHV1larDQQCKQxpUscyhUmXJuCSNpYWPsAU6wPxHW6aWbgsu+v e3RUs7geHc+fON3O+M4c5HHLkyHG/eISkg5heIGmUr++hVWigyY6THlejbWSt0Bv8QBXX2MF7jK U4IyjjJ45xg31sYKZuw7Xv9Gh6vvXO9QbBtbGNJ8Ert+AlTURkFjQX9g5e4ykGUcBm+FaDexx2M UQOYhIL2Lpj09oV9CvsQgPuePj+hP037BL6M6yRSdDZHWVOcBHcEv7FvyN8xxqmeynovA1Baf4U VvANhyn/Uq8E/Q57ssNufhvx1QZrDHfS9p9i3sQsnscdNowXWEQlOBXMYyI4j3EavqFUzpOYl4O TqUJ9+NzmkbXyb6Ryfumm7Wso4it2cYXL6K6PeBmcV8E5iEvxPDjv8CyVaxQfsIfbqGIlf17k6B b/Ae0cnahfg6KuAElFTkSuQmCC item4.IMPP;X-SERVICE-TYPE=GoogleTalk:xmpp:google%20talk item5.IMPP;X-SERVICE-TYPE=AIM:aim:aim item6.IMPP;X-SERVICE-TYPE=Yahoo:ymsgr:yahoo item7.IMPP;X-SERVICE-TYPE=Skype:skype:skype item8.IMPP;X-SERVICE-TYPE=QQ:x-apple:QQ item9.IMPP;X-SERVICE-TYPE=MSN:msnim:MSN item10.IMPP;X-SERVICE-TYPE=ICQ:aim:ICQ item11.IMPP;X-SERVICE-TYPE=Jabber:xmpp:Jabber item12.IMPP;X-SERVICE-TYPE=Chat-label:x-apple:custom%20chat X-EVOLUTION-FILE-AS:Doe\, John X-MOZILLA-HTML:FALSE X-ABLABEL:custom-label X-PHONETIC-FIRST-NAME:John X-PHONETIC-LAST-NAME:Doe item1.X-ABLabel:custom-label item2.X-ABDATE:1971-01-01 item2.X-ABLabel:Anniversary item3.X-ABDATE:2000-02-01 item3.X-ABLabel:custom-label item4.X-ABLabel:Other item5.X-ABLabel:Other item6.X-ABLabel:Other item7.X-ABLabel:Other item8.X-ABLabel:Other item9.X-ABLabel:Other item10.X-ABLabel:Other item11.X-ABLabel:Other item12.X-ABLabel:Other item13.X-ABLabel:Google Voice item14.X-ABLabel:custom-label item15.X-ABRELATEDNAMES:spouse item15.X-ABLabel:Spouse item16.X-ABRELATEDNAMES:child item16.X-ABLabel:Child item17.X-ABRELATEDNAMES:mother item17.X-ABLabel:Mother item18.X-ABRELATEDNAMES:father item18.X-ABLabel:Father item19.X-ABRELATEDNAMES:parent item19.X-ABLabel:Parent item20.X-ABRELATEDNAMES:brother item20.X-ABLabel:Brother item21.X-ABRELATEDNAMES:sister item21.X-ABLabel:Sister item22.X-ABRELATEDNAMES:friend item22.X-ABLabel:Friend item23.X-ABRELATEDNAMES:relative item23.X-ABLabel:relative item24.X-ABRELATEDNAMES:manager
Re: [os-libsynthesis] vCard group tags
On Tue, 2014-04-29 at 09:50 +0200, Patrick Ohly wrote: On Mon, 2014-04-28 at 23:18 +0200, Lukas Zeller wrote: Hi Patrick, Unfortunately I am not getting the group-tag field populated. I'm attaching my field list and profile. small oversight on my and your part :-) The attribute to be added to property is called groupfield, not grouptag... I fixed that (see attached profile + field list). It fills the GROUP_TAG array now, but the LABEL array only has one entry, apparently the last one. The array positions also don't match: item34.URL:http\://custom.com item34.X-ABLabel:Custom-label - 3 : string GROUP_TAG [ 0, n/a, 0] : array with 19 elements -- element0 : item34 - 4 : string LABEL [ 0, 0, 0] : array with 1 elements -- element0 : Custom-label - 34 : string WEB [ 0, 0, 0] : array with 19 elements -- element0 : unassigned ... -- element 18 : http://custom.com; I've stepped through TMimeDirProfileHandler::parseProperty() when parsing a simpler example: BEGIN:VCARD VERSION:3.0 N:Doe;John;1;Mr.;Sr. FN:Mr. John 1 Doe Sr. UID:6f354d698b7ccd22 item1.URL:http\://company.com item1.X-ABLabel:Work item2.URL:http\://custom.com item2.X-ABLabel:Custom-label END:VCARD When parsing item1.X-ABLabel:Work, TMimeDirProfileHandler::parseProperty() immediately skips over the parameter parsing because there is none and fieldoffsetfound was set to true in fieldoffsetfound = (aPropP-nameExts==NULL); // no first pass needed at all w/o nameExts, just use offs=0 It then has repoffset == 0 when storing the group tag: // parameters are all processed by now, decision made to store data (if !dostore, routine exits above) // - store the group tag value if we have one if (aPropP-groupFieldID!=FID_NOT_SUPPORTED) { TItemField *g_fldP = aItem.getArrayFieldAdjusted(aPropP-groupFieldID+baseoffset,repoffset,false); if (g_fldP) g_fldP-setAsString(aGroupName,aGroupNameLen); // store the group name (aGroupName might be NULL, that's ok) } This happens to be correct (accidentally) for item1.X-ABLabel:Work. When repeating this for item2.X-ABLabel, the setAsString() above overwrites item1 with item2 at offset 0, leading to: - 3 : string GROUP_TAG [ 0, n/a, 0] : array with 2 elements -- element0 : item2 -- element1 : item2 The second element here came from item2.URL. The group tag matching is buried in the parameter parsing loop. Skipping it via the (aPropP-nameExts==NULL) is incorrect if the property has a group name. I'm not sure what the correct way of executing that code in this particular case is. The following patch does not work: diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp index 5b0ecc7..16a5aac 100644 --- a/src/sysync/mimedirprofile.cpp +++ b/src/sysync/mimedirprofile.cpp @@ -3835,7 +3835,7 @@ bool TMimeDirProfileHandler::parseProperty( encoding = enc_none; // no encoding by default charset = aMimeMode==mimo_standard ? chs_utf8 : fDefaultInCharset; // always UTF8 for real MIME-DIR (same as enclosing SyncML doc), for mimo_old depends on inputcharset remote rule option (normally UTF-8) nameextmap = 0; // no name extensions detected so far - fieldoffsetfound = (aPropP-nameExts==NULL); // no first pass needed at all w/o nameExts, just use offs=0 + fieldoffsetfound = (aPropP-nameExts==NULL) !aGroupNameLen; // no first pass needed at all w/o nameExts, just use offs=0, except when we have to match a group name valuelist = aPropP-valuelist; // cache flag // prepare storage as unprocessed value if (aPropP-unprocessed) { It loops twice, but still never reaches the group name matching because that is inside a while (propnameextP) loop that never gets entered. Should that code be copied out for the simpler case of a property with no aPropP-nameExts? -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter. ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
Re: [os-libsynthesis] vCard group tags
On Tue, 2014-04-29 at 17:18 +0200, Patrick Ohly wrote: On Tue, 2014-04-29 at 09:50 +0200, Patrick Ohly wrote: On Mon, 2014-04-28 at 23:18 +0200, Lukas Zeller wrote: Hi Patrick, Unfortunately I am not getting the group-tag field populated. I'm attaching my field list and profile. small oversight on my and your part :-) The attribute to be added to property is called groupfield, not grouptag... I fixed that (see attached profile + field list). It fills the GROUP_TAG array now, but the LABEL array only has one entry, apparently the last one. The array positions also don't match: item34.URL:http\://custom.com item34.X-ABLabel:Custom-label - 3 : string GROUP_TAG [ 0, n/a, 0] : array with 19 elements -- element0 : item34 - 4 : string LABEL [ 0, 0, 0] : array with 1 elements -- element0 : Custom-label - 34 : string WEB [ 0, 0, 0] : array with 19 elements -- element0 : unassigned ... -- element 18 : http://custom.com; I've stepped through TMimeDirProfileHandler::parseProperty() when parsing a simpler example: BEGIN:VCARD VERSION:3.0 N:Doe;John;1;Mr.;Sr. FN:Mr. John 1 Doe Sr. UID:6f354d698b7ccd22 item1.URL:http\://company.com item1.X-ABLabel:Work item2.URL:http\://custom.com item2.X-ABLabel:Custom-label END:VCARD When parsing item1.X-ABLabel:Work, TMimeDirProfileHandler::parseProperty() immediately skips over the parameter parsing because there is none and fieldoffsetfound was set to true in fieldoffsetfound = (aPropP-nameExts==NULL); // no first pass needed at all w/o nameExts, just use offs=0 It then has repoffset == 0 when storing the group tag: // parameters are all processed by now, decision made to store data (if !dostore, routine exits above) // - store the group tag value if we have one if (aPropP-groupFieldID!=FID_NOT_SUPPORTED) { TItemField *g_fldP = aItem.getArrayFieldAdjusted(aPropP-groupFieldID+baseoffset,repoffset,false); if (g_fldP) g_fldP-setAsString(aGroupName,aGroupNameLen); // store the group name (aGroupName might be NULL, that's ok) } This happens to be correct (accidentally) for item1.X-ABLabel:Work. Looking further at aPropP-nameExts it seems that this what relates to position in the profile config. I did not have that for my X-ABLabel. Adding it seems to fix the problem. So it seems that groupfield can only be used reliably with a property which has a position, correct? property name=X-ABLabel suppressempty=yes groupfield=GROUP_TAG value field=LABEL repeat=array increment=1 minshow=0/ position field=LABEL repeat=array increment=1 minshow=1/ /property -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter. ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
Re: [os-libsynthesis] vCard group tags
Hi Patrick, you are faster in understanding the details than I could look them up :-) Yes, again I should have noticed, but I lack the daily sync practice... Every property that can occur multiple times, i.e. maps to a series of side-by-side fields or array fields, needs the position tag to specify how the multiple instances are to be filled into fields. This has nothing to do with groupfield directly, but of course groupfield usually does not make sense for non recurring properties. On 29.04.2014, at 17:48, Patrick Ohly patrick.o...@intel.com wrote: Looking further at aPropP-nameExts it seems that this what relates to position in the profile config. Exactly. (the reason why it is called nameExts internally is because in the early days, the primary usage was to direct TELs into one of multiple TEL fields based on WORK, HOME, FAX, so these worked as field name extensions. Like having fields TEL_WORK and TEL_HOME, and two positions that routed incoming TELs according to TYPE using the has and hasnot attributes) I did not have that for my X-ABLabel. Adding it seems to fix the problem. So it seems that groupfield can only be used reliably with a property which has a position, correct? Correct, see above. Best Regards, Lukas signature.asc Description: Message signed with OpenPGP using GPGMail ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
Re: [os-libsynthesis] vCard group tags
Hello Patrick, On 11.04.2014, at 12:18, Patrick Ohly patrick.o...@intel.com wrote: Google CardDAV and iOS/OS X use group tags to represent custom labels in vCards. Attached is an example. Note that the Google vCard format used by CardDAV is not the same as the one used by Gmail's export feature. The example is from CardDAV. I am trying to understand how I can support that using libsynthesis. The doc mentions: groupfield [...] Is there an example using this feature? I implemented that feature back at Synthesis in 2010 for Beat's Android client, and what is shown in the docs (the TITLE/ORG case) is in fact taken from that client's config. Is the following field list and profile correct? Field list: field name=TITLE array=yes type=string/ field name=ORG_NAME array=yes type=string/ field name=ORG_DIVISION array=yes type=string/ field name=ORG_OFFICE tarray=yes ype=string/ field name=ORG_TEAM array=yes type=string/ field name=ROLE array=yes type=string/ field name=GROUP-TAG-TITLE-ORG array=yes type=string/ Profile: property name=TITLE grouptag=GROUP-TAG-TITLE-ORG value field=TITLE/ /property property name=ORG values=4 grouptag=GROUP-TAG-TITLE-ORG value index=0 field=ORG_NAME/ value index=1 field=ORG_DIVISION/ value index=2 field=ORG_OFFICE/ value index=3 field=ORG_TEAM/ /property My understanding is that parsing the example from the documentation will lead to: ORG = [ myOwnCompany, myEmployer ] TITLE = [ boss, employee ] GROUP-TAG-TITLE-ORG = [ A, B ] Yes, that's excactly what is supposed to happen. The challenge will be to convert between item6.IMPP;X-SERVICE-TYPE=AIM:aim:aim item6.X-ABLabel:Other and X-AIM:aim Custom labels will also be fun, if that's what Evolution decides to use (currently it is unsupported). As always, vCard details are fun, and X-stuff even more so ;-) Best Regards, Lukas signature.asc Description: Message signed with OpenPGP using GPGMail ___ os-libsynthesis mailing list os-libsynthesis@synthesis.ch http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis