gares 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -0
- data/gares.gemspec +1 -0
- data/lib/gares/train.rb +62 -0
- data/lib/gares/train_stop.rb +86 -0
- data/lib/gares/version.rb +1 -1
- data/lib/gares.rb +3 -0
- data/spec/fixtures/get-train-11641 +547 -0
- data/spec/fixtures/get-train-17495 +539 -0
- data/spec/fixtures/get-train-17709 +713 -0
- data/spec/fixtures/get-train-6815 +352 -0
- data/spec/fixtures/post-train-11641 +0 -0
- data/spec/fixtures/post-train-17495 +0 -0
- data/spec/fixtures/post-train-17709 +0 -0
- data/spec/fixtures/post-train-6815 +0 -0
- data/spec/gares/train_spec.rb +96 -0
- data/spec/spec_helper.rb +30 -1
- data/tasks/fixtures.rake +22 -0
- metadata +26 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a7346ed6637e992bd4ce2dc1be20d8b1e44fcf8
|
4
|
+
data.tar.gz: 2d681f7d329983887a33aed98d6399fde4097c85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca67937fb6fdfc242aefebb4661e67f456fde6512463ee367cab41bf33a06d0be452b21e8e5a1002ad75c28b22f0f044209cab6b899560295917303feaedf34d
|
7
|
+
data.tar.gz: 58958615ac14299dbae8ee968e8ef22ce9e9eeaf71bfddcc5664412c214a118f480bba287e38df92ad20353e9c44684c96e8e578c643f580e315c1df0c04852b
|
data/README.md
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
## Description
|
6
6
|
|
7
7
|
The Gares gem allows you to easily access publicly available data from gares-en-mouvement.com.
|
8
|
+
It can also retrieve data from sncf.com for live train information.
|
8
9
|
|
9
10
|
## Features
|
10
11
|
|
@@ -12,6 +13,7 @@ Gares currently features the following:
|
|
12
13
|
|
13
14
|
* Search for a station
|
14
15
|
* Retrieve station information
|
16
|
+
* Search for a train to get live information about it
|
15
17
|
|
16
18
|
## Examples
|
17
19
|
|
@@ -34,6 +36,8 @@ Gares currently features the following:
|
|
34
36
|
[g.lat, g.long]
|
35
37
|
#=> [45.760281, 4.859801]
|
36
38
|
|
39
|
+
See the [`Gares::Base` class documentation](http://www.rubydoc.info/github/paulrbr/gares/master/Gares/Base) for all available data on a station.
|
40
|
+
|
37
41
|
### Searching:
|
38
42
|
|
39
43
|
g = Gares::Search.new("Aix")
|
@@ -49,6 +53,30 @@ Gares currently features the following:
|
|
49
53
|
station.name
|
50
54
|
#=> "Paris Gare de Lyon"
|
51
55
|
|
56
|
+
### Train information:
|
57
|
+
|
58
|
+
train = Gares::Train.new(11641, Time.now)
|
59
|
+
|
60
|
+
train.departure.station
|
61
|
+
#=> #<Gares::Station:0x000f0000000000 @slug="frpst", @name="Paris Est">
|
62
|
+
|
63
|
+
train.departure.departure_date
|
64
|
+
#=> 2015-04-25 06:42:00 +0200
|
65
|
+
|
66
|
+
train.stops.size
|
67
|
+
#=> 12
|
68
|
+
|
69
|
+
train.delayed?
|
70
|
+
#=> false
|
71
|
+
|
72
|
+
train.arrival.station.name
|
73
|
+
#=> "Culmont - Chalindrey"
|
74
|
+
|
75
|
+
train.arrival.platform
|
76
|
+
#=> "B"
|
77
|
+
|
78
|
+
See the [`Gares::Train` class documentation](http://www.rubydoc.info/github/paulrbr/gares/master/Gares/Train) for all available data on a train.
|
79
|
+
|
52
80
|
## Installation
|
53
81
|
|
54
82
|
gem install gares
|
@@ -85,6 +113,8 @@ the fixture files once with up-to-date content:
|
|
85
113
|
|
86
114
|
$ rake fixtures:refresh
|
87
115
|
|
116
|
+
__Warning: this will probably break some tests, in particular the live train information tests.__
|
117
|
+
|
88
118
|
When you run the test suite now, it will use the updated fixture files.
|
89
119
|
|
90
120
|
## Disclaimer
|
data/gares.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency 'nokogiri', '~> 1.6'
|
23
23
|
s.add_dependency 'hashie', '~> 3.4'
|
24
24
|
s.add_dependency 'unidecoder', '~> 1.1'
|
25
|
+
s.add_dependency 'httparty', '~> 0.13'
|
25
26
|
|
26
27
|
s.add_development_dependency 'rake'
|
27
28
|
s.add_development_dependency 'rspec'
|
data/lib/gares/train.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
module Gares
|
5
|
+
# Represents something a train from http://www.sncf.com/fr/horaires-info-trafic/train
|
6
|
+
class Train
|
7
|
+
attr_accessor :date, :number
|
8
|
+
|
9
|
+
# Initialize a new Train object with it's number and departure date
|
10
|
+
#
|
11
|
+
# train = Gares::Train.new(6704, Time.parse('2015-04-15'))
|
12
|
+
#
|
13
|
+
# Gares::Train objects are lazy loaded, meaning that no HTTP request
|
14
|
+
# will be performed when a new object is created. An HTTP request is made (once)
|
15
|
+
# Only when you use an accessor that needs the remote data.
|
16
|
+
def initialize(number, date)
|
17
|
+
fail "Please provide a train number" unless number.is_a?(Integer)
|
18
|
+
fail "Please provide a departure date" unless date.is_a?(Time)
|
19
|
+
|
20
|
+
@number = number
|
21
|
+
@date = date
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [TrainStop] The departure point of the train
|
25
|
+
def departure
|
26
|
+
@departure ||= TrainStop.new(document.at('tr.itinerary-start'), @date)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Array<TrainStop>] A list of all stops between departure and arrival stations.
|
30
|
+
def stops
|
31
|
+
@stops ||= document.css('tr.itinerary-stop').map { |stop| TrainStop.new(stop, @date) }
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [TrainStop] The arrival point of the train
|
35
|
+
def arrival
|
36
|
+
@arrival ||= TrainStop.new(document.at('tr.itinerary-end'), @date)
|
37
|
+
end
|
38
|
+
|
39
|
+
def delayed?
|
40
|
+
([departure] + stops + [arrival]).any?(&:delayed?)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Returns a new Nokogiri document for parsing.
|
46
|
+
def document
|
47
|
+
@document ||= Nokogiri::HTML(self.class.request_sncf(@number, @date))
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.request_sncf(number, date)
|
51
|
+
uri = URI.parse("http://www.sncf.com/sncf/train")
|
52
|
+
response = Net::HTTP.post_form(uri, {"numeroTrain" => number, "date" => date.strftime("%d/%m/%Y")})
|
53
|
+
cookies = response.get_fields('Set-Cookie').map { |cookie| cookie.split(";").first }.join(";")
|
54
|
+
|
55
|
+
uri = URI.parse("http://www.sncf.com/en/horaires-info-trafic/train/resultats")
|
56
|
+
req = Net::HTTP::Get.new(uri.path)
|
57
|
+
req.add_field("Cookie", cookies)
|
58
|
+
Net::HTTP.new(uri.host, uri.port).start { |http| http.request(req) }.body
|
59
|
+
end
|
60
|
+
|
61
|
+
end # Train
|
62
|
+
end # Gares
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Gares
|
4
|
+
# Represents a stop for a train from http://www.sncf.com/fr/horaires-info-trafic/train
|
5
|
+
class TrainStop
|
6
|
+
# @!attribute departure_date
|
7
|
+
# @return [Time] The scheduled departure date at this stop.
|
8
|
+
|
9
|
+
# @!attribute real_departure_date
|
10
|
+
# @return [Time] The live schedule departure date at this stop.
|
11
|
+
|
12
|
+
# @!attribute arrival_date
|
13
|
+
# @return [Time] The scheduled arrival date at this stop.
|
14
|
+
|
15
|
+
# @!attribute real_arrival_date
|
16
|
+
# @return [Time] The live schedule departure date at this stop.
|
17
|
+
|
18
|
+
# @!attribute station
|
19
|
+
# @return [Station] The station in which this train is stopping.
|
20
|
+
|
21
|
+
# @!attribute platform
|
22
|
+
# @return [String] The platform number/letter if available.
|
23
|
+
|
24
|
+
# @!attribute formatted_info
|
25
|
+
# @return [String] A formatted detailed information in HTML.
|
26
|
+
|
27
|
+
attr_accessor :departure_date, :real_departure_date, :arrival_date, :real_arrival_date,
|
28
|
+
:station, :platform, :formatted_info
|
29
|
+
|
30
|
+
# Given the HTML node from sncf.com/fr/horaires-info-trafic/train containing the stop
|
31
|
+
# and the +date+ for this train stop.
|
32
|
+
# The object gathers all useful information about the stop made by the train.
|
33
|
+
def initialize(nokogiri_node, date)
|
34
|
+
initialize_dates(nokogiri_node, date)
|
35
|
+
initialize_station(nokogiri_node)
|
36
|
+
@platform = nokogiri_node.at('td.track').inner_html.strip
|
37
|
+
@formatted_info = nokogiri_node.at('td.info').inner_html.strip
|
38
|
+
end
|
39
|
+
|
40
|
+
def delayed?
|
41
|
+
minutes_of_delay > 0
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Integer] The amount of minutes of delay at this stop.
|
45
|
+
def minutes_of_delay
|
46
|
+
if @real_departure_date
|
47
|
+
(@real_departure_date - @departure_date) / 60
|
48
|
+
else
|
49
|
+
0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def initialize_dates(node, date)
|
56
|
+
raw_time = node.at('td.time').inner_html.strip
|
57
|
+
raw_real_time = node.at('td.new-schedule').inner_html.strip
|
58
|
+
raw_arrival_time = raw_time.split('<br/>').first
|
59
|
+
raw_departure_time = raw_time.split('<br/>').last
|
60
|
+
raw_real_arrival_time = raw_real_time.split('<br/>').first
|
61
|
+
raw_real_departure_time = raw_real_time.split('<br/>').last
|
62
|
+
|
63
|
+
@departure_date = Time.parse(raw_departure_time, date)
|
64
|
+
@arrival_date = Time.parse(raw_arrival_time, date)
|
65
|
+
if raw_real_departure_time
|
66
|
+
@real_departure_date = Time.parse(raw_real_departure_time, date)
|
67
|
+
end
|
68
|
+
if raw_real_arrival_time
|
69
|
+
@real_arrival_date = Time.parse(raw_real_arrival_time, date)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize_station(node)
|
74
|
+
raw_name = node.at('td.stations div.station').inner_html.strip
|
75
|
+
stations = Station.search(raw_name)
|
76
|
+
@station = if stations.size > 1
|
77
|
+
stations.find do |station|
|
78
|
+
name = /(^#{raw_name}$|^#{raw_name} | #{raw_name}$| #{raw_name} )/i
|
79
|
+
station.name.match(name)
|
80
|
+
end
|
81
|
+
else
|
82
|
+
stations.first
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/gares/version.rb
CHANGED
data/lib/gares.rb
CHANGED
@@ -7,6 +7,7 @@ require 'nokogiri'
|
|
7
7
|
require 'json'
|
8
8
|
require 'hashie'
|
9
9
|
require 'unidecoder'
|
10
|
+
require 'httparty'
|
10
11
|
|
11
12
|
require 'gares/base'
|
12
13
|
require 'gares/station'
|
@@ -15,4 +16,6 @@ require 'gares/sales'
|
|
15
16
|
require 'gares/services'
|
16
17
|
require 'gares/search'
|
17
18
|
require 'gares/string_extensions'
|
19
|
+
require 'gares/train'
|
20
|
+
require 'gares/train_stop'
|
18
21
|
require 'gares/version'
|