[Rt-commit] r3590 - in Data-ICal: . lib/Data lib/Data/ICal
lib/Data/ICal/Entry lib/Data/ICal/Entry/Alarm
lib/Data/ICal/Entry/TimeZone t t/ics
glasser at bestpractical.com
glasser at bestpractical.com
Wed Aug 3 11:35:25 EDT 2005
Author: glasser
Date: Wed Aug 3 11:35:23 2005
New Revision: 3590
Added:
Data-ICal/lib/Data/ICal/Entry/TimeZone/
Data-ICal/lib/Data/ICal/Entry/TimeZone/Daylight.pm
Data-ICal/lib/Data/ICal/Entry/TimeZone/Standard.pm
Data-ICal/t/08.parse.t
Data-ICal/t/ics/
Data-ICal/t/ics/badlyformed.ics
Data-ICal/t/ics/test.ics
Modified:
Data-ICal/ (props changed)
Data-ICal/Changes
Data-ICal/MANIFEST
Data-ICal/Makefile.PL
Data-ICal/README
Data-ICal/lib/Data/ICal.pm
Data-ICal/lib/Data/ICal/Entry.pm
Data-ICal/lib/Data/ICal/Entry/Alarm/Audio.pm
Data-ICal/lib/Data/ICal/Entry/Alarm/Display.pm
Data-ICal/lib/Data/ICal/Entry/Alarm/Email.pm
Data-ICal/lib/Data/ICal/Entry/Alarm/Procedure.pm
Data-ICal/lib/Data/ICal/Entry/Event.pm
Data-ICal/lib/Data/ICal/Entry/FreeBusy.pm
Data-ICal/lib/Data/ICal/Entry/Journal.pm
Data-ICal/lib/Data/ICal/Entry/TimeZone.pm
Data-ICal/lib/Data/ICal/Entry/Todo.pm
Log:
r38399 at tin-foil: glasser | 2005-08-03 11:13:23 -0400
Changes from Simon Wistow: parsing support, and full timezone support.
r38400 at tin-foil: glasser | 2005-08-03 11:20:31 -0400
A bit of POD cleanup
r38401 at tin-foil: glasser | 2005-08-03 11:26:05 -0400
Authorship, changelog, etc
r38402 at tin-foil: glasser | 2005-08-03 11:33:19 -0400
Make the parsing/roundtrip tests just one file
r38403 at tin-foil: glasser | 2005-08-03 11:34:29 -0400
MANIFEST fix
Modified: Data-ICal/Changes
==============================================================================
--- Data-ICal/Changes (original)
+++ Data-ICal/Changes Wed Aug 3 11:35:23 2005
@@ -1,5 +1,9 @@
Revision history for Data-ICal
+0.02 Wed Aug 03 11:25:00 EDT 2005
+ * Parser support, thanks to Simon Wistow
+ * Full Time Zone support
+
0.01 Wed Jul 27 11:52:12 EDT 2005
* Initial release
Modified: Data-ICal/MANIFEST
==============================================================================
--- Data-ICal/MANIFEST (original)
+++ Data-ICal/MANIFEST Wed Aug 3 11:35:23 2005
@@ -1,4 +1,3 @@
-SIGNATURE
Changes
doc/rfc2445.txt
inc/Module/Install.pm
@@ -19,12 +18,15 @@
lib/Data/ICal/Entry/FreeBusy.pm
lib/Data/ICal/Entry/Journal.pm
lib/Data/ICal/Entry/TimeZone.pm
+lib/Data/ICal/Entry/TimeZone/Daylight.pm
+lib/Data/ICal/Entry/TimeZone/Standard.pm
lib/Data/ICal/Entry/Todo.pm
lib/Data/ICal/Property.pm
Makefile.PL
MANIFEST This list of files
META.yml
README
+SIGNATURE
t/00.load.t
t/01.simplegen.t
t/02.linewrap.t
@@ -32,5 +34,8 @@
t/04.mandatory-props.t
t/05.prop-params.t
t/06.prop-bad-quote.t
+t/08.parse.t
+t/ics/badlyformed.ics
+t/ics/test.ics
t/pod-coverage.t
t/pod.t
Modified: Data-ICal/Makefile.PL
==============================================================================
--- Data-ICal/Makefile.PL (original)
+++ Data-ICal/Makefile.PL Wed Aug 3 11:35:23 2005
@@ -8,6 +8,8 @@
build_requires('Test::More');
build_requires('Test::Warn');
build_requires('Test::NoWarnings');
+build_requires('Test::LongString');
requires('Class::Accessor');
+requires('Text::vFile::asData');
&WriteAll;
Modified: Data-ICal/README
==============================================================================
--- Data-ICal/README (original)
+++ Data-ICal/README Wed Aug 3 11:35:23 2005
@@ -1,4 +1,4 @@
-Data-ICal version 0.0.1
+Data-ICal
Data::ICal is a straightforward generator for iCalendar (RFC 2445) files, such
as those used in Apple's iCal.
Modified: Data-ICal/lib/Data/ICal.pm
==============================================================================
--- Data-ICal/lib/Data/ICal.pm (original)
+++ Data-ICal/lib/Data/ICal.pm Wed Aug 3 11:35:23 2005
@@ -3,7 +3,10 @@
package Data::ICal;
use base qw/Data::ICal::Entry/;
-our $VERSION = '0.01';
+
+use Text::vFile::asData;
+
+our $VERSION = '0.02';
use Carp;
@@ -20,9 +23,14 @@
my $vtodo = Data::ICal::Entry::Todo->new();
$vtodo->add_properties(
- # ... see Data::ICal::Entry::Todo documentation
+ # ... see Data::ICal::Entry::Todo documentation
);
+ # ... or
+
+ $calendar = Data::ICal->new('foo.ics'); # parse existing file
+
+
$calendar->add_entry($vtodo);
print $calendar->as_string;
@@ -50,21 +58,55 @@
=head2 new
-Creates a new L<Data::ICal> object; sets its C<VERSION> and C<PRODID> properties
-to "2.0" and the value of the C<product_id> method respectively.
+Creates a new L<Data::ICal> object.
+
+If a file name is passed, this parses that file into the object; otherwise it
+just sets its C<VERSION> and C<PRODID> properties to "2.0" and the value of the
+C<product_id> method respectively.
+
+Returns undef upon failure to open file or parse .ics file.
=cut
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
- $self->add_properties(
- version => '2.0',
- prodid => $self->product_id,
- );
+
+ if (@_) {
+ $self->parse_file(@_) || return undef;
+ } else {
+ $self->add_properties(
+ version => '2.0',
+ prodid => $self->product_id,
+ );
+ }
return $self;
}
+=head2 parse_file
+
+Parse a .ics file and populate a L<Data::ICal> object.
+
+=cut
+
+sub parse_file {
+ my ($self, $file) = @_;
+
+
+ # open the file (checking as we go, like good little Perl mongers)
+ open my($fh), $file or return undef;
+ my $cal = Text::vFile::asData->new->parse($fh) || return undef;
+ close $fh;
+
+ return undef unless exists $cal->{objects};
+ # loop through all the vcards
+ foreach my $object (@{ $cal->{objects} }) {
+ $self->parse_object($object);
+ }
+ return 1;
+}
+
+
=head2 ical_entry_type
Returns C<VCALENDAR>, its iCalendar entry name.
@@ -159,7 +201,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
@@ -194,5 +236,4 @@
SUCH DAMAGES.
=cut
-
1;
Modified: Data-ICal/lib/Data/ICal/Entry.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry.pm Wed Aug 3 11:35:23 2005
@@ -14,7 +14,7 @@
my $vtodo = Data::ICal::Entry::Todo->new();
$vtodo->add_properties(
- # ... see Data::ICal::Entry::Todo documentation
+ # ... see Data::ICal::Entry::Todo documentation
);
$calendar->add_entry($vtodo);
@@ -139,6 +139,20 @@
return $self->{'properties'};
}
+
+=head2 property
+
+Given a property name returns a reference to the array of L<Data::ICal::Property> objects.
+
+=cut
+
+sub property {
+ my $self = shift;
+ my $prop = lc shift;
+ return $self->{'properties'}->{$prop};
+}
+
+
=head2 add_property $propname => $propval
Creates a new L<Data::ICal::Property> object with name C<$propname> and value
@@ -350,9 +364,136 @@
return 'END:' . $self->ical_entry_type . "\n";
}
+# mapping of event types to class (under the Data::Ical::Event namespace)
+my %_generic = (
+ vevent => 'Event',
+ vtodo => 'Todo',
+ vjournal => 'Journal',
+ vfreebusy => 'FreeBusy',
+ vtimezone => 'TimeZone',
+ standard => 'TimeZone::Standard',
+ daylight => 'TimeZone::Daylight',
+);
+
+
+=head2 parse_object
+
+Translate a L<Text::vFile::asData> sub object into the appropriate
+L<Data::iCal::Event> subtype.
+
+=cut
+
+
+# TODO: this is currently recursive which could blow the stack -
+# it might be worth refactoring to make it sequential
+sub parse_object {
+ my ($self,$object) = @_;
+
+
+ my $type = $object->{type};
+
+
+ my $new_self;
+
+ # First check to see if it's generic long name just in case there
+ # event turns out to be a VGENERIC entry type
+ if (my $class = $_generic{lc($type)}) {
+ $new_self = $self->_parse_data_ical_generic($class, $object);
+ # then look for specific overrides
+ } elsif (my $sub = $self->can('_parse_'.lc($type))) {
+ $new_self = $self->$sub($object);
+ # bitch
+ } else {
+ warn "Can't parse type $type yet";
+ return;
+ }
+
+ # recurse through sub-objects
+ foreach my $sub_object(@{ $object->{objects} }) {
+ $new_self->parse_object($sub_object);
+ }
+
+}
+
+
+
+# special because we want to use ourselves as the parent
+sub _parse_vcalendar {
+ my ($self, $object) = @_;
+ $self->_parse_generic_event($self, $object);
+ return $self;
+}
+
+# mapping of action types to class (under the Data::Ical::Event::Alarm namespace)
+my %_action_map = (
+ AUDIO => 'Audio',
+ DISPLAY => 'Display',
+ EMAIL => 'Email',
+ PROCEDURE => 'Procedure',
+);
+
+# alarms have actions
+sub _parse_valarm {
+ my ($parent, $object) = @_;
+
+ # ick
+ my $action = $object->{properties}->{ACTION}->[0]->{value};
+ die "Can't parse VALARM with action $action" unless exists $_action_map{$action};
+
+
+ my $alarm_class = "Data::ICal::Entry::Alarm::".$_action_map{$action};
+ eval "require $alarm_class";
+ die "Failed to require $alarm_class : $@" if $@;
+
+ $alarm_class->import;
+ my $alarm = $alarm_class->new;
+ $parent->_parse_generic_event($alarm, $object);
+ $parent->add_entry($alarm);
+ return $alarm;
+
+
+}
+
+# generic event handler
+sub _parse_data_ical_generic {
+ my ($parent, $class, $object) = @_;
+
+ my $entry_class = "Data::ICal::Entry::$class";
+ eval "require $entry_class";
+ die "Failed to require $entry_class : $@" if $@;
+
+ $entry_class->import;
+ my $entry = $entry_class->new;
+ $parent->_parse_generic_event($entry, $object);
+ $parent->add_entry($entry);
+ return $entry;
+}
+
+# handle transferring of properties
+sub _parse_generic_event {
+ my ($parent, $entry, $object) = @_;
+
+ my $p = $object->{properties};
+ while (my($key,$val) = each(%$p)) {
+ foreach my $occurence (@$val) {
+ my $prop;
+ # handle optional params and 'normal' key/value pairs
+ # TODO: line wrapping?
+ if ($occurence->{param}) {
+ $prop = [ $occurence->{value}, $occurence->{param} ];
+ } else {
+ $prop = $occurence->{value};
+ }
+ $entry->add_property( lc($key) => $prop );
+ }
+ }
+ return $entry;
+}
+
+
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/Alarm/Audio.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Alarm/Audio.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Alarm/Audio.pm Wed Aug 3 11:35:23 2005
@@ -88,7 +88,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/Alarm/Display.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Alarm/Display.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Alarm/Display.pm Wed Aug 3 11:35:23 2005
@@ -85,7 +85,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/Alarm/Email.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Alarm/Email.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Alarm/Email.pm Wed Aug 3 11:35:23 2005
@@ -117,7 +117,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/Alarm/Procedure.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Alarm/Procedure.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Alarm/Procedure.pm Wed Aug 3 11:35:23 2005
@@ -90,7 +90,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/Event.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Event.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Event.pm Wed Aug 3 11:35:23 2005
@@ -89,7 +89,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/FreeBusy.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/FreeBusy.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/FreeBusy.pm Wed Aug 3 11:35:23 2005
@@ -74,7 +74,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/Journal.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Journal.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Journal.pm Wed Aug 3 11:35:23 2005
@@ -80,7 +80,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Modified: Data-ICal/lib/Data/ICal/Entry/TimeZone.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/TimeZone.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/TimeZone.pm Wed Aug 3 11:35:23 2005
@@ -64,7 +64,7 @@
=head2 mandatory_unique_properties
According to the iCalendar standard, the C<tzid> property must be specified
-exact one time in a time zone declaration.
+exactly one time in a time zone declaration.
=cut
@@ -76,7 +76,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Added: Data-ICal/lib/Data/ICal/Entry/TimeZone/Daylight.pm
==============================================================================
--- (empty file)
+++ Data-ICal/lib/Data/ICal/Entry/TimeZone/Daylight.pm Wed Aug 3 11:35:23 2005
@@ -0,0 +1,145 @@
+use warnings;
+use strict;
+
+package Data::ICal::Entry::TimeZone::Daylight;
+
+use base qw/Data::ICal::Entry/;
+
+=head1 NAME
+
+Data::ICal::Entry::TimeZone::Daylight - Represents a Daylight Time base offset from UTC for parent TimeZone
+
+
+=head1 SYNOPSIS
+
+
+=head1 DESCRIPTION
+
+A time zone is unambiguously defined by the set of time
+measurement rules determined by the governing body for a given
+geographic area. These rules describe at a minimum the base offset
+from UTC for the time zone, often referred to as the Standard Time
+offset. Many locations adjust their Standard Time forward or backward
+by one hour, in order to accommodate seasonal changes in number of
+daylight hours, often referred to as Daylight Saving Time. Some
+locations adjust their time by a fraction of an hour. Standard Time
+is also known as Winter Time. Daylight Saving Time is also known as
+Advanced Time, Summer Time, or Legal Time in certain countries. The
+following table shows the changes in time zone rules in effect for
+New York City starting from 1967. Each line represents a description
+or rule for a particular observance.
+
+ Effective Observance Rule
+
+ Date (Date/Time) Offset Abbreviation
+
+ 1967-* last Sun in Oct, 02:00 -0500 EST
+
+ 1967-1973 last Sun in Apr, 02:00 -0400 EDT
+
+ 1974-1974 Jan 6, 02:00 -0400 EDT
+
+ 1975-1975 Feb 23, 02:00 -0400 EDT
+
+ 1976-1986 last Sun in Apr, 02:00 -0400 EDT
+
+ 1987-* first Sun in Apr, 02:00 -0400 EDT
+
+Note: The specification of a global time zone registry is not
+addressed by this document and is left for future study.
+However, implementers may find the Olson time zone database [TZ]
+a useful reference. It is an informal, public-domain collection
+of time zone information, which is currently being maintained by
+volunteer Internet participants, and is used in several
+operating systems. This database contains current and historical
+time zone information for a wide variety of locations around the
+globe; it provides a time zone identifier for every unique time
+zone rule set in actual use since 1970, with historical data
+going back to the introduction of standard time.
+
+=head1 METHODS
+
+=cut
+
+=head2 ical_entry_type
+
+Returns C<DAYLIGHT>, its iCalendar entry name.
+
+=cut
+
+sub ical_entry_type {'DAYLIGHT'}
+
+=head2 mandatory_unique_properties
+
+According to the iCalendar standard, the following properties must be specified
+exactly one time in a daylight declaration:
+
+ dtstart tzoffsetto tzoffsetfrom
+
+=cut
+
+sub mandatory_unique_properties {
+ qw(
+ dtstart
+ tzoffsetto
+ tzoffsetfrom
+ );
+}
+
+=head2 optional_repeatable_properties
+
+According to the iCalendar standard, the following properties may be specified
+any number of times for a daylight declaration:
+
+ comment rdate rrule tzname
+
+=cut
+
+sub optional_repeatable_properties {
+ qw(
+ comment
+ rdate
+ rrule
+ tzname
+ );
+}
+
+=head1 AUTHOR
+
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
+
+
+=head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2005, Best Practical Solutions, LLC. All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself. See L<perlartistic>.
+
+
+=head1 DISCLAIMER OF WARRANTY
+
+BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
+YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR, OR CORRECTION.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+=cut
+
+1;
Added: Data-ICal/lib/Data/ICal/Entry/TimeZone/Standard.pm
==============================================================================
--- (empty file)
+++ Data-ICal/lib/Data/ICal/Entry/TimeZone/Standard.pm Wed Aug 3 11:35:23 2005
@@ -0,0 +1,145 @@
+use warnings;
+use strict;
+
+package Data::ICal::Entry::TimeZone::Standard;
+
+use base qw/Data::ICal::Entry/;
+
+=head1 NAME
+
+Data::ICal::Entry::TimeZone::Standard - Represents a Standard Time base offset from UTC for parent TimeZone
+
+
+=head1 SYNOPSIS
+
+
+=head1 DESCRIPTION
+
+A time zone is unambiguously defined by the set of time
+measurement rules determined by the governing body for a given
+geographic area. These rules describe at a minimum the base offset
+from UTC for the time zone, often referred to as the Standard Time
+offset. Many locations adjust their Standard Time forward or backward
+by one hour, in order to accommodate seasonal changes in number of
+daylight hours, often referred to as Daylight Saving Time. Some
+locations adjust their time by a fraction of an hour. Standard Time
+is also known as Winter Time. Daylight Saving Time is also known as
+Advanced Time, Summer Time, or Legal Time in certain countries. The
+following table shows the changes in time zone rules in effect for
+New York City starting from 1967. Each line represents a description
+or rule for a particular observance.
+
+ Effective Observance Rule
+
+ Date (Date/Time) Offset Abbreviation
+
+ 1967-* last Sun in Oct, 02:00 -0500 EST
+
+ 1967-1973 last Sun in Apr, 02:00 -0400 EDT
+
+ 1974-1974 Jan 6, 02:00 -0400 EDT
+
+ 1975-1975 Feb 23, 02:00 -0400 EDT
+
+ 1976-1986 last Sun in Apr, 02:00 -0400 EDT
+
+ 1987-* first Sun in Apr, 02:00 -0400 EDT
+
+Note: The specification of a global time zone registry is not
+addressed by this document and is left for future study.
+However, implementers may find the Olson time zone database [TZ]
+a useful reference. It is an informal, public-domain collection
+of time zone information, which is currently being maintained by
+volunteer Internet participants, and is used in several
+operating systems. This database contains current and historical
+time zone information for a wide variety of locations around the
+globe; it provides a time zone identifier for every unique time
+zone rule set in actual use since 1970, with historical data
+going back to the introduction of standard time.
+
+=head1 METHODS
+
+=cut
+
+=head2 ical_entry_type
+
+Returns C<STANDARD>, its iCalendar entry name.
+
+=cut
+
+sub ical_entry_type {'STANDARD'}
+
+=head2 mandatory_unique_properties
+
+According to the iCalendar standard, the following properties must be specified
+exactly one time in a standard time declaration:
+
+ dtstart tzoffsetto tzoffsetfrom
+
+=cut
+
+sub mandatory_unique_properties {
+ qw(
+ dtstart
+ tzoffsetto
+ tzoffsetfrom
+ );
+}
+
+=head2 optional_repeatable_properties
+
+According to the iCalendar standard, the following properties may be specified
+any number of times for a standard time declaration:
+
+ comment rdate rrule tzname
+
+=cut
+
+sub optional_repeatable_properties {
+ qw(
+ comment
+ rdate
+ rrule
+ tzname
+ );
+}
+
+=head1 AUTHOR
+
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
+
+
+=head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2005, Best Practical Solutions, LLC. All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself. See L<perlartistic>.
+
+
+=head1 DISCLAIMER OF WARRANTY
+
+BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
+YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR, OR CORRECTION.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+=cut
+
+1;
Modified: Data-ICal/lib/Data/ICal/Entry/Todo.pm
==============================================================================
--- Data-ICal/lib/Data/ICal/Entry/Todo.pm (original)
+++ Data-ICal/lib/Data/ICal/Entry/Todo.pm Wed Aug 3 11:35:23 2005
@@ -89,7 +89,7 @@
=head1 AUTHOR
-Jesse Vincent C<< <jesse at bestpractical.com> >>
+Jesse Vincent C<< <jesse at bestpractical.com> >> with David Glasser and Simon Wistow
=head1 LICENCE AND COPYRIGHT
Added: Data-ICal/t/08.parse.t
==============================================================================
--- (empty file)
+++ Data-ICal/t/08.parse.t Wed Aug 3 11:35:23 2005
@@ -0,0 +1,85 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+
+use constant TESTS_IN_TEST_CALENDAR => 15;
+use Test::More tests => 6 + 2 * TESTS_IN_TEST_CALENDAR;
+use Test::LongString;
+use Test::NoWarnings; # this catches our warnings like setting unknown properties
+
+BEGIN { use_ok('Data::ICal') }
+
+
+
+our $s;
+$s = Data::ICal->new('t/ics/nonexistent.ics');
+
+is($s, undef, "Caught no file death");
+
+$s = Data::ICal->new('t/ics/badlyformed.ics');
+is($s, undef, "Caught badly formed ics file death");
+
+$s = Data::ICal->new('t/ics/test.ics');
+
+isa_ok($s, 'Data::ICal');
+
+test_calendar();
+
+SKIP: {
+ skip "Can't create t/ics/out.ics: $!", 1 + TESTS_IN_TEST_CALENDAR unless open(ICS,">t/ics/out.ics");
+ print ICS $s->as_string;
+ close ICS;
+
+ undef($s);
+ $s = Data::ICal->new('t/ics/out.ics');
+ isa_ok($s, 'Data::ICal');
+
+ test_calendar();
+
+ unlink('t/ics/out.ics');
+}
+
+sub test_calendar {
+ is($s->ical_entry_type, 'VCALENDAR', "Is a VCALENDAR");
+ my $id = $s->property('prodid')->[0]->value;
+ my $name = $s->property('x-wr-calname')->[0]->value;
+ is($id,'Data::ICal test', 'Got id');
+ is($name,'Data::ICal test calendar', 'Got name');
+
+ my @entries = @{$s->entries};
+ is(@entries,2,"Correct number of entries");
+
+ my ($event, $timezone);
+
+ for (@entries) {
+ if ( $_->ical_entry_type eq 'VEVENT' ) {
+ $event = $_;
+ } elsif ( $_->ical_entry_type eq 'VTIMEZONE' ) {
+ $timezone = $_;
+ }
+ }
+ undef(@entries);
+
+ # Event
+ isa_ok($event, 'Data::ICal::Entry::Event');
+ is($event->property('location')->[0]->value, 'The Restaurant at the End of the Universe', 'Correct location');
+ is($event->property('url')->[0]->value, 'http://www.bestpractical.com', 'Correct URL');
+ is($event->property('url')->[0]->parameters->{VALUE}, 'URI', 'Got parameter');
+
+ # check sub entries
+ @entries = @{$event->entries};
+ is(@entries, 1, "Got sub entries");
+ isa_ok($entries[0],'Data::ICal::Entry::Alarm::Audio');
+ undef(@entries);
+
+ # TimeZone
+ isa_ok($timezone, 'Data::ICal::Entry::TimeZone');
+ is($timezone->property('tzid')->[0]->value, 'Europe/London', 'Got TimeZone ID');
+
+ # check daylight and standard settings
+ @entries = @{$timezone->entries};
+ is(@entries, 6, 'Got Daylight/Standard Entries');
+ is( grep( ($_->ical_entry_type eq 'DAYLIGHT'), @entries), 3, '3 DAYLIGHT');
+ is( grep( ($_->ical_entry_type eq 'STANDARD'), @entries), 3, '3 STANDARD');
+}
Added: Data-ICal/t/ics/badlyformed.ics
==============================================================================
--- (empty file)
+++ Data-ICal/t/ics/badlyformed.ics Wed Aug 3 11:35:23 2005
@@ -0,0 +1 @@
+this is a (very) badly formed ics file
Added: Data-ICal/t/ics/test.ics
==============================================================================
--- (empty file)
+++ Data-ICal/t/ics/test.ics Wed Aug 3 11:35:23 2005
@@ -0,0 +1,60 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+X-WR-CALNAME:Data::ICal test calendar
+PRODID:Data::ICal test
+BEGIN:VTIMEZONE
+TZID:Europe/London
+LAST-MODIFIED:20050716T111510Z
+BEGIN:DAYLIGHT
+DTSTART:20030330T020000
+TZOFFSETTO:+0100
+TZOFFSETFROM:+0000
+TZNAME:BST
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20031026T020000
+TZOFFSETTO:+0000
+TZOFFSETFROM:+0100
+TZNAME:GMT
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20040328T020000
+TZOFFSETTO:+0100
+TZOFFSETFROM:+0000
+TZNAME:BST
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20041031T020000
+TZOFFSETTO:+0000
+TZOFFSETFROM:+0100
+TZNAME:GMT
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20050327T020000
+TZOFFSETTO:+0100
+TZOFFSETFROM:+0000
+TZNAME:BST
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20051030T020000
+TZOFFSETTO:+0000
+TZOFFSETFROM:+0100
+TZNAME:GMT
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTART;TZID=Europe/London:20050802T170000
+DURATION:PT6H
+LOCATION:The Restaurant at the End of the Universe
+SEQUENCE:42
+SUMMARY:Data::ICal release party
+URL;VALUE=URI:http://www.bestpractical.com
+BEGIN:VALARM
+TRIGGER;VALUE=DATE-TIME:19970317T133000Z
+REPEAT:4
+DURATION:PT15M
+ACTION:AUDIO
+ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
+END:VALARM
+END:VEVENT
+END:VCALENDAR
More information about the Rt-commit
mailing list