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,71 @@
1
+ # encoding: utf-8
2
+
3
+ require 'assembla_api/api/config'
4
+
5
+ module Assembla
6
+ # Stores the configuration
7
+ class Configuration < API::Config
8
+
9
+ # Other adapters are :typhoeus, :patron, :em_synchrony, :excon, :test
10
+ property :adapter, default: :net_http
11
+
12
+ # By default, don't traverse the page links
13
+ property :auto_pagination, default: false
14
+
15
+ # Basic authentication
16
+ property :basic_auth
17
+
18
+ # By default, don't set an application key
19
+ property :client_id
20
+
21
+ # By default, don't set an application secret
22
+ property :client_secret
23
+
24
+ # By default, don't set an api key
25
+ property :api_key
26
+
27
+ # By default, don't set an api secret
28
+ property :api_secret
29
+
30
+ # By default, don't set a user oauth access token
31
+ property :oauth_token
32
+
33
+ # The api endpoint used to connect to Assembla if none is set
34
+ property :endpoint, default: 'https://api.assembla.com/v1'.freeze
35
+
36
+ # The web endpoint used to connect to Assembla if none is set
37
+ property :site, default: 'https://www.assembla.com'.freeze
38
+
39
+ # The default SSL configuration
40
+ property :ssl, default: {
41
+ :ca_file => File.expand_path('../ssl_certs/cacerts.pem', __FILE__)
42
+ }
43
+
44
+ # By default the Accept header will make a request for JSON
45
+ property :mime_type
46
+
47
+ # The value sent in the http header for 'User-Agent' if none is set
48
+ property :user_agent, default: "Assembla API Ruby Gem #{Assembla::VERSION::STRING}".freeze
49
+
50
+ # By default uses the Faraday connection options if none is set
51
+ property :connection_options, default: {}
52
+
53
+ # Global repository name
54
+ property :repo
55
+
56
+ property :user
57
+
58
+ # TODO Portfolio
59
+ property :org
60
+
61
+ property :login
62
+
63
+ property :password
64
+
65
+ # By default display 30 resources
66
+ property :per_page, default: 30
67
+
68
+ # Add Faraday::RackBuilder to overwrite middleware
69
+ property :stack
70
+ end # Configuration
71
+ end # Assembla
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ # Specifies Http connection options
5
+ module Connection
6
+ extend self
7
+ include Assembla::Constants
8
+
9
+ ALLOWED_OPTIONS = [
10
+ :headers,
11
+ :url,
12
+ :params,
13
+ :request,
14
+ :ssl
15
+ ].freeze
16
+
17
+ def default_options(options = {})
18
+ accept = options[:headers] && options[:headers][:accept]
19
+ {
20
+ headers: {
21
+ ACCEPT => accept || 'application/vnd.assembla.v1+json,' \
22
+ 'application/vnd.assembla.beta+json;q=0.5,' \
23
+ 'application/json;q=0.1',
24
+ ACCEPT_CHARSET => 'utf-8',
25
+ USER_AGENT => options[:user_agent]
26
+ },
27
+ ssl: options[:ssl],
28
+ url: options[:endpoint]
29
+ }
30
+ end
31
+
32
+ def clear_cache
33
+ @connection = nil
34
+ end
35
+
36
+ def caching?
37
+ !@connection.nil?
38
+ end
39
+
40
+ # Exposes middleware builder to facilitate custom stacks and easy
41
+ # addition of new extensions such as cache adapter.
42
+ #
43
+ # @api public
44
+ def stack(options = {})
45
+ @stack ||= begin
46
+ builder_class = defined?(Faraday::RackBuilder) ? Faraday::RackBuilder : Faraday::Builder
47
+ builder_class.new(&Assembla.default_middleware(options))
48
+ end
49
+ end
50
+
51
+ # Creates http connection
52
+ #
53
+ # Returns a Fraday::Connection object
54
+ def connection(api, options = {})
55
+ connection_options = default_options(options)
56
+ clear_cache unless options.empty?
57
+ builder = api.stack ? api.stack : stack(options.merge!(api: api))
58
+ connection_options.merge!(builder: builder)
59
+ if ENV['DEBUG']
60
+ p "Connection options : \n"
61
+ pp connection_options
62
+ end
63
+ @connection ||= Faraday.new(connection_options)
64
+ end
65
+ end # Connection
66
+ end # Assembla
@@ -0,0 +1,74 @@
1
+ module Assembla
2
+ module Constants
3
+ extend self
4
+
5
+ # Response headers
6
+ RATELIMIT_REMAINING = 'X-RateLimit-Remaining'.freeze
7
+
8
+ RATELIMIT_LIMIT = 'X-RateLimit-Limit'.freeze
9
+
10
+ CONTENT_TYPE = 'Content-Type'.freeze
11
+
12
+ CONTENT_LENGTH = 'content-length'.freeze
13
+
14
+ CACHE_CONTROL = 'cache-control'.freeze
15
+
16
+ ETAG = 'ETag'.freeze
17
+
18
+ SERVER = 'Server'.freeze
19
+
20
+ DATE = 'Date'.freeze
21
+
22
+ LOCATION = 'Location'.freeze
23
+
24
+ USER_AGENT = 'User-Agent'.freeze
25
+
26
+ ACCEPT = 'Accept'.freeze
27
+
28
+ ACCEPT_CHARSET = 'Accept-Charset'.freeze
29
+
30
+ OAUTH_SCOPES = 'X-Oauth-Scopes'.freeze
31
+
32
+ ACCEPTED_OAUTH_SCOPES = 'X-Accepted-Oauth-Scopes'.freeze
33
+
34
+ # Link headers
35
+ HEADER_LINK = "Link".freeze
36
+
37
+ HEADER_NEXT = "X-Next".freeze
38
+
39
+ HEADER_LAST = "X-Last".freeze
40
+
41
+ META_REL = "rel".freeze
42
+
43
+ META_LAST = "last".freeze
44
+
45
+ META_NEXT = "next".freeze
46
+
47
+ META_FIRST = "first".freeze
48
+
49
+ META_PREV = "prev".freeze
50
+
51
+ PARAM_PAGE = "page".freeze
52
+
53
+ PARAM_PER_PAGE = "per_page".freeze
54
+
55
+ PARAM_START_PAGE = "start_page".freeze
56
+
57
+ class ToolTypes
58
+ MILESTONES = 9
59
+ STANDUP = 10
60
+ TICKETS = 13
61
+ FILES = 18
62
+ MESSAGES = 21
63
+ WIKI = 23
64
+ WEBHOOKS = 112
65
+ GIT = 128
66
+ SSH = 200
67
+ # TODO add all tools
68
+ ALL = [ MESSAGES, TICKETS, MILESTONES, FILES, STANDUP, GIT, WIKI, WEBHOOKS,
69
+ SSH
70
+ ]
71
+ end
72
+
73
+ end # Constants
74
+ end # Assembla
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ class Array # :nodoc:
4
+
5
+ # Returns a new arrray with keys removed
6
+ #
7
+ def except(*keys)
8
+ self.dup.except!(*keys)
9
+ end unless method_defined? :except
10
+
11
+ # Similar to except but modifies self
12
+ #
13
+ def except!(*items)
14
+ copy = self.dup
15
+ copy.reject! { |item| items.include? item }
16
+ copy
17
+ end unless method_defined? :except!
18
+
19
+ # Selects a hash from the arguments list
20
+ #
21
+ def extract_options!
22
+ last.is_a?(::Hash) ? pop : {}
23
+ end unless method_defined? :extract_options!
24
+
25
+ end # Array
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ class Hash # :nodoc:
4
+
5
+ # Returns a new hash with keys removed
6
+ #
7
+ def except(*items)
8
+ self.dup.except!(*items)
9
+ end unless method_defined? :except
10
+
11
+ # Similar to except but modifies self
12
+ #
13
+ def except!(*keys)
14
+ copy = self.dup
15
+ keys.each { |key| copy.delete!(key) }
16
+ copy
17
+ end unless method_defined? :except!
18
+
19
+ # Returns a new hash with all the keys converted to symbols
20
+ #
21
+ def symbolize_keys
22
+ inject({}) do |hash, (key, value)|
23
+ hash[(key.to_sym rescue key) || key] = value
24
+ hash
25
+ end
26
+ end unless method_defined? :symbolize_keys
27
+
28
+ # Similar to symbolize_keys but modifies self
29
+ #
30
+ def symbolize_keys!
31
+ hash = symbolize_keys
32
+ hash.each do |key, val|
33
+ hash[key] = case val
34
+ when Hash
35
+ val.symbolize_keys!
36
+ when Array
37
+ val.map do |item|
38
+ item.is_a?(Hash) ? item.symbolize_keys! : item
39
+ end
40
+ else
41
+ val
42
+ end
43
+ end
44
+ return hash
45
+ end unless method_defined? :symbolize_keys!
46
+
47
+ # Returns hash collapsed into a query string
48
+ #
49
+ def serialize
50
+ self.map { |key, val| [key, val].join("=") }.join("&")
51
+ end unless method_defined? :serialize
52
+
53
+ # Searches for all deeply nested keys
54
+ #
55
+ def deep_keys
56
+ keys = self.keys
57
+ keys.each do |key|
58
+ if self[key].is_a?(Hash)
59
+ keys << self[key].deep_keys.compact.flatten
60
+ next
61
+ end
62
+ end
63
+ keys.flatten
64
+ end unless method_defined? :deep_keys
65
+
66
+ # Returns true if the given key is present inside deeply nested hash
67
+ #
68
+ def deep_key?(key)
69
+ self.deep_keys.include? key
70
+ end unless method_defined? :deep_key?
71
+
72
+ # Recursively merges self with other hash and returns new hash.
73
+ #
74
+ def deep_merge(other, &block)
75
+ dup.deep_merge!(other, &block)
76
+ end unless method_defined? :deep_merge
77
+
78
+ # Similar as deep_merge but modifies self
79
+ #
80
+ def deep_merge!(other, &block)
81
+ other.each_pair do |key, val|
82
+ tval = self[key]
83
+ if tval.is_a?(Hash) && val.is_a?(Hash)
84
+ self[key] = tval.deep_merge(val)
85
+ else
86
+ self[key] = block && tval ? block.call(k, tval, val) : val
87
+ end
88
+ end
89
+ self
90
+ end unless method_defined? :deep_merge!
91
+
92
+ end # Hash
@@ -0,0 +1,107 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+ module CoreExt #:nodoc:
5
+
6
+ if RUBY_VERSION >= '1.9'
7
+ class OrderedHash < ::Hash; end
8
+ else
9
+ class OrderedHash < ::Hash
10
+ attr_accessor :order
11
+
12
+ class << self
13
+ def [](*args)
14
+ hsh = OrderedHash.new
15
+ if Hash == args[0]
16
+ hsh.replace args[0]
17
+ elsif (args.size % 2) != 0
18
+ pp args
19
+ raise ArgumentError, "odd number of elements for Hash"
20
+ else
21
+ 0.step(args.size - 1, 2) do |a|
22
+ b = a + 1
23
+ hsh[args[a]] = args[b]
24
+ end
25
+ end
26
+ hsh
27
+ end
28
+ end
29
+
30
+ def initialize(*args, &block)
31
+ super
32
+ @order = []
33
+ end
34
+
35
+ def []=(key, value)
36
+ @order.push key unless member?(key)
37
+ super key, value
38
+ end
39
+
40
+ def ==(hsh2)
41
+ return false if @order != hsh2.order
42
+ super hsh2
43
+ end
44
+
45
+ def clear
46
+ @order = []
47
+ super
48
+ end
49
+
50
+ def delete(key)
51
+ @order.delete key
52
+ super
53
+ end
54
+
55
+ def each_key
56
+ @order.each { |k| yield k }
57
+ self
58
+ end
59
+
60
+ def each_value
61
+ @order.each { |k| yield self[k] }
62
+ self
63
+ end
64
+
65
+ def each
66
+ @order.each { |k| yield k, self[k] }
67
+ self
68
+ end
69
+ alias :each_pair :each
70
+
71
+ def delete_if
72
+ @order.clone.each { |k| delete k if yield }
73
+ self
74
+ end
75
+
76
+ def values
77
+ ary = []
78
+ @order.each { |k| ary.push self[k] }
79
+ ary
80
+ end
81
+
82
+ def keys
83
+ @order
84
+ end
85
+
86
+ def replace(hsh2)
87
+ @order = hsh2.keys
88
+ super hsh2
89
+ end
90
+
91
+ def shift
92
+ key = @order.first
93
+ key ? [key, delete(key)] : super
94
+ end
95
+
96
+ def class
97
+ Hash
98
+ end
99
+
100
+ def __class__
101
+ OrderedHash
102
+ end
103
+ end # OrderedHash
104
+ end
105
+
106
+ end # CoreExt
107
+ end # Assembla
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ module Assembla
4
+
5
+ DEPRECATION_PREFIX = "[AssemblaAPI] Deprecation warning:"
6
+
7
+ class << self
8
+
9
+ attr_writer :deprecation_tracker
10
+
11
+ def deprecation_tracker
12
+ @deprecation_tracker ||= []
13
+ end
14
+
15
+ # Displays deprecation message to the user.
16
+ # Each message is printed once.
17
+ def deprecate(method, alternate_method=nil)
18
+ return if deprecation_tracker.include? method
19
+ deprecation_tracker << method
20
+
21
+ message = <<-NOTICE
22
+ #{DEPRECATION_PREFIX}
23
+
24
+ * #{method} is deprecated.
25
+ NOTICE
26
+ if alternate_method
27
+ message << <<-ADDITIONAL
28
+ * please use #{alternate_method} instead.
29
+ ADDITIONAL
30
+ end
31
+ warn_deprecation(message)
32
+ end
33
+
34
+ def warn_deprecation(message)
35
+ send :warn, message
36
+ end
37
+ end
38
+
39
+ end # Assembla