zendesk_api 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/Gemfile +7 -0
- data/Gemfile.lock +10 -2
- data/LICENSE +176 -19
- data/Readme.md +13 -5
- data/config/newrelic.yml +255 -0
- data/lib/zendesk_api/association.rb +1 -1
- data/lib/zendesk_api/associations.rb +129 -100
- data/lib/zendesk_api/client.rb +44 -25
- data/lib/zendesk_api/collection.rb +83 -58
- data/lib/zendesk_api/console/extensions.rb +47 -28
- data/lib/zendesk_api/server/base.rb +4 -0
- data/lib/zendesk_api/server/docs/account_settings.md +8 -0
- data/lib/zendesk_api/server/docs/automations.md +6 -0
- data/lib/zendesk_api/server/docs/changes_roadmap.md +76 -1
- data/lib/zendesk_api/server/docs/forum_subscriptions.md +2 -2
- data/lib/zendesk_api/server/docs/introduction.md +4 -2
- data/lib/zendesk_api/server/docs/macros.md +2 -0
- data/lib/zendesk_api/server/docs/organizations.md +3 -4
- data/lib/zendesk_api/server/docs/requests.md +21 -7
- data/lib/zendesk_api/server/docs/tickets.md +64 -8
- data/lib/zendesk_api/server/docs/topic_subscriptions.md +3 -3
- data/lib/zendesk_api/server/docs/topic_votes.md +0 -1
- data/lib/zendesk_api/server/docs/triggers.md +7 -0
- data/lib/zendesk_api/server/docs/users.md +4 -4
- data/lib/zendesk_api/server/docs/views.md +57 -8
- data/lib/zendesk_api/server/public/doc/ZendeskAPI.html +131 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Ability.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Activity.html +616 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Attachment.html +362 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Automation.html +438 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Bookmark.html +243 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/CRMData.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/CRMDataStatus.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Category.html +462 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Client.html +1490 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Collection.html +2825 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Configuration.html +1212 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Console.html +860 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Console/Eval.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Create.html +134 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Create/ClassMethods.html +322 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/CreateResource.html +222 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/CustomRole.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Data.html +1432 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/DataResource.html +348 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/DeleteResource.html +216 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Destroy.html +307 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Destroy/ClassMethod.html +245 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/FormatError.html +123 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Forum.html +1196 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/ForumSubscription.html +616 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Group.html +243 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/GroupMembership.html +616 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/JobStatus.html +209 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Locale.html +209 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Macro.html +438 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/MobileDevice.html +361 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Organization.html +1016 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Read.html +278 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/ReadResource.html +220 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Request.html +826 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Request/Comment.html +604 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Resource.html +258 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Role.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/RuleExecution.html +383 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/SatisfactionRating.html +938 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Save.html +510 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Search.html +403 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Search/Result.html +166 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server.html +131 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server/App.html +523 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server/Helper.html +684 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server/HtmlRenderer.html +303 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server/HtmlRenderer/RedcarpetRenderer.html +508 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server/UserRequest.html +125 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Server/ZlibJSON.html +244 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Setting.html +350 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/SharingAgreement.html +209 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/SingularResource.html +247 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/SuspendedTicket.html +342 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Ticket.html +2731 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Ticket/Audit.html +385 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Ticket/Comment.html +636 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Ticket/Tag.html +243 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/TicketField.html +243 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/TicketMetric.html +205 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Topic.html +1086 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Topic/TopicComment.html +232 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Topic/TopicVote.html +624 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/TopicComment.html +743 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/TopicSubscription.html +616 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Trigger.html +438 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Update.html +140 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Update/ClassMethod.html +237 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/UpdateResource.html +222 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Upload.html +404 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/User.html +3611 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/User/Identity.html +563 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/User/TopicComment.html +194 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/Verbs.html +338 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/View.html +1283 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/ViewCount.html +190 -0
- data/lib/zendesk_api/server/public/doc/ZendeskAPI/ViewRow.html +1342 -0
- data/lib/zendesk_api/server/public/doc/_index.html +799 -0
- data/lib/zendesk_api/server/public/doc/class_list.html +53 -0
- data/lib/zendesk_api/server/public/doc/css/common.css +1 -0
- data/lib/zendesk_api/server/public/doc/css/full_list.css +57 -0
- data/lib/zendesk_api/server/public/doc/css/style.css +328 -0
- data/lib/zendesk_api/server/public/doc/file.Readme.html +377 -0
- data/lib/zendesk_api/server/public/doc/file_list.html +55 -0
- data/lib/zendesk_api/server/public/doc/frames.html +28 -0
- data/lib/zendesk_api/server/public/doc/index.html +377 -0
- data/lib/zendesk_api/server/public/doc/js/app.js +214 -0
- data/lib/zendesk_api/server/public/doc/js/full_list.js +173 -0
- data/lib/zendesk_api/server/public/doc/js/jquery.js +4 -0
- data/lib/zendesk_api/server/public/doc/method_list.html +2540 -0
- data/lib/zendesk_api/server/public/doc/top-level-namespace.html +144 -0
- data/lib/zendesk_api/version.rb +1 -1
- data/zendesk_api.gemspec +1 -1
- metadata +96 -3
@@ -71,7 +71,7 @@ module ZendeskAPI
|
|
71
71
|
|
72
72
|
def _side_load(resource, side_loads)
|
73
73
|
side_loads.map! do |side_load|
|
74
|
-
resource.send(:wrap_resource, side_load, options
|
74
|
+
resource.send(:wrap_resource, side_load, options)
|
75
75
|
end
|
76
76
|
|
77
77
|
ZendeskAPI::Collection.new(resource.client, options[:class]).tap do |collection|
|
@@ -10,11 +10,13 @@ module ZendeskAPI
|
|
10
10
|
# @private
|
11
11
|
module Associations
|
12
12
|
def self.included(base)
|
13
|
-
base.
|
13
|
+
base.extend ClassMethods
|
14
14
|
end
|
15
15
|
|
16
|
-
def wrap_resource(resource,
|
16
|
+
def wrap_resource(resource, class_level_association)
|
17
17
|
instance_association = Association.new(class_level_association.merge(:parent => self))
|
18
|
+
klass = class_level_association[:class]
|
19
|
+
|
18
20
|
case resource
|
19
21
|
when Hash
|
20
22
|
klass.new(@client, resource.merge(:association => instance_association))
|
@@ -30,6 +32,11 @@ module ZendeskAPI
|
|
30
32
|
module ClassMethods
|
31
33
|
include Rescue
|
32
34
|
|
35
|
+
def self.extended(klass)
|
36
|
+
klass.extend Has
|
37
|
+
klass.extend HasMany
|
38
|
+
end
|
39
|
+
|
33
40
|
def associations
|
34
41
|
@associations ||= []
|
35
42
|
end
|
@@ -44,133 +51,155 @@ module ZendeskAPI
|
|
44
51
|
end
|
45
52
|
end
|
46
53
|
|
47
|
-
|
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
|
54
|
+
private
|
57
55
|
|
58
|
-
|
56
|
+
def build_association(klass, resource_name, options)
|
57
|
+
{
|
59
58
|
:class => klass,
|
60
59
|
:name => resource_name,
|
61
|
-
:inline =>
|
62
|
-
:path =>
|
63
|
-
:include => (
|
64
|
-
:include_key => (
|
65
|
-
:singular =>
|
60
|
+
:inline => options.delete(:inline),
|
61
|
+
:path => options.delete(:path),
|
62
|
+
:include => (options.delete(:include) || klass.resource_name).to_s,
|
63
|
+
:include_key => (options.delete(:include_key) || :id).to_s,
|
64
|
+
:singular => options.delete(:singular)
|
66
65
|
}
|
66
|
+
end
|
67
67
|
|
68
|
-
|
68
|
+
def define_used(association)
|
69
|
+
define_method "#{association[:name]}_used?" do
|
70
|
+
!!instance_variable_get("@#{association[:name]}")
|
71
|
+
end
|
72
|
+
end
|
69
73
|
|
70
|
-
|
74
|
+
module Has
|
75
|
+
# Represents a parent-to-child association between resources. Options to pass in are: class, path.
|
76
|
+
# @param [Symbol] resource_name_or_class The underlying resource name or a class to get it from
|
77
|
+
# @param [Hash] class_level_options The options to pass to the method definition.
|
78
|
+
def has(resource_name_or_class, class_level_options = {})
|
79
|
+
if klass = class_level_options.delete(:class)
|
80
|
+
resource_name = resource_name_or_class
|
81
|
+
else
|
82
|
+
klass = resource_name_or_class
|
83
|
+
resource_name = klass.singular_resource_name
|
84
|
+
end
|
85
|
+
|
86
|
+
class_level_association = build_association(klass, resource_name, class_level_options)
|
87
|
+
class_level_association.merge!(:singular => true, :id_column => "#{resource_name}_id")
|
71
88
|
|
72
|
-
|
73
|
-
|
89
|
+
associations << class_level_association
|
90
|
+
|
91
|
+
define_used(class_level_association)
|
92
|
+
define_has_getter(class_level_association)
|
93
|
+
define_has_setter(class_level_association)
|
74
94
|
end
|
75
95
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
96
|
+
private
|
97
|
+
|
98
|
+
def define_has_getter(association)
|
99
|
+
klass = association[:class] # shorthand
|
100
|
+
|
101
|
+
define_method association[:name] do |*args|
|
102
|
+
instance_options = args.last.is_a?(Hash) ? args.pop : {}
|
103
|
+
|
104
|
+
# return if cached
|
105
|
+
cached = instance_variable_get("@#{association[:name]}")
|
106
|
+
return cached if cached && !instance_options[:reload]
|
107
|
+
|
108
|
+
# find and cache association
|
109
|
+
instance_association = Association.new(association.merge(:parent => self))
|
110
|
+
resource = if klass.respond_to?(:find) && resource_id = method_missing(association[:id_column])
|
111
|
+
klass.find(@client, :id => resource_id, :association => instance_association)
|
112
|
+
elsif found = method_missing(association[:name].to_sym)
|
113
|
+
wrap_resource(found, association)
|
114
|
+
elsif klass.superclass == DataResource
|
115
|
+
rescue_client_error do
|
116
|
+
response = @client.connection.get(instance_association.generate_path(:with_parent => true))
|
117
|
+
klass.new(@client, response.body[klass.singular_resource_name].merge(:association => instance_association))
|
118
|
+
end
|
93
119
|
end
|
94
|
-
end
|
95
120
|
|
96
|
-
|
97
|
-
|
121
|
+
send("#{association[:id_column]}=", resource.id) if resource && has_key?(association[:id_column])
|
122
|
+
instance_variable_set("@#{association[:name]}", resource)
|
123
|
+
end
|
98
124
|
end
|
99
125
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
126
|
+
def define_has_setter(association)
|
127
|
+
define_method "#{association[:name]}=" do |resource|
|
128
|
+
resource = wrap_resource(resource, association)
|
129
|
+
send("#{association[:id_column]}=", resource.id) if has_key?(association[:id_column])
|
130
|
+
instance_variable_set("@#{association[:name]}", resource)
|
131
|
+
end
|
104
132
|
end
|
105
133
|
end
|
106
134
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
}
|
135
|
+
module HasMany
|
136
|
+
# Represents a parent-to-children association between resources. Options to pass in are: class, path.
|
137
|
+
# @param [Symbol] resource_name_or_class The underlying resource name or class to get it from
|
138
|
+
# @param [Hash] class_level_options The options to pass to the method definition.
|
139
|
+
def has_many(resource_name_or_class, class_level_options = {})
|
140
|
+
if klass = class_level_options.delete(:class)
|
141
|
+
resource_name = resource_name_or_class
|
142
|
+
else
|
143
|
+
klass = resource_name_or_class
|
144
|
+
resource_name = klass.resource_name
|
145
|
+
end
|
127
146
|
|
128
|
-
|
147
|
+
class_level_association = build_association(klass, resource_name, class_level_options)
|
148
|
+
class_level_association.merge!(:singular => false, :id_column => "#{resource_name}_ids")
|
129
149
|
|
130
|
-
|
150
|
+
associations << class_level_association
|
131
151
|
|
132
|
-
|
133
|
-
|
152
|
+
define_used(class_level_association)
|
153
|
+
define_has_many_getter(class_level_association)
|
154
|
+
define_has_many_setter(class_level_association)
|
134
155
|
end
|
135
156
|
|
136
|
-
|
137
|
-
|
157
|
+
private
|
158
|
+
|
159
|
+
def define_has_many_getter(association)
|
160
|
+
klass = association[:class]
|
161
|
+
|
162
|
+
define_method association[:name] do |*args|
|
163
|
+
instance_opts = args.last.is_a?(Hash) ? args.pop : {}
|
138
164
|
|
139
|
-
|
140
|
-
|
141
|
-
|
165
|
+
# return if cached
|
166
|
+
cached = instance_variable_get("@#{association[:name]}")
|
167
|
+
return cached if cached && !instance_opts[:reload]
|
142
168
|
|
143
|
-
|
144
|
-
|
145
|
-
|
169
|
+
# find and cache association
|
170
|
+
instance_association = Association.new(association.merge(:parent => self))
|
171
|
+
singular_resource_name = Inflection.singular(association[:name].to_s)
|
146
172
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
173
|
+
resources = if (ids = method_missing("#{singular_resource_name}_ids")) && ids.any?
|
174
|
+
ids.map do |id|
|
175
|
+
klass.find(@client, :id => id, :association => instance_association)
|
176
|
+
end.compact
|
177
|
+
elsif (resources = method_missing(association[:name].to_sym)) && resources.any?
|
178
|
+
resources.map do |res|
|
179
|
+
klass.new(@client, res.merge(:association => instance_association))
|
180
|
+
end
|
181
|
+
else
|
182
|
+
ZendeskAPI::Collection.new(@client, klass, instance_opts.merge(:association => instance_association))
|
154
183
|
end
|
155
|
-
else
|
156
|
-
ZendeskAPI::Collection.new(@client, klass, instance_opts.merge(:association => instance_association))
|
157
|
-
end
|
158
184
|
|
159
|
-
|
160
|
-
|
185
|
+
send("#{association[:id_column]}=", resources.map(&:id)) if resource && has_key?(association[:id_column])
|
186
|
+
instance_variable_set("@#{association[:name]}", resources)
|
187
|
+
end
|
161
188
|
end
|
162
189
|
|
163
|
-
|
164
|
-
|
165
|
-
resources.
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
190
|
+
def define_has_many_setter(association)
|
191
|
+
define_method "#{association[:name]}=" do |resources|
|
192
|
+
if resources.is_a?(Array)
|
193
|
+
resources.map! { |attr| wrap_resource(attr, association) }
|
194
|
+
send(association[:name]).replace(resources)
|
195
|
+
else
|
196
|
+
resources.association = Association.new(association.merge(:parent => self))
|
197
|
+
instance_variable_set("@#{association[:name]}", resources)
|
198
|
+
end
|
171
199
|
|
172
|
-
|
173
|
-
|
200
|
+
send("#{association[:id_column]}=", resources.map(&:id)) if resources && has_key?(association[:id_column])
|
201
|
+
resource
|
202
|
+
end
|
174
203
|
end
|
175
204
|
end
|
176
205
|
end
|
data/lib/zendesk_api/client.rb
CHANGED
@@ -78,34 +78,16 @@ module ZendeskAPI
|
|
78
78
|
@config = ZendeskAPI::Configuration.new
|
79
79
|
yield config
|
80
80
|
|
81
|
-
if !config.allow_http && config.url !~ /^https/
|
82
|
-
raise ArgumentError, "zendesk_api is ssl only; url must begin with https://"
|
83
|
-
end
|
84
|
-
|
85
|
-
config.retry = !!config.retry # nil -> false
|
86
|
-
|
87
|
-
if config.token && !config.password
|
88
|
-
config.password = config.token
|
89
|
-
config.username += "/token" unless config.username.end_with?("/token")
|
90
|
-
end
|
91
|
-
|
92
|
-
if config.logger.nil? || config.logger == true
|
93
|
-
require 'logger'
|
94
|
-
config.logger = Logger.new($stderr)
|
95
|
-
config.logger.level = Logger::WARN
|
96
|
-
end
|
97
|
-
|
98
81
|
@callbacks = []
|
99
|
-
|
100
82
|
@resource_cache = {}
|
101
83
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
84
|
+
check_url
|
85
|
+
|
86
|
+
config.retry = !!config.retry # nil -> false
|
87
|
+
|
88
|
+
set_token_auth
|
89
|
+
set_default_logger
|
90
|
+
add_warning_callback
|
109
91
|
end
|
110
92
|
|
111
93
|
# Creates a connection if there is none, otherwise returns the existing connection.
|
@@ -162,5 +144,42 @@ module ZendeskAPI
|
|
162
144
|
builder.adapter *config.adapter || Faraday.default_adapter
|
163
145
|
end
|
164
146
|
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def check_url
|
151
|
+
if !config.allow_http && config.url !~ /^https/
|
152
|
+
raise ArgumentError, "zendesk_api is ssl only; url must begin with https://"
|
153
|
+
end
|
154
|
+
|
155
|
+
if config.url !~ %r{api/v2}
|
156
|
+
warn "this gem doesn't support the v1 api"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def set_token_auth
|
161
|
+
if config.token && !config.password
|
162
|
+
config.password = config.token
|
163
|
+
config.username += "/token" unless config.username.end_with?("/token")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def set_default_logger
|
168
|
+
if config.logger.nil? || config.logger == true
|
169
|
+
require 'logger'
|
170
|
+
config.logger = Logger.new($stderr)
|
171
|
+
config.logger.level = Logger::WARN
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def add_warning_callback
|
176
|
+
return unless logger = config.logger
|
177
|
+
|
178
|
+
insert_callback do |env|
|
179
|
+
if warning = env[:response_headers]["X-Zendesk-API-Warn"]
|
180
|
+
logger.warn "WARNING: #{warning}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
165
184
|
end
|
166
185
|
end
|
@@ -27,32 +27,21 @@ module ZendeskAPI
|
|
27
27
|
# @param [String] resource The resource being collected.
|
28
28
|
# @param [Hash] options Any additional options to be passed in.
|
29
29
|
def initialize(client, resource, options = {})
|
30
|
-
@client, @resource = client, resource.resource_name
|
30
|
+
@client, @resource_class, @resource = client, resource, resource.resource_name
|
31
31
|
@options = Hashie::Mash.new(options)
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
association_options = { :path => @options.delete(:path) }
|
37
|
-
association_options[:path] ||= @collection_path.join("/") if @collection_path
|
38
|
-
@association = @options.delete(:association) || Association.new(association_options.merge(:class => resource))
|
33
|
+
set_association_from_options
|
34
|
+
join_special_params
|
39
35
|
|
40
|
-
|
41
|
-
@options.each do |k, v|
|
42
|
-
if SPECIALLY_JOINED_PARAMS.include?(k.to_sym) && v.is_a?(Array)
|
43
|
-
@options[k] = v.join(',')
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
@collection_path ||= [@resource]
|
48
|
-
@resource_class = resource
|
49
|
-
@fetchable = true
|
36
|
+
@verb = @options.delete(:verb)
|
50
37
|
@includes = Array(@options.delete(:include))
|
51
38
|
|
52
39
|
# Used for Attachments, TicketComment
|
53
40
|
if @resource_class.is_a?(Class) && @resource_class.superclass == ZendeskAPI::Data
|
54
41
|
@resources = []
|
55
42
|
@fetchable = false
|
43
|
+
else
|
44
|
+
@fetchable = true
|
56
45
|
end
|
57
46
|
end
|
58
47
|
|
@@ -158,39 +147,16 @@ module ZendeskAPI
|
|
158
147
|
# Executes actual GET from API and loads resources into proper class.
|
159
148
|
# @param [Boolean] reload Whether to disregard cache
|
160
149
|
def fetch(reload = false)
|
161
|
-
|
162
|
-
|
163
|
-
|
150
|
+
if @resources && (!@fetchable || !reload)
|
151
|
+
return @resources
|
152
|
+
elsif association && association.options.parent && association.options.parent.new_record?
|
164
153
|
return @resources = []
|
165
154
|
end
|
166
155
|
|
167
|
-
|
168
|
-
|
169
|
-
@query = nil
|
170
|
-
else
|
171
|
-
path = self.path
|
172
|
-
end
|
173
|
-
|
174
|
-
@response = @client.connection.send(@verb || "get", path) do |req|
|
175
|
-
opts = @options.delete_if {|k, v| v.nil?}
|
176
|
-
|
177
|
-
req.params.merge!(:include => @includes.join(",")) if @includes.any?
|
178
|
-
|
179
|
-
if %w{put post}.include?(@verb.to_s)
|
180
|
-
req.body = opts
|
181
|
-
else
|
182
|
-
req.params.merge!(opts)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
body = @response.body.dup
|
187
|
-
|
188
|
-
results = body.delete(@resource_class.model_key) || body.delete("results")
|
189
|
-
@resources = results.map {|res| @resource_class.new(@client, res)}
|
190
|
-
|
191
|
-
set_page_and_count(body)
|
192
|
-
set_includes(@resources, @includes, body)
|
156
|
+
@response = get_response(@query || self.path)
|
157
|
+
handle_response(@response.body.dup)
|
193
158
|
|
159
|
+
@query = nil
|
194
160
|
@resources
|
195
161
|
end
|
196
162
|
|
@@ -238,8 +204,7 @@ module ZendeskAPI
|
|
238
204
|
if @options["page"]
|
239
205
|
clear_cache
|
240
206
|
@options["page"] += 1
|
241
|
-
elsif @next_page
|
242
|
-
@query = @next_page
|
207
|
+
elsif @query = @next_page
|
243
208
|
fetch(true)
|
244
209
|
else
|
245
210
|
clear_cache
|
@@ -255,8 +220,7 @@ module ZendeskAPI
|
|
255
220
|
if @options["page"] && @options["page"] > 1
|
256
221
|
clear_cache
|
257
222
|
@options["page"] -= 1
|
258
|
-
elsif @prev_page
|
259
|
-
@query = @prev_page
|
223
|
+
elsif @query = @prev_page
|
260
224
|
fetch(true)
|
261
225
|
else
|
262
226
|
clear_cache
|
@@ -277,16 +241,12 @@ module ZendeskAPI
|
|
277
241
|
|
278
242
|
# Sends methods to underlying array of resources.
|
279
243
|
def method_missing(name, *args, &block)
|
280
|
-
|
281
|
-
|
282
|
-
if methods.include?(name)
|
283
|
-
@resource_class.send(name, @client, *args, &block)
|
244
|
+
if resource_methods.include?(name)
|
245
|
+
collection_method(name, *args, &block)
|
284
246
|
elsif Array.new.respond_to?(name)
|
285
|
-
|
247
|
+
array_method(name, *args, &block)
|
286
248
|
else
|
287
|
-
|
288
|
-
opts.merge!(:collection_path => @collection_path.dup.push(name))
|
289
|
-
self.class.new(@client, @resource_class, @options.merge(opts))
|
249
|
+
next_collection(name, *args, &block)
|
290
250
|
end
|
291
251
|
end
|
292
252
|
|
@@ -316,5 +276,70 @@ module ZendeskAPI
|
|
316
276
|
@options["page"] = $1.to_i + 1
|
317
277
|
end
|
318
278
|
end
|
279
|
+
|
280
|
+
## Initialize
|
281
|
+
|
282
|
+
def join_special_params
|
283
|
+
# some params use comma-joined strings instead of query-based arrays for multiple values
|
284
|
+
@options.each do |k, v|
|
285
|
+
if SPECIALLY_JOINED_PARAMS.include?(k.to_sym) && v.is_a?(Array)
|
286
|
+
@options[k] = v.join(',')
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def set_association_from_options
|
292
|
+
@collection_path = @options.delete(:collection_path)
|
293
|
+
|
294
|
+
association_options = { :path => @options.delete(:path) }
|
295
|
+
association_options[:path] ||= @collection_path.join("/") if @collection_path
|
296
|
+
@association = @options.delete(:association) || Association.new(association_options.merge(:class => @resource_class))
|
297
|
+
|
298
|
+
@collection_path ||= [@resource]
|
299
|
+
end
|
300
|
+
|
301
|
+
## Fetch
|
302
|
+
|
303
|
+
def get_response(path)
|
304
|
+
@response = @client.connection.send(@verb || "get", path) do |req|
|
305
|
+
opts = @options.delete_if {|_, v| v.nil?}
|
306
|
+
|
307
|
+
req.params.merge!(:include => @includes.join(",")) if @includes.any?
|
308
|
+
|
309
|
+
if %w{put post}.include?(@verb.to_s)
|
310
|
+
req.body = opts
|
311
|
+
else
|
312
|
+
req.params.merge!(opts)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def handle_response(body)
|
318
|
+
results = body.delete(@resource_class.model_key) || body.delete("results")
|
319
|
+
@resources = results.map {|res| @resource_class.new(@client, res)}
|
320
|
+
|
321
|
+
set_page_and_count(body)
|
322
|
+
set_includes(@resources, @includes, body)
|
323
|
+
end
|
324
|
+
|
325
|
+
## Method missing
|
326
|
+
|
327
|
+
def array_method(name, *args, &block)
|
328
|
+
to_a.send(name, *args, &block)
|
329
|
+
end
|
330
|
+
|
331
|
+
def next_collection(name, *args, &block)
|
332
|
+
opts = args.last.is_a?(Hash) ? args.last : {}
|
333
|
+
opts.merge!(:collection_path => @collection_path.dup.push(name))
|
334
|
+
self.class.new(@client, @resource_class, @options.merge(opts))
|
335
|
+
end
|
336
|
+
|
337
|
+
def collection_method(name, *args, &block)
|
338
|
+
@resource_class.send(name, @client, *args, &block)
|
339
|
+
end
|
340
|
+
|
341
|
+
def resource_methods
|
342
|
+
@resource_methods ||= @resource_class.singleton_methods(false).map(&:to_sym)
|
343
|
+
end
|
319
344
|
end
|
320
345
|
end
|