line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl -w |
2
|
|
|
|
|
|
|
# vi:sts=4:shiftwidth=4 |
3
|
|
|
|
|
|
|
# -*- Mode: perl -*- |
4
|
|
|
|
|
|
|
#====================================================================== |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# This package is free software and is provided "as is" without |
7
|
|
|
|
|
|
|
# express or implied warranty. It may be used, redistributed and/or |
8
|
|
|
|
|
|
|
# modified under the same terms as perl itself. ( Either the Artistic |
9
|
|
|
|
|
|
|
# License or the GPL. ) |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# $Id: Todo.pm,v 1.16 2001/07/09 20:52:57 lotr Exp $ |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# (C) COPYRIGHT 2000-2001, Reefknot developers. |
14
|
|
|
|
|
|
|
# |
15
|
|
|
|
|
|
|
# See the AUTHORS file included in the distribution for a full list. |
16
|
|
|
|
|
|
|
#====================================================================== |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 NAME |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Net::ICal::Todo -- Todo class |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=cut |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
package Net::ICal::Todo; |
25
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
48
|
|
26
|
|
|
|
|
|
|
|
27
|
1
|
|
|
1
|
|
7
|
use base qw(Net::ICal::ETJ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
112
|
|
28
|
|
|
|
|
|
|
|
29
|
1
|
|
|
1
|
|
6
|
use Net::ICal::Util qw(add_validation_error); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
444
|
|
30
|
|
|
|
|
|
|
# TODO: work on this documentation. |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 SYNOPSIS |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
use Net::ICal::Todo; |
35
|
|
|
|
|
|
|
my $c = new Net::ICal::Todo(); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=begin testing |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use Net::ICal::Todo; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=end testing |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 DESCRIPTION |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Net::ICal::Todo represents something someone needs to get done. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head1 BASIC METHODS |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head2 new($args) |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Construct a new Todo. Parameters are in a hash. |
52
|
|
|
|
|
|
|
Meaningful parameters are: |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head2 REQUIRED |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=over 4 |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item * organizer - a Net::ICal::Attendee for who's organizing this meeting. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=back |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head2 OPTIONAL |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=over 4 |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=item * dtstart - a Net::ICal::Time for when this Todo starts. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=item * duration - a Net::ICal::Duration; how long this thing will take |
69
|
|
|
|
|
|
|
to do. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=item * alarms - an array of Net::ICal::Alarm objects; reminders about |
72
|
|
|
|
|
|
|
doing this item. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item * class - PUBLIC, PRIVATE, or CONFIDENTIAL - the creator's intention |
75
|
|
|
|
|
|
|
about who should see this Todo. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=item * created - a Net::ICal::Time saying when this object was created. |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item * description - a hash with at least a content key, maybe an altrep |
80
|
|
|
|
|
|
|
and a language key. Content is a description of this Todo. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item * dtstamp - when this Todo was created. Will be set to the current |
83
|
|
|
|
|
|
|
time unless otherwise specified. |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=item * geo - a pair of real numbers--- the latitude and longitude of |
86
|
|
|
|
|
|
|
this Todo. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item * last_modified - a Net::ICal::Time specifying the last time this |
89
|
|
|
|
|
|
|
object was changed. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=item * location - a hash for where this Todo is taking place. The |
92
|
|
|
|
|
|
|
content key points to a string about the location; the altrep key gives |
93
|
|
|
|
|
|
|
an alternate representation, for example a URL. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=item * priority - a number from 0 (undefined) to 1 (highest) to |
96
|
|
|
|
|
|
|
9 (lowest) representing how important this event is. |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item * status - NEEDS-ACTION, IN-PROGRESS, COMPLETED, or CANCELLED; |
99
|
|
|
|
|
|
|
the status of this todo item. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=item * summary - a one-line summary of this Todo. If you need more |
102
|
|
|
|
|
|
|
space, use the description parameter. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item * uid - a globally unique identifier for this event. Will be created |
105
|
|
|
|
|
|
|
automagically. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item * url - a URL for this Todo. Optional. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=item * attach - a Net::ICal::Attach - attached file for this Todo. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=item * attendee - who's going to be at this meeting; an array of |
112
|
|
|
|
|
|
|
Net::ICal::Attendee objects. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item * categories - what categories this event falls into. Make up |
115
|
|
|
|
|
|
|
your own categories. Optional. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=item * comment - a hash like that for description (above), comments |
118
|
|
|
|
|
|
|
on this Todo item. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=item * contact - a string describing who to contact about this Todo. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=item * request_status - how successful we've been at scheduling this Todo |
123
|
|
|
|
|
|
|
so far. Values can be integers separated by periods. 1.x.y is a preliminary |
124
|
|
|
|
|
|
|
success, 2.x.y is a complete successful request, 3.x.y is a failed request |
125
|
|
|
|
|
|
|
because of bad iCal format, 4.x.y is a calendar server failure. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=item * related_to - an array of other Event, Todo, or Journal objects this |
128
|
|
|
|
|
|
|
Todo is related to. |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=item * resources - resources (such as an overhead projector) required for |
131
|
|
|
|
|
|
|
doing this task. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=item * sequence - an integer that starts at 0 when this object is |
134
|
|
|
|
|
|
|
created and is incremented every time the object is changed. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=back |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 RECURRING TASKS |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=over 4 |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=item * recurrence_id - if this task occurs multiple times, which occurrence of |
143
|
|
|
|
|
|
|
it is this particular task? |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=item * rdate - an array of Net::ICal::Time objects describing repeated occurrences |
146
|
|
|
|
|
|
|
of this task. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=item * rrule - an array of Net::ICal::Recurrence objects telling when |
149
|
|
|
|
|
|
|
this task repeats. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=item * exdate - a Net::ICal::Time giving a single-date exception to a |
152
|
|
|
|
|
|
|
recurring task. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=item * exrule - an array of Net::ICal::Recurrence objects giving a |
155
|
|
|
|
|
|
|
recurring exception to a recurring task. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=back |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=for testing |
160
|
|
|
|
|
|
|
ok($c = Net::ICal::Todo->new , "Simple creation should return an object"); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=cut |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub new { |
165
|
0
|
|
|
0
|
1
|
0
|
my ($class, %args) = @_; |
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
0
|
my $self = &_create ($class, %args); |
168
|
0
|
0
|
|
|
|
0
|
return undef unless (defined $self); |
169
|
0
|
|
|
|
|
0
|
$self->_init; |
170
|
0
|
0
|
|
|
|
0
|
return undef unless ($self->validate); |
171
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
0
|
return $self; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=pod |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head2 $class->validate |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Validates the properties of a Todo. Returns 1 for success, undef for |
180
|
|
|
|
|
|
|
failure. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
TODO: make sure that this object has the bare minimum requirements |
183
|
|
|
|
|
|
|
specified by the RFC. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=for testing |
186
|
|
|
|
|
|
|
ok( $c->validate , "Simple todo should pass"); |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=cut |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub validate { |
191
|
12
|
|
|
12
|
1
|
21
|
my ($self) = @_; |
192
|
|
|
|
|
|
|
|
193
|
12
|
50
|
66
|
|
|
65
|
if (defined $self->due and $self->duration) { |
194
|
0
|
|
|
|
|
0
|
add_validation_error ($self, "Can't have both due and duration in one Todo"); |
195
|
|
|
|
|
|
|
} |
196
|
12
|
100
|
66
|
|
|
448
|
if ($self->dtstart and $self->due) { # 4.8.2.3 |
197
|
1
|
|
|
|
|
54
|
my $foo = $self->dtstart->compare ($self->due); |
198
|
1
|
50
|
|
|
|
76
|
if ($self->dtstart->compare ($self->due) > 0) { |
199
|
1
|
|
|
|
|
53
|
add_validation_error ($self, "the due time must not be earlier than the dtstart time"); |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
} |
202
|
12
|
100
|
66
|
|
|
317
|
if ($self->completed and $self->completed !~ /Z$/) { # 4.8.2.1 |
203
|
2
|
|
|
|
|
123
|
add_validation_error ($self, "The completed date/time MUST be a UTC value"); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
12
|
|
|
|
|
315
|
return $self->SUPER::validate; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=pod |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=head1 DEVELOPER METHODS |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
The following methods are probably not of interest to you unless you are |
214
|
|
|
|
|
|
|
a Reefknot developer. |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=head2 $c->_create(%args) |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Class::MethodMapper creation routine. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=for testing |
221
|
|
|
|
|
|
|
#ok($c->_create(%args), "Simple _create call"); |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=cut |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub _create { |
226
|
12
|
|
|
12
|
|
25
|
my ($class, %args) = @_; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# don't pass in the %args just yet, as we don't have a complete |
229
|
|
|
|
|
|
|
# map |
230
|
12
|
|
|
|
|
58
|
my $self = $class->SUPER::_create ('VTODO'); |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# add new elements to the map. |
233
|
12
|
|
|
|
|
136
|
my $map = { |
234
|
|
|
|
|
|
|
completed => { # 4.8.2.1 |
235
|
|
|
|
|
|
|
type => 'parameter', |
236
|
|
|
|
|
|
|
doc => 'the time this to-do was completed', |
237
|
|
|
|
|
|
|
domain => 'ref', |
238
|
|
|
|
|
|
|
options => 'Net::ICal::Time', |
239
|
|
|
|
|
|
|
value => undef, |
240
|
|
|
|
|
|
|
}, |
241
|
|
|
|
|
|
|
percent_complete => { # RFC2445 4.8.1.8 - optional in a VTODO |
242
|
|
|
|
|
|
|
type => 'parameter', |
243
|
|
|
|
|
|
|
doc => 'how completed this task is', |
244
|
|
|
|
|
|
|
value => undef, |
245
|
|
|
|
|
|
|
}, |
246
|
|
|
|
|
|
|
due => { # RFC2445 4.8.2.3 - optional in a VTODO |
247
|
|
|
|
|
|
|
type => 'parameter', |
248
|
|
|
|
|
|
|
doc => 'when this has to be done', |
249
|
|
|
|
|
|
|
domain => 'ref', |
250
|
|
|
|
|
|
|
options => 'Net::ICal::Time', |
251
|
|
|
|
|
|
|
value => undef, |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
}, |
254
|
|
|
|
|
|
|
}; |
255
|
|
|
|
|
|
|
# add the extra map item definitions |
256
|
12
|
|
|
|
|
62
|
$self->set_map (%$map); |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
# now fill in the map values |
259
|
12
|
|
|
|
|
208
|
$self->set (%args); |
260
|
|
|
|
|
|
|
|
261
|
12
|
|
|
|
|
83
|
return $self; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
1; |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head1 SEE ALSO |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
More documentation pointers can be found in L. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=cut |