Class: Assembla::API
- Inherits:
-
Object
- Object
- Assembla::API
- Extended by:
- ClassMethods
- Includes:
- Authorization, Constants, MimeType, RateLimit, Request::Verbs
- Defined in:
- lib/assembla_api/api.rb,
lib/assembla_api/api/config.rb,
lib/assembla_api/api/actions.rb,
lib/assembla_api/api/factory.rb,
lib/assembla_api/api/arguments.rb,
lib/assembla_api/api/config/property.rb,
lib/assembla_api/api/config/property_set.rb
Overview
Responsible for providing inspection of api methods
Direct Known Subclasses
Client, Client::Activity, Client::Authorizations, Client::Portfolio, Client::Portfolio::Invitations, Client::Portfolio::Spaces, Client::Portfolio::StandupReports, Client::Portfolio::Tasks, Client::Portfolio::TicketReports, Client::Portfolio::Tickets, Client::Portfolio::Users, Client::Spaces, Client::Spaces::Documents, Client::Spaces::Milestones, Client::Spaces::SpaceTools, Client::Spaces::SpaceTools::MergeRequests, Client::Spaces::SpaceTools::MergeRequests::Versions, Client::Spaces::SpaceTools::MergeRequests::Versions::Comments, Client::Spaces::SpaceTools::MergeRequests::Versions::Votes, Client::Spaces::Ssh, Client::Spaces::Ssh::Actions, Client::Spaces::Ssh::Actions::Launches, Client::Spaces::Ssh::Keys, Client::Spaces::Ssh::Launches, Client::Spaces::Ssh::Servers, Client::Spaces::StandupAwayReports, Client::Spaces::StandupReports, Client::Spaces::Tags, Client::Spaces::Tickets, Client::Spaces::Tickets::Associations, Client::Spaces::Tickets::Comments, Client::Spaces::Tickets::CustomFields, Client::Spaces::Tickets::Statuses, Client::Spaces::UserRoles, Client::Spaces::Users, Client::Spaces::Webhooks, Client::Spaces::WikiPages, Client::Spaces::WikiPages::Versions, Client::Tasks, Client::Users, Client::Users::Keys
Defined Under Namespace
Classes: Arguments, Config, Factory
Constant Summary
Constants included from MimeType
Constants included from Constants
Constants::ACCEPT, Constants::ACCEPTED_OAUTH_SCOPES, Constants::ACCEPT_CHARSET, Constants::CACHE_CONTROL, Constants::CONTENT_LENGTH, Constants::CONTENT_TYPE, Constants::DATE, Constants::ETAG, Constants::HEADER_LAST, Constants::HEADER_LINK, Constants::HEADER_NEXT, Constants::LOCATION, Constants::META_FIRST, Constants::META_LAST, Constants::META_NEXT, Constants::META_PREV, Constants::META_REL, Constants::OAUTH_SCOPES, Constants::PARAM_PAGE, Constants::PARAM_PER_PAGE, Constants::PARAM_START_PAGE, Constants::RATELIMIT_LIMIT, Constants::RATELIMIT_REMAINING, Constants::SERVER, Constants::USER_AGENT
Class Attribute Summary collapse
-
.root ⇒ Object
(also: root?)
readonly
Returns the value of attribute root.
Instance Attribute Summary collapse
-
#current_options ⇒ Object
Returns the value of attribute current_options.
Attributes included from Authorization
Class Method Summary collapse
-
.after_callbacks ⇒ Object
List of after callbacks.
-
.after_request(callback, params = {}) ⇒ Object
After request filter.
-
.before_callbacks ⇒ Object
List of before callbacks.
-
.before_request(callback, params = {}) ⇒ Object
Before request filter.
- .clear_request_methods! ⇒ Object
-
.extend_with_actions(child_class) ⇒ nil
Returns all API public methods for a given class.
- .extra_methods ⇒ Object
-
.extract_class_name(name, options) ⇒ String
private
Extracts class name from options.
- .inherited(child_class) ⇒ Object
- .internal_methods ⇒ Object
- .method_added(method_name) ⇒ Object
-
.namespace(*names) ⇒ self
Defines a namespace.
-
.request_methods ⇒ Set
private
Find all the api methods that should be considred by request callbacks.
- .root! ⇒ Object
Instance Method Summary collapse
-
#api_methods_in(klass) ⇒ Object
private
Finds api methods in a class.
-
#arguments(args = (not_set = true), options = {}, &block) ⇒ Object
Acts as setter and getter for api requests arguments parsing.
-
#execute(action, *args, &block) ⇒ Object
private
Execute action.
-
#filter_callbacks(kind, action_name) ⇒ Array[Hash]
private
Filter callbacks based on kind.
-
#initialize(options = {}, &block) ⇒ API
constructor
Create new API.
-
#method_missing(method_name, *args, &block) ⇒ Object
private
Responds to attribute query or attribute clear.
-
#module_methods_in(klass) ⇒ Object
private
Finds methods included through class modules.
-
#process_basic_auth(auth) ⇒ Object
Extract login and password from basic_auth parameter.
-
#run_callbacks(action_name, &block) ⇒ Object
private
Run all callbacks associated with this action.
-
#set(option, value = (not_set=true), ignore_setter = false, &block) ⇒ self
Set a configuration option for a given namespace.
-
#setup(options = {}) ⇒ Object
private
Configure options and process basic authorization.
-
#with(args) ⇒ Object
Scope for passing request required arguments.
- #yield_or_eval(&block) ⇒ Object
Methods included from ClassMethods
configuration, configure, require_all
Methods included from RateLimit
#ratelimit, #ratelimit_remaining, #ratelimit_reset
Methods included from Request::Verbs
#delete_request, #get_request, #head_request, #options_request, #patch_request, #post_request, #put_request
Methods included from MimeType
Methods included from Authorization
#auth_code, #authenticated?, #authentication, #authorize_url, #basic_authed?, #client, #get_token
Constructor Details
#initialize(options = {}, &block) ⇒ API
Create new API
45 46 47 48 |
# File 'lib/assembla_api/api.rb', line 45 def initialize(={}, &block) setup() yield_or_eval(&block) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Responds to attribute query or attribute clear
232 233 234 235 236 237 238 239 240 241 |
# File 'lib/assembla_api/api.rb', line 232 def method_missing(method_name, *args, &block) # :nodoc: case method_name.to_s when /^(.*)\?$/ return !!send($1.to_s) when /^clear_(.*)$/ send("#{$1.to_s}=", nil) else super end end |
Class Attribute Details
.root ⇒ Object (readonly) Also known as: root?
Returns the value of attribute root.
108 109 110 |
# File 'lib/assembla_api/api.rb', line 108 def root @root end |
Instance Attribute Details
#current_options ⇒ Object
Returns the value of attribute current_options.
30 31 32 |
# File 'lib/assembla_api/api.rb', line 30 def @current_options end |
Class Method Details
.after_callbacks ⇒ Object
List of after callbacks
89 90 91 |
# File 'lib/assembla_api/api.rb', line 89 def self.after_callbacks @after_callbacks ||= [] end |
.after_request(callback, params = {}) ⇒ Object
After request filter
103 104 105 |
# File 'lib/assembla_api/api.rb', line 103 def self.after_request(callback, params = {}) after_callbacks << params.merge(callback: callback) end |
.before_callbacks ⇒ Object
List of before callbacks
82 83 84 |
# File 'lib/assembla_api/api.rb', line 82 def self.before_callbacks @before_callbacks ||= [] end |
.before_request(callback, params = {}) ⇒ Object
Before request filter
96 97 98 |
# File 'lib/assembla_api/api.rb', line 96 def self.before_request(callback, params = {}) before_callbacks << params.merge(callback: callback) end |
.clear_request_methods! ⇒ Object
157 158 159 |
# File 'lib/assembla_api/api.rb', line 157 def self.clear_request_methods! @request_methods = nil end |
.extend_with_actions(child_class) ⇒ nil
Returns all API public methods for a given class.
11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/assembla_api/api/actions.rb', line 11 def self.extend_with_actions(child_class) child_class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def self.actions self.new.api_methods_in(#{child_class}) + self.new.module_methods_in(#{child_class}) end def actions api_methods_in(#{child_class}) + module_methods_in(#{child_class}) end RUBY_EVAL end |
.extra_methods ⇒ Object
138 139 140 |
# File 'lib/assembla_api/api.rb', line 138 def self.extra_methods ['actions'] end |
.extract_class_name(name, options) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Extracts class name from options
328 329 330 331 332 333 334 |
# File 'lib/assembla_api/api.rb', line 328 def self.extract_class_name(name, ) converted = .fetch(:full_name, name).to_s converted = converted.split('_').map(&:capitalize).join class_name = .fetch(:root, false) ? '': "#{self.name}::" class_name += converted class_name end |
.inherited(child_class) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/assembla_api/api.rb', line 116 def self.inherited(child_class) before_callbacks.reverse_each { |callback| child_class.before_callbacks.unshift(callback) } after_callbacks.reverse_each { |callback| child_class.after_callbacks.unshift(callback) } extend_with_actions(child_class) unless child_class.instance_variable_defined?(:@root) child_class.instance_variable_set(:@root, false) end super end |
.internal_methods ⇒ Object
132 133 134 135 136 |
# File 'lib/assembla_api/api.rb', line 132 def self.internal_methods api = self api = api.superclass until api.root? api.public_instance_methods(true) end |
.method_added(method_name) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/assembla_api/api.rb', line 161 def self.method_added(method_name) method_name = method_name.to_s.gsub(/_with(out)?_callback_.*$/, '') # Only subclasses matter return if self.root? return if extra_methods.include?(method_name) # Only public methods are of interest return unless request_methods.include?(method_name) # Do not redefine return if (@__methods_added ||= []).include?(method_name) class_name = self.name.to_s.split('::').last.downcase with_method = "#{method_name}_with_callback_#{class_name}" without_method = "#{method_name}_without_callback_#{class_name}" return if public_method_defined?(with_method) [method_name, with_method, without_method].each do |met| @__methods_added << met end return if public_method_defined?(with_method) define_method(with_method) do |*args, &block| send(:execute, without_method, *args, &block) end alias_method without_method, method_name alias_method method_name, with_method clear_request_methods! end |
.namespace(*names) ⇒ self
Defines a namespace
303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/assembla_api/api.rb', line 303 def self.namespace(*names) = names.last.is_a?(Hash) ? names.pop : {} names = names.map(&:to_sym) name = names.pop return if public_method_defined?(name) class_name = extract_class_name(name, ) define_method(name) do |*args, &block| = args.last.is_a?(Hash) ? args.pop : {} API::Factory.new(class_name, .merge(), &block) end self end |
.request_methods ⇒ Set
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find all the api methods that should be considred by request callbacks.
148 149 150 151 152 153 154 155 |
# File 'lib/assembla_api/api.rb', line 148 def self.request_methods @request_methods ||= begin methods = (public_instance_methods(true) - internal_methods + public_instance_methods(false)).uniq.map(&:to_s) Set.new(methods - extra_methods) end end |
.root! ⇒ Object
112 113 114 |
# File 'lib/assembla_api/api.rb', line 112 def self.root! @root = true end |
Instance Method Details
#api_methods_in(klass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Finds api methods in a class
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/assembla_api/api/actions.rb', line 30 def api_methods_in(klass) methods = klass.send(:instance_methods, false) - [:actions] methods.sort.each_with_object([]) do |method_name, accumulator| unless method_name.to_s.include?('with') || method_name.to_s.include?('without') accumulator << method_name end accumulator end end |
#arguments(args = (not_set = true), options = {}, &block) ⇒ Object
Acts as setter and getter for api requests arguments parsing.
Returns Arguments instance.
247 248 249 250 251 252 253 |
# File 'lib/assembla_api/api.rb', line 247 def arguments(args=(not_set = true), ={}, &block) if not_set @arguments else @arguments = Arguments.new(.merge!(api: self)).parse(*args, &block) end end |
#execute(action, *args, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute action
220 221 222 223 224 225 226 227 |
# File 'lib/assembla_api/api.rb', line 220 def execute(action, *args, &block) action_name = action.to_s.gsub(/_with(out)?_callback_.*$/, '') result = nil run_callbacks(action_name) do result = send(action, *args, &block) end result end |
#filter_callbacks(kind, action_name) ⇒ Array[Hash]
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Filter callbacks based on kind
198 199 200 201 202 |
# File 'lib/assembla_api/api.rb', line 198 def filter_callbacks(kind, action_name) matched_callbacks = self.class.send("#{kind}_callbacks").select do |callback| callback[:only].nil? || callback[:only].include?(action_name) end end |
#module_methods_in(klass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Finds methods included through class modules
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/assembla_api/api/actions.rb', line 47 def module_methods_in(klass) klass.included_modules.each_with_object([]) do |mod, accumulator| if mod.to_s =~ /#{klass}/ mod.instance_methods(false).each do |method| accumulator << method end end accumulator end end |
#process_basic_auth(auth) ⇒ Object
Extract login and password from basic_auth parameter
69 70 71 72 73 74 75 76 77 |
# File 'lib/assembla_api/api.rb', line 69 def process_basic_auth(auth) case auth when String self.login, self.password = auth.split(':', 2) when Hash self.login = auth[:login] self.password = auth[:password] end end |
#run_callbacks(action_name, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Run all callbacks associated with this action
209 210 211 212 213 |
# File 'lib/assembla_api/api.rb', line 209 def run_callbacks(action_name, &block) filter_callbacks(:before, action_name).each { |hook| send hook[:callback] } yield if block_given? filter_callbacks(:after, action_name).each { |hook| send hook[:callback] } end |
#set(option, value = (not_set=true), ignore_setter = false, &block) ⇒ self
Set a configuration option for a given namespace
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/assembla_api/api.rb', line 278 def set(option, value=(not_set=true), ignore_setter=false, &block) raise ArgumentError, 'value not set' if block and !not_set return self if !not_set and value.nil? if not_set option return self end if respond_to?("#{option}=") and not ignore_setter return __send__("#{option}=", value) end define_accessors option, value self end |
#setup(options = {}) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Configure options and process basic authorization
58 59 60 61 62 63 64 65 |
# File 'lib/assembla_api/api.rb', line 58 def setup(={}) = Assembla.configuration.fetch.merge() self. = Assembla.configuration.property_names.each do |key| send("#{key}=", [key]) end process_basic_auth([:basic_auth]) end |
#with(args) ⇒ Object
Scope for passing request required arguments.
257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/assembla_api/api.rb', line 257 def with(args) case args when Hash set args when /.*\/.*/i user, repo = args.split('/') set :user => user, :repo => repo else ::Kernel.raise ArgumentError, 'This api does not support passed in arguments' end end |
#yield_or_eval(&block) ⇒ Object
50 51 52 53 |
# File 'lib/assembla_api/api.rb', line 50 def yield_or_eval(&block) return unless block block.arity > 0 ? yield(self) : self.instance_eval(&block) end |