codenamev_bitbucket_api 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +43 -0
  3. data/README.md +169 -0
  4. data/Rakefile +3 -0
  5. data/lib/bitbucket_rest_api/api/actions.rb +50 -0
  6. data/lib/bitbucket_rest_api/api/arguments.rb +248 -0
  7. data/lib/bitbucket_rest_api/api/config/property.rb +30 -0
  8. data/lib/bitbucket_rest_api/api/config/property_set.rb +118 -0
  9. data/lib/bitbucket_rest_api/api/config.rb +107 -0
  10. data/lib/bitbucket_rest_api/api/factory.rb +29 -0
  11. data/lib/bitbucket_rest_api/api.rb +242 -0
  12. data/lib/bitbucket_rest_api/authorization.rb +34 -0
  13. data/lib/bitbucket_rest_api/client/invitations.rb +16 -0
  14. data/lib/bitbucket_rest_api/client/issues/comments.rb +109 -0
  15. data/lib/bitbucket_rest_api/client/issues/components.rb +103 -0
  16. data/lib/bitbucket_rest_api/client/issues/milestones.rb +103 -0
  17. data/lib/bitbucket_rest_api/client/issues.rb +214 -0
  18. data/lib/bitbucket_rest_api/client/repos/changesets.rb +55 -0
  19. data/lib/bitbucket_rest_api/client/repos/following.rb +40 -0
  20. data/lib/bitbucket_rest_api/client/repos/keys.rb +88 -0
  21. data/lib/bitbucket_rest_api/client/repos/pull_requests/comments.rb +42 -0
  22. data/lib/bitbucket_rest_api/client/repos/pull_requests/commits.rb +24 -0
  23. data/lib/bitbucket_rest_api/client/repos/pull_requests.rb +199 -0
  24. data/lib/bitbucket_rest_api/client/repos/services.rb +104 -0
  25. data/lib/bitbucket_rest_api/client/repos/sources.rb +32 -0
  26. data/lib/bitbucket_rest_api/client/repos.rb +224 -0
  27. data/lib/bitbucket_rest_api/client/user.rb +96 -0
  28. data/lib/bitbucket_rest_api/client/users/account.rb +54 -0
  29. data/lib/bitbucket_rest_api/client/users.rb +14 -0
  30. data/lib/bitbucket_rest_api/client.rb +54 -0
  31. data/lib/bitbucket_rest_api/compatibility.rb +23 -0
  32. data/lib/bitbucket_rest_api/configuration.rb +59 -0
  33. data/lib/bitbucket_rest_api/connection.rb +61 -0
  34. data/lib/bitbucket_rest_api/constants.rb +50 -0
  35. data/lib/bitbucket_rest_api/core_ext/array.rb +17 -0
  36. data/lib/bitbucket_rest_api/core_ext/hash.rb +56 -0
  37. data/lib/bitbucket_rest_api/core_ext/ordered_hash.rb +107 -0
  38. data/lib/bitbucket_rest_api/deprecation.rb +39 -0
  39. data/lib/bitbucket_rest_api/error/bad_request.rb +12 -0
  40. data/lib/bitbucket_rest_api/error/client_error.rb +20 -0
  41. data/lib/bitbucket_rest_api/error/forbidden.rb +12 -0
  42. data/lib/bitbucket_rest_api/error/internal_server_error.rb +12 -0
  43. data/lib/bitbucket_rest_api/error/invalid_options.rb +18 -0
  44. data/lib/bitbucket_rest_api/error/not_found.rb +12 -0
  45. data/lib/bitbucket_rest_api/error/required_params.rb +18 -0
  46. data/lib/bitbucket_rest_api/error/service_error.rb +19 -0
  47. data/lib/bitbucket_rest_api/error/service_unavailable.rb +12 -0
  48. data/lib/bitbucket_rest_api/error/unauthorized.rb +12 -0
  49. data/lib/bitbucket_rest_api/error/unknown_value.rb +18 -0
  50. data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +12 -0
  51. data/lib/bitbucket_rest_api/error/validations.rb +18 -0
  52. data/lib/bitbucket_rest_api/error.rb +35 -0
  53. data/lib/bitbucket_rest_api/ext/faraday.rb +38 -0
  54. data/lib/bitbucket_rest_api/middleware.rb +31 -0
  55. data/lib/bitbucket_rest_api/normalizer.rb +27 -0
  56. data/lib/bitbucket_rest_api/null_encoder.rb +25 -0
  57. data/lib/bitbucket_rest_api/page_iterator.rb +90 -0
  58. data/lib/bitbucket_rest_api/page_links.rb +33 -0
  59. data/lib/bitbucket_rest_api/paged_request.rb +29 -0
  60. data/lib/bitbucket_rest_api/pagination.rb +97 -0
  61. data/lib/bitbucket_rest_api/parameter_filter.rb +32 -0
  62. data/lib/bitbucket_rest_api/params_hash.rb +100 -0
  63. data/lib/bitbucket_rest_api/request/basic_auth.rb +33 -0
  64. data/lib/bitbucket_rest_api/request/jsonize.rb +51 -0
  65. data/lib/bitbucket_rest_api/request/oauth.rb +51 -0
  66. data/lib/bitbucket_rest_api/request/verbs.rb +53 -0
  67. data/lib/bitbucket_rest_api/request.rb +91 -0
  68. data/lib/bitbucket_rest_api/response/header.rb +68 -0
  69. data/lib/bitbucket_rest_api/response/helpers.rb +21 -0
  70. data/lib/bitbucket_rest_api/response/jsonize.rb +30 -0
  71. data/lib/bitbucket_rest_api/response/mashify.rb +24 -0
  72. data/lib/bitbucket_rest_api/response/raise_error.rb +31 -0
  73. data/lib/bitbucket_rest_api/response/xmlize.rb +26 -0
  74. data/lib/bitbucket_rest_api/response.rb +28 -0
  75. data/lib/bitbucket_rest_api/response_wrapper.rb +157 -0
  76. data/lib/bitbucket_rest_api/result.rb +68 -0
  77. data/lib/bitbucket_rest_api/users.rb +20 -0
  78. data/lib/bitbucket_rest_api/utils/url.rb +56 -0
  79. data/lib/bitbucket_rest_api/validations/format.rb +24 -0
  80. data/lib/bitbucket_rest_api/validations/presence.rb +30 -0
  81. data/lib/bitbucket_rest_api/validations/required.rb +24 -0
  82. data/lib/bitbucket_rest_api/validations/token.rb +43 -0
  83. data/lib/bitbucket_rest_api/validations.rb +25 -0
  84. data/lib/bitbucket_rest_api/version.rb +11 -0
  85. data/lib/bitbucket_rest_api.rb +136 -0
  86. metadata +238 -0
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 401
5
+ module Error
6
+ class Unauthorized < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ end # BitBucket
@@ -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,12 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket #:nodoc
4
+ # Raised when BitBucket returns the HTTP status code 422
5
+ module Error
6
+ class UnprocessableEntity < BitBucketError
7
+ def initialize(env)
8
+ super(env)
9
+ end
10
+ end
11
+ end # Error
12
+ 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