yar 1.0.1 → 1.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.
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