codenamev_bitbucket_api 0.4.0
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 +43 -0
- data/README.md +169 -0
- data/Rakefile +3 -0
- data/lib/bitbucket_rest_api/api/actions.rb +50 -0
- data/lib/bitbucket_rest_api/api/arguments.rb +248 -0
- data/lib/bitbucket_rest_api/api/config/property.rb +30 -0
- data/lib/bitbucket_rest_api/api/config/property_set.rb +118 -0
- data/lib/bitbucket_rest_api/api/config.rb +107 -0
- data/lib/bitbucket_rest_api/api/factory.rb +29 -0
- data/lib/bitbucket_rest_api/api.rb +242 -0
- data/lib/bitbucket_rest_api/authorization.rb +34 -0
- data/lib/bitbucket_rest_api/client/invitations.rb +16 -0
- data/lib/bitbucket_rest_api/client/issues/comments.rb +109 -0
- data/lib/bitbucket_rest_api/client/issues/components.rb +103 -0
- data/lib/bitbucket_rest_api/client/issues/milestones.rb +103 -0
- data/lib/bitbucket_rest_api/client/issues.rb +214 -0
- data/lib/bitbucket_rest_api/client/repos/changesets.rb +55 -0
- data/lib/bitbucket_rest_api/client/repos/following.rb +40 -0
- data/lib/bitbucket_rest_api/client/repos/keys.rb +88 -0
- data/lib/bitbucket_rest_api/client/repos/pull_requests/comments.rb +42 -0
- data/lib/bitbucket_rest_api/client/repos/pull_requests/commits.rb +24 -0
- data/lib/bitbucket_rest_api/client/repos/pull_requests.rb +199 -0
- data/lib/bitbucket_rest_api/client/repos/services.rb +104 -0
- data/lib/bitbucket_rest_api/client/repos/sources.rb +32 -0
- data/lib/bitbucket_rest_api/client/repos.rb +224 -0
- data/lib/bitbucket_rest_api/client/user.rb +96 -0
- data/lib/bitbucket_rest_api/client/users/account.rb +54 -0
- data/lib/bitbucket_rest_api/client/users.rb +14 -0
- data/lib/bitbucket_rest_api/client.rb +54 -0
- data/lib/bitbucket_rest_api/compatibility.rb +23 -0
- data/lib/bitbucket_rest_api/configuration.rb +59 -0
- data/lib/bitbucket_rest_api/connection.rb +61 -0
- data/lib/bitbucket_rest_api/constants.rb +50 -0
- data/lib/bitbucket_rest_api/core_ext/array.rb +17 -0
- data/lib/bitbucket_rest_api/core_ext/hash.rb +56 -0
- data/lib/bitbucket_rest_api/core_ext/ordered_hash.rb +107 -0
- data/lib/bitbucket_rest_api/deprecation.rb +39 -0
- data/lib/bitbucket_rest_api/error/bad_request.rb +12 -0
- data/lib/bitbucket_rest_api/error/client_error.rb +20 -0
- data/lib/bitbucket_rest_api/error/forbidden.rb +12 -0
- data/lib/bitbucket_rest_api/error/internal_server_error.rb +12 -0
- data/lib/bitbucket_rest_api/error/invalid_options.rb +18 -0
- data/lib/bitbucket_rest_api/error/not_found.rb +12 -0
- data/lib/bitbucket_rest_api/error/required_params.rb +18 -0
- data/lib/bitbucket_rest_api/error/service_error.rb +19 -0
- data/lib/bitbucket_rest_api/error/service_unavailable.rb +12 -0
- data/lib/bitbucket_rest_api/error/unauthorized.rb +12 -0
- data/lib/bitbucket_rest_api/error/unknown_value.rb +18 -0
- data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +12 -0
- data/lib/bitbucket_rest_api/error/validations.rb +18 -0
- data/lib/bitbucket_rest_api/error.rb +35 -0
- data/lib/bitbucket_rest_api/ext/faraday.rb +38 -0
- data/lib/bitbucket_rest_api/middleware.rb +31 -0
- data/lib/bitbucket_rest_api/normalizer.rb +27 -0
- data/lib/bitbucket_rest_api/null_encoder.rb +25 -0
- data/lib/bitbucket_rest_api/page_iterator.rb +90 -0
- data/lib/bitbucket_rest_api/page_links.rb +33 -0
- data/lib/bitbucket_rest_api/paged_request.rb +29 -0
- data/lib/bitbucket_rest_api/pagination.rb +97 -0
- data/lib/bitbucket_rest_api/parameter_filter.rb +32 -0
- data/lib/bitbucket_rest_api/params_hash.rb +100 -0
- data/lib/bitbucket_rest_api/request/basic_auth.rb +33 -0
- data/lib/bitbucket_rest_api/request/jsonize.rb +51 -0
- data/lib/bitbucket_rest_api/request/oauth.rb +51 -0
- data/lib/bitbucket_rest_api/request/verbs.rb +53 -0
- data/lib/bitbucket_rest_api/request.rb +91 -0
- data/lib/bitbucket_rest_api/response/header.rb +68 -0
- data/lib/bitbucket_rest_api/response/helpers.rb +21 -0
- data/lib/bitbucket_rest_api/response/jsonize.rb +30 -0
- data/lib/bitbucket_rest_api/response/mashify.rb +24 -0
- data/lib/bitbucket_rest_api/response/raise_error.rb +31 -0
- data/lib/bitbucket_rest_api/response/xmlize.rb +26 -0
- data/lib/bitbucket_rest_api/response.rb +28 -0
- data/lib/bitbucket_rest_api/response_wrapper.rb +157 -0
- data/lib/bitbucket_rest_api/result.rb +68 -0
- data/lib/bitbucket_rest_api/users.rb +20 -0
- data/lib/bitbucket_rest_api/utils/url.rb +56 -0
- data/lib/bitbucket_rest_api/validations/format.rb +24 -0
- data/lib/bitbucket_rest_api/validations/presence.rb +30 -0
- data/lib/bitbucket_rest_api/validations/required.rb +24 -0
- data/lib/bitbucket_rest_api/validations/token.rb +43 -0
- data/lib/bitbucket_rest_api/validations.rb +25 -0
- data/lib/bitbucket_rest_api/version.rb +11 -0
- data/lib/bitbucket_rest_api.rb +136 -0
- metadata +238 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module BitBucket #:nodoc
|
|
4
|
+
# Raised when invalid options are passed to a request body
|
|
5
|
+
module Error
|
|
6
|
+
class UnknownValue < ClientError
|
|
7
|
+
def initialize(key, value, permitted)
|
|
8
|
+
super(
|
|
9
|
+
generate_message(
|
|
10
|
+
:problem => "Wrong value of '#{value}' for the parameter: #{key} provided for this request.",
|
|
11
|
+
:summary => "BitBucket gem checks the request parameters passed to ensure that bitbucket api is not hit unnecessairly and fails fast.",
|
|
12
|
+
:resolution => "Permitted values are: #{permitted}, make sure these are the ones you are using"
|
|
13
|
+
)
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end # Error
|
|
18
|
+
end # BitBucket
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module BitBucket #:nodoc
|
|
4
|
+
# Raised when passed parameters are missing or contain wrong values.
|
|
5
|
+
module Error
|
|
6
|
+
class Validations < ClientError
|
|
7
|
+
def initialize(errors)
|
|
8
|
+
super(
|
|
9
|
+
generate_message(
|
|
10
|
+
:problem => '',
|
|
11
|
+
:summary => '',
|
|
12
|
+
:resolution => ''
|
|
13
|
+
)
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end # Error
|
|
18
|
+
end # BitBucket
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module BitBucket
|
|
4
|
+
module Error
|
|
5
|
+
class BitBucketError < StandardError
|
|
6
|
+
attr_reader :response_message, :response_headers
|
|
7
|
+
|
|
8
|
+
def initialize(message)
|
|
9
|
+
super message
|
|
10
|
+
@response_message = message
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# def inspect
|
|
14
|
+
# %(#<#{self.class}>)
|
|
15
|
+
# end
|
|
16
|
+
end
|
|
17
|
+
end # Error
|
|
18
|
+
end # BitBucket
|
|
19
|
+
|
|
20
|
+
%w[
|
|
21
|
+
service_error
|
|
22
|
+
not_found
|
|
23
|
+
forbidden
|
|
24
|
+
bad_request
|
|
25
|
+
unauthorized
|
|
26
|
+
service_unavailable
|
|
27
|
+
internal_server_error
|
|
28
|
+
unprocessable_entity
|
|
29
|
+
client_error
|
|
30
|
+
invalid_options
|
|
31
|
+
required_params
|
|
32
|
+
unknown_value
|
|
33
|
+
].each do |error|
|
|
34
|
+
require "bitbucket_rest_api/error/#{error}"
|
|
35
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Faraday
|
|
4
|
+
module Utils
|
|
5
|
+
|
|
6
|
+
class ParamsHash
|
|
7
|
+
def params_encoder(encoder = nil)
|
|
8
|
+
if encoder
|
|
9
|
+
@encoder = encoder
|
|
10
|
+
else
|
|
11
|
+
@encoder
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_query(encoder = nil)
|
|
16
|
+
Utils.build_nested_query(self, nil, params_encoder)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def build_nested_query(value, prefix = nil, encoder = nil)
|
|
21
|
+
case value
|
|
22
|
+
when Array
|
|
23
|
+
value.map { |v| build_nested_query(v, "#{prefix}%5B%5D", encoder) }.join("&")
|
|
24
|
+
when Hash
|
|
25
|
+
value.map { |k, v|
|
|
26
|
+
processed_value = encoder ? encoder.escape(k) : escape(k)
|
|
27
|
+
build_nested_query(v, prefix ? "#{prefix}%5B#{processed_value}%5D" : processed_value, encoder)
|
|
28
|
+
}.join("&")
|
|
29
|
+
when NilClass
|
|
30
|
+
prefix
|
|
31
|
+
else
|
|
32
|
+
raise ArgumentError, "value must be a Hash" if prefix.nil?
|
|
33
|
+
processed_value = encoder ? encoder.escape(value) : escape(value)
|
|
34
|
+
"#{prefix}=#{processed_value}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'bitbucket_rest_api/response'
|
|
4
|
+
require 'bitbucket_rest_api/response/mashify'
|
|
5
|
+
require 'bitbucket_rest_api/response/jsonize'
|
|
6
|
+
require 'bitbucket_rest_api/response/raise_error'
|
|
7
|
+
require 'bitbucket_rest_api/response/header'
|
|
8
|
+
|
|
9
|
+
module BitBucket
|
|
10
|
+
class Middleware
|
|
11
|
+
def self.default(options = {})
|
|
12
|
+
api = options[:api]
|
|
13
|
+
proc do |builder|
|
|
14
|
+
builder.use BitBucket::Request::Jsonize
|
|
15
|
+
builder.use Faraday::Request::UrlEncoded
|
|
16
|
+
builder.use Faraday::Request::Multipart
|
|
17
|
+
builder.use BitBucket::Request::OAuth, {:consumer_key => api.client_id, :consumer_secret => api.client_secret, :token => api.oauth_token, :token_secret => api.oauth_secret} if api.client_id? and api.client_secret?
|
|
18
|
+
builder.use BitBucket::Request::BasicAuth, api.authentication if api.basic_authed?
|
|
19
|
+
|
|
20
|
+
builder.use Faraday::Response::Logger if ENV['DEBUG']
|
|
21
|
+
#builder.use BitBucket::Response::Helpers
|
|
22
|
+
unless options[:raw]
|
|
23
|
+
builder.use BitBucket::Response::Mashify
|
|
24
|
+
builder.use BitBucket::Response::Jsonize
|
|
25
|
+
end
|
|
26
|
+
builder.use BitBucket::Response::RaiseError
|
|
27
|
+
builder.adapter options[:adapter]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end # Middleware
|
|
31
|
+
end # BitBucket
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module BitBucket
|
|
4
|
+
# Deals with normalizing client supplied parameter keys.
|
|
5
|
+
module Normalizer
|
|
6
|
+
|
|
7
|
+
# Turns any keys from nested hashes including nested arrays into strings
|
|
8
|
+
#
|
|
9
|
+
def normalize!(params)
|
|
10
|
+
case params
|
|
11
|
+
when Hash
|
|
12
|
+
params.keys.each do |k|
|
|
13
|
+
params[k.to_s] = params.delete(k)
|
|
14
|
+
normalize!(params[k.to_s])
|
|
15
|
+
end
|
|
16
|
+
when Array
|
|
17
|
+
params.map! do |el|
|
|
18
|
+
normalize!(el)
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
params.to_s
|
|
22
|
+
end
|
|
23
|
+
return params
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end # Normalizer
|
|
27
|
+
end # BitBucket
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
|
|
5
|
+
module BitBucket
|
|
6
|
+
|
|
7
|
+
# Skip encoding of the key nested parameters
|
|
8
|
+
module NullParamsEncoder
|
|
9
|
+
if defined?(Faraday::NestedParamsEncoder)
|
|
10
|
+
class << self
|
|
11
|
+
Faraday::NestedParamsEncoder.singleton_methods do |m|
|
|
12
|
+
define_method m, ::Faraday::NestedParamsEncoder.method(m).to_proc
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.escape(s)
|
|
18
|
+
s.to_s
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.unescape(s)
|
|
22
|
+
s.to_s
|
|
23
|
+
end
|
|
24
|
+
end # NullEncoder
|
|
25
|
+
end # BitBucket
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'bitbucket_rest_api/utils/url'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
6
|
+
module BitBucket
|
|
7
|
+
class PageIterator
|
|
8
|
+
include BitBucket::Constants
|
|
9
|
+
include BitBucket::Utils::Url
|
|
10
|
+
include BitBucket::PagedRequest
|
|
11
|
+
|
|
12
|
+
# Setup attribute accesor for all the link types
|
|
13
|
+
ATTRIBUTES = [ META_FIRST, META_NEXT, META_PREV ]
|
|
14
|
+
|
|
15
|
+
ATTRIBUTES.each do |attr|
|
|
16
|
+
attr_accessor :"#{attr}_page_uri", :"#{attr}_page"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_reader :current_api
|
|
20
|
+
|
|
21
|
+
def initialize(links, current_api)
|
|
22
|
+
@links = links
|
|
23
|
+
@current_api = current_api
|
|
24
|
+
update_page_links @links
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def has_next?
|
|
28
|
+
next_page == 0 || !next_page_uri.nil?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Perform http get request for the first resource
|
|
32
|
+
#
|
|
33
|
+
def first
|
|
34
|
+
return nil unless first_page_uri
|
|
35
|
+
perform_request(first_page_uri)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Perform http get request for the next resource
|
|
39
|
+
#
|
|
40
|
+
def next
|
|
41
|
+
return nil unless has_next?
|
|
42
|
+
perform_request(next_page_uri)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Perform http get request for the previous resource
|
|
46
|
+
#
|
|
47
|
+
def prev
|
|
48
|
+
return nil unless prev_page_uri
|
|
49
|
+
perform_request(prev_page_uri)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns the result for a specific page.
|
|
53
|
+
#
|
|
54
|
+
def get_page(page_number)
|
|
55
|
+
# Find URI that we can work with, if we cannot get the first
|
|
56
|
+
# page URI then there is only one page.
|
|
57
|
+
return nil unless first_page_uri
|
|
58
|
+
params = parse_query URI(first_page_uri).query
|
|
59
|
+
params['page'] = page_number
|
|
60
|
+
|
|
61
|
+
response = page_request URI(first_page_uri).path, params
|
|
62
|
+
update_page_links response.links
|
|
63
|
+
response
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def perform_request(attribute)
|
|
69
|
+
page_uri = URI(attribute)
|
|
70
|
+
params = parse_query(page_uri.query)
|
|
71
|
+
|
|
72
|
+
if next_page and next_page >= 1
|
|
73
|
+
params['page'] = attribute.to_i
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
response = page_request(page_uri.path, params)
|
|
77
|
+
update_page_links response.links
|
|
78
|
+
response
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Wholesale update of all link attributes
|
|
82
|
+
def update_page_links(links) # :nodoc:
|
|
83
|
+
ATTRIBUTES.each do |attr|
|
|
84
|
+
self.send(:"#{attr}_page_uri=", links.send(:"#{attr}"))
|
|
85
|
+
self.send(:"#{attr}_page=", links.send(:"#{attr}"))
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end # PageIterator
|
|
90
|
+
end # BitBucket
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module BitBucket
|
|
2
|
+
# Determines the links in the current response to be used
|
|
3
|
+
# to find the links to other pages of request responses.
|
|
4
|
+
class PageLinks
|
|
5
|
+
include BitBucket::Constants
|
|
6
|
+
|
|
7
|
+
FIRST_PAGE_NUMBER = 1 # :nodoc:
|
|
8
|
+
|
|
9
|
+
# Hold the extracted values for URI from the response body
|
|
10
|
+
# for the next and previous page.
|
|
11
|
+
attr_accessor :response_dup, :first, :next, :prev
|
|
12
|
+
|
|
13
|
+
# Parses links from executed request
|
|
14
|
+
#
|
|
15
|
+
def initialize(response)
|
|
16
|
+
self.response_dup = response
|
|
17
|
+
if response.body.is_a?(Hash) and !response.body[PARAM_PAGE].nil?
|
|
18
|
+
self.first = path_for_page(FIRST_PAGE_NUMBER)
|
|
19
|
+
self.next = response.body[META_NEXT] unless response.body
|
|
20
|
+
self.prev = response.body[META_PREV]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def path_for_page(page_number)
|
|
27
|
+
if response_dup.respond_to?(:url)
|
|
28
|
+
self.response_dup.url.to_s.gsub(BitBucket.endpoint, '')
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end # PageLinks
|
|
33
|
+
end # BitBucket
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module BitBucket
|
|
4
|
+
|
|
5
|
+
# A module that adds http get request to response pagination
|
|
6
|
+
module PagedRequest
|
|
7
|
+
include BitBucket::Constants
|
|
8
|
+
include BitBucket::Normalizer
|
|
9
|
+
|
|
10
|
+
FIRST_PAGE = 1 # Default request page if none provided
|
|
11
|
+
|
|
12
|
+
NOT_FOUND = -1 # Page parameter not present
|
|
13
|
+
|
|
14
|
+
def default_page
|
|
15
|
+
current_api.current_page ? current_api.current_page : FIRST_PAGE
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Perform http get request with pagination parameters
|
|
19
|
+
#
|
|
20
|
+
def page_request(path, params={})
|
|
21
|
+
if params[PARAM_PAGE] && params[PARAM_PAGE] == NOT_FOUND
|
|
22
|
+
params[PARAM_PAGE] = default_page
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
current_api.get_request(path, ParamsHash.new(params))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end # PagedRequest
|
|
29
|
+
end # BitBucket
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module BitBucket
|
|
3
|
+
|
|
4
|
+
# A module that decorates response with pagination helpers
|
|
5
|
+
module Pagination
|
|
6
|
+
include BitBucket::Constants
|
|
7
|
+
|
|
8
|
+
def paginated?
|
|
9
|
+
body.is_a?(Hash) and !body[PARAM_PAGE].nil?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Return page links
|
|
13
|
+
def links
|
|
14
|
+
@links = BitBucket::PageLinks.new(self.response)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Iterate over results set pages by automatically calling `next_page`
|
|
18
|
+
# until all pages are exhausted. Caution needs to be exercised when
|
|
19
|
+
# using this feature - 100 pages iteration will perform 100 API calls.
|
|
20
|
+
# By default this is off. You can set it on the client, individual API
|
|
21
|
+
# instances or just per given request.
|
|
22
|
+
#
|
|
23
|
+
def auto_paginate(auto=false)
|
|
24
|
+
if paginated? and (current_api.auto_pagination? || auto)
|
|
25
|
+
resources_bodies = []
|
|
26
|
+
each_page do |resource|
|
|
27
|
+
if resource.body.respond_to?(:values) and resource.body[:values]
|
|
28
|
+
resources_bodies += resource.body[:values].collect {|value| ::Hashie::Mash.new(value) }
|
|
29
|
+
else
|
|
30
|
+
resources_bodies += Array(resource.body)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
self.body = resources_bodies
|
|
34
|
+
end
|
|
35
|
+
self
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Iterator like each for response pages. If there are no pages to
|
|
39
|
+
# iterate over this method will return current page.
|
|
40
|
+
def each_page
|
|
41
|
+
yield self
|
|
42
|
+
while page_iterator.has_next?
|
|
43
|
+
yield next_page
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Retrives the result of the first page. Returns <tt>nil</tt> if there is
|
|
48
|
+
# no first page - either because you are already on the first page
|
|
49
|
+
# or there are no pages at all in the result.
|
|
50
|
+
def first_page
|
|
51
|
+
first_request = page_iterator.first
|
|
52
|
+
self.instance_eval { @env = first_request.env } if first_request
|
|
53
|
+
first_request
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Retrives the result of the next page. Returns <tt>nil</tt> if there is
|
|
57
|
+
# no next page or no pages at all.
|
|
58
|
+
def next_page
|
|
59
|
+
next_request = page_iterator.next
|
|
60
|
+
self.instance_eval { @env = next_request.env } if next_request
|
|
61
|
+
next_request
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Retrives the result of the previous page. Returns <tt>nil</tt> if there is
|
|
65
|
+
# no previous page or no pages at all.
|
|
66
|
+
def prev_page
|
|
67
|
+
prev_request = page_iterator.prev
|
|
68
|
+
self.instance_eval { @env = prev_request.env } if prev_request
|
|
69
|
+
prev_request
|
|
70
|
+
end
|
|
71
|
+
alias :previous_page :prev_page
|
|
72
|
+
|
|
73
|
+
# Retrives a specific result for a page given page number.
|
|
74
|
+
# The <tt>page_number</tt> parameter is not validate, hitting a page
|
|
75
|
+
# that does not exist will return BitBucket API error. Consequently, if
|
|
76
|
+
# there is only one page, this method returns nil
|
|
77
|
+
def page(page_number)
|
|
78
|
+
request = page_iterator.get_page(page_number)
|
|
79
|
+
self.instance_eval { @env = request.env } if request
|
|
80
|
+
request
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns <tt>true</tt> if there is another page in the result set,
|
|
84
|
+
# otherwise <tt>false</tt>
|
|
85
|
+
def has_next_page?
|
|
86
|
+
page_iterator.has_next?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
# Internally used page iterator
|
|
92
|
+
def page_iterator # :nodoc:
|
|
93
|
+
@page_iterator = BitBucket::PageIterator.new(links, current_api)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end # Pagination
|
|
97
|
+
end # BitBucket
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module BitBucket
|
|
4
|
+
# Allows you to specify parameters keys which will be preserved
|
|
5
|
+
# in parameters hash and its subhashes. Any keys from the nested
|
|
6
|
+
# hash that do not match will be removed.
|
|
7
|
+
module ParameterFilter
|
|
8
|
+
|
|
9
|
+
# Removes any keys from nested hashes that don't match predefiend keys
|
|
10
|
+
#
|
|
11
|
+
def filter!(keys, params, options={:recursive => true}) # :nodoc:
|
|
12
|
+
case params
|
|
13
|
+
when Hash, ParamsHash
|
|
14
|
+
params.keys.each do |k, v|
|
|
15
|
+
unless (keys.include?(k) or BitBucket::Validations::VALID_API_KEYS.include?(k))
|
|
16
|
+
params.delete(k)
|
|
17
|
+
else
|
|
18
|
+
filter!(keys, params[k]) if options[:recursive]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
when Array
|
|
22
|
+
params.map! do |el|
|
|
23
|
+
filter!(keys, el) if options[:recursive]
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
params
|
|
27
|
+
end
|
|
28
|
+
return params
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end # Filter
|
|
32
|
+
end # BitBucket
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'delegate'
|
|
4
|
+
require 'base64'
|
|
5
|
+
|
|
6
|
+
module BitBucket
|
|
7
|
+
|
|
8
|
+
# Class responsible for holding request parameters
|
|
9
|
+
class ParamsHash < DelegateClass(Hash)
|
|
10
|
+
include Normalizer
|
|
11
|
+
|
|
12
|
+
def initialize(hash)
|
|
13
|
+
super(normalize!(Hash[hash]))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Create empty hash
|
|
17
|
+
#
|
|
18
|
+
def self.empty
|
|
19
|
+
new({})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Extract and parse media type param
|
|
23
|
+
#
|
|
24
|
+
# [.version].param[+json]
|
|
25
|
+
#
|
|
26
|
+
def media
|
|
27
|
+
parse(delete('media'))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Return accept header if present
|
|
31
|
+
#
|
|
32
|
+
def accept
|
|
33
|
+
if has_key?('accept')
|
|
34
|
+
delete('accept')
|
|
35
|
+
elsif has_key?('media')
|
|
36
|
+
media
|
|
37
|
+
else
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Extract request data from parameters
|
|
43
|
+
#
|
|
44
|
+
def data
|
|
45
|
+
if has_key?('data') && !self['data'].nil?
|
|
46
|
+
return delete('data')
|
|
47
|
+
else
|
|
48
|
+
return to_hash
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def encoder
|
|
53
|
+
if has_key?('encoder') && self['encoder']
|
|
54
|
+
return delete('encoder')
|
|
55
|
+
else
|
|
56
|
+
return {}
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Any client configuration options
|
|
61
|
+
#
|
|
62
|
+
def options
|
|
63
|
+
opts = has_key?('options') ? delete('options') : {}
|
|
64
|
+
headers = opts.fetch(:headers) { {} }
|
|
65
|
+
if value = accept
|
|
66
|
+
headers[:accept] = value
|
|
67
|
+
end
|
|
68
|
+
if value = delete('content_type')
|
|
69
|
+
headers[:content_type] = value
|
|
70
|
+
end
|
|
71
|
+
opts[:raw] = has_key?('raw') ? delete('raw') : false
|
|
72
|
+
opts[:headers] = headers unless headers.empty?
|
|
73
|
+
opts
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Update hash with default parameters for non existing keys
|
|
77
|
+
#
|
|
78
|
+
def merge_default(defaults)
|
|
79
|
+
if defaults && !defaults.empty?
|
|
80
|
+
defaults.each do |key, value|
|
|
81
|
+
self[key] = value unless self.has_key?(key)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Base64 encode string removing newline characters
|
|
88
|
+
#
|
|
89
|
+
def strict_encode64(key)
|
|
90
|
+
value = self[key]
|
|
91
|
+
encoded = if Base64.respond_to?(:strict_encode64)
|
|
92
|
+
Base64.strict_encode64(value)
|
|
93
|
+
else
|
|
94
|
+
[value].pack("m0")
|
|
95
|
+
end
|
|
96
|
+
self[key] = encoded.delete("\n\r")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end # ParamsHash
|
|
100
|
+
end # BitBucket
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'base64'
|
|
5
|
+
|
|
6
|
+
module BitBucket
|
|
7
|
+
class Request
|
|
8
|
+
class BasicAuth < Faraday::Middleware
|
|
9
|
+
dependency 'base64'
|
|
10
|
+
|
|
11
|
+
def call(env)
|
|
12
|
+
unless @auth.to_s.empty?
|
|
13
|
+
env[:request_headers].merge!('Authorization' => "Basic #{@auth}\"")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@app.call env
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(app, *args)
|
|
20
|
+
@app = app
|
|
21
|
+
credentials = ""
|
|
22
|
+
options = args.extract_options!
|
|
23
|
+
if options.has_key? :login
|
|
24
|
+
credentials = "#{options[:login]}:#{options[:password]}"
|
|
25
|
+
elsif options.has_key? :basic_auth
|
|
26
|
+
credentials = "#{options[:basic_auth]}"
|
|
27
|
+
end
|
|
28
|
+
@auth = Base64.encode64(credentials)
|
|
29
|
+
@auth.gsub!("\n", "")
|
|
30
|
+
end
|
|
31
|
+
end # BasicAuth
|
|
32
|
+
end # Request
|
|
33
|
+
end # BitBucket
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
|
|
5
|
+
module BitBucket
|
|
6
|
+
class Request::Jsonize < Faraday::Middleware
|
|
7
|
+
|
|
8
|
+
CONTENT_TYPE = 'Content-Type'.freeze
|
|
9
|
+
MIME_TYPE = 'application/json'.freeze
|
|
10
|
+
|
|
11
|
+
dependency 'multi_json'
|
|
12
|
+
|
|
13
|
+
def call(env)
|
|
14
|
+
if request_with_body?(env)
|
|
15
|
+
env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
|
|
16
|
+
env[:body] = encode_body env unless env[:body].respond_to?(:to_str)
|
|
17
|
+
else
|
|
18
|
+
# Ensure valid body for put and post requests
|
|
19
|
+
if [:put, :patch, :post].include? env[:method]
|
|
20
|
+
env[:body] = encode_body({})
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
@app.call env
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def encode_body(env)
|
|
27
|
+
if MultiJson.respond_to?(:dump)
|
|
28
|
+
MultiJson.dump env[:body]
|
|
29
|
+
else
|
|
30
|
+
MultiJson.encode env[:body]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def request_with_body?(env)
|
|
35
|
+
type = request_type(env)
|
|
36
|
+
has_body?(env) and (type.empty? or type == MIME_TYPE)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Don't encode bodies in string form
|
|
40
|
+
def has_body?(env)
|
|
41
|
+
body = env[:body] and !(body.respond_to?(:to_str) and body.empty?)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def request_type(env)
|
|
45
|
+
type = env[:request_headers][CONTENT_TYPE].to_s
|
|
46
|
+
type = type.split(';', 2).first if type.index(';')
|
|
47
|
+
type
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end # Request::Jsonize
|
|
51
|
+
end # BitBucket
|