File Coverage

blib/lib/WWW/IRail/API/Connections.pm
Criterion Covered Total %
statement 21 23 91.3
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package WWW::IRail::API::Connections;
2             BEGIN {
3 1     1   1899 $WWW::IRail::API::Connections::AUTHORITY = 'cpan:ESSELENS';
4             }
5             BEGIN {
6 1     1   20 $WWW::IRail::API::Connections::VERSION = '0.003';
7             }
8 1     1   9 use strict;
  1         3  
  1         40  
9              
10 1     1   5 use Carp qw/croak/;
  1         2  
  1         57  
11 1     1   5 use Date::Format;
  1         2  
  1         69  
12 1     1   81 use DateTime::Format::Natural;
  1         2  
  1         48  
13 1     1   7 use HTTP::Request::Common;
  1         1  
  1         72  
14 1     1   5 use JSON::XS;
  1         3  
  1         57  
15 1     1   563 use XML::Simple;
  0            
  0            
16             use YAML qw/freeze/;
17              
18              
19             sub make_request {
20             my %attr = ref $_[0] eq 'HASH' ? %{$_[0]} : @_;
21              
22             croak 'from is a required argument' unless defined $attr{from};
23             croak 'to is a required argument' unless defined $attr{to};
24              
25             # reformat several different date input formats
26             if ($attr{date} =~ m/^\d+$/ ) { $attr{date} = time2str( "%d%m%y", $attr{data} ) }
27             elsif ($attr{date} =~ m/^\d{2}(\d{2})\W?(\d{2})\W?(\d{2})$/) { $attr{data} = "$3$2$1" }
28              
29             # reformat time input formats
30             if ($attr{date} =~ m/(\d{2})\W?(\d{2})/) { $attr{date} = "$1$2" }
31            
32             # if date contains words, try to parse it as natural language
33             if ($attr{date} =~ m/\w/) {
34             my $dateparser = new DateTime::Format::Natural(prefer_future => 1);
35             my $dt = $dateparser->parse_datetime( $attr{date} );
36             if($dateparser->success) {
37             $attr{'date'} = sprintf("%02d%02d%02d", $dt->day, $dt->month, substr($dt->year,2,2) );
38             $attr{'time'} = sprintf("%02d%02d", $dt->hour, $dt->min);
39             }
40             }
41              
42             croak 'date could not be parsed' unless $attr{date} =~ m/^\d{6}$/ and int($attr{date}) != 0;
43              
44             my $url = 'http://dev.api.irail.be/connections/?'.
45             join '&', map { $_.'='.$attr{$_} }
46             qw/from to date time/;
47              
48             my $req = new HTTP::Request(GET => $url);
49              
50             return $req;
51             }
52              
53             sub parse_response {
54             my ($http_response, $dataType) = @_;
55              
56             my $obj = XMLin($http_response->content,
57             NoAttr => $dataType eq 'XML' ? 0 : 1,
58             SuppressEmpty => '',
59             NormaliseSpace => 2,
60             ForceArray => [ 'connection','via' ],
61             KeepRoot => $dataType =~ /XML/i ? 0 : 1,
62             GroupTags => { connections => 'connection', vias => 'via' },
63             KeyAttr => [],
64             );
65              
66             for ($dataType) {
67             /xml/i and return XMLout $obj, RootName=>'connections',KeepRoot => 0, GroupTags => { connections => 'connection', vias => 'via' };
68             /json/i and return JSON::XS->new->ascii->pretty->allow_nonref->encode($obj);
69             /yaml/i and return freeze $obj;
70             /perl/i and return $obj;
71             }
72              
73             return $obj; # default to perl
74              
75             }
76              
77             42;
78              
79              
80              
81             =pod
82              
83             =head1 VERSION
84              
85             version 0.003
86              
87             =head1 NAME
88              
89             WWW::IRail::API::Connections - HTTP::Request builder and HTTP::Response parser for the IRail API (Train)Connection data
90              
91             =head1 SYNOPSIS
92              
93             make_request( from => 'brussel noord', to => 'oostende' );
94              
95             =head1 DESCRIPTION
96              
97             This module builds a L and has a parser for the
98             L. It's up to you to transmit it over the wire. If don't want
99             to do that yourself, don't use this module directly and use L
100             instead.
101              
102             =head1 METHODS
103              
104             =head2 make_request( I 'val'> | I<{ key => 'val' }> )
105              
106             C and C are the only arguments required, all time and date arguments default
107             to the current time and date on the iRail API side.
108              
109             make_request (
110             from => 'oostende',
111             to => 'brussel noord',
112             date => '2010-11-28' || '20101128' || 'tomorrow afternoon',
113             time => '6:24' || 1290922133,
114             );
115              
116             =head2 parse_response( I<$http_response>, I )
117              
118             parses the HTTP::Response you got back from the server, which if all went well contains XML.
119             That XML is then transformed into other data formats
120              
121             =over 4
122              
123             =item *
124              
125             xml
126              
127             =item *
128              
129             XML
130              
131             =item *
132              
133             YAML
134              
135             =item *
136              
137             JSON
138              
139             =item *
140              
141             perl (default)
142              
143             =back
144              
145             =head3 example of output when dataType = 'xml'
146              
147             =head1 METHODS
148              
149             =begin xml
150              
151            
152            
153            
154            
155            
156            
157            
158            
159            
160            
161            
162            
163            
164            
165            
166              
167            
168              
169            
170              
171             =end xml
172              
173             =head3 example of output when dataType = 'XML'
174              
175             =begin xml
176              
177            
178            
179            
180             3
181             OOSTENDE
182            
183            
184            
185             NA
186             BRUXELLES NORD
187            
188            
189            
190            
191            
192             7
193             OOSTENDE
194            
195            
196            
197             4
198             BRUXELLES NORD
199            
200            
201            
202            
203            
204            
205            
206            
207            
208            
209             BRUGGE
210            
211            
212            
213              
214            
215            
216              
217             =end xml
218              
219             =head3 example of output when dataType = 'JSON'
220              
221             =begin json
222              
223             {
224             "connections" : [
225             {
226             "duration" : "4860",
227             "departure" : {
228             "station" : "BRUXELLES NORD",
229             "time" : "1290927360",
230             "vehicle" : "BE.NMBS.IC529",
231             "platform" : "NA"
232             },
233             "arrival" : {
234             "station" : "OOSTENDE",
235             "time" : "1290932220",
236             "vehicle" : "BE.NMBS.IC529",
237             "platform" : "3"
238             }
239             },
240             {
241             "duration" : "5040",
242             "departure" : {
243             "station" : "BRUXELLES NORD",
244             "time" : "1290928980",
245             "vehicle" : "BE.NMBS.IC1529",
246             "platform" : "4"
247             },
248             "vias" : [
249             {
250             "station" : "BRUGGE",
251             "timeBetween" : "300",
252             "vehicle" : "BE.NMBS.IC1529",
253             "departure" : {
254             "time" : "1290933240",
255             "platform" : "7"
256             },
257             "arrival" : {
258             "time" : "1290932940",
259             "platform" : "5"
260             }
261             }
262             ],
263             "arrival" : {
264             "station" : "OOSTENDE",
265             "time" : "1290934020",
266             "vehicle" : "BE.NMBS.IC829",
267             "platform" : "7"
268             }
269             },
270              
271             // ... snip ...
272             ]
273             }
274              
275             =end json
276              
277             =head3 example of output when dataType = 'YAML'
278              
279             =for YAML ---
280             connections:
281             - arrival:
282             platform: 3
283             station: OOSTENDE
284             time: 1290932220
285             vehicle: BE.NMBS.IC529
286             departure:
287             platform: NA
288             station: BRUXELLES NORD
289             time: 1290927360
290             vehicle: BE.NMBS.IC529
291             duration: 4860
292             - arrival:
293             platform: 7
294             station: OOSTENDE
295             time: 1290934020
296             vehicle: BE.NMBS.IC829
297             departure:
298             platform: 4
299             station: BRUXELLES NORD
300             time: 1290928980
301             vehicle: BE.NMBS.IC1529
302             duration: 5040
303             vias:
304             - arrival:
305             platform: 5
306             time: 1290932940
307             departure:
308             platform: 7
309             time: 1290933240
310             station: BRUGGE
311             timeBetween: 300
312             vehicle: BE.NMBS.IC1529
313              
314             =head3 example of output when dataType="perl" (default)
315              
316             =for perl $VAR1 = {
317             'connections' => [
318             {
319             'duration' => '5040',
320             'departure' => {
321             'station' => 'BRUXELLES NORD',
322             'time' => '1290928980',
323             'vehicle' => 'BE.NMBS.IC1529',
324             'platform' => '4'
325             },
326             'arrival' => {
327             'station' => 'OOSTENDE',
328             'time' => '1290934020',
329             'vehicle' => 'BE.NMBS.IC829',
330             'platform' => '7'
331             }
332             'vias' => [
333             {
334             'station' => 'BRUGGE',
335             'timeBetween' => '300',
336             'vehicle' => 'BE.NMBS.IC1529',
337             'departure' => {
338             'time' => '1290933240',
339             'platform' => '7'
340             },
341             'arrival' => {
342             'time' => '1290932940',
343             'platform' => '5'
344             }
345             }
346             ],
347             },
348             ]
349             };
350              
351             =head1 INSTALLATION
352              
353             See perlmodinstall for information and options on installing Perl modules.
354              
355             =head1 BUGS AND LIMITATIONS
356              
357             No bugs have been reported.
358              
359             Please report any bugs or feature requests through the web interface at
360             L.
361              
362             =head1 AUTHOR
363              
364             Tim Esselens
365              
366             =head1 COPYRIGHT AND LICENSE
367              
368             This software is copyright (c) 2010 by Tim Esselens.
369              
370             This is free software; you can redistribute it and/or modify it under
371             the same terms as the Perl 5 programming language system itself.
372              
373             =cut
374              
375              
376             __END__