diff options
author | Birte Kristina Friesel <derf@finalrewind.org> | 2024-12-24 10:01:08 +0100 |
---|---|---|
committer | Birte Kristina Friesel <derf@finalrewind.org> | 2024-12-24 10:01:08 +0100 |
commit | 9cb71f78d09b8dc6e7b431c31c2cfac7657d7682 (patch) | |
tree | 53531d309d9e5e71fa4d5a12d9fccbb6a7784331 | |
parent | e1535415b0ee257b0a475e7de5978612e6153ec3 (diff) |
add journey support
-rwxr-xr-x | bin/dbris-m | 40 | ||||
-rw-r--r-- | lib/Travel/Status/DE/DBRIS.pm | 29 | ||||
-rw-r--r-- | lib/Travel/Status/DE/DBRIS/Journey.pm | 45 | ||||
-rw-r--r-- | lib/Travel/Status/DE/DBRIS/JourneyAtStop.pm | 87 | ||||
-rw-r--r-- | lib/Travel/Status/DE/DBRIS/Location.pm | 27 | ||||
-rw-r--r-- | lib/Travel/Status/DE/DBRIS/Stop.pm | 87 |
6 files changed, 276 insertions, 39 deletions
diff --git a/bin/dbris-m b/bin/dbris-m index cc495a8..3e3488b 100755 --- a/bin/dbris-m +++ b/bin/dbris-m @@ -74,7 +74,7 @@ elsif ( $opt{station} =~ m{ ^ [?] (?<query> .*) $ }x ) { delete $opt{station}; } elsif ( $opt{station} =~ m{[|]} ) { - $opt{journey} = { id => $opt{station} }; + $opt{journey} = $opt{station}; delete $opt{station}; } elsif ( $opt{station} !~ m{ ^ \d+ $ }x ) { @@ -191,6 +191,44 @@ if ( $opt{station} ) { } } } +elsif ( $opt{journey} ) { + my $trip = $status->result; + + my $max_name = max map { length( $_->name ) } $trip->route; + my $max_platform = max map { length( $_->platform // q{} ) } $trip->route; + + say $trip->train; + say q{}; + + for my $stop ( $trip->route ) { + if ( $stop->is_cancelled ) { + print(' --:-- '); + } + elsif ( $stop->arr and $stop->dep ) { + printf( '%s → %s', + $stop->arr->strftime('%H:%M'), + $stop->dep->strftime('%H:%M'), + ); + } + elsif ( $stop->dep ) { + printf( ' %s', $stop->dep->strftime('%H:%M') ); + } + elsif ( $stop->arr ) { + printf( '%s ', $stop->arr->strftime('%H:%M') ); + } + else { + print(' '); + } + printf( " %${max_name}s %${max_platform}s\n", + $stop->name, $stop->platform // q{} ); + } + if ( $trip->messages ) { + say q{}; + } + for my $message ( $trip->messages ) { + say $message->{text}; + } +} elsif ( $opt{geoSearch} ) { for my $result ( $status->results ) { if ( defined $result->eva ) { diff --git a/lib/Travel/Status/DE/DBRIS.pm b/lib/Travel/Status/DE/DBRIS.pm index 2f17e90..66790b2 100644 --- a/lib/Travel/Status/DE/DBRIS.pm +++ b/lib/Travel/Status/DE/DBRIS.pm @@ -13,6 +13,7 @@ use DateTime::Format::Strptime; use Encode qw(decode encode); use JSON; use LWP::UserAgent; +use Travel::Status::DE::DBRIS::JourneyAtStop; use Travel::Status::DE::DBRIS::Journey; use Travel::Status::DE::DBRIS::Location; @@ -77,10 +78,16 @@ sub new { $req = "https://www.bahn.de/web/api/reiseloesung/orte?suchbegriff=${query}&typ=ALL&limit=10"; } - - # journey : https://www.bahn.de/web/api/reiseloesung/fahrt?journeyId=2%7C%23VN%231%23ST%231733779122%23PI%230%23ZI%23324190%23TA%230%23DA%23141224%231S%238000001%231T%231822%23LS%238000080%23LT%232050%23PU%2380%23RT%231%23CA%23DPN%23ZE%2326431%23ZB%23RE+26431%23PC%233%23FR%238000001%23FT%231822%23TO%238000080%23TT%232050%23&poly=true + elsif ( my $journey_id = $conf{journey} ) { + my $poly = $conf{with_polyline} ? 'true' : 'false'; + $journey_id =~ s{[#]}{%23}g; + $req + = "https://www.bahn.de/web/api/reiseloesung/fahrt?journeyId=${journey_id}&poly=${poly}"; + } else { - confess('station or geoSearch must be specified'); + confess( + 'station / geoSearch / locationSearch / journey must be specified' + ); } $self->{strptime_obj} //= DateTime::Format::Strptime->new( @@ -120,6 +127,9 @@ sub new { if ( $conf{station} ) { $self->parse_stationboard; } + elsif ( $conf{journey} ) { + $self->parse_journey; + } elsif ( $conf{geoSearch} or $conf{locationSearch} ) { $self->parse_search; } @@ -257,6 +267,15 @@ sub get_with_cache_p { return $promise; } +sub parse_journey { + my ($self) = @_; + + $self->{result} = Travel::Status::DE::DBRIS::Journey->new( + json => $self->{raw_json}, + strptime_obj => $self->{strptime_obj} + ); +} + sub parse_search { my ($self) = @_; @@ -273,7 +292,7 @@ sub parse_stationboard { # @{$self->{messages}} = map { Travel::Status::DE::DBRIS::Message->new(...) } @{$self->{raw_json}{globalMessages}/[]}; @{ $self->{results} } = map { - Travel::Status::DE::DBRIS::Journey->new( + Travel::Status::DE::DBRIS::JourneyAtStop->new( json => $_, strptime_obj => $self->{strptime_obj} ) @@ -440,7 +459,7 @@ it. Returns undef otherwise. =item $status->results -Returns a list of Travel::Status::DE::DBRIS::Location(3pm) or Travel::Status::DE::DBRIS::Journey(3pm) objects, depending on the arguments passed to B<new>. +Returns a list of Travel::Status::DE::DBRIS::Location(3pm) or Travel::Status::DE::DBRIS::JourneyAtStop(3pm) objects, depending on the arguments passed to B<new>. =back diff --git a/lib/Travel/Status/DE/DBRIS/Journey.pm b/lib/Travel/Status/DE/DBRIS/Journey.pm index 47dd726..c4f7df6 100644 --- a/lib/Travel/Status/DE/DBRIS/Journey.pm +++ b/lib/Travel/Status/DE/DBRIS/Journey.pm @@ -6,11 +6,11 @@ use 5.020; use parent 'Class::Accessor'; +use Travel::Status::DE::DBRIS::Location; + our $VERSION = '0.01'; -Travel::Status::DE::DBRIS::Journey->mk_ro_accessors( - qw(type dep sched_dep rt_dep delay is_cancelled line stop_eva id platform rt_platform destination via via_last) -); +Travel::Status::DE::DBRIS::Journey->mk_ro_accessors(qw(train is_cancelled)); sub new { my ( $obj, %opt ) = @_; @@ -19,36 +19,15 @@ sub new { my $strptime = $opt{strptime_obj}; my $ref = { - type => $json->{verkehrmittel}{kurzText}, - line => $json->{verkehrmittel}{mittelText}, - id => $json->{journeyId}, - stop_eva => $json->{bahnhofsId}, - destination => $json->{terminus}, - platform => $json->{gleis}, - rt_platform => $json->{ezGleis}, - via => $json->{ueber}, - via_last => ( $json->{ueber} // [] )->[-1], + train => $json->{zugName}, + is_cancelled => $json->{cancelled}, + raw_route => $json->{halte}, + strptime_obj => $strptime, }; bless( $ref, $obj ); - if ( $json->{zeit} ) { - $ref->{sched_dep} = $strptime->parse_datetime( $json->{zeit} ); - } - if ( $json->{ezZeit} ) { - $ref->{rt_dep} = $strptime->parse_datetime( $json->{ezZeit} ); - } - $ref->{dep} = $ref->{rt_dep} // $ref->{sched_dep}; - - if ( $ref->{sched_dep} and $ref->{rt_dep} ) { - $ref->{delay} = $ref->{rt_dep}->subtract_datetime( $ref->{sched_dep} ) - ->in_units('minutes'); - } - - for my $message ( @{ $json->{meldungen} // [] } ) { - if ( $message->{type} and $message->{type} eq 'HALT_AUSFALL' ) { - $ref->{is_cancelled} = 1; - } + for my $message ( @{ $json->{himMeldungen} // [] } ) { push( @{ $ref->{messages} }, $message ); } @@ -63,8 +42,12 @@ sub route { } @{ $self->{route} } - = map { Travel::Status::DE::DBRIS::Location->new( json => $_ ) } - ( @{ $self->{raw_route} // [] }, + = map { + Travel::Status::DE::DBRIS::Location->new( + json => $_, + strptime_obj => $self->{strptime_obj} + ) + } ( @{ $self->{raw_route} // [] }, @{ $self->{raw_cancelled_route} // [] } ); return @{ $self->{route} }; diff --git a/lib/Travel/Status/DE/DBRIS/JourneyAtStop.pm b/lib/Travel/Status/DE/DBRIS/JourneyAtStop.pm new file mode 100644 index 0000000..7ab9ed7 --- /dev/null +++ b/lib/Travel/Status/DE/DBRIS/JourneyAtStop.pm @@ -0,0 +1,87 @@ +package Travel::Status::DE::DBRIS::JourneyAtStop; + +use strict; +use warnings; +use 5.020; + +use parent 'Class::Accessor'; + +our $VERSION = '0.01'; + +Travel::Status::DE::DBRIS::JourneyAtStop->mk_ro_accessors( + qw(type dep sched_dep rt_dep delay is_cancelled line stop_eva id platform rt_platform destination via via_last) +); + +sub new { + my ( $obj, %opt ) = @_; + + my $json = $opt{json}; + my $strptime = $opt{strptime_obj}; + + my $ref = { + type => $json->{verkehrmittel}{kurzText}, + line => $json->{verkehrmittel}{mittelText}, + id => $json->{journeyId}, + stop_eva => $json->{bahnhofsId}, + destination => $json->{terminus}, + platform => $json->{gleis}, + rt_platform => $json->{ezGleis}, + via => $json->{ueber}, + via_last => ( $json->{ueber} // [] )->[-1], + }; + + bless( $ref, $obj ); + + if ( $json->{zeit} ) { + $ref->{sched_dep} = $strptime->parse_datetime( $json->{zeit} ); + } + if ( $json->{ezZeit} ) { + $ref->{rt_dep} = $strptime->parse_datetime( $json->{ezZeit} ); + } + $ref->{dep} = $ref->{rt_dep} // $ref->{sched_dep}; + + if ( $ref->{sched_dep} and $ref->{rt_dep} ) { + $ref->{delay} = $ref->{rt_dep}->subtract_datetime( $ref->{sched_dep} ) + ->in_units('minutes'); + } + + for my $message ( @{ $json->{meldungen} // [] } ) { + if ( $message->{type} and $message->{type} eq 'HALT_AUSFALL' ) { + $ref->{is_cancelled} = 1; + } + push( @{ $ref->{messages} }, $message ); + } + + return $ref; +} + +sub route { + my ($self) = @_; + + if ( $self->{route} ) { + return @{ $self->{route} }; + } + + @{ $self->{route} } + = map { Travel::Status::DE::DBRIS::Location->new( json => $_ ) } + ( @{ $self->{raw_route} // [] }, + @{ $self->{raw_cancelled_route} // [] } ); + + return @{ $self->{route} }; +} + +sub messages { + my ($self) = @_; + + return @{ $self->{messages} // [] }; +} + +sub TO_JSON { + my ($self) = @_; + + my $ret = { %{$self} }; + + return $ret; +} + +1; diff --git a/lib/Travel/Status/DE/DBRIS/Location.pm b/lib/Travel/Status/DE/DBRIS/Location.pm index f053f2b..2dfba2c 100644 --- a/lib/Travel/Status/DE/DBRIS/Location.pm +++ b/lib/Travel/Status/DE/DBRIS/Location.pm @@ -9,7 +9,9 @@ use parent 'Class::Accessor'; our $VERSION = '0.01'; Travel::Status::DE::DBRIS::Location->mk_ro_accessors( - qw(eva id lat lon name products type is_cancelled is_additional is_separation display_priority) + qw(eva id lat lon name products type is_cancelled is_additional is_separation display_priority + dep arr platform + ) ); sub new { @@ -27,9 +29,30 @@ sub new { type => $json->{type}, is_cancelled => $json->{canceled}, is_additional => $json->{additional}, - + platform => $json->{gleis}, + rt_platform => $json->{ezGleis}, }; + if ( $json->{abfahrtsZeitpunkt} ) { + $ref->{sched_dep} + = $opt{strptime_obj}->parse_datetime( $json->{abfahrtsZeitpunkt} ); + } + if ( $json->{ezAbfahrtsZeitpunkt} ) { + $ref->{rt_dep} + = $opt{strptime_obj}->parse_datetime( $json->{ezAbfahrtsZeitpunkt} ); + } + if ( $json->{ankunftsZeitpunkt} ) { + $ref->{sched_arr} + = $opt{strptime_obj}->parse_datetime( $json->{ankunftsZeitpunkt} ); + } + if ( $json->{ezAnkunftsZeitpunkt} ) { + $ref->{rt_arr} + = $opt{strptime_obj}->parse_datetime( $json->{ezAnkunftsZeitpunkt} ); + } + + $ref->{arr} = $ref->{rt_arr} // $ref->{sched_arr}; + $ref->{dep} = $ref->{rt_dep} // $ref->{sched_dep}; + bless( $ref, $obj ); return $ref; diff --git a/lib/Travel/Status/DE/DBRIS/Stop.pm b/lib/Travel/Status/DE/DBRIS/Stop.pm new file mode 100644 index 0000000..d717ec4 --- /dev/null +++ b/lib/Travel/Status/DE/DBRIS/Stop.pm @@ -0,0 +1,87 @@ +package Travel::Status::DE::DBRIS::Stop; + +use strict; +use warnings; +use 5.020; + +use parent 'Class::Accessor'; + +our $VERSION = '0.01'; + +Travel::Status::DE::DBRIS::Stop->mk_ro_accessors( + qw(type dep sched_dep rt_dep delay is_cancelled line stop_eva id platform rt_platform destination via via_last) +); + +sub new { + my ( $obj, %opt ) = @_; + + my $json = $opt{json}; + my $strptime = $opt{strptime_obj}; + + my $ref = { + type => $json->{verkehrmittel}{kurzText}, + line => $json->{verkehrmittel}{mittelText}, + id => $json->{journeyId}, + stop_eva => $json->{bahnhofsId}, + destination => $json->{terminus}, + platform => $json->{gleis}, + rt_platform => $json->{ezGleis}, + via => $json->{ueber}, + via_last => ( $json->{ueber} // [] )->[-1], + }; + + bless( $ref, $obj ); + + if ( $json->{zeit} ) { + $ref->{sched_dep} = $strptime->parse_datetime( $json->{zeit} ); + } + if ( $json->{ezZeit} ) { + $ref->{rt_dep} = $strptime->parse_datetime( $json->{ezZeit} ); + } + $ref->{dep} = $ref->{rt_dep} // $ref->{sched_dep}; + + if ( $ref->{sched_dep} and $ref->{rt_dep} ) { + $ref->{delay} = $ref->{rt_dep}->subtract_datetime( $ref->{sched_dep} ) + ->in_units('minutes'); + } + + for my $message ( @{ $json->{meldungen} // [] } ) { + if ( $message->{type} and $message->{type} eq 'HALT_AUSFALL' ) { + $ref->{is_cancelled} = 1; + } + push( @{ $ref->{messages} }, $message ); + } + + return $ref; +} + +sub route { + my ($self) = @_; + + if ( $self->{route} ) { + return @{ $self->{route} }; + } + + @{ $self->{route} } + = map { Travel::Status::DE::DBRIS::Location->new( json => $_ ) } + ( @{ $self->{raw_route} // [] }, + @{ $self->{raw_cancelled_route} // [] } ); + + return @{ $self->{route} }; +} + +sub messages { + my ($self) = @_; + + return @{ $self->{messages} // [] }; +} + +sub TO_JSON { + my ($self) = @_; + + my $ret = { %{$self} }; + + return $ret; +} + +1; |