init III
This commit is contained in:
331
Perl OTRS/Kernel/cpan-lib/Data/ICal.pm
Normal file
331
Perl OTRS/Kernel/cpan-lib/Data/ICal.pm
Normal file
@@ -0,0 +1,331 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal;
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
use Class::ReturnValue;
|
||||
use Text::vFile::asData;
|
||||
|
||||
our $VERSION = '0.22';
|
||||
|
||||
use Carp;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal - Generates iCalendar (RFC 2445) calendar files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Data::ICal;
|
||||
|
||||
my $calendar = Data::ICal->new();
|
||||
|
||||
my $vtodo = Data::ICal::Entry::Todo->new();
|
||||
$vtodo->add_properties(
|
||||
# ... see Data::ICal::Entry::Todo documentation
|
||||
);
|
||||
|
||||
# ... or
|
||||
$calendar = Data::ICal->new(filename => 'foo.ics'); # parse existing file
|
||||
$calendar = Data::ICal->new(data => 'BEGIN:VCALENDAR...'); # parse from scalar
|
||||
$calendar->add_entry($vtodo);
|
||||
print $calendar->as_string;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal> object represents a C<VCALENDAR> object as defined in the
|
||||
iCalendar protocol (RFC 2445, MIME type "text/calendar"), as implemented in many
|
||||
popular calendaring programs such as Apple's iCal.
|
||||
|
||||
Each L<Data::ICal> object is a collection of "entries", which are objects of a
|
||||
subclass of L<Data::ICal::Entry>. The types of entries defined by iCalendar
|
||||
(which refers to them as "components") include events, to-do items, journal
|
||||
entries, free/busy time indicators, and time zone descriptors; in addition,
|
||||
events and to-do items can contain alarm entries. (Currently, L<Data::ICal>
|
||||
only implements to-do items and events.)
|
||||
|
||||
L<Data::ICal> is a subclass of L<Data::ICal::Entry>; see its manpage for more
|
||||
methods applicable to L<Data::ICal>.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new [ data => $data, ] [ filename => $file ], [ calname => $string ], [ vcal10 => $bool ], [ rfc_strict => $bool ], [ auto_uid => $bool ]
|
||||
|
||||
Creates a new L<Data::ICal> object.
|
||||
|
||||
If it is given a filename or data argument is passed, then this parses the
|
||||
content of the file or string into the object. If the C<vcal10> flag is passed,
|
||||
parses it according to vCalendar 1.0, not iCalendar 2.0; this in particular impacts
|
||||
the parsing of continuation lines in quoted-printable sections.
|
||||
|
||||
If a calname is passed, sets x-wr-calname to the given string. Although
|
||||
not specified in RFC2445, most calendar software respects x-wr-calname
|
||||
as the displayed name of the calendar.
|
||||
|
||||
If the C<rfc_strict> flag is set to true, will require Data::ICal to
|
||||
include UIDs, as per RFC2445:
|
||||
|
||||
4.8.4.7 Unique Identifier
|
||||
... The property MUST be specified in the "VEVENT", "VTODO",
|
||||
"VJOURNAL" or "VFREEBUSY" calendar components"
|
||||
|
||||
If the C<auto_uid> flag is set to true, will automatically generate a
|
||||
default UID for each type which requires it, based on the RFC-suggested
|
||||
algorithm. Explicitly-set UID attributes will override this
|
||||
auto-generated value.
|
||||
|
||||
If a filename or data argument is not passed, this just sets the
|
||||
object's C<VERSION> and C<PRODID> properties to "2.0" (or "1.0" if the
|
||||
C<vcal10> flag is passed) and the value of the C<product_id> method
|
||||
respectively.
|
||||
|
||||
Returns a false value upon failure to open or parse the file or data; this false
|
||||
value is a L<Class::ReturnValue> object and can be queried as to its
|
||||
C<error_message>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
|
||||
my %args = (
|
||||
filename => undef,
|
||||
calname => undef,
|
||||
data => undef,
|
||||
vcal10 => 0,
|
||||
rfc_strict => 0,
|
||||
auto_uid => 0,
|
||||
@_
|
||||
);
|
||||
|
||||
$self->vcal10( $args{vcal10} );
|
||||
$self->rfc_strict( $args{rfc_strict} );
|
||||
$self->auto_uid( $args{auto_uid} );
|
||||
|
||||
if ( defined $args{filename} or defined $args{data} ) {
|
||||
|
||||
# might return a Class::ReturnValue if parsing fails
|
||||
return $self->parse(%args);
|
||||
} else {
|
||||
$self->add_properties(
|
||||
version => ( $self->vcal10 ? '1.0' : '2.0' ),
|
||||
prodid => $self->product_id,
|
||||
);
|
||||
$self->add_property('x-wr-calname' => $args{calname})
|
||||
if defined $args{calname};
|
||||
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 parse [ data => $data, ] [ filename => $file, ]
|
||||
|
||||
Parse a C<.ics> file or string containing one, and populate C<$self>
|
||||
with its contents.
|
||||
|
||||
Should only be called once on a given object, and will be automatically
|
||||
called by C<new> if you provide arguments to C<new>.
|
||||
|
||||
Returns C<$self> on success. Returns a false value upon failure to
|
||||
open or parse the file or data; this false value is a
|
||||
L<Class::ReturnValue> object and can be queried as to its
|
||||
C<error_message>.
|
||||
|
||||
=cut
|
||||
|
||||
sub parse {
|
||||
my $self = shift;
|
||||
my %args = (
|
||||
filename => undef,
|
||||
data => undef,
|
||||
@_
|
||||
);
|
||||
|
||||
unless ( defined $args{filename} or defined $args{data} ) {
|
||||
return $self->_error(
|
||||
"parse called with no filename or data specified");
|
||||
}
|
||||
|
||||
my @lines;
|
||||
|
||||
# open the file (checking as we go, like good little Perl mongers)
|
||||
if ( defined $args{filename} ) {
|
||||
open my $fh, '<', $args{filename}
|
||||
or return $self->_error("could not open '$args{filename}': $!");
|
||||
@lines = map { chomp; $_ } <$fh>;
|
||||
} else {
|
||||
@lines = split /\r?\n/, $args{data};
|
||||
}
|
||||
|
||||
@lines = $self->_vcal10_input_cleanup(@lines) if $self->vcal10;
|
||||
|
||||
# Parse the lines; Text::vFile doesn't want trailing newlines
|
||||
my $cal = eval { Text::vFile::asData->new->parse_lines(@lines) };
|
||||
return $self->_error("parse failure: $@") if $@;
|
||||
|
||||
return $self->_error("parse failure")
|
||||
unless $cal and exists $cal->{objects};
|
||||
|
||||
# loop through all the vcards
|
||||
foreach my $object ( @{ $cal->{objects} } ) {
|
||||
$self->parse_object($object);
|
||||
}
|
||||
|
||||
my $version_ref = $self->property("version");
|
||||
my $version = $version_ref ? $version_ref->[0]->value : undef;
|
||||
unless ( defined $version ) {
|
||||
return $self->_error("data does not specify a version property");
|
||||
}
|
||||
|
||||
if ( $version eq '1.0' and not $self->vcal10
|
||||
or $version eq '2.0' and $self->vcal10 )
|
||||
{
|
||||
return $self->_error( 'application claims data is'
|
||||
. ( $self->vcal10 ? '' : ' not' )
|
||||
. ' vCal 1.0 but doc contains VERSION:'
|
||||
. $version );
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _error {
|
||||
my $self = shift;
|
||||
my $msg = shift;
|
||||
|
||||
my $ret = Class::ReturnValue->new;
|
||||
$ret->as_error( errno => 1, message => $msg );
|
||||
return $ret;
|
||||
}
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VCALENDAR>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VCALENDAR'}
|
||||
|
||||
=head2 product_id
|
||||
|
||||
Returns the product ID used in the calendar's C<PRODID> property; you may
|
||||
wish to override this in a subclass for your own application.
|
||||
|
||||
=cut
|
||||
|
||||
sub product_id {
|
||||
my $self = shift;
|
||||
return "Data::ICal $VERSION";
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties must be specified
|
||||
exactly one time for a calendar:
|
||||
|
||||
prodid version
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
qw(
|
||||
prodid version
|
||||
);
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be specified
|
||||
at most one time for a calendar:
|
||||
|
||||
calscale method
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
qw(
|
||||
calscale method
|
||||
);
|
||||
}
|
||||
|
||||
# In quoted-printable sections, convert from vcal10 "=\n" line endings to
|
||||
# ical20 "\n ".
|
||||
sub _vcal10_input_cleanup {
|
||||
my $self = shift;
|
||||
my @in_lines = @_;
|
||||
|
||||
my @out_lines;
|
||||
|
||||
my $in_qp = 0;
|
||||
LINE: while (@in_lines) {
|
||||
my $line = shift @in_lines;
|
||||
|
||||
if ( not $in_qp and $line =~ /^[^:]+;ENCODING=QUOTED-PRINTABLE/i ) {
|
||||
$in_qp = 1;
|
||||
}
|
||||
|
||||
unless ($in_qp) {
|
||||
push @out_lines, $line;
|
||||
next LINE;
|
||||
}
|
||||
|
||||
if ( $line =~ s/=$// ) {
|
||||
push @out_lines, $line;
|
||||
$in_lines[0] = ' ' . $in_lines[0] if @in_lines;
|
||||
} else {
|
||||
push @out_lines, $line;
|
||||
$in_qp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return @out_lines;
|
||||
}
|
||||
|
||||
=head1 DEPENDENCIES
|
||||
|
||||
L<Data::ICal> requires L<Class::Accessor>, L<Text::vFile::asData>,
|
||||
L<MIME::QuotedPrint>, and L<Class::ReturnValue>.
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
L<Data::ICal> does not support time zone daylight or standard entries,
|
||||
so time zone components are basically useless.
|
||||
|
||||
While L<Data::ICal> tries to check which properties are required and
|
||||
repeatable, this only works in simple cases; it does not check for
|
||||
properties that must either both exist or both not exist, or for
|
||||
mutually exclusive properties.
|
||||
|
||||
L<Data::ICal> does not check to see if property parameter names are
|
||||
known in general or allowed on the particular property.
|
||||
|
||||
L<Data::ICal> does not check to see if nested entries are nested
|
||||
properly (alarms in todos and events only, everything else in
|
||||
calendars only).
|
||||
|
||||
The only property encoding supported by L<Data::ICal> is quoted
|
||||
printable.
|
||||
|
||||
Please report any bugs or feature requests to
|
||||
C<bug-data-ical@rt.cpan.org>, or through the web interface at
|
||||
L<http://rt.cpan.org>.
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
640
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry.pm
Normal file
640
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry.pm
Normal file
@@ -0,0 +1,640 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry;
|
||||
use base qw/Class::Accessor/;
|
||||
use Data::ICal::Property;
|
||||
use Sys::Hostname qw(); # For unique UIDs for entries
|
||||
use Carp;
|
||||
|
||||
use constant CRLF => "\x0d\x0a";
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry - Represents an entry in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $vtodo = Data::ICal::Entry::Todo->new();
|
||||
$vtodo->add_property(
|
||||
# ... see Data::ICal::Entry::Todo documentation
|
||||
);
|
||||
$vtodo->add_properties( ... );
|
||||
|
||||
$calendar->add_entry($vtodo);
|
||||
|
||||
$event->add_entry($alarm);
|
||||
$event->add_entries($alarm1, ...);
|
||||
|
||||
# or all in one go
|
||||
my $vtodo = Data::ICal::Entry::Todo->new( \%props, \@entries );
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry> object represents a single entry in an
|
||||
iCalendar file. (Note that the iCalendar RFC refers to entries as
|
||||
"components".) iCalendar defines several types of entries, such as
|
||||
events and to-do lists; each of these corresponds to a subclass of
|
||||
L<Data::ICal::Entry> (though only to-do lists and events are currently
|
||||
implemented). L<Data::ICal::Entry> should be treated as an abstract
|
||||
base class -- all objects created should be of its subclasses. The
|
||||
entire calendar itself (the L<Data::ICal> object) is also represented
|
||||
as a L<Data::ICal::Entry> object.
|
||||
|
||||
Each entry has an entry type (such as C<VCALENDAR> or C<VEVENT>), a
|
||||
series of "properties", and possibly some sub-entries. (Only the root
|
||||
L<Data::ICal> object can have sub-entries, except for alarm entries
|
||||
contained in events and to-dos (not yet implemented).)
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new entry object with no properties or sub-entries.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new();
|
||||
# ALLOW passing arguments here!
|
||||
$self->set( properties => {} );
|
||||
$self->set( entries => [] );
|
||||
for (@_) {
|
||||
ref $_ eq "HASH" and $self->add_properties( %$_ );
|
||||
ref $_ eq "ARRAY" and $self->add_entries( @$_ );
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 as_string [ crlf => C<CRLF> ]
|
||||
|
||||
Returns the entry as an appropriately formatted string (with trailing
|
||||
newline).
|
||||
|
||||
Properties are returned in alphabetical order, with multiple
|
||||
properties of the same name returned in the order added. (Property
|
||||
order is unimportant in iCalendar, and this makes testing easier.)
|
||||
|
||||
If any mandatory property is missing, issues a warning.
|
||||
|
||||
The string to use as a newline can optionally be specified by giving
|
||||
the a C<crlf> argument, which defaults to C<\x0d\x0a>, per RFC 2445
|
||||
spec; this option is primarily for backwards compatibility with
|
||||
versions of this module before 0.16.
|
||||
|
||||
=cut
|
||||
|
||||
my $uid = 0;
|
||||
sub as_string {
|
||||
my $self = shift;
|
||||
my %args = (
|
||||
crlf => CRLF,
|
||||
@_
|
||||
);
|
||||
my $output = $self->header(%args);
|
||||
|
||||
my @mandatory = (
|
||||
$self->mandatory_unique_properties,
|
||||
$self->mandatory_repeatable_properties,
|
||||
);
|
||||
|
||||
if (grep {$_ eq "uid"} @mandatory and !defined $self->properties->{uid}
|
||||
and $self->auto_uid) {
|
||||
# Per the RFC, create a "persistent, globally unique" UID for this
|
||||
# event; "persistent" in this context does not mean consistent
|
||||
# across time, but rather "unique across all time"
|
||||
$self->add_property(
|
||||
uid => time() . '-' .$$ . '-' . $uid++ . '@' . Sys::Hostname::hostname()
|
||||
);
|
||||
}
|
||||
|
||||
for my $name ( @mandatory ) {
|
||||
carp "Mandatory property for " . ( ref $self ) . " missing: $name"
|
||||
unless $self->properties->{$name}
|
||||
and @{ $self->properties->{$name} };
|
||||
}
|
||||
|
||||
my @properties = sort {
|
||||
# RFC2445 implies an order (see 4.6 Calendar Components) but does not
|
||||
# require it. However, some applications break if VERSION is not first
|
||||
# (see http://icalvalid.cloudapp.net/Default.aspx and [rt.cpan.org # #65447]).
|
||||
return -1 if $a eq 'version';
|
||||
return 1 if $b eq 'version';
|
||||
return $a cmp $b;
|
||||
} keys %{ $self->properties };
|
||||
|
||||
for my $name (@properties) {
|
||||
$output .= $_
|
||||
for map { $_->as_string(%args) } @{ $self->properties->{$name} };
|
||||
}
|
||||
|
||||
for my $entry ( @{ $self->entries } ) {
|
||||
$output .= $entry->as_string(%args);
|
||||
}
|
||||
$output .= $self->footer(%args);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
=head2 add_entry $entry
|
||||
|
||||
Adds an entry to this entry. (According to the standard, this should
|
||||
only be called on either a to-do or event entry with an alarm entry,
|
||||
or on a calendar entry (L<Data::ICal>) with a to-do, event, journal,
|
||||
timezone, or free/busy entry.)
|
||||
|
||||
Returns true if the entry was successfully added, and false otherwise
|
||||
(perhaps because you tried to add an entry of an invalid type, but
|
||||
this check hasn't been implemented yet).
|
||||
|
||||
=cut
|
||||
|
||||
sub add_entry {
|
||||
my $self = shift;
|
||||
my $entry = shift;
|
||||
push @{ $self->{entries} }, $entry;
|
||||
|
||||
$entry->vcal10( $self->vcal10 );
|
||||
$entry->rfc_strict( $self->rfc_strict );
|
||||
$entry->auto_uid( $self->auto_uid );
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 add_entries $entry1, [$entry2, ...]
|
||||
|
||||
Convenience function to call C<add_entry> several times with a list
|
||||
of entries.
|
||||
|
||||
=cut
|
||||
|
||||
sub add_entries {
|
||||
my $self = shift;
|
||||
$self->add_entry( $_ ) for @_;
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 entries
|
||||
|
||||
Returns a reference to the array of subentries of this entry.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->mk_ro_accessors('entries');
|
||||
|
||||
=head2 properties
|
||||
|
||||
Returns a reference to the hash of properties of this entry. The keys
|
||||
are property names and the values are array references containing
|
||||
L<Data::ICal::Property> objects.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->mk_ro_accessors('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 C<$propval> and adds it to the event.
|
||||
|
||||
If the property is not known to exist for that object type and does
|
||||
not begin with C<X->, issues a warning.
|
||||
|
||||
If the property is known to be unique, replaces the original property.
|
||||
|
||||
To specify parameters for the property, let C<$propval> be a
|
||||
two-element array reference where the first element is the property
|
||||
value and the second element is a hash reference. The keys of the
|
||||
hash are parameter names; the values should be either strings or array
|
||||
references of strings, depending on whether the parameter should have
|
||||
one or multiple (to be comma-separated) values.
|
||||
|
||||
Examples of setting parameters:
|
||||
|
||||
# Add a property with a parameter of VALUE set to 'DATE'
|
||||
$event->add_property( rdate => [ $date, { VALUE => 'DATE' } ] );
|
||||
|
||||
=cut
|
||||
|
||||
sub add_property {
|
||||
my $self = shift;
|
||||
my $prop = lc shift;
|
||||
my $val = shift;
|
||||
|
||||
return unless defined $prop;
|
||||
|
||||
unless ( $self->is_property($prop) or $prop =~ /^x-/i ) {
|
||||
carp "Unknown property for " . ( ref $self ) . ": $prop";
|
||||
}
|
||||
|
||||
if ( $self->is_unique($prop) ) {
|
||||
|
||||
# It should be unique, so clear out anything we might have first
|
||||
$self->properties->{$prop} = [];
|
||||
}
|
||||
|
||||
$val = [ $val, {} ] unless ref $val eq 'ARRAY';
|
||||
|
||||
my ( $prop_value, $param_hash ) = @$val;
|
||||
|
||||
my $p = Data::ICal::Property->new( $prop => $prop_value, $param_hash );
|
||||
$p->vcal10( $self->vcal10 );
|
||||
|
||||
push @{ $self->properties->{$prop} }, $p;
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 add_properties $propname1 => $propval1, [$propname2 => $propname2, ...]
|
||||
|
||||
Convenience function to call C<add_property> several times with a list
|
||||
of properties.
|
||||
|
||||
This method is guaranteed to call add C<add_property> on them in the
|
||||
order given, so that unique properties given later in the call will
|
||||
take precedence over those given earlier. (This is unrelated to the
|
||||
order of properties when the entry is rendered as a string, though.)
|
||||
|
||||
Parameters for the properties are specified in the same way as in
|
||||
C<add_property>.
|
||||
|
||||
=cut
|
||||
|
||||
sub add_properties {
|
||||
my $self = shift;
|
||||
|
||||
if ( @_ % 2 ) {
|
||||
carp "Odd number of elements in add_properties call";
|
||||
return;
|
||||
}
|
||||
|
||||
while (@_) {
|
||||
my $prop = shift;
|
||||
my $val = shift;
|
||||
$self->add_property( $prop => $val );
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
Subclasses should override this method (which returns an empty list by
|
||||
default) to provide a list of lower case strings identifying the
|
||||
properties which must appear exactly once in the subclass's entry
|
||||
type.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties { () }
|
||||
|
||||
=head2 mandatory_repeatable_properties
|
||||
|
||||
Subclasses should override this method (which returns an empty list by
|
||||
default) to provide a list of lower case strings identifying the
|
||||
properties which must appear at least once in the subclass's entry
|
||||
type.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_repeatable_properties { () }
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
Subclasses should override this method (which returns an empty list by
|
||||
default) to provide a list of lower case strings identifying the
|
||||
properties which must appear at most once in the subclass's entry
|
||||
type.
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties { () }
|
||||
|
||||
=head2 optional_repeatable_properties
|
||||
|
||||
Subclasses should override this method (which returns an empty list by
|
||||
default) to provide a list of lower case strings identifying the
|
||||
properties which may appear zero, one, or more times in the subclass's
|
||||
entry type.
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_repeatable_properties { () }
|
||||
|
||||
=head2 is_property $name
|
||||
|
||||
Returns a boolean value indicating whether or not the property
|
||||
C<$name> is known to the class (that is, if it's listed in
|
||||
C<(mandatory/optional)_(unique/repeatable)_properties>).
|
||||
|
||||
=cut
|
||||
|
||||
sub is_property {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
return scalar grep { $_ eq $name } $self->mandatory_unique_properties,
|
||||
$self->mandatory_repeatable_properties,
|
||||
$self->optional_unique_properties,
|
||||
$self->optional_repeatable_properties;
|
||||
}
|
||||
|
||||
=head2 is_mandatory $name
|
||||
|
||||
Returns a boolean value indicating whether or not the property
|
||||
C<$name> is known to the class as mandatory (that is, if it's listed
|
||||
in C<mandatory_(unique/repeatable)_properties>).
|
||||
|
||||
=cut
|
||||
|
||||
sub is_mandatory {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
return scalar grep { $_ eq $name } $self->mandatory_unique_properties,
|
||||
$self->mandatory_repeatable_properties;
|
||||
}
|
||||
|
||||
=head2 is_optional $name
|
||||
|
||||
Returns a boolean value indicating whether or not the property
|
||||
C<$name> is known to the class as optional (that is, if it's listed in
|
||||
C<optional_(unique/repeatable)_properties>).
|
||||
|
||||
=cut
|
||||
|
||||
sub is_optional {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
return scalar grep { $_ eq $name } $self->optional_unique_properties,
|
||||
$self->optional_repeatable_properties;
|
||||
}
|
||||
|
||||
=head2 is_unique $name
|
||||
|
||||
Returns a boolean value indicating whether or not the property
|
||||
C<$name> is known to the class as unique (that is, if it's listed in
|
||||
C<(mandatory/optional)_unique_properties>).
|
||||
|
||||
=cut
|
||||
|
||||
sub is_unique {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
return scalar grep { $_ eq $name } $self->mandatory_unique_properties,
|
||||
$self->optional_unique_properties;
|
||||
}
|
||||
|
||||
=head2 is_repeatable $name
|
||||
|
||||
Returns a boolean value indicating whether or not the property
|
||||
C<$name> is known to the class as repeatable (that is, if it's listed
|
||||
in C<(mandatory/optional)_repeatable_properties>).
|
||||
|
||||
=cut
|
||||
|
||||
sub is_repeatable {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
return scalar grep { $_ eq $name } $self->mandatory_repeatable_properties,
|
||||
$self->optional_repeatable_properties;
|
||||
}
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Subclasses should override this method to provide the identifying type
|
||||
name of the entry (such as C<VCALENDAR> or C<VTODO>).
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'UNDEFINED'}
|
||||
|
||||
=head2 vcal10 [$bool]
|
||||
|
||||
Gets or sets a boolean saying whether this entry should be interpreted
|
||||
as vCalendar 1.0 (as opposed to iCalendar 2.0). Generally, you can
|
||||
just set this on your main L<Data::ICal> object when you construct it;
|
||||
C<add_entry> automatically makes sure that sub-entries end up with the
|
||||
same value as their parents.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->mk_accessors('vcal10');
|
||||
|
||||
=head2 rfc_strict [$bool]
|
||||
|
||||
Gets or sets a boolean saying whether this entry will complain about
|
||||
missing UIDs as per RFC2446. Defaults to false, for backwards
|
||||
compatibility. Generally, you can just set this on your main
|
||||
L<Data::ICal> object when you construct it; C<add_entry> automatically
|
||||
makes sure that sub-entries end up with the same value as their parents.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->mk_accessors('rfc_strict');
|
||||
|
||||
=head2 auto_uid [$bool]
|
||||
|
||||
Gets or sets a boolean saying whether this entry should automatically
|
||||
generate its own persistently unique UIDs. Defaults to false.
|
||||
Generally, you can just set this on your main L<Data::ICal> object when
|
||||
you construct it; C<add_entry> automatically makes sure that sub-entries
|
||||
end up with the same value as their parents.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->mk_accessors('auto_uid');
|
||||
|
||||
=head2 header
|
||||
|
||||
Returns the header line for the entry (including trailing newline).
|
||||
|
||||
=cut
|
||||
|
||||
sub header {
|
||||
my $self = shift;
|
||||
my %args = (
|
||||
crlf => CRLF,
|
||||
@_
|
||||
);
|
||||
return 'BEGIN:' . $self->ical_entry_type . $args{crlf};
|
||||
}
|
||||
|
||||
=head2 footer
|
||||
|
||||
Returns the footer line for the entry (including trailing newline).
|
||||
|
||||
=cut
|
||||
|
||||
sub footer {
|
||||
my $self = shift;
|
||||
my %args = (
|
||||
crlf => CRLF,
|
||||
@_
|
||||
);
|
||||
return 'END:' . $self->ical_entry_type . $args{crlf};
|
||||
}
|
||||
|
||||
# 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);
|
||||
|
||||
# complain
|
||||
} 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);
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
# 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',
|
||||
NONE => 'None',
|
||||
URI => 'URI',
|
||||
);
|
||||
|
||||
# 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};
|
||||
|
||||
$action = $_action_map{$action};
|
||||
my $alarm_class = "Data::ICal::Entry::Alarm::$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;
|
||||
$entry->vcal10($parent->vcal10);
|
||||
$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};
|
||||
for my $key ( sort keys %$p ) {
|
||||
foreach my $occurence (@{ $p->{$key} }) {
|
||||
my $prop;
|
||||
|
||||
# Unescapes, but only in v2, and not if it's explicitly not TEXT
|
||||
if (not $parent->vcal10
|
||||
and ( not $occurence->{param}
|
||||
or not defined $occurence->{param}{VALUE}
|
||||
or $occurence->{param}{VALUE} eq "TEXT" )
|
||||
)
|
||||
{
|
||||
$occurence->{value} =~ s/\\([;,\\])/$1/g;
|
||||
$occurence->{value} =~ s/\\n/\n/ig;
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
101
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm.pm
Normal file
101
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm.pm
Normal file
@@ -0,0 +1,101 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm;
|
||||
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm - Abstract base class for alarms
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Data::ICal::Entry::Alarm> is an abstract base class for the other type
|
||||
of supported by alarms:
|
||||
|
||||
=over
|
||||
|
||||
=item L<Data::ICal::Entry::Alarm::Audio>
|
||||
|
||||
=item L<Data::ICal::Entry::Alarm::Display>
|
||||
|
||||
=item L<Data::ICal::Entry::Alarm::Email>
|
||||
|
||||
=item L<Data::ICal::Entry::Alarm::Procedure>
|
||||
|
||||
=back
|
||||
|
||||
It is a subclass of L<Data::ICal::Entry> and accepts all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
die "Can't instantiate abstract base class Data::ICal::Entry::Alarm"
|
||||
if $class eq __PACKAGE__;
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VALARM>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VALARM'}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the C<duration> and C<retreat>
|
||||
properties may be specified at most one time all types of alarms; if one
|
||||
is specified, the other one must be also, though this module does not
|
||||
enforce that restriction.
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
qw(
|
||||
duration repeat
|
||||
);
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
According to the iCalendar standard, the C<trigger> property must be
|
||||
specified exactly once for an all types of alarms; subclasses may have
|
||||
additional required properties.
|
||||
|
||||
In addition, the C<action> property must be specified exactly once, but
|
||||
all subclasses automatically set said property appropriately.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
qw(
|
||||
action trigger
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
76
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Audio.pm
Normal file
76
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Audio.pm
Normal file
@@ -0,0 +1,76 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm::Audio;
|
||||
|
||||
use base qw/Data::ICal::Entry::Alarm/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm::Audio - Represents an audio alarm in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $valarm = Data::ICal::Entry::Alarm::Audio->new();
|
||||
$valarm->add_properties(
|
||||
attach => [ "ftp://host.com/pub/sounds/bell-01.aud", { fmttype => "audio/basic" } ],
|
||||
# Dat*e*::ICal is not a typo here
|
||||
trigger => [ Date::ICal->new( epoch => ... )->ical, { value => 'DATE-TIME' } ],
|
||||
);
|
||||
|
||||
$vevent->add_entry($valarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Alarm::Audio> object represents an audio alarm
|
||||
attached to a todo item or event in an iCalendar file. (Note that the
|
||||
iCalendar RFC refers to entries as "components".) It is a subclass of
|
||||
L<Data::ICal::Entry::Alarm> and accepts all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new L<Data::ICal::Entry::Alarm::Audio> object; sets its
|
||||
C<ACTION> property to C<AUDIO>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->add_property( action => "AUDIO" );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
In addition to C<duration> and C<repeat> (see
|
||||
L<Data::ICal::Entry::Alarm/optional_unique_properties>), audio alarms
|
||||
may specify a value for C<attach>.
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
return (
|
||||
shift->SUPER::optional_unique_properties,
|
||||
"attach",
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
77
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Display.pm
Normal file
77
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Display.pm
Normal file
@@ -0,0 +1,77 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm::Display;
|
||||
|
||||
use base qw/Data::ICal::Entry::Alarm/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm::Display - Represents a displayed alarm in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $valarm = Data::ICal::Entry::Alarm::Display->new();
|
||||
$valarm->add_properties(
|
||||
description => "Wake up!",
|
||||
# Dat*e*::ICal is not a typo here
|
||||
trigger => [ Date::ICal->new( epoch => ... )->ical, { value => 'DATE-TIME' } ],
|
||||
);
|
||||
|
||||
$vevent->add_entry($valarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Alarm::Display> object represents a alarm that
|
||||
displays a message which is attached to a todo item or event in an
|
||||
iCalendar file. (Note that the iCalendar RFC refers to entries as
|
||||
"components".) It is a subclass of L<Data::ICal::Entry::Alarm> and
|
||||
accepts all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new L<Data::ICal::Entry::Alarm::Display> object; sets its
|
||||
C<ACTION> property to C<DISPLAY>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->add_property( action => "DISPLAY" );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
In addition to C<action> and C<trigger> (see
|
||||
L<Data::ICal::Entry::Alarm/mandatory_unique_properties>), displayed
|
||||
alarms must also specify a value for C<description>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
return (
|
||||
shift->SUPER::mandatory_unique_properties,
|
||||
"description",
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
106
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Email.pm
Normal file
106
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Email.pm
Normal file
@@ -0,0 +1,106 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm::Email;
|
||||
|
||||
use base qw/Data::ICal::Entry::Alarm/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm::Email - Represents an emailed alarm in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $valarm = Data::ICal::Entry::Alarm::Audio->new();
|
||||
$valarm->add_properties(
|
||||
attach => [ "basic:ftp://host.com/pub/sounds/bell-01.aud", { fmttype => "audio/basic" } ],
|
||||
# Dat*e*::ICal is not a typo here
|
||||
trigger => [ Date::ICal->new( epoch => ... )->ical, { value => 'DATE-TIME' } ],
|
||||
);
|
||||
|
||||
$vevent->add_entry($valarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Alarm::Email> object represents an emailed
|
||||
alarm attached to a todo item or event in an iCalendar file. (Note
|
||||
that the iCalendar RFC refers to entries as "components".) It is a
|
||||
subclass of L<Data::ICal::Entry::Alarm> and accepts all of its methods.
|
||||
|
||||
The C<attendee> properties are intended as the recipient list of the
|
||||
email; the C<summary> as its subject; the C<description> as its body;
|
||||
and the C<attach> as its attachments.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new L<Data::ICal::Entry::Alarm::Email> object; sets its
|
||||
C<ACTION> property to C<EMAIL>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->add_property( action => "EMAIL" );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
In addition to C<action> and C<trigger> (see
|
||||
L<Data::ICal::Entry::Alarm/mandatory_unique_properties>), emailed alarms
|
||||
must also specify a value for C<description> and C<summary>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
return (
|
||||
shift->SUPER::mandatory_unique_properties,
|
||||
"description", "summary",
|
||||
);
|
||||
}
|
||||
|
||||
=head2 mandatory_repeatable_properties
|
||||
|
||||
According to the iCalendar standard, the C<attendee> property must be
|
||||
specified at least once for an emailed alarm.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_repeatable_properties {
|
||||
qw(
|
||||
attendee
|
||||
);
|
||||
}
|
||||
|
||||
=head2 optional_repeatable_properties
|
||||
|
||||
According to the iCalendar standard, the C<attach> property may be
|
||||
specified any number of times for an emailed alarm.
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_repeatable_properties {
|
||||
qw(
|
||||
attach
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
63
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/None.pm
Normal file
63
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/None.pm
Normal file
@@ -0,0 +1,63 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm::None;
|
||||
|
||||
use base qw/Data::ICal::Entry::Alarm/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm::None - Represents an default no-op alarm
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $valarm = Data::ICal::Entry::Alarm::None->new();
|
||||
$vevent->add_entry($valarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Alarm::None> object represents a default alarm
|
||||
that does nothing; this is different from a lack of alarm, because
|
||||
clients may be expected to "override" any default alarm present in
|
||||
calendar data with the current value retrieved from the server. This
|
||||
class is a subclass of L<Data::ICal::Entry::Alarm> and accepts all of
|
||||
its methods.
|
||||
|
||||
This element is not included in the official iCal RFC, but is rather an
|
||||
unaccepted draft standard; see
|
||||
L<https://tools.ietf.org/html/draft-daboo-valarm-extensions-04#section-11>
|
||||
B<Its interoperability and support is thus limited.> This is alarm type
|
||||
is primarily used by Apple.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new L<Data::ICal::Entry::Alarm::None> object; sets its
|
||||
C<ACTION> property to C<NONE>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->add_property( action => "NONE" );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
92
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Procedure.pm
Normal file
92
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/Procedure.pm
Normal file
@@ -0,0 +1,92 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm::Procedure;
|
||||
|
||||
use base qw/Data::ICal::Entry::Alarm/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm::Procedure - Represents a procedure-call alarm in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $valarm = Data::ICal::Entry::Alarm::Procedure->new();
|
||||
$valarm->add_properties(
|
||||
attach => [ "ftp://host.com/novo-procs/felizano.exe", { fmttype => "application/binary" } ],
|
||||
# Dat*e*::ICal is not a typo here
|
||||
trigger => [ Date::ICal->new( epoch => ... )->ical, { value => 'DATE-TIME' } ],
|
||||
);
|
||||
|
||||
$vevent->add_entry($valarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Alarm::Procedure> object represents an alarm
|
||||
that calls a procedure (in some application-defined way), which is
|
||||
attached to a todo item or event in an iCalendar file. (Note that the
|
||||
iCalendar RFC refers to entries as "components".) It is a subclass of
|
||||
L<Data::ICal::Entry::Alarm> and accepts all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new L<Data::ICal::Entry::Alarm::Procedure> object; sets its
|
||||
C<ACTION> property to C<PROCEDURE>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->add_property( action => "PROCEDURE" );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
In addition to C<duration> and C<repeat> (see
|
||||
L<Data::ICal::Entry::Alarm/optional_unique_properties>), procedure-call
|
||||
alarms may also specify a value for C<description>.
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
return (
|
||||
shift->SUPER::optional_unique_properties,
|
||||
"description",
|
||||
);
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
In addition to C<action> and C<trigger> (see
|
||||
L<Data::ICal::Entry::Alarm/mandatory_unique_properties>), procedure-call
|
||||
alarms must also specify a value for C<attach>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
return (
|
||||
shift->SUPER::mandatory_unique_properties,
|
||||
"attach",
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
83
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/URI.pm
Normal file
83
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Alarm/URI.pm
Normal file
@@ -0,0 +1,83 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Alarm::URI;
|
||||
|
||||
use base qw/Data::ICal::Entry::Alarm/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Alarm::URI - Represents notification via a custom URI
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $valarm = Data::ICal::Entry::Alarm::URI->new();
|
||||
$valarm->add_properties(
|
||||
uri => "sms:+15105550101?body=hello%20there",
|
||||
# Dat*e*::ICal is not a typo here
|
||||
trigger => [ Date::ICal->new( epoch => ... )->ical, { value => 'DATE-TIME' } ],
|
||||
);
|
||||
|
||||
$vevent->add_entry($valarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Alarm::URI> object represents an alarm that
|
||||
notifies via arbitrary URI which is attached to a todo item or event in
|
||||
an iCalendar file. (Note that the iCalendar RFC refers to entries as
|
||||
"components".) It is a subclass of L<Data::ICal::Entry::Alarm> and
|
||||
accepts all of its methods.
|
||||
|
||||
This element is not included in the official iCal RFC, but is rather an
|
||||
unaccepted draft standard; see
|
||||
L<https://tools.ietf.org/html/draft-daboo-valarm-extensions-04#section-6>
|
||||
B<Its interoperability and support is thus limited.> This is alarm type
|
||||
is primarily used by Apple.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new
|
||||
|
||||
Creates a new L<Data::ICal::Entry::Alarm::Alarm> object; sets its
|
||||
C<ACTION> property to C<NONE>.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->add_property( action => "URI" );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
In addition to C<action> and C<trigger> (see
|
||||
L<Data::ICal::Entry::Alarm/mandatory_unique_properties>), uri alarms
|
||||
must also specify a value for C<uri>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
return (
|
||||
shift->SUPER::mandatory_unique_properties,
|
||||
"uri",
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
163
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Event.pm
Normal file
163
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Event.pm
Normal file
@@ -0,0 +1,163 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Event;
|
||||
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Event - Represents an event in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $vevent = Data::ICal::Entry::Event->new();
|
||||
$vevent->add_properties(
|
||||
summary => "my party",
|
||||
description => "I'll cry if I want to",
|
||||
# Dat*e*::ICal is not a typo here
|
||||
dtstart => Date::ICal->new( epoch => time )->ical,
|
||||
);
|
||||
|
||||
$calendar->add_entry($vevent);
|
||||
|
||||
$vevent->add_entry($alarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Event> object represents a single event in an
|
||||
iCalendar file. (Note that the iCalendar RFC refers to entries as
|
||||
"components".) It is a subclass of L<Data::ICal::Entry> and accepts
|
||||
all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VEVENT>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VEVENT'}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
The C<uid> property is mandatory if C<rfc_strict> was passed to
|
||||
L<Data::ICal/new>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
my $self = shift;
|
||||
return $self->rfc_strict ? ("uid") : ()
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified at most one time for an event:
|
||||
|
||||
class created description dtstart geo
|
||||
last-modified location organizer priority
|
||||
dtstamp sequence status summary transp
|
||||
uid url recurrence-id
|
||||
|
||||
In addition, C<dtend> and C<duration> may be specified at most once
|
||||
each, but not both in the same entry (though this restriction is not
|
||||
enforced).
|
||||
|
||||
Or if C<< vcal10 => 1 >>:
|
||||
|
||||
class dcreated completed description dtstart dtend
|
||||
last-modified location rnum priority
|
||||
sequence status summary transp
|
||||
url uid
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
my $self = shift;
|
||||
my @ret = $self->rfc_strict ? () : ("uid");
|
||||
if (not $self->vcal10) {
|
||||
push @ret, qw(
|
||||
class created description dtstart geo
|
||||
last-modified location organizer priority
|
||||
dtstamp sequence status summary transp
|
||||
url recurrence-id
|
||||
|
||||
dtend duration
|
||||
);
|
||||
} else {
|
||||
push @ret, qw(
|
||||
class dcreated completed description dtstart dtend
|
||||
last-modified location rnum priority
|
||||
sequence status summary transp
|
||||
url
|
||||
);
|
||||
}
|
||||
return @ret;
|
||||
}
|
||||
|
||||
=head2 optional_repeatable_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified any number of times for an event:
|
||||
|
||||
attach attendee categories comment
|
||||
contact exdate exrule request-status related-to
|
||||
resources rdate rrule
|
||||
|
||||
Or if C<< vcal10 => 1 >>:
|
||||
|
||||
aalarm attach attendee categories
|
||||
dalarm exdate exrule malarm palarm related-to
|
||||
resources rdate rrule
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_repeatable_properties {
|
||||
my $self = shift;
|
||||
if (not $self->vcal10) {
|
||||
qw(
|
||||
attach attendee categories comment
|
||||
contact exdate exrule request-status related-to
|
||||
resources rdate rrule
|
||||
);
|
||||
} else {
|
||||
qw(
|
||||
aalarm attach attendee categories
|
||||
dalarm exdate exrule malarm palarm related-to
|
||||
resources rdate rrule
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=over 4
|
||||
|
||||
=item L<Data::ICal::DateTime>
|
||||
|
||||
For date parsing and formatting, including denoting "all day" events,
|
||||
considering using this module. Because it's a "mix in", you can still
|
||||
use all the methods here as well as the new date handling methods it
|
||||
defines.
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
103
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/FreeBusy.pm
Normal file
103
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/FreeBusy.pm
Normal file
@@ -0,0 +1,103 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::FreeBusy;
|
||||
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::FreeBusy - Represents blocks of free and busy time in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $vfreebusy = Data::ICal::Entry::FreeBusy->new();
|
||||
$vfreebusy->add_properties(
|
||||
organizer => 'MAILTO:jsmith@host.com',
|
||||
# Dat*e*::ICal is not a typo here
|
||||
freebusy => Date::ICal->new( epoch => ... )->ical . '/' . Date::ICal->new( epoch => ... )->ical,
|
||||
);
|
||||
|
||||
$calendar->add_entry($vfreebusy);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::FreeBusy> object represents a request for
|
||||
information about free and busy time or a reponse to such a request,
|
||||
in an iCalendar file. (Note that the iCalendar RFC refers to entries
|
||||
as "components".) It is a subclass of L<Data::ICal::Entry> and
|
||||
accepts all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VFREEBUSY>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VFREEBUSY'}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
The C<uid> property is mandatory if C<rfc_strict> was passed to
|
||||
L<Data::ICal/new>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
my $self = shift;
|
||||
return $self->rfc_strict ? ("uid") : ()
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified at most one time for a free/busy entry:
|
||||
|
||||
contact dtstart dtend duration dtstamp
|
||||
organizer uid url
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
my $self = shift;
|
||||
my @ret = qw(
|
||||
contact dtstart dtend duration dtstamp
|
||||
organizer url
|
||||
);
|
||||
push @ret, "uid" unless $self->rfc_strict;
|
||||
return @ret;
|
||||
}
|
||||
|
||||
=head2 optional_repeatable_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified any number of times for free/busy entry:
|
||||
|
||||
attendee comment freebusy request-status
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_repeatable_properties {
|
||||
qw(
|
||||
attendee comment freebusy request-status
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
109
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Journal.pm
Normal file
109
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Journal.pm
Normal file
@@ -0,0 +1,109 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Journal;
|
||||
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Journal - Represents a journal entry in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $vjournal = Data::ICal::Entry::Journal->new();
|
||||
$vjournal->add_properties(
|
||||
summary => "Minutes of my party",
|
||||
description => "I cried because I wanted to.",
|
||||
# Dat*e*::ICal is not a typo here
|
||||
dtstart => Date::ICal->new( epoch => time )->ical,
|
||||
);
|
||||
|
||||
$calendar->add_entry($vjournal);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Journal> object represents a single journal
|
||||
entry in an iCalendar file. (Note that the iCalendar RFC refers to
|
||||
entries as "components".) It is a subclass of L<Data::ICal::Entry>
|
||||
and accepts all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VJOURNAL>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VJOURNAL'}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
The C<uid> property is mandatory if C<rfc_strict> was passed to
|
||||
L<Data::ICal/new>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
my $self = shift;
|
||||
return $self->rfc_strict ? ("uid") : ()
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified at most one time for a journal entry:
|
||||
|
||||
class created description dtstart dtstamp
|
||||
last-modified organizer recurrence-id sequence status
|
||||
summary uid url
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
my $self = shift;
|
||||
my @ret = qw(
|
||||
class created description dtstart dtstamp
|
||||
last-modified organizer recurrence-id sequence status
|
||||
summary url
|
||||
);
|
||||
push @ret, "uid" unless $self->rfc_strict;
|
||||
return @ret;
|
||||
}
|
||||
|
||||
=head2 optional_repeatable_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified any number of times for a journal entry:
|
||||
|
||||
attach attendee categories comment
|
||||
contact exdate exrule related-to rdate
|
||||
rrule request-status
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_repeatable_properties {
|
||||
qw(
|
||||
attach attendee categories comment
|
||||
contact exdate exrule related-to rdate
|
||||
rrule request-status
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
89
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/TimeZone.pm
Normal file
89
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/TimeZone.pm
Normal file
@@ -0,0 +1,89 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::TimeZone;
|
||||
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::TimeZone - Represents a time zone definition in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $vtimezone = Data::ICal::Entry::TimeZone->new();
|
||||
$vtimezone->add_properties(
|
||||
tzid => "US-Eastern",
|
||||
tzurl => "http://zones.stds_r_us.net/tz/US-Eastern"
|
||||
);
|
||||
|
||||
$vtimezone->add_entry($daylight); # daylight/ standard not yet implemented
|
||||
$vtimezone->add_entry($standard); # :-(
|
||||
|
||||
$calendar->add_entry($vtimezone);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::TimeZone> object represents the declaration of
|
||||
a time zone in an iCalendar file. (Note that the iCalendar RFC refers
|
||||
to entries as "components".) It is a subclass of L<Data::ICal::Entry>
|
||||
and accepts all of its methods.
|
||||
|
||||
This module is not yet useful, because every time zone declaration
|
||||
needs to contain at least one C<STANDARD> or C<DAYLIGHT> component,
|
||||
and these have not yet been implemented.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VTIMEZONE>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VTIMEZONE'}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified at most one time for a time zone declaration:
|
||||
|
||||
last-modified tzurl
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
qw(
|
||||
last-modified tzurl
|
||||
);
|
||||
}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
According to the iCalendar standard, the C<tzid> property must be
|
||||
specified exactly one time in a time zone declaration.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
qw(
|
||||
tzid
|
||||
);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
116
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/TimeZone/Daylight.pm
Normal file
116
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/TimeZone/Daylight.pm
Normal file
@@ -0,0 +1,116 @@
|
||||
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 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
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
116
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/TimeZone/Standard.pm
Normal file
116
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/TimeZone/Standard.pm
Normal file
@@ -0,0 +1,116 @@
|
||||
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 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
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
150
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Todo.pm
Normal file
150
Perl OTRS/Kernel/cpan-lib/Data/ICal/Entry/Todo.pm
Normal file
@@ -0,0 +1,150 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Entry::Todo;
|
||||
|
||||
use base qw/Data::ICal::Entry/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Entry::Todo - Represents a to-do entry in an iCalendar file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $vtodo = Data::ICal::Entry::Todo->new();
|
||||
$vtodo->add_properties(
|
||||
summary => "go to sleep",
|
||||
status => 'INCOMPLETE',
|
||||
# Dat*e*::ICal is not a typo here
|
||||
dtstart => Date::ICal->new( epoch => time )->ical,
|
||||
);
|
||||
|
||||
$calendar->add_entry($vtodo);
|
||||
|
||||
$vtodo->add_entry($alarm);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Entry::Todo> object represents a single to-do entry in
|
||||
an iCalendar file. (Note that the iCalendar RFC refers to entries as
|
||||
"components".) It is a subclass of L<Data::ICal::Entry> and accepts
|
||||
all of its methods.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 ical_entry_type
|
||||
|
||||
Returns C<VTODO>, its iCalendar entry name.
|
||||
|
||||
=cut
|
||||
|
||||
sub ical_entry_type {'VTODO'}
|
||||
|
||||
=head2 mandatory_unique_properties
|
||||
|
||||
The C<uid> property is mandatory if C<rfc_strict> was passed to
|
||||
L<Data::ICal/new>.
|
||||
|
||||
=cut
|
||||
|
||||
sub mandatory_unique_properties {
|
||||
my $self = shift;
|
||||
return $self->rfc_strict ? ("uid") : ()
|
||||
}
|
||||
|
||||
=head2 optional_unique_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified at most one time for a to-do item:
|
||||
|
||||
class completed created description dtstamp
|
||||
dtstart geo last-modified location organizer
|
||||
percent-complete priority recurrence-id sequence status
|
||||
summary uid url
|
||||
|
||||
In addition, C<due> and C<duration> may be specified at most once
|
||||
each, but not both in the same entry (though this restriction is not
|
||||
enforced).
|
||||
|
||||
Or if C<< vcal10 => 1 >>:
|
||||
|
||||
class dcreated completed description dtstart due
|
||||
last-modified location rnum priority
|
||||
sequence status summary transp
|
||||
url uid
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_unique_properties {
|
||||
my $self = shift;
|
||||
my @ret = $self->rfc_strict ? () : ("uid");
|
||||
if (not $self->vcal10) {
|
||||
push @ret, qw(
|
||||
class completed created description dtstamp
|
||||
dtstart geo last-modified location organizer
|
||||
percent-complete priority recurrence-id sequence status
|
||||
summary uid url
|
||||
|
||||
due duration
|
||||
);
|
||||
} else {
|
||||
push @ret, qw(
|
||||
class dcreated completed description dtstart due
|
||||
last-modified location rnum priority
|
||||
sequence status summary transp
|
||||
url uid
|
||||
);
|
||||
}
|
||||
return @ret;
|
||||
}
|
||||
|
||||
=head2 optional_repeatable_properties
|
||||
|
||||
According to the iCalendar standard, the following properties may be
|
||||
specified any number of times for a to-do item:
|
||||
|
||||
attach attendee categories comment contact
|
||||
exdate exrule request-status related-to resources
|
||||
rdate rrule
|
||||
|
||||
Or if C<< vcal10 => 1 >>:
|
||||
|
||||
aalarm attach attendee categories
|
||||
dalarm exdate exrule malarm palarm related-to
|
||||
resources rdate rrule
|
||||
|
||||
=cut
|
||||
|
||||
sub optional_repeatable_properties {
|
||||
my $self = shift;
|
||||
if (not $self->vcal10) {
|
||||
qw(
|
||||
attach attendee categories comment contact
|
||||
exdate exrule request-status related-to resources
|
||||
rdate rrule
|
||||
);
|
||||
} else {
|
||||
qw(
|
||||
aalarm attach attendee categories
|
||||
dalarm exdate exrule malarm palarm related-to
|
||||
resources rdate rrule
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
357
Perl OTRS/Kernel/cpan-lib/Data/ICal/Property.pm
Normal file
357
Perl OTRS/Kernel/cpan-lib/Data/ICal/Property.pm
Normal file
@@ -0,0 +1,357 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
package Data::ICal::Property;
|
||||
|
||||
use base qw/Class::Accessor/;
|
||||
|
||||
use Carp;
|
||||
use MIME::QuotedPrint ();
|
||||
|
||||
our $VERSION = '0.06';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Data::ICal::Property - Represents a property on an entry in an iCalendar file
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A L<Data::ICal::Property> object represents a single property on an
|
||||
entry in an iCalendar file. Properties have parameters in addition to
|
||||
their value.
|
||||
|
||||
You shouldn't need to create L<Data::ICal::Property> values directly
|
||||
-- just use C<add_property> in L<Data::ICal::Entry>.
|
||||
|
||||
The C<encoding> parameter value is only interpreted by L<Data::ICal>
|
||||
in the C<decoded_value> and C<encode> methods: all other methods
|
||||
access the encoded version directly (if there is an encoding).
|
||||
|
||||
Currently, the only supported encoding is C<QUOTED-PRINTABLE>.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
=head2 new $key, $value, [$parameter_hash]
|
||||
|
||||
Creates a new L<Data::ICal::Property> with key C<$key> and value C<$value>.
|
||||
|
||||
If C<$parameter_hash> is provided, sets the property's parameters to
|
||||
it. The parameter hash should have keys equal to the names of the
|
||||
parameters (case insensitive; parameter hashes should not contain two
|
||||
different keys which are the same when converted to upper case); the
|
||||
values should either be a string if the parameter has a single value
|
||||
or an array reference of strings if the parameter has multiple values.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = {};
|
||||
|
||||
bless $self, $class;
|
||||
|
||||
$self->key(shift);
|
||||
$self->value(shift);
|
||||
$self->parameters( shift || {} );
|
||||
return ($self);
|
||||
}
|
||||
|
||||
=head2 key [$key]
|
||||
|
||||
Gets or sets the key name of this property.
|
||||
|
||||
=head2 value [$value]
|
||||
|
||||
Gets or sets the value of this property.
|
||||
|
||||
=head2 parameters [$param_hash]
|
||||
|
||||
Gets or sets the parameter hash reference of this property. Parameter
|
||||
keys are converted to upper case.
|
||||
|
||||
=head2 vcal10 [$bool]
|
||||
|
||||
Gets or sets a boolean saying whether this should be interpreted as
|
||||
vCalendar 1.0 (as opposed to iCalendar 2.0). Generally, you can just
|
||||
set this on your main L<Data::ICal> object when you construct it;
|
||||
C<add_entry> automatically makes sure that sub-entries end up with the
|
||||
same value as their parents, and C<add_property> makes sure that
|
||||
properties end up with the same value as their entry.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->mk_accessors(qw(key value _parameters vcal10));
|
||||
|
||||
sub parameters {
|
||||
my $self = shift;
|
||||
|
||||
if (@_) {
|
||||
my $params = shift;
|
||||
my $new_params = {};
|
||||
while ( my ( $k, $v ) = each %$params ) {
|
||||
$new_params->{ uc $k } = $v;
|
||||
}
|
||||
$self->_parameters($new_params);
|
||||
}
|
||||
|
||||
return $self->_parameters;
|
||||
}
|
||||
|
||||
my %ENCODINGS = (
|
||||
'QUOTED-PRINTABLE' => {
|
||||
encode => sub {
|
||||
my $dec = shift || '';
|
||||
$dec =~ s/\n/\r\n/g;
|
||||
return MIME::QuotedPrint::encode( $dec, '' );
|
||||
},
|
||||
decode => sub {
|
||||
my $dec = MIME::QuotedPrint::decode( shift || '' );
|
||||
$dec =~ s/\r\n/\n/g;
|
||||
return $dec;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
=head2 decoded_value
|
||||
|
||||
Gets the value of this property, converted from the encoding specified
|
||||
in its encoding parameter. (That is, C<value> will return the encoded
|
||||
version; this will apply the encoding.) If the encoding is not
|
||||
specified or recognized, just returns the raw value.
|
||||
|
||||
=cut
|
||||
|
||||
sub decoded_value {
|
||||
my $self = shift;
|
||||
my $value = $self->value;
|
||||
my $encoding = uc( $self->parameters->{'ENCODING'} || "" );
|
||||
|
||||
if ( $ENCODINGS{$encoding} ) {
|
||||
return $ENCODINGS{$encoding}{'decode'}->($value);
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 encode $encoding
|
||||
|
||||
Calls C<decoded_value> to get the current decoded value, then encodes
|
||||
it in C<$encoding>, sets the value to that, and sets the encoding
|
||||
parameter to C<$encoding>. (C<$encoding> is first converted to upper
|
||||
case.)
|
||||
|
||||
If C<$encoding> is undef, deletes the encoding parameter and sets the
|
||||
value to the decoded value. Does nothing if the encoding is not
|
||||
recognized.
|
||||
|
||||
=cut
|
||||
|
||||
sub encode {
|
||||
my $self = shift;
|
||||
my $encoding = uc shift;
|
||||
|
||||
my $decoded_value = $self->decoded_value;
|
||||
|
||||
if ( not defined $encoding ) {
|
||||
$self->value($decoded_value);
|
||||
delete $self->parameters->{'ENCODING'};
|
||||
} elsif ( $ENCODINGS{$encoding} ) {
|
||||
$self->value( $ENCODINGS{$encoding}{'encode'}->($decoded_value) );
|
||||
$self->parameters->{'ENCODING'} = $encoding;
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 as_string ARGS
|
||||
|
||||
Returns the property formatted as a string (including trailing
|
||||
newline).
|
||||
|
||||
Takes named arguments:
|
||||
|
||||
=over
|
||||
|
||||
=item fold
|
||||
|
||||
Defaults to true. pass in a false value if you need to generate
|
||||
non-rfc-compliant calendars.
|
||||
|
||||
=item crlf
|
||||
|
||||
Defaults to C<\x0d\x0a>, per RFC 2445 spec. This option is primarily
|
||||
for backwards compatibility with version of this module prior to 0.16,
|
||||
which used C<\x0a>.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub as_string {
|
||||
my $self = shift;
|
||||
my %args = (
|
||||
fold => 1,
|
||||
crlf => Data::ICal::Entry->CRLF,
|
||||
@_
|
||||
);
|
||||
my $string
|
||||
= uc( $self->key )
|
||||
. $self->_parameters_as_string . ":"
|
||||
. $self->_value_as_string( $self->key )
|
||||
. $args{crlf};
|
||||
|
||||
# Assumption: the only place in an iCalendar that needs folding are property
|
||||
# lines
|
||||
if ( $args{'fold'} ) {
|
||||
return $self->_fold( $string, $args{crlf} );
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
=begin private
|
||||
|
||||
=head2 _value_as_string
|
||||
|
||||
Returns the property's value as a string. Comma and semicolon are not
|
||||
escaped when the value is recur type (the key is rrule).
|
||||
|
||||
Values are quoted according the iCal spec, unless this is in vCal 1.0
|
||||
mode.
|
||||
|
||||
=end private
|
||||
|
||||
=cut
|
||||
|
||||
sub _value_as_string {
|
||||
my $self = shift;
|
||||
my $key = shift;
|
||||
my $value = defined( $self->value() ) ? $self->value() : '';
|
||||
|
||||
unless ( $self->vcal10 ) {
|
||||
$value =~ s/\\/\\\\/gs;
|
||||
$value =~ s/;/\\;/gs unless lc($key) eq 'rrule';
|
||||
$value =~ s/,/\\,/gs unless lc($key) eq 'rrule';
|
||||
$value =~ s/\x0d?\x0a/\\n/gs;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
=begin private
|
||||
|
||||
=head2 _parameters_as_string
|
||||
|
||||
Returns the property's parameters as a string. Properties are sorted alphabetically
|
||||
to aid testing.
|
||||
|
||||
=end private
|
||||
|
||||
=cut
|
||||
|
||||
sub _parameters_as_string {
|
||||
my $self = shift;
|
||||
my $out = '';
|
||||
for my $name ( sort keys %{ $self->parameters } ) {
|
||||
my $value = $self->parameters->{$name};
|
||||
$out
|
||||
.= ';'
|
||||
. $name . '='
|
||||
. $self->_quoted_parameter_values(
|
||||
ref $value ? @$value : $value );
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
=begin private
|
||||
|
||||
=head2 _quoted_parameter_values @values
|
||||
|
||||
Quotes any of the values in C<@values> that need to be quoted and
|
||||
returns the quoted values joined by commas.
|
||||
|
||||
If any of the values contains a double-quote, erases it and emits a
|
||||
warning.
|
||||
|
||||
=end private
|
||||
|
||||
=cut
|
||||
|
||||
sub _quoted_parameter_values {
|
||||
my $self = shift;
|
||||
my @values = @_;
|
||||
|
||||
for my $val (@values) {
|
||||
if ( $val =~ /"/ ) {
|
||||
|
||||
# Get all the way back to the user's code
|
||||
local $Carp::CarpLevel = $Carp::CarpLevel + 1;
|
||||
carp "Invalid parameter value (contains double quote): $val";
|
||||
$val =~ tr/"//d;
|
||||
}
|
||||
}
|
||||
|
||||
return join ',', map { /[;,:]/ ? qq("$_") : $_ } @values;
|
||||
}
|
||||
|
||||
=begin private
|
||||
|
||||
=head2 _fold $string $crlf
|
||||
|
||||
Returns C<$string> folded with newlines and leading whitespace so that
|
||||
each line is at most 75 characters.
|
||||
|
||||
(Note that it folds at 75 characters, not 75 bytes as specified in the
|
||||
standard.)
|
||||
|
||||
If this is vCalendar 1.0 and encoded with QUOTED-PRINTABLE, does not
|
||||
fold at all.
|
||||
|
||||
=end private
|
||||
|
||||
=cut
|
||||
|
||||
sub _fold {
|
||||
my $self = shift;
|
||||
my $string = shift;
|
||||
my $crlf = shift;
|
||||
|
||||
my $quoted_printable = $self->vcal10
|
||||
&& uc( $self->parameters->{'ENCODING'} || '' ) eq 'QUOTED-PRINTABLE';
|
||||
|
||||
if ($quoted_printable) {
|
||||
|
||||
# In old vcal, quoted-printable properties have different folding rules.
|
||||
# But some interop tests suggest it's wiser just to not fold for vcal 1.0
|
||||
# at all (in quoted-printable).
|
||||
} else {
|
||||
my $pos = 0;
|
||||
|
||||
# Walk through the value, looking to replace 75 characters at
|
||||
# a time. We assign to pos() to update where to pick up for
|
||||
# the next match.
|
||||
while ( $string =~ s/\G(.{75})(?=.)/$1$crlf / ) {
|
||||
$pos += 75 + length($crlf);
|
||||
pos($string) = $pos;
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2005 - 2015, 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>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
||||
Reference in New Issue
Block a user