toolhound-ruby 1.0.4

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.
@@ -0,0 +1,31 @@
1
+ module Nearmiss
2
+ class Client
3
+
4
+ # Methods for the Notifications API
5
+ #
6
+ module Notifications
7
+
8
+ # List notifications for the current user
9
+ #
10
+ # If user is not supplied, repositories for the current
11
+ # authenticated user are returned.
12
+ #
13
+ # @note If the user provided is a GitHub organization, only the
14
+ # organization's public repositories will be listed. For retrieving
15
+ # organization repositories the {Organizations#organization_repositories}
16
+ # method should be used instead.
17
+ # @see https://developer.github.com/v3/repos/#list-your-repositories
18
+ # @see https://developer.github.com/v3/repos/#list-user-repositories
19
+ # @param user [Integer, String] Optional GitHub user login or id for which
20
+ # to list repos.
21
+ # @return [Array<Sawyer::Resource>] List of projects
22
+ def notifications(options = {})
23
+ paginate "notifications", options
24
+ end
25
+ alias :list_notifications :notifications
26
+
27
+
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ module Toolhound
2
+ class Client
3
+
4
+ # Methods for the Projects API
5
+ #
6
+ module Projects
7
+
8
+ # List projects
9
+ #
10
+ # @note Shows a list of projects for the users organization aka account
11
+ #
12
+ # @return [Array<Sawyer::Resource>] List of projects
13
+ def projects(options = {})
14
+ # paginate "projects", options
15
+
16
+ end
17
+ # alias :list_projects :projects
18
+
19
+ # Get a single project
20
+ #
21
+ # @param project [String] UUID of project to fetch
22
+ # @return [Sawyer::Resource] Project information
23
+ #
24
+ def project(project, options = {})
25
+ # get "#{project_path(project)}", options
26
+ end
27
+
28
+ private
29
+
30
+ # def project_path(id)
31
+ # if uuid?(id)
32
+ # "projects/#{id}"
33
+ # else
34
+ # "project/#{id}"
35
+ # end
36
+ # end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,81 @@
1
+ module Toolhound
2
+ class Client
3
+
4
+ # Methods for the Users API
5
+ #
6
+ module Users
7
+
8
+ # List users
9
+ #
10
+ # @note Logged in user must be an admin to see all users
11
+ #
12
+ # @return [Array<Sawyer::Resource>] List of projects
13
+ def users(options = {})
14
+ paginate "users", options
15
+ end
16
+ alias :list_users :users
17
+
18
+ # Get a single user
19
+ #
20
+ # @param user [String] Nearmiss user email or id.
21
+ # @return [Sawyer::Resource]
22
+ # @example
23
+ # Nearmiss.user("31817811-dce4-48c4-aa5f-f49603c5abee") or Nearmiss.user("m4rkuskk+a@gmail.com")
24
+ def user(user=nil, options = {})
25
+ if user.nil?
26
+ get "me", options
27
+ else
28
+ get "users/#{user}", options
29
+ end
30
+ # get User.path(user), options
31
+ end
32
+
33
+ # Edit a user
34
+ #
35
+ # @param options [Hash] User information.
36
+ # @option options [String] :email Email of user
37
+ # @option options [String] :name Name of user
38
+ # @option options [String] :nickname Nickname of user
39
+ # @option options [Integer] :role Set to admin or not
40
+ # @option options [String] :phone_number Phone number of user
41
+ # @option options [String] :image URL of image of user
42
+ # @option options [String] :language Code "en", "de", "es"
43
+ # @return
44
+ # [Sawyer::Resource] Edited user info
45
+ # @example Update a user
46
+ # @client.edit_user('some_id', {
47
+ # email: "mklooth@webcor.com",
48
+ # name: "Markus Klooth"
49
+ # })
50
+ #
51
+ def edit_user(user, options = {})
52
+ patch "update_user/#{user}", options
53
+ end
54
+ alias :update_user :edit_user
55
+
56
+ def update_email(user, options = {})
57
+
58
+ end
59
+
60
+
61
+ def delete_user(user, options = {})
62
+ delete "users/#{user}", options
63
+ end
64
+
65
+ # Validate user username and password
66
+ #
67
+ # @param options [Hash] User credentials
68
+ # @option options [String] :email Nearmiss login email
69
+ # @option options [String] :password Nearmiss password
70
+ # @return [Boolean] True if credentials are valid
71
+ def validate_credentials(options = {})
72
+ !self.class.new(options).user.nil?
73
+ rescue Toolhound::Unauthorized
74
+ false
75
+ end
76
+
77
+
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,47 @@
1
+ module Toolhound
2
+ module Configurable
3
+
4
+ # attr_accessor :auto_paginate, :per_page
5
+ attr_writer :dataserver, :port, :username, :password
6
+
7
+ # Define static methods
8
+ class << self
9
+
10
+ def keys
11
+ @keys ||= [
12
+ :dataserver,
13
+ :port,
14
+ :username,
15
+ :password
16
+ ]
17
+ end
18
+ end
19
+
20
+ # Set configuration options using a block
21
+ def configure
22
+ yield self
23
+ end
24
+
25
+ # Reset configuration options to default values
26
+ def reset!
27
+ Toolhound::Configurable.keys.each do |key|
28
+ instance_variable_set(:"@#{key}", Toolhound::Default.options[key])
29
+ end
30
+ self
31
+ end
32
+ alias setup reset!
33
+
34
+ # def api_endpoint
35
+ # File.join(@api_endpoint, "")
36
+ # end
37
+
38
+ def options
39
+ Hash[Toolhound::Configurable.keys.map{|key| [key, instance_variable_get(:"@#{key}")]}]
40
+ end
41
+
42
+ private
43
+
44
+
45
+
46
+ end
47
+ end
@@ -0,0 +1,16 @@
1
+ class String
2
+
3
+ def underscore()
4
+ camel_cased_word = self
5
+ acronym_regex = /#{["REST"].join("|")}/
6
+ return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
7
+ word = camel_cased_word.to_s.gsub('::'.freeze, '/'.freeze)
8
+ word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'.freeze }#{$2.downcase}" }
9
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
10
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
11
+ word.tr!("-".freeze, "_".freeze)
12
+ word.downcase!
13
+ word
14
+ end
15
+
16
+ end
@@ -0,0 +1,57 @@
1
+ # require "bim360/version" unless defined?(Nearmiss::VERSION)
2
+ # require 'bim360/response/raise_error'
3
+
4
+ module Toolhound
5
+
6
+
7
+ # Default configuration options for {Client}
8
+ module Default
9
+
10
+ # Default User Agent header string
11
+
12
+ PORT = 1433.freeze
13
+
14
+ class << self
15
+
16
+ # Configuration options
17
+ # @return [Hash]
18
+ def options
19
+ Hash[Toolhound::Configurable.keys.map{|key| [key, send(key)]}]
20
+ end
21
+
22
+
23
+
24
+ def config
25
+ @config ||= {}
26
+ end
27
+
28
+ # Default API endpoint from ENV or {API_ENDPOINT}
29
+ # @return [String]
30
+ def dataserver
31
+ ENV['TOOLHOUND_DATASERVER'] || config['dataserver']
32
+ end
33
+
34
+ def port
35
+ ENV['TOOLHOUND_PORT'] || config['port'] || PORT
36
+ end
37
+
38
+ # Default BIM360-Field username for Basic Auth from ENV
39
+ # @return [String]
40
+ def username
41
+ ENV['TOOLHOUND_USERNAME'] || config['username']
42
+ # ENV['NEARMISS_EMAIL'] || config['email']
43
+ end
44
+
45
+ # Default BIM360-Field password for Basic Auth from ENV
46
+ # @return [String]
47
+ def password
48
+ ENV['TOOLHOUND_PASSWORD'] || config['password']
49
+ end
50
+
51
+
52
+
53
+
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,186 @@
1
+ module Toolhound
2
+ # Custom error class for rescuing from all GitHub errors
3
+ class Error < StandardError
4
+
5
+ # Returns the appropriate Nearmiss::Error sublcass based
6
+ # on status and response message
7
+ #
8
+ # @param [Hash] response HTTP response
9
+ # @return [Nearmiss::Error]
10
+ def self.from_response(response)
11
+ status = response[:status].to_i
12
+ body = response[:body].to_s
13
+ headers = response[:response_headers]
14
+
15
+
16
+
17
+ if klass = case status
18
+ when 400 then Nearmiss::BadRequest
19
+ when 401 then Nearmiss::Unauthorized
20
+ when 403 then Nearmiss::Forbidden
21
+ when 404 then Nearmiss::NotFound
22
+ when 405 then Nearmiss::MethodNotAllowed
23
+ when 406 then Nearmiss::NotAcceptable
24
+ when 409 then Nearmiss::Conflict
25
+ when 415 then Nearmiss::UnsupportedMediaType
26
+ when 422 then Nearmiss::UnprocessableEntity
27
+ when 400..499 then Nearmiss::ClientError
28
+ when 500 then Nearmiss::InternalServerError
29
+ when 501 then Nearmiss::NotImplemented
30
+ when 502 then Nearmiss::BadGateway
31
+ when 503 then Nearmiss::ServiceUnavailable
32
+ when 500..599 then Nearmiss::ServerError
33
+ end
34
+ klass.new(response)
35
+ end
36
+ end
37
+
38
+ def initialize(response=nil)
39
+ @response = response
40
+ super(build_error_message)
41
+ end
42
+
43
+ # Array of validation errors
44
+ # @return [Array<Hash>] Error info
45
+ def errors
46
+ if data && data.is_a?(Hash)
47
+ data[:errors] || []
48
+ else
49
+ []
50
+ end
51
+ end
52
+
53
+ # private
54
+
55
+ def data
56
+ @data ||=
57
+ if (body = @response[:body]) && !body.empty?
58
+ if body.is_a?(String) &&
59
+ @response[:response_headers] &&
60
+ @response[:response_headers][:content_type] =~ /json/
61
+
62
+ # Sawyer::Agent.serializer.decode(body)
63
+ else
64
+ body
65
+ end
66
+ else
67
+ nil
68
+ end
69
+ end
70
+
71
+ def response_message
72
+ case data
73
+ when Hash
74
+ data[:message]
75
+ when String
76
+ data
77
+ end
78
+ end
79
+
80
+ def response_error
81
+ "Error: #{data[:error]}" if data.is_a?(Hash) && data[:error]
82
+ end
83
+
84
+ def response_error_summary
85
+ return nil unless data.is_a?(Hash) && !Array(data[:errors]).empty?
86
+
87
+ summary = "\nError summary:\n"
88
+ # summary << data[:errors].map do |hash|
89
+ # hash.map { |k,v| " #{k}: #{v}" }
90
+ # end.join("\n")
91
+ summary << data[:errors].join("\n")
92
+ summary
93
+ end
94
+
95
+ def build_error_message
96
+ return nil if @response.nil?
97
+
98
+
99
+
100
+ message = "#{@response[:method].to_s.upcase} "
101
+ message << redact_url(@response[:url].to_s) + ": "
102
+ message << "#{@response[:status]} - "
103
+ message << "#{response_message}" unless response_message.nil?
104
+ message << "#{response_error}" unless response_error.nil?
105
+ message << "#{response_error_summary}" unless response_error_summary.nil?
106
+ # message << MultiJson.dump(@response)
107
+ message
108
+ end
109
+
110
+ def redact_url(url_string)
111
+ %w[client_secret access_token].each do |token|
112
+ url_string.gsub!(/#{token}=\S+/, "#{token}=(redacted)") if url_string.include? token
113
+ end
114
+ url_string
115
+ end
116
+
117
+ end
118
+
119
+ # Raised on errors in the 400-499 range
120
+ class ClientError < Error; end
121
+
122
+ # Raised when Nearmiss-Field returns a 400 HTTP status code
123
+ class BadRequest < ClientError; end
124
+
125
+ # Raised when Nearmiss-Field returns a 401 HTTP status code
126
+ class Unauthorized < ClientError; end
127
+ # Raised when Nearmiss-Field returns a 403 HTTP status code
128
+ class Forbidden < ClientError; end
129
+
130
+ # Raised when Nearmiss-Field returns a 403 HTTP status code
131
+ # and body matches 'rate limit exceeded'
132
+ class TooManyRequests < Forbidden; end
133
+
134
+ # Raised when Nearmiss-Field returns a 403 HTTP status code
135
+ # and body matches 'login attempts exceeded'
136
+ class TooManyLoginAttempts < Forbidden; end
137
+
138
+ # Raised when Nearmiss-Field returns a 404 HTTP status code
139
+ class NotFound < ClientError; end
140
+
141
+ # Raised when Nearmiss-Field returns a 405 HTTP status code
142
+ class MethodNotAllowed < ClientError; end
143
+
144
+ # Raised when Nearmiss-Field returns a 406 HTTP status code
145
+ class NotAcceptable < ClientError; end
146
+
147
+ # Raised when Nearmiss-Field returns a 409 HTTP status code
148
+ class Conflict < ClientError; end
149
+
150
+ # Raised when Nearmiss-Field returns a 414 HTTP status code
151
+ class UnsupportedMediaType < ClientError; end
152
+
153
+ # Raised when Nearmiss-Field returns a 422 HTTP status code
154
+ class UnprocessableEntity < ClientError; end
155
+
156
+ # Raised on errors in the 500-599 range
157
+ class ServerError < Error; end
158
+
159
+ # Raised when Nearmiss-Field returns a 500 HTTP status code
160
+ class InternalServerError < ServerError; end
161
+
162
+ # Raised when Nearmiss-Field returns a 501 HTTP status code
163
+ class NotImplemented < ServerError; end
164
+
165
+ # Raised when Nearmiss-Field returns a 502 HTTP status code
166
+ class BadGateway < ServerError; end
167
+
168
+ # Raised when Nearmiss-Field returns a 503 HTTP status code
169
+ class ServiceUnavailable < ServerError; end
170
+
171
+ # Raised when client fails to provide valid Content-Type
172
+ class MissingContentType < ArgumentError; end
173
+
174
+ # Raised when a method requires an application client_id
175
+ # and secret but none is provided
176
+ class ApplicationCredentialsRequired < StandardError; end
177
+
178
+ class MissingParams < Error
179
+ def initialize(msg)
180
+
181
+ msg
182
+ end
183
+ end
184
+
185
+
186
+ end