I have a vCard file mycontacts.vcf
:
BEGIN:VCARD
N:Montana;Joe;;;
FN:Joe Montana
BDAY;value=date:1988-05-20
END:VCARD
BEGIN:VCARD
N:Smith;Joe;;;
FN:Joe Smith
BDAY;value=date:1999-07-04
END:VCARD
How can one create a CalDAV file from this from linux command line, e.g. using awk or a simple python script, such that the output is:
BEGIN:VEVENT
SUMMARY:Joe Montana
DTSTART;VALUE=DATE:19880520
DTEND;VALUE=DATE:19880521
END:VEVENT
BEGIN:VEVENT
SUMMARY:Joe Smith
DTSTART;VALUE=DATE:19990704
DTEND;VALUE=DATE:19990705
END:VEVENT
By the way, contacts were exported from an ipad using pythonista app:
import contacts
people = contacts.get_all_people()
for p in people:
print(p.vcard.decode('utf-8'))
The resulting CalDAV is to be imported into thunderbird.
With any awk you can set the end date to the current date:
$ cat vcf2dav.awk
BEGIN { OFS=":" }
!NF { print; next }
{
tag = val = $0
sub(/[:;].*$/,"",tag)
sub(/^[^:]+:/,"",val)
}
tag ~ /^(BEGIN|END)$/ { print tag, "VEVENT" }
tag == "FN" { print "SUMMARY", val }
tag == "BDAY" {
gsub(/-/,"",val)
print "DTSTART;VALUE=DATE", val
print "DTEND;VALUE=DATE", val
}
.
$ awk -f vcf2dav.awk mycontacts.vcf
BEGIN:VEVENT
SUMMARY:Joe Montana
DTSTART;VALUE=DATE:19880520
DTEND;VALUE=DATE:19880520
END:VEVENT
BEGIN:VEVENT
SUMMARY:Joe Smith
DTSTART;VALUE=DATE:19990704
DTEND;VALUE=DATE:19990704
END:VEVENT
but if you really want it to be the day after then you need to employ time functions, e.g. with GNU awk for built in time functions:
$ cat vcf2dav.awk
BEGIN { OFS=":" }
!NF { print; next }
{
tag = val = $0
sub(/[:;].*$/,"",tag)
sub(/^[^:]+:/,"",val)
}
tag ~ /^(BEGIN|END)$/ { print tag, "VEVENT" }
tag == "FN" { print "SUMMARY", val }
tag == "BDAY" {
begDate = val
endDate = dayAfter(begDate)
gsub(/-/,"",begDate)
print "DTSTART;VALUE=DATE", begDate
print "DTEND;VALUE=DATE", endDate
}
function dayAfter(curDate, curSecs, nxtDate) {
curSecs = mktime(gensub(/-/," ","g",curDate)" 0 0 0")
nxtDate = strftime("%Y%m%d",curSecs + 24*60*60)
return nxtDate
}
.
$ awk -f vcf2dav.awk mycontacts.vcf
BEGIN:VEVENT
SUMMARY:Joe Montana
DTSTART;VALUE=DATE:19880520
DTEND;VALUE=DATE:19880521
END:VEVENT
BEGIN:VEVENT
SUMMARY:Joe Smith
DTSTART;VALUE=DATE:19990704
DTEND;VALUE=DATE:19990705
END:VEVENT
With other awks you'd change the dayAfter()
function to call UNIX date
or do whatever else works in your environment to get the next day.