File Coverage

blib/lib/EWS/Calendar/Item.pm
Criterion Covered Total %
statement 25 69 36.2
branch 0 12 0.0
condition n/a
subroutine 9 18 50.0
pod 1 7 14.2
total 35 106 33.0


line stmt bran cond sub pod time code
1             package EWS::Calendar::Item;
2             BEGIN {
3 1     1   23 $EWS::Calendar::Item::VERSION = '1.143070';
4             }
5 1     1   4 use Moose;
  1         1  
  1         7  
6              
7 1     1   7620 use Moose::Util::TypeConstraints;
  1         4  
  1         16  
8 1     1   4249 use DateTime::Format::ISO8601;
  1         34778  
  1         98  
9 1     1   14 use DateTime;
  1         2  
  1         17  
10 1     1   769 use HTML::Strip;
  1         6356  
  1         65  
11 1     1   10 use Encode;
  1         1  
  1         95  
12 1     1   420 use EWS::Calendar::Mailbox;
  1         4  
  1         982  
13              
14             has Start => (
15             is => 'ro',
16             isa => 'DateTime',
17             required => 1,
18             );
19              
20             has End => (
21             is => 'ro',
22             isa => 'DateTime',
23             required => 1,
24             );
25              
26             has TimeSpan => (
27             is => 'ro',
28             isa => 'Str',
29             lazy_build => 1,
30             );
31              
32             sub _build_TimeSpan {
33 0     0     my $self = shift;
34             # FIXME: plenty of edge cases we are not picking up on, yet
35              
36 0 0         if ($self->IsAllDayEvent) {
37 0 0         if ($self->Start->day == ($self->End->day - 1)) {
38 0           return sprintf '%s %s %s',
39             $self->Start->day, $self->Start->month_abbr,
40             $self->Start->year;
41             }
42             else {
43 0           return sprintf '%s %s - %s, %s',
44             $self->Start->month_abbr, $self->Start->day,
45             ($self->End->day - 1), $self->Start->year;
46             }
47             }
48             else {
49 0           return sprintf '%s %s %s %s - %s',
50             $self->Start->day, $self->Start->month_abbr,
51             $self->Start->year, $self->Start->strftime('%H:%M'),
52             $self->End->strftime('%H:%M');
53             }
54             }
55              
56             has Subject => (
57             is => 'ro',
58             isa => 'Str',
59             required => 1,
60             );
61              
62             has Body => (
63             is => 'ro',
64             isa => 'Str',
65             required => 0,
66             default => '',
67             );
68              
69 0     0 0   sub has_Body { return length ((shift)->Body) }
70              
71             has Location => (
72             is => 'ro',
73             isa => 'Str',
74             required => 0,
75             default => '',
76             );
77              
78 0     0 0   sub has_Location { return length ((shift)->Location) }
79              
80             has CalendarItemType => (
81             is => 'ro',
82             isa => enum([qw/Single Occurrence Exception/]),
83             required => 1,
84             );
85              
86 0     0 0   sub Type { (shift)->CalendarItemType }
87              
88 0     0 0   sub IsRecurring { return ((shift)->Type ne 'Single') }
89              
90             has Sensitivity => (
91             is => 'ro',
92             isa => enum([qw/Normal Personal Private Confidential/]),
93             required => 1,
94             );
95              
96             has DisplayTo => (
97             is => 'ro',
98             isa => 'ArrayRef[Str]',
99             required => 1,
100             );
101              
102 0     0 0   sub has_DisplayTo { return scalar @{(shift)->DisplayTo} }
  0            
103              
104             has Organizer => (
105             is => 'ro',
106             isa => 'EWS::Calendar::Mailbox',
107             required => 1,
108             );
109              
110             has IsCancelled => (
111             is => 'ro',
112             isa => 'Int', # bool
113             lazy_build => 1,
114             );
115              
116             sub _build_IsCancelled {
117 0     0     my $self = shift;
118 0           return ($self->AppointmentState & 0x0004);
119             }
120              
121             has AppointmentState => (
122             is => 'ro',
123             isa => 'Str', # bool - Was 'Int' but failed type constraint on 2012-06-20
124             required => 1,
125             );
126              
127             has LegacyFreeBusyStatus => (
128             is => 'ro',
129             isa => 'Str', # Was enum([qw/Free Tentative Busy OOF NoData/]),
130             required => 0,
131             default => 'NoData',
132             );
133              
134 0     0 0   sub Status { (shift)->LegacyFreeBusyStatus }
135              
136             has IsDraft => (
137             is => 'ro',
138             isa => 'Int', # bool
139             required => 1,
140             );
141              
142             has IsAllDayEvent => (
143             is => 'ro',
144             isa => 'Int', # bool
145             required => 0,
146             default => 0,
147             );
148              
149             has Sensitivity => (
150             is => 'ro',
151             isa => enum([qw/Normal Personal Private Confidential/]),
152             required => 1,
153             );
154              
155             has RequiredAttendees => (
156             is => 'ro',
157             isa => 'ArrayRef[EWS::Calendar::Mailbox]',
158             required => 0,
159             );
160              
161             has Duration => (
162             is => 'ro',
163             isa => 'Str',
164             required => 1,
165             );
166              
167             has OptionalAttendees => (
168             is => 'ro',
169             isa => 'ArrayRef[EWS::Calendar::Mailbox]',
170             required => 0,
171             );
172              
173             has UID => (
174             is => 'ro',
175             isa => 'Str',
176             required => 0,
177             default => '',
178             );
179              
180             sub BUILDARGS {
181 0     0 1   my ($class, @rest) = @_;
182 0 0         my $params = (scalar @rest == 1 ? $rest[0] : {@rest});
183              
184             # could coerce but this is always required, so do it here instead
185 0           $params->{'Start'} = DateTime::Format::ISO8601->parse_datetime($params->{'Start'});
186 0           $params->{'End'} = DateTime::Format::ISO8601->parse_datetime($params->{'End'});
187              
188             # fish data out of deep structure
189 0           $params->{'Organizer'} = EWS::Calendar::Mailbox->new($params->{'Organizer'}->{'Mailbox'});
190 0           $params->{'OptionalAttendees'} = [ map { EWS::Calendar::Mailbox->new($_->{'Mailbox'}) }
  0            
191 0           @{$params->{'OptionalAttendees'}->{Attendee}} ];
192 0           $params->{'RequiredAttendees'} = [ map { EWS::Calendar::Mailbox->new($_->{'Mailbox'}) }
  0            
193 0           @{$params->{'RequiredAttendees'}->{Attendee}} ];
194 0           $params->{'Body'} = $params->{'Body'}->{'_'};
195              
196             # rework semicolon separated list into array, and also remove Organizer
197 0           $params->{'DisplayTo'} = [ grep {$_ ne $params->{'Organizer'}->{'Name'}}
  0            
198             split m/; /, $params->{'DisplayTo'} ];
199              
200             # set Perl's encoding flag on all data coming from Exchange
201             # also strip HTML tags from incoming data
202 0           my $hs = HTML::Strip->new(emit_spaces => 0);
203              
204 0           foreach my $key (keys %$params) {
205 0 0         if ( $key =~ /RequiredAttendees|OptionalAttendees|IsDraft|IsAllDayEvent/ ) {
    0          
    0          
206 0           next;
207             }
208             elsif (ref $params->{$key} eq 'ARRAY') {
209 0           $params->{$key} = [
210 0           map {$hs->parse($_)}
211 0           map {Encode::encode('utf8', $_)}
212 0           @{ $params->{$key} }
213             ];
214             }
215             elsif (ref $params->{$key}) {
216 0           next;
217             }
218             else {
219 0           $params->{$key} = $hs->parse(Encode::encode('utf8', $params->{$key}));
220             }
221             }
222              
223             # the Body is usually a mess if created by Outlook
224 0           $params->{'Body'} =~ s/^\s+//;
225 0           $params->{'Body'} =~ s/\s+$//;
226 0           $params->{'Body'} =~ s/\n{3,}/\n\n/g;
227 0           $params->{'Body'} =~ s/ {2,}/ /g;
228              
229 0           return $params;
230             }
231              
232             __PACKAGE__->meta->make_immutable;
233 1     1   10 no Moose;
  1         1  
  1         17  
234             1;