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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 371e96298472d334dcfbce42c20bc6a67813139a
4
- data.tar.gz: 3dc98f7e626ed7d6092b912a8e3441047bffb0c3
3
+ metadata.gz: 5a7346ed6637e992bd4ce2dc1be20d8b1e44fcf8
4
+ data.tar.gz: 2d681f7d329983887a33aed98d6399fde4097c85
5
5
  SHA512:
6
- metadata.gz: 89a404991c7555b8c65ccfa57987f8e553b03f18c284be6a73536ab0ab3213e8060e32faafe29b2d4b8492c340d0ec8586ffe7cbf0b678ba8f71efe1485b69aa
7
- data.tar.gz: a19cc680b00bc2244cf8670e0c60e60c91a92e75a0bade68004abc8adfc6f3c9e90a58000cc25700b0186629cbf0de49969162831c34a5caff3b9c48e40bccb9
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'
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Gares
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
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'