citygrid_api 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/citygrid_api.gemspec +3 -2
- data/lib/citygrid/api/advertising/image.rb +5 -5
- data/lib/citygrid/api.rb +119 -99
- data/lib/citygrid/citygrid_exceptions.rb +199 -0
- data/test/helper.rb +6 -6
- metadata +21 -20
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/citygrid_api.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "citygrid_api"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Elpizo Choi", "Joseph Chen"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-03-01"
|
13
13
|
s.description = "Ruby wrapper for CityGrid APIs"
|
14
14
|
s.email = "Joseph.Chen@citygridmedia.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -105,6 +105,7 @@ Gem::Specification.new do |s|
|
|
105
105
|
"lib/citygrid/api/mutable.rb",
|
106
106
|
"lib/citygrid/api/response.rb",
|
107
107
|
"lib/citygrid/api/searchable.rb",
|
108
|
+
"lib/citygrid/citygrid_exceptions.rb",
|
108
109
|
"lib/citygrid/details.rb",
|
109
110
|
"lib/citygrid/listing.rb",
|
110
111
|
"lib/citygrid/offers.rb",
|
@@ -13,11 +13,11 @@ class CityGrid
|
|
13
13
|
:body => {"mutateOperationListResource" => [
|
14
14
|
{
|
15
15
|
"operand" => {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
"imageType" => type,
|
17
|
+
"imageName" => name,
|
18
|
+
"imageFormat" => format,
|
19
|
+
"image" => image_data
|
20
|
+
},
|
21
21
|
"operator" => "ADD",
|
22
22
|
"userId" => user_id
|
23
23
|
}
|
data/lib/citygrid/api.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "httparty"
|
2
2
|
require "json"
|
3
|
+
require "citygrid/citygrid_exceptions"
|
3
4
|
|
4
5
|
class CityGrid
|
5
6
|
class API
|
6
7
|
include HTTParty
|
8
|
+
include CityGridExceptions
|
7
9
|
#debug_output $stderr
|
8
10
|
|
9
11
|
DEFAULT_HEADERS = {
|
@@ -83,128 +85,146 @@ class CityGrid
|
|
83
85
|
"options" => Net::HTTP::Options
|
84
86
|
}
|
85
87
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
Rails.logger.info req.to_curl
|
110
|
-
else
|
111
|
-
puts req.to_curl
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
if !response.parsed_response.is_a?(Hash)
|
116
|
-
raise ResponseParseError.new req, response
|
117
|
-
elsif response["errors"]
|
118
|
-
raise ResponseError.new req, response["errors"], response
|
119
|
-
elsif response["message"] && response["message"] == "Invalid Token or Expired"
|
120
|
-
raise InvalidAuthToken.new
|
88
|
+
def strip_unsafe_params options
|
89
|
+
puts "OPTIONS: #{options}"
|
90
|
+
unsafe_params = {
|
91
|
+
:password => "[FILTERED]", :securityCode => "[FILTERED]",
|
92
|
+
:cardNumber => "[FILTERED]", :expirationMonth => "[FILTERED]",
|
93
|
+
:expirationYear => "[FILTERED]"
|
94
|
+
}
|
95
|
+
if !options[:query].nil?
|
96
|
+
to_merge[:query] = options[:query].merge(unsafe_params.select { |k| options.keys.include? k })
|
97
|
+
return options.merge(to_merge)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
def parse_multiple_responses response
|
103
|
+
parsing = response.values.select{ |x| x.is_a? Array }.first
|
104
|
+
if parsing.nil? || parsing == []
|
105
|
+
ap "Response was too hard to parse... letting it through..."
|
106
|
+
return parsing
|
107
|
+
elsif parsing != nil && parsing != []
|
108
|
+
if parsing[0]["response"]
|
109
|
+
parsing = [parsing[0]["response"]["code"], parsing[0]["response"]["message"]]
|
110
|
+
return parsing
|
121
111
|
else
|
122
|
-
|
112
|
+
# this accomodates geocode response which does not contain a response node
|
113
|
+
ap "Response was too hard to parse... letting it through..."
|
114
|
+
return nil
|
123
115
|
end
|
124
|
-
|
125
|
-
|
126
|
-
raise
|
116
|
+
else
|
117
|
+
# We should figure out a better way to do this
|
118
|
+
raise CityGridExceptions::APIError.new "Received a JSON error code but it could not be parsed: #{response}"
|
127
119
|
end
|
128
120
|
end
|
129
121
|
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
122
|
+
# Transform response into API::Response object
|
123
|
+
# or throw exception if an error exists
|
124
|
+
def request_and_handle http_method, path, options
|
125
|
+
if http_method.is_a?(String) || http_method.is_a?(Symbol)
|
126
|
+
http_method = HTTP_METHODS[http_method.to_s]
|
127
|
+
raise "Unknown http method: #{http_method}" unless http_method
|
136
128
|
end
|
137
|
-
end
|
138
129
|
|
139
|
-
|
140
|
-
|
130
|
+
req_options = default_options.dup
|
131
|
+
req_options = req_options.merge(options)
|
141
132
|
|
142
|
-
|
143
|
-
|
144
|
-
self.response = response
|
145
|
-
|
146
|
-
super "API returned error message", request
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
class RequestError < APIError
|
151
|
-
attr_accessor :inner_exception
|
133
|
+
raise ConfigurationError.new "No endpoint defined" if !path || path.empty?
|
134
|
+
raise ConfigurationError.new "No hostname defined" if !req_options[:base_uri] || req_options[:base_uri].empty?
|
152
135
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
136
|
+
# prepare request and sanitized request for logs
|
137
|
+
#puts "Options after strip unsafe: #{strip_unsafe_params(req_options)}"
|
138
|
+
#puts "options before that: #{req_options}"
|
139
|
+
#safe_req_options = strip_unsafe_params(req_options)
|
140
|
+
req = HTTParty::Request.new http_method, path, req_options
|
141
|
+
#req_to_output = HTTParty::Request.new http_method, path, safe_req_options
|
142
|
+
# ap "HERE ARE THE INGREDIENTS OF THE REQUEST:"
|
143
|
+
# ap "http_method is: #{http_method}"
|
144
|
+
# ap "path is: #{path}"
|
145
|
+
# ap "req_options is: #{req_options}"
|
146
|
+
|
147
|
+
begin
|
148
|
+
response = req.perform
|
149
|
+
rescue => ex
|
150
|
+
raise CityGridExceptions::RequestError.new req, ex
|
151
|
+
ensure
|
152
|
+
if defined?(Rails.logger)
|
153
|
+
Rails.logger.info req.to_curl
|
154
|
+
else
|
155
|
+
puts req.to_curl
|
156
|
+
ap response
|
157
|
+
end
|
157
158
|
end
|
158
|
-
end
|
159
|
-
|
160
|
-
class ResponseParseError < APIError
|
161
|
-
attr_accessor :server_msg, :description, :raw_response
|
162
|
-
def initialize request, response
|
163
|
-
self.raw_response = response
|
164
|
-
# parse Tomcat error report
|
165
|
-
if response.match /<title>Apache Tomcat.* - Error report<\/title>/
|
166
|
-
response.scan(/<p><b>(message|description)<\/b> *<u>(.*?)<\/u><\/p>/).each do |match|
|
167
|
-
case match[0]
|
168
|
-
when "message"
|
169
|
-
self.server_msg = match[1]
|
170
|
-
when "description"
|
171
|
-
self.description = match[1]
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
error_body = response.match(/<body>(.*?)<\/body>/m)[1]
|
176
|
-
|
177
|
-
msg = <<-EOS
|
178
|
-
Unexpected response format. Expected response to be a hash, but was instead:\n#{error_body}\n
|
179
|
-
EOS
|
180
159
|
|
181
|
-
|
160
|
+
begin
|
161
|
+
# catch unparsable responses (html etc)
|
162
|
+
if !response.parsed_response.is_a?(Hash)
|
163
|
+
ap "[gem] the response was unparsable (response was not a hash)"
|
164
|
+
raise CityGridExceptions::ResponseParseError.new req, response
|
165
|
+
# catch responses not in new response format
|
166
|
+
elsif response["errors"]
|
167
|
+
ap "[gem] An error in the old response format was caught. Raising a general response error..."
|
168
|
+
raise CityGridExceptions::ResponseError.new req, response["errors"], response
|
169
|
+
|
170
|
+
# Parse and handle new response codes
|
171
|
+
elsif (response["response"] && response["response"]["code"] != "SUCCESS") &&
|
172
|
+
(response["response"] && response["response"]["code"] != 200) &&
|
173
|
+
(response["response"] && response["response"]["code"] != 400)
|
174
|
+
error_code = response["response"]["code"]
|
175
|
+
ap "[gem] The response was contained in the first level of the response hash. Below:"
|
176
|
+
ap response
|
177
|
+
ap "found error code: #{error_code}"
|
178
|
+
ap "****************************************************************************"
|
179
|
+
raise CityGridExceptions.appropriate_error(error_code).new req, response, response["response"]["message"].to_s #+ " " + CityGridExceptions.print_superclasses(error_code)
|
180
|
+
# if the response is a nested hash/nested hash containing arrays
|
181
|
+
elsif response["totalNumEntries"] && response["response"].nil?
|
182
|
+
ap "[gem] now parsing a response with multiple entries: #{response}"
|
183
|
+
error_code = parse_multiple_responses(response)
|
184
|
+
ap "the error code that came back is #{error_code}"
|
185
|
+
if error_code.nil? || error_code == []
|
186
|
+
ap "[gem] passing over this for now"
|
187
|
+
return CityGrid::API::Response.new response # pass over for now
|
188
|
+
elsif error_code[0] == "SUCCESS" || error_code[0] == 200 || error_code[0] == 400
|
189
|
+
return CityGrid::API::Response.new response
|
190
|
+
else
|
191
|
+
ap "[gem] we found an error and it was #{error_code[1]}"
|
192
|
+
raise CityGridExceptions.appropriate_error(error_code[0]).new req, response, error_code[1].to_s + " "# + CityGridExceptions.print_superclasses(error_code[0])
|
193
|
+
end
|
182
194
|
else
|
183
|
-
|
184
|
-
Unexpected response format. Expected response to be a hash, but was instead:\n#{response.parsed_response}\n
|
185
|
-
EOS
|
186
|
-
|
187
|
-
super msg, request
|
195
|
+
return CityGrid::API::Response.new response
|
188
196
|
end
|
197
|
+
rescue => ex
|
198
|
+
ap "The gem threw an error: #{ex}"
|
199
|
+
raise ex if CityGrid.raise_errors?
|
189
200
|
end
|
190
201
|
end
|
191
202
|
|
192
|
-
|
193
|
-
def initialize message = "Invalid Token or Expired"
|
194
|
-
super message
|
195
|
-
end
|
196
|
-
end
|
203
|
+
# Errors
|
197
204
|
|
198
|
-
class
|
199
|
-
def initialize
|
200
|
-
super
|
205
|
+
class MUSHPendingChanges <StandardError
|
206
|
+
def initialize message = "The are currently pending changes in the mush. Cannot update."
|
207
|
+
super message
|
201
208
|
end
|
202
209
|
end
|
203
210
|
|
211
|
+
# class InvalidAuthToken < StandardError
|
212
|
+
# def initialize message = "Invalid Token or Expired"
|
213
|
+
# super message
|
214
|
+
# end
|
215
|
+
# end
|
216
|
+
|
217
|
+
# class MissingAuthToken < StandardError
|
218
|
+
# def initialize
|
219
|
+
# super "Missing authToken - token is required"
|
220
|
+
# end
|
221
|
+
# end
|
222
|
+
|
204
223
|
class ConfigurationError < StandardError
|
205
224
|
def initialize message = "Invalid Configuration"
|
206
225
|
super message
|
207
226
|
end
|
208
227
|
end
|
209
228
|
end
|
210
|
-
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
module CityGridExceptions
|
2
|
+
|
3
|
+
# Define parent error classes
|
4
|
+
# All errors thrown in the API should extend APIError - Level 1
|
5
|
+
class APIError < StandardError
|
6
|
+
attr_accessor :request
|
7
|
+
|
8
|
+
def initialize request, response, msg = "An API error occurred"
|
9
|
+
super msg
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Level 2 - These represent three different error scenarios:
|
14
|
+
# 1. Response is totally not parsable to JSON
|
15
|
+
# 2. The API call/parameters were malformed
|
16
|
+
# 3. The request was fine but their was an error API side
|
17
|
+
|
18
|
+
class ResponseParseError < APIError
|
19
|
+
attr_accessor :server_msg, :description, :raw_response
|
20
|
+
def initialize request, response, msg = nil
|
21
|
+
self.raw_response = response
|
22
|
+
# parse Tomcat error report
|
23
|
+
if response.match /<title>Apache Tomcat.* - Error report<\/title>/
|
24
|
+
response.scan(/<p><b>(message|description)<\/b> *<u>(.*?)<\/u><\/p>/).each do |match|
|
25
|
+
case match[0]
|
26
|
+
when "message"
|
27
|
+
self.server_msg = match[1]
|
28
|
+
when "description"
|
29
|
+
self.description = match[1]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
error_body = response.match(/<body>(.*?)<\/body>/m)[1]
|
34
|
+
|
35
|
+
msg = <<-EOS
|
36
|
+
Unexpected response format. Expected response to be a hash, but was instead:\n#{error_body}\n
|
37
|
+
EOS
|
38
|
+
|
39
|
+
super msg, request
|
40
|
+
else
|
41
|
+
msg = <<-EOS
|
42
|
+
Unexpected response format. Expected response to be a hash, but was instead:\n#{response.parsed_response}\n
|
43
|
+
EOS
|
44
|
+
|
45
|
+
super msg, request
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class RequestError < APIError
|
51
|
+
attr_accessor :inner_exception
|
52
|
+
|
53
|
+
def initialize request, response, msg = nil
|
54
|
+
self.inner_exception = inner_exception
|
55
|
+
self.request = request
|
56
|
+
super msg, request
|
57
|
+
#super msg || "Error while performing request: #{inner_exception.message}", request
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class ResponseError < APIError
|
62
|
+
attr_accessor :errors, :response
|
63
|
+
|
64
|
+
def initialize request, errors, response
|
65
|
+
self.errors = errors
|
66
|
+
self.response = response
|
67
|
+
|
68
|
+
super "API returned error message", request
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Level 3
|
73
|
+
class GeneralError < APIError; end
|
74
|
+
class HeaderError < APIError; end
|
75
|
+
class AuthenticationError < APIError; end
|
76
|
+
class AuthorizationError < APIError; end
|
77
|
+
class OperatorError < RequestError; end
|
78
|
+
class GeneralDataError < APIError; end
|
79
|
+
class SpecificDataError < APIError; end
|
80
|
+
|
81
|
+
# Level 4
|
82
|
+
|
83
|
+
# General Errors
|
84
|
+
class SystemErrorTryAgainError < GeneralError; end
|
85
|
+
class SystemErrorUnknownError < GeneralError; end
|
86
|
+
class BadRequestTypeError < GeneralError; end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
# HeaderErrors < RequestError
|
91
|
+
class ContentTypeRequiredError < HeaderError; end
|
92
|
+
class ContentTypeInvalidError < HeaderError; end
|
93
|
+
class AcceptRequiredError < HeaderError; end
|
94
|
+
class AcceptInvalidError < HeaderError; end
|
95
|
+
|
96
|
+
# Authentication Error
|
97
|
+
class AuthTokenInvalidError < AuthenticationError; end
|
98
|
+
class AuthTokenExpiredError < AuthenticationError; end
|
99
|
+
class AuthTokenNoneError < AuthenticationError; end
|
100
|
+
class UsernameRequiredError < AuthenticationError; end
|
101
|
+
class PasswordRequiredError < AuthenticationError; end
|
102
|
+
class AccountNotFoundError < AuthenticationError; end
|
103
|
+
|
104
|
+
#Authorization Error
|
105
|
+
class PermissionDeniedError < AuthorizationError; end
|
106
|
+
class NoPermissionsError < AuthorizationError; end
|
107
|
+
|
108
|
+
# Request Error
|
109
|
+
class ParameterRequiredError < RequestError; end
|
110
|
+
class ParameterRequiredConditionalError < RequestError; end
|
111
|
+
class ParameterInvalidError < RequestError; end
|
112
|
+
class ParameterFormatError < RequestError; end
|
113
|
+
class ParameterNotSupportedError < RequestError; end
|
114
|
+
class ParameterRangeTooLowError < RequestError; end
|
115
|
+
class ParameterRangeTooHighError < RequestError; end
|
116
|
+
class ParameterSizeLimitExceededError < RequestError; end
|
117
|
+
class ParameterCannotBeZeroError < RequestError; end
|
118
|
+
class ParameterOnlyOne < RequestError; end
|
119
|
+
|
120
|
+
# Operator Error
|
121
|
+
class OperatorInvalidError < OperatorError; end
|
122
|
+
|
123
|
+
# General Data Errors
|
124
|
+
class EntityNotFoundError < GeneralDataError; end
|
125
|
+
class EntityExistsError < GeneralDataError; end
|
126
|
+
class EntityLimitError < GeneralDataError; end
|
127
|
+
class EntityAlreadyInUseError < GeneralDataError; end
|
128
|
+
class EntityExpiredError < GeneralDataError; end
|
129
|
+
class EntityInactiveError < GeneralDataError; end
|
130
|
+
class EntityNotEligibleError < GeneralDataError; end
|
131
|
+
class EntityNotModifiedError < GeneralDataError; end
|
132
|
+
class EntityStateInvalidError < GeneralDataError; end
|
133
|
+
class EntityMissingDataError < GeneralDataError; end
|
134
|
+
class DataNotFoundError < GeneralDataError; end
|
135
|
+
class AssociationExistsError < GeneralDataError; end
|
136
|
+
class NoAssociationExistsError < GeneralDataError; end
|
137
|
+
class DuplicateError < GeneralDataError; end
|
138
|
+
class DateBeforeDateError < GeneralDataError; end
|
139
|
+
class RemoveNotAllowedError < GeneralDataError; end
|
140
|
+
|
141
|
+
#data errors - specific
|
142
|
+
class MopExpiredError < SpecificDataError; end
|
143
|
+
class AccountInactiveError < SpecificDataError; end
|
144
|
+
class AccountDelinquentError < SpecificDataError; end
|
145
|
+
class MonthlyBudgetReachedError < SpecificDataError; end
|
146
|
+
class QuotaExceededError < SpecificDataError; end
|
147
|
+
class RateExceededError < SpecificDataError; end
|
148
|
+
|
149
|
+
# unused errors
|
150
|
+
#400 => RequestError,
|
151
|
+
@possible_errors =
|
152
|
+
{
|
153
|
+
0 => ResponseError, nil => ResponseParseError, "" => ResponseParseError,
|
154
|
+
401 => AuthenticationError, 403 => RequestError, 405 => RequestError, 406 => HeaderError,
|
155
|
+
500 => ResponseError, "SYSTEM_ERROR_TRY_AGAIN" => SystemErrorTryAgainError,
|
156
|
+
"SYSTEM_ERROR_UNKNOWN" => SystemErrorUnknownError, "BAD_REQUEST_TYPE" => BadRequestTypeError,
|
157
|
+
"HEADER_CONTENT_TYPE_IS_REQUIRED" => ContentTypeRequiredError, "HEADER_CONTENT_TYPE_INVALID" => ContentTypeInvalidError,
|
158
|
+
"HEADER_ACCEPT_IS_REQUIRED" => AcceptRequiredError, "HEADER_ACCEPT_INVALID" => AcceptInvalidError,
|
159
|
+
"AUTH_TOKEN_INVALID" => AuthTokenInvalidError, "AUTH_TOKEN_EXPIRED" => AuthTokenExpiredError,
|
160
|
+
"AUTH_TOKEN_NONE" => AuthTokenNoneError,
|
161
|
+
"USERNAME_IS_REQUIRED" => UsernameRequiredError, "PASSWORD_IS_REQUIRED" => PasswordRequiredError,
|
162
|
+
"ACCOUNT_NOT_FOUND" => AccountNotFoundError, "PERMISSION_DENIED" => PermissionDeniedError,
|
163
|
+
"NO_PERMISSIONS" => NoPermissionsError, "PARAMETER_REQUIRED" => ParameterRequiredError,
|
164
|
+
"PARAMETER_REQUIRED_CONDITIONAL" => ParameterRequiredConditionalError, "PARAMETER_INVALID" => ParameterInvalidError,
|
165
|
+
"PARAMETER_FORMAT" => ParameterFormatError, "PARAMETER_NOT_SUPPORTED" => ParameterNotSupportedError,
|
166
|
+
"PARAMETER_RANGE_TOO_LOW" => ParameterRangeTooLowError, "PARAMETER_RANGE_TOO_HIGH" => ParameterRangeTooHighError,
|
167
|
+
"PARAMETER_SIZE_LIMIT_EXCEEDED" => ParameterSizeLimitExceededError, "PARAMETER_CANNOT_BE_ZERO" => ParameterCannotBeZeroError,
|
168
|
+
"PARAMETER_ONLY_ONE" => ParameterOnlyOne, "OPERATOR_INVALID" => OperatorInvalidError,
|
169
|
+
"ENTITY_NOT_FOUND" => EntityNotFoundError, "ENTITY_EXISTS" => EntityExistsError,
|
170
|
+
"ENTITY_LIMIT" => EntityLimitError, "ENTITY_ALREADY_IN_USE" => EntityAlreadyInUseError,
|
171
|
+
"ENTITY_EXPIRED" => EntityExpiredError, "ENTITY_INACTIVE" => EntityInactiveError,
|
172
|
+
"ENTITY_NOT_ELIGIBLE" => EntityNotEligibleError, "ENTITY_NOT_MODIFIED" => EntityNotModifiedError,
|
173
|
+
"ENTITY_STATE_INVALID" => EntityStateInvalidError, "ENTITY_MISSING_DATA" => EntityMissingDataError,
|
174
|
+
"DATA_NOT_FOUND" => DataNotFoundError, "ASSOCIATION_EXISTS" => AssociationExistsError,
|
175
|
+
"NO_ASSOCIATION_EXISTS" => NoAssociationExistsError, "DUPLICATE" => DuplicateError,
|
176
|
+
"DATE_BEFORE_DATE" => DateBeforeDateError, "REMOVE_NOT_ALLOWED" => RemoveNotAllowedError,
|
177
|
+
"MOP_EXPIRED" => MopExpiredError, "ACCOUNT_INACTIVE" => AccountInactiveError,
|
178
|
+
"ACCOUNT_DELINQUENT" => AccountDelinquentError, "MONTHLY_BUDGET_REACHED" => MonthlyBudgetReachedError,
|
179
|
+
"QUOTA_EXCEEDED" => QuotaExceededError,"RATE_EXCEEDED" => RateExceededError
|
180
|
+
}
|
181
|
+
|
182
|
+
def CityGridExceptions.appropriate_error error_code
|
183
|
+
if @possible_errors.include?(error_code)
|
184
|
+
return @possible_errors[error_code]
|
185
|
+
else
|
186
|
+
return APIError
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def CityGridExceptions.print_superclasses error_code
|
191
|
+
begin
|
192
|
+
raise appropriate_error[error_code]
|
193
|
+
rescue => ex
|
194
|
+
class_hierarchy = ex.class.ancestors
|
195
|
+
class_hierarchy.slice!(class_hierarchy.index(StandardError)..-1)
|
196
|
+
return class_hierarchy.reverse.join("::")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
data/test/helper.rb
CHANGED
@@ -22,9 +22,9 @@ unless defined? IN_DASHBOARD
|
|
22
22
|
|
23
23
|
# load default config
|
24
24
|
CityGrid.load_config File.expand_path(File.join(File.dirname(__FILE__), '..', 'citygrid_api.yml.sample'))
|
25
|
-
|
25
|
+
|
26
26
|
# CityGrid.load_config File.expand_path(File.join(File.dirname(__FILE__), '..', 'citygrid_api.yml.sandbox'))
|
27
|
-
|
27
|
+
|
28
28
|
# Run code with rescue so that exceptions
|
29
29
|
# will be printed, but won't stop test suite
|
30
30
|
def run_with_rescue
|
@@ -45,10 +45,10 @@ unless defined? IN_DASHBOARD
|
|
45
45
|
false # return false
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
# patch in VCR
|
50
50
|
require 'vcr'
|
51
|
-
|
51
|
+
|
52
52
|
VCR.config do |c|
|
53
53
|
c.cassette_library_dir = 'fixtures/vcr_cassettes'
|
54
54
|
c.stub_with :webmock
|
@@ -69,8 +69,8 @@ unless defined? IN_DASHBOARD
|
|
69
69
|
# end
|
70
70
|
# end
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
end
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: citygrid_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-03-01 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: httparty
|
17
|
-
requirement: &
|
17
|
+
requirement: &70321245070140 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 0.8.1
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70321245070140
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: json
|
28
|
-
requirement: &
|
28
|
+
requirement: &70321245069540 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - =
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 1.5.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70321245069540
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: riot
|
39
|
-
requirement: &
|
39
|
+
requirement: &70321245068820 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 0.12.4
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70321245068820
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: awesome_print
|
50
|
-
requirement: &
|
50
|
+
requirement: &70321245068080 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: 0.4.0
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70321245068080
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: bundler
|
61
|
-
requirement: &
|
61
|
+
requirement: &70321245067160 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ~>
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: 1.0.0
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *70321245067160
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: jeweler
|
72
|
-
requirement: &
|
72
|
+
requirement: &70321245063220 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: 1.6.2
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *70321245063220
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: rcov
|
83
|
-
requirement: &
|
83
|
+
requirement: &70321245062700 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ! '>='
|
@@ -88,10 +88,10 @@ dependencies:
|
|
88
88
|
version: '0'
|
89
89
|
type: :development
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *70321245062700
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: vcr
|
94
|
-
requirement: &
|
94
|
+
requirement: &70321245061660 !ruby/object:Gem::Requirement
|
95
95
|
none: false
|
96
96
|
requirements:
|
97
97
|
- - ! '>='
|
@@ -99,10 +99,10 @@ dependencies:
|
|
99
99
|
version: '0'
|
100
100
|
type: :development
|
101
101
|
prerelease: false
|
102
|
-
version_requirements: *
|
102
|
+
version_requirements: *70321245061660
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: webmock
|
105
|
-
requirement: &
|
105
|
+
requirement: &70321245059820 !ruby/object:Gem::Requirement
|
106
106
|
none: false
|
107
107
|
requirements:
|
108
108
|
- - ! '>='
|
@@ -110,7 +110,7 @@ dependencies:
|
|
110
110
|
version: '0'
|
111
111
|
type: :development
|
112
112
|
prerelease: false
|
113
|
-
version_requirements: *
|
113
|
+
version_requirements: *70321245059820
|
114
114
|
description: Ruby wrapper for CityGrid APIs
|
115
115
|
email: Joseph.Chen@citygridmedia.com
|
116
116
|
executables: []
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- lib/citygrid/api/mutable.rb
|
208
208
|
- lib/citygrid/api/response.rb
|
209
209
|
- lib/citygrid/api/searchable.rb
|
210
|
+
- lib/citygrid/citygrid_exceptions.rb
|
210
211
|
- lib/citygrid/details.rb
|
211
212
|
- lib/citygrid/listing.rb
|
212
213
|
- lib/citygrid/offers.rb
|