Skip to content

Commit

Permalink
Item9246: first commit of working codebase to svn
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.foswiki.org/trunk/FullCalendarPlugin@8057 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
DavidPatterson authored and DavidPatterson committed Jul 7, 2010
0 parents commit 95e39e8
Show file tree
Hide file tree
Showing 42 changed files with 7,465 additions and 0 deletions.
21 changes: 21 additions & 0 deletions data/System/EventObject.txt
@@ -0,0 +1,21 @@
%META:TOPICINFO{author="ProjectContributor" date="1270024972" format="1.1" reprev="1.1" version="1.1"}%
%META:TOPICPARENT{name="FullCalendarPlugin"}%
---+ %SPACEOUT{%TOPIC%}%

| *Name:* | *Type:* | *Size:* | *Value:* | *Tooltip message:* | *Attributes:* |
| reltopic | text | 20 | | | |
| startDate | text | 10 | | | |
| durationDays | text | 10 | | | |
| startTime | text | 15 | | | |
| endTime | text | 15 | | | |
| users | select+names+multi | 5 | %CALGROUPLIST% | | |
| title | text | 100 | | | |
| location | text | 100 | | | |
| category | select | 1 | mission,meeting,leave,milestone | | |
| repeater | select | 1 | ,YMdd,YMndow,Mdd,Mndow,Wdow,D | | |
| every | select | 1 | ,1,2,3,4,5,6,7,8,9,10 | | |
| nth | select | 1 | ,1,2,3,4,5 | | |
| dow | checkbox+multi | 7 | 1,2,3,4,5,6,7 | | |
| exceptions | text | 50 | | | |
| rangeEnd | text | 10 | | | |
| allDay | select | 1 | 1,0 | | |
723 changes: 723 additions & 0 deletions data/System/FullCalendarNewViewTemplate.txt

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions data/System/FullCalendarPlugin.txt
@@ -0,0 +1,49 @@
%META:TOPICINFO{author="ProjectContributor" date="1275395213" format="1.1" version="1.1"}%
%META:TOPICPARENT{name="WebHome"}%
---+!! Full Calendar Plugin
<!--
* Set SHORTDESCRIPTION = %$SHORTDESCRIPTION%
-->
%SHORTDESCRIPTION%

Adam Shaw has produced a great Web 2.0 Calendar UI, the jQuery !FullCalendar Plugin. This Foswiki plugin provides the backend calendar management code and the js/html interface ontop of the calendar UI for the creation and editing of calendar events.

%TOC%

---++ Features
As well as one-off events, repeating events can be created - daily, weekly, monthly, yearly, every n, every dow, until end-date or no end-date. And exceptions can be created in repeating events.

---
---++ The Calendar Event Object
The event attributes are defined in the EventObject topic. The default definition is in the =%<nop>SYSTEMWEB%=, but can be overridden by a new !EventObject in the =%<nop>USERSWEB%= and finally by one defined in the current web.

---++ Creating and Editing Calendar Events
Just click on a day in the calendar to create a new event via the input form. Click on an existing event to edit its properties via the input form. If the selected event is part of a repeating sequence, the options are to:
* Change this instance only (Create a new event)
* Change all instances (Update the original event record)
* Change all instances from this point onwards (Create a new event record)

---++ Customisation
The EventObject and FullCalendarViewTemplate topics are provided as the default installation. View WebCalendar to see the result. As indicated above, you can create your own EventObject with attributes relevant to your installation and a new view template can be created for the populating of your new event object.

%X% *Note, the default FullCalendarViewTemplate expects the =%USERGROUP%= variable to be set to a Group topic that gets parsed to provide a multi-select list of attendees. You can, off course, change this to be a free text field.*

---++ Future Integration with ActionTrackerPlugin
This feature is already coded but currently commented out because it should be configurable via =configure= .

---+ Plugin Installation Instructions

%$INSTALL_INSTRUCTIONS%

---+ Plugin Info

| Plugin Author: | Foswiki:Main/DavidPatterson |
| License: | [[http://www.gnu.org/licenses/gpl.html][GPL (Gnu General Public License)]] |
| Release: | %$RELEASE% |
| Version: | %$VERSION% |
| Change History: | |
| 20 Jun 2010 | First release |
| 15 Apr 2010 | Demo version |
| Dependencies: | <table border="1"><tr><th>Name</th><th>Version</th><th>Description</th></tr><tr><td align="left">Date::Calc</td><td align="left">&gt;=6.13</td><td align="left">Required. Available from the CPAN:Date::Calc archive.</td></tr><tr><td align="left">Data::Dumper</td><td align="left">&gt;=</td><td align="left">Available from the CPAN:Data::Dumper archive.</td></tr><tr><td align="left">Foswiki:Extensions/Testing/ObjectPlugin</td><td align="left">&gt;=0</td><td align="left">Required for management of the event objects</td></tr></table> |
| Home: | Foswiki:Extensions/%TOPIC% |
| Support: | Foswiki:Support/%TOPIC% |
191 changes: 191 additions & 0 deletions data/System/FullCalendarViewTemplate.txt

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions data/System/WebCalendar.txt
@@ -0,0 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1268316360" format="1.1" version="1.1"}%
%META:TOPICPARENT{name="FullCalendarPlugin"}%

%META:PREFERENCE{name="VIEW_TEMPLATE" title="VIEW_TEMPLATE" type="Set" value="FullCalendarView"}%
234 changes: 234 additions & 0 deletions lib/Foswiki/Plugins/FullCalendarPlugin.pm
@@ -0,0 +1,234 @@
#
# Copyright (C) 2010 David Patterson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html
#
package Foswiki::Plugins::FullCalendarPlugin;

use strict;
use Assert;
use Error qw( :try );
use Data::Dumper;
use Date::Calc qw( Date_to_Days Add_Delta_Days );

require Foswiki::Func;
require Foswiki::Plugins;
require Foswiki::Plugins::ObjectPlugin;
require Foswiki::Plugins::ObjectPlugin::ObjectSet;
require Foswiki::Plugins::ObjectPlugin::Object;
require Foswiki::Plugins::FullCalendarPlugin::EventSet;
require Foswiki::Plugins::FullCalendarPlugin::Event;
require Foswiki::Time;
require Foswiki::OopsException;

use vars qw( $VERSION $RELEASE $SHORTDESCRIPTION $debug );
$debug = 0; # toggle me
$VERSION = '$Rev$';
$RELEASE = '1.0';
$SHORTDESCRIPTION = 'Web 2.0 calendar app';

my %months = ( '01'=>'Jan', '02'=>'Feb', '03'=>'Mar', '04'=>'Apr', '05'=>'May', '06'=>'Jun',
'07'=>'Jul', '08'=>'Aug', '09'=>'Sep', '10'=>'Oct', '11'=>'Nov', '12'=>'Dec' );

sub initPlugin {

# COVERAGE OFF standard plugin code

if( $Foswiki::Plugins::VERSION < 1.026 ) {
Foswiki::Func::writeWarning( 'Version mismatch between ObjectPlugin and Plugins.pm $Foswiki::Plugins::VERSION. 1.026 required.' );
}
# COVERAGE ON

Foswiki::Func::registerRESTHandler( 'edit', \&_editEventRESTHandler );
Foswiki::Func::registerRESTHandler( 'events', \&_eventsRESTHandler );
# $debug = $Foswiki::cfg{Plugins}{ObjectPlugin}{Debug} || 1;
return 1;
};

sub parseISOdate {
my $date = shift;
if ($date =~ /(\d\d\d\d)(?:-(\d\d)(?:-(\d\d))?)?(?:T(\d\d)(?::(\d\d)(?::(\d\d(?:\.\d+)?))?)?)?(Z|[-+]\d\d(?::\d\d)?)?/ ) {
my $dateObj = {
Y => $1,
M => $2||1,
D => $3||1,
h => $4||0,
m => $5||0,
s => $6||0,
tz => $7||'',
fulldate => $date
};
$dateObj->{date} = "$dateObj->{Y}-$dateObj->{M}-$dateObj->{D}";
$dateObj->{days} = Date_to_Days($dateObj->{Y}, $dateObj->{M}, $dateObj->{D});
return $dateObj;
}
return undef;
}

sub getMatchingActions {
my ($start, $end, $web) = @_;

require Foswiki::Plugins::ActionTrackerPlugin::ActionSet;
require Foswiki::Plugins::ActionTrackerPlugin::Action;
my $due = '<'.sprintf('%.4u/%.2u/%.2u',$end->{Y},$end->{M},$end->{D});
my $attrs = {
web => $web,
topic => 'WebActions',
due => $due,
state => "open"
};
# writeDebug(Dumper($attrs));
my $actions = Foswiki::Plugins::ActionTrackerPlugin::ActionSet::allActionsInWeb( $web, $attrs, 0 );
# writeDebug(Dumper($actions));
my $os = [];
foreach my $action (@{$actions->{ACTIONS}}) {
my $object = {};
$object->{id} = $action->{uid};
$object->{className} = 'action';
$object->{allDay} = 1;
$object->{start} = $action->{due};
$object->{title} = "$action->{who}";
$object->{editable} = 0;
foreach my $key (keys %$action) {
$object->{$key} = $action->{$key};
}
push(@{$os},$object);
}
# writeDebug(Dumper($os));
return $os;
}

sub _eventsRESTHandler {
my( $session ) = @_;
return Foswiki::Plugins::ObjectPlugin::objectResponse($session,\&_dateRangeSearch);
}

sub _editEventRESTHandler {
my $session = shift;
return Foswiki::Plugins::ObjectPlugin::objectResponse($session,\&_eventEdit);
}

sub _findSingleEvent {
my ( $web, $topic, $uid ) = @_;

my $es = Foswiki::Plugins::FullCalendarPlugin::EventSet::load($web, $topic);

foreach my $event (@{$es->{OBJECTS}}) {
if (ref($event)) {
if ($event->{uid} eq $uid) {
return $event;
}
}
}
return {}; # no match
}

sub _dateRangeSearch {
my ($web, $topic, $query) = @_;

my $start = $query->param('start');
my $end = $query->param('end');
# writeDebug("$start $end");
$start = Foswiki::Time::formatTime($start, 'iso');
$end = Foswiki::Time::formatTime($end, 'iso');
writeDebug("$start $end $topic");
my $es = Foswiki::Plugins::FullCalendarPlugin::EventSet::dateRangeSearch( $web, $topic, $start, $end );
# writeDebug(Dumper(@{$es->{OBJECTS}}));
my $startObj = parseISOdate($start);
my $endObj = parseISOdate($end);
if (scalar @{$es->{OBJECTS}}) {
# store an array of year,month pairs that we want events for in the startObj
# the chronological order of the pairs is important
if ($startObj->{D} == 1) {
my ($prevY, $prevM, $prevD) = Add_Delta_Days($startObj->{Y},$startObj->{M},1,-1);
push(@{$startObj->{ympair}},"$prevY,$prevM");
}
# writeDebug(Dumper($startObj));
push(@{$startObj->{ympair}},"$startObj->{Y},$startObj->{M}");
# writeDebug(Dumper($startObj));
if (($endObj->{days} - $startObj->{days}) > 8 && $startObj->{D} > 1) {
# we're looking at a month view with multiple months in view, let's add the middle/main month to the ympair array
my $month = $startObj->{M} + 1;
my $year;
if ($month == 13) {
$year = $startObj->{Y} + 1;
$month = 1;
} else {
$year = $startObj->{Y};
}
push(@{$startObj->{ympair}},"$year,$month");
}
# writeDebug(Dumper($startObj));
if ($startObj->{M} != $endObj->{M} && $endObj->{D} != 1) {
push(@{$startObj->{ympair}},"$endObj->{Y},$endObj->{M}");
}
# writeDebug(Dumper($startObj));
$es = $es->expandEvents($startObj,$endObj,$query->param('asobject'));
}
# the next two lines are commented out because they should be configurable via configure
# my $actions = getMatchingActions($startObj,$endObj,$web);
# push(@{$es->{OBJECTS}},@{$actions});
# writeDebug('expanded objects with actions - '.Dumper($es->{OBJECTS}));
# if (scalar @{$es->{OBJECTS}}) {
return $es;
# } else {
# throw Foswiki::OopsException('fullcalendar',
# def => 'noeventsfound',
# web => $web,
# topic => $topic,
# params => [ $start, $end, "$web.$topic" ] );
# }
}

sub _eventEdit {
my ($web, $topic, $query) = @_;
my $uid = $query->param('uid');
my ($event, $pre, $post, $meta) = Foswiki::Plugins::ObjectPlugin::ObjectSet::loadToFind(
$uid, $web, $topic, undef, 'VIEW', 0, 'Foswiki::Plugins::FullCalendarPlugin::Event' );
# my $event = _findSingleEvent($web, $topic, $uid);
if (defined $event) {
# expand the found event to match the date on which it was selected in the calendar
# - like a mini dateRangeSearch
my $start = $query->param('start');
my $end = $query->param('end');
# writeDebug("$start $end");
$start = Foswiki::Time::formatTime($start, 'iso');
$end = Foswiki::Time::formatTime($end, 'iso');
my $startObj = parseISOdate($start);
my $endObj = parseISOdate($end);
push(@{$startObj->{ympair}},"$startObj->{Y},$startObj->{M}");
$event->setFullCalendarAttrs();
my $eventSet = new Foswiki::Plugins::FullCalendarPlugin::EventSet();
$event->expand($eventSet, $startObj, $endObj, $query->param('asobject'));
if (scalar @{$eventSet->{OBJECTS}}) {
return $eventSet->{OBJECTS}[0];
} else {
throw Foswiki::OopsException('fullcalendar',
def => 'noeventdatematch',
web => $web,
topic => $topic,
params => [ $uid, "$startObj->{D} $months{$startObj->{M}} $startObj->{Y}" ] );
}
} else {
throw Foswiki::OopsException('object',
def => 'noobjectuid',
web => $web,
topic => $topic,
params => [ $uid, "$web.$topic" ] );
}
}

sub writeDebug {
Foswiki::Func::writeDebug("FullCalendarPlugin - $_[0]") if $debug;
}

1;
5 changes: 5 additions & 0 deletions lib/Foswiki/Plugins/FullCalendarPlugin/DEPENDENCIES
@@ -0,0 +1,5 @@
# Dependencies for FullCalendarPlugin
# Example:
# Time::ParseDate,>=2003.0211,cpan,Required.
# Foswiki::Plugins,>=1.2,perl,Requires version 1.2 of handler API.

0 comments on commit 95e39e8

Please sign in to comment.