elessar 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 397fc3055adbb9d6d5a8415a5709e22899cc90fd471552ca810566b9dcc4cbaa
4
+ data.tar.gz: 693aa15f1092a68147bf7cc35f324f1f52329921a850fa1be29d0d1cec4aa949
5
+ SHA512:
6
+ metadata.gz: 9e2b4cc37588bb6b9455099a204fcb1f1e0a772acce9ec14558eb580465f0b0bef4eeb5bb33be9ba3ca074eb60b3fcda10bab4051a93437c017468266cd4d62a
7
+ data.tar.gz: 0b753bcb26d4aedda291524c67a6e84ea72154c0e571c251031075cd23c71a9bb6585464ab1004191fa4a13308bbd09cd7268836125cd70ab521d3036181bcac
data/Gemfile.lock ADDED
@@ -0,0 +1,27 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ elessar (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ mocha (2.0.2)
10
+ ruby2_keywords (>= 0.0.5)
11
+ power_assert (1.2.0)
12
+ rake (13.0.6)
13
+ ruby2_keywords (0.0.5)
14
+ test-unit (3.3.7)
15
+ power_assert
16
+
17
+ PLATFORMS
18
+ arm64-darwin-21
19
+
20
+ DEPENDENCIES
21
+ elessar!
22
+ mocha
23
+ rake
24
+ test-unit
25
+
26
+ BUNDLED WITH
27
+ 2.2.3
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Elessar Ruby Library
2
+
3
+ Elessar - In the book, Elessar is a green gemstone that is a symbol of the kingship of Gondor.
4
+
5
+ The Elessar Ruby library provides convenient access to the The Lord of the Rings API from
6
+ applications written in the Ruby language.
7
+
8
+ ## Documentation
9
+
10
+ See the [The Lord of the Rings API docs](https://the-one-api.dev/documentation).
11
+
12
+ ## Installation
13
+
14
+ You don't need this source code unless you want to modify the gem. If you just
15
+ want to use the package, just run:
16
+
17
+ ```sh
18
+ gem install elessar
19
+ ```
20
+
21
+ If you want to build the gem from source:
22
+
23
+ ```sh
24
+ gem build elessar.gemspec
25
+ ```
26
+
27
+ ### Requirements
28
+
29
+ - Ruby 2.3+.
30
+
31
+ ### Bundler
32
+
33
+ If you are installing via bundler, you should be sure to use the https rubygems
34
+ source in your Gemfile, as any gems fetched over http could potentially be
35
+ compromised in transit and alter the code of gems fetched securely over https:
36
+
37
+ ```ruby
38
+ gem 'elessar'
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ The library needs to be configured with your account's secret key which is
44
+ available in your [The Lord of the Rings Account](https://the-one-api.dev/account). Set `Elessar.api_key` to its
45
+ value:
46
+
47
+ ```ruby
48
+ require 'elessar'
49
+ Elessar.api_key = 'aR9j-...'
50
+
51
+ # list movies
52
+ Elessar::Movie.list()
53
+
54
+ # retrieve single movie
55
+ movie = Elessar::Movie.retrieve('5cd95395de30eff6ebccde5b')
56
+
57
+ # list quotes
58
+ movie.list_quotes()
59
+ ```
60
+
61
+ ### Params
62
+ ```ruby
63
+ # using params as hash
64
+ Elessar::Movie.list({limit: 3, page: 2})
65
+
66
+ # using params as string
67
+ Elessar::Movie.list("budgetInMillions<100")
68
+ ```
69
+
70
+
71
+ ### Configuring Automatic Retries
72
+
73
+ You can enable automatic retries on requests that fail due to a transient
74
+ problem by configuring the maximum number of retries:
75
+
76
+ ```ruby
77
+ Elessar.max_network_retries = 2
78
+ ```
79
+
80
+ Various errors can trigger a retry, like a connection error or a timeout, and
81
+ also certain API responses like HTTP status `409 Conflict`.
82
+
83
+ ### Configuring Timeouts
84
+
85
+ Open, read timeouts are configurable:
86
+
87
+ ```ruby
88
+ Elessar.open_timeout = 30 # in seconds
89
+ Elessar.read_timeout = 80
90
+ ```
91
+
92
+
93
+ ## Development
94
+
95
+ Instructions to run tests:
96
+
97
+ ```sh
98
+ bundle install
99
+ ```
100
+
101
+ Run all tests:
102
+
103
+ ```sh
104
+ bundle exec ruby test/run_test.rb
105
+ ```
106
+
107
+ Run a single test:
108
+
109
+ ```sh
110
+ bundle exec ruby test/elessar_test.rb
111
+ ```
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
data/bin/sdk-console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require "irb"
6
+ require "irb/completion"
7
+
8
+ require "#{::File.dirname(__FILE__)}/../lib/sdk.rb"
9
+
10
+ # Config IRB to enable --simple-prompt and auto indent
11
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
12
+ IRB.conf[:AUTO_INDENT] = true
13
+
14
+ puts "Loaded gem 'murilo-zaffalon-sdk'"
15
+
16
+ IRB.start
data/designer.md ADDED
@@ -0,0 +1,22 @@
1
+ ### Designer
2
+
3
+ You can add `opts` to add some headers to the request.
4
+
5
+ ```ruby
6
+ # get movie by id
7
+ Elessar::Movie.retrieve(id, opts = {})
8
+
9
+ # get all movies
10
+ movie = Elessar::Movie.list(filters = {limit: 10}, opts = {})
11
+
12
+ # You can acces the data
13
+ movie.docs.first.name
14
+
15
+ # get all quotes from a movie
16
+ quote = movie.list_quotes(filters = { limit: 10 }, opts = {})
17
+
18
+ quote.docs.first.dialog
19
+
20
+ # For Custom searches you can use the filters passing the string
21
+ Elessar::Movie.list("budgetInMillions<100")
22
+ ```
data/elessar.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ $LOAD_PATH.unshift(::File.join(::File.dirname(__FILE__), "lib"))
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "elessar"
5
+ s.version = "0.0.1"
6
+ s.required_ruby_version = ">= 2.3.0"
7
+
8
+ s.authors = ["Murilo Zaffalon"]
9
+ s.date = %q{2023-03-05}
10
+ s.description = %q{A simple SDK for Murilo Zaffalon, Elessar - In the book, Elessar is a green gemstone that is a symbol of the kingship of Gondor.}
11
+ s.email = %q{mzaffalon@hotmail.com}
12
+ # s.test_files = ["test/test_hola.rb"]
13
+ s.homepage = %q{http://rubygems.org/gems/elessar}
14
+ s.summary = %q{Murilo Zaffalon SDK!}
15
+
16
+ ignored = Regexp.union(
17
+ "elessar-0.0.1.gem",
18
+ /\A\.git/,
19
+ /\A\.vscode/,
20
+ /\Atest/
21
+ )
22
+ s.files = `git ls-files`.split("\n").reject { |f| ignored.match(f) }
23
+ s.executables = `git ls-files -- bin/*`.split("\n")
24
+ .map { |f| ::File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
data/gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ group :development do
8
+ gem "rake"
9
+ gem "mocha"
10
+
11
+ gem "test-unit"
12
+ end
data/lib/.DS_Store ADDED
Binary file
Binary file
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elessar
4
+ module APIOperations
5
+ module Request
6
+ module ClassMethods
7
+ def request(method, url, params = {}, opts = {})
8
+ connection = Elessar::ConnectionManager.new
9
+ connection.execute_request(
10
+ method,
11
+ url,
12
+ query: params,
13
+ headers: opts,
14
+ )
15
+ end
16
+ end
17
+
18
+ def request(method, url, params = {}, opts = {})
19
+ connection = Elessar::ConnectionManager.new
20
+ connection.execute_request(
21
+ method,
22
+ url,
23
+ query: params,
24
+ headers: opts,
25
+ )
26
+ end
27
+
28
+ def self.included(base)
29
+ base.extend(ClassMethods)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elessar
4
+ class ConnectionManager
5
+ attr_reader :config
6
+
7
+ def initialize(config = Elessar.config)
8
+ @config = config
9
+ @active_connections = {}
10
+ end
11
+
12
+ def connection_for(uri)
13
+ u = URI.parse(uri)
14
+ connection = @active_connections[[u.host, u.port]]
15
+
16
+ if connection.nil?
17
+ connection = create_connection(u)
18
+ connection.start
19
+
20
+ @active_connections[[u.host, u.port]] = connection
21
+ end
22
+
23
+ connection
24
+ end
25
+
26
+ def authorization_headers
27
+ headers = {
28
+ "Authorization" => "Bearer #{Elessar.api_key}",
29
+ "Content-Type" => "application/json",
30
+ }
31
+ end
32
+
33
+ def execute_request(method, uri, body: nil, headers: {}, query:, &block)
34
+ raise ArgumentError, "method should be a symbol" unless method.is_a?(Symbol)
35
+ raise ArgumentError, "uri should be a string" unless uri.is_a?(String)
36
+ raise ArgumentError, "body should be a string" if body && !body.is_a?(String)
37
+ raise ArgumentError, "headers should be a hash" if headers && !headers.is_a?(Hash)
38
+ raise ArgumentError, "query should be a hash or string" if query && (!query.is_a?(Hash) and !query.is_a?(String))
39
+
40
+ headers = headers.merge(authorization_headers)
41
+ uri = Elessar.api_base + uri
42
+
43
+ connection = connection_for(uri)
44
+
45
+ u = URI.parse(uri)
46
+ path = case query
47
+ when String
48
+ u.path + "?" + query
49
+ when Hash
50
+ u.path + "?" + URI.encode_www_form(query)
51
+ else
52
+ u.path
53
+ end
54
+
55
+ method_name = method.to_s.upcase
56
+ has_response_body = method_name != "HEAD"
57
+ request = Net::HTTPGenericRequest.new(
58
+ method_name,
59
+ (body ? true : false),
60
+ has_response_body,
61
+ path,
62
+ headers
63
+ )
64
+
65
+ http_resp = begin
66
+ retries ||= 0
67
+ connection.request(request, body, &block)
68
+ rescue
69
+ retry if (retries += 1) < Elessar.max_network_retries
70
+ end
71
+
72
+ begin
73
+ resp = ElessarResponse.from_net_http(http_resp)
74
+ rescue JSON::ParserError
75
+ raise general_api_error(http_resp.code.to_i, http_resp.body)
76
+ end
77
+ end
78
+
79
+ private def create_connection(uri)
80
+ connection = Net::HTTP.new(uri.host, uri.port)
81
+
82
+ connection.use_ssl = true
83
+ connection.keep_alive_timeout = 30
84
+ connection.open_timeout = config.open_timeout
85
+ connection.read_timeout = config.read_timeout
86
+
87
+ connection
88
+ end
89
+
90
+ private def general_api_error(status, body)
91
+ StandardError.new("Invalid response object from API: #{body.inspect} " \
92
+ "(HTTP response code was #{status})")
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elessar
4
+ class ElessarConfiguration
5
+ attr_accessor :api_key
6
+ attr_accessor :api_version
7
+
8
+ attr_reader :api_base
9
+ attr_reader :max_network_retries
10
+ attr_reader :open_timeout
11
+ attr_reader :read_timeout
12
+
13
+ def self.setup
14
+ new.tap do |instance|
15
+ yield(instance) if block_given?
16
+ end
17
+ end
18
+
19
+ def initialize
20
+ @max_network_retries = 0
21
+
22
+ @open_timeout = 30
23
+ @read_timeout = 80
24
+
25
+ @api_base = "https://the-one-api.dev/v2/"
26
+ end
27
+
28
+ def max_network_retries=(val)
29
+ @max_network_retries = val.to_i
30
+ end
31
+
32
+ def open_timeout=(open_timeout)
33
+ @open_timeout = open_timeout
34
+ end
35
+
36
+ def read_timeout=(read_timeout)
37
+ @read_timeout = read_timeout
38
+ end
39
+
40
+ def api_base=(api_base)
41
+ @api_base = api_base
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elessar
4
+ class ElessarResponseHeaders
5
+ def self.from_net_http(resp)
6
+ new(resp.to_hash || resp.to_h)
7
+ end
8
+
9
+ def initialize(hash)
10
+ return if hash.nil?
11
+ @hash = {}
12
+
13
+ hash.each do |k, v|
14
+ @hash[k.downcase] = v
15
+ end
16
+ end
17
+ end
18
+
19
+ module ElessarResponseBase
20
+ attr_accessor :http_headers
21
+ attr_accessor :http_status
22
+
23
+ def self.populate_for_net_http(resp, http_resp)
24
+ resp.http_headers = ElessarResponseHeaders.from_net_http(http_resp)
25
+ resp.http_status = http_resp.code.to_i
26
+ end
27
+ end
28
+
29
+ class ElessarResponse
30
+ include ElessarResponseBase
31
+
32
+ attr_accessor :data
33
+ attr_accessor :http_body
34
+
35
+ def self.from_net_http(http_resp)
36
+ resp = ElessarResponse.new
37
+ resp.data = JSON.parse(http_resp.body, object_class: OpenStruct)
38
+ resp.http_body = http_resp.body
39
+ ElessarResponseBase.populate_for_net_http(resp, http_resp)
40
+ resp
41
+ end
42
+ end
43
+
44
+ ElessarResponse::Headers = ElessarResponseHeaders
45
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elessar
4
+ class Movie
5
+ include Elessar::APIOperations::Request
6
+
7
+ attr_accessor :id, :data
8
+
9
+ def initialize(id, data = {})
10
+ @id = id
11
+ @data = data
12
+ end
13
+
14
+ OBJECT_NAME = "movie"
15
+
16
+ def self.retrieve(id, opts = {})
17
+ url = resource_url + "/#{id}"
18
+ resp = request(:get, url, params = nil, opts = opts)
19
+ new(id, resp.data)
20
+ end
21
+
22
+ def self.list(filters = { limit: 10 }, opts = {})
23
+ resp = request(:get, resource_url, params = filters, opts = opts)
24
+ new(nil, resp.data)
25
+ end
26
+
27
+ def list_quotes(filters = { limit: 10 }, opts = {})
28
+ url = "#{resource_url}/#{id}/quote"
29
+ resp = request(:get, url, params = filters, opts = opts)
30
+ Elessar::Quote.new(nil, resp.data)
31
+ end
32
+
33
+ def self.resource_url
34
+ "#{OBJECT_NAME}"
35
+ end
36
+
37
+ def resource_url
38
+ "#{OBJECT_NAME}"
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elessar
4
+ class Quote
5
+ include Elessar::APIOperations::Request
6
+
7
+ attr_accessor :id, :data
8
+
9
+ def initialize(id, data = {})
10
+ @id = id
11
+ @data = data
12
+ end
13
+
14
+ OBJECT_NAME = "quote"
15
+
16
+ def self.list(filters = { limit: 10 }, opts = {})
17
+ resp = request(:get, resource_url, params = filters, opts = opts)
18
+ new(nil, resp.data)
19
+ end
20
+
21
+ def self.resource_url
22
+ "#{OBJECT_NAME}"
23
+ end
24
+
25
+ def resource_url
26
+ "#{OBJECT_NAME}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "elessar/resources/movie"
4
+ require "elessar/resources/quote"
data/lib/elessar.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "net/http"
2
+ require "json"
3
+ require "forwardable"
4
+
5
+ # API operations
6
+ require "elessar/api_operations/request"
7
+
8
+ require "elessar/elessar_configuration"
9
+ require "elessar/connection_manager"
10
+ require "elessar/elessar_response"
11
+
12
+ require "elessar/resources"
13
+
14
+ module Elessar
15
+ @config = Elessar::ElessarConfiguration.setup
16
+
17
+ class << self
18
+ extend Forwardable
19
+
20
+ attr_reader :config
21
+
22
+ def_delegators :@config, :api_key, :api_key=
23
+ def_delegators :@config, :api_version, :api_version=
24
+ def_delegators :@config, :api_base, :api_base=
25
+ def_delegators :@config, :open_timeout, :open_timeout=
26
+ def_delegators :@config, :read_timeout, :read_timeout=
27
+ def_delegators :@config, :max_network_retries, :max_network_retries=
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elessar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Murilo Zaffalon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-03-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple SDK for Murilo Zaffalon, Elessar - In the book, Elessar is a
14
+ green gemstone that is a symbol of the kingship of Gondor.
15
+ email: mzaffalon@hotmail.com
16
+ executables:
17
+ - sdk-console
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - Gemfile.lock
22
+ - README.md
23
+ - Rakefile
24
+ - bin/sdk-console
25
+ - designer.md
26
+ - elessar.gemspec
27
+ - gemfile
28
+ - lib/.DS_Store
29
+ - lib/elessar.rb
30
+ - lib/elessar/.DS_Store
31
+ - lib/elessar/api_operations/request.rb
32
+ - lib/elessar/connection_manager.rb
33
+ - lib/elessar/elessar_configuration.rb
34
+ - lib/elessar/elessar_response.rb
35
+ - lib/elessar/resources.rb
36
+ - lib/elessar/resources/movie.rb
37
+ - lib/elessar/resources/quote.rb
38
+ homepage: http://rubygems.org/gems/elessar
39
+ licenses: []
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 2.3.0
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 3.2.3
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Murilo Zaffalon SDK!
60
+ test_files: []