use v5.36; #use Feature::Compat::Class 0.07; use Object::Pad 0.78 qw(:experimental(init_expr)); package Object::Groupware::Event 0.01; class Object::Groupware::Event : isa(Object::Groupware); use utf8; use Log::Any qw( ); use Feature::Compat::Try; use DateTime::Locale; use Encode qw(decode_utf8); field $log = Log::Any->get_logger; field $entry : param; field $dt_locale; field $span; field $start : reader = $entry->start; field $end : reader = $entry->end; field $summary : reader = decode_utf8 $entry->summary; field $description : reader = decode_utf8 $entry->description || ''; field $location : reader = decode_utf8 $entry->_simple_property('location'); field $price : reader; field @attendees; field @attachments; ADJUST { if ( $self->dt_locale ) { $dt_locale = $self->dt_locale; $start->set_locale($dt_locale); $end->set_locale($dt_locale) if defined $end; } else { # we need the object regardless, to fetch CLDR patterns $dt_locale = DateTime::Locale->load('en_US'); } $start->set_locale( $self->dt_locale ); for ( $self->dt_time_zone || () ) { $start->set_time_zone($_); $end->set_time_zone($_) if defined $end; } $description =~ s/\n\n[Pp]ris:\s*((?!\n).+)\s*\z//m; $price = $1; if ( $entry->property('attendee') ) { for ( @{ $entry->property('attendee') } ) { push @attendees, decode_utf8( $_->parameters->{'CN'} ) || decode_utf8( $_->value =~ s/^mailto://r ); } } if ( $entry->property('attach') ) { for ( @{ $entry->property('attach') } ) { my $uri; try { $uri = URI->new( decode_utf8 $_->value ) } catch ($e) { $log->errorf( 'failed to parse URI %s: %s', $uri, $e ); next; } $uri->authority and $uri->host or next; push @attachments, $uri; } } $log->tracef( "Object %s contents:\n%s", __CLASS__, decode_utf8 $entry->as_string ); } method start_date { $start->strftime('%F') } method end_date { $end->strftime('%F') } method attendees { !!@attendees ? [@attendees] : undef } method attachments { !!@attachments ? [@attachments] : undef } method span () { return $span if defined($span); return $span = '' unless $end; require DateTime::Span; $span = DateTime::Span->from_datetimes( start => $start, before => $end ); return $span; } method datespan () { return ucfirst( $start->format_cldr( $dt_locale->date_format_medium() ) ) if $entry->all_day; return '' if !$span or $end->clone->truncate( to => 'day' ) eq $start->clone->truncate( to => 'day' ); return ucfirst( sprintf '%s - %s', $start->format_cldr( $dt_locale->date_format_medium() ), $end->format_cldr( $dt_locale->date_format_medium() ) ); } method timespan () { return '' if $span and $end->clone->truncate( to => 'day' ) ne $start->clone->truncate( to => 'day' ); return ucfirst( $start->format_cldr( $dt_locale->date_format_medium() ) ) if $entry->all_day; return $span = ucfirst( sprintf '%s-%s', $start->format_cldr( $dt_locale->datetime_format_medium() ), $end->format_cldr( $dt_locale->time_format_medium() ) ); } method time_brief () { return $self->datespan || ucfirst( $start->format_cldr( $dt_locale->datetime_format_medium() ) ); } 1;