spbus 0.0.2 → 0.0.3

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.
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