vCard/vCal Parsing?
Alex Tweedly
alex at tweedly.net
Sun Sep 11 19:30:23 EDT 2016
Do you actually mean vCal ? or (more likely) vCalendar - which is the
one that is very similar to vCard ?
vCalendar (better known nowadays as iCalendar) is probably as much of a
minefield for incompatability as vCard :-)
I have a library for *helping to* deal with these, called icsLib. It was
released late 2013 and Jan 2014 (but has been very little used). It
comes as a libray stack, with a demo/test stack and some test data. The
documentation is below (after my signature) to help you decide if it's
likely to be any help to you.
Hmmm - and the web link for it is stale .... so if you would like to try
it out, let me know and I'll email a copy directly, until I get the web
site updated.
It is available under GPL or commercial license, so can be used with the
Community version of Livecode (and I'm going to change it to MIT license
to make it easier and simpler to understand - so feel free to use it any
way you want - by the time anything happens it'll be MIT licensed).
-- Alex.
-- icsLib Both Commercial and GPL / Trial version
-- © 2013 Pebble Beach Apps. To get in touch contact
support at pebblebeachapps.com
-- This stack was written by Alex Tweedly
Current version matching these docs is 1.0
Overview
-------
The library is intended to aid in reading ics (ical) files, created
according to rfc5545.
The library includes a number of small utility functions, and two
significant functions which provide all the main capabilities.
These allow you to import a ".ics" (aka ical) file, and build a calendar
array of the data, and subsequently to "expand" a calendar
to extract all events (and instances of events) which impact a specific
"period of interest" in time. Note that since many calendars
include open-ended recurring events, it is not possible to just "expand"
a calendar - it MUST be for a limited time period.
The parameters and results of these functions are described below in the
detailed functionality section. Here we have simply a
description of the calendar array that is created.
Calendar array definition
-------------------
All data from the ics file is maintained in the calendar array. Note
that (although LC is generally case insensitive), I have followed
a convention on the use of case for array elements - all data from the
ics file is stored using an upper case key (actually, using the
case present in the ics file - which is upper case) using "-" (minus
sign) to separate 'words' in the key; and all data generated by
the library is stored in a lower-case named key, using "_" (underscore)
as a word separator. So for example, an event will generally
have its start date as stored in the ics file
CalA["events"][2]["DTSTART"] will have 20131025T080000Z
CalA["events"][2]["start_date"] will have 20131025
and
CalA["events"][2]["start_date_time"] will have 20131025.060000
(NB even though the event specifies a date+time, "start_date" is
just the date.
"start_date_time" has both date and time - and it has been
adjusted to the correct local timezone).
Since all the data in the ics file is fully described by the RFC, I have
not repeated all that info here, but instead
only described a small subset of the original data, only those which I
think are most often likely to be used.
CalA["X-WR-TIMEZONE"] :: the default timezone for any event which
doesn't specify its own time zone
CalA["default_time_zone"] :: the ultimate default timezone specified by
the app, in case X-WR-TIMEZONE isn't set
CalA["event_count"] :: the number of events in the calendar
CalA["timezones"] :: array of timezone info
[<name>] :: the name of the timezone, and
it contains an array ofdata about it
["TZID"] :: the name of the
TZ - should be the same as the key <name>
["daylight_saving_dates"] ::
a sorted CR-delimited list of dates when clocks change
has the decimal-date/time of the change, and the offset (from UTC)
before, and after, the change
["DAYLIGHT"]
["STANDARD"] For each of
daylight and standard time periods, a numerically indexed array
of event-like info specifying the rules for changing between the two
time periods.
CalA["events"] :: a numerically-indexed list of event structures (i.e. 1
... CalA["event_count"])
Each event structure (i.e. within ["events"][N] or
["timezones"][<name>][<period>][N]) has the following data
...["SUMMARY"] :: the short summary description of the event
...["start_date"] :: the date on which the event starts
...["start_date_time"] :: the date+time the event starts (IF it is a
timed event)
...["whole_day"] :: boolean true if the event is a 'whole day' event
(i.e. untimed)
...["end_date"] and ...["end_date_time"] same as start_date,
start_date_time above, but for the end of the event
...["days_delta_to_end"] :: the number of days from start_date to end_date
...["recur_rule"] :: an array (numericaly indexed - can be multiple of
them) holding the expanded info from any RRULE
...["list_of_rdates"] ;; a CR delimited list of dateItems for the
dates specified by an RDATE entry
Licensing terms
------------
-- These scripts are licensed to you if you agree to be bound to one of
the following
-- License types at your choice.
-- 1) GPL 3
-- You may use icsLib as FREE Software as outlined in the terms of the
GPL3 or any
-- higher version of the GPL as found here:
http://www.gnu.org/licenses/gpl-3.0.html
-- 2) Commercial license:
-- If you do not want to disclose the sources of your application you
have the option to purchase a commercial license
-- by paying a fee. You can buy a commercial license from the runrev
marketplace. At the time of the writing of this document
-- this can be done following this link: http://www.pebblebeachapps.com/???
-- You are paying a license fee for the major version of icsLib. If you
are licensing icsLib 1.x, you will be
-- able to use all upgrades that carry the same major version number (in
this case 1.x). Once the switch is made to a version
-- 2.x of the library, you will need to upgrade your license to use the
latest version. However, of course you may continue to use
-- any version of the library you currently have licensed, without
needing to purchase an upgrade.
-- Such a commercial license releases you from the requirements of the
copyleft GPL license, which include: distribution of all
-- source code, including your own product; licensing of your own
product under the GPL license; prominent mention of the
-- Pebble Beach Apps copyright and the GPL license; and disclosure of
modifications to the library.
-- Code Contributions
-- If you want to contribute to icsLib's codebase and want your changes
to be accepted into the main trunk,
-- you will have to accept our open source contribution agreement as
found here: http:<to be defined>
Dates, Times, etc.
--------------
The interface to the library uses two main styles of dates/times. One is
LC's "dateItems" (q.v.) format, the other is a
8-char date format (YYYYMMDD) and/or 15 character date+time
(YYYYMMDD.HHMMSS). I wanted to choose a format which
satisfied as many as possible of the following criteria:
1. It should be easy to compare two dates or date/times.
2. It should be easy to do arithmetic (add days, find difference between
dates, etc)
3. It should be easy to work with.
One obvious choice would have been Julian days / dates; they are
comparable and easy for arithmetic, but
I found them so hard to deal with ( is 2456590.89948 today or tomorrow ?
...)
They YYYYMMDD.HHMMSS format dates are comparable and very easy to use.
You can't do arithmetic on them easily,
but that is only needed in a couple of places - hence that was the
format chosen.
Note the dates and date/times within the ICS files are in a different
(again) format, YYYYMMDD'T'HHMMSS(Z)
using the letter 'T' where I used a ".", and optionally having a 'Z' on
the end to indicate UTC time. So if you look at the
calendar info, you will see that format of dates.
Detailed Function descriptions
------------------------
function icsParseICSData pData, @pCalA, pDefaultTimeZone
Returns the string of wanrings / exceptions from processing.
The real result is the modification of pCalA
Parameters
pData - the string contining the calendar data (i.e. .ics format)
@pCalA - an array passed by reference - it will be filled in with
the calendar contents.
pDefaultTimeZone - the timezone to be used by default, for events
which do not specify their own
timezone, and where there is no
calendar-wide default.
function icsExpandCal pCalName, pCalA, @pDays, @pInstances, pStart, pEnd
Returns the affected days and the event number+ date of all instances of
events affecting the specified time period,
Note that an event which extends over 3 days within the period of
interest will therefore have 3 entriesin the "days" list,
and a single entry on the "instance" list.
Parameters
pCalName - the name of the calendar (used in some error reporting)
pCalA - the calendar array (e.g. as filled in by icsParseICSData)
@pdays - passed by reference - filled in with the affected days.
This is a CR-delimited list of days affected by the
events of the calendar; each line consists of
event-ID,day
(event-ID is a number -
the index within pCalA["events"]
day is in YYYYMMDD format)
@pInstances - passed by reference - filled in with the instance of
any event affecting the time period
This is a CR-delimited list of instances, each line
consisting of
event-ID,start-day,end-day
(event-ID is a number -
the index within pCalA["events"]
start-day and end-day
are in YYYYMMDD format)
pStart - the start date of the period of interest
pEnd - end date of the period of interest
function icsVersion
Returns the version number of the library e.g. 1.7
function icsTimeAdjust @pWholeCalA, @pDateTimeItems, pTZID
Returns empty (for future use)
Adjust pDateTimeItems appropriately by the first available of
- the timezone pTZID
- a calendar-wide default timezone (i.e. if defined by
X-WR-TIMEZONE)
- an app-defined default timezone (i.e. if defined in an earlier
call to icsPasrseCSData)
Parameters:
@pWholeCalA - calendar array (for timezone definitions and pehaps
default timezone)
passed by reference, but not modified
@pDateItems - passed in a date+time (as LC dateItems), modified
according to the timezone
@pTZID - name of the timezone to be used; empty to use a default
function icsGetBuiltInTZAsCalendar
Returns a calendar array for all the built-in timezones
function icsGetTZPeriodName @pWholeCalA, pDateTimeItems, pTZID
Returns the name of the period of the timezone on the specified
date+time (e.g. BST, CDT, ...)
Parameters:
@pWholeCalA - calendar array (for timezone definitions and pehaps
default timezone)
passed by reference, but not modified
@pDateItems - passed in a date+time (as LC dateItems), modified
according to the timezone
@pTZID - name of the timezone to be used; empty to use a default
function icsDOWName pDateItems
Return the name of the day of the week
Parameters
pDateItems - the date+time for which the name is to be given
function icsDOY pDateItems
Return the day number within the year of a given date+time
Parameters
pDateItems - the date+time for which the name is to be given
function icsISOCW pY, pM, pD
Returns the ISO week number within the year
Parameters
pY, pM, pD - the Year, Month and Day of the date in question
function icsLastDayInMonth pY, pM
Returns the number of days in the specified month
Parameters
pY, pM - the Year and Month
function icsAddDays pDate, pCount
Returns the result (in YYYYMMDD format ) of adding some days to an
initial date
Parameters
pDate - the initial date in YYYYMMDD format
pCount - the number of days to add
function icsDateItemsDelta p1, p2
Returns the number of seconds between two dates (NB positive if second
is later than first)
Parameters
p1, p2 - dates in dateItems format
function icsDateTime2Items pDate
Returns the dateItems corresponding to a 15 or 16 character date/time
(i.e. suitable inputs are either floating or UTC date/time from
an ICS file)
The result does not distinguish between floating and UTC - that
is left for the caller.
Parameters
pDate - either a 15 char floating (20131028T123530) or 16-char UTC
(20131028T123530Z)
function icsDate2Items pDate
Returns a date in dateItems format
Parameters
pDate - a date (i.e. no time specified), primarily in YYYYMMDD format
such as 20131028, but will also (mostly for
historical reasons)
also accept YYYY-MM-DD format, or even DD-MM-YYYY
function icsItems2Date pDate
Returns a YYYYMMDD format date given a dateItems format
Parameters
pDate - a dateItems format date
function icsItems2DateTime pDateItems
Returns a "decimal date time" from a dateItems format date/time. Result
will be in format YYYYMMDDT.HHMMSS
Note the decimal part is in HHMMSS format - NOT a decimal
fraction of a day !!
This allows comparison against simple date/time (YYYYMMDD) or
with another decimal date/time.
Parameters
pDateItems - a dateItems format date/time
function icsDate2DayNum pDate
Returns the day number within the week of a YYYYMMDD
Parameters
pDate - YYYYMMDD format date
-----------------------------------------------
On 09/09/2016 14:44, Peter Reid wrote:
> Has anyone got a library for parsing vCard and vCal files? I found some forum chat from 2006 about a library called vObjectPackage developed by Andre Garzia but the links to this are dead. Does anyone know whether this is still available or whether there are alternatives?
>
> Thanks
>
> Peter
> --
> Peter Reid
> Loughborough, UK
>
>
> _______________________________________________
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode
More information about the use-livecode
mailing list