spbus 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/example.rb +14 -18
  3. data/lib/spbus/bus.rb +2 -3
  4. data/lib/spbus/request.rb +31 -0
  5. data/lib/spbus/route.rb +6 -40
  6. data/lib/spbus/scrapers/locations.rb +48 -0
  7. data/lib/spbus/scrapers/route_details.rb +56 -0
  8. data/lib/spbus/scrapers/routes.rb +74 -0
  9. data/lib/spbus/version.rb +1 -1
  10. data/lib/spbus.rb +23 -5
  11. data/spbus.gemspec +1 -1
  12. data/spec/bus_spec.rb +12 -0
  13. data/spec/cassettes/auth_request.yml +278 -0
  14. data/spec/cassettes/{SpBus_Crawler/_fetch_routes/returns_all_bus_routes.yml → bus_routes.yml} +26269 -26401
  15. data/spec/cassettes/buses_locations.yml +276 -0
  16. data/spec/cassettes/invalid_route_detail.yml +276 -0
  17. data/spec/cassettes/normal_request.yml +136 -0
  18. data/spec/cassettes/normal_route_detail.yml +278 -0
  19. data/spec/cassettes/one_way_route_detail.yml +278 -0
  20. data/spec/request_spec.rb +39 -0
  21. data/spec/route_spec.rb +23 -32
  22. data/spec/scrapers/locations_scraper_spec.rb +24 -0
  23. data/spec/scrapers/route_details_scraper_spec.rb +68 -0
  24. data/spec/scrapers/routes_scraper_spec.rb +30 -0
  25. data/spec/spbus_spec.rb +40 -0
  26. data/spec/spec_helper.rb +1 -1
  27. metadata +35 -25
  28. data/lib/spbus/crawler.rb +0 -52
  29. data/lib/spbus/locations.rb +0 -37
  30. data/spec/cassettes/SpBus_Crawler/_fetch_routes/returns_creates_a_Route_object_for_every_found_route.yml +0 -32809
  31. data/spec/cassettes/SpBus_Locations/_fetch_locations/retrieves_all_buses_locations.yml +0 -34
  32. data/spec/cassettes/SpBus_Route/_fetch_details/sets_destination_attribute.yml +0 -36
  33. data/spec/cassettes/SpBus_Route/_fetch_details/sets_origin_attribute.yml +0 -36
  34. data/spec/cassettes/SpBus_Route/_fetch_details/sets_route_position_codes.yml +0 -36
  35. data/spec/cassettes/SpBus_Route/_to_h/returns_a_hash.yml +0 -36
  36. data/spec/crawler_spec.rb +0 -20
  37. data/spec/locations_spec.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 721321499ae1d4ad22f3f61f5802e2872ebd0f9b
4
- data.tar.gz: 9b936314c670942e1e5a8a770725267c48897a37
3
+ metadata.gz: a2ca7dae44b502aa40c4e71c960147be430435d7
4
+ data.tar.gz: 643b83405b7deb7231f966b01853818c3239c222
5
5
  SHA512:
6
- metadata.gz: cd2770c6723a184ab1bfe7abe5be0552f749f99dbc1563d8e037eb0a8d669dca810f20ee36168d486b5f7b1f0dc27db055249200d52a6471b5e283aaad7e5e0b
7
- data.tar.gz: fe6ca2c698b0ea89f7cc02ea5d49fb44f814adad7e795489f02d09ce040e829b8c85416e3ea33b11d3d8813c1c8e0a0b378a915387caea55dd63d4698ea5e434
6
+ metadata.gz: f3553382bfaaf6635602253c3ae313adaab8bd32819e4ea89dbfa94f7b95396f61e13a94064f1c877f75617a26666b2da8dc872630577799d6a3d351944a1d79
7
+ data.tar.gz: 042caf114ba9b096d978c29989ffac2f7907e16ba888535828892c40a8da170952a20b040cc450e343a3537b2ce3767a63955d40b81f7e3bdfae876f18fb2b52
data/example.rb CHANGED
@@ -1,25 +1,21 @@
1
1
  require "spbus"
2
+ require "pry"
2
3
 
3
- crawler = SpBus::Crawler.new
4
- crawler.fetch_routes
4
+ puts "Fetching all routes..."
5
5
 
6
- puts "Found #{crawler.routes.size} routes"
6
+ routes = SpBus.fetch_routes
7
7
 
8
- crawler.routes.each do |route|
9
- puts "Fetching details for route #{route.number}"
8
+ puts "Found #{routes.size} routes"
10
9
 
11
- begin
12
- route.fetch_details
13
-
14
- puts <<-EOF
15
- Origin: #{route.origin}
16
- Destination: #{route.destination}
17
- Code for origin: #{route.code_for_origin}
18
- Code for destination: #{route.code_for_destination}
19
- EOF
20
-
21
- rescue SpBus::InconsistentResponse
22
- puts "Can't fetch details for #{route.number}"
23
- end
10
+ routes.each do |route|
11
+ puts <<-EOF
12
+ Number: #{route.number}
13
+ Origin: #{route.origin}
14
+ Destination: #{route.destination}
15
+ One way?: #{route.one_way?}
16
+ Origin id: #{route.origin_id}
17
+ Destination id: #{route.destination_id}
18
+ --------------------------------------------------
19
+ EOF
24
20
  end
25
21
 
data/lib/spbus/bus.rb CHANGED
@@ -1,7 +1,6 @@
1
- require "ostruct"
2
-
3
1
  module SpBus
4
- class Bus < OpenStruct
2
+ class Bus
3
+ attr_accessor :latitude, :longitude, :route
5
4
  end
6
5
  end
7
6
 
@@ -0,0 +1,31 @@
1
+ module SpBus
2
+ class Request
3
+
4
+ AUTH_URL = "http://olhovivo.sptrans.com.br/"
5
+
6
+ attr_writer :authenticated
7
+
8
+ def initialize(url)
9
+ @url = url
10
+ @authenticated = true
11
+ end
12
+
13
+ def get
14
+ get_cookies if @authenticated
15
+ open(@url, request_headers).read
16
+ end
17
+
18
+ private
19
+
20
+ def get_cookies
21
+ @cookies = open(AUTH_URL).meta["set-cookie"]
22
+ end
23
+
24
+ def request_headers
25
+ headers = {}
26
+ headers["Cookie"] = @cookies if @authenticated
27
+ headers
28
+ end
29
+ end
30
+ end
31
+
data/lib/spbus/route.rb CHANGED
@@ -1,53 +1,19 @@
1
- # encoding: utf-8
2
-
3
1
  module SpBus
4
2
  class Route
5
3
 
6
- BUS_ROUTE_DETAILS = "http://200.189.189.54/InternetServices/BuscaLinhasSIM"
7
-
8
- attr_reader :number, :origin, :destination, :code_for_origin,
9
- :code_for_destination
4
+ attr_accessor :number, :origin, :destination, :origin_id, :destination_id
5
+ attr_writer :one_way
10
6
 
11
7
  def initialize(number)
12
8
  @number = number
13
9
  end
14
10
 
15
- def fetch_details
16
- sptrans_request
17
-
18
- raise InconsistentResponse unless valid_response?
19
-
20
- @origin = @response[0][:DenominacaoTSTP]
21
- @destination = @response[1][:DenominacaoTPTS]
22
- @code_for_origin = @response[0][:CodigoLinha]
23
- @code_for_destination = @response[1][:CodigoLinha]
24
-
25
- true
26
- end
27
-
28
- def to_h
29
- {
30
- number: number,
31
- origin: origin,
32
- destination: destination,
33
- code_for_origin: code_for_origin,
34
- code_for_destination: code_for_destination
35
- }
36
- end
37
-
38
- private
39
-
40
- def sptrans_request
41
- @response = JSON.parse(
42
- RestClient.get(BUS_ROUTE_DETAILS, params: { termosBusca: number }),
43
- symbolize_names: true
44
- )[:BuscaLinhasSIMResult]
11
+ def one_way?
12
+ !!@one_way
45
13
  end
46
14
 
47
- def valid_response?
48
- !@response.nil? && @response.size == 2 &&
49
- @response[0][:DenominacaoTSTP] == @response[1][:DenominacaoTSTP] &&
50
- @response[0][:DenominacaoTPTS] == @response[1][:DenominacaoTPTS]
15
+ def fetch_details
16
+ Scrapers::RouteDetails.new(self).fetch
51
17
  end
52
18
  end
53
19
  end
@@ -0,0 +1,48 @@
1
+ module SpBus::Scrapers
2
+ class Locations
3
+
4
+ URL = "http://olhovivo.sptrans.com.br/v0/Posicao"
5
+
6
+ attr_reader :buses
7
+
8
+ def initialize(destination_id)
9
+ @destination_id = destination_id
10
+ end
11
+
12
+ def fetch
13
+ doc = SpBus::Request.new(url_with_params).get
14
+ @json = JSON.parse(doc, symbolize_names: true)
15
+
16
+ validate_response
17
+
18
+ @buses = @json[:vs].collect do |hash|
19
+ build_bus(hash)
20
+ end
21
+
22
+ true
23
+ end
24
+
25
+ private
26
+
27
+ def url_with_params
28
+ params = URI.encode_www_form(codigoLinha: @destination_id)
29
+ "#{URL}?#{params}"
30
+ end
31
+
32
+ def validate_response
33
+ if @json.nil? ||
34
+ @json[:hr].nil? ||
35
+ @json[:hr].empty?
36
+ raise SpBus::UnknownResponse
37
+ end
38
+ end
39
+
40
+ def build_bus(hash)
41
+ bus = SpBus::Bus.new
42
+ bus.latitude = hash[:py]
43
+ bus.longitude = hash[:px]
44
+ bus
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,56 @@
1
+ module SpBus::Scrapers
2
+ class RouteDetails
3
+
4
+ URL = "http://olhovivo.sptrans.com.br/v0/Linha/Buscar"
5
+
6
+ def initialize(route)
7
+ @route = route
8
+ end
9
+
10
+ def fetch
11
+ doc = SpBus::Request.new(url_with_params).get
12
+ @json = JSON.parse(doc, symbolize_names: true)
13
+
14
+ validate_response
15
+ build_route
16
+
17
+ true
18
+ end
19
+
20
+ private
21
+
22
+ def url_with_params
23
+ params = URI.encode_www_form(termosBusca: @route.number)
24
+ "#{URL}?#{params}"
25
+ end
26
+
27
+ def validate_response
28
+ if @json.nil? ||
29
+ @json.size != 2 ||
30
+ @json[0][:DenominacaoTSTP] != @json[1][:DenominacaoTSTP] ||
31
+ @json[0][:DenominacaoTPTS] != @json[1][:DenominacaoTPTS]
32
+ raise SpBus::UnknownResponse
33
+ end
34
+ end
35
+
36
+ def build_route
37
+ origin = find_origin
38
+ destination = find_destination
39
+
40
+ @route.origin = origin[:DenominacaoTSTP]
41
+ @route.origin_id = origin[:CodigoLinha] unless @route.one_way?
42
+
43
+ @route.destination = destination[:DenominacaoTPTS]
44
+ @route.destination_id = destination[:CodigoLinha]
45
+ end
46
+
47
+ def find_origin
48
+ @json.select { |h| h[:Sentido] == 2 }.first
49
+ end
50
+
51
+ def find_destination
52
+ @json.select { |h| h[:Sentido] == 1 }.first
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ module SpBus::Scrapers
4
+ class Routes
5
+
6
+ ALL_ROUTES_URL = "http://200.99.150.170/PlanOperWeb/linhaselecionada.asp"
7
+ VALIDATOR_PATH = "#contentScroll p:first-child"
8
+ VALIDATOR_REGEX = /Foram encontrados vários resultados para a sua busca/i
9
+ ROUTE_PATH = "#contentScroll ul li .labelHold"
10
+ ROUTE_NUMBER_PATH = ".linkLinha:nth-child(1)"
11
+ ROUTE_NUMBER_REGEX = /Linha: (?<number>[a-z0-9]+[-][0-9a-z]+)/i
12
+ WAY_PATH = ".linkLinha:nth-child(2)"
13
+ WAY_MATCHER = /\(Ver Ida\)(?<two_way> \/ \(Ver Volta\))?/i
14
+ SPACES = /\u00A0|\t|\n|\r/
15
+
16
+ attr_reader :routes
17
+
18
+ def fetch
19
+ make_request
20
+ validate_response
21
+ build_routes
22
+ true
23
+ end
24
+
25
+ private
26
+
27
+ def make_request
28
+ request = SpBus::Request.new(ALL_ROUTES_URL)
29
+ request.authenticated = false
30
+
31
+ @doc = Nokogiri::HTML(request.get)
32
+ end
33
+
34
+ def validate_response
35
+ if @doc.css(VALIDATOR_PATH).inner_text !~ VALIDATOR_REGEX
36
+ raise SpBus::UnknownResponse
37
+ end
38
+ end
39
+
40
+ def build_routes
41
+ @routes = []
42
+
43
+ @doc.css(ROUTE_PATH).each do |node|
44
+ if route = build_route(node)
45
+ @routes << route
46
+ end
47
+ end
48
+ end
49
+
50
+ def normalize(str)
51
+ str.gsub(SPACES, " ").squeeze(" ").strip
52
+ end
53
+
54
+ def one_way?(node)
55
+ text = normalize(node.css(WAY_PATH).inner_text)
56
+ match = WAY_MATCHER.match(text)
57
+ match && !match[:two_way]
58
+ end
59
+
60
+ def build_route(node)
61
+ raw_number = normalize(node.css(ROUTE_NUMBER_PATH).inner_text)
62
+ match = ROUTE_NUMBER_REGEX.match(raw_number)
63
+
64
+ if match
65
+ route = SpBus::Route.new(match[:number])
66
+ route.one_way = one_way?(node)
67
+ route
68
+ else
69
+ false
70
+ end
71
+ end
72
+ end
73
+ end
74
+
data/lib/spbus/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module SpBus
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/spbus.rb CHANGED
@@ -1,13 +1,31 @@
1
- require "rest_client"
2
1
  require "nokogiri"
2
+ require "open-uri"
3
3
  require "json"
4
- require "spbus/version"
5
- require "spbus/crawler"
4
+
6
5
  require "spbus/route"
7
6
  require "spbus/bus"
8
- require "spbus/locations"
7
+ require "spbus/request"
8
+ require "spbus/scrapers/routes"
9
+ require "spbus/scrapers/route_details"
10
+ require "spbus/scrapers/locations"
11
+
12
+ require "spbus/version"
9
13
 
10
14
  module SpBus
11
- class InconsistentResponse < StandardError ; end
15
+
16
+ class UnknownResponse < StandardError ; end
17
+
18
+ def self.fetch_routes
19
+ scraper = Scrapers::Routes.new
20
+ scraper.fetch
21
+ scraper.routes.each(&:fetch_details)
22
+ scraper.routes
23
+ end
24
+
25
+ def self.fetch_buses(destination_id)
26
+ scraper = Scrapers::Locations.new(destination_id)
27
+ scraper.fetch
28
+ scraper.buses
29
+ end
12
30
  end
13
31
 
data/spbus.gemspec CHANGED
@@ -23,8 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rspec"
24
24
  spec.add_development_dependency "webmock"
25
25
  spec.add_development_dependency "vcr"
26
+ spec.add_development_dependency "pry"
26
27
 
27
28
  spec.add_dependency "nokogiri"
28
- spec.add_dependency "rest-client"
29
29
  end
30
30
 
data/spec/bus_spec.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe SpBus::Bus do
4
+ it { should respond_to(:latitude) }
5
+ it { should respond_to(:longitude) }
6
+ it { should respond_to(:route) }
7
+
8
+ it { should respond_to(:latitude=) }
9
+ it { should respond_to(:longitude=) }
10
+ it { should respond_to(:route=) }
11
+ end
12
+
@@ -0,0 +1,278 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://olhovivo.sptrans.com.br/
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - '*/*'
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Cache-Control:
22
+ - private
23
+ Content-Type:
24
+ - text/html; charset=utf-8
25
+ Server:
26
+ - Microsoft-IIS/7.5
27
+ X-Frame-Options:
28
+ - DENY
29
+ X-Aspnetmvc-Version:
30
+ - '4.0'
31
+ X-Aspnet-Version:
32
+ - 4.0.30319
33
+ Set-Cookie:
34
+ - apiCredentials-v0=10F5B3A97F2C811043EC864760E6C6FCD0259406E3F2BDCC5033990E24EC4C8A7CCFDBC0208DDC90BF200D0848BB373CA7164BC518653DE57F1D2391D31E39968B58FB3132F9A21E86586A5530D40C45FA476A02E945EC8C1055D886AE3782209118DB1C664ADC5D8BFA661221110280C4A426713F2BCD29FE5E12182DD245C210DF0DC8CBF693888413717C325E856F4863D62122672D5F014EE2E7B099D5879719A8C6511E392AF487F4AF46F6FF6F364875C9B44F03B2F0BA6DF13FDF9D96715C05682EC1AF2AFA2BF2977E83D6D8;
35
+ path=/; HttpOnly
36
+ X-Powered-By:
37
+ - ASP.NET
38
+ Date:
39
+ - Thu, 26 Sep 2013 04:37:56 GMT
40
+ Content-Length:
41
+ - '8223'
42
+ body:
43
+ encoding: ASCII-8BIT
44
+ string: !binary |-
45
+ PCFET0NUWVBFIGh0bWw+DQo8aHRtbCBpZD0iaHRtbFRhZyIgZGlyPSJsdHIi
46
+ IGxhbmc9InB0LWJyIj4NCjxoZWFkIGlkPSJodG1sV2ViSGVhZGVyIj4NCiAg
47
+ ICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNl
48
+ LXdpZHRoLCBtaW5pbXVtLXNjYWxlPTEsIGluaXRpYWwtc2NhbGU9MS4wLCB1
49
+ c2VyLXNjYWxhYmxlPW5vIiAvPg0KICAgIDxtZXRhIG5hbWU9ImRlc2NyaXB0
50
+ aW9uIiBjb250ZW50PSJPbGhvIFZpdm8gU1BUcmFuczogTm92byBzaXN0ZW1h
51
+ IGRlIGFwcm94aW1hw6fDo28gZSBsb2NhbGl6YcOnw6NvIG9ubGluZSBkb3Mg
52
+ w7RuaWJ1cyBkYSBjaWRhZGUgZGUgU8OjbyBQYXVsby4iIC8+DQogICAgPG1l
53
+ dGEgbmFtZT0ia2V5d29yZHMiIGNvbnRlbnQ9InByZXZpc8OjbywgbG9jYWxp
54
+ emHDp8OjbywgZ3BzLCDDtG5pYnVzLCBvbmlidXMsIGNvbmR1w6fDo28sIHNw
55
+ dHJhbnMsIHNwIHRyYW5zLCBzw6NvIHBhdWxvLCBwYXJhZGFzLCBwb250b3Ms
56
+ IG1hcGEsIGNhbWluaG8sIHDDumJsaWNvIiAvPg0KICAgIDxtZXRhIG5hbWU9
57
+ ImNvcHlyaWdodCIgY29udGVudD0iQ29weXJpZ2h0IDIwMTIgU8OjbyBQYXVs
58
+ byBUcmFuc3BvcnRlIFMvQS4gVG9kb3Mgb3MgZGlyZWl0b3MgcmVzZXJ2YWRv
59
+ cy4iLz4NCiAgICANCg0KICAgICAgICANCiAgICA8dGl0bGU+T2xobyBWaXZv
60
+ IFNQVHJhbnM8L3RpdGxlPg0KICAgIDxsaW5rIHJlbD0ic2hvcnRjdXQgaWNv
61
+ biIgaHJlZj0iL0NvbnRlbnQvdGhlbWUvaW1hZ2Vucy9pY29uZXMvZmF2aWNv
62
+ bi5pY28iIC8+DQogICAgPGxpbmsgcmVsPSJpY29uIiBocmVmPSIvQ29udGVu
63
+ dC90aGVtZS9pbWFnZW5zL2ljb25lcy9mYXZpY29uLmljbyIgLz4NCiAgICA8
64
+ bGluayBocmVmPSIvQ29udGVudC90aGVtZS9vbGhvdml2bz92PWRlODNWbXhD
65
+ ZVJDZjBoRV9BWHFpRDh0MHVQQi10bjB6RkJwUXRneWs3Q3MxIiByZWw9InN0
66
+ eWxlc2hlZXQiLz4NCg0KICAgIA0KICAgIDxsaW5rIGhyZWY9Ii9Db250ZW50
67
+ L3RoZW1lL29saG92aXZvZGVza3RvcD92PWh6VlZjd3ZLc0N2UHZoRk9aMmxT
68
+ c1RiQlctUEd2S29wbUw2cmxpRGxybEExIiByZWw9InN0eWxlc2hlZXQiLz4N
69
+ Cg0KPGxpbmsgaHJlZj0iL0NvbnRlbnQvdGhlbWUvb2xob3Zpdm9OT05JRT92
70
+ PVllbUhjbzkwd2hKbFo0YXV0RG1qUXZpYVFaMnRiRmYwX1g1NE45M3AyVkkx
71
+ IiByZWw9InN0eWxlc2hlZXQiLz4NCg0KICAgICAgICANCiAgICA8c2NyaXB0
72
+ IHNyYz0iaHR0cDovL21hcHMuZ29vZ2xlYXBpcy5jb20vbWFwcy9hcGkvanM/
73
+ c2Vuc29yPXRydWUmcmVnaW9uPUJSIj48L3NjcmlwdD4NCiAgICA8c2NyaXB0
74
+ PiB2YXIgX19jcF9fID0gIi8iOyA8L3NjcmlwdD4NCiAgICA8c2NyaXB0IHNy
75
+ Yz0iL2Ivb2xob3Zpdm8/dj1MengyYVZOZlJnamRJdHV6eVlRU29tTmJkZ3N0
76
+ Q0ZqNGJWc3dLTkc2bUIwMSI+PC9zY3JpcHQ+DQoNCiAgICANCiAgICAgICAg
77
+ ICAgIDxzY3JpcHQgc3JjPSIvYi9qcXVlcnlGbGFzaD92PVRCcW9QNEZVR0Jw
78
+ Z19YbjgwTFdXYkFOVmp5R2puRkQ0UmptMDluNFJXVWsxIj48L3NjcmlwdD4N
79
+ Cg0KICAgIDxzY3JpcHQ+dmFyIHBhc3NvYXBhc3NvT2xob05hVmlhID0gJy9N
80
+ YW51YWxEZU9saG9OYVZpYSc7PC9zY3JpcHQ+DQoNCiAgICAgICAgDQo8L2hl
81
+ YWQ+IA0KDQo8Ym9keT4NCjxkaXYgaWQ9InBhZ2VQcmV2aXNhbyIgZGF0YS1y
82
+ b2xlPSJwYWdlIiBkYXRhLXRoZW1lPSJzIiBzdHlsZT0ibWluLWhlaWdodDox
83
+ MDAlIj4NCiAgICANCiAgICA8ZGl2IGRhdGEtcm9sZT0iY29udGVudCIgaWQ9
84
+ InByaUNvbnRlbnQiPgkNCjxkaXYgY2xhc3M9ImNvbnRlbnQtc2Vjb25kYXJ5
85
+ IiBpZD0id2ViVG9wQ29udGVudCI+DQoJPGRpdiBjbGFzcz0iaGVhZGVyV2Vi
86
+ IGJnSGVhZGVyV2ViIj4NCgkJPGgxPk9saG8gVml2byBTUFRyYW5zIC0gTG9j
87
+ YWxpemHDp8OjbyBlIEFwcm94aW1hw6fDo28gZGUgw5RuaWJ1czwvaDE+DQog
88
+ ICAgICAgIDxkaXYgY2xhc3M9ImhlYWRlck1lbnNhZ2VtIj4NCiAgICAgICAg
89
+ ICAgIDxiPlByb2dyYW1lLXNlIGFudGVzIGRlIHNhaXIuPC9iPjxiciAvPlNh
90
+ aWJhIDxiPnF1YW5kbzwvYj4gbyBwcsOzeGltbyDDtG5pYnVzIDxiPnBvZGVy
91
+ w6EgcGFzc2FyPC9iPiwgYSA8Yj52ZWxvY2lkYWRlPC9iPiBlIG8gPGI+dGVt
92
+ cG8gZGUgdmlhZ2VtPC9iPiBub3MgcHJpbmNpcGFpcyBjb3JyZWRvcmVzIGRh
93
+ IGNpZGFkZS4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9Imxv
94
+ Z29TaWdhVHd0IiB0aXRsZT0iU2lnYSBhIFNQVHJhbnMgbm8gVHdpdHRlciI+
95
+ Jm5ic3A7PC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImJ0RG93bmxvYWRHdWlh
96
+ Ij48YSBocmVmPSIvZmlsZXMvVHV0b3JpYWxOb3ZvT2xob1Zpdm8ucGRmIiB0
97
+ YXJnZXQ9Il9ibGFuayIgdGl0bGU9IkFjZXNzZSBvIGd1aWEgZGUgdXRpbGl6
98
+ YcOnw6NvIj5BY2Vzc2UgbyA8Yj5ndWlhIGRlIHV0aWxpemHDp8OjbzwvYj48
99
+ L2E+PC9kaXY+DQoNCgkJPGRpdiBjbGFzcz0idWktZ3JpZC1iIj4NCgkJCTxk
100
+ aXYgY2xhc3M9ImhCbG9jayB1aS1ibG9jay1hIj4NCiAgICAgICAgICAgICAg
101
+ ICA8ZGl2IGNsYXNzPSJ0aXR1bG8gdGl0dWxvLWxpbmhhIj4mbmJzcDs8L2Rp
102
+ dj4NCiAgICAgICAgICAgICAgICA8YSBpZD0iYnREZU9saG9MaW5oYSIgY2xh
103
+ c3M9ImNvbnRldWRvIiBocmVmPSIjdHhTZWFyY2hMaW5oYSIgZGF0YS1yb2xl
104
+ PSJidXR0b24iPg0KICAgICAgICAgICAgICAgIDxiPkxvY2FsaXphw6fDo28g
105
+ ZG9zIMO0bmlidXM8L2I+PGJyIC8+DQogICAgICAgICAgICAgICAgQ29uc3Vs
106
+ dGUsIGFvIGxvbmdvIGRvIHRyYWpldG8gZGUgc3VhIGxpbmhhLCBvbmRlIGVz
107
+ dMOjbyBvcyDDtG5pYnVzIHF1ZSBwb2RlcsOjbyBhdGVuZMOqLWxvLg0KICAg
108
+ ICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgICAgIDwvZGl2Pg0KCQkJPGRp
109
+ diBjbGFzcz0iaEJsb2NrIHVpLWJsb2NrLWIiPg0KICAgICAgICAgICAgICAg
110
+ IDxkaXYgY2xhc3M9InRpdHVsbyB0aXR1bG8tcG9udG8iPiZuYnNwOzwvZGl2
111
+ Pg0KICAgICAgICAgICAgICAgIDxhIGlkPSJidERlT2xob1BvbnRvIiBjbGFz
112
+ cz0iY29udGV1ZG8iIGhyZWY9IiN0eFNlYXJjaFBhcmFkYSIgZGF0YS1yb2xl
113
+ PSJidXR0b24iPg0KICAgICAgICAgICAgICAgIDxiPlByw7N4aW1vcyDDtG5p
114
+ YnVzPC9iPjxiciAvPg0KICAgICAgICAgICAgICAgIFNhaWJhIGVtIHF1YW50
115
+ byB0ZW1wbyBlIHF1YWlzIGxpbmhhcyBkZSDDtG5pYnVzIHNlIGFwcm94aW1h
116
+ bSBkbyBwb250byBxdWUgdm9jw6ogZXN0w6Egb3UgaXLDoSB1dGlsaXphciBl
117
+ bSB1bSBkb3MgY29ycmVkb3JlcyBkZSDDtG5pYnVzLg0KICAgICAgICAgICAg
118
+ ICAgIDwvYT4NCiAgICAgICAgICAgIDwvZGl2Pg0KCQkJPGRpdiBjbGFzcz0i
119
+ aEJsb2NrIHVpLWJsb2NrLWMiPg0KICAgICAgICAgICAgICAgIDxkaXYgY2xh
120
+ c3M9InRpdHVsbyB0aXR1bG8tdmlhIj4mbmJzcDs8L2Rpdj4NCiAgICAgICAg
121
+ ICAgICAgICA8YSBjbGFzcz0iY29udGV1ZG8iIGhyZWY9IiNwRGVPbGhvVmlh
122
+ IiBkYXRhLXJvbGU9ImJ1dHRvbiI+DQogICAgICAgICAgICAgICAgPGI+VmVs
123
+ b2NpZGFkZSBtw6lkaWEgZSB0ZW1wbyBkZSBwZXJjdXJzbzwvYj48YnIgLz4N
124
+ CiAgICAgICAgICAgICAgICBWZWphIGNvbW8gZXN0w6EgbyBkZXNlbXBlbmhv
125
+ IGRvcyBwcmluY2lwYWlzIGNvcnJlZG9yZXMgdmnDoXJpb3MgZGEgY2lkYWRl
126
+ Lg0KICAgICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgICAgIDwvZGl2Pg0K
127
+ CQk8L2Rpdj4NCg0KCTwvZGl2Pg0KPC9kaXY+ICAgICAgICA8ZGl2IGNsYXNz
128
+ PSJjb250ZW50LXByaW1hcnkgYXBwQ29udGVudCI+DQogICAgICAgICAgICA8
129
+ dWwgZGF0YS1yb2xlPSJsaXN0dmlldyIgZGF0YS1pbnNldD0idHJ1ZSIgZGF0
130
+ YS10aGVtZT0icyI+DQogICAgICAgICAgICAgICAgPGxpIGRhdGEtcm9sZT0i
131
+ bGlzdC1kaXZpZGVyIiBpZD0ibGJsVGl0dWxvQ29uc3VsdGFIb21lIj4mbmJz
132
+ cDs8L2xpPg0KICAgICAgICAgICAgPC91bD4NCiAgICAgICAgICAgIDxkaXYg
133
+ aWQ9ImJvdG9lc1Blc3F1aXNhSW5pY2lhbCI+DQoJCQkgICAgPGRpdiBjbGFz
134
+ cz0idWktZ3JpZC1hIj4NCgkJCQkgICAgPGRpdiBjbGFzcz0idWktYmxvY2st
135
+ YSI+DQoJCQkJCSAgICA8aW5wdXQgdHlwZT0ic2VhcmNoIiBpZD0idHhTZWFy
136
+ Y2hMaW5oYSIgcGxhY2Vob2xkZXI9IkJ1c2NhIHBvciBMaW5oYXMiIHRpdGxl
137
+ PSJCdXNjYSBwb3IgTGluaGFzIiBtYXhsZW5ndGg9IjM2IiAvPg0KCQkJCSAg
138
+ ICA8L2Rpdj4NCgkJCQkgICAgPGRpdiBjbGFzcz0idWktYmxvY2stYiI+DQoJ
139
+ CQkJCSAgICA8ZGl2IGNsYXNzPSJ3cmFwcGVyIj4NCiAgICAgICAgICAgICAg
140
+ ICAgICAgICAgIDxhIGhyZWY9IiN0eFNlYXJjaExpbmhhIiBpZD0iYnRCdXNj
141
+ YUxpbmhhIiBkYXRhLXR5cGU9ImJ1dHRvbiIgZGF0YS1yb2xlPSJidXR0b24i
142
+ IGRhdGEtaW5saW5lPSJ0cnVlIj5PazwvYT4NCiAgICAgICAgICAgICAgICAg
143
+ ICAgICAgIDwvZGl2Pg0KCQkJCSAgICA8L2Rpdj4NCgkJCSAgICA8L2Rpdj48
144
+ YnIgY2xhc3M9ImJvdGgiIC8+DQoJCQkgICAgPGRpdiBjbGFzcz0idWktZ3Jp
145
+ ZC1hIj4NCgkJCQkgICAgPGRpdiBjbGFzcz0idWktYmxvY2stYSI+DQoJCQkJ
146
+ CSAgICA8aW5wdXQgdHlwZT0ic2VhcmNoIiBpZD0idHhTZWFyY2hQYXJhZGEi
147
+ IHBsYWNlaG9sZGVyPSJCdXNjYSBwb3IgUGFyYWRhcyBkZSBDb3JyZWRvciIg
148
+ dGl0bGU9IkJ1c2NhIHBvciBQYXJhZGFzIGRlIENvcnJlZG9yIiBtYXhsZW5n
149
+ dGg9IjM2IiAvPg0KCQkJCSAgICA8L2Rpdj4NCgkJCQkgICAgPGRpdiBjbGFz
150
+ cz0idWktYmxvY2stYiI+DQoJCQkJCSAgICA8ZGl2IGNsYXNzPSJ3cmFwcGVy
151
+ Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9IiN0eFNlYXJj
152
+ aFBhcmFkYSIgaWQ9ImJ0QnVzY2FQYXJhZGEiIGRhdGEtdHlwZT0iYnV0dG9u
153
+ IiBkYXRhLXJvbGU9ImJ1dHRvbiIgZGF0YS1pbmxpbmU9InRydWUiPk9rPC9h
154
+ Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQoJCQkJICAgIDwv
155
+ ZGl2Pg0KCQkJICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxzZWxlY3Qg
156
+ ZGF0YS1uYXRpdmUtbWVudT0iZmFsc2UiIGRhdGEtb3ZlcmxheS10aGVtZT0i
157
+ ZCIgaWQ9InNlbGVjdC1jb3JyZWRvciIgbmFtZT0iQ29ycmVkb3JlcyIgdGl0
158
+ bGU9IlNlbGVjaW9uZSB1bSBjb3JyZWRvciI+PG9wdGlvbiB2YWx1ZT0iIj5T
159
+ ZWxlY2lvbmUgdW0gY29ycmVkb3I8L29wdGlvbj4NCjxvcHRpb24gdmFsdWU9
160
+ IjgiPkNhbXBvIExpbXBvPC9vcHRpb24+DQo8b3B0aW9uIHZhbHVlPSI5Ij5F
161
+ eHByZXNzbyBUaXJhZGVudGVzPC9vcHRpb24+DQo8b3B0aW9uIHZhbHVlPSIz
162
+ Ij5JbmFqYXIgZGUgU291emE8L29wdGlvbj4NCjxvcHRpb24gdmFsdWU9Ijci
163
+ PlBhcmVsaGVpcm9zPC9vcHRpb24+DQo8b3B0aW9uIHZhbHVlPSIxIj5QaXJp
164
+ dHViYTwvb3B0aW9uPg0KPG9wdGlvbiB2YWx1ZT0iMiI+U2FudG8gQW1hcm88
165
+ L29wdGlvbj4NCjxvcHRpb24gdmFsdWU9IjEwIj5QYWVzIGRlIEJhcnJvczwv
166
+ b3B0aW9uPg0KPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgPHNlbGVjdCBp
167
+ ZD0nc2VsZWN0LWJ0Rm9vdENvbWVudGUnIHRpdGxlPSdDb21lbnRlJyBkYXRh
168
+ LW92ZXJsYXktdGhlbWU9J2QnIGRhdGEtbmF0aXZlLW1lbnU9J2ZhbHNlJz4N
169
+ CiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbj5Db21lbnRlPC9vcHRpb24+
170
+ DQogICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9JzAnPkVtYWls
171
+ PC9vcHRpb24+DQogICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9
172
+ JzEnPlR3aXR0ZXI8L29wdGlvbj4NCiAgICAgICAgICAgICAgICA8L3NlbGVj
173
+ dD4NCg0KICAgICAgICAgICAgPC9kaXY+ICAgICAgICAgICAgPGRpdiBpZD0i
174
+ bG9nb3NGb290ZXIiPg0KICAgICAgICAgICAgICAgIDxpbWcgc3JjPSIvQ29u
175
+ dGVudC90aGVtZS9pbWFnZW5zL2xvZ29zRm9vdGVyXzIwMTIwNzE2LmpwZyIg
176
+ YWx0PSJMb2dvbWFyY2EgU1BUcmFucyBlIFByZWZlaXR1cmEgZGEgQ2lkYWRl
177
+ IGRlIFPDo28gUGF1bG8iIC8+DQogICAgICAgICAgICA8L2Rpdj4gICAgICAg
178
+ IDwvZGl2Pg0KCTwvZGl2Pg0KPC9kaXY+DQoNCjxkaXYgaWQ9InNwIiBjbGFz
179
+ cz0iaW50ZXJuYS1lc3RydXR1cmEiIGRhdGEtcm9sZT0icGFnZSIgZGF0YS10
180
+ aGVtZT0icyI+DQogICAgPGRpdiBjbGFzcz0iY29udGVudC1zZWNvbmRhcnki
181
+ IGlkPSJ3ZWJUb3BDb250ZW50SW50Ij4NCiAgICAgICAgPGRpdiBjbGFzcz0i
182
+ aGVhZGVyV2ViIj4NCiAgICAgICAgICAgIDxoMT5QcmV2aXPDo28gV2ViPC9o
183
+ MT4NCiAgICAgICAgPC9kaXY+DQogICAgPC9kaXY+DQogICAgPGRpdiBkYXRh
184
+ LXJvbGU9ImhlYWRlciIgZGF0YS10aGVtZT0icyI+DQogICAgICAgIDxhIGNs
185
+ YXNzPSJiYWNrQnV0dG9uIiBkYXRhLXJlbD0iYmFjayIgZGF0YS1kaXJlY3Rp
186
+ b249InJldmVyc2UiIGRhdGEtcm9sZT0iYnV0dG9uIiBkYXRhLWljb249ImJh
187
+ Y2siIGRhdGEtdGhlbWU9InMiPlZvbHRhcjwvYT4NCiAgICAgICAgPGRpdiBj
188
+ bGFzcz0idWktYnRuLXJpZ2h0Ij4NCiAgICAgICAgICAgIDxhIGRhdGEtaWNv
189
+ bj0iaG9tZSIgZGF0YS1pY29ucG9zPSJub3RleHQiIGRhdGEtcm9sZT0iYnV0
190
+ dG9uIiBocmVmPSIvSW5kZXgiIGlkPSJob21lQnV0dG9uIiByZWw9ImV4dGVy
191
+ bmFsIj5Ib21lPC9hPg0KICAgICAgICAgICAgPGEgaHJlZj0iI3RvcCIgaWQ9
192
+ InJlZnJlc2hCdXR0b24iIGNsYXNzPSJiYWNrQnV0dG9uIiBkYXRhLXJvbGU9
193
+ ImJ1dHRvbiIgZGF0YS1pY29uPSJyZWZyZXNoIiBkYXRhLWljb25wb3M9Im5v
194
+ dGV4dCI+QXR1YWxpemFyPC9hPg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAg
195
+ PGgxPjwvaDE+DQogICAgPC9kaXY+DQogICAgPGRpdiBkYXRhLXJvbGU9ImNv
196
+ bnRlbnQiPjwvZGl2Pg0KPC9kaXY+DQoNCjxkaXYgaWQ9InBEZU9saG9WaWEi
197
+ IGNsYXNzPSJpbnRlcm5hLWVzdHJ1dHVyYSIgZGF0YS1yb2xlPSJwYWdlIiBk
198
+ YXRhLXRoZW1lPSJzIj4NCiAgICA8ZGl2IGNsYXNzPSJjb250ZW50LXNlY29u
199
+ ZGFyeSI+DQogICAgICAgIDxkaXYgY2xhc3M9ImhlYWRlcldlYiI+DQogICAg
200
+ ICAgICAgICA8aDE+UHJldmlzw6NvIFdlYjwvaDE+DQogICAgICAgIDwvZGl2
201
+ Pg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgZGF0YS1yb2xlPSJoZWFkZXIiIGRh
202
+ dGEtdGhlbWU9InMiPg0KICAgICAgICA8YSBjbGFzcz0iYmFja0J1dHRvbiIg
203
+ ZGF0YS1yZWw9ImJhY2siIGRhdGEtZGlyZWN0aW9uPSJyZXZlcnNlIiBkYXRh
204
+ LXJvbGU9ImJ1dHRvbiIgZGF0YS1pY29uPSJiYWNrIiBkYXRhLXRoZW1lPSJz
205
+ Ij5Wb2x0YXI8L2E+DQogICAgICAgIDxkaXYgY2xhc3M9InVpLWJ0bi1yaWdo
206
+ dCI+DQogICAgICAgICAgICA8YSBkYXRhLWljb249ImhvbWUiIGRhdGEtaWNv
207
+ bnBvcz0ibm90ZXh0IiBkYXRhLXJvbGU9ImJ1dHRvbiIgaHJlZj0iL0luZGV4
208
+ IiBpZD0iQTEiIHJlbD0iZXh0ZXJuYWwiPkhvbWU8L2E+DQogICAgICAgICAg
209
+ ICA8YSBocmVmPSIjdG9wIiBpZD0iQTIiIGNsYXNzPSJiYWNrQnV0dG9uIiBk
210
+ YXRhLXJvbGU9ImJ1dHRvbiIgZGF0YS1pY29uPSJyZWZyZXNoIiBkYXRhLWlj
211
+ b25wb3M9Im5vdGV4dCI+QXR1YWxpemFyPC9hPg0KICAgICAgICA8L2Rpdj4N
212
+ CiAgICAgICAgPGgxPjwvaDE+DQogICAgPC9kaXY+DQogICAgPGRpdiBkYXRh
213
+ LXJvbGU9ImNvbnRlbnQiPg0KICAgICAgICA8ZGl2IGlkPSJjb250ZW50RGVP
214
+ bGhvVmlhIj48L2Rpdj4NCiAgICAgICAgPGRpdiBpZD0iYWNjb3JkaW9uT1Yi
215
+ IGNsYXNzPSJzaG93SGlkZSI+PC9kaXY+DQogICAgPC9kaXY+DQo8L2Rpdj4N
216
+ CjxkaXYgaWQ9ImJveEFsZXJ0IiBjbGFzcz0idWktc2VsZWN0bWVudSB1aS1v
217
+ dmVybGF5LXNoYWRvdyB1aS1jb3JuZXItYWxsIHVpLWJvZHktYSI+PC9kaXY+
218
+ DQo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+DQogICAgdmFyIF9n
219
+ YXEgPSBfZ2FxIHx8IFtdOyBfZ2FxLnB1c2goWyJfc2V0QWNjb3VudCIsICJV
220
+ QS0xMTQ1NTA2MC01Il0pOyAoZnVuY3Rpb24gKCkgeyB2YXIgYSA9IGRvY3Vt
221
+ ZW50LmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpOyBhLnR5cGUgPSAidGV4dC9q
222
+ YXZhc2NyaXB0IjsgYS5hc3luYyA9IHRydWU7IGEuc3JjID0gKCJodHRwczoi
223
+ ID09IGRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sID8gImh0dHBzOi8vc3Ns
224
+ IiA6ICJodHRwOi8vd3d3IikgKyAiLmdvb2dsZS1hbmFseXRpY3MuY29tL2dh
225
+ LmpzIjsgdmFyIGIgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgi
226
+ c2NyaXB0IilbMF07IGIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoYSwgYikg
227
+ fSkoKQ0KPC9zY3JpcHQ+DQo8L2JvZHk+DQo8L2h0bWw+
228
+ http_version:
229
+ recorded_at: Thu, 26 Sep 2013 04:37:59 GMT
230
+ - request:
231
+ method: get
232
+ uri: http://olhovivo.sptrans.com.br/v0/Linha/Buscar?termosBusca=6400-10
233
+ body:
234
+ encoding: US-ASCII
235
+ string: ''
236
+ headers:
237
+ Cookie:
238
+ - apiCredentials-v0=10F5B3A97F2C811043EC864760E6C6FCD0259406E3F2BDCC5033990E24EC4C8A7CCFDBC0208DDC90BF200D0848BB373CA7164BC518653DE57F1D2391D31E39968B58FB3132F9A21E86586A5530D40C45FA476A02E945EC8C1055D886AE3782209118DB1C664ADC5D8BFA661221110280C4A426713F2BCD29FE5E12182DD245C210DF0DC8CBF693888413717C325E856F4863D62122672D5F014EE2E7B099D5879719A8C6511E392AF487F4AF46F6FF6F364875C9B44F03B2F0BA6DF13FDF9D96715C05682EC1AF2AFA2BF2977E83D6D8;
239
+ path=/; HttpOnly
240
+ Accept-Encoding:
241
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
242
+ Accept:
243
+ - '*/*'
244
+ User-Agent:
245
+ - Ruby
246
+ response:
247
+ status:
248
+ code: 200
249
+ message: OK
250
+ headers:
251
+ Cache-Control:
252
+ - no-cache
253
+ Pragma:
254
+ - no-cache
255
+ Content-Type:
256
+ - application/json; charset=utf-8
257
+ Expires:
258
+ - '-1'
259
+ Server:
260
+ - Microsoft-IIS/7.5
261
+ X-Frame-Options:
262
+ - DENY
263
+ X-Aspnet-Version:
264
+ - 4.0.30319
265
+ X-Powered-By:
266
+ - ASP.NET
267
+ Date:
268
+ - Thu, 26 Sep 2013 04:37:56 GMT
269
+ Content-Length:
270
+ - '348'
271
+ body:
272
+ encoding: UTF-8
273
+ string: '[{"CodigoLinha":57,"Circular":false,"Letreiro":"6400","Sentido":1,"Tipo":10,"DenominacaoTPTS":"TERMINAL
274
+ BANDEIRA","DenominacaoTSTP":"TERMINAL JOAO DIAS","Informacoes":null},{"CodigoLinha":32825,"Circular":false,"Letreiro":"6400","Sentido":2,"Tipo":10,"DenominacaoTPTS":"TERMINAL
275
+ BANDEIRA","DenominacaoTSTP":"TERMINAL JOAO DIAS","Informacoes":null}]'
276
+ http_version:
277
+ recorded_at: Thu, 26 Sep 2013 04:37:59 GMT
278
+ recorded_with: VCR 2.5.0