From f9a1b9d76d368679922e64ee7fbee86742957315 Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Tue, 31 Oct 2017 23:17:06 +0000 Subject: [PATCH] Initial commit --- Changes | 4 ++ MANIFEST | 6 +++ Makefile.PL | 25 +++++++++ README | 31 +++++++++++ lib/WWW/Oxontime.pm | 122 ++++++++++++++++++++++++++++++++++++++++++++ t/WWW-Oxontime.t | 11 ++++ 6 files changed, 199 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 README create mode 100644 lib/WWW/Oxontime.pm create mode 100644 t/WWW-Oxontime.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..c0a2930 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +Revision history for Perl extension WWW::Oxontime. + +0.001 2017-10-31T23:17+00:00 + - Initial release diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..d20f272 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,6 @@ +Changes +Makefile.PL +MANIFEST +README +t/WWW-Oxontime.t +lib/WWW/Oxontime.pm diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..2f70d00 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,25 @@ +use 5.014000; +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'WWW::Oxontime', + VERSION_FROM => 'lib/WWW/Oxontime.pm', + ABSTRACT_FROM => 'lib/WWW/Oxontime.pm', + AUTHOR => 'Marius Gavrilescu ', + MIN_PERL_VERSION => '5.14.0', + LICENSE => 'perl', + SIGN => 1, + PREREQ_PM => { + qw/HTML::Tree 0 + JSON::MaybeXS 0/, + }, + TEST_REQUIRES => { + qw/Test::RequiresInternet 0/, + }, + META_ADD => { + dynamic_config => 0, + resources => { + repository => 'https://git.ieval.ro/?p=www-oxontime.git', + }, + } +); diff --git a/README b/README new file mode 100644 index 0000000..9b0e431 --- /dev/null +++ b/README @@ -0,0 +1,31 @@ +WWW-Oxontime version 0.001 +========================== + +This module wraps L to provide live bus +departures in Oxford. + +INSTALLATION + +To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + +This module requires these other modules and libraries: + +* HTML::Tree +* JSON::MaybeXS + +COPYRIGHT AND LICENCE + +Copyright (C) 2017 by Marius Gavrilescu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.26.1 or, +at your option, any later version of Perl 5 you may have available. + + diff --git a/lib/WWW/Oxontime.pm b/lib/WWW/Oxontime.pm new file mode 100644 index 0000000..a277472 --- /dev/null +++ b/lib/WWW/Oxontime.pm @@ -0,0 +1,122 @@ +package WWW::Oxontime; + +use 5.014000; +use strict; +use warnings; +use parent qw/Exporter/; + +our $VERSION = '0.001'; +our @EXPORT_OK = qw/stops_for_route departures_for_stop/; +our @EXPORT = ''; + +use HTML::TreeBuilder; +use HTTP::Tiny; +use JSON::MaybeXS; +use Time::Piece; + +our $STOPS_URL = 'http://www.buscms.com/Nimbus/operatorpages/widgets/departureboard/ssi.aspx?method=updateRouteStops&routeid=%d&callback=cb&_=%d'; +our $DEPARTS_URL = 'http://www.buscms.com/api/REST/html/departureboard.aspx?clientid=Nimbus&stopid=%d&format=jsonp&cachebust=123&sourcetype=siri&requestor=Netescape&includeTimestamp=true&_=%d'; +our $DEPART_TIME_FORMAT = '%d/%m/%Y %T'; + +our $ht = HTTP::Tiny->new(agent => "WWW-Oxontime/$VERSION"); + +sub stops_for_route { + my ($route_id) = @_; + my $url = sprintf $STOPS_URL, int $route_id, time; + my $result = $ht->get($url); + die $result->{reason} unless $result->{success}; + my $json = $result->{content}; + $json = substr $json, 3, (length $json) - 5; + my $stops = decode_json($json)->{stops}; + wantarray ? @$stops : $stops +} + +sub departures_for_stop { + my ($stop_id) = @_; + my $url = sprintf $DEPARTS_URL, int $stop_id, time; + my $result = $ht->get($url); + die $result->{reason} unless $result->{success}; + my $content = $result->{content}; + $content =~ s/\s/ /g; # replaces tabs with spaces + $content = JSON->new->allow_nonref(1)->decode(qq/"$content"/); + my $html = HTML::TreeBuilder->new_from_content($content); + + my @lines = $html->look_down(class => qr/\browServiceDeparture\b/); + my @result = map { + my @cells = $_->find('td'); + my $departs = $cells[2]->attr('data-departureTime'); + +{ + service => $cells[0]->as_trimmed_text, + destination => $cells[1]->as_trimmed_text, + departs => Time::Piece->strptime($departs, $DEPART_TIME_FORMAT), + } + } @lines; + wantarray ? @result : \@result +} + +1; +__END__ + +=encoding utf-8 + +=head1 NAME + +WWW::Oxontime - live Oxford bus departures from Oxontime + +=head1 SYNOPSIS + + use WWW::Oxontime qw/stops_for_route departures_for_stop/; + my @stops_on_8_outbound = stops_for_route 15957; + my $queens_lane = $stops_on_8_outbound[2]->{stopId}; + my @from_queens_lane = departures_for_stop $queens_lane; + for my $entry (@from_queens_lane) { + say $entry->{service}, ' towards ', $entry->{destination}, ' departs at ', $entry->{departs}; + } + +=head1 DESCRIPTION + +This module wraps L to provide live bus +departures in Oxford. + +Two methods can be exported (none by default): + +=over + +=item B(I<$route_id>) + +Given a route ID (these can be obtained by inspecting the homepage of +Oxontime), returns in list context a list of hashrefs having the keys +C (name of stop) and C (ID of stop, suitable for +passing to C). In scalar context, an arrayref +containing this list is returned. + +=item B(I<$stop_id>) + +Given a stop ID (these can be obtained by inspecting the homepage of +Oxontime or by calling C), returns in list context a +list of hashrefs having the keys C (name of service and +company that runs it), C (where the service is finishing) +and C (L object representing the time when the +service departs). In scalar context, an arrayref containing the list +is returned. + +Note that C is in the time zone of Oxford, but Time::Piece +interprets it as being in local time. If local time is different from +time in Oxford, this needs to be taken into account. + +=back + +=head1 AUTHOR + +Marius Gavrilescu, Emarius@ieval.roE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2017 by Marius Gavrilescu + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.26.1 or, +at your option, any later version of Perl 5 you may have available. + + +=cut diff --git a/t/WWW-Oxontime.t b/t/WWW-Oxontime.t new file mode 100644 index 0000000..7b058aa --- /dev/null +++ b/t/WWW-Oxontime.t @@ -0,0 +1,11 @@ +#!/usr/bin/perl +use strict; +use warnings; + +use Test::RequiresInternet ('www.oxontime.com' => 80); + +use Test::More tests => 2; +BEGIN { use_ok('WWW::Oxontime', 'stops_for_route') }; + +my @stops = stops_for_route 15957; +ok @stops > 1, 'route 15957 has at least two stops'; -- 2.30.2