Skip to content

Commit

Permalink
Merge pull request #4906 from cyrusimap/vcardcomponent_transform
Browse files Browse the repository at this point in the history
vCard: add support for libicalvcard vcardcomponent_transform()
  • Loading branch information
rsto committed Jul 15, 2024
2 parents 07f9adc + 038bb83 commit 2f0c1bc
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 358 deletions.
14 changes: 7 additions & 7 deletions cassandane/tiny-tests/Carddav/bulk_import_export
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ sub test_bulk_import_export
my $single = <<EOF;
BEGIN:VCARD
VERSION:3.0
UID:$uid1
UID:$uid3
N:Gump;Forrest;;Mr.
FN:Forrest Gump
ORG:Bubba Gump Shrimp Co.
Expand All @@ -29,14 +29,14 @@ EOF
BEGIN:VCARD
VERSION:4.0
NICKNAME:me
UID:$uid2
UID;VALUE=TEXT:$uid2
FN:Cyrus Daboo
EMAIL:cdaboo\@example.com
END:VCARD
BEGIN:VCARD
VERSION:4.0
NICKNAME:eric
UID:$uid3
UID:urn:uuid:$uid1
FN:Eric York
END:VCARD
EOF
Expand All @@ -54,7 +54,7 @@ EOF
$self->assert_num_equals(207, $res->{status});

my $xml = XMLin($res->{content});
$self->assert_str_equals($uid1, $xml->{'D:response'}{'D:propstat'}{'D:prop'}{'CS:uid'});
$self->assert_str_equals($uid3, $xml->{'D:response'}{'D:propstat'}{'D:prop'}{'CS:uid'});

xlog $self, "Import multiple vCards";
$res = $CardDAV->{ua}->request('POST', $CardDAV->request_url($Id), {
Expand All @@ -65,14 +65,14 @@ EOF

$xml = XMLin($res->{content});
$self->assert_str_equals($uid2, $xml->{'D:response'}[0]{'D:propstat'}{'D:prop'}{'CS:uid'});
$self->assert_str_equals($uid3, $xml->{'D:response'}[1]{'D:propstat'}{'D:prop'}{'CS:uid'});
$self->assert_str_equals("urn:uuid:$uid1", $xml->{'D:response'}[1]{'D:propstat'}{'D:prop'}{'CS:uid'});

xlog $self, "Export the vCards";
$res = $CardDAV->{ua}->request('GET', $CardDAV->request_url($Id), {
headers => \%Headers,
});
$self->assert_num_equals(200, $res->{status});
$self->assert_matches(qr/UID:$uid1\r\nN:Gump/, $res->{content});
$self->assert_matches(qr/UID:$uid3\r\nN:Gump/, $res->{content});
$self->assert_matches(qr/UID:$uid2\r\nFN:Cyrus Daboo/, $res->{content});
$self->assert_matches(qr/UID:$uid3\r\nFN:Eric York/, $res->{content});
$self->assert_matches(qr/UID:$uid1\r\nFN:Eric York/, $res->{content});
}
15 changes: 8 additions & 7 deletions cassandane/tiny-tests/Carddav/put_get_v3_v4
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ EOF
$self->assert_matches(qr/TEL;TYPE=foo$typesep$work;PREF=1:/, $newcard);
$self->assert_matches(qr/EMAIL;PREF=1:$email1/, $newcard);
$self->assert_matches(qr/EMAIL:$email2/, $newcard);
$self->assert_matches(qr/TZ;VALUE=$utcoff:-0500/, $newcard);
$self->assert_matches(qr/TZ;VALUE=$utcoff:-05(00)?/, $newcard);
$self->assert_matches(qr/TZ(;VALUE=$text)?:$tzid/, $newcard);

xlog $self, "PUT same vCard as v4 with some edits";
$newcard =~ s|END:|SOUND;MEDIATYPE=audio/mp3:data:;base64,$sound\r\nEND:|;
$newcard =~ s/:$tel/;VALUE=URL:tel:$tel/;
$newcard =~ s/:\+1/;VALUE=URI:tel:+1/;
$newcard =~ s/EMAIL;PREF=1:/EMAIL;PREF=2:/;
$newcard =~ s/:$email2/;PREF=1:$email2/;
# $newcard =~ s/-0500/-05/; #not supported by libicalvcard yet
$newcard =~ s/-0500/-05/;
$newcard =~ s/TZ;VALUE=TEXT:/TZ:/;

$Response = $CardDAV->{ua}->request('PUT', $CardDAV->request_url($href), {
Expand All @@ -107,12 +107,13 @@ EOF
$self->assert_matches(qr/PHOTO;TYPE=$video(,$gif)?;$binary(;TYPE=$gif)?:$photo/,
$newcard);
$self->assert_matches(qr/LOGO;VALUE=$uri;TYPE=JPEG:$logo/, $newcard);
$self->assert_matches(qr/SOUND;$binary;TYPE=$mp3:$sound/, $newcard);
$self->assert_matches(qr/SOUND(;TYPE=$mp3)?;$binary(;TYPE=$mp3)?:$sound/,
$newcard);
$self->assert_matches(qr/GEO:$lat;$lon/, $newcard);
$self->assert_matches(qr/TEL;TYPE=foo$typesep$work$typesep$pref:$tel/,
$self->assert_matches(qr/TEL;TYPE=foo$typesep$work$typesep$pref(;PREF=1)?:$tel/,
$newcard);
$self->assert_matches(qr/EMAIL:$email1/, $newcard);
$self->assert_matches(qr/EMAIL;TYPE=$pref:$email2/, $newcard);
$self->assert_matches(qr/EMAIL(;PREF=2)?:$email1/, $newcard);
$self->assert_matches(qr/EMAIL(;PREF=1)?;TYPE=$pref:$email2/, $newcard);
$self->assert_matches(qr/TZ(;VALUE=$utcoff)?:-05(:)?00/, $newcard);
$self->assert_matches(qr/TZ;VALUE=$text:$tzid/, $newcard);
}
4 changes: 2 additions & 2 deletions cassandane/tiny-tests/JMAPContacts/card_get_v4
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sub test_card_get_v4
my $card = <<EOF;
BEGIN:VCARD
VERSION:4.0
UID:$id
UID;VALUE=TEXT:$id
KIND:individual
FN:Simon Perreault
N:Perreault;Simon;;;ing. jr
Expand All @@ -50,7 +50,7 @@ foo.TZ:America/Montreal
URL;PROP-ID=L1;TYPE=home:http://nomis80.org
PHOTO;PROP-ID=P1:data:image/jpeg;base64,c29tZSBwaG90bw==
LOGO;PROP-ID=L1;MEDIATYPE=image/png:http://example.org/logo.png
SOUND;VALUE=X;PROP-ID=S1:data:audio/mpeg;base64,c29tZSBzb3VuZA==
SOUND;VALUE=URI;PROP-ID=S1:data:audio/mpeg;base64,c29tZSBzb3VuZA==
IMPP;PROP-ID=OS1;PREF=1:xmpp:simon\@example.com
SOCIALPROFILE;PROP-ID=OS2;SERVICE-TYPE=Mastodon;USERNAME="Simon P.":https://example.com/\@simon
REV:20230422T194639Z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ sub test_card_set_create_anniversaries
my $card = $res->{content};
$card =~ s/\r?\n[ \t]+//gs; # unfold long properties

$self->assert_matches(qr|BDAY;VALUE=DATE;PROP-ID=k8:19530415|, $card);
$self->assert_matches(qr|BDAY;PROP-ID=k8:19530415|, $card);
$self->assert_matches(qr|DEATHDATE;VALUE=TIMESTAMP;PROP-ID=k9:20191015T231000Z|, $card);
$self->assert_matches(qr|DEATHPLACE;PROP-ID=k9:4445 Tree Street\\nNew England\\, ND 58647\\nUSA|, $card);
$self->assert_matches(qr|ANNIVERSARY;VALUE=DATE;PROP-ID=k10:1975|, $card);
$self->assert_matches(qr|ANNIVERSARY;PROP-ID=k10:1975|, $card);
$self->assert_matches(qr|JSPROP;JSPTR=anniversaries/k10/place:|, $card);
}
17 changes: 10 additions & 7 deletions imap/http_carddav.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,8 +951,9 @@ static int export_addressbook(struct transaction_t *txn,
(vcardcomponent_get_version(vcard) == VCARD_VERSION_40) ? 4 : 3;

if (version != want_ver || want_ver == 4) {
if (want_ver == 4) vcard_to_v4_x(vcard);
else vcard_to_v3_x(vcard);
vcardcomponent_transform(vcard,
want_ver == 4 ? VCARD_VERSION_40 :
VCARD_VERSION_30);
}

if (r++ && *sep) {
Expand All @@ -976,7 +977,7 @@ static int export_addressbook(struct transaction_t *txn,

if (vcard) {
struct vparse_entry *ventry =
vparse_get_entry(vcard, NULL, "version");
vparse_get_entry(vcard->objects, NULL, "version");
unsigned version = (ventry && ventry->v.value[0] == '4') ? 4 : 3;

if (version != want_ver || want_ver == 4) {
Expand Down Expand Up @@ -1339,8 +1340,9 @@ static int carddav_get(struct transaction_t *txn, struct mailbox *mailbox,
if (cdata->version != want_ver || want_ver == 4) {
/* Translate between vCard versions */
*obj = record_to_vcard_x(mailbox, record);
if (want_ver == 4) vcard_to_v4_x(*obj);
else vcard_to_v3_x(*obj);
vcardcomponent_transform(*obj,
want_ver == 4 ? VCARD_VERSION_40 :
VCARD_VERSION_30);
}

return HTTP_CONTINUE;
Expand Down Expand Up @@ -2230,8 +2232,9 @@ static int propfind_addrdata(const xmlChar *name, xmlNsPtr ns,

if (!vcard) vcard = fctx->obj = vcard_parse_string_x(data);

if (want_ver == 4) vcard_to_v4_x(vcard);
else vcard_to_v3_x(vcard);
vcardcomponent_transform(vcard,
want_ver == 4 ? VCARD_VERSION_40 :
VCARD_VERSION_30);
}

if (strarray_size(partial)) {
Expand Down
Loading

0 comments on commit 2f0c1bc

Please sign in to comment.