assembla_api 0.1.2
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 +7 -0
- data/LICENSE.txt +20 -0
- data/Rakefile +22 -0
- data/lib/assembla_api.rb +130 -0
- data/lib/assembla_api/api.rb +373 -0
- data/lib/assembla_api/api/actions.rb +58 -0
- data/lib/assembla_api/api/arguments.rb +248 -0
- data/lib/assembla_api/api/config.rb +107 -0
- data/lib/assembla_api/api/config/property.rb +30 -0
- data/lib/assembla_api/api/config/property_set.rb +119 -0
- data/lib/assembla_api/api/factory.rb +33 -0
- data/lib/assembla_api/authorization.rb +76 -0
- data/lib/assembla_api/client.rb +21 -0
- data/lib/assembla_api/client/activity.rb +30 -0
- data/lib/assembla_api/client/authorizations.rb +143 -0
- data/lib/assembla_api/client/authorizations/app.rb +98 -0
- data/lib/assembla_api/client/portfolio.rb +19 -0
- data/lib/assembla_api/client/portfolio/invitations.rb +30 -0
- data/lib/assembla_api/client/portfolio/spaces.rb +13 -0
- data/lib/assembla_api/client/portfolio/standup_reports.rb +34 -0
- data/lib/assembla_api/client/portfolio/tasks.rb +13 -0
- data/lib/assembla_api/client/portfolio/ticket_reports.rb +13 -0
- data/lib/assembla_api/client/portfolio/tickets.rb +13 -0
- data/lib/assembla_api/client/portfolio/users.rb +13 -0
- data/lib/assembla_api/client/spaces.rb +140 -0
- data/lib/assembla_api/client/spaces/documents.rb +87 -0
- data/lib/assembla_api/client/spaces/milestones.rb +102 -0
- data/lib/assembla_api/client/spaces/space_tools.rb +65 -0
- data/lib/assembla_api/client/spaces/space_tools/merge_requests.rb +105 -0
- data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions.rb +41 -0
- data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/comments.rb +34 -0
- data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/votes.rb +46 -0
- data/lib/assembla_api/client/spaces/ssh.rb +14 -0
- data/lib/assembla_api/client/spaces/ssh/actions.rb +76 -0
- data/lib/assembla_api/client/spaces/ssh/actions/launches.rb +14 -0
- data/lib/assembla_api/client/spaces/ssh/keys.rb +18 -0
- data/lib/assembla_api/client/spaces/ssh/launches.rb +29 -0
- data/lib/assembla_api/client/spaces/ssh/servers.rb +63 -0
- data/lib/assembla_api/client/spaces/standup_away_reports.rb +41 -0
- data/lib/assembla_api/client/spaces/standup_reports.rb +41 -0
- data/lib/assembla_api/client/spaces/tags.rb +96 -0
- data/lib/assembla_api/client/spaces/tickets.rb +154 -0
- data/lib/assembla_api/client/spaces/tickets/associations.rb +57 -0
- data/lib/assembla_api/client/spaces/tickets/comments.rb +45 -0
- data/lib/assembla_api/client/spaces/tickets/custom_fields.rb +57 -0
- data/lib/assembla_api/client/spaces/tickets/statuses.rb +55 -0
- data/lib/assembla_api/client/spaces/user_roles.rb +61 -0
- data/lib/assembla_api/client/spaces/users.rb +11 -0
- data/lib/assembla_api/client/spaces/webhooks.rb +63 -0
- data/lib/assembla_api/client/spaces/wiki_pages.rb +78 -0
- data/lib/assembla_api/client/spaces/wiki_pages/versions.rb +20 -0
- data/lib/assembla_api/client/tasks.rb +72 -0
- data/lib/assembla_api/client/users.rb +49 -0
- data/lib/assembla_api/client/users/keys.rb +97 -0
- data/lib/assembla_api/configuration.rb +71 -0
- data/lib/assembla_api/connection.rb +66 -0
- data/lib/assembla_api/constants.rb +74 -0
- data/lib/assembla_api/core_ext/array.rb +25 -0
- data/lib/assembla_api/core_ext/hash.rb +92 -0
- data/lib/assembla_api/core_ext/ordered_hash.rb +107 -0
- data/lib/assembla_api/deprecation.rb +39 -0
- data/lib/assembla_api/error.rb +37 -0
- data/lib/assembla_api/error/bad_request.rb +14 -0
- data/lib/assembla_api/error/client_error.rb +20 -0
- data/lib/assembla_api/error/forbidden.rb +14 -0
- data/lib/assembla_api/error/internal_server_error.rb +15 -0
- data/lib/assembla_api/error/invalid_options.rb +18 -0
- data/lib/assembla_api/error/not_acceptable.rb +15 -0
- data/lib/assembla_api/error/not_found.rb +14 -0
- data/lib/assembla_api/error/required_params.rb +18 -0
- data/lib/assembla_api/error/service_error.rb +68 -0
- data/lib/assembla_api/error/service_unavailable.rb +15 -0
- data/lib/assembla_api/error/unauthorized.rb +15 -0
- data/lib/assembla_api/error/unknown_media.rb +18 -0
- data/lib/assembla_api/error/unknown_value.rb +18 -0
- data/lib/assembla_api/error/unprocessable_entity.rb +14 -0
- data/lib/assembla_api/error/validations.rb +18 -0
- data/lib/assembla_api/ext/faraday.rb +38 -0
- data/lib/assembla_api/jsonable.rb +18 -0
- data/lib/assembla_api/middleware.rb +31 -0
- data/lib/assembla_api/mime_type.rb +33 -0
- data/lib/assembla_api/normalizer.rb +25 -0
- data/lib/assembla_api/null_encoder.rb +25 -0
- data/lib/assembla_api/page_iterator.rb +142 -0
- data/lib/assembla_api/page_links.rb +45 -0
- data/lib/assembla_api/paged_request.rb +40 -0
- data/lib/assembla_api/pagination.rb +102 -0
- data/lib/assembla_api/parameter_filter.rb +32 -0
- data/lib/assembla_api/params_hash.rb +101 -0
- data/lib/assembla_api/rate_limit.rb +25 -0
- data/lib/assembla_api/request.rb +85 -0
- data/lib/assembla_api/request/basic_auth.rb +33 -0
- data/lib/assembla_api/request/jsonize.rb +53 -0
- data/lib/assembla_api/request/key_auth.rb +31 -0
- data/lib/assembla_api/request/oauth2.rb +42 -0
- data/lib/assembla_api/request/verbs.rb +60 -0
- data/lib/assembla_api/response.rb +28 -0
- data/lib/assembla_api/response/header.rb +76 -0
- data/lib/assembla_api/response/jsonize.rb +29 -0
- data/lib/assembla_api/response/mashify.rb +24 -0
- data/lib/assembla_api/response/raise_error.rb +18 -0
- data/lib/assembla_api/response/xmlize.rb +26 -0
- data/lib/assembla_api/response_wrapper.rb +157 -0
- data/lib/assembla_api/ssl_certs/cacerts.pem +2183 -0
- data/lib/assembla_api/utils/url.rb +59 -0
- data/lib/assembla_api/validations.rb +25 -0
- data/lib/assembla_api/validations/format.rb +24 -0
- data/lib/assembla_api/validations/presence.rb +30 -0
- data/lib/assembla_api/validations/required.rb +24 -0
- data/lib/assembla_api/validations/token.rb +41 -0
- data/lib/assembla_api/version.rb +12 -0
- metadata +347 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 544c0b5cf90c28355fa82a7c6705f1ac875a1ce2
|
|
4
|
+
data.tar.gz: 8d97d3258aa5ae4fef0838249c7230de0f00fe26
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3068a96928b8169a1a0dce98ec74a905203b8160774e84f744649bfcc60dacd1b9d2b6a4ad920524429071c9231dc8a6fe8c9994a1a6721e123b796797c243ca
|
|
7
|
+
data.tar.gz: 830a2513a480adb5922289325df0c5e4527dea53284bba6422d76407899b908183174dd708e5c88131bd9b23bc9f5e8b705e903485a831152ac6085caff760dd
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2014 Assembla
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
|
|
6
|
+
#RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
7
|
+
# spec.pattern = FileList['spec/**/*_spec.rb']
|
|
8
|
+
#end
|
|
9
|
+
|
|
10
|
+
FileList['tasks/**/*.rake'].each(&method(:import))
|
|
11
|
+
|
|
12
|
+
#desc 'Run all specs on CI'
|
|
13
|
+
#task ci: [:spec, :features, 'coveralls:push']
|
|
14
|
+
|
|
15
|
+
desc 'Load gem inside irb console'
|
|
16
|
+
task :console do
|
|
17
|
+
require 'irb'
|
|
18
|
+
require 'irb/completion'
|
|
19
|
+
require File.join(__FILE__, '../lib/assembla_api')
|
|
20
|
+
ARGV.clear
|
|
21
|
+
IRB.start
|
|
22
|
+
end
|
data/lib/assembla_api.rb
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'assembla_api/version'
|
|
5
|
+
require 'assembla_api/configuration'
|
|
6
|
+
require 'assembla_api/constants'
|
|
7
|
+
require 'assembla_api/utils/url'
|
|
8
|
+
require 'assembla_api/connection'
|
|
9
|
+
require 'assembla_api/deprecation'
|
|
10
|
+
require 'assembla_api/core_ext/ordered_hash'
|
|
11
|
+
require 'assembla_api/ext/faraday'
|
|
12
|
+
require 'assembla_api/middleware'
|
|
13
|
+
|
|
14
|
+
module Assembla
|
|
15
|
+
LIBNAME = 'assembla_api'
|
|
16
|
+
|
|
17
|
+
LIBDIR = File.expand_path("../#{LIBNAME}", __FILE__)
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
def included(base)
|
|
21
|
+
base.extend ClassMethods
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Alias for Assembla::Client.new
|
|
25
|
+
#
|
|
26
|
+
# @param [Hash] options
|
|
27
|
+
# the configuration options
|
|
28
|
+
#
|
|
29
|
+
# @return [Assembla::Client]
|
|
30
|
+
#
|
|
31
|
+
# @api public
|
|
32
|
+
def new(options = {}, &block)
|
|
33
|
+
Client.new(options, &block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Default middleware stack that uses default adapter as specified
|
|
37
|
+
# by configuration setup
|
|
38
|
+
#
|
|
39
|
+
# @return [Proc]
|
|
40
|
+
#
|
|
41
|
+
# @api private
|
|
42
|
+
def default_middleware(options = {})
|
|
43
|
+
Middleware.default(options)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Delegate to Assembla::Client
|
|
47
|
+
#
|
|
48
|
+
# @api private
|
|
49
|
+
def method_missing(method_name, *args, &block)
|
|
50
|
+
if new.respond_to?(method_name)
|
|
51
|
+
new.send(method_name, *args, &block)
|
|
52
|
+
elsif configuration.respond_to?(method_name)
|
|
53
|
+
Assembla.configuration.send(method_name, *args, &block)
|
|
54
|
+
else
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def respond_to?(method_name, include_private = false)
|
|
60
|
+
new.respond_to?(method_name, include_private) ||
|
|
61
|
+
configuration.respond_to?(method_name) ||
|
|
62
|
+
super(method_name, include_private)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
module ClassMethods
|
|
67
|
+
|
|
68
|
+
# Requires internal libraries
|
|
69
|
+
#
|
|
70
|
+
# @param [String] prefix
|
|
71
|
+
# the relative path prefix
|
|
72
|
+
# @param [Array[String]] libs
|
|
73
|
+
# the array of libraries to require
|
|
74
|
+
#
|
|
75
|
+
# @return [self]
|
|
76
|
+
def require_all(prefix, *libs)
|
|
77
|
+
libs.each do |lib|
|
|
78
|
+
require "#{File.join(prefix, lib)}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# The client configuration
|
|
83
|
+
#
|
|
84
|
+
# @return [Configuration]
|
|
85
|
+
#
|
|
86
|
+
# @api public
|
|
87
|
+
def configuration
|
|
88
|
+
@configuration ||= Configuration.new
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Configure options
|
|
92
|
+
#
|
|
93
|
+
# @example
|
|
94
|
+
# Assembla.configure do |c|
|
|
95
|
+
# c.some_option = true
|
|
96
|
+
# end
|
|
97
|
+
#
|
|
98
|
+
# @yield the configuration block
|
|
99
|
+
# @yieldparam configuration [Assembla::Configuration]
|
|
100
|
+
# the configuration instance
|
|
101
|
+
#
|
|
102
|
+
# @return [nil]
|
|
103
|
+
#
|
|
104
|
+
# @api public
|
|
105
|
+
def configure
|
|
106
|
+
yield configuration
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
extend ClassMethods
|
|
111
|
+
|
|
112
|
+
require_all LIBDIR,
|
|
113
|
+
'authorization',
|
|
114
|
+
'validations',
|
|
115
|
+
'normalizer',
|
|
116
|
+
'parameter_filter',
|
|
117
|
+
'api',
|
|
118
|
+
'client',
|
|
119
|
+
'pagination',
|
|
120
|
+
'request',
|
|
121
|
+
'response',
|
|
122
|
+
'response_wrapper',
|
|
123
|
+
'error',
|
|
124
|
+
'mime_type',
|
|
125
|
+
'page_links',
|
|
126
|
+
'paged_request',
|
|
127
|
+
'page_iterator',
|
|
128
|
+
'params_hash'
|
|
129
|
+
|
|
130
|
+
end # Assembla
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'assembla_api/configuration'
|
|
4
|
+
require 'assembla_api/mime_type'
|
|
5
|
+
require 'assembla_api/rate_limit'
|
|
6
|
+
require 'assembla_api/core_ext/hash'
|
|
7
|
+
require 'assembla_api/core_ext/array'
|
|
8
|
+
require 'assembla_api/null_encoder'
|
|
9
|
+
|
|
10
|
+
require 'assembla_api/request/verbs'
|
|
11
|
+
|
|
12
|
+
require 'assembla_api/api/actions'
|
|
13
|
+
require 'assembla_api/api/factory'
|
|
14
|
+
require 'assembla_api/api/arguments'
|
|
15
|
+
|
|
16
|
+
module Assembla
|
|
17
|
+
# Core class responsible for api interface operations
|
|
18
|
+
class API
|
|
19
|
+
extend Assembla::ClassMethods
|
|
20
|
+
include Constants
|
|
21
|
+
include Authorization
|
|
22
|
+
include MimeType
|
|
23
|
+
include Request::Verbs
|
|
24
|
+
include RateLimit
|
|
25
|
+
|
|
26
|
+
attr_reader *Assembla.configuration.property_names
|
|
27
|
+
|
|
28
|
+
attr_accessor *Validations::VALID_API_KEYS
|
|
29
|
+
|
|
30
|
+
attr_accessor :current_options
|
|
31
|
+
|
|
32
|
+
# Callback to update current configuration options
|
|
33
|
+
class_eval do
|
|
34
|
+
Assembla.configuration.property_names.each do |key|
|
|
35
|
+
define_method "#{key}=" do |arg|
|
|
36
|
+
self.instance_variable_set("@#{key}", arg)
|
|
37
|
+
self.current_options.merge!({:"#{key}" => arg})
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Create new API
|
|
43
|
+
#
|
|
44
|
+
# @api public
|
|
45
|
+
def initialize(options={}, &block)
|
|
46
|
+
setup(options)
|
|
47
|
+
yield_or_eval(&block) if block_given?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def yield_or_eval(&block)
|
|
51
|
+
return unless block
|
|
52
|
+
block.arity > 0 ? yield(self) : self.instance_eval(&block)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Configure options and process basic authorization
|
|
56
|
+
#
|
|
57
|
+
# @api private
|
|
58
|
+
def setup(options={})
|
|
59
|
+
options = Assembla.configuration.fetch.merge(options)
|
|
60
|
+
self.current_options = options
|
|
61
|
+
Assembla.configuration.property_names.each do |key|
|
|
62
|
+
send("#{key}=", options[key])
|
|
63
|
+
end
|
|
64
|
+
process_basic_auth(options[:basic_auth])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Extract login and password from basic_auth parameter
|
|
68
|
+
#
|
|
69
|
+
def process_basic_auth(auth)
|
|
70
|
+
case auth
|
|
71
|
+
when String
|
|
72
|
+
self.login, self.password = auth.split(':', 2)
|
|
73
|
+
when Hash
|
|
74
|
+
self.login = auth[:login]
|
|
75
|
+
self.password = auth[:password]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# List of before callbacks
|
|
80
|
+
#
|
|
81
|
+
# @api public
|
|
82
|
+
def self.before_callbacks
|
|
83
|
+
@before_callbacks ||= []
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# List of after callbacks
|
|
87
|
+
#
|
|
88
|
+
# @api public
|
|
89
|
+
def self.after_callbacks
|
|
90
|
+
@after_callbacks ||= []
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Before request filter
|
|
94
|
+
#
|
|
95
|
+
# @api public
|
|
96
|
+
def self.before_request(callback, params = {})
|
|
97
|
+
before_callbacks << params.merge(callback: callback)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# After request filter
|
|
101
|
+
#
|
|
102
|
+
# @api public
|
|
103
|
+
def self.after_request(callback, params = {})
|
|
104
|
+
after_callbacks << params.merge(callback: callback)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
class << self
|
|
108
|
+
attr_reader :root
|
|
109
|
+
alias_method :root?, :root
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.root!
|
|
113
|
+
@root = true
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.inherited(child_class)
|
|
117
|
+
before_callbacks.reverse_each { |callback|
|
|
118
|
+
child_class.before_callbacks.unshift(callback)
|
|
119
|
+
}
|
|
120
|
+
after_callbacks.reverse_each { |callback|
|
|
121
|
+
child_class.after_callbacks.unshift(callback)
|
|
122
|
+
}
|
|
123
|
+
extend_with_actions(child_class)
|
|
124
|
+
unless child_class.instance_variable_defined?(:@root)
|
|
125
|
+
child_class.instance_variable_set(:@root, false)
|
|
126
|
+
end
|
|
127
|
+
super
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
root!
|
|
131
|
+
|
|
132
|
+
def self.internal_methods
|
|
133
|
+
api = self
|
|
134
|
+
api = api.superclass until api.root?
|
|
135
|
+
api.public_instance_methods(true)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def self.extra_methods
|
|
139
|
+
['actions']
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Find all the api methods that should be considred by
|
|
143
|
+
# request callbacks.
|
|
144
|
+
#
|
|
145
|
+
# @return [Set]
|
|
146
|
+
#
|
|
147
|
+
# @api private
|
|
148
|
+
def self.request_methods
|
|
149
|
+
@request_methods ||= begin
|
|
150
|
+
methods = (public_instance_methods(true) -
|
|
151
|
+
internal_methods +
|
|
152
|
+
public_instance_methods(false)).uniq.map(&:to_s)
|
|
153
|
+
Set.new(methods - extra_methods)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def self.clear_request_methods!
|
|
158
|
+
@request_methods = nil
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def self.method_added(method_name)
|
|
162
|
+
method_name = method_name.to_s.gsub(/_with(out)?_callback_.*$/, '')
|
|
163
|
+
# Only subclasses matter
|
|
164
|
+
return if self.root?
|
|
165
|
+
return if extra_methods.include?(method_name)
|
|
166
|
+
# Only public methods are of interest
|
|
167
|
+
return unless request_methods.include?(method_name)
|
|
168
|
+
# Do not redefine
|
|
169
|
+
return if (@__methods_added ||= []).include?(method_name)
|
|
170
|
+
|
|
171
|
+
class_name = self.name.to_s.split('::').last.downcase
|
|
172
|
+
with_method = "#{method_name}_with_callback_#{class_name}"
|
|
173
|
+
without_method = "#{method_name}_without_callback_#{class_name}"
|
|
174
|
+
|
|
175
|
+
return if public_method_defined?(with_method)
|
|
176
|
+
|
|
177
|
+
[method_name, with_method, without_method].each do |met|
|
|
178
|
+
@__methods_added << met
|
|
179
|
+
end
|
|
180
|
+
return if public_method_defined?(with_method)
|
|
181
|
+
|
|
182
|
+
define_method(with_method) do |*args, &block|
|
|
183
|
+
send(:execute, without_method, *args, &block)
|
|
184
|
+
end
|
|
185
|
+
alias_method without_method, method_name
|
|
186
|
+
alias_method method_name, with_method
|
|
187
|
+
clear_request_methods!
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Filter callbacks based on kind
|
|
191
|
+
#
|
|
192
|
+
# @param [Symbol] kind
|
|
193
|
+
# one of :before or :after
|
|
194
|
+
#
|
|
195
|
+
# @return [Array[Hash]]
|
|
196
|
+
#
|
|
197
|
+
# @api private
|
|
198
|
+
def filter_callbacks(kind, action_name)
|
|
199
|
+
matched_callbacks = self.class.send("#{kind}_callbacks").select do |callback|
|
|
200
|
+
callback[:only].nil? || callback[:only].include?(action_name)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Run all callbacks associated with this action
|
|
205
|
+
#
|
|
206
|
+
# @apram [Symbol] action_name
|
|
207
|
+
#
|
|
208
|
+
# @api private
|
|
209
|
+
def run_callbacks(action_name, &block)
|
|
210
|
+
filter_callbacks(:before, action_name).each { |hook| send hook[:callback] }
|
|
211
|
+
yield if block_given?
|
|
212
|
+
filter_callbacks(:after, action_name).each { |hook| send hook[:callback] }
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Execute action
|
|
216
|
+
#
|
|
217
|
+
# @param [Symbol] action
|
|
218
|
+
#
|
|
219
|
+
# @api private
|
|
220
|
+
def execute(action, *args, &block)
|
|
221
|
+
action_name = action.to_s.gsub(/_with(out)?_callback_.*$/, '')
|
|
222
|
+
result = nil
|
|
223
|
+
run_callbacks(action_name) do
|
|
224
|
+
result = send(action, *args, &block)
|
|
225
|
+
end
|
|
226
|
+
result
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Responds to attribute query or attribute clear
|
|
230
|
+
#
|
|
231
|
+
# @api private
|
|
232
|
+
def method_missing(method_name, *args, &block) # :nodoc:
|
|
233
|
+
case method_name.to_s
|
|
234
|
+
when /^(.*)\?$/
|
|
235
|
+
return !!send($1.to_s)
|
|
236
|
+
when /^clear_(.*)$/
|
|
237
|
+
send("#{$1.to_s}=", nil)
|
|
238
|
+
else
|
|
239
|
+
super
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Acts as setter and getter for api requests arguments parsing.
|
|
244
|
+
#
|
|
245
|
+
# Returns Arguments instance.
|
|
246
|
+
#
|
|
247
|
+
def arguments(args=(not_set = true), options={}, &block)
|
|
248
|
+
if not_set
|
|
249
|
+
@arguments
|
|
250
|
+
else
|
|
251
|
+
@arguments = Arguments.new(options.merge!(api: self)).parse(*args, &block)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Scope for passing request required arguments.
|
|
256
|
+
#
|
|
257
|
+
def with(args)
|
|
258
|
+
case args
|
|
259
|
+
when Hash
|
|
260
|
+
set args
|
|
261
|
+
when /.*\/.*/i
|
|
262
|
+
user, repo = args.split('/')
|
|
263
|
+
set :user => user, :repo => repo
|
|
264
|
+
else
|
|
265
|
+
::Kernel.raise ArgumentError, 'This api does not support passed in arguments'
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Set a configuration option for a given namespace
|
|
270
|
+
#
|
|
271
|
+
# @param [String] option
|
|
272
|
+
# @param [Object] value
|
|
273
|
+
# @param [Boolean] ignore_setter
|
|
274
|
+
#
|
|
275
|
+
# @return [self]
|
|
276
|
+
#
|
|
277
|
+
# @api public
|
|
278
|
+
def set(option, value=(not_set=true), ignore_setter=false, &block)
|
|
279
|
+
raise ArgumentError, 'value not set' if block and !not_set
|
|
280
|
+
return self if !not_set and value.nil?
|
|
281
|
+
|
|
282
|
+
if not_set
|
|
283
|
+
set_options option
|
|
284
|
+
return self
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
if respond_to?("#{option}=") and not ignore_setter
|
|
288
|
+
return __send__("#{option}=", value)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
define_accessors option, value
|
|
292
|
+
self
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Defines a namespace
|
|
296
|
+
#
|
|
297
|
+
# @param [Array[Symbol]] names
|
|
298
|
+
# the name for the scope
|
|
299
|
+
#
|
|
300
|
+
# @return [self]
|
|
301
|
+
#
|
|
302
|
+
# @api public
|
|
303
|
+
def self.namespace(*names)
|
|
304
|
+
options = names.last.is_a?(Hash) ? names.pop : {}
|
|
305
|
+
names = names.map(&:to_sym)
|
|
306
|
+
name = names.pop
|
|
307
|
+
return if public_method_defined?(name)
|
|
308
|
+
|
|
309
|
+
class_name = extract_class_name(name, options)
|
|
310
|
+
define_method(name) do |*args, &block|
|
|
311
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
312
|
+
API::Factory.new(class_name, current_options.merge(options), &block)
|
|
313
|
+
end
|
|
314
|
+
self
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Extracts class name from options
|
|
318
|
+
#
|
|
319
|
+
# @param [Hash] options
|
|
320
|
+
# @option options [String] :full_name
|
|
321
|
+
# the full name for the class
|
|
322
|
+
# @option options [Boolean] :root
|
|
323
|
+
# if the class is at the root or not
|
|
324
|
+
#
|
|
325
|
+
# @return [String]
|
|
326
|
+
#
|
|
327
|
+
# @api private
|
|
328
|
+
def self.extract_class_name(name, options)
|
|
329
|
+
converted = options.fetch(:full_name, name).to_s
|
|
330
|
+
converted = converted.split('_').map(&:capitalize).join
|
|
331
|
+
class_name = options.fetch(:root, false) ? '': "#{self.name}::"
|
|
332
|
+
class_name += converted
|
|
333
|
+
class_name
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
private
|
|
337
|
+
|
|
338
|
+
# Set multiple options
|
|
339
|
+
#
|
|
340
|
+
# @api private
|
|
341
|
+
def set_options(options)
|
|
342
|
+
unless options.respond_to?(:each)
|
|
343
|
+
raise ArgumentError, 'cannot iterate over value'
|
|
344
|
+
end
|
|
345
|
+
options.each { |key, value| set(key, value) }
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Define setters and getters
|
|
349
|
+
#
|
|
350
|
+
# @api private
|
|
351
|
+
def define_accessors(option, value)
|
|
352
|
+
setter = proc { |val| set option, val, true }
|
|
353
|
+
getter = proc { value }
|
|
354
|
+
|
|
355
|
+
define_singleton_method("#{option}=", setter) if setter
|
|
356
|
+
define_singleton_method(option, getter) if getter
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Dynamically define a method for setting request option
|
|
360
|
+
#
|
|
361
|
+
# @api private
|
|
362
|
+
def define_singleton_method(method_name, content=Proc.new)
|
|
363
|
+
(class << self; self; end).class_eval do
|
|
364
|
+
undef_method(method_name) if method_defined?(method_name)
|
|
365
|
+
if String === content
|
|
366
|
+
class_eval("def #{method_name}() #{content}; end")
|
|
367
|
+
else
|
|
368
|
+
define_method(method_name, &content)
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end # API
|
|
373
|
+
end # Assembla
|