assembla_api 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/Rakefile +22 -0
  4. data/lib/assembla_api.rb +130 -0
  5. data/lib/assembla_api/api.rb +373 -0
  6. data/lib/assembla_api/api/actions.rb +58 -0
  7. data/lib/assembla_api/api/arguments.rb +248 -0
  8. data/lib/assembla_api/api/config.rb +107 -0
  9. data/lib/assembla_api/api/config/property.rb +30 -0
  10. data/lib/assembla_api/api/config/property_set.rb +119 -0
  11. data/lib/assembla_api/api/factory.rb +33 -0
  12. data/lib/assembla_api/authorization.rb +76 -0
  13. data/lib/assembla_api/client.rb +21 -0
  14. data/lib/assembla_api/client/activity.rb +30 -0
  15. data/lib/assembla_api/client/authorizations.rb +143 -0
  16. data/lib/assembla_api/client/authorizations/app.rb +98 -0
  17. data/lib/assembla_api/client/portfolio.rb +19 -0
  18. data/lib/assembla_api/client/portfolio/invitations.rb +30 -0
  19. data/lib/assembla_api/client/portfolio/spaces.rb +13 -0
  20. data/lib/assembla_api/client/portfolio/standup_reports.rb +34 -0
  21. data/lib/assembla_api/client/portfolio/tasks.rb +13 -0
  22. data/lib/assembla_api/client/portfolio/ticket_reports.rb +13 -0
  23. data/lib/assembla_api/client/portfolio/tickets.rb +13 -0
  24. data/lib/assembla_api/client/portfolio/users.rb +13 -0
  25. data/lib/assembla_api/client/spaces.rb +140 -0
  26. data/lib/assembla_api/client/spaces/documents.rb +87 -0
  27. data/lib/assembla_api/client/spaces/milestones.rb +102 -0
  28. data/lib/assembla_api/client/spaces/space_tools.rb +65 -0
  29. data/lib/assembla_api/client/spaces/space_tools/merge_requests.rb +105 -0
  30. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions.rb +41 -0
  31. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/comments.rb +34 -0
  32. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/votes.rb +46 -0
  33. data/lib/assembla_api/client/spaces/ssh.rb +14 -0
  34. data/lib/assembla_api/client/spaces/ssh/actions.rb +76 -0
  35. data/lib/assembla_api/client/spaces/ssh/actions/launches.rb +14 -0
  36. data/lib/assembla_api/client/spaces/ssh/keys.rb +18 -0
  37. data/lib/assembla_api/client/spaces/ssh/launches.rb +29 -0
  38. data/lib/assembla_api/client/spaces/ssh/servers.rb +63 -0
  39. data/lib/assembla_api/client/spaces/standup_away_reports.rb +41 -0
  40. data/lib/assembla_api/client/spaces/standup_reports.rb +41 -0
  41. data/lib/assembla_api/client/spaces/tags.rb +96 -0
  42. data/lib/assembla_api/client/spaces/tickets.rb +154 -0
  43. data/lib/assembla_api/client/spaces/tickets/associations.rb +57 -0
  44. data/lib/assembla_api/client/spaces/tickets/comments.rb +45 -0
  45. data/lib/assembla_api/client/spaces/tickets/custom_fields.rb +57 -0
  46. data/lib/assembla_api/client/spaces/tickets/statuses.rb +55 -0
  47. data/lib/assembla_api/client/spaces/user_roles.rb +61 -0
  48. data/lib/assembla_api/client/spaces/users.rb +11 -0
  49. data/lib/assembla_api/client/spaces/webhooks.rb +63 -0
  50. data/lib/assembla_api/client/spaces/wiki_pages.rb +78 -0
  51. data/lib/assembla_api/client/spaces/wiki_pages/versions.rb +20 -0
  52. data/lib/assembla_api/client/tasks.rb +72 -0
  53. data/lib/assembla_api/client/users.rb +49 -0
  54. data/lib/assembla_api/client/users/keys.rb +97 -0
  55. data/lib/assembla_api/configuration.rb +71 -0
  56. data/lib/assembla_api/connection.rb +66 -0
  57. data/lib/assembla_api/constants.rb +74 -0
  58. data/lib/assembla_api/core_ext/array.rb +25 -0
  59. data/lib/assembla_api/core_ext/hash.rb +92 -0
  60. data/lib/assembla_api/core_ext/ordered_hash.rb +107 -0
  61. data/lib/assembla_api/deprecation.rb +39 -0
  62. data/lib/assembla_api/error.rb +37 -0
  63. data/lib/assembla_api/error/bad_request.rb +14 -0
  64. data/lib/assembla_api/error/client_error.rb +20 -0
  65. data/lib/assembla_api/error/forbidden.rb +14 -0
  66. data/lib/assembla_api/error/internal_server_error.rb +15 -0
  67. data/lib/assembla_api/error/invalid_options.rb +18 -0
  68. data/lib/assembla_api/error/not_acceptable.rb +15 -0
  69. data/lib/assembla_api/error/not_found.rb +14 -0
  70. data/lib/assembla_api/error/required_params.rb +18 -0
  71. data/lib/assembla_api/error/service_error.rb +68 -0
  72. data/lib/assembla_api/error/service_unavailable.rb +15 -0
  73. data/lib/assembla_api/error/unauthorized.rb +15 -0
  74. data/lib/assembla_api/error/unknown_media.rb +18 -0
  75. data/lib/assembla_api/error/unknown_value.rb +18 -0
  76. data/lib/assembla_api/error/unprocessable_entity.rb +14 -0
  77. data/lib/assembla_api/error/validations.rb +18 -0
  78. data/lib/assembla_api/ext/faraday.rb +38 -0
  79. data/lib/assembla_api/jsonable.rb +18 -0
  80. data/lib/assembla_api/middleware.rb +31 -0
  81. data/lib/assembla_api/mime_type.rb +33 -0
  82. data/lib/assembla_api/normalizer.rb +25 -0
  83. data/lib/assembla_api/null_encoder.rb +25 -0
  84. data/lib/assembla_api/page_iterator.rb +142 -0
  85. data/lib/assembla_api/page_links.rb +45 -0
  86. data/lib/assembla_api/paged_request.rb +40 -0
  87. data/lib/assembla_api/pagination.rb +102 -0
  88. data/lib/assembla_api/parameter_filter.rb +32 -0
  89. data/lib/assembla_api/params_hash.rb +101 -0
  90. data/lib/assembla_api/rate_limit.rb +25 -0
  91. data/lib/assembla_api/request.rb +85 -0
  92. data/lib/assembla_api/request/basic_auth.rb +33 -0
  93. data/lib/assembla_api/request/jsonize.rb +53 -0
  94. data/lib/assembla_api/request/key_auth.rb +31 -0
  95. data/lib/assembla_api/request/oauth2.rb +42 -0
  96. data/lib/assembla_api/request/verbs.rb +60 -0
  97. data/lib/assembla_api/response.rb +28 -0
  98. data/lib/assembla_api/response/header.rb +76 -0
  99. data/lib/assembla_api/response/jsonize.rb +29 -0
  100. data/lib/assembla_api/response/mashify.rb +24 -0
  101. data/lib/assembla_api/response/raise_error.rb +18 -0
  102. data/lib/assembla_api/response/xmlize.rb +26 -0
  103. data/lib/assembla_api/response_wrapper.rb +157 -0
  104. data/lib/assembla_api/ssl_certs/cacerts.pem +2183 -0
  105. data/lib/assembla_api/utils/url.rb +59 -0
  106. data/lib/assembla_api/validations.rb +25 -0
  107. data/lib/assembla_api/validations/format.rb +24 -0
  108. data/lib/assembla_api/validations/presence.rb +30 -0
  109. data/lib/assembla_api/validations/required.rb +24 -0
  110. data/lib/assembla_api/validations/token.rb +41 -0
  111. data/lib/assembla_api/version.rb +12 -0
  112. metadata +347 -0
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+
3
+ require 'delegate'
4
+ require 'base64'
5
+
6
+ module Assembla
7
+
8
+ # Class responsible for holding request parameters
9
+ class ParamsHash < DelegateClass(Hash)
10
+ include Normalizer
11
+ include MimeType
12
+
13
+ def initialize(hash)
14
+ super(normalize!(Hash[hash]))
15
+ end
16
+
17
+ # Create empty hash
18
+ #
19
+ def self.empty
20
+ new({})
21
+ end
22
+
23
+ # Extract and parse media type param
24
+ #
25
+ # [.version].param[+json]
26
+ #
27
+ def media
28
+ parse(delete('media'))
29
+ end
30
+
31
+ # Return accept header if present
32
+ #
33
+ def accept
34
+ if has_key?('accept')
35
+ delete('accept')
36
+ elsif has_key?('media')
37
+ media
38
+ else
39
+ nil
40
+ end
41
+ end
42
+
43
+ # Extract request data from parameters
44
+ #
45
+ def data
46
+ if has_key?('data') && !self['data'].nil?
47
+ return delete('data')
48
+ else
49
+ return to_hash
50
+ end
51
+ end
52
+
53
+ def encoder
54
+ if has_key?('encoder') && self['encoder']
55
+ return delete('encoder')
56
+ else
57
+ return {}
58
+ end
59
+ end
60
+
61
+ # Any client configuration options
62
+ #
63
+ def options
64
+ opts = has_key?('options') ? delete('options') : {}
65
+ headers = opts.fetch(:headers) { {} }
66
+ if value = accept
67
+ headers[:accept] = value
68
+ end
69
+ if value = delete('content_type')
70
+ headers[:content_type] = value
71
+ end
72
+ opts[:raw] = has_key?('raw') ? delete('raw') : false
73
+ opts[:headers] = headers unless headers.empty?
74
+ opts
75
+ end
76
+
77
+ # Update hash with default parameters for non existing keys
78
+ #
79
+ def merge_default(defaults)
80
+ if defaults && !defaults.empty?
81
+ defaults.each do |key, value|
82
+ self[key] = value unless self.has_key?(key)
83
+ end
84
+ end
85
+ self
86
+ end
87
+
88
+ # Base64 encode string removing newline characters
89
+ #
90
+ def strict_encode64(key)
91
+ value = self[key]
92
+ encoded = if Base64.respond_to?(:strict_encode64)
93
+ Base64.strict_encode64(value)
94
+ else
95
+ [value].pack("m0")
96
+ end
97
+ self[key] = encoded.delete("\n\r")
98
+ end
99
+
100
+ end # ParamsHash
101
+ end # Assembla
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ module RateLimit
5
+
6
+ def ratelimit(*args)
7
+ arguments(args)
8
+
9
+ get_request("/rate_limit", arguments.params).rate.limit
10
+ end
11
+
12
+ def ratelimit_remaining(*args)
13
+ arguments(args)
14
+
15
+ get_request("/rate_limit", arguments.params).rate.remaining
16
+ end
17
+
18
+ def ratelimit_reset(*args)
19
+ arguments(args)
20
+
21
+ get_request("/rate_limit", arguments.params).rate.reset
22
+ end
23
+
24
+ end # RateLimit
25
+ end # Assembla
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ require 'assembla_api/request/oauth2'
4
+ require 'assembla_api/request/basic_auth'
5
+ require 'assembla_api/request/key_auth'
6
+ require 'assembla_api/request/jsonize'
7
+
8
+ require 'assembla_api/connection'
9
+
10
+ module Assembla
11
+ # A class responsible for dispatching http requests
12
+ class Request
13
+ include Connection
14
+
15
+ HTTP_METHODS = [:get, :head, :post, :put, :delete, :patch]
16
+
17
+ METHODS_WITH_BODIES = [:post, :put, :patch]
18
+
19
+ # Return http verb
20
+ #
21
+ # @return [Symbol]
22
+ attr_reader :action
23
+
24
+ # Return url
25
+ #
26
+ # @return [String]
27
+ attr_accessor :path
28
+
29
+ # Return api this request is associated with
30
+ #
31
+ # @return [Assembla::API]
32
+ attr_reader :api
33
+
34
+ # Create a new Request
35
+ #
36
+ # @return [Assembla::Request]
37
+ #
38
+ # @api public
39
+ def initialize(action, path, api)
40
+ @action = action
41
+ @path = path
42
+ @api = api
43
+ end
44
+
45
+ # Performs a request
46
+ #
47
+ # @param [Symbol] method - The Symbol the HTTP verb
48
+ # @param [String] path - String relative URL to access
49
+ # @param [ParamsHash] params - ParamsHash to configure the request API
50
+ #
51
+ # @return [Assembla::ResponseWrapper]
52
+ #
53
+ # @api private
54
+ def call(current_options, params)
55
+ unless HTTP_METHODS.include?(action)
56
+ raise ArgumentError, "unknown http method: #{method}"
57
+ end
58
+
59
+ puts "EXECUTED: #{action} - #{path} with PARAMS: #{params}" if ENV['DEBUG']
60
+
61
+ request_options = params.options
62
+ connection_options = current_options.merge(request_options)
63
+ conn = connection(api, connection_options)
64
+
65
+ if conn.path_prefix != '/' && self.path.index(conn.path_prefix) != 0
66
+ self.path = (conn.path_prefix + self.path).gsub(/\/(\/)*/, '/')
67
+ end
68
+
69
+ response = conn.send(action) do |request|
70
+ case action.to_sym
71
+ when *(HTTP_METHODS - METHODS_WITH_BODIES)
72
+ request.body = params.data if params.has_key?('data')
73
+ if params.has_key?('encoder')
74
+ request.params.params_encoder(params.encoder)
75
+ end
76
+ request.url(self.path, params.to_hash)
77
+ when *METHODS_WITH_BODIES
78
+ request.url(self.path, connection_options[:query] || {})
79
+ request.body = params.data unless params.empty?
80
+ end
81
+ end
82
+ ResponseWrapper.new(response, api)
83
+ end
84
+ end # Request
85
+ end # Assembla
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'base64'
5
+
6
+ module Assembla
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 # Assembla
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Assembla
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
+ unless env[:request_headers][CONTENT_TYPE].to_s =~ /^multipart/
15
+ if request_with_body?(env)
16
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
17
+ env[:body] = encode_body env[:body] unless env[:body].respond_to?(:to_str)
18
+ else
19
+ # Ensure valid body for put and post requests
20
+ if [:put, :patch, :post].include? env[:method]
21
+ env[:body] = encode_body({})
22
+ end
23
+ end
24
+ end
25
+
26
+ @app.call env
27
+ end
28
+
29
+ def encode_body(value)
30
+ if MultiJson.respond_to?(:dump)
31
+ MultiJson.dump(value)
32
+ else
33
+ MultiJson.encode(value)
34
+ end
35
+ end
36
+
37
+ def request_with_body?(env)
38
+ type = request_type(env)
39
+ has_body?(env) and (type.empty? or type == MIME_TYPE)
40
+ end
41
+
42
+ # Don't encode bodies in string form
43
+ def has_body?(env)
44
+ body = env[:body] and !(body.respond_to?(:to_str) and body.empty?)
45
+ end
46
+
47
+ def request_type(env)
48
+ type = env[:request_headers][CONTENT_TYPE].to_s
49
+ type = type.split(';', 2).first if type.index(';')
50
+ type
51
+ end
52
+ end # Request::Jsonize
53
+ end # Assembla
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'base64'
5
+
6
+ module Assembla
7
+ class Request
8
+ class KeyAuth < Faraday::Middleware
9
+ dependency 'base64'
10
+
11
+ def call(env)
12
+ unless @api_key.to_s.empty?
13
+ env[:request_headers].merge!('X-Api-Key' => @api_key,
14
+ 'X-Api-Secret' => @api_secret)
15
+ end
16
+
17
+ @app.call env
18
+ end
19
+
20
+ def initialize(app, *args)
21
+ @app = app
22
+ options = args.extract_options!
23
+
24
+ if options.has_key? :api_key
25
+ @api_key = options[:api_key]
26
+ @api_secret = options[:api_secret]
27
+ end
28
+ end
29
+ end # KeyAuth
30
+ end # Request
31
+ end # Assembla
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Assembla
6
+ class Request
7
+ class OAuth2 < Faraday::Middleware
8
+ include Assembla::Utils::Url
9
+
10
+ ACCESS_TOKEN = 'access_token'.freeze
11
+ AUTH_HEADER = 'Authorization'.freeze
12
+
13
+ dependency 'oauth2'
14
+
15
+ def call(env)
16
+ # Extract parameters from the query
17
+ params = { ACCESS_TOKEN => @token }.update query_params(env[:url])
18
+
19
+ if token = params[ACCESS_TOKEN] and !token.empty?
20
+ env[:url].query = build_query params
21
+ env[:request_headers].merge!(AUTH_HEADER => "Token token=\"#{token}\"")
22
+ end
23
+
24
+ @app.call env
25
+ end
26
+
27
+ def initialize(app, *args)
28
+ super app
29
+ @app = app
30
+ @token = args.shift
31
+ end
32
+
33
+ def query_params(url)
34
+ if url.query.nil? or url.query.empty?
35
+ {}
36
+ else
37
+ parse_query url.query
38
+ end
39
+ end
40
+ end # OAuth2
41
+ end # Request
42
+ end # Assembla
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ # A class responsible for dispatching http requests
5
+ class Request
6
+
7
+ # Defines HTTP verbs
8
+ module Verbs
9
+ # Make a head request
10
+ #
11
+ # @api public
12
+ def head_request(path, params = ParamsHash.empty)
13
+ Request.new(:head, path, self).call(current_options, params)
14
+ end
15
+
16
+ # Make a get request
17
+ #
18
+ # @api public
19
+ def get_request(path, params = ParamsHash.empty)
20
+ request = Request.new(:get, path, self).call(current_options, params)
21
+ request.auto_paginate
22
+ end
23
+
24
+ # Make a patch request
25
+ #
26
+ # @api public
27
+ def patch_request(path, params = ParamsHash.empty)
28
+ Request.new(:patch, path, self).call(current_options, params)
29
+ end
30
+
31
+ # Make a post request
32
+ #
33
+ # @api public
34
+ def post_request(path, params = ParamsHash.empty)
35
+ Request.new(:post, path, self).call(current_options, params)
36
+ end
37
+
38
+ # Make a put request
39
+ #
40
+ # @api public
41
+ def put_request(path, params = ParamsHash.empty)
42
+ Request.new(:put, path, self).call(current_options, params)
43
+ end
44
+
45
+ # Make a delete request
46
+ #
47
+ # @api public
48
+ def delete_request(path, params = ParamsHash.empty)
49
+ Request.new(:delete, path, self).call(current_options, params)
50
+ end
51
+
52
+ # Make a options request
53
+ #
54
+ # @api public
55
+ def options_request(path, params = ParamsHash.empty)
56
+ Request.new(:options, path, self).call(current_options, params)
57
+ end
58
+ end # Verbs
59
+ end # Request
60
+ end # Assembla
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Assembla
6
+ # Contains methods and attributes that act on the response returned from the
7
+ # request
8
+ class Response < Faraday::Response::Middleware
9
+ CONTENT_TYPE = 'Content-Type'.freeze
10
+
11
+ class << self
12
+ attr_accessor :parser
13
+ end
14
+
15
+ def self.define_parser(&block)
16
+ @parser = block
17
+ end
18
+
19
+ def response_type(env)
20
+ env[:response_headers][CONTENT_TYPE].to_s
21
+ end
22
+
23
+ def parse_response?(env)
24
+ env[:body].respond_to? :to_str
25
+ end
26
+
27
+ end # Response
28
+ end # Assembla