#!/usr/bin/perl -w # # Get dart times and parse them into something readable # # http://www.irishrail.ie/your_journey/picker_real_time_results.asp?station_name=Glenageary&station=GYDN%2CGYUP&direction=S&mins=60&image1.x=11&image1.y=5&radioservice=1&radioservice1=1 # http://www.irishrail.ie/your_journey/picker_real_time_results.asp?station_name=Glenageary&direction=S&mins=60&image1.x=11&image1.y=5&radioservice=1&radioservice1=1 also works # use WWW::Mechanize; use HTML::TokeParser; use CGI; use strict; use constant CACHEDIR => "/var/tmp/.dartcache"; -d CACHEDIR or mkdir CACHEDIR, 0755; my $agent = WWW::Mechanize->new( env_proxy => 1, autocheck => 1 ); $agent->agent_alias( 'Windows IE 6' ); # arrange these from north to south my @locations = ( [ "Skerries", 0, 0 ], [ "Sutton", 0, 0 ], [ "Balbriggan", 0, 0 ], [ "Bayside", 0, 0 ], [ "Clontarf Road", 0, 0 ], [ "Donabate", 0, 0 ], [ "Drogheda", 0, 0 ], [ "Drumcondra", 0, 0 ], [ "Gormanston", 0, 0 ], [ "Harmonstown", 0, 0 ], [ "Howth Jct", 0, 0 ], [ "Howth", 0, 0 ], [ "Kilbarrack", 0, 0 ], [ "Killester", 0, 0 ], [ "Laytown", 0, 0 ], [ "Malahide", 0, 0 ], [ "Raheny", 0, 0 ], [ "Rush & Lusk", 0, 0 ], [ "Portmarnock", 0, 0 ], [ "Connolly", 0, 0 ], [ "Tara Street", 0, 0 ], [ "Pearse", 0, 0 ], [ "Gd Canal Dock", 0, 0 ], [ "Lansdowne Rd", 0, 0 ], [ "Sandymount", 0, 0 ], [ "Sydney Parade", 0, 0 ], [ "Booterstown", 0, 0 ], [ "Blackrock", 0, 0 ], [ "Seapoint", 0, 0 ], [ "Salthill", 53.29532, -6.15241 ], [ "Dun Laoghaire", 53.29503, -6.13496 ], [ "Sandycove", 53.28812, -6.12722 ], [ "Glenageary", 53.28132, -6.12290 ], [ "Dalkey", 53.27562, -6.10307 ], [ "Killiney", 0, 0 ], [ "Shankill", 0, 0 ], [ "Bray", 0, 0 ], [ "Greystones", 0, 0 ], ); my $station; my $cgi; my $output = "text"; my ( $wap, $html ); if ( $ENV{'REMOTE_ADDR'} ) { $cgi = new CGI; # find out what the hell is talking to us $wap = $cgi->Accept( "text/vnd.wap.wml" ); $html = $cgi->Accept( "text/html" ); # prefer wap only if it's higher up the list if ( $wap >= $html ) { $output = "wap"; } else { $output = "html"; } # or explictly requested if ( $cgi->param( "fmt" )) { $output = $cgi->param( "fmt" ); if ( $output ne "html" and $output ne "wap" and $output ne "xml" ) { $output = "html"; } } $station = $cgi->param( "station" ); } if ( $output eq "html" ) { print $cgi->header; print $cgi->start_html( -title => "DART Timetable (HTML)" ); } elsif ( $output eq "xml" ) { print $cgi->header( -type => 'text/xml' ); } elsif ( $output eq "wap" ) { print $cgi->header( -type => 'text/vnd.wap.wml', -vary => '*' ); print <<"WML"; WML } else { if ( @ARGV ) { $station = join( " ", @ARGV ); } } if ( defined( $station )) { my @times = get_times( $station ); my $se = $station; $se =~ s/\&/\&/g; if ( $output eq "wap" ) { print "\n

"; } if ( @times ) { my $maxw = 0; map { if ( length( $_->[0] ) > $maxw ) { $maxw = length( $_->[0] ); } } @times; $maxw++; print "Times for $se\n"; if ( $output ne "text" ) { print "\n"; } for my $t ( @times ) { if ( $output eq "text" ) { printf( "%-${maxw}s %-8s %7s\n", @{$t} ); } else { my @t = ( $t->[0], $t->[2] ); # skip platform print ""; } } if ( $output ne "text" ) { print "
"; print join( "", @t ); print "
\n

\n"; } if ( $output eq "wap" ) { print "
\n"; } } else { print "No scheduled services listed for $station"; } } else { # present a list of stations my @stations = get_stations(); if ( @stations ) { if ( $output eq "wap" ) { print "\n"; # print "\n"; } if ( $output ne "text" ) { # debug print "

pref wml: $wap, html: $html

\n"; print "

"; } print "Please choose a DART station"; if ( $output ne "text" ) { print "

"; } print "\n"; if ( $output eq "html" ) { print "
\n"; } if ( $output eq "wap" ) { print "

"; } if ( $output ne "text" ) { print "\n"; } if ( $output eq "wap" ) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "Get Timetable\n"; print "\n"; print "

\n\n"; } if ( $output eq "html" ) { print "\n"; print "
\n"; } # simple! if ( $output eq "text" ) { print join( "\n", @stations ) . "\n"; } } else { print STDERR "error: unable to get station list\n"; } } if ( $output eq "html" ) { print $cgi->end_html . "\n"; } elsif ( $output eq "wap" ) { print "
\n"; } sub get_times { my $station = shift; my @times; $station =~ s/\&/%26/g; my $fetch = 'http://www.iarnrodeireann.ie/your_journey/picker_real_time_results.asp?station_name=' . $station . '&direction=A&mins=60&image1.x=11&image1.y=5&radioservice=1&radioservice1=1'; my $res = $agent->get( $fetch ); if ( $res->is_success ) { my $content = $res->content; if ( $content =~ /There are no trains running/s ) { # hacky push @times, [ "There are no trains running", "", "" ]; return @times; } if ( $content =~ /invalid station/ ) { push @times, [ "You have", "picked an invalid", "station" ]; return @times; } my $parser = new HTML::TokeParser \$content; while ( my $token = $parser->get_token ) { if ( $token->[0] eq "S" and $token->[1] eq "a" and ( $token->[2]{name}||"") eq "content" ) { my $tag = $parser->get_tag( "table" ); # header $tag = $parser->get_tag( "table" ); # header 2 $tag = $parser->get_tag( "table" ); while ( $token = $parser->get_token ) { if ( $token->[0] eq "E" and $token->[1] eq "table" ) { last; } if ( $token->[0] eq "S" and $token->[1] eq "tr" ) { $tag = $parser->get_tag( "td" ); my $from = $parser->get_trimmed_text( "/td" ); $tag = $parser->get_tag( "td" ); my $plat = $parser->get_trimmed_text( "/td" ); $tag = $parser->get_tag( "td" ); my $time = $parser->get_trimmed_text( "/td" ); push @times, [ $from, $plat, $time ]; } } last; } } } else { return ( [ "error", "fetching", "page" ] ); } return @times; } sub get_stations { my @stations; if ( open( STATIONS, CACHEDIR . "/stations.txt" )) { @stations = map { chomp; $_ } ; } else { my $res = $agent->get( 'http://www.iarnrodeireann.ie/include/rtpi_stationpicker.asp?box=station&service=6' ); if ( $res->is_success) { my $c = $res->content; my $p = new HTML::TokeParser( \$c ); while ( my $t = $p->get_tag( "select" )) { if ( $t->[1]{name} eq "selectmenu" ) { while ( $t = $p->get_token ) { if ( $t->[0] eq "S" and $t->[1] eq "option" ) { my $station = $p->get_trimmed_text( "/option" ); push @stations, $station; } last if ( $t->[0] eq "E" and $t->[1] eq "select" ); } last; } } } else { return; } if ( open( STATIONS, ">" . CACHEDIR . "/stations.txt" )) { print STATIONS join( "\n", @stations ) . "\n"; close( STATIONS ); } } return @stations; }