summaryrefslogtreecommitdiff
path: root/lib/Travel/Routing/DE/EFA
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Travel/Routing/DE/EFA')
-rw-r--r--lib/Travel/Routing/DE/EFA/Exception.pod57
-rw-r--r--lib/Travel/Routing/DE/EFA/Route.pm121
-rw-r--r--lib/Travel/Routing/DE/EFA/Route/Part.pm217
3 files changed, 395 insertions, 0 deletions
diff --git a/lib/Travel/Routing/DE/EFA/Exception.pod b/lib/Travel/Routing/DE/EFA/Exception.pod
new file mode 100644
index 0000000..5ec2991
--- /dev/null
+++ b/lib/Travel/Routing/DE/EFA/Exception.pod
@@ -0,0 +1,57 @@
+=head1 NAME
+
+Travel::Routing::DE::EFA::Exception - Travel::Routing::DE::EFA Exceptions
+
+=head1 DESCRIPTION
+
+All Exceptions thrown by Travel::Routing::DE::EFA are
+Travel::Routing::DE::EFA::Exception objects created by Exception::Class(3pm).
+
+See Exception::Class::Base(3pm) for their common methods.
+
+=head1 LIST OF EXCEPTIONS
+
+=head2 Travel::Routing::DE::EFA::Exception::Setup
+
+An argument to B<new> had an invalid format.
+
+Additional methods:
+
+=over
+
+=item $exception->option
+
+The option in which the error occured.
+
+=item $exception->have
+
+The argument we got.
+
+=item $exception->want
+
+What kind of argument we want.
+
+=back
+
+=head2 Travel::Routing::DE::EFA::Exception::Net
+
+The HTTP request to the efa interface failed. Contains an HTTP::Response(3pm)
+object describing the error in B<http_response>.
+
+=head2 Travel::Routing::DE::EFA::Exception::NoData
+
+We got no parsable data from the EFA service
+
+=head2 Travel::Routing::DE::EFA::Exception::Ambiguous
+
+Our request contained ambiguous data. B<post_key> contains the relevant POST
+key, B<possibilities> is a comma-separated string of possible key values (as
+reported by the EFA service).
+
+=head2 Travel::Routing::DE::EFA::Exception::NoConnections
+
+The EFA service found no connections for our request.
+
+=head1 SEE ALSO
+
+Travel::Routing::DE::EFA(3pm)
diff --git a/lib/Travel/Routing/DE/EFA/Route.pm b/lib/Travel/Routing/DE/EFA/Route.pm
new file mode 100644
index 0000000..11fbacd
--- /dev/null
+++ b/lib/Travel/Routing/DE/EFA/Route.pm
@@ -0,0 +1,121 @@
+package Travel::Routing::DE::EFA::Route;
+
+use strict;
+use warnings;
+use 5.010;
+
+use parent 'Class::Accessor';
+
+use Travel::Routing::DE::EFA::Route::Part;
+
+our $VERSION = '2.04';
+
+Travel::Routing::DE::EFA::Route->mk_ro_accessors(
+ qw(duration ticket_text ticket_type fare_adult fare_child vehicle_time));
+
+sub new {
+ my ( $obj, $info, @parts ) = @_;
+
+ my $ref = $info;
+
+ for my $part (@parts) {
+ push(
+ @{ $ref->{parts} },
+ Travel::Routing::DE::EFA::Route::Part->new( %{$part} )
+ );
+ }
+
+ return bless( $ref, $obj );
+}
+
+sub parts {
+ my ($self) = @_;
+
+ return @{ $self->{parts} };
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Travel::Routing::DE::EFA::Route - Single route (connection) between two points
+
+=head1 SYNOPSIS
+
+ for my $route ( $efa->routes ) {
+ for my $part ( $route->parts ) {
+ # $part is a Travel::Routing::DE::EFA::Route::Part object
+ }
+ }
+
+=head1 VERSION
+
+version 2.04
+
+=head1 DESCRIPTION
+
+Travel::Routing::DE::EFA::Route describes a single method of getting from one
+point to another. It holds a bunch of Travel::Routing::DE::EFA::Route::Part(3pm)
+objects describing the parts of the route in detail. Each part depends on the
+previous one.
+
+You usually want to acces it via C<< $efa->routes >>.
+
+=head1 METHODS
+
+=head2 ACCESSORS
+
+=over
+
+=item $route->duration
+
+route duration as string in HH:MM format
+
+=item $route->parts
+
+Returns a list of Travel::Routing::DE::EFA::Route::Part(3pm) elements describing
+the actual route
+
+=item $route->ticket_type
+
+Type of the required ticket for this route, if available (empty string otherwise)
+
+=item $route->fare_adult
+
+ticket price for an adult in EUR
+
+=item $route->fare_child
+
+ticket price for a child in EUR
+
+=item $route->vehicle_time
+
+on-vehicle time (excluding waiting time) of the route in minutes
+
+=back
+
+=head1 DIAGNOSTICS
+
+None.
+
+=head1 DEPENDENCIES
+
+None.
+
+=head1 BUGS AND LIMITATIONS
+
+None known.
+
+=head1 SEE ALSO
+
+Travel::Routing::DE::EFA(3pm), Travel::Routing::DE::EFA::Route::Part(3pm).
+
+=head1 AUTHOR
+
+Copyright (C) 2011-2014 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+
+=head1 LICENSE
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
diff --git a/lib/Travel/Routing/DE/EFA/Route/Part.pm b/lib/Travel/Routing/DE/EFA/Route/Part.pm
new file mode 100644
index 0000000..137581d
--- /dev/null
+++ b/lib/Travel/Routing/DE/EFA/Route/Part.pm
@@ -0,0 +1,217 @@
+package Travel::Routing::DE::EFA::Route::Part;
+
+use strict;
+use warnings;
+use 5.010;
+
+use parent 'Class::Accessor';
+
+our $VERSION = '2.04';
+
+Travel::Routing::DE::EFA::Route::Part->mk_ro_accessors(
+ qw(arrival_platform arrival_stop
+ arrival_date arrival_time arrival_sdate arrival_stime
+ delay departure_platform departure_stop
+ departure_date departure_time departure_sdate departure_stime
+ train_line train_destination
+ )
+);
+
+sub new {
+ my ( $obj, %conf ) = @_;
+
+ my $ref = \%conf;
+
+ return bless( $ref, $obj );
+}
+
+sub arrival_stop_and_platform {
+ my ($self) = @_;
+
+ if ( length( $self->arrival_platform ) ) {
+ return
+ sprintf( '%s: %s', $self->get(qw(arrival_stop arrival_platform)) );
+ }
+ return $self->arrival_stop;
+}
+
+sub departure_stop_and_platform {
+ my ($self) = @_;
+
+ if ( length( $self->departure_platform ) ) {
+
+ return
+ sprintf( '%s: %s',
+ $self->get(qw(departure_stop departure_platform)) );
+ }
+ return $self->departure_stop;
+}
+
+sub extra {
+ my ($self) = @_;
+
+ return @{ $self->{extra} // [] };
+}
+
+sub via {
+ my ($self) = @_;
+
+ return @{ $self->{via} // [] };
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Travel::Routing::DE::EFA::Route::Part - Describes one connection between two
+points, without interchanges
+
+=head1 SYNOPSIS
+
+ for my $part ( $route->parts ) {
+
+ if ( $part->extra ) {
+ say join( "\n", $part->extra );
+ }
+
+ printf(
+ "%s at %s -> %s at %s, via %s to %s",
+ $part->departure_time, $part->departure_stop,
+ $part->arrival_time, $part->arrival_stop,
+ $part->train_line, $part->train_destination,
+ );
+ }
+
+=head1 VERSION
+
+version 2.04
+
+=head1 DESCRIPTION
+
+B<Travel::Routing::DE::EFA::Route::Part> holds one specific connection (without
+interchanges) between two points. It specifies the start/stop point and time,
+the train line and its destination, and optional additional data.
+
+It is usually obtained by a call to Travel::Routing::DE::EFA::Route(3pm)'s
+B<parts> method.
+
+=head1 METHODS
+
+=head2 ACCESSORS
+
+"Actual" in the description means that the delay (if available) is already
+included in the calculation, "Scheduled" means it isn't.
+
+=over
+
+=item $part->arrival_stop
+
+arrival stop (city name plus station name)
+
+=item $part->arrival_platform
+
+arrival platform (either "Gleis x" or "Bstg. x")
+
+=item $part->arrival_stop_and_platform
+
+"stop: platform" concatenation
+
+=item $part->arrival_date
+
+Actual arrival date in DD.MM.YYYY format
+
+=item $part->arrival_time
+
+Actual arrival time in HH:MM format
+
+=item $part->arrival_sdate
+
+Scheduled arrival date in DD.MM.YYYY format
+
+=item $part->arrival_stime
+
+Scheduled arrival time in HH:MM format
+
+=item $part->delay
+
+delay in minutes, 0 if unknown
+
+=item $part->departure_stop
+
+departure stop (city name plus station name)
+
+=item $part->departure_platform
+
+departure platform (either "Gleis x" or "Bstg. x")
+
+=item $part->departure_stop_and_platform
+
+"stop: platform" concatenation
+
+=item $part->departure_date
+
+Actual departure date in DD.MM.YYYY format
+
+=item $part->departure_time
+
+Actual departure time in HH:MM format
+
+=item $part->departure_sdate
+
+Scheduled departure date in DD.MM.YYYY format
+
+=item $part->departure_stime
+
+Scheduled departure time in HH:MM format
+
+=item $part->extra
+
+Additional information about the connection. Returns a list of
+newline-terminated strings
+
+=item $part->train_destination
+
+destination of the line providing the connection
+
+=item $part->train_line
+
+name / number of the line
+
+=item $part->via
+
+List of stops passed between departure_stop and arrival_stop, as
+C<< [ "DD.MM.YYYY", "HH:MM", stop, platform ] >> hashrefs.
+
+May be empty, these are not always reported by efa.vrr.de.
+
+=back
+
+=head1 DIAGNOSTICS
+
+None.
+
+=head1 DEPENDENCIES
+
+=over
+
+=item * Class::Accessor(3pm)
+
+=back
+
+=head1 BUGS AND LIMITATIONS
+
+$part->via does not work reliably.
+
+=head1 SEE ALSO
+
+Travel::Routing::DE::EFA(3pm), Class::Accessor(3pm).
+
+=head1 AUTHOR
+
+Copyright (C) 2011-2014 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
+
+=head1 LICENSE
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.