Unverified Commit 7cb9cb98 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

add ticket offer API client and --with-offers option

parent 43f9af3c
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -16,9 +16,9 @@ use Travel::Routing::DE::DBRIS;

my ( $date, $time, $arrival, $from, $to, $language );
my $mots;
my ( $show_jid,       $show_full_route, $show_offers );
my ( $first_class,    $passengers );
my ( $developer_mode, $verbose );
my ( $show_jid,       $show_full_route );
my ( $json_output,    $raw_json_output );
my $use_cache = 1;
my $cache;
@@ -55,6 +55,7 @@ GetOptions(
	'j|with-jid'           => \$show_jid,
	'm|modes-of-transit=s' => \$mots,
	'l|language=s'         => \$language,
	'o|with-offers'        => \$show_offers,
	'p|passengers=s'       => \$passengers,
	't|time=s'             => \$time,
	'v|verbose'            => \$verbose,
@@ -369,6 +370,30 @@ for my $connection ( $ris->connections ) {
		$header,
	);

	if ($show_offers) {
		my $offers_req = Travel::Routing::DE::DBRIS->new(
			developer_mode => $developer_mode,
			offers => {
				recon => $connection->recon,
			},
			passengers => $opt{passengers},
			first_class => $opt{first_class},
		);
		if ( my $err = $offers_req->errstr ) {
			say STDERR "Request error while looking up offers: ${err}";
		}
		for my $offer ($offers_req->offers) {
			printf('- %5.2f %s %s', $offer->price, $offer->price_unit =~ s{EUR}{€}r, $offer->name);
			if ($first_class and $offer->class == 2 or not $first_class and $offer->class == 1) {
				printf(" %d. Klasse", $offer->class);
			}
			if (scalar $offer->conditions) {
				printf(' (%s)', join(q{ · }, map { $_->{textKurz} } $offer->conditions));
			}
			say q{};
		}
	}

	if ($verbose) {
		for my $note ( $connection->notes ) {
			printf( "| %s (%s)\n", $note->{value}, $note->{key} );
+84 −34
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ use JSON;
use LWP::UserAgent;
use Travel::Status::DE::DBRIS;
use Travel::Routing::DE::DBRIS::Connection;
use Travel::Routing::DE::DBRIS::Offer;

our $VERSION = '0.03';

@@ -60,11 +61,14 @@ sub new {
		@mots = @{ $conf{modes_of_transit} // [] };
	}

	my $req_url
	my ($req_url, $req);

	if ($conf{from} and $conf{to}) {
		$req_url
		= $self->{language} eq 'de'
		? 'https://www.bahn.de/web/api/angebote/fahrplan'
		: 'https://int.bahn.de/web/api/angebote/fahrplan';
	my $req = {
		$req = {
			abfahrtsHalt     => $conf{from}->id,
			ankunftsHalt     => $conf{to}->id,
			anfrageZeitpunkt => $dt->strftime('%Y-%m-%dT%H:%M:00'),
@@ -91,6 +95,33 @@ sub new {
			nurDeutschlandTicketVerbindungen  => \0,
			deutschlandTicketVorhanden        => \0
		};
	}
	elsif ($conf{offers}) {
		$req_url
		= $self->{language} eq 'de'
		? 'https://www.bahn.de/web/api/angebote/recon'
		: 'https://int.bahn.de/web/api/angebote/recon';
		$req = {
			klasse           => $conf{first_class} ? 'KLASSE_1' : 'KLASSE_2',
			ctxRecon => $conf{offers}{recon},
			reisende         => [
				{
					typ            => 'ERWACHSENER',
					ermaessigungen => [
						{
							art    => 'KEINE_ERMAESSIGUNG',
							klasse => 'KLASSENLOS'
						},
					],
					alter  => [],
					anzahl => 1,
				}
			],
			reservierungsKontingenteVorhanden => \0,
			nurDeutschlandTicketVerbindungen  => \0,
			deutschlandTicketVorhanden        => \0
		};
	}

	for my $via ( @{ $conf{via} } ) {
		my $via_stop = { id => $via->{stop}->id };
@@ -184,8 +215,13 @@ sub new {
		}

		$self->{raw_json} = $json->decode($content);
		if ($conf{from} and $conf{to}) {
			$self->parse_connections;
		}
		elsif ($conf{offers}) {
			$self->parse_offers;
		}
	}

	return $self;
}
@@ -258,7 +294,6 @@ sub post_with_cache {
	);

	if ( $reply->is_error ) {
		say $reply->status_line;
		return ( undef, $reply->status_line );
	}
	my $content = $reply->content;
@@ -294,6 +329,16 @@ sub parse_connections {
	}
}

sub parse_offers {
	my ($self) = @_;

	for my $offer (@{$self->{raw_json}{verbindungen}[0]{reiseAngebote} // []}) {
		push(@{$self->{offers}}, Travel::Routing::DE::DBRIS::Offer->new(
			json => $offer
		));
	}
}

# }}}
# {{{ Public Functions

@@ -305,7 +350,12 @@ sub errstr {

sub connections {
	my ($self) = @_;
	return @{ $self->{connections} };
	return @{ $self->{connections} // []};
}

sub offers {
	my ($self) = @_;
	return @{$self->{offers} // [] };
}

# }}}
+2 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ Travel::Routing::DE::DBRIS::Connection->mk_ro_accessors(
	  sched_dep rt_dep dep
	  sched_arr rt_arr arr
	  occupancy occupancy_first occupancy_second
	  price price_unit
	  price price_unit recon
	)
);

@@ -35,6 +35,7 @@ sub new {
		  // -1,
		is_unscheduled => $json->{isAlternativeVerbindung},
		id             => $json->{tripId},
		recon          => $json->{ctxRecon},
		price          => $json->{angebotsPreis}{betrag},
		price_unit     => $json->{angebotsPreis}{waehrung},
		strptime_obj   => $strptime,
+39 −0
Original line number Diff line number Diff line
package Travel::Routing::DE::DBRIS::Offer;

use strict;
use warnings;
use 5.020;
use utf8;

use parent 'Class::Accessor';

our $VERSION = '0.03';

Travel::Routing::DE::DBRIS::Offer->mk_ro_accessors(
	qw(class name price price_unit));

sub new {
	my ( $obj, %opt ) = @_;

	my $json = $opt{json};

	my $ref = {
		class      => $json->{klasse} =~ s{KLASSE_}{}r,
		name       => $json->{name},
		price      => $json->{preis}{betrag},
		price_unit => $json->{preis}{waehrung},
		conditions => $json->{konditionsAnzeigen},
	};

	bless( $ref, $obj );

	return $ref;
}

sub conditions {
	my ($self) = @_;

	return @{ $self->{conditions} // [] };
}

1;