zendesk_api 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/.yardopts CHANGED
@@ -1 +1,8 @@
1
- --tag internal --hide-tag internal --no-private --protected lib/**/*.rb -e util/resource_handler.rb -e util/verb_handler.rb - Readme.md
1
+ --tag internal
2
+ --hide-tag internal
3
+ --no-private
4
+ --protected lib/**/*.rb
5
+ --load ./util/resource_handler.rb
6
+ --load ./util/verb_handler.rb
7
+ -
8
+ Readme.md
data/Gemfile.lock CHANGED
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- zendesk_api (0.2.5)
16
+ zendesk_api (0.2.6)
17
17
  faraday (>= 0.8.0)
18
18
  faraday_middleware (>= 0.8.7)
19
19
  hashie
@@ -63,7 +63,7 @@ GEM
63
63
  inflection (1.0.0)
64
64
  jruby-openssl (0.8.2)
65
65
  bouncy-castle-java (>= 1.5.0146.1)
66
- json (1.7.6)
66
+ json (1.7.7)
67
67
  mime-types (1.20.1)
68
68
  mongoid (3.0.21)
69
69
  activemodel (~> 3.1)
@@ -58,34 +58,11 @@ module ZendeskAPI
58
58
 
59
59
  resources.each do |resource|
60
60
  if resource.key?(plural_key) # Grab associations from child_ids field on resource
61
- ids = resource.send(plural_key)
62
-
63
- resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
64
- ids.include?(side_load[options.include_key])
65
- }))
61
+ side_load_from_child_ids(resource, side_loads, plural_key)
66
62
  elsif resource.key?(key) || options.singular
67
- # Either grab association from child_id field on resource or parent_id on child resource
68
- if resource.key?(key)
69
- id = resource.send(key)
70
- include_key = options.include_key
71
- else
72
- id = resource.id
73
- include_key = "#{resource.class.singular_resource_name}_id"
74
- end
75
-
76
- next unless id
77
-
78
- side_load = side_loads.detect do |side_load|
79
- id == side_load[include_key]
80
- end
81
-
82
- resource.send("#{options.name}=", side_load) if side_load
63
+ side_load_from_child_or_parent_id(resource, side_loads, key)
83
64
  else # Grab associations from parent_id field from multiple child resources
84
- key = "#{resource.class.singular_resource_name}_id"
85
-
86
- resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
87
- side_load[key] == resource.id
88
- }))
65
+ side_load_from_parent_id(resource, side_loads, key)
89
66
  end
90
67
  end
91
68
  end
@@ -102,6 +79,41 @@ module ZendeskAPI
102
79
  end
103
80
  end
104
81
 
82
+ def side_load_from_parent_id(resource, side_loads, key)
83
+ key = "#{resource.class.singular_resource_name}_id"
84
+
85
+ resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
86
+ side_load[key] == resource.id
87
+ }))
88
+ end
89
+
90
+ def side_load_from_child_ids(resource, side_loads, plural_key)
91
+ ids = resource.send(plural_key)
92
+
93
+ resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
94
+ ids.include?(side_load[options.include_key])
95
+ }))
96
+ end
97
+
98
+ def side_load_from_child_or_parent_id(resource, side_loads, key)
99
+ # Either grab association from child_id field on resource or parent_id on child resource
100
+ if resource.key?(key)
101
+ id = resource.send(key)
102
+ include_key = options.include_key
103
+ else
104
+ id = resource.id
105
+ include_key = "#{resource.class.singular_resource_name}_id"
106
+ end
107
+
108
+ return unless id
109
+
110
+ side_load = side_loads.detect do |side_load|
111
+ id == side_load[include_key]
112
+ end
113
+
114
+ resource.send("#{options.name}=", side_load) if side_load
115
+ end
116
+
105
117
  def build_parent_namespace(parent_class, instance, options, original_options)
106
118
  return unless association_on_parent = parent_class.associations.detect {|a| a[:class] == @options[:class] }
107
119
  [
@@ -134,179 +146,4 @@ module ZendeskAPI
134
146
  end
135
147
  end
136
148
  end
137
-
138
- # This module holds association method for resources.
139
- # Associations can be loaded in three ways:
140
- # * Commonly used resources are automatically side-loaded server side and sent along with their parent object.
141
- # * Associated resource ids are sent and are then loaded one-by-one into the parent collection.
142
- # * The association is represented with Rails' nested association urls (such as tickets/:id/groups) and are loaded that way.
143
- #
144
- # @private
145
- module Associations
146
- def self.included(base)
147
- base.send(:extend, ClassMethods)
148
- end
149
-
150
- def wrap_resource(resource, klass, class_level_association)
151
- instance_association = Association.new(class_level_association.merge(:parent => self))
152
- case resource
153
- when Hash
154
- klass.new(@client, resource.merge(:association => instance_association))
155
- when String, Fixnum
156
- klass.new(@client, :id => resource, :association => instance_association)
157
- else
158
- resource.association = instance_association
159
- resource
160
- end
161
- end
162
-
163
- # @private
164
- module ClassMethods
165
- include Rescue
166
-
167
- def associations
168
- @associations ||= []
169
- end
170
-
171
- def associated_with(name)
172
- associations.inject([]) do |associated_with, association|
173
- if association[:include] == name.to_s
174
- associated_with.push(Association.new(association))
175
- end
176
-
177
- associated_with
178
- end
179
- end
180
-
181
- # Represents a parent-to-child association between resources. Options to pass in are: class, path.
182
- # @param [Symbol] resource_name_or_class The underlying resource name or a class to get it from
183
- # @param [Hash] class_level_options The options to pass to the method definition.
184
- def has(resource_name_or_class, class_level_options = {})
185
- if klass = class_level_options.delete(:class)
186
- resource_name = resource_name_or_class
187
- else
188
- klass = resource_name_or_class
189
- resource_name = klass.singular_resource_name
190
- end
191
-
192
- class_level_association = {
193
- :class => klass,
194
- :name => resource_name,
195
- :inline => class_level_options.delete(:inline),
196
- :path => class_level_options.delete(:path),
197
- :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
198
- :include_key => (class_level_options.delete(:include_key) || :id).to_s,
199
- :singular => true
200
- }
201
-
202
- associations << class_level_association
203
-
204
- id_column = "#{resource_name}_id"
205
-
206
- define_method "#{resource_name}_used?" do
207
- !!instance_variable_get("@#{resource_name}")
208
- end
209
-
210
- define_method resource_name do |*args|
211
- instance_options = args.last.is_a?(Hash) ? args.pop : {}
212
-
213
- # return if cached
214
- cached = instance_variable_get("@#{resource_name}")
215
- return cached if cached && !instance_options[:reload]
216
-
217
- # find and cache association
218
- instance_association = Association.new(class_level_association.merge(:parent => self))
219
- resource = if klass.respond_to?(:find) && resource_id = method_missing(id_column)
220
- klass.find(@client, :id => resource_id, :association => instance_association)
221
- elsif found = method_missing(resource_name.to_sym)
222
- wrap_resource(found, klass, class_level_association)
223
- elsif klass.superclass == DataResource
224
- rescue_client_error do
225
- response = @client.connection.get(instance_association.generate_path(:with_parent => true))
226
- klass.new(@client, response.body[klass.singular_resource_name].merge(:association => instance_association))
227
- end
228
- end
229
-
230
- send("#{id_column}=", resource.id) if resource && has_key?(id_column)
231
- instance_variable_set("@#{resource_name}", resource)
232
- end
233
-
234
- define_method "#{resource_name}=" do |resource|
235
- resource = wrap_resource(resource, klass, class_level_association)
236
- send("#{id_column}=", resource.id) if has_key?(id_column)
237
- instance_variable_set("@#{resource_name}", resource)
238
- end
239
- end
240
-
241
- # Represents a parent-to-children association between resources. Options to pass in are: class, path.
242
- # @param [Symbol] resource_name_or_class The underlying resource name or class to get it from
243
- # @param [Hash] class_level_options The options to pass to the method definition.
244
- def has_many(resource_name_or_class, class_level_options = {})
245
- if klass = class_level_options.delete(:class)
246
- resource_name = resource_name_or_class
247
- else
248
- klass = resource_name_or_class
249
- resource_name = klass.resource_name
250
- end
251
-
252
- class_level_association = {
253
- :class => klass,
254
- :name => resource_name,
255
- :inline => class_level_options.delete(:inline),
256
- :path => class_level_options.delete(:path),
257
- :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
258
- :include_key => (class_level_options.delete(:include_key) || :id).to_s,
259
- :singular => false
260
- }
261
-
262
- associations << class_level_association
263
-
264
- id_column = "#{resource_name}_ids"
265
-
266
- define_method "#{resource_name}_used?" do
267
- !!instance_variable_get("@#{resource_name}")
268
- end
269
-
270
- define_method resource_name do |*args|
271
- instance_opts = args.last.is_a?(Hash) ? args.pop : {}
272
-
273
- # return if cached
274
- cached = instance_variable_get("@#{resource_name}")
275
- return cached if cached && !instance_opts[:reload]
276
-
277
- # find and cache association
278
- instance_association = Association.new(class_level_association.merge(:parent => self))
279
- singular_resource_name = Inflection.singular(resource_name.to_s)
280
-
281
- resources = if (ids = method_missing("#{singular_resource_name}_ids")) && ids.any?
282
- ids.map do |id|
283
- klass.find(@client, :id => id, :association => instance_association)
284
- end.compact
285
- elsif (resources = method_missing(resource_name.to_sym)) && resources.any?
286
- resources.map do |res|
287
- klass.new(@client, res.merge(:association => instance_association))
288
- end
289
- else
290
- ZendeskAPI::Collection.new(@client, klass, instance_opts.merge(:association => instance_association))
291
- end
292
-
293
- send("#{id_column}=", resources.map(&:id)) if resource && has_key?(id_column)
294
- instance_variable_set("@#{resource_name}", resources)
295
- end
296
-
297
- define_method "#{resource_name}=" do |resources|
298
- if resources.is_a?(Array)
299
- resources.map! { |attr| wrap_resource(attr, klass, class_level_association) }
300
- send(resource_name).replace(resources)
301
- else
302
- resources.association = instance_association
303
- instance_variable_set("@#{resource_name}", resources)
304
- end
305
-
306
- send("#{id_column}=", resources.map(&:id)) if resources && has_key?(id_column)
307
- resource
308
- end
309
- end
310
- end
311
- end
312
149
  end
@@ -0,0 +1,178 @@
1
+ require 'zendesk_api/helpers'
2
+
3
+ module ZendeskAPI
4
+ # This module holds association method for resources.
5
+ # Associations can be loaded in three ways:
6
+ # * Commonly used resources are automatically side-loaded server side and sent along with their parent object.
7
+ # * Associated resource ids are sent and are then loaded one-by-one into the parent collection.
8
+ # * The association is represented with Rails' nested association urls (such as tickets/:id/groups) and are loaded that way.
9
+ #
10
+ # @private
11
+ module Associations
12
+ def self.included(base)
13
+ base.send(:extend, ClassMethods)
14
+ end
15
+
16
+ def wrap_resource(resource, klass, class_level_association)
17
+ instance_association = Association.new(class_level_association.merge(:parent => self))
18
+ case resource
19
+ when Hash
20
+ klass.new(@client, resource.merge(:association => instance_association))
21
+ when String, Fixnum
22
+ klass.new(@client, :id => resource, :association => instance_association)
23
+ else
24
+ resource.association = instance_association
25
+ resource
26
+ end
27
+ end
28
+
29
+ # @private
30
+ module ClassMethods
31
+ include Rescue
32
+
33
+ def associations
34
+ @associations ||= []
35
+ end
36
+
37
+ def associated_with(name)
38
+ associations.inject([]) do |associated_with, association|
39
+ if association[:include] == name.to_s
40
+ associated_with.push(Association.new(association))
41
+ end
42
+
43
+ associated_with
44
+ end
45
+ end
46
+
47
+ # Represents a parent-to-child association between resources. Options to pass in are: class, path.
48
+ # @param [Symbol] resource_name_or_class The underlying resource name or a class to get it from
49
+ # @param [Hash] class_level_options The options to pass to the method definition.
50
+ def has(resource_name_or_class, class_level_options = {})
51
+ if klass = class_level_options.delete(:class)
52
+ resource_name = resource_name_or_class
53
+ else
54
+ klass = resource_name_or_class
55
+ resource_name = klass.singular_resource_name
56
+ end
57
+
58
+ class_level_association = {
59
+ :class => klass,
60
+ :name => resource_name,
61
+ :inline => class_level_options.delete(:inline),
62
+ :path => class_level_options.delete(:path),
63
+ :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
64
+ :include_key => (class_level_options.delete(:include_key) || :id).to_s,
65
+ :singular => true
66
+ }
67
+
68
+ associations << class_level_association
69
+
70
+ id_column = "#{resource_name}_id"
71
+
72
+ define_method "#{resource_name}_used?" do
73
+ !!instance_variable_get("@#{resource_name}")
74
+ end
75
+
76
+ define_method resource_name do |*args|
77
+ instance_options = args.last.is_a?(Hash) ? args.pop : {}
78
+
79
+ # return if cached
80
+ cached = instance_variable_get("@#{resource_name}")
81
+ return cached if cached && !instance_options[:reload]
82
+
83
+ # find and cache association
84
+ instance_association = Association.new(class_level_association.merge(:parent => self))
85
+ resource = if klass.respond_to?(:find) && resource_id = method_missing(id_column)
86
+ klass.find(@client, :id => resource_id, :association => instance_association)
87
+ elsif found = method_missing(resource_name.to_sym)
88
+ wrap_resource(found, klass, class_level_association)
89
+ elsif klass.superclass == DataResource
90
+ rescue_client_error do
91
+ response = @client.connection.get(instance_association.generate_path(:with_parent => true))
92
+ klass.new(@client, response.body[klass.singular_resource_name].merge(:association => instance_association))
93
+ end
94
+ end
95
+
96
+ send("#{id_column}=", resource.id) if resource && has_key?(id_column)
97
+ instance_variable_set("@#{resource_name}", resource)
98
+ end
99
+
100
+ define_method "#{resource_name}=" do |resource|
101
+ resource = wrap_resource(resource, klass, class_level_association)
102
+ send("#{id_column}=", resource.id) if has_key?(id_column)
103
+ instance_variable_set("@#{resource_name}", resource)
104
+ end
105
+ end
106
+
107
+ # Represents a parent-to-children association between resources. Options to pass in are: class, path.
108
+ # @param [Symbol] resource_name_or_class The underlying resource name or class to get it from
109
+ # @param [Hash] class_level_options The options to pass to the method definition.
110
+ def has_many(resource_name_or_class, class_level_options = {})
111
+ if klass = class_level_options.delete(:class)
112
+ resource_name = resource_name_or_class
113
+ else
114
+ klass = resource_name_or_class
115
+ resource_name = klass.resource_name
116
+ end
117
+
118
+ class_level_association = {
119
+ :class => klass,
120
+ :name => resource_name,
121
+ :inline => class_level_options.delete(:inline),
122
+ :path => class_level_options.delete(:path),
123
+ :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
124
+ :include_key => (class_level_options.delete(:include_key) || :id).to_s,
125
+ :singular => false
126
+ }
127
+
128
+ associations << class_level_association
129
+
130
+ id_column = "#{resource_name}_ids"
131
+
132
+ define_method "#{resource_name}_used?" do
133
+ !!instance_variable_get("@#{resource_name}")
134
+ end
135
+
136
+ define_method resource_name do |*args|
137
+ instance_opts = args.last.is_a?(Hash) ? args.pop : {}
138
+
139
+ # return if cached
140
+ cached = instance_variable_get("@#{resource_name}")
141
+ return cached if cached && !instance_opts[:reload]
142
+
143
+ # find and cache association
144
+ instance_association = Association.new(class_level_association.merge(:parent => self))
145
+ singular_resource_name = Inflection.singular(resource_name.to_s)
146
+
147
+ resources = if (ids = method_missing("#{singular_resource_name}_ids")) && ids.any?
148
+ ids.map do |id|
149
+ klass.find(@client, :id => id, :association => instance_association)
150
+ end.compact
151
+ elsif (resources = method_missing(resource_name.to_sym)) && resources.any?
152
+ resources.map do |res|
153
+ klass.new(@client, res.merge(:association => instance_association))
154
+ end
155
+ else
156
+ ZendeskAPI::Collection.new(@client, klass, instance_opts.merge(:association => instance_association))
157
+ end
158
+
159
+ send("#{id_column}=", resources.map(&:id)) if resource && has_key?(id_column)
160
+ instance_variable_set("@#{resource_name}", resources)
161
+ end
162
+
163
+ define_method "#{resource_name}=" do |resources|
164
+ if resources.is_a?(Array)
165
+ resources.map! { |attr| wrap_resource(attr, klass, class_level_association) }
166
+ send(resource_name).replace(resources)
167
+ else
168
+ resources.association = instance_association
169
+ instance_variable_set("@#{resource_name}", resources)
170
+ end
171
+
172
+ send("#{id_column}=", resources.map(&:id)) if resources && has_key?(id_column)
173
+ resource
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -14,22 +14,25 @@ module ZendeskAPI
14
14
  @cache_key_prefix = options.fetch(:cache_key_prefix, :faraday_etags)
15
15
  end
16
16
 
17
+ def cache_key(env)
18
+ [@cache_key_prefix, env[:url].to_s]
19
+ end
20
+
17
21
  def call(env)
18
22
  return @app.call(env) unless [:get, :head].include?(env[:method])
19
- cache_key = [@cache_key_prefix, env[:url].to_s]
20
23
 
21
24
  # send known etag
22
- if cached = @cache.read(cache_key)
25
+ cached = @cache.read(cache_key(env))
26
+
27
+ if cached
23
28
  env[:request_headers]["If-None-Match"] ||= cached[:response_headers]["Etag"]
24
29
  end
25
30
 
26
31
  @app.call(env).on_complete do
27
32
  if cached && env[:status] == 304 # not modified
28
33
  env[:body] = cached[:body]
29
- end
30
-
31
- if env[:status] == 200 && env[:response_headers]["Etag"] # modified and cacheable
32
- @cache.write(cache_key, env)
34
+ elsif env[:status] == 200 && env[:response_headers]["Etag"] # modified and cacheable
35
+ @cache.write(cache_key(env), env)
33
36
  end
34
37
  end
35
38
  end
@@ -2,6 +2,7 @@ require 'zendesk_api/helpers'
2
2
  require 'zendesk_api/trackie'
3
3
  require 'zendesk_api/actions'
4
4
  require 'zendesk_api/association'
5
+ require 'zendesk_api/associations'
5
6
  require 'zendesk_api/verbs'
6
7
 
7
8
  module ZendeskAPI
@@ -29,17 +29,7 @@ module ZendeskAPI::Server
29
29
  end
30
30
 
31
31
  begin
32
- response = client.connection.send(@method, @path) do |request|
33
- request.params = @url_params.inject({}) do |accum, h|
34
- accum.merge(h["name"] => h["value"])
35
- end
36
-
37
- if @method != :get && @json && !@json.empty?
38
- request.body = JSON.parse(@json)
39
- end
40
-
41
- set_request(request.to_env(client.connection))
42
- end
32
+ response = get_response
43
33
  rescue Faraday::Error::ConnectionFailed => e
44
34
  @error = "The connection failed"
45
35
  rescue Faraday::Error::ClientError => e
@@ -55,6 +45,20 @@ module ZendeskAPI::Server
55
45
  end
56
46
  end
57
47
 
48
+ def get_response
49
+ client.connection.send(@method, @path) do |request|
50
+ request.params = @url_params.inject({}) do |accum, h|
51
+ accum.merge(h["name"] => h["value"])
52
+ end
53
+
54
+ if @method != :get && @json && !@json.empty?
55
+ request.body = JSON.parse(@json)
56
+ end
57
+
58
+ set_request(request.to_env(client.connection))
59
+ end
60
+ end
61
+
58
62
  def map_headers(headers)
59
63
  headers.map do |k,v|
60
64
  name = k.split("-").map(&:capitalize).join("-")
@@ -1,3 +1,3 @@
1
1
  module ZendeskAPI
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zendesk_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-06 00:00:00.000000000 Z
13
+ date: 2013-02-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bump
@@ -244,6 +244,7 @@ files:
244
244
  - lib/zendesk_api.rb
245
245
  - lib/zendesk_api/actions.rb
246
246
  - lib/zendesk_api/association.rb
247
+ - lib/zendesk_api/associations.rb
247
248
  - lib/zendesk_api/client.rb
248
249
  - lib/zendesk_api/collection.rb
249
250
  - lib/zendesk_api/configuration.rb