#!/usr/bin/env perl # Copyright (C) 2020 Daniel Friesel # # SPDX-License-Identifier: BSD-2-Clause use strict; use warnings; use 5.020; use utf8; use DateTime; use DateTime::Format::Strptime; use File::Slurp qw(read_file); use JSON; my $strp = DateTime::Format::Strptime->new( pattern => '%F', time_zone => 'Europe/Berlin' ); my $now = DateTime->now( time_zone => 'Europe/Berlin' ); sub range_is_today { my ($range) = @_; if ( $range =~ m{^(.*)/(.*)$} ) { my $dt1 = $strp->parse_datetime($1); my $dt2 = $strp->parse_datetime($2); if ( $dt1 and $dt2 and $dt1->epoch < $now->epoch < $dt2->epoch ) { return 1; } } else { if ( my $dt = $strp->parse_datetime($range) ) { if ( $dt->ymd eq $now->ymd ) { return 1; } } } return; } sub weekday_is_today { my ($weekdys) = @_; return ( ${ $weekdys->[ $now->day_of_week - 1 ] } == 1 ); } if ( @ARGV == 0 ) { exit 1; } my $data = JSON->new->utf8->decode( read_file( $ARGV[0] ) ); my %map = %{ $data->{train_variants} }; my %smap; for my $train_no ( keys %map ) { if ( @{ $map{$train_no} } == 1 ) { $smap{$train_no} = $map{$train_no}[0]; } else { my $latest_valid; my $valid_count = 0; for my $train ( @{ $map{$train_no} } ) { my $is_valid = 0; for my $schedule ( @{ $train->{schedules} // [] } ) { for my $valid ( @{ $schedule->{valid} // [] } ) { if ( range_is_today($valid) ) { $is_valid = 1; } } # invalid may override valid for certain days for my $invalid ( @{ $schedule->{invalid} // [] } ) { if ( range_is_today($invalid) ) { $is_valid = 0; } } } if ($is_valid) { $latest_valid = $train; $valid_count++; } } if ( $valid_count == 1 ) { $smap{$train_no} = $latest_valid; } else { $valid_count = 0; $latest_valid = undef; for my $train ( @{ $map{$train_no} } ) { my $is_valid = 0; for my $schedule ( @{ $train->{schedules} // [] } ) { for my $valid ( @{ $schedule->{valid} // [] } ) { if ( range_is_today($valid) and weekday_is_today( $schedule->{weekdays} ) ) { $is_valid = 1; } } # invalid may override valid for certain days for my $invalid ( @{ $schedule->{invalid} // [] } ) { if ( range_is_today($invalid) ) { $is_valid = 0; } } } if ($is_valid) { $latest_valid = $train; $valid_count++; } } if ( $valid_count == 1 ) { $smap{$train_no} = $latest_valid; } } } } delete $data->{train_variants}; $data->{train} = {%smap}; say JSON->new->utf8->canonical->encode($data);