diff options
-rw-r--r-- | cgi/index.pl | 60 | ||||
-rw-r--r-- | lib/App/VRR/Fakedisplay.pm | 28 |
2 files changed, 74 insertions, 14 deletions
diff --git a/cgi/index.pl b/cgi/index.pl index 90ef4db..2c64482 100644 --- a/cgi/index.pl +++ b/cgi/index.pl @@ -2,6 +2,9 @@ use Mojolicious::Lite; use Cache::File; +use DateTime; +use DateTime::Format::DateParse; + use App::VRR::Fakedisplay; use Travel::Status::DE::VRR; @@ -49,15 +52,62 @@ sub render_image { my $city = $self->stash('city'); my $stop = $self->stash('stop'); + my $dt_now = DateTime->now(time_zone => 'Europe/Berlin'); + $self->res->headers->content_type('image/png'); my ($results, $errstr) = get_results_for($city, $stop); - my $png = App::VRR::Fakedisplay->new(); - for my $d (@{$results}[0 .. 5]) { - $png->draw_at(0, $d->line); - $png->draw_at(30, $d->destination); - $png->draw_at(180, $d->time); + my $png = App::VRR::Fakedisplay->new(width => 180, height => 50); + for my $d (@{$results}) { + + my $line = $d->line; + my $platform = (split(qr{ }, $d->platform))[-1]; + my $destination = $d->destination; + my $time = $d->time; + my $etr; + + my $dt_dep = DateTime::Format::DateParse->parse_datetime($time, 'floating'); + my $dt; + + if ($time =~ m{ ^ \d\d? : \d\d $ }x) { + $dt = DateTime->new( + year => $dt_now->year, + month => $dt_now->month, + day => $dt_now->day, + hour => $dt_dep->hour, + minute => $dt_dep->minute, + second => $dt_dep->second, + time_zone => 'Europe/Berlin', + ); + } + else { + $dt = $dt_dep; + } + + my $duration = $dt->subtract_datetime($dt_now); + + if ($duration->is_negative) { + next; + } + elsif ($duration->in_units('minutes') == 0) { + $etr = 'sofort'; + } + elsif ($duration->in_units('hours') == 0) { + $etr = sprintf( + ' %2dmin', + $duration->in_units('minutes'), + ); + } + else { + last; + } + + $destination =~ s{ $city \s }{}ix; + + $png->draw_at(0, $line); + $png->draw_at(25, $destination); + $png->draw_at(145, $etr); $png->new_line(); } diff --git a/lib/App/VRR/Fakedisplay.pm b/lib/App/VRR/Fakedisplay.pm index 3912560..782f7ca 100644 --- a/lib/App/VRR/Fakedisplay.pm +++ b/lib/App/VRR/Fakedisplay.pm @@ -3,6 +3,7 @@ package App::VRR::Fakedisplay; use strict; use warnings; use 5.010; +use utf8; use File::ShareDir qw(dist_file); use GD; @@ -10,12 +11,12 @@ use GD; our $VERSION = '0.00'; sub new { - my ( $class, %opts ) = @_; + my ( $class, %opt ) = @_; my $self = { font_file => dist_file( 'App-VRR-Fakedisplay', 'font.png' ), - width => 300, - height => 50, + width => $opt{width} || 140, + height => $opt{height} || 40, scale => 10, offset_x => 0, offset_y => 0, @@ -44,6 +45,10 @@ sub locate_char { when (/[A-Z]/) { $y = 0; $x = (ord($char) - 65) * 10 } when (/[0-9]/) { $y = 20; $x = (ord($char) - 48) * 10 } + when (q{ä}) { $y = 40; $x = 0 } + when (q{ö}) { $y = 40; $x = 10 } + when (q{ü}) { $y = 40; $x = 20 } + when (q{ }) { $y = 90; $x = 0 } when (q{:}) { $y = 30; $x = 0 } when (q{-}) { $y = 30; $x = 10 } @@ -53,9 +58,9 @@ sub locate_char { given ($char) { when (/[WwMm]/) { $w = 8 } - when (/[BDEt]/) { $w = 5 } - when (/[il]/) { $w = 4 } - when (/[:.,]/) { $w = 3 } + when (/[BDErt ]/) { $w = 5 } + when (/[il1:]/) { $w = 4 } + when (/[.,]/) { $w = 3 } } return ($x, $y, $w, $h); @@ -72,20 +77,25 @@ sub draw_at { my $font_idx = $self->{font_idx}; + my $scale = $self->{scale}; + my ($off_x, $off_y) = ($offset_x, $self->{offset_y}); + if ($off_y >= $self->{height} or $off_x >= $self->{width}) { + return; + } + for my $char (split(qr{}, $text)) { my ($x, $y, $w, $h) = $self->locate_char($char); for my $pos_x ( $x .. ($x + $w) ) { for my $pos_y ( $y .. ($y + $h)) { if ($font->getPixel($pos_x, $pos_y) == $font_idx) { $im->filledEllipse( - ($off_x + $pos_x - $x) * 10, ($off_y + $pos_y - $y) * 10, - 10, 10, + ($off_x + $pos_x - $x) * $scale, ($off_y + $pos_y - $y) * $scale, + $scale, $scale, $c_fg ); } - say ""; } } $off_x += $w; |