Skip to content

Instantly share code, notes, and snippets.

@stevepiercy
Forked from jolle-c/Lasso_icalendar.lasso
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevepiercy/8100cbe011912dec763c to your computer and use it in GitHub Desktop.
Save stevepiercy/8100cbe011912dec763c to your computer and use it in GitHub Desktop.
[
/*
2014-10-08 JC Added to Gist
*/
/**!
ical_encodebreak
Method to ensure that the given string complies to the icalendar requirements that no row inside an icalendar object is longer than 75 octets (bytes)
EXAMPLE
ical_encodebreak('Räksmörgås Lorem ipsum dolor sit amet, consectetur räksmörgås adip\:SNOWMAN: iscing elit.')
CHANGE NOTES
2014-07-16 JC First version, based heavily on Kyle Jessups suggestion in Lassotalk
*/
define ical_encodebreak(string::string, max::integer = 73) => {
local(result = string, count = 0)
#string -> replace(regexp(`(\r\n|\r|\n)`), `\\n`)
with char in #string -> eachcharacter
let b = #char -> asbytes
let size = #b -> size
do {
if (#count + #size > #max) => {
#result -> append('\r\n ' + #char)
#count = 0
else
#count += #size
#result->append(#char)
}
}
return #result
}
define ical_encodebreak(string::bytes, max::integer = 73) => ical_encodebreak(string(#string), #max)
/**!
ical_package
Method to create and package an Icalendar bytes object. Can handle a single ical event or an entire calendar.
EXAMPLE
ical_package(
'//Kulturfaktorn//Org Name Goes Here//Lasso ' + lasso_version + '//SV',
array(
map(
'created_datetime' = #row(::created_datetime),
'updated_datetime' = #row(::updated_datetime),
'id' = #row(::id),
'rrule_freq' = #row(::rrule_freq),
'rrule_count' = #row(::rrule_count),
'rrule_enddate' = #row(::rrule_enddate),
'attach' = (with filerow in #filerows select ((server_port == 443 ? 'https://' | 'http://') + server_name + '/file/' + encode_base64url(string(#filerow(::id)) + '||event') + '/' + encode_url(string(#filerow(::original_filename)))
)) -> asstaticarray,
'event_timezone' = #row(::event_timezone),
'event_endtime' = #row(::event_endtime),
'event_enddate' = #row(::event_enddate),
'event_title' = #row(::event_title),
'event_starttime' = #row(::event_starttime),
'event_startdate' = #row(::event_startdate),
'event_location' = #row(::event_location),
'event_sequence' = #row(::event_sequence),
'event_description' = #row(::event_description),
)
)
)
CHANGE NOTES
2014-07-16 JC First version
*/
define ical_package(prodid::string, eventdata::array) => {
local(
noerror = true,
dtstamp = date,
export = array(
'BEGIN:VCALENDAR',
'CALSCALE:GREGORIAN',
'VERSION:2.0',
'METHOD:PUBLISH',
'PRODID:-' + #prodid,
'BEGIN:VTIMEZONE',
'TZID:Europe/Stockholm',
'BEGIN:DAYLIGHT',
'TZOFFSETFROM:+0100',
'RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU',
'DTSTART:19810329T020000',
'TZNAME:CEST',
'TZOFFSETTO:+0200',
'END:DAYLIGHT',
'BEGIN:STANDARD',
'TZOFFSETFROM:+0200',
'RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU',
'DTSTART:19961027T030000',
'TZNAME:CET',
'TZOFFSETTO:+0100',
'END:STANDARD',
'END:VTIMEZONE'
),
createddate, modifieddate, attach, event_endtime, event_starttime
)
#dtstamp -> timezone = 'GMT'
with event in #eventdata do {
#createddate = date(#event -> find('created_datetime'))
#createddate -> timezone = 'GMT'
#modifieddate = date(#event -> find('updated_datetime'))
#modifieddate -> timezone = 'GMT'
#event_starttime = string(#event -> find('event_starttime'))
#event_starttime -> replace(':', '')
#event_endtime = string(#event -> find('event_endtime'))
#event_endtime -> replace(':', '')
#export -> insert('BEGIN:VEVENT')
#export -> insert('CREATED:' + #createddate -> knop_format(`yyyyMMdd'T'HHmmss'Z'`))
#export -> insert('LAST-MODIFIED:' + #modifieddate -> knop_format(`yyyyMMdd'T'HHmmss'Z'`))
#export -> insert('UID:' + #event -> find('id'))
if(#event -> find('rrule_freq')) => {
local(ruletext = 'RRULE:FREQ=' + #event -> find('rrule_freq') + ';INTERVAL=' + (#event -> find('rrule_interval') or '1'))
if(#event -> find('rrule_count')) => {
#ruletext -> append(';COUNT=' + #event -> find('rrule_count'))
else(#event -> find('rrule_enddate'))
#ruletext -> append(';UNTIL=' + date(#event -> find('rrule_enddate')) -> knop_format(`yyyyMMdd`) + 'T215959Z')
}
#export -> insert(#ruletext)
}
#attach = #event -> find('attach')
if(#attach -> isa(::array) or #attach -> isa(::staticarray)) => {
with attachval in #attach do {
#export -> insert('ATTACH;VALUE=URI:' + #attachval)
}
}
#export -> insert('DTEND;TZID=' + (#event -> find('event_timezone') or 'Europe/Stockholm') + (not #event_endtime ? ';VALUE=DATE') + ':' + date(#event -> find('event_enddate')) -> knop_format(`yyyyMMdd`) + (#event_endtime ? 'T' + #event_endtime))
#export -> insert('TRANSP:OPAQUE')
#export -> insert('SUMMARY:' + #event -> find('event_title'))
#export -> insert('DTSTART;TZID=' + (#event -> find('event_timezone') or 'Europe/Stockholm') + (not #event_starttime ? ';VALUE=DATE') + ':' + date(#event -> find('event_startdate')) -> knop_format(`yyyyMMdd`) + (#event_starttime ? 'T' + #event_starttime))
#export -> insert('DTSTAMP:' + #dtstamp -> knop_format(`yyyyMMdd'T'HHmmss'Z'`))
#export -> insert('LOCATION:' + #event -> find('event_location'))
#export -> insert('SEQUENCE:' + #event -> find('event_sequence'))
#export -> insert('DESCRIPTION:' + #event -> find('event_description'))
#export -> insert('END:VEVENT')
}
#export -> insert('END:VCALENDAR')
return (with row in #export select ical_encodebreak(#row)) -> join('\r\n') -> asbytes
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment