nextcloud / contacts

📇 Contacts app for Nextcloud
https://apps.nextcloud.com/apps/contacts
GNU Affero General Public License v3.0
563 stars 169 forks source link

Support jCard (exportation and importation). #3956

Open RokeJulianLockhart opened 3 months ago

RokeJulianLockhart commented 3 months ago

Is your feature request related to a problem? Please describe.

As Y U NO I18N?! states:

There are several versions of vCard out there. The latest version, 4.0, sensibly mandates UTF-8 as the character encoding of the vCard. Unfortunately, nobody seems to support vCard 4.0. Version 3.0 of the vCard specification says the character encoding must be specified in the Content-Type MIME header field, using the charset parameter. That is fine, unless you don't use HTTP to transmit the vCard, at which point you either agree between parties, or you guess. Poor old version 2.1 from 1996, still in active duty, has the ASCII character encoding as the default, unless you specify something else with the CHARSET parameter. For every property. As you can imagine, nobody does that, and then we get stuff like “Käpyaho” for my last name (and I really resent that).

As vCard – hard to parse, hard to generate, almost easy to read states:

On the surface, vCard seems simple enough. It is based on lines, each of which has a delimited format. Here is a simple sample of a vCard from [randomuser.me](https://randomuser.me/), converted to vCard 3.0 by hand: ```vCard BEGIN:VCARD VERSION:3.0 FN:Marilou Lam N:Lam;Marilou;;Ms; ADR:;;3892 Duke St;Oakville;NJ;79279;U.S.A. EMAIL:marilou.lam@example.com BDAY:1967-06-09T06:59:48-05:00 END:VCARD ``` Doesn't seem to bad, does it? Well, I've written my share of ad hoc vCard parsers and generators in the past (in Objective-C, Java, and C#), and never went all the way, because when you start looking into the corner cases and the special handling required for many fields, you want to run away and hide. First of all, the lines are not just lines. They could continue on to the next, and the process of continuation is complex, but not as complex as joining them back together, so most naïve vCard handlers just ignore continuation. By the way, according to the specification the line delimiter is a CR-LF pair. The properties are separated from the values with a colon. Some properties may have multiple fields, so those need to be separated with a semicolon. Some properties may have multiple values, so those need to be separated with a comma. The fun begins if you need to have any of those separators in a value (it could happen, you know). They need to be escaped with a backslash. If you need to have a backslash, it's time for another backslash. And newlines in values need to be expressed just like in many programming languages, with \n. It's complicated. So vCard may be quite human-readable, but that is neither here nor there, because vCards are not meant for eyeballing. They are meant for information exchange between computer systems. That also brings up the not insignificant issue of character encodings.

Anecdotally, I've had my contacts corrupted (mostly by loss of fields, both merely visual and literal) myriad times.

Describe the solution you'd like

As jCard – easy to parse, fairly easy to generate, hard to read (except when pretty-printed) explains, the jCard standard (codified at https://datatracker.ietf.org/doc/html/rfc7095#section-3) should replace vCard:

Consider the jCard equivalent of the vCard above. Because it is JSON, it has a uniform syntax, so that you can feed it into any JSON parser and reap the rewards. It looks something like this: ```jCard ["vcard", [ ["version", {}, "text", "4.0"], ["fn", {}, "text", "Marilou Lam"], ["n", {}, "text", ["Lam", "Marilou", "", "", "Ms"] ], ["adr", {}, "text", ["", "", "3892 Duke St", "Oakville", "NJ", "79279", "U.S.A."] ], ["email", { }, "text", "marilou.lam@example.com"], ["bday", {}, "date-and-or-time", "1967-06-09T06:59:48-05:00"] ] ] ``` As you can see, the jCard has a standard JSON syntax, but the content itself is not typical JSON. It is a polymorphic array, containing string and arrays. The top-level object is an array, so that you can have multiple contacts in one payload. All the vCard properties are arrays where the first item is a string identifying the property. The rest are objects, simple values or arrays, based on the property. The jCard specification goes into great detail explaining how they are constructed. The JSON example above is verbose, because it has been pretty-printed to be eyeballed by a human. If you were to condense it for online transmission, it would look like this: ```jCard ["vcard",[["version",{},"text","4.0"],["fn",{},"text","Marilou Lam"], ["n",{},"text",["Lam","Marilou","","","Ms"]],["adr",{},"text", ["","","3892 Duke St","Oakville","NJ","79279","U.S.A."]], ["email",{},"text","marilou.lam@example.com"],["bday",{}, "date-and-or-time","1967-06-09T06:59:48-05:00"]]] ``` I only cheated a little by inserting a couple of newlines, which are not actually part of the condensed representation, but actually it's tight, no-nonsense JSON.

Describe alternatives you've considered

Allow exporting to JSON (or XML, but that's generally considered worse for myriad but inconsequential reasons). However, this would probably not be an interoperable solution, because I cannot imagine Outlook, Apple, or Google permitting mere JSON output (remember that CSV is merely inferior TSV - its advantage is supposedly that it is human-readable) whereas I can easily envisage them adopting jCard due to how it is a direct, standard improvement over vCard, which is supported by all.

Additional context

Maybe worth filing a counterpart at https://issuetracker.google.com/issues/new?component=344199&template=1041029.

hamza221 commented 2 months ago

cc @SebastianKrupinski opinions ?

SebastianKrupinski commented 2 months ago

@hamza221

I agree, jCards (JSON format) and xCards (XML format) are major improvement over the current vCard format.

I also agree that these formats a currently NOT widely used. But if we have a good enough use case reason, implementation would NOT be that difficult.

RokeJulianLockhart commented 2 months ago

https://github.com/nextcloud/contacts/issues/3956#issuecomment-2202153553

@SebastianKrupinski, if NextCloud supported either format with this official server application - nextcloud/contacts - I could quite feasibly expand its support into a multitude of clients, like Fossify Contacts. From my experience, the most significant hurdle to adoption thus far has been a lack of decent server software to test it with. Next, it's synchronisation tools like DAVx5, but ultimately, those can be bypassed. It just needs server-side support.