citygrid_api 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|