diff options
author | Matthew Somerville <matthew@mysociety.org> | 2020-06-16 16:25:07 +0100 |
---|---|---|
committer | M Somerville <matthew-github@dracos.co.uk> | 2020-11-11 10:29:20 +0000 |
commit | c0f9b0dcb1fc7cecb4b98ad82715600f73707bf0 (patch) | |
tree | 52631c2abc794598fc1b99bc436b7647f103a14a | |
parent | 613f45c6514ace275b3a49a5d50f7b83ed536b5f (diff) |
[Waste] ICal generation, with Data::ICal.
-rw-r--r-- | cpanfile | 2 | ||||
-rw-r--r-- | cpanfile.snapshot | 46 | ||||
-rw-r--r-- | perllib/Data/ICal/Entry/Event7986.pm | 18 | ||||
-rw-r--r-- | perllib/Data/ICal/RFC7986.pm | 17 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Waste.pm | 38 | ||||
-rw-r--r-- | templates/web/base/waste/bin_days.html | 2 |
6 files changed, 122 insertions, 1 deletions
@@ -136,6 +136,8 @@ feature 'uk', 'FixMyStreet.com specific requirements' => sub { requires 'SOAP::Lite', '1.20'; # TfL requires 'Net::Subnet'; + # Bromley + requires 'Data::ICal'; }; feature 'zurich', 'Zueri wie neu specific requirements' => sub { diff --git a/cpanfile.snapshot b/cpanfile.snapshot index cdb785a26..92a8535a3 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -947,6 +947,14 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 + Class-ReturnValue-0.55 + pathname: J/JE/JESSE/Class-ReturnValue-0.55.tar.gz + provides: + Class::ReturnValue 0.55 + requirements: + Devel::StackTrace 0 + ExtUtils::MakeMaker 0 + Test::More 0 Class-Singleton-1.4 pathname: A/AB/ABW/Class-Singleton-1.4.tar.gz provides: @@ -1723,6 +1731,36 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 6.42 perl 5.006 + Data-ICal-0.24 + pathname: B/BP/BPS/Data-ICal-0.24.tar.gz + provides: + Data::ICal 0.24 + Data::ICal::Entry undef + Data::ICal::Entry::Alarm undef + Data::ICal::Entry::Alarm::Audio undef + Data::ICal::Entry::Alarm::Display undef + Data::ICal::Entry::Alarm::Email undef + Data::ICal::Entry::Alarm::None undef + Data::ICal::Entry::Alarm::Procedure undef + Data::ICal::Entry::Alarm::URI undef + Data::ICal::Entry::Event undef + Data::ICal::Entry::FreeBusy undef + Data::ICal::Entry::Journal undef + Data::ICal::Entry::TimeZone undef + Data::ICal::Entry::TimeZone::Daylight undef + Data::ICal::Entry::TimeZone::Standard undef + Data::ICal::Entry::Todo undef + Data::ICal::Property 0.06 + requirements: + Class::Accessor 0 + Class::ReturnValue 0 + ExtUtils::MakeMaker 6.36 + MIME::QuotedPrint 0 + Test::LongString 0 + Test::More 0 + Test::NoWarnings 0 + Test::Warn 0 + Text::vFile::asData 0 Data-OptList-0.110 pathname: R/RJ/RJBS/Data-OptList-0.110.tar.gz provides: @@ -7931,6 +7969,14 @@ DISTRIBUTIONS Text::Unidecode 0.04 requirements: ExtUtils::MakeMaker 0 + Text-vFile-asData-0.08 + pathname: R/RC/RCLAMP/Text-vFile-asData-0.08.tar.gz + provides: + Text::vFile::asData 0.08 + requirements: + Class::Accessor::Chained 0 + ExtUtils::MakeMaker 0 + Test::More 0.88 Throwable-0.200013 pathname: R/RJ/RJBS/Throwable-0.200013.tar.gz provides: diff --git a/perllib/Data/ICal/Entry/Event7986.pm b/perllib/Data/ICal/Entry/Event7986.pm new file mode 100644 index 000000000..ae627861a --- /dev/null +++ b/perllib/Data/ICal/Entry/Event7986.pm @@ -0,0 +1,18 @@ +package Data::ICal::Entry::Event7986; + +use parent 'Data::ICal::Entry::Event'; + +sub optional_unique_properties { + return ( + shift->SUPER::optional_unique_properties, + "color", + ); +} + +sub optional_repeatable_properties { + return ( + shift->SUPER::optional_repeatable_properties, + "conference", "image", + ); +} + diff --git a/perllib/Data/ICal/RFC7986.pm b/perllib/Data/ICal/RFC7986.pm new file mode 100644 index 000000000..01f9d354e --- /dev/null +++ b/perllib/Data/ICal/RFC7986.pm @@ -0,0 +1,17 @@ +package Data::ICal::RFC7986; + +use parent 'Data::ICal'; + +sub optional_unique_properties { + qw( calscale method + uid last-modified url refresh-interval source color + ); +} + +# name/description are only repeatable to provide +# translations with language param +sub optional_repeatable_properties { + qw( name description categories image ); +} + +1; diff --git a/perllib/FixMyStreet/App/Controller/Waste.pm b/perllib/FixMyStreet/App/Controller/Waste.pm index a31c359f1..e606b1d8c 100644 --- a/perllib/FixMyStreet/App/Controller/Waste.pm +++ b/perllib/FixMyStreet/App/Controller/Waste.pm @@ -92,6 +92,44 @@ sub bin_days : Chained('uprn') : PathPart('') : Args(0) { my ($self, $c) = @_; } +sub calendar : Chained('uprn') : PathPart('calendar.ics') : Args(0) { + my ($self, $c) = @_; + $c->res->header(Content_Type => 'text/calendar'); + require Data::ICal::RFC7986; + require Data::ICal::Entry::Event; + my $calendar = Data::ICal::RFC7986->new( + calname => 'Bin calendar', + rfc_strict => 1, + auto_uid => 1, + ); + $calendar->add_properties( + prodid => '//FixMyStreet//Bin Collection Calendars//EN', + method => 'PUBLISH', + 'refresh-interval' => [ 'P1D', { value => 'DURATION' } ], + 'x-published-ttl' => 'P1D', + calscale => 'GREGORIAN', + 'x-wr-timezone' => 'Europe/London', + source => [ $c->uri_for_action($c->action, [ $c->stash->{uprn} ]), { value => 'URI' } ], + url => $c->uri_for_action('waste/bin_days', [ $c->stash->{uprn} ]), + ); + + my $events = $c->cobrand->bin_future_collections; + my $stamp = DateTime->now->strftime('%Y%m%dT%H%M%SZ'); + foreach (@$events) { + my $event = Data::ICal::Entry::Event->new; + $event->add_properties( + summary => $_->{summary}, + description => $_->{desc}, + dtstamp => $stamp, + dtstart => [ $_->{date}->ymd(''), { value => 'DATE' } ], + dtend => [ $_->{date}->add(days=>1)->ymd(''), { value => 'DATE' } ], + ); + $calendar->add_entry($event); + } + + $c->res->body($calendar->as_string); +} + sub construct_bin_request_form { my $c = shift; diff --git a/templates/web/base/waste/bin_days.html b/templates/web/base/waste/bin_days.html index 0b51e9a47..e5a1d41c5 100644 --- a/templates/web/base/waste/bin_days.html +++ b/templates/web/base/waste/bin_days.html @@ -71,7 +71,7 @@ <div class="aside-download"> <h3>Download your collection schedule</h3> <ul> - <li><a href="#">Add to your calendar (.ics file)</a></li> + <li><a href="[% c.uri_for_action('waste/calendar', [ uprn ]) %]">Add to your calendar (.ics file)</a></li> </ul> </div> [% IF any_report_allowed OR any_request_allowed %] |