nokotime-ruby-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ module Nokotime
2
+ module Authentication
3
+ AUTHENTICATION_TYPE = [
4
+ :noko_token
5
+ ].freeze
6
+
7
+ def valid_auth?(type)
8
+ AUTHENTICATION_TYPE.include? type
9
+ end
10
+
11
+ def authorize_request(request)
12
+ case auth_type
13
+ when :noko_token
14
+ request.headers["X-NokoToken"] = token
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def token
21
+ Nokotime.configuration.token
22
+ end
23
+
24
+ def auth_type
25
+ Nokotime.configuration.auth_type
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ module Nokotime
2
+ module Client
3
+ class Entries
4
+ ENDPOINT = "/v2/entries".freeze
5
+
6
+ attr_reader :params
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+
12
+ def all
13
+ multiple_pages.get(ENDPOINT, params: entry_params)
14
+ end
15
+
16
+ def show(id)
17
+ single_page.get("#{ENDPOINT}/#{id}")
18
+ end
19
+
20
+ private
21
+
22
+ def multiple_pages
23
+ @multiple_pages ||= Request::MultiplePages.new
24
+ end
25
+
26
+ def single_page
27
+ @single_page ||= Request::SinglePage.new
28
+ end
29
+
30
+ def entry_params
31
+ return params if validation.success?
32
+
33
+ raise Errors::InvalidParams, validation.messages
34
+ end
35
+
36
+ def validation
37
+ @validation ||= Validator::EntrySchema.validate(params)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ module Nokotime
2
+ module Client
3
+ class ProjectGroups
4
+ ENDPOINT = "/v2/project_groups".freeze
5
+
6
+ attr_reader :params
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+
12
+ def all
13
+ multiple_pages.get(ENDPOINT, params: project_group_params)
14
+ end
15
+
16
+ private
17
+
18
+ def multiple_pages
19
+ @multiple_pages ||= Request::MultiplePages.new
20
+ end
21
+
22
+ def project_group_params
23
+ return params if validation.success?
24
+
25
+ raise Errors::InvalidParams, validation.messages
26
+ end
27
+
28
+ def validation
29
+ @validation ||= Validator::ProjectGroupSchema.validate(params)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ module Nokotime
2
+ module Client
3
+ class Projects
4
+ ENDPOINT = "/v2/projects".freeze
5
+
6
+ attr_reader :params
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+
12
+ def all
13
+ multiple_pages.get(ENDPOINT, params: project_params)
14
+ end
15
+
16
+ def show(id)
17
+ single_page.get("#{ENDPOINT}/#{id}")
18
+ end
19
+
20
+ private
21
+
22
+ def multiple_pages
23
+ @multiple_pages ||= Request::MultiplePages.new
24
+ end
25
+
26
+ def single_page
27
+ @single_page ||= Request::SinglePage.new
28
+ end
29
+
30
+ def project_params
31
+ return params if validation.success?
32
+
33
+ raise Errors::InvalidParams, validation.messages
34
+ end
35
+
36
+ def validation
37
+ @validation ||= Validator::ProjectSchema.validate(params)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ module Nokotime
2
+ module Client
3
+ class Tags
4
+ ENDPOINT = "/v2/tags".freeze
5
+
6
+ attr_reader :params
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+
12
+ def all
13
+ multiple_pages.get(ENDPOINT, params: tag_params)
14
+ end
15
+
16
+ private
17
+
18
+ def multiple_pages
19
+ @multiple_pages ||= Request::MultiplePages.new
20
+ end
21
+
22
+ def tag_params
23
+ return params if validation.success?
24
+
25
+ raise Errors::InvalidParams, validation.messages
26
+ end
27
+
28
+ def validation
29
+ @validation ||= Validator::TagSchema.validate(params)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ module Nokotime
2
+ module Client
3
+ class Users
4
+ ENDPOINT = "/v2/users".freeze
5
+
6
+ attr_reader :params
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+
12
+ def all
13
+ multiple_pages.get(ENDPOINT, params: user_params)
14
+ end
15
+
16
+ def show(id)
17
+ single_page.get("#{ENDPOINT}/#{id}")
18
+ end
19
+
20
+ private
21
+
22
+ def multiple_pages
23
+ @multiple_pages ||= Request::MultiplePages.new
24
+ end
25
+
26
+ def single_page
27
+ @single_page ||= Request::SinglePage.new
28
+ end
29
+
30
+ def user_params
31
+ return params if validation.success?
32
+
33
+ raise Errors::InvalidParams, validation.messages
34
+ end
35
+
36
+ def validation
37
+ @validation ||= Validator::UserSchema.validate(params)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,44 @@
1
+ module Nokotime
2
+ class Configuration
3
+ include Nokotime::Authentication
4
+
5
+ attr_writer :auth_type
6
+ attr_writer :max_concurrency
7
+ attr_writer :token
8
+ attr_accessor :url
9
+
10
+ DEFAULT_URL = "https://api.nokotime.com".freeze
11
+
12
+ def initialize
13
+ @auth_type = nil
14
+ @max_concurrency = nil
15
+ @token = nil
16
+ @url = DEFAULT_URL
17
+ end
18
+
19
+ def auth_type
20
+ unless valid_auth?(@auth_type)
21
+ raise(
22
+ Errors::Configuration,
23
+ "#{@auth_type} isn't valid type authentication."
24
+ )
25
+ end
26
+
27
+ @auth_type || raise(
28
+ Errors::Configuration, "Authentication type missing."
29
+ )
30
+ end
31
+
32
+ def max_concurrency
33
+ @max_concurrency || raise(
34
+ Errors::Configuration, "Max concurrency missing."
35
+ )
36
+ end
37
+
38
+ def token
39
+ @token || raise(
40
+ Errors::Configuration, "Token missing."
41
+ )
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,87 @@
1
+ module Nokotime
2
+ class Connection
3
+ include Nokotime::Authentication
4
+
5
+ # rubocop:disable Metrics/MethodLength
6
+ def get(path, params: {}, request_options: {})
7
+ response = connection.get do |request|
8
+ authorize_request(request)
9
+ set_request_options(request, request_options)
10
+ request.url path, params
11
+ end
12
+
13
+ response
14
+ rescue Faraday::ConnectionFailed => e
15
+ raise Errors::ConnectionFailed.new(e), e.message
16
+ rescue Faraday::ResourceNotFound => e
17
+ raise Errors::ResourceNotFound.new(e), e.message
18
+ rescue Faraday::ClientError => e
19
+ raise Errors::ClientError.new(e), e.message
20
+ end
21
+ # rubocop:enable Metrics/MethodLength
22
+
23
+ # rubocop:disable Metrics/AbcSize
24
+ # rubocop:disable Metrics/MethodLength
25
+ def get_in_parallel(
26
+ path,
27
+ from_page_number,
28
+ to_page_number,
29
+ params: {},
30
+ request_options: {}
31
+ )
32
+ responses = []
33
+
34
+ connection.in_parallel(manager) do
35
+ (from_page_number..to_page_number).each do |page|
36
+ merged_params = {page: page}.merge(params)
37
+
38
+ responses << get(
39
+ path, params: merged_params, request_options: request_options
40
+ )
41
+ end
42
+ end
43
+
44
+ responses
45
+ rescue Faraday::ConnectionFailed => e
46
+ raise Errors::ConnectionFailed.new(e), e.message
47
+ rescue Faraday::ResourceNotFound => e
48
+ raise Errors::ResourceNotFound.new(e), e.message
49
+ rescue Faraday::ClientError => e
50
+ raise Errors::ClientError.new(e), e.message
51
+ end
52
+ # rubocop:enable Metrics/MethodLength
53
+ # rubocop:enable Metrics/AbcSize
54
+
55
+ private
56
+
57
+ def connection
58
+ @connection ||= Faraday.new(default_options) do |connection|
59
+ connection.request :json
60
+ connection.response :json, content_type: /\bjson$/
61
+ connection.response :raise_error
62
+ connection.adapter :typhoeus
63
+ end
64
+ end
65
+
66
+ def default_options
67
+ {
68
+ url: Nokotime.configuration.url,
69
+ headers: {
70
+ user_agent: "MyNokoBot/1.0",
71
+ accept: "application/json"
72
+ }
73
+ }
74
+ end
75
+
76
+ def set_request_options(request, options)
77
+ request.options.timeout = options[:timeout]
78
+ request.options.open_timeout = options[:open_timeout]
79
+ end
80
+
81
+ def manager
82
+ @manager ||= Typhoeus::Hydra.new(
83
+ max_concurrency: Nokotime.configuration.max_concurrency
84
+ )
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,5 @@
1
+ module Nokotime
2
+ module Errors
3
+ class Configuration < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module Nokotime
2
+ module Errors
3
+ class ConnectionFailed < StandardError; end
4
+ class ResourceNotFound < StandardError; end
5
+ class ClientError < StandardError; end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Nokotime
2
+ module Errors
3
+ class InvalidParams < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,67 @@
1
+ module Nokotime
2
+ class Paginator
3
+ attr_reader :raw_links
4
+
5
+ def initialize(raw_links)
6
+ @raw_links = raw_links
7
+ end
8
+
9
+ def next
10
+ find("next")&.dig(:url)
11
+ end
12
+
13
+ def prev
14
+ find("prev")&.dig(:url)
15
+ end
16
+
17
+ def first
18
+ find("first")&.dig(:url)
19
+ end
20
+
21
+ def last
22
+ find("last")&.dig(:url)
23
+ end
24
+
25
+ def total_pages
26
+ find("last")&.dig(:number_page)
27
+ end
28
+
29
+ private
30
+
31
+ def find(rel)
32
+ pages.find { |page| page[:rel] == rel }
33
+ end
34
+
35
+ def pages
36
+ return {} if raw_links.empty?
37
+
38
+ @pages ||=
39
+ raw_links.split(",").map do |link|
40
+ url, rel, number_page = split_and_clean_link(link)
41
+
42
+ {
43
+ url: "#{url.path}?#{url.query}",
44
+ rel: rel,
45
+ number_page: number_page
46
+ }
47
+ end
48
+ end
49
+
50
+ # Example of link response headers:
51
+ # "<https://api.nokotime.com/v2/users?page=2>; rel=\"last\""
52
+ #
53
+ # The first element is an URI. "Rel" means the relative position
54
+ # of the current page, in this case is last page.
55
+
56
+ def split_and_clean_link(link)
57
+ raw_url, rel = link.split(";").map(&:strip)
58
+
59
+ raw_url = raw_url.gsub(/<|>/, "")
60
+ rel = rel.gsub(/(rel=)?"/, "")
61
+ url = URI.parse(raw_url)
62
+ page = CGI.parse(url.query)["page"].first
63
+
64
+ [url, rel, page]
65
+ end
66
+ end
67
+ end