yar 1.0.1 → 1.0.3

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
  SHA256:
3
- metadata.gz: ac226a0af6b4c8761daa6f7814417fcf12ff2548604e49ba53d398a9791c62f1
4
- data.tar.gz: 7d3b2293ab13f4abcb10f466083b18265f6cecefad12b8cf77dfa17900827538
3
+ metadata.gz: e6761bb224ba7edb4489779cc8420ca3253109440bbaa99ef41944079a4f0493
4
+ data.tar.gz: dd7cdb4cc45403c79e7bff546de0b7d75acfc782b7b3a423dcf3c8cdf490c0e1
5
5
  SHA512:
6
- metadata.gz: 5c47e561f76733d7304f6bc0d37e612abf69f185e1e78923afed4bfd3e9f69b0afc7945175468aa3fe7140b5864cd316fa3f6f1af756ceef88d408b60ff27edb
7
- data.tar.gz: 49ae082c99afe2e21e1075124d3018b8b1575a9bf0d279c260e577e540e4e825555ef9c3e56414e258e09def824fb1779120cd9f8ee21fe6e3bbb3e343e8aaaf
6
+ metadata.gz: 9086b3f810a0a6c36f4da403bdc054d6e2a7b20ce0900b89e49dde7929d18baec03015517f285c15e216d3eaa23d26ef5f757582b9faef688a51671a26ebd90f
7
+ data.tar.gz: 846528c02d13bc1bf0d32617bdde71f05c762d96558ebec9a149ef3b3729a0868ada0d6f0e93acaeb3cfbc695ac4dd6918fd66f5fea9563d41a484586c4264ab
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yar (1.0.1)
4
+ yar (1.0.3)
5
5
  faraday (~> 1.7)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # yar
1
+ # yar [![Ruby specs](https://github.com/ruby-api-client/yar/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby-api-client/yar/actions/workflows/ci.yml) [![Gem Version](https://badge.fury.io/rb/yar.svg)](https://badge.fury.io/rb/yar) ![GitHub](https://img.shields.io/github/license/ruby-api-client/yar) [![Coverage Status](https://coveralls.io/repos/github/ruby-api-client/yar/badge.svg?branch=main)](https://coveralls.io/github/ruby-api-client/yar?branch=main) ![Gem](https://img.shields.io/gem/dt/yar)
2
2
 
3
3
  Yandex.Rasp API - API Яндекс.Расписаний
4
4
  docs: <https://yandex.ru/dev/rasp/doc/concepts/about.html>
data/lib/Yar/version.rb CHANGED
@@ -3,6 +3,6 @@
3
3
  module Yar
4
4
  major = 1
5
5
  minor = 0
6
- patch = 1
6
+ patch = 3
7
7
  VERSION = "#{major}.#{minor}.#{patch}"
8
8
  end
data/lib/yar/client.rb ADDED
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Client
5
+ BASE_URL = "https://api.rasp.yandex.net/v3.0/"
6
+
7
+ attr_reader :token, :adapter, :format
8
+
9
+ # new client
10
+ def initialize(token:, adapter: Faraday.default_adapter, stubs: nil, format: "json")
11
+ @token = token
12
+ @adapter = adapter
13
+ @stubs = stubs
14
+ @format = format
15
+ end
16
+
17
+ def copyright
18
+ CopyrightResource.new(self)
19
+ end
20
+
21
+ def stations
22
+ StationsResource.new(self)
23
+ end
24
+
25
+ def carrier
26
+ CarrierResource.new(self)
27
+ end
28
+
29
+ def nearest
30
+ NearestResource.new(self)
31
+ end
32
+
33
+ def schedule
34
+ ScheduleResource.new(self)
35
+ end
36
+
37
+ def connection
38
+ @connection ||= Faraday.new(BASE_URL) do |conn|
39
+ conn.request :authorization, nil, token
40
+ conn.request :json
41
+ conn.request :url_encoded
42
+
43
+ # conn.params[:format] = @format
44
+
45
+ conn.response :json, content_type: "application/json"
46
+ conn.response :xml, content_type: "application/xml" if @format == "xml"
47
+
48
+ conn.adapter adapter, @stubs
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Collection
5
+ attr_reader :data, :items, :total
6
+
7
+ def self.from_response(response, key:, type:)
8
+ body = response.body
9
+ new(
10
+ data: body[key].map {|attrs| type.new(attrs) },
11
+ items: body["items"],
12
+ total: body["total"]
13
+ )
14
+ end
15
+
16
+ def initialize(data:, items:, total:)
17
+ @data = data
18
+ @items = items
19
+ @total = total
20
+ end
21
+ end
22
+ end
data/lib/yar/error.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Error < StandardError; end
5
+ end
data/lib/yar/object.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ostruct"
4
+
5
+ module Yar
6
+ # TODO: change to Struct
7
+ class Object < OpenStruct
8
+ def initialize(attributes)
9
+ super to_ostruct(attributes)
10
+ end
11
+
12
+ # Convert Array or Hash to OpenStruct
13
+ def to_ostruct(obj)
14
+ case obj
15
+ when Hash
16
+ # obj.to_struct
17
+ # rubocop:disable Style/HashTransformValues
18
+ OpenStruct.new(obj.map {|key, val| [key, to_ostruct(val)] }.to_h)
19
+ # rubocop:enable Style/HashTransformValues
20
+ when Array
21
+ obj.map {|o| to_ostruct(o) }
22
+ else
23
+ obj
24
+ end
25
+ end
26
+ end
27
+
28
+ # class Hash
29
+ # def to_struct
30
+ # s = Struct.new(*self.keys.map(&:to_sym))
31
+ # construct = map do |k,v|
32
+ # v.is_a?(Hash) ? v.to_struct : v.is_a?(Array) ? v.join(", ") : v
33
+ # end
34
+ # s.new(*construct)
35
+ # end
36
+ # end
37
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Carrier < Object; end
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class City < Object; end
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Copyright < Object; end
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Schedule < Object; end
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Station < Object; end
5
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class Resource
5
+ attr_reader :client
6
+
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ private
12
+
13
+ def get(url, params: {}, headers: {})
14
+ handle_response client.connection.get(url, params, headers)
15
+ end
16
+
17
+ def post(url, body:, headers: {})
18
+ handle_response client.connection.post(url, body, headers)
19
+ end
20
+
21
+ def patch(url, body:, headers: {})
22
+ handle_response client.connection.patch(url, body, headers)
23
+ end
24
+
25
+ def put(url, body:, headers: {})
26
+ handle_response client.connection.put(url, body, headers)
27
+ end
28
+
29
+ def delete(url, params: {}, headers: {})
30
+ handle_response client.connection.delete(url, params, headers)
31
+ end
32
+ alias delete_request delete
33
+
34
+ # rubocop:disable Metrics/CyclomaticComplexity
35
+ # rubocop:disable Metrics/AbcSize
36
+ def handle_response(response)
37
+ case response.status
38
+ when 302
39
+ raise Error, "Redirect found. #{response.body['error']}"
40
+ when 400
41
+ raise Error, "Your request was malformed. #{response.body['error']}"
42
+ when 401
43
+ raise Error, "You did not supply valid authentication credentials. #{response.body['error']}"
44
+ when 403
45
+ raise Error, "You are not allowed to perform that action. #{response.body['error']}"
46
+ when 404
47
+ raise Error, "No results were found for your request. #{response.body['error']}"
48
+ when 429
49
+ raise Error, "Your request exceeded the API rate limit. #{response.body['error']}"
50
+ when 500
51
+ raise Error, "We were unable to perform the request due to server-side problems. #{response.body['error']}"
52
+ when 503
53
+ raise Error, "You have been rate limited for sending more requests per second. #{response.body['error']}"
54
+ end
55
+
56
+ response
57
+ end
58
+ # rubocop:enable Metrics/AbcSize
59
+ # rubocop:enable Metrics/CyclomaticComplexity
60
+ end
61
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class CarrierResource < Resource
5
+ def info(code:, system: "yandex")
6
+ Carrier.new get("carrier/?code=#{code}&system=#{system}").body
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class CopyrightResource < Resource
5
+ def info
6
+ Copyright.new get("copyright/").body
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class NearestResource < Resource
5
+ def stations(lat:, long:, distance:)
6
+ resp = get("nearest_stations/?lat=#{lat}&lng=#{long}&distance=#{distance}")
7
+ Collection.from_response(resp, key: "stations", type: Station)
8
+ end
9
+
10
+ def city(lat:, long:)
11
+ City.new get("nearest_settlement/?lat=#{lat}&lng=#{long}").body
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class ScheduleResource < Resource
5
+ # TODO: move to Schedule.info station: -> Schedule
6
+ def info(station:)
7
+ Schedule.new get("schedule/?station=#{station}").body
8
+ end
9
+
10
+ # TODO: move to Schedule.between(from: to:) -> Schedule
11
+ def between(from:, to:)
12
+ Schedule.new get("search/?from=#{from}&to=#{to}").body
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ class StationsResource < Resource
5
+ # def list
6
+ # resp = get("stations_list/")
7
+ # Collection.from_response(resp, key: "countries", type: Region)
8
+ # end
9
+ def list
10
+ Object.new get("stations_list/").body
11
+ end
12
+
13
+ # TODO: move to Schedule.info station: -> Schedule
14
+ def schedule(station:)
15
+ Schedule.new get("schedule/?station=#{station}").body
16
+ end
17
+
18
+ # TODO: move to Schedule.between(from: to:) -> Schedule
19
+ def between(from:, to:)
20
+ Schedule.new get("search/?from=#{from}&to=#{to}").body
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yar
4
+ major = 1
5
+ minor = 0
6
+ patch = 3
7
+ VERSION = "#{major}.#{minor}.#{patch}"
8
+ end
data/yar.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.description = "Yandex.Rasp API wrapper written in Ruby"
13
13
  s.authors = ["Ilya Brin"]
14
14
  s.email = "ilya@codeplay.ru"
15
- s.files = `git ls-files -z`.split("\x0")
15
+ s.files = `git ls-files`.split($RS).reject {|fn| fn.start_with? "spec" }
16
16
  s.executables = s.files.grep(%r{^bin/}) {|f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
18
  s.homepage = "https://github.com/ruby-api-client/yar"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Brin
@@ -161,21 +161,22 @@ files:
161
161
  - lib/Yar/resources/stations.rb
162
162
  - lib/Yar/version.rb
163
163
  - lib/yar.rb
164
- - spec/client_spec.rb
165
- - spec/lib/resources/carrier_spec.rb
166
- - spec/lib/resources/copyright_spec.rb
167
- - spec/lib/resources/nearest_spec.rb
168
- - spec/lib/resources/schedule_spec.rb
169
- - spec/lib/resources/stations_spec.rb
170
- - spec/spec_helper.rb
171
- - spec/vcr/carrier/schedule.yml
172
- - spec/vcr/copyright/info.yml
173
- - spec/vcr/nearest/city.yml
174
- - spec/vcr/nearest/stations.yml
175
- - spec/vcr/schedule/between.yml
176
- - spec/vcr/schedule/schedule.yml
177
- - spec/vcr/stations/between.yml
178
- - spec/vcr/stations/schedule.yml
164
+ - lib/yar/client.rb
165
+ - lib/yar/collection.rb
166
+ - lib/yar/error.rb
167
+ - lib/yar/object.rb
168
+ - lib/yar/objects/carrier.rb
169
+ - lib/yar/objects/city.rb
170
+ - lib/yar/objects/copyright.rb
171
+ - lib/yar/objects/schedule.rb
172
+ - lib/yar/objects/station.rb
173
+ - lib/yar/resource.rb
174
+ - lib/yar/resources/carrier.rb
175
+ - lib/yar/resources/copyright.rb
176
+ - lib/yar/resources/nearest.rb
177
+ - lib/yar/resources/schedule.rb
178
+ - lib/yar/resources/stations.rb
179
+ - lib/yar/version.rb
179
180
  - yar.gemspec
180
181
  homepage: https://github.com/ruby-api-client/yar
181
182
  licenses:
data/spec/client_spec.rb DELETED
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Yar::Client do
4
- subject(:client) { described_class.new token: "TOKEN" }
5
-
6
- context "with default format" do
7
- it { expect(client).to be_an Yar::Client }
8
- it { expect(client.format).to eq "json" }
9
- end
10
-
11
- context "with format XML" do
12
- subject(:client) { described_class.new token: "TOKEN", format: "xml" }
13
- it { expect(client.format).to eq "xml" }
14
- end
15
-
16
- describe "VERSION" do
17
- it { expect(Yar::VERSION).to eq "1.0.1" }
18
- end
19
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "yar"
5
-
6
- RSpec.describe "#carrier" do
7
- describe ".info" do
8
- subject(:resp) do
9
- VCR.use_cassette("carrier/schedule") do
10
- @yar.carrier.info code: "TK", system: "iata"
11
- end
12
- end
13
-
14
- it { expect(resp).to be_an Yar::Carrier }
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "yar"
5
-
6
- RSpec.describe "#copyright" do
7
- describe ".info" do
8
- subject(:resp) do
9
- VCR.use_cassette("copyright/info") do
10
- @yar.copyright.info
11
- end
12
- end
13
-
14
- it { expect(resp).to be_an Yar::Copyright }
15
- end
16
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "yar"
5
-
6
- RSpec.describe "#nearest" do
7
- let(:lat) { 55.733970 }
8
- let(:long) { 37.586780 }
9
-
10
- describe ".stations" do
11
- subject(:resp) do
12
- VCR.use_cassette("nearest/stations") do
13
- @yar.nearest.stations lat: 55.733970, long: 37.586780, distance: 10
14
- end
15
- end
16
-
17
- it { expect(resp).to be_an Yar::Collection }
18
- it { expect(resp.data.first).to be_an Yar::Station }
19
- end
20
-
21
- describe ".city" do
22
- subject(:resp) do
23
- VCR.use_cassette("nearest/city") do
24
- @yar.nearest.city(lat: lat, long: long)
25
- end
26
- end
27
-
28
- it { expect(resp).to be_an Yar::City }
29
- end
30
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "yar"
5
-
6
- RSpec.describe "#schedule" do
7
- describe ".info" do
8
- subject(:resp) do
9
- VCR.use_cassette("schedule/schedule") do
10
- @yar.schedule.info station: "s9848585"
11
- end
12
- end
13
-
14
- it { expect(resp).to be_an Yar::Schedule }
15
- end
16
-
17
- describe ".between" do
18
- subject(:resp) do
19
- VCR.use_cassette("schedule/between") do
20
- @yar.schedule.between from: "s9848585", to: "s9848577"
21
- end
22
- end
23
-
24
- it { expect(resp).to be_an Yar::Schedule }
25
- end
26
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "yar"
5
-
6
- RSpec.describe "#stations" do
7
- describe ".schedule" do
8
- subject(:resp) do
9
- VCR.use_cassette("stations/schedule") do
10
- @yar.stations.schedule station: "s9848585"
11
- end
12
- end
13
-
14
- it { expect(resp).to be_an Yar::Schedule }
15
- end
16
-
17
- describe ".between" do
18
- subject(:resp) do
19
- VCR.use_cassette("stations/between") do
20
- @yar.stations.between from: "s9848585", to: "s9848577"
21
- end
22
- end
23
-
24
- it { expect(resp).to be_an Yar::Schedule }
25
- end
26
- end
data/spec/spec_helper.rb DELETED
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/setup"
4
- require "simplecov"
5
- require "simplecov-lcov"
6
- require "webmock/rspec"
7
- require "vcr"
8
-
9
- require "yar"
10
-
11
- SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
12
- SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
13
-
14
- SimpleCov.start do
15
- add_filter "spec/"
16
- add_group "Lib", "lib"
17
- minimum_coverage 80.0
18
- end
19
-
20
- ACCESS_TOKEN = ENV["YAR_ACCESS_TOKEN"] || "SECRET_TOKEN"
21
-
22
- RSpec.configure do |config|
23
- config.before(:each) do
24
- @yar = Yar::Client.new(token: ACCESS_TOKEN)
25
- end
26
-
27
- config.example_status_persistence_file_path = ".rspec_status"
28
- config.disable_monkey_patching!
29
-
30
- config.expect_with :rspec do |c|
31
- c.syntax = :expect
32
- c.include_chain_clauses_in_custom_matcher_descriptions = true
33
- end
34
-
35
- config.mock_with :rspec do |mocks|
36
- mocks.verify_partial_doubles = true
37
- end
38
- config.shared_context_metadata_behavior = :apply_to_host_groups
39
- end
40
-
41
- VCR.configure do |c|
42
- c.before_record do |i|
43
- i.response.body.force_encoding("UTF-8")
44
- end
45
-
46
- c.ignore_localhost = true
47
- c.cassette_library_dir = "spec/vcr"
48
- c.hook_into :webmock
49
-
50
- c.default_cassette_options = {
51
- decode_compressed_response: true,
52
- allow_unused_http_interactions: false
53
- }
54
-
55
- c.filter_sensitive_data("TOKEN") do |i|
56
- i.request["headers"]["Authorization"].first
57
- end
58
-
59
- c.configure_rspec_metadata!
60
- end
@@ -1,44 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: get
5
- uri: https://api.rasp.yandex.net/v3.0/carrier/?code=TK&system=iata
6
- body:
7
- encoding: US-ASCII
8
- string: ''
9
- headers:
10
- User-Agent:
11
- - Faraday v1.10.2
12
- Authorization:
13
- - TOKEN
14
- Accept-Encoding:
15
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
- Accept:
17
- - "*/*"
18
- response:
19
- status:
20
- code: 200
21
- message: OK
22
- headers:
23
- Allow:
24
- - GET
25
- Content-Length:
26
- - '311'
27
- Content-Type:
28
- - application/json; charset=utf-8
29
- Date:
30
- - Sun, 23 Oct 2022 08:29:12 GMT
31
- Vary:
32
- - Accept, Accept-Encoding
33
- X-Content-Type-Options:
34
- - nosniff
35
- body:
36
- encoding: UTF-8
37
- string: '{"carriers":[{"code":5483,"title":"AnadoluJet","codes":{"sirena":null,"iata":"TK","icao":"AJA"},"address":"Bakırköy/
38
- İstanbul","url":"http://www.anadolujet.com/","email":"musteri@anadolujet.com","contacts":"","phone":"444
39
- 25 38","logo":"https://yastat.net/s3/rasp/media/data/company/logo/anadolujet.png","offices":[]},{"code":680,"title":"Turkish
40
- Airlines","codes":{"sirena":null,"iata":"TK","icao":"THY"},"address":"Bakırköy/
41
- İstanbul","url":"http://www.turkishairlines.com/","email":"","contacts":"","phone":"444
42
- 08 49","logo":"https://yastat.net/s3/rasp/media/data/company/logo/thy_kopya.jpg","offices":[]}]}'
43
- recorded_at: Sun, 23 Oct 2022 08:29:12 GMT
44
- recorded_with: VCR 6.1.0