| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
|
2
|
|
|
|
|
|
|
# Date::HolidayParser |
|
3
|
|
|
|
|
|
|
# A parser of ~/.holiday-style files. |
|
4
|
|
|
|
|
|
|
# The format is based off of the holiday files found bundled |
|
5
|
|
|
|
|
|
|
# with the plan program, not any official spec. This because no |
|
6
|
|
|
|
|
|
|
# official spec could be found. |
|
7
|
|
|
|
|
|
|
# Copyright (C) Eskild Hustvedt 2006, 2007, 2008, 2010 |
|
8
|
|
|
|
|
|
|
# |
|
9
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify it |
|
10
|
|
|
|
|
|
|
# under the same terms as Perl itself. There is NO warranty; |
|
11
|
|
|
|
|
|
|
# not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
12
|
|
|
|
|
|
|
# |
|
13
|
|
|
|
|
|
|
# This is the iCalendar component, which emulates a DP::iCalendar-like interface |
|
14
|
|
|
|
|
|
|
# in order to make it easier to use for users familiar with iCalendar, and |
|
15
|
|
|
|
|
|
|
# make it compatible with DP::iCalendar::Manager. |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
package Date::HolidayParser::iCalendar; |
|
18
|
|
|
|
|
|
|
|
|
19
|
2
|
|
|
2
|
|
47857
|
use Any::Moose; |
|
|
2
|
|
|
|
|
95660
|
|
|
|
2
|
|
|
|
|
15
|
|
|
20
|
2
|
|
|
2
|
|
2942
|
use Date::HolidayParser; |
|
|
2
|
|
|
|
|
10
|
|
|
|
2
|
|
|
|
|
83
|
|
|
21
|
2
|
|
|
2
|
|
23
|
use constant { true => 1, false => undef }; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
2588
|
|
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our $VERSION = 0.41; |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
extends 'Date::HolidayParser'; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
has '_UID_List' => ( |
|
28
|
|
|
|
|
|
|
is => 'rw', |
|
29
|
|
|
|
|
|
|
isa => 'HashRef', |
|
30
|
|
|
|
|
|
|
default => sub { {} }, |
|
31
|
|
|
|
|
|
|
); |
|
32
|
|
|
|
|
|
|
has '_iCal_cache' => ( |
|
33
|
|
|
|
|
|
|
is => 'rw', |
|
34
|
|
|
|
|
|
|
isa => 'HashRef', |
|
35
|
|
|
|
|
|
|
default => sub { {} }, |
|
36
|
|
|
|
|
|
|
); |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# -- Public methods -- |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# Purpose: Get an iCalendar hash with holiday info matching the supplied UID |
|
41
|
|
|
|
|
|
|
# Usage: get_info(UID); |
|
42
|
|
|
|
|
|
|
sub get_info |
|
43
|
|
|
|
|
|
|
{ |
|
44
|
72
|
|
|
72
|
1
|
110
|
my $self = shift; |
|
45
|
72
|
|
|
|
|
95
|
my $UID = shift; |
|
46
|
72
|
100
|
|
|
|
545
|
return($self->_UID_List->{$UID}) if $self->_UID_List->{$UID}; |
|
47
|
3
|
|
|
|
|
14
|
return(false); |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Purpose: List events in said year, on said month and day |
|
51
|
|
|
|
|
|
|
# Usage: obj->list_events(year?,month?,day?); |
|
52
|
|
|
|
|
|
|
# year is required, others are optional. |
|
53
|
|
|
|
|
|
|
# |
|
54
|
|
|
|
|
|
|
# This is the primary API for this module. It does only wrap the other |
|
55
|
|
|
|
|
|
|
# methods, but provides a cleaner interface for new code. |
|
56
|
|
|
|
|
|
|
sub list_events |
|
57
|
|
|
|
|
|
|
{ |
|
58
|
24
|
|
|
24
|
1
|
8114
|
my ($self,$Year,$Month,$Day) = @_; |
|
59
|
24
|
50
|
|
|
|
79
|
if(not defined $Year) |
|
60
|
|
|
|
|
|
|
{ |
|
61
|
0
|
|
|
|
|
0
|
croak('Requried parameter "Year" not supplied'); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
24
|
100
|
|
|
|
64
|
if(defined $Day) |
|
|
|
100
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
{ |
|
65
|
9
|
|
|
|
|
26
|
return $self->get_timeinfo($Year,$Month,$Day,'DAY'); |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
elsif(defined $Month) |
|
68
|
|
|
|
|
|
|
{ |
|
69
|
12
|
|
|
|
|
35
|
return $self->get_monthinfo($Year,$Month); |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
else |
|
72
|
|
|
|
|
|
|
{ |
|
73
|
3
|
|
|
|
|
10
|
return $self->get_months($Year); |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# Purpose: Get information for the supplied month (list of days there are events) |
|
78
|
|
|
|
|
|
|
# Usage: my $TimeRef = $object->get_monthinfo(YEAR,MONTH,DAY); |
|
79
|
|
|
|
|
|
|
sub get_monthinfo |
|
80
|
|
|
|
|
|
|
{ |
|
81
|
24
|
|
|
24
|
0
|
8803
|
my($self, $Year, $Month) = @_; # TODO: verify that they are set |
|
82
|
24
|
|
|
|
|
80
|
$self->get($Year); |
|
83
|
24
|
|
|
|
|
33
|
my @Array; |
|
84
|
24
|
50
|
33
|
|
|
184
|
if(defined($self->_iCal_cache->{$Year}) and defined($self->_iCal_cache->{$Year}{$Month})){ |
|
85
|
24
|
|
|
|
|
33
|
@Array = sort keys(%{$self->_iCal_cache->{$Year}{$Month}}); |
|
|
24
|
|
|
|
|
160
|
|
|
86
|
|
|
|
|
|
|
} |
|
87
|
24
|
|
|
|
|
144
|
return(\@Array); |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# Purpose: Get information for the supplied date (list of times in the day there are events) |
|
91
|
|
|
|
|
|
|
# Usage: my $TimeRef = $object->get_dateinfo(YEAR,MONTH,DAY); |
|
92
|
|
|
|
|
|
|
sub get_dateinfo |
|
93
|
|
|
|
|
|
|
{ |
|
94
|
6
|
|
|
6
|
0
|
1358
|
my($self, $Year, $Month, $Day) = @_; # TODO: verify that they are set |
|
95
|
6
|
|
|
|
|
21
|
$self->get($Year); |
|
96
|
6
|
|
|
|
|
9
|
my @Array; |
|
97
|
6
|
100
|
33
|
|
|
80
|
if(defined($self->_iCal_cache->{$Year}) and defined($self->_iCal_cache->{$Year}{$Month}) and defined($self->_iCal_cache->{$Year}{$Month}{$Day})) { |
|
|
|
|
66
|
|
|
|
|
|
98
|
3
|
|
|
|
|
6
|
@Array = sort keys(%{$self->_iCal_cache->{$Year}{$Month}{$Day}}); |
|
|
3
|
|
|
|
|
20
|
|
|
99
|
|
|
|
|
|
|
} |
|
100
|
6
|
|
|
|
|
34
|
return(\@Array); |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# Purpose: Return an empty array, unsupported. |
|
104
|
|
|
|
|
|
|
# Usage: my $UIDRef = $object->get_timeinfo(YEAR,MONTH,DAY,TIME); |
|
105
|
|
|
|
|
|
|
sub get_timeinfo |
|
106
|
|
|
|
|
|
|
{ |
|
107
|
18
|
|
|
18
|
0
|
35
|
my($self, $Year, $Month, $Day,$Time) = @_; |
|
108
|
|
|
|
|
|
|
|
|
109
|
18
|
50
|
|
|
|
43
|
return(undef) if not $Time eq 'DAY'; |
|
110
|
|
|
|
|
|
|
|
|
111
|
18
|
|
|
|
|
58
|
$self->get($Year); |
|
112
|
|
|
|
|
|
|
|
|
113
|
18
|
100
|
33
|
|
|
209
|
if( defined($self->_iCal_cache->{$Year}) and |
|
|
|
|
66
|
|
|
|
|
|
114
|
|
|
|
|
|
|
defined($self->_iCal_cache->{$Year}{$Month}) and |
|
115
|
|
|
|
|
|
|
defined($self->_iCal_cache->{$Year}{$Month}{$Day}) |
|
116
|
|
|
|
|
|
|
) |
|
117
|
|
|
|
|
|
|
{ |
|
118
|
12
|
|
|
|
|
89
|
return($self->_iCal_cache->{$Year}{$Month}{$Day}{$Time}); |
|
119
|
|
|
|
|
|
|
} |
|
120
|
6
|
|
|
|
|
27
|
return([]); |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
# Purpose: Get a list of months which have events (those with *only* recurring not counted) |
|
124
|
|
|
|
|
|
|
# Usage: my $ArrayRef = $object->get_months(YEAR); |
|
125
|
|
|
|
|
|
|
sub get_months |
|
126
|
|
|
|
|
|
|
{ |
|
127
|
6
|
|
|
6
|
0
|
12
|
my ($self, $Year) = @_; |
|
128
|
6
|
|
|
|
|
33
|
$self->get($Year); |
|
129
|
6
|
|
|
|
|
7
|
my @Array = sort keys(%{$self->_iCal_cache->{$Year}}); |
|
|
6
|
|
|
|
|
54
|
|
|
130
|
6
|
|
|
|
|
43
|
return(\@Array); |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# Purpose: Check if there is an holiday event with the supplied UID |
|
134
|
|
|
|
|
|
|
# Usage: $bool = $object->exists($UID); |
|
135
|
|
|
|
|
|
|
sub exists |
|
136
|
|
|
|
|
|
|
{ |
|
137
|
36
|
|
|
36
|
0
|
47068
|
my $self = shift; |
|
138
|
36
|
|
|
|
|
62
|
my $UID = shift; |
|
139
|
36
|
100
|
|
|
|
284
|
return(true) if defined($self->_UID_List->{$UID}); |
|
140
|
3
|
|
|
|
|
12
|
return(false); |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# -- Unsupported or dummy methods, here for compatibility -- |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# Purpose: Return an empty array, unsupported. |
|
146
|
|
|
|
|
|
|
# Usage: my $ArrayRef = $object->get_years(); |
|
147
|
|
|
|
|
|
|
sub get_years |
|
148
|
|
|
|
|
|
|
{ |
|
149
|
3
|
|
|
3
|
0
|
4293
|
return([]); |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# -- DP::iCalendar compatibility code -- |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Used by DP::iCalendar::Manager to set the prodid in output iCalendar files. |
|
155
|
|
|
|
|
|
|
# We can't output iCalendar files, so we just ignore calls to it. |
|
156
|
3
|
|
|
3
|
0
|
6
|
sub set_prodid { } |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Purpose: Return manager information |
|
159
|
|
|
|
|
|
|
# Usage: get_manager_version(); |
|
160
|
|
|
|
|
|
|
sub get_manager_version |
|
161
|
|
|
|
|
|
|
{ |
|
162
|
6
|
|
|
6
|
0
|
2214
|
my $self = shift; |
|
163
|
6
|
|
|
|
|
29
|
return('01_capable'); |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# Purpose: Return manager capability information |
|
167
|
|
|
|
|
|
|
# Usage: get_manager_capabilities |
|
168
|
|
|
|
|
|
|
sub get_manager_capabilities |
|
169
|
|
|
|
|
|
|
{ |
|
170
|
|
|
|
|
|
|
# All capabilites as of 01_capable |
|
171
|
6
|
|
|
6
|
0
|
35
|
return(['LIST_DPI',]) |
|
172
|
|
|
|
|
|
|
} |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# -- Private methods -- |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# Purpose: Wraps _addParsedEvent in Date::HolidayParser so that an iCalendar version |
|
178
|
|
|
|
|
|
|
# is also created at the same time. |
|
179
|
|
|
|
|
|
|
around '_addParsedEvent' => sub |
|
180
|
|
|
|
|
|
|
{ |
|
181
|
|
|
|
|
|
|
my $orig = shift; |
|
182
|
|
|
|
|
|
|
my $self = shift; |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
my($FinalParsing,$final_mon,$final_mday,$HolidayName,$holidayType,$FinalYDay,$PosixYear) = @_; |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
my $UID = $self->_event_to_iCalendar($FinalYDay,$PosixYear,$HolidayName); |
|
187
|
|
|
|
|
|
|
my $Year = $PosixYear+1900; |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
if(not $self->_iCal_cache->{$Year}->{$final_mon}{$final_mday}{'DAY'}) |
|
190
|
|
|
|
|
|
|
{ |
|
191
|
|
|
|
|
|
|
$self->_iCal_cache->{$Year}->{$final_mon}{$final_mday}{'DAY'} = []; |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
push(@{$self->_iCal_cache->{$Year}->{$final_mon}{$final_mday}{'DAY'}}, $UID); |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
return $self->$orig(@_); |
|
196
|
|
|
|
|
|
|
}; |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Purpose: Generate an iCalendar entry |
|
199
|
|
|
|
|
|
|
# Usage: this->_event_to_iCalendar(UNIXTIME, NAME); |
|
200
|
|
|
|
|
|
|
sub _event_to_iCalendar |
|
201
|
|
|
|
|
|
|
{ |
|
202
|
44
|
|
|
44
|
|
56
|
my $self = shift; |
|
203
|
44
|
|
|
|
|
56
|
my $FinalYDay = shift; |
|
204
|
44
|
|
|
|
|
57
|
my $PosixYear = shift; |
|
205
|
44
|
|
|
|
|
54
|
my $name = shift; |
|
206
|
44
|
|
|
|
|
252
|
$name =~ s/\s/-/g; |
|
207
|
|
|
|
|
|
|
|
|
208
|
44
|
|
|
|
|
492
|
my $unixtime = POSIX::mktime(0, 0, 0, $FinalYDay, 0, $PosixYear); |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Generate the UID of the event, this is simply a |
|
211
|
44
|
|
|
|
|
132
|
my $sum = unpack('%32C*', $name); |
|
212
|
|
|
|
|
|
|
# This should be unique enough for our needs. |
|
213
|
|
|
|
|
|
|
# We don't want it to be random, because if someone copies the events to their |
|
214
|
|
|
|
|
|
|
# own calendar, we want DP::iCalendar::Manager to fetch the information from |
|
215
|
|
|
|
|
|
|
# the changed calendar, instead of from the HolidayParser object. |
|
216
|
44
|
|
|
|
|
123
|
my $UID = 'D-HP-ICS-'.$FinalYDay.'-'.$PosixYear.'-'.$sum; |
|
217
|
|
|
|
|
|
|
|
|
218
|
44
|
|
|
|
|
85
|
$self->_UID_List->{$UID} = { |
|
219
|
|
|
|
|
|
|
UID => $UID, |
|
220
|
|
|
|
|
|
|
DTSTART => iCal_ConvertFromUnixTime($unixtime), |
|
221
|
|
|
|
|
|
|
DTEND => iCal_ConvertFromUnixTime($unixtime+86390), # Yes, this is purposefully not 86400 |
|
222
|
|
|
|
|
|
|
SUMMARY => $name, |
|
223
|
|
|
|
|
|
|
}; |
|
224
|
44
|
|
|
|
|
138
|
return($UID); |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# The following three functions are originally from DP::iCalendar |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
# Purpose: Generate an iCalendar date-time from multiple values |
|
230
|
|
|
|
|
|
|
# Usage: my $iCalDateTime = iCal_GenDateTime(YEAR, MONTH, DAY, TIME); |
|
231
|
|
|
|
|
|
|
sub iCal_GenDateTime { |
|
232
|
|
|
|
|
|
|
# NOTE: This version ignores $Time because it isn't used in HolidayParser |
|
233
|
88
|
|
|
88
|
0
|
152
|
my ($Year, $Month, $Day, $Time) = @_; |
|
234
|
|
|
|
|
|
|
# Fix the month and day |
|
235
|
88
|
|
|
|
|
150
|
my $iCalMonth = _PrefixZero($Month); |
|
236
|
88
|
|
|
|
|
157
|
my $iCalDay = _PrefixZero($Day); |
|
237
|
88
|
|
|
|
|
552
|
return("$Year$iCalMonth$iCalDay"); |
|
238
|
|
|
|
|
|
|
} |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# Purpose: Generate an iCalendar date-time string from a UNIX time string |
|
241
|
|
|
|
|
|
|
# Usage: my $iCalDateTime = iCal_ConvertFromUnixTime(UNIX TIME); |
|
242
|
|
|
|
|
|
|
sub iCal_ConvertFromUnixTime { |
|
243
|
88
|
|
|
88
|
0
|
115
|
my $UnixTime = shift; |
|
244
|
88
|
|
|
|
|
605
|
my ($realsec,$realmin,$realhour,$realmday,$realmonth,$realyear,$realwday,$realyday,$realisdst) = localtime($UnixTime); |
|
245
|
88
|
|
|
|
|
155
|
$realyear += 1900; # Fix the year |
|
246
|
88
|
|
|
|
|
98
|
$realmonth++; # Fix the month |
|
247
|
|
|
|
|
|
|
# Return data from iCal_GenDateTime |
|
248
|
88
|
|
|
|
|
397
|
return(iCal_GenDateTime($realyear,$realmonth,$realmday,"$realhour:$realmin")); |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Purpose: Prefix a "0" to a number if it is only one digit. |
|
252
|
|
|
|
|
|
|
# Usage: my $NewNumber = PrefixZero(NUMBER); |
|
253
|
|
|
|
|
|
|
sub _PrefixZero { |
|
254
|
176
|
100
|
|
176
|
|
559
|
if ($_[0] =~ /^\d$/) { |
|
255
|
88
|
|
|
|
|
221
|
return("0$_[0]"); |
|
256
|
|
|
|
|
|
|
} |
|
257
|
88
|
|
|
|
|
180
|
return($_[0]); |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
# End of Date::HolidayParser::iCalendar |
|
261
|
|
|
|
|
|
|
1; |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
__END__ |