diff options
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 31 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Contact.pm | 25 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Open311conf.pm | 39 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 26 | ||||
-rw-r--r-- | perllib/Open311.pm | 179 |
5 files changed, 294 insertions, 6 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 346dfb377..2311b4aff 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -15,6 +15,7 @@ use Path::Class; use Utils; use mySociety::EmailUtil; use mySociety::TempFiles; +use JSON; =head1 NAME @@ -449,6 +450,7 @@ sub setup_categories_and_councils : Private { my %area_ids_to_list = (); # Areas with categories assigned my @category_options = (); # categories to show my $category_label = undef; # what to call them + my %category_extras = (); # extra fields to fill in for open311 # FIXME - implement in cobrand if ( $c->cobrand->moniker eq 'emptyhomes' ) { @@ -495,8 +497,12 @@ sub setup_categories_and_councils : Private { next if $contact->category eq _('Other'); - push @category_options, $contact->category - unless $seen{$contact->category}; + unless ( $seen{$contact->category} ) { + push @category_options, $contact->category; + + $category_extras{ $contact->category } = $contact->extra + if $contact->extra; + } $seen{$contact->category} = 1; } @@ -511,6 +517,7 @@ sub setup_categories_and_councils : Private { $c->stash->{area_ids_to_list} = [ keys %area_ids_to_list ]; $c->stash->{category_label} = $category_label; $c->stash->{category_options} = \@category_options; + $c->stash->{category_extras} = encode_json \%category_extras; my @missing_details_councils = grep { !$area_ids_to_list{$_} } # @@ -689,6 +696,26 @@ sub process_report : Private { if $council_string && @{ $c->stash->{missing_details_councils} }; $report->council($council_string); + my @extra = (); + my $metas = $contacts[0]->extra; + + foreach my $field ( sort { $a->{order} <=> $b->{order} } values %$metas ) { + if ( lc( $field->{required} ) eq 'true' ) { + unless ( $c->request->param( $field->{code} ) ) { + $c->stash->{field_errors}->{ $field->{code} } = _('This information is required'); + } + } + push @extra, { + name => $field->{code}, + description => $field->{description}, + value => $c->request->param( $field->{code} ), + }; + } + + if ( @extra ) { + $c->stash->{report_meta} = \@extra; + $report->extra( \@extra ); + } } elsif ( @{ $c->stash->{area_ids_to_list} } ) { # There was an area with categories, but we've not been given one. Bail. diff --git a/perllib/FixMyStreet/DB/Result/Contact.pm b/perllib/FixMyStreet/DB/Result/Contact.pm index 001fb4ac6..779ca9bc2 100644 --- a/perllib/FixMyStreet/DB/Result/Contact.pm +++ b/perllib/FixMyStreet/DB/Result/Contact.pm @@ -34,12 +34,33 @@ __PACKAGE__->add_columns( { data_type => "timestamp", is_nullable => 0 }, "note", { data_type => "text", is_nullable => 0 }, + "extra", + { data_type => "text", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("contacts_area_id_category_idx", ["area_id", "category"]); +__PACKAGE__->filter_column( + extra => { + filter_from_storage => sub { + my $self = shift; + my $ser = shift; + return undef unless defined $ser; + my $h = new IO::String($ser); + return RABX::wire_rd($h); + }, + filter_to_storage => sub { + my $self = shift; + my $data = shift; + my $ser = ''; + my $h = new IO::String($ser); + RABX::wire_wr( $data, $h ); + return $ser; + }, + } +); -# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-06-23 15:49:48 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BXGd4uk1ybC5RTKlInTr0w +# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-08-01 10:07:59 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4y6yRz4rMN66pBpkzfJJhg 1; diff --git a/perllib/FixMyStreet/DB/Result/Open311conf.pm b/perllib/FixMyStreet/DB/Result/Open311conf.pm new file mode 100644 index 000000000..0a5784560 --- /dev/null +++ b/perllib/FixMyStreet/DB/Result/Open311conf.pm @@ -0,0 +1,39 @@ +package FixMyStreet::DB::Result::Open311conf; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); +__PACKAGE__->table("open311conf"); +__PACKAGE__->add_columns( + "id", + { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + sequence => "open311conf_id_seq", + }, + "area_id", + { data_type => "integer", is_nullable => 0 }, + "endpoint", + { data_type => "text", is_nullable => 0 }, + "jurisdiction", + { data_type => "text", is_nullable => 1 }, + "api_key", + { data_type => "text", is_nullable => 1 }, +); +__PACKAGE__->set_primary_key("id"); +__PACKAGE__->add_unique_constraint("open311conf_area_id_key", ["area_id"]); + + +# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-07-29 18:09:25 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ryqCpvwjNtQrZm4I3s0hxg + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index ff730958a..09d1e058a 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -78,6 +78,8 @@ __PACKAGE__->add_columns( { data_type => "timestamp", is_nullable => 1 }, "send_questionnaire", { data_type => "boolean", default_value => \"true", is_nullable => 0 }, + "extra", + { data_type => "text", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->has_many( @@ -100,8 +102,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-06-23 15:49:48 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3sw/1dqxlTvcWEI/eJTm4w +# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-07-29 16:26:23 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ifvx9FOlbui66hPyzNIAPA # Add fake relationship to stored procedure table __PACKAGE__->has_many( @@ -111,11 +113,31 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +__PACKAGE__->filter_column( + extra => { + filter_from_storage => sub { + my $self = shift; + my $ser = shift; + return undef unless defined $ser; + my $h = new IO::String($ser); + return RABX::wire_rd($h); + }, + filter_to_storage => sub { + my $self = shift; + my $data = shift; + my $ser = ''; + my $h = new IO::String($ser); + RABX::wire_wr( $data, $h ); + return $ser; + }, + } +); use DateTime::TimeZone; use Image::Size; use Moose; use namespace::clean -except => [ 'meta' ]; use Utils; +use RABX; with 'FixMyStreet::Roles::Abuser'; diff --git a/perllib/Open311.pm b/perllib/Open311.pm new file mode 100644 index 000000000..0c8c3fde6 --- /dev/null +++ b/perllib/Open311.pm @@ -0,0 +1,179 @@ +package Open311; + +use URI; +use Moose; +use XML::Simple; +use LWP::Simple; +use LWP::UserAgent; +use HTTP::Request::Common qw(POST); + +has jurisdiction => ( is => 'ro', isa => 'Str' );; +has api_key => ( is => 'ro', isa => 'Str' ); +has endpoint => ( is => 'ro', isa => 'Str' ); + +sub get_service_list { + my $self = shift; + + my $service_list_xml = $self->_get( 'services.xml' ); + + return $self->_get_xml_object( $service_list_xml ); +} + +sub get_service_meta_info { + my $self = shift; + my $service_id = shift; + + my $service_meta_xml = $self->_get( "services/$service_id.xml" ); + return $self->_get_xml_object( $service_meta_xml ); +} + +sub send_service_request { + my $self = shift; + my $problem = shift; + my $extra = shift; + my $service_code = shift; + + my $description = <<EOT; +title: @{[$problem->title()]} + +detail: @{[$problem->detail()]} + +url: $extra->{url} + +Submitted via FixMyStreet +EOT +; + + my $params = { + lat => $problem->latitude, + long => $problem->longitude, + email => $problem->user->email, + description => $description, + service_code => $service_code, + }; + + if ( $problem->user->phone ) { + $params->{ phone } = $problem->user->phone; + } + + if ( $extra->{image_url} ) { + $params->{media_url} = $extra->{image_url}; + } + + if ( $problem->extra ) { + my $extras = $problem->extra; + + for my $attr ( @$extras ) { + my $name = sprintf( 'attribute[%s]', $attr->{name} ); + $params->{ $name } = $attr->{value}; + } + } + + my $response = $self->_post( 'requests.xml', $params ); + + if ( $response ) { + my $obj = $self->_get_xml_object( $response ); + + if ( $obj ) { + if ( $obj->{ request }->{ service_request_id } ) { + return $obj->{ request }->{ service_request_id }; + } else { + my $token = $obj->{ request }->{ token }; + return $self->get_service_request_id_from_token( $token ); + } + } + } +} + +sub get_service_requests { + my $self = shift; + + my $service_request_xml = $self->_get( 'requests.xml' ); +} + +sub get_service_request_id_from_token { + my $self = shift; + my $token = shift; + + my $service_token_xml = $self->_get( "tokens/$token.xml" ); + + my $obj = $self->_get_xml_object( $service_token_xml ); + + if ( $obj && $obj->{ request }->{ service_request_id } ) { + return $obj->{ request }->{ service_request_id }; + } else { + return 0; + } +} + +sub _get { + my $self = shift; + my $path = shift; + my $params = shift; + + my $uri = URI->new( $self->endpoint ); + $uri->path( $uri->path . $path ); + $uri->query_form( jurisdiction_id => $self->jurisdiction ); + + my $content = get( $uri->as_string ); + + return $content; +} + +sub _post { + my $self = shift; + my $path = shift; + my $params = shift; + + my $uri = URI->new( $self->endpoint ); + $uri->path( $uri->path . $path ); + + my $req = POST $uri->as_string, + [ + jurisdiction_id => $self->jurisdiction, + api_key => $self->api_key, + %{ $params } + ]; + + my $ua = LWP::UserAgent->new(); + my $res = $ua->request( $req ); + + if ( $res->is_success ) { + return $res->decoded_content; + } else { + warn "request failed: " . $res->status_line; + warn $self->_process_error( $res->decoded_content ); + return 0; + } +} + +sub _process_error { + my $self = shift; + my $error = shift; + + my $obj = $self->_get_xml_object( $error ); + + my $msg = ''; + if ( ref $obj && exists $obj->{error} ) { + my $errors = $obj->{error}; + $errors = [ $errors ] if ref $errors ne 'ARRAY'; + $msg .= sprintf( "%s: %s\n", $_->{code}, $_->{description} ) for @{ $errors }; + } + + return $msg || 'unknown error'; +} + +sub _get_xml_object { + my $self = shift; + my $xml= shift; + + my $simple = XML::Simple->new(); + my $obj; + + eval { + $obj = $simple ->XMLin( $xml ); + }; + + return $obj; +} +1; |