travel_time 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91279926b05e377d9d73d3f98be36f2db93a734e69d63a282f387fdb7bb6cc4c
4
- data.tar.gz: 9447eae966f88cbc91e5a3b710f3110ad70b2053e74c1140cb1338b7e81bd9bf
3
+ metadata.gz: 6f41a5c8d37b2b2be35de90168616082a28c31fd759635b1905430e3bd6b6b01
4
+ data.tar.gz: 5aae0fe795498bbbbde3379a3bdb2195e89640c55773ec31eff670b0cf8e5d72
5
5
  SHA512:
6
- metadata.gz: 1ceda4f7bfc94edbaee9680c66f2d415ffba96e0b53e29096f40f852ca0bd5c9ace69f75c21047b5ce4443ccd09866a384ebd9ae4daf12af61114a7dda6d4465
7
- data.tar.gz: 3d32c9ec52c3805db9956fdc6335f094571d83b96876471784c57a2aa75dca060f222a4b29774875020c7c8c74956d13cda09a18e592d1d5fc542e05562189b4
6
+ metadata.gz: 7a9f2d1cab48eb5f76d34b20cb77cf76db7f246007263317845d6e6566dae5167f3d63dbf40064e048a2e127ec18fd9115f0943fc8cea0e40bb2f583e4205f61
7
+ data.tar.gz: cf33e330e80a64d3701ca0f9470979146c60f6a08af3480c9fc9cbe92f91478f63a8ec8ff24a61190ad5282e9a0106ecf19a759c2e60e6ac41c228a502cc06c0
data/README.md CHANGED
@@ -193,11 +193,17 @@ puts response.body
193
193
 
194
194
  ### [Isochrones (Time Map) Fast](https://docs.traveltime.com/api/reference/isochrones-fast)
195
195
  A very fast version of Isochrone API. However, the request parameters are much more limited.
196
+ Find unions/intersections between different searches.
197
+
198
+ Body attributes:
199
+ * arrival_searches: Searches based on arrival times, split into `one_to_many` and `many_to_one`.
200
+ * unions: Define unions of shapes that are results of previously defined searches.
201
+ * intersections: Define intersections of shapes that are results of previously defined searches.
196
202
 
197
203
  ```ruby
198
204
  require 'time'
199
205
 
200
- arrival_search = {
206
+ public_transport_search = {
201
207
  id: "public transport to Trafalgar Square",
202
208
  coords: {
203
209
  lat: 51.506756,
@@ -208,10 +214,33 @@ arrival_search = {
208
214
  travel_time: 1800,
209
215
  }
210
216
 
217
+ driving_search = {
218
+ id: "driving to Trafalgar Square",
219
+ coords: {
220
+ lat: 51.506756,
221
+ lng: -0.128050
222
+ },
223
+ transportation: { type: "driving" },
224
+ arrival_time_period: 'weekday_morning',
225
+ travel_time: 1800,
226
+ }
227
+
228
+ union = {
229
+ id: 'union of driving and public transport',
230
+ search_ids: ['driving to Trafalgar Square', 'public transport to Trafalgar Square']
231
+ }
232
+
233
+ intersection = {
234
+ id: 'intersection of driving and public transport',
235
+ search_ids: ['driving to Trafalgar Square', 'public transport to Trafalgar Square']
236
+ }
237
+
211
238
  response = client.time_map_fast(
212
239
  arrival_searches: {
213
- one_to_many: [arrival_search]
240
+ one_to_many: [public_transport_search, driving_search]
214
241
  },
242
+ unions: [union],
243
+ intersections: [intersection]
215
244
  )
216
245
 
217
246
  puts response.body
@@ -12,6 +12,7 @@ module TravelTime
12
12
  extend Limiter::Mixin
13
13
 
14
14
  API_BASE_URL = 'https://api.traveltimeapp.com/v4/'
15
+ PROTO_BASE_URL = 'https://proto.api.traveltimeapp.com/api/v3/'
15
16
 
16
17
  attr_reader :connection, :proto_connection
17
18
 
@@ -39,9 +40,9 @@ module TravelTime
39
40
 
40
41
  def init_proto_connection
41
42
  @proto_connection = Faraday.new do |f|
42
- f.use TravelTime::Middleware::ProtoMiddleware
43
43
  f.response :raise_error if TravelTime.config.raise_on_failure
44
44
  f.response :logger if TravelTime.config.enable_logging
45
+ f.use TravelTime::Middleware::ProtoMiddleware
45
46
  f.adapter TravelTime.config.http_adapter || Faraday.default_adapter
46
47
  end
47
48
  end
@@ -57,7 +58,7 @@ module TravelTime
57
58
  def perform_request
58
59
  unwrap(yield)
59
60
  rescue Faraday::Error => e
60
- raise TravelTime::Error.new(response: Response.from_hash(e.response)) if e.response
61
+ raise TravelTime::Error.new(response: Response.from_hash(e.response), exception: e) if e.response
61
62
 
62
63
  raise TravelTime::Error.new(exception: e)
63
64
  rescue StandardError => e
@@ -66,6 +67,10 @@ module TravelTime
66
67
 
67
68
  def perform_request_proto
68
69
  unwrap_proto(yield)
70
+ rescue Faraday::Error => e
71
+ raise TravelTime::Error.new(response: Response.from_proto_error(e.response), exception: e) if e.response
72
+
73
+ raise TravelTime::Error.new(exception: e)
69
74
  rescue StandardError => e
70
75
  raise TravelTime::Error.new(exception: e)
71
76
  end
@@ -120,9 +125,11 @@ module TravelTime
120
125
  perform_request { connection.post('distance-map', payload, { 'Accept' => format }) }
121
126
  end
122
127
 
123
- def time_map_fast(arrival_searches:, format: nil)
128
+ def time_map_fast(arrival_searches:, unions: nil, intersections: nil, format: nil)
124
129
  payload = {
125
- arrival_searches: arrival_searches
130
+ arrival_searches: arrival_searches,
131
+ unions: unions,
132
+ intersections: intersections
126
133
  }.compact
127
134
  perform_request { connection.post('time-map/fast', payload, { 'Accept' => format }) }
128
135
  end
@@ -153,8 +160,7 @@ module TravelTime
153
160
  properties: properties, request_type: request_type)
154
161
  payload = ProtoUtils.encode_proto_message(message)
155
162
  perform_request_proto do
156
- proto_connection.post("http://proto.api.traveltimeapp.com/api/v3/#{country}/time-filter/fast/#{transport_obj.url_name}",
157
- payload)
163
+ proto_connection.post("#{PROTO_BASE_URL}#{country}/time-filter/fast/#{transport_obj.url_name}", payload)
158
164
  end
159
165
  end
160
166
 
@@ -15,7 +15,7 @@ module TravelTime
15
15
  end
16
16
 
17
17
  def parse_message(message)
18
- message || wrapped_exception&.message || description || DEFAULT_MESSAGE
18
+ message || description || wrapped_exception&.message || DEFAULT_MESSAGE
19
19
  end
20
20
 
21
21
  def description
@@ -37,7 +37,8 @@ module TravelTime
37
37
  private
38
38
 
39
39
  def extract_from_body(field)
40
- response&.body&.[](field)
40
+ body = response&.body
41
+ body[field] if body.is_a?(Hash)
41
42
  end
42
43
  end
43
44
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'faraday'
4
4
  require 'base64'
5
+ require 'travel_time/error'
5
6
 
6
7
  module TravelTime
7
8
  module Middleware
@@ -9,8 +10,11 @@ module TravelTime
9
10
  # on each request. These are automatically taken from the `TravelTime.config`.
10
11
  class ProtoMiddleware < Faraday::Middleware
11
12
  def on_request(env)
13
+ scheme = env.url.scheme
14
+ raise TravelTime::Error, "Refusing to send credentials over #{scheme}" unless scheme == 'https'
15
+
12
16
  env.request_headers['Authorization'] =
13
- "Basic #{Base64.encode64("#{TravelTime.config.application_id}:#{TravelTime.config.api_key}")}"
17
+ "Basic #{Base64.strict_encode64("#{TravelTime.config.application_id}:#{TravelTime.config.api_key}")}"
14
18
  env.request_headers['Content-Type'] = 'application/octet-stream'
15
19
  env.request_headers['Accept'] = 'application/octet-stream'
16
20
  env.request_headers['User-Agent'] = 'Travel Time Ruby SDK'
@@ -19,7 +19,7 @@ module TravelTime
19
19
  new(
20
20
  status: response.status,
21
21
  headers: response.headers,
22
- body: response.success? ? ProtoUtils.decode_proto_response(response.body) : nil
22
+ body: response.success? ? ProtoUtils.decode_proto_response(response.body) : proto_error(response.headers)
23
23
  )
24
24
  end
25
25
 
@@ -31,6 +31,25 @@ module TravelTime
31
31
  )
32
32
  end
33
33
 
34
+ def self.from_proto_error(response)
35
+ new(
36
+ status: response[:status],
37
+ headers: response[:headers],
38
+ body: proto_error(response[:headers])
39
+ )
40
+ end
41
+
42
+ # Keyed by the fields TravelTime::Error reads from a JSON error body. Header values are always
43
+ # strings, where the JSON API gives an integer error_code and a hash additional_info.
44
+ def self.proto_error(headers)
45
+ {
46
+ 'error_code' => headers['X-ERROR-CODE'],
47
+ 'description' => headers['X-ERROR-MESSAGE'],
48
+ 'additional_info' => headers['X-ERROR-DETAILS']
49
+ }
50
+ end
51
+ private_class_method :proto_error
52
+
34
53
  def initialize(status: nil, headers: nil, body: nil)
35
54
  @status = status
36
55
  @headers = headers
@@ -16,7 +16,7 @@ module TravelTime
16
16
  'driving+pt': { code: 2, url_name: 'pt' },
17
17
  driving: { code: 1, url_name: 'driving' },
18
18
  walking: { code: 4, url_name: 'walking' },
19
- cycling: { code: 5, url_name: 'driving' },
19
+ cycling: { code: 5, url_name: 'cycling' },
20
20
  'driving+ferry': { code: 3, url_name: 'driving+ferry' },
21
21
  'cycling+ferry': { code: 6, url_name: 'cycling+ferry' },
22
22
  'walking+ferry': { code: 7, url_name: 'walking+ferry' }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TravelTime
4
- VERSION = '0.8.1'
4
+ VERSION = '0.9.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: travel_time
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TravelTime Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-24 00:00:00.000000000 Z
11
+ date: 2026-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64