-
-
Save stevepiercy/8100cbe011912dec763c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
/* | |
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