adventures in civic hacking

54
Adventures in civic hacking FixMyStreet & Open311 [email protected] https://www.flickr.com/photos/theodevil/5457434597/

Upload: osfameron

Post on 25-Dec-2014

284 views

Category:

Internet


2 download

DESCRIPTION

What is civic hacking, and what does it have to do with fixing potholes? My talk from YAPC::EU::2014 in Sofia. https://www.youtube.com/watch?v=pUp1mQx61No

TRANSCRIPT

Page 1: Adventures in civic hacking

Adventures incivic hacking

FixMyStreet & [email protected]

https://www.flickr.com/photos/theodevil/5457434597/

Page 2: Adventures in civic hacking

"easily launch a website that helps people to report street problems like potholes and broken street lights."

Page 3: Adventures in civic hacking
Page 4: Adventures in civic hacking
Page 5: Adventures in civic hacking
Page 6: Adventures in civic hacking
Page 7: Adventures in civic hacking

We make websites and tools that empower citizens

For communities.

For opening democracy.

For getting things changed.

Page 8: Adventures in civic hacking
Page 9: Adventures in civic hacking
Page 10: Adventures in civic hacking
Page 11: Adventures in civic hacking
Page 12: Adventures in civic hacking
Page 13: Adventures in civic hacking
Page 14: Adventures in civic hacking
Page 15: Adventures in civic hacking
Page 16: Adventures in civic hacking

FixMyStreet <-> Local Government

• User submits problem on web/app

• We work out who to contact, based on location/type of problem

• We send an email

Page 17: Adventures in civic hacking

FixMyStreet <-> Local Government

• User submits problem on web/app

• We work out who to contact, based on location/type of problem

• We send an email

• Council employee lovingly copies email into their actual system

Page 18: Adventures in civic hacking

https://www.flickr.com/photos/ltdemartinet/2811744365/

Page 19: Adventures in civic hacking

Integrations

• User submits problem on web/app

• We work out who to contact, based on location/type of problem

• We run custom code which calls council API to recreate the FMS problem on a council’s system

Page 20: Adventures in civic hacking

Integrations

• User submits problem on web/app

• We work out who to contact, based on location/type of problem

• We run custom code which calls council API to recreate the FMS problem on a council’s system• Exor

• Mayrise

• SAP

• MS Dynamics CRM (via SOAP, eeek. Later versions REST)

• etc….

Page 21: Adventures in civic hacking

Open311

…is a form of technology that provides open channels of communication for issues that concern public space and public services. Primarily, Open311 refers to a standardized protocol for location-based collaborative issue-tracking.—http://www.open311.org/learn/

Page 22: Adventures in civic hacking

http://raulrene.wordpress.com/renes-pixie-pixelarium/

Page 23: Adventures in civic hacking
Page 24: Adventures in civic hacking
Page 25: Adventures in civic hacking
Page 26: Adventures in civic hacking
Page 27: Adventures in civic hacking

Simples!

• FixMyStreet has builtin Open311 client

• Council backend is Open311 server

Page 28: Adventures in civic hacking

Simples!

• FixMyStreet has builtin Open311 client

• Council backend is not Open311 server

Page 29: Adventures in civic hacking
Page 30: Adventures in civic hacking
Page 31: Adventures in civic hacking

Here comes the architecture

Shim

Backend

Page 32: Adventures in civic hacking

CGI shim script

Simple

Few dependencies Easily run in hostile

environment

Subset of Open311

Non-standard URLS Won’t actually support

other Open311 clients

Hardcoded assumptions Hard to extend

Hard to test

Page 33: Adventures in civic hacking

Open311::Endpoint

• Plack

• Web::Simple

• DateTime::Parser::

• Data::Rx

• Moo, Types::Standard, MooX::HandlesVia

• DBD::Oracle

• XML

Page 34: Adventures in civic hacking
Page 35: Adventures in civic hacking

Plack::Test

my $endpoint = Test::Endpoint->new;

my $res = $endpoint->run_test_request(

GET => '/services.xml‘

);

Page 36: Adventures in civic hacking

End to end tests?

Shim

Backend

Page 37: Adventures in civic hacking

Stub out backend

Test::Shim

(Stubbed)

Page 38: Adventures in civic hacking
Page 39: Adventures in civic hacking

LWP::Protocol::PSGI

Test::Shim

(Stubbed)

my $endpoint = Test::Endpoint->new;

LWP::Protocol::PSGI->register($endpoint,host => 'open311.example.com‘

);

Page 40: Adventures in civic hacking
Page 41: Adventures in civic hacking

https://www.flickr.com/photos/cunaldo/468824934/

Page 42: Adventures in civic hacking

Web::Simplesub dispatch_request {

my $self = shift;

sub (GET + /services + ?*) {

my ($self, $args) = @_;

$self->call_api(GET_Service_List => $args);

},

sub (POST + /requests + %*) {

my ($self, $args) = @_;

$self->call_api(POST_Service_Request => $args);

},

Page 43: Adventures in civic hacking

https://www.flickr.com/photos/alanenglish/2780298470/

Page 44: Adventures in civic hacking

Types::Standard, MooX::HandlesVia

has latlong => (is => 'ro',isa => Tuple[ Num, Num ],default => sub { [0,0] },handles_via => 'Array',handles => {

lat => [ get => 0 ],long => [ get => 1 ],

});

Page 45: Adventures in civic hacking

Types::Standard, MooX::HandlesVia

has latlong => (is => 'ro',isa => Tuple[ Num, Num ],default => sub { [0,0] },handles_via => 'Array',handles => {

lat => [ get => 0 ],long => [ get => 1 ],

});

Page 46: Adventures in civic hacking

Types::Standard, MooX::HandlesVia

has latlong => (is => 'ro',isa => Tuple[ Num, Num ],default => sub { [0,0] },handles_via => 'Array',handles => {

lat => [ get => 0 ],long => [ get => 1 ],

});

Page 47: Adventures in civic hacking

Types::Standard, MooX::HandlesVia

has latlong => (is => 'ro',isa => Tuple[ Num, Num ],default => sub { [0,0] },handles_via => 'Array',handles => {

lat => [ get => 0 ],long => [ get => 1 ],

});

Page 48: Adventures in civic hacking

https://www.flickr.com/photos/dopey/9591636030/

Page 49: Adventures in civic hacking

Data::Rx

$schema->learn_type('tag:GeoReport_v2:rx/service', {

type => '//rec',

required => {

service_name => '//str',

type => '/open311/post_type',

metadata => '/open311/bool',

description => '//str',

},

optional => {

keywords => '//str',

group => '//str',

}});

Page 50: Adventures in civic hacking

Data::Rx

$schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/datetime',

{

type => '/open311/regex',

pattern => qr{

^

\d{4} - \d{2} - \d{2} # yyyy-mm-dd

T

\d{2} : \d{2} : \d{2} # hh:mm:ss

(?:

Z # "Zulu" time, e.g. UTC

| [+-] \d{2} : \d{2} # +/- hh:mm offset

)

$

}ax, # use ascii semantics so /d means [0-9]

message => "found value isn't a datetime",

});

Page 51: Adventures in civic hacking
Page 52: Adventures in civic hacking

Inputs and Outputs

sub GET_Service_Definition_input_schema {

return { type => '//seq',

contents => [

$self->get_identifier_type('service_code'),

$self->get_jurisdiction_id_validation, ] } }

sub GET_Service_Definition_output_schema {

return { type => '//rec',

required => {

service_definition => {

type => '/open311/service_definition',

} } } }

Page 53: Adventures in civic hacking

XML::Simple

• Yeah, I know…

• Wrapped in Open311::Endpoint::Spark• interop with JSON schema

Page 54: Adventures in civic hacking

https://www.flickr.com/photos/rossap/7619777396/