aboutsummaryrefslogtreecommitdiff
path: root/lib/Object/Groupware/Event.pm
blob: a7f584250ffdf5a763ba386392efe700c0ef7bc6 (plain)
  1. use v5.36;
  2. #use Feature::Compat::Class 0.07;
  3. use Object::Pad 0.78;
  4. package Object::Groupware::Event 0.01;
  5. class Object::Groupware::Event : isa(Object::Groupware);
  6. use utf8;
  7. use Log::Any qw( );
  8. use Feature::Compat::Try;
  9. use DateTime::Locale;
  10. use Encode qw(decode_utf8);
  11. field $log = undef;
  12. field $entry : param;
  13. field $dt_locale;
  14. field $span;
  15. field $start : reader = undef;
  16. field $end : reader = undef;
  17. field $summary : reader = undef;
  18. field $description : reader = undef;
  19. field $location : reader = undef;
  20. field $price : reader;
  21. field @attendees;
  22. field @attachments;
  23. ADJUST {
  24. # TODO: use Object::Pad 0.07 and move these to field initializer
  25. $log //= Log::Any->get_logger;
  26. $start //= $entry->start;
  27. $end //= $entry->end;
  28. $summary //= decode_utf8 $entry->summary;
  29. $description //= decode_utf8 $entry->description || '';
  30. $location //= decode_utf8 $entry->_simple_property('location');
  31. if ( $self->dt_locale ) {
  32. $dt_locale = $self->dt_locale;
  33. $start->set_locale($dt_locale);
  34. $end->set_locale($dt_locale) if defined $end;
  35. }
  36. else {
  37. # we need the object regardless, to fetch CLDR patterns
  38. $dt_locale = DateTime::Locale->load('en_US');
  39. }
  40. $start->set_locale( $self->dt_locale );
  41. for ( $self->dt_time_zone || () ) {
  42. $start->set_time_zone($_);
  43. $end->set_time_zone($_) if defined $end;
  44. }
  45. $description =~ s/\n\n[Pp]ris:\s*((?!\n).+)\s*\z//m;
  46. $price = $1;
  47. if ( $entry->property('attendee') ) {
  48. for ( @{ $entry->property('attendee') } ) {
  49. push @attendees, decode_utf8( $_->parameters->{'CN'} )
  50. || decode_utf8( $_->value =~ s/^mailto://r );
  51. }
  52. }
  53. if ( $entry->property('attach') ) {
  54. for ( @{ $entry->property('attach') } ) {
  55. my $uri;
  56. try { $uri = URI->new( decode_utf8 $_->value ) }
  57. catch ($e) {
  58. $log->errorf( 'failed to parse URI %s: %s', $uri, $e );
  59. next;
  60. }
  61. $uri->authority and $uri->host
  62. or next;
  63. push @attachments, $uri;
  64. }
  65. }
  66. $log->tracef(
  67. "Object %s contents:\n%s", __CLASS__,
  68. decode_utf8 $entry->as_string
  69. );
  70. }
  71. method start_date { $start->strftime('%F') }
  72. method end_date { $end->strftime('%F') }
  73. method attendees { !!@attendees ? [@attendees] : undef }
  74. method attachments { !!@attachments ? [@attachments] : undef }
  75. method span ()
  76. {
  77. return $span
  78. if defined($span);
  79. return $span = ''
  80. unless $end;
  81. require DateTime::Span;
  82. $span = DateTime::Span->from_datetimes( start => $start, before => $end );
  83. return $span;
  84. }
  85. method datespan ()
  86. {
  87. return ucfirst( $start->format_cldr( $dt_locale->date_format_medium() ) )
  88. if $entry->all_day;
  89. return ''
  90. if !$span
  91. or $end->clone->truncate( to => 'day' ) eq
  92. $start->clone->truncate( to => 'day' );
  93. return ucfirst(
  94. sprintf '%s - %s',
  95. $start->format_cldr( $dt_locale->date_format_medium() ),
  96. $end->format_cldr( $dt_locale->date_format_medium() )
  97. );
  98. }
  99. method timespan ()
  100. {
  101. return ''
  102. if $span
  103. and $end->clone->truncate( to => 'day' ) ne
  104. $start->clone->truncate( to => 'day' );
  105. return ucfirst( $start->format_cldr( $dt_locale->date_format_medium() ) )
  106. if $entry->all_day;
  107. return $span = ucfirst(
  108. sprintf '%s-%s',
  109. $start->format_cldr( $dt_locale->datetime_format_medium() ),
  110. $end->format_cldr( $dt_locale->time_format_medium() )
  111. );
  112. }
  113. method time_brief ()
  114. {
  115. return $self->datespan
  116. || ucfirst(
  117. $start->format_cldr( $dt_locale->datetime_format_medium() ) );
  118. }
  119. 1;