Fix iCal processing in the Calendar module and workflow. Errors with

generation and processing.
This commit is contained in:
Colin Kuskie 2009-06-30 15:43:40 +00:00
parent bb3de4bf96
commit 755d7909a5
4 changed files with 153 additions and 33 deletions

View file

@ -1,6 +1,7 @@
7.7.13
- fixed #10574: Creating Calendar Entry
- fixed #10522: Metadata value & label problem
- fixed #10594: iCal title display error.
7.7.12
- Updated auth to allow sending back of non-text/html mime types.

View file

@ -671,11 +671,22 @@ TODO: Allow WebGUI::DateTime objects to be passed as the parameters.
This is the main API method to get events from a calendar, so it must be flexible.
C<options> is a hash reference with the following keys:
=head3 startDate
order - The order to return the events. Will default to the
sortEventsBy asset property. Valid values are:
'time', 'sequenceNumber'
A date with optional time in MySQL format.
=head3 endDate
A date with optional time in MySQL format.
=head3 options
A hash reference with any the following keys and values:
=head4 order
The order to return the events. Will default to the sortEventsBy asset property.
Valid values are: 'time', 'sequenceNumber'
=cut
@ -698,21 +709,23 @@ sub getEventsIn {
# Create objects and adjust for timezone
warn "start: $start\n";
warn "end: $end\n";
my ($startDate,$startTime) = split / /, $start;
my ($endDate,$endTime) = split / /, $end;
#use Data::Dumper;
#$self->session->errorHandler->warn( Dumper [caller(1), caller(2), caller(3)] );
my $startTz = WebGUI::DateTime->new($self->session, mysql => $start, time_zone => $tz)
->set_time_zone("UTC")->toMysql;
my $endTz = WebGUI::DateTime->new($self->session, mysql => $end, time_zone => $tz)
->set_time_zone("UTC")->toMysql;
my $startTz = WebGUI::DateTime->new($self->session, mysql => $start, time_zone => $tz)->set_time_zone("UTC")->toMysql;
my $endTz = WebGUI::DateTime->new($self->session, mysql => $end, time_zone => $tz)->set_time_zone("UTC")->toMysql;
warn $startTz;
warn $endTz;
my $where
= qq{
(
Event.startTime IS NULL
&& Event.endTime IS NULL
Event.startTime IS NULL
&& Event.endTime IS NULL
&&
!(
Event.startDate >= '$endDate'
@ -720,7 +733,7 @@ sub getEventsIn {
)
)
|| (
CONCAT(Event.startDate,' ',Event.startTime) >= '$startTz'
CONCAT(Event.startDate,' ',Event.startTime) >= '$startTz'
&& CONCAT(Event.startDate,' ',Event.startTime) < '$endTz'
)
};
@ -1738,7 +1751,7 @@ sub wrapIcal {
$text =~ s/([,;\\])/\\$1/g;
$text =~ s/\n/\\n/g;
my @text = ($text =~ m/.{0,75}/g);
my @text = ($text =~ m/.{1,75}/g);
return join "\r\n ",@text;
}

View file

@ -121,7 +121,6 @@ sub execute {
[$session->getId,$feed->{assetId},"SPECTRE"]);
}
#/KLUDGE
#warn "FEED URL: ".$feed->{url} ."\n";
## Somebody point me to a DECENT iCalendar parser...
# Text::vFile perhaps?
@ -148,10 +147,10 @@ sub execute {
my $active = 0; # Parser on/off
my %current_event = ();
my $current_entry = "";
my %events;
my $line_number = 0;
for my $line (split /[\r\n]+/,$data) {
$data =~ s/[ \t]?[\r\n]+[ \t]+/ /msg; #Process line continuations
LINE: for my $line (split /[\r\n]+/,$data) {
chomp $line;
$line_number++;
next unless $line =~ /\w/;
@ -160,6 +159,7 @@ sub execute {
if ($line =~ /^BEGIN:VEVENT$/i) {
$active = 1;
next LINE;
}
elsif ($line =~ /^END:VEVENT$/i) {
$active = 0;
@ -169,15 +169,12 @@ sub execute {
$events{$uid} = {%current_event};
$self->session->log->info( "Found event $uid from feed " . $feed->{feedId} );
%current_event = ();
}
elsif ($line =~ /^ /) {
# Add to entry data
$current_entry .= substr $line, 1;
next LINE;
}
else {
# Flush old entry
# KEY;ATTRIBUTE=VALUE;ATTRIBUTE=VALUE:KEYVALUE
my ($key_attrs,$value) = split /:/,$current_entry,2;
my ($key_attrs,$value) = split /:/,$line,2;
my @attrs = $key_attrs ? (split /;/, $key_attrs) : ();
my $key = shift @attrs;
my %attrs;
@ -186,13 +183,7 @@ sub execute {
$attrs{lc $attr_key} = $attr_value;
}
# Unescape value
$current_event{lc $key} = [\%attrs,$value];
# Start new entry
$current_entry = $line;
}
}
@ -330,23 +321,24 @@ sub execute {
}
# If there are X-WebGUI-* fields
for my $key (grep /^X-WEBGUI-/, keys %{$events{$id}}) {
for my $key (grep /^x-webgui-/, keys %{$events{$id}}) {
my $property_name = $key;
$property_name =~ s/^X-WEBGUI-//;
$property_name =~ s/^x-webgui-//;
$property_name = lc $property_name;
if (lc $property_name eq "groupidedit")
if ($property_name eq "groupidedit")
{
$properties->{groupIdEdit} = $events{$id}->{$key}->[1];
}
elsif (lc $property_name eq "groupidview")
elsif ($property_name eq "groupidview")
{
$properties->{groupIdView} = $events{$id}->{$key}->[1];
}
elsif (lc $property_name eq "url")
elsif ($property_name eq "url")
{
$properties->{url} = $events{$id}->{$key}->[1];
}
elsif (lc $property_name eq "menutitle")
elsif ($property_name eq "menutitle")
{
$properties->{menuTitle} = $events{$id}->{$key}->[1];
}
@ -538,7 +530,7 @@ sub _icalToMySQL {
sub _unwrapIcalText {
my $text = shift;
$text =~ s/\\([.;\\])/$1/g;
$text =~ s/\\([,;\\])/$1/g;
return $text;
}

View file

@ -0,0 +1,114 @@
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
use FindBin;
use strict;
use lib "$FindBin::Bin/../../lib";
use WebGUI::Test;
use WebGUI::Session;
use WebGUI::Utility;
use WebGUI::Workflow::Activity::CalendarUpdateFeeds;
use WebGUI::Asset::Wobject::Calendar;
use Test::More;
use Test::Deep;
if (!$ENV{WEBGUI_LIVE}) {
plan skip_all => 'No website available';
}
else {
plan tests => 10; # increment this value for each test you create
}
my $session = WebGUI::Test->session;
my $home = WebGUI::Asset->getDefault($session);
my $sender = $home->addChild({
className => 'WebGUI::Asset::Wobject::Calendar',
title => 'Sending Calendar',
});
my $receiver = $home->addChild({
className => 'WebGUI::Asset::Wobject::Calendar',
title => 'Receiving Calendar',
});
$session->db->setRow('Calendar_feeds', 'feedId', {
feedId => 'new',
assetId => $receiver->getId,
url => $session->url->getSiteURL.$session->url->gateway($sender->getUrl('func=ical')),
feedType => 'ical',
});
my $dt = WebGUI::DateTime->new($session, time());
$dt->add(days => 1);
my $party = $sender->addChild({
className => 'WebGUI::Asset::Event',
title => 'WebGUI 100th Anniversary',
menuTitle => 'Anniversary',
description => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum', ##Set at longer than 72 characters to test for line wrapping
url => 'webgui_anniversary',
startDate => $dt->toDatabaseDate, ##Times and dates have to be entered in UTC
endDate => $dt->toDatabaseDate,
timeZone => 'America/Chicago',
location => 'Madison, Wisconsin',
groupIdView => 7,
groupIdEdit => 12,
ownerUserId => 3,
}, undef, undef, {skipAutoCommitWorkflows => 1});
my $tag = WebGUI::VersionTag->getWorking($session);
$tag->commit;
WebGUI::Test->tagsToRollback($tag);
my $workflow = WebGUI::Workflow->create($session,
{
enabled => 1,
objectType => 'None',
mode => 'realtime',
},
);
my $icalFetch = $workflow->addActivity('WebGUI::Workflow::Activity::CalendarUpdateFeeds');
my $instance1 = WebGUI::Workflow::Instance->create($session,
{
workflowId => $workflow->getId,
skipSpectreNotification => 1,
}
);
my $oldEvents = $receiver->getLineage(['children'], { returnObjects => 1, });
is(scalar @{ $oldEvents }, 0, 'receiving calendar has no events');
my $retVal;
$retVal = $instance1->run();
is($retVal, 'complete', 'cleanup: activity complete');
$retVal = $instance1->run();
is($retVal, 'done', 'cleanup: activity is done');
$instance1->delete;
my $newEvents = $receiver->getLineage(['children'], { returnObjects => 1, });
is(scalar @{ $newEvents }, 1, 'ical import of 1 event');
my $anniversary = pop @{ $newEvents };
is($anniversary->get('title'), $party->get('title'), 'transferred title');
is($anniversary->get('menuTitle'), $party->get('menuTitle'), '... menuTitle');
is($anniversary->get('groupIdView'), $party->get('groupIdView'), '... groupIdView');
is($anniversary->get('groupIdEdit'), $party->get('groupIdEdit'), '... groupIdEdit');
is($anniversary->get('url'), $party->get('url').'2', '... url (accounting for duplicate)');
is($anniversary->get('description'), $party->get('description'), '... description, checks for line wrapping');
END {
$instance1 && $instance1->delete('skipNotify');
$workflow && $workflow->delete;
}