Changeset 8063
- Timestamp:
- 07/07/10 15:44:23 (23 months ago)
- Location:
- trunk/CalDAVPlugin
- Files:
-
- 4 edited
-
data/System/CalDAVPlugin.txt (modified) (3 diffs)
-
lib/Foswiki/Plugins/CalDAVPlugin.pm (modified) (2 diffs)
-
lib/Foswiki/Plugins/CalDAVPlugin/Config.spec (modified) (1 diff)
-
lib/Foswiki/Plugins/CalDAVPlugin/Core.pm (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/CalDAVPlugin/data/System/CalDAVPlugin.txt
r7999 r8063 8 8 [[http://en.wikipedia.org/wiki/CalDAV][CalDAV]] server and the 9 9 CalendarPlugin. !CalDAV is a protocol used by many calendaring applications, 10 t he most notable being iCal on Apple products.10 two of the most notable being Apple's iCal, and Google calendar. 11 11 12 12 The plugin works by accessing a calendar on the !CalDAV server and 13 13 generating an event list in the "bulleted event list" format that 14 the !CalendarPlugin uses. 14 the !CalendarPlugin (and HolidaylistPlugin) can use. 15 16 Note that the !CalDAVPlugin will generate individual events for recurrences. 17 The limits for the number of events generated for each recurrence can be 18 configured using the =stop= parameter. 15 19 16 20 %TOC% 17 21 18 22 ---++ Usage 19 Put the macro =%<nop>CALDAV{"calendar"}% anywhere on a topic. The 20 CalendarPlugin will automatically pick up the events from it. 23 Put the macro =%<nop>CALDAV{"calendar"}%= anywhere on a topic. This will 24 generate a bulleted list when the macro is expanded. The 25 CalendarPlugin (and HolidaylistPlugin) will automatically pick up the 26 events from this list. 21 27 22 | *Parameter* | *Meaning* | 23 | ="calendar"= | The name of a declared calendar|24 | = url= | The url of a remote calendar you want to view|25 | =u ser= | Username used to access the remote calendar|26 | = pass= | Password for the user used to access the remote calendar|27 | = stop= | Hard stop for recurrences. This takes two values, separated by commas. The first value specifies the maximum number of events generated by a single recurrence, and the second value specifies the maximum number of days to generate events for. For example, =stop="50,365"= (the default) will prevent any recurrence generating more than 50 events, or any events more than 365 days from now.|28 *Source parameters* 29 | *Parameter* | *Meaning* | *Default* | 30 | ="calendar"= | The name of a pre-declared calendar (see Installation, below) | none; if you don't provide this, you have to specify =url=, =user= and =pass=. | 31 | =url= | The url of a remote calendar you want to view | from =calendar= | 32 | =user= | Username used to access the remote calendar | from =calendar= | 33 | =pass= | Password for the user used to access the remote calendar | from =calendar= | 28 34 29 For obvious security reasons, you are recommended to use the ="calendar"= method to specify the calendar to retrieve. 35 *Generator parameters* 36 | *Parameter* | *Meaning* | *Default* | 37 | =stop= | Hard stop for recurrences. This takes two values, separated by commas. The first value specifies the maximum number of events generated by a single recurrence, and the second value specifies the maximum number of days to generate events for. For example, =stop="50,365"= will prevent any recurrence generating more than 50 events, or any events more than 365 days from now. | =50,365= | 38 | =target= | Name of a predefined target format e.g. =calendar= for the !CalendarPlugin or =holidaylist= for the !HolidayListPlugin. | =calendar= | 39 | =event= | Format of an individual event. If =target= is given, this parameter will override the default provided by the =target=. | =target= | 40 | =range= | Format of an event range. If =target= is given, this parameter will override the default provided by the =target=. | =target= | 41 | =separator= | String used to separate events in the output | =$n= | 42 Any other named parameters will be passed on to the output via the corresponding format token. 30 43 31 Note that the !CalendarPlugin does not support a wide range of recurrences, 32 and the !CalDAVPlugin will generate individual events for recurrences that 33 it can't map to the !CalendarPlugin. The limits for the number of events 34 generated for each recurrence can be configured using the plugin parameters. 44 The output is generated by expanding format tokens in the =event= and =range= format parameters as appropriate. The tokens expanded from the event data are: 45 | *Token* | *Meaning* | 46 | =$second= (seconds, 00..59)<br/> =$minute= (minutes, 00..59)<br/> =$hour= (hours, 00..23)<br/> =$day= (day of month, 01..31)<br/> =$month= (month, 01..12)<br/> =$mon= (month in text format, Jan..Dec)<br/> =$year= (4 digit year, 1999)<br/> =$ye= (2 digit year, 99)<br/> =$wd= (day of the week, 1 for Sunday, 2 for Monday, etc)<br/> =$wday= (day of the week, Sun..Sat)<br/> =$weekday= (day of the week, Sunday..Saturday)<br/> =$yearday= (day of the year) | Event time (or start time for a range) | 47 | As above, but with =e= at the start of the name e.g. =$esecond=, =$eminute= etc. | Range end time | 48 | =$summary= | Event summary | 49 | =$description= | Event (full) description | 50 | =$param= | where =param= is the name of a parameter to %<nop>CALDAV e.g. =$icon= | 51 52 All [[FormatTokens][standard format tokens]] are supported (once all the above format tokens have been expanded). 53 54 __Tip__ you can hide the bulleted list that the %<nop>CALDAV macro generates 55 by enclosing it in HTML comments e.g. 56 <verbatim> 57 <!-- 58 %CALDAV{"GeorgeWShrub" target="holidaylist"}% 59 --> 60 </verbatim> 61 62 ---+++ !CalendarPlugin 63 The events generated when using the =target="calendar"= format use the following formats: 64 * =event='$day $month $year - $summary'= 65 * =range='$day $month $year - $eday $emonth $eyear - $summary'= 66 Example: =%<nop>CALDAV{"Jean" target="calendar"}%= 67 68 ---+++ !HolidaylistPlugin 69 * =event='$day $month $year - $name - $summary - $icon'= 70 * =range='$day $month $year - $eday $emonth $eyear - $name - $summary - $icon'= 71 =$name= is the calendar name, or can be overridden by a =name= parameter. 72 =$icon= is taken from the parameter of the same name, and is a fragment of TML that generates an icon. It defaults to the empty string. 73 74 Example: =%<nop>CALDAV{"UK" icon="$percntICON{ukflag}$percnt" target="holidaylist"}%= 35 75 36 76 ---++ Installation Instructions … … 38 78 %$INSTALL_INSTRUCTIONS% 39 79 40 Use =configure= to set up the calendars you want to access. 80 Use =configure= to set up any pre-declared calendars you want to access. Example 81 configuration: 82 <verbatim> 83 $Foswiki::cfg{Plugins}{CalDAVPlugin}{Calendars} = { 84 home => { 85 url => 'http://127.0.0.1/caldav.php/simon/home/Home.ics', 86 user => 'simon', 87 pass => 'xxx' 88 }, 89 office => { 90 url => 'http://calendar.corp.com/simple/simon', 91 user => 'caladmin', 92 pass => 'yyy' 93 }; 94 </verbatim> 95 This configures two calendars, 'home' and 'office'. The parameters specify 96 the !CalDAV server - for more information on what these parameters mean, see [[http://search.cpan.org/~simonw/Cal-DAV-0.6/lib/Cal/DAV.pm][the !CalDAV module on CPAN]] 97 98 Pre-declaring calendars is obviously important from a perspective of 99 protecting sensitive username and password information. Unfortunately there 100 is no way to limit access to remote calendars based on the logged-in user. 41 101 42 102 ---++ Info 43 103 Many thanks to the following sponsors for supporting this work: 44 * Apple Inc.104 * Apple, Inc. 45 105 46 106 | Author(s): | Crawford Currie http://c-dot.co.uk | … … 50 110 | Version: | %$VERSION% | 51 111 | Change History: | <!-- versions below in reverse order --> | 112 | 1.000 (7 Jul 2010) | Initial release | 52 113 | Dependencies: | %$DEPENDENCIES% | 53 114 | Home page: | http://foswiki.org/bin/view/Extensions/CalDAVPlugin | -
trunk/CalDAVPlugin/lib/Foswiki/Plugins/CalDAVPlugin.pm
r7999 r8063 5 5 6 6 ---+ package Foswiki::Plugins::CalDAVPlugin 7 8 When developing a plugin it is important to remember that9 Foswiki is tolerant of plugins that do not compile. In this case,10 the failure will be silent but the plugin will not be available.11 See %SYSTEMWEB%.InstalledPlugins for error messages.12 13 __NOTE:__ Foswiki:Development.StepByStepRenderingOrder helps you decide which14 rendering handler to use. When writing handlers, keep in mind that these may15 be invoked on included topics. For example, if a plugin generates links to the16 current topic, these need to be generated before the =afterCommonTagsHandler=17 is run. After that point in the rendering loop we have lost the information18 that the text had been included from another topic.19 20 __NOTE:__ Not all handlers (and not all parameters passed to handlers) are21 available with all versions of Foswiki. Where a handler has been added22 (or deprecated) the POD comment will indicate this with a "Since" line23 e.g. *Since:* Foswiki::Plugins::VERSION 1.124 25 See http://foswiki.org/Download/ReleaseDates for a breakdown of release26 versions.27 7 28 8 =cut … … 34 14 35 15 our $VERSION = '$Rev: 7888 $'; 36 our $RELEASE = '1. 1.1';16 our $RELEASE = '1.000'; 37 17 our $SHORTDESCRIPTION = 'Extract a list of events from a CalDAV (iCal) server'; 38 18 our $NO_PREFS_IN_TOPIC = 1; 39 19 40 20 sub initPlugin { 41 my ( $topic, $web, $user, $installWeb ) = @_; 42 21 # my ( $topic, $web, $user, $installWeb ) = @_; 43 22 Foswiki::Func::registerTagHandler( 'CALDAV', \&_CALDAV ); 44 45 23 return 1; 46 24 } 47 25 48 26 sub _CALDAV { 49 my($session, $params, $theTopic, $theWeb) = @_;27 # my($session, $params, $topic, $web) = @_; 50 28 51 29 require Foswiki::Plugins::CalDAVPlugin::Core; -
trunk/CalDAVPlugin/lib/Foswiki/Plugins/CalDAVPlugin/Config.spec
r7999 r8063 2 2 #---++ CalDAVPlugin 3 3 # **PERL** 4 # Set of calendars that can be accessed using shortcuts f rm the CALDAV macro.4 # Set of calendars that can be accessed using shortcuts form the CALDAV macro. 5 5 # Each calendar specification must include a user, password and url. 6 6 $Foswiki::cfg{Plugins}{CalDAVPlugin}{Calendars} = { 7 home => {8 url => 'http:// simian:x@192.168.1.12/caldav.php/simian/home/Home.ics',9 user => ' simian',10 pass => ' x'7 example => { 8 url => 'http://example.com/caldav.php/example', 9 user => 'example', 10 pass => 'example' 11 11 }, 12 12 }; -
trunk/CalDAVPlugin/lib/Foswiki/Plugins/CalDAVPlugin/Core.pm
r7999 r8063 1 1 # See bottom of file for license and copyright information 2 2 package Foswiki::Plugins::CalDAVPlugin::Core; 3 4 use strict; 5 use warnings; 3 6 4 7 use Cal::DAV; … … 6 9 use DateTime::Format::ICal; 7 10 8 # Target formats 9 # dd MMM yyyy - description 10 # * 09 Dec 2002 - Expo 11 # dd MMM yyyy - dd MMM yyyy - description 12 # * 02 Feb 2002 - 04 Feb 2002 - Vacation 13 # dd MMM - description 14 # * 05 Jun - Every 5th of June 15 # w DDD MMM - description 16 # * 2 Tue Mar - Every 2nd Tuesday of March 17 # rrule: FREQ=MONTHLY 18 # L DDD MMM - description 19 # * L Mon May - The last Monday of May 20 # rrule: FREQ=MONTHLY 21 # A dd MMM yyyy - description 22 # * A 20 Jul 1969 - First moon landing 23 # FREQ=YEARLY 24 # w DDD - description 25 # * 1 Fri - Every 1st Friday of the month 26 # FREQ=MONTHLY,BYDAY=FR 27 # L DDD - description 28 # * L Mon - The last Monday of each month 29 # dd - description 30 # * 14 - The 14th of every month 31 # E DDD - description 32 # * E Wed - Every Wednesday 33 # E DDD dd MMM yyyy - description 34 # * E Wed 27 Jan 2005 - Every Wednesday Starting 27 Jan 2005 35 # E DDD dd MMM yyyy - dd MMM yyyy - description 36 # * E Wed 1 Jan 2005 - 27 Jan 2005 - Every Wednesday from 1 Jan 2005 through 27 Jan 2005 (inclusive) 37 # En dd MMM yyyy - description 38 # * E3 02 Dec 2002 - Every three days starting 02 Dec 2002 39 # En dd MMM yyyy - dd MMM yyyy - description 40 # * E3 12 Apr 2005 - 31 Dec 2005 - Every three days from 12 Apr 2005 through 31 Dec 2005 (inclusive) 11 my %formats = ( 12 calendar => { 13 event => ' * $day $month $year - $summary', 14 range => ' * $day $month $year - $eday $emonth $eyear - $summary', 15 }, 16 holidaylist => { 17 event => ' * $day $month $year - $name - $summary - $icon', 18 range => ' * $day $month $year - $eday $emonth $eyear - $name - $summary', 19 }, 20 ); 21 22 use constant TRACE => 1; 23 24 =begin TML 25 26 ---++ StaticMethod CALDAV($session, $params, $topic, $web) 27 28 Macro handler, indirected via CalDAVPlugin.pm 29 30 Read CalDAV data from a remote server and generate output in a format 31 suitable for use by different plugins. 32 33 You can define an output format (using the 'target' parameter), or 34 select from a range of predefined formats. 'header', 'footer' and 35 'separator' have conventional interpretations, and all standard formatting 36 tokens are supported. 37 38 =cut 41 39 42 40 sub CALDAV { … … 67 65 my $cal; 68 66 eval { 69 $cal = Cal::DAV->new( user => $user, pass => $pass, url => $url);67 $cal = Cal::DAV->new( user => $user, pass => $pass, url => $url); 70 68 }; 71 69 unless ($cal) { … … 73 71 return "<span class='foswikiAlert'>Calendar could not be opened</span>"; 74 72 } 73 74 $params->{name} = $calendar unless defined $params->{name}; 75 $params->{name} = $params->{url} unless defined $params->{name}; 76 $params->{separator} = '$n()' unless defined $params->{separator}; 75 77 76 78 my $stop = $params->{stop}; … … 92 94 $event{start} = 93 95 DateTime::Format::ICal->parse_datetime($p->value); 94 push(@events, " # dtstart ".$event{start});96 push(@events, " dtstart ".$event{start}) if (TRACE); 95 97 } elsif ($k eq 'dtend') { 96 98 $event{end} = 97 99 DateTime::Format::ICal->parse_datetime($p->value); 98 push(@events, " # dtend ".$event{end});100 push(@events, " dtend ".$event{end}) if (TRACE); 99 101 } elsif ($k eq 'summary') { 102 $event{summary} = $p->{value}; 103 push(@events, " summary ".$event{summary}) if (TRACE); 104 } elsif ($k eq 'description') { 100 105 $event{description} = $p->{value}; 101 $event{description} =~ s/\n/<br>/gs;102 106 } elsif ($k eq 'rrule') { 103 push(@events, " # rrule $p->{value}");107 push(@events, " rrule $p->{value}") if (TRACE); 104 108 $event{recurrence} = $p->{value}; 105 109 } … … 113 117 recurrence => $event{recurrence}, 114 118 dtstart => $event{start}); 115 # Limit to the request range *or* $stopDays *or* $stopCount repeats 119 # Limit to the request range *or* $stopDays *or* 120 # $stopCount repeats 116 121 my $span = DateTime::Span->from_datetimes( 117 122 start => $event{start} || … … 122 127 $event{count} = $stopCount if ($event{count} > $stopCount); 123 128 124 push(@events, " * ".Foswiki::Time::formatTime( 125 Foswiki::Time::parseTime($event{start})) 126 . ' - '.$event{description}); 129 my $s = Foswiki::Time::parseTime($event{start}); 130 push(@events, 131 { 132 start => $s, 133 summary => $event{summary}, 134 description => $event{description}, 135 }); 127 136 $event{count}--; 128 137 my $iter = $recur->iterator(span => $span); 129 138 while ( $event{count} && (my $dt = $iter->next) ) { 130 push(@events, " * " . Foswiki::Time::formatTime( 131 Foswiki::Time::parseTime($dt)) 132 . ' - '.$event{description}); 139 my $d = Foswiki::Time::parseTime($dt); 140 next if $d == $s; 141 push(@events, 142 { 143 start => $d, 144 summary => $event{summary}, 145 description => $event{description}, 146 }); 133 147 $event{count}--; 134 148 } 135 149 } else { 136 my $evs = Foswiki::Time::formatTime(137 Foswiki::Time::parseTime($event{start}));138 if (defined $event{end}) {139 $evs .= ' - '.Foswiki::Time::formatTime(140 Foswiki::Time::parseTime($event{end}));141 }142 $evs .= ' - '.$event{description};143 push(@events, " * $evs");150 push(@events, 151 { 152 start => Foswiki::Time::parseTime($event{start}), 153 end => (defined $event{end}) ? 154 Foswiki::Time::parseTime($event{end}) : undef, 155 summary => $event{summary}, 156 description => $event{description}, 157 }); 144 158 } 145 159 } 146 return "\n".join("\n", @events)."\n"; 160 return _formatEvents(\@events, $params); 161 } 162 163 sub _formatEvents { 164 my ($events, $params) = @_; 165 166 my $format; 167 my $target = $params->{target} || 'calendar'; 168 if ($target) { 169 $format = $formats{$target} || $formats{calendar}; 170 } 171 my $es = $params->{event}; 172 $es = $format->{event} unless defined $es; 173 my $rs = $params->{range}; 174 $rs = $format->{range} unless defined $rs; 175 my @r = map { _formatEvent($_, $params, $es, $rs) } @$events; 176 return Foswiki::Func::decodeFormatTokens(join($params->{separator}, @r)); 177 } 178 179 sub _formatEvent { 180 my ($event, $params, $es, $rs) = @_; 181 return $event unless ref($event); 182 my $s = (defined $event->{end}) ? $rs : $es; 183 $s = Foswiki::Time::formatTime($event->{start}, $s); 184 if (defined $event->{end}) { 185 $s =~ s/\$e(seco?n?d?s?|minu?t?e?s?|hour?s?|day|w(eek|day)|dow 186 |mo(?:nt?h?)?|ye(?:ar)?)(\(\)|(?=\W|$))/\$$1/gx; 187 $s = Foswiki::Time::formatTime($event->{end}, $s); 188 } 189 foreach my $f (keys %$event) { 190 $s =~ s/\$$f(\(\)|(?=\W|$))/$event->{$f}/; 191 } 192 foreach my $f (keys %$params) { 193 next if $f =~ /^_/; 194 $s =~ s/\$$f(\(\)|(?=\W|$))/$params->{$f}/; 195 } 196 return $s; 147 197 } 148 198
Note: See TracChangeset
for help on using the changeset viewer.
