cdek_client 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +418 -0
- data/Rakefile +2 -0
- data/cdek_client.gemspec +25 -0
- data/lib/cdek_client.rb +153 -0
- data/lib/cdek_client/abstract_client.rb +120 -0
- data/lib/cdek_client/calculator_client.rb +68 -0
- data/lib/cdek_client/calculator_errors.rb +73 -0
- data/lib/cdek_client/client.rb +256 -0
- data/lib/cdek_client/errors.rb +386 -0
- data/lib/cdek_client/result.rb +22 -0
- data/lib/cdek_client/util.rb +125 -0
- data/lib/cdek_client/version.rb +3 -0
- metadata +101 -0
@@ -0,0 +1,386 @@
|
|
1
|
+
module CdekClient
|
2
|
+
|
3
|
+
class Error < StandardError
|
4
|
+
|
5
|
+
attr_reader :code, :message
|
6
|
+
|
7
|
+
def initialize(code, message)
|
8
|
+
@code = code
|
9
|
+
@message = message
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
class ResponseError < Error; end
|
15
|
+
|
16
|
+
class APIError < Error; end
|
17
|
+
|
18
|
+
class UnkownAPIError < APIError; end
|
19
|
+
|
20
|
+
class AttributeEmptyError < APIError; end
|
21
|
+
|
22
|
+
class AuthError < APIError; end
|
23
|
+
|
24
|
+
class BarcodeDublError < APIError; end
|
25
|
+
|
26
|
+
class CallcourierCityError < APIError; end
|
27
|
+
|
28
|
+
class CallcourierCountError < APIError; end
|
29
|
+
|
30
|
+
class CallcourierDatetimeError < APIError; end
|
31
|
+
|
32
|
+
class CallcourierDateDublError < APIError; end
|
33
|
+
|
34
|
+
class CallcourierDateExistsError < APIError; end
|
35
|
+
|
36
|
+
class CallcourierTimeError < APIError; end
|
37
|
+
|
38
|
+
class CallcourierTimelunchError < APIError; end
|
39
|
+
|
40
|
+
class CallcourierTimeIntervalError < APIError; end
|
41
|
+
|
42
|
+
class CallDublError < APIError; end
|
43
|
+
|
44
|
+
class CashLimitError < APIError; end
|
45
|
+
|
46
|
+
class CashNoError < APIError; end
|
47
|
+
|
48
|
+
class DatabaseError < APIError; end
|
49
|
+
|
50
|
+
class DatabaseTestError < APIError; end
|
51
|
+
|
52
|
+
class DateformatError < APIError; end
|
53
|
+
|
54
|
+
class DateinvoiceError < APIError; end
|
55
|
+
|
56
|
+
class DboAuthError < APIError; end
|
57
|
+
|
58
|
+
class DboAuthHashError < APIError; end
|
59
|
+
|
60
|
+
class DboCityIncorrectForServiceError < APIError; end
|
61
|
+
|
62
|
+
class DboClientCurrencyError < APIError; end
|
63
|
+
|
64
|
+
class DboDateCreateInvalidError < APIError; end
|
65
|
+
|
66
|
+
class DboForbiddenSumForCashError < APIError; end
|
67
|
+
|
68
|
+
class DboIncorrectUrlError < APIError; end
|
69
|
+
|
70
|
+
class DboInvalidAdditionalserviceError < APIError; end
|
71
|
+
|
72
|
+
class DboNeedAuthError < APIError; end
|
73
|
+
|
74
|
+
class DboNotFoundError < APIError; end
|
75
|
+
|
76
|
+
class DboPackageNumberEmptyError < APIError; end
|
77
|
+
|
78
|
+
class DboParamEmptyError < APIError; end
|
79
|
+
|
80
|
+
class DboParamMistakeError < APIError; end
|
81
|
+
|
82
|
+
class DboParamMistakePvzError < APIError; end
|
83
|
+
|
84
|
+
class DboParamServiceInterfaceError < APIError; end
|
85
|
+
|
86
|
+
class DboPayerEmptyError < APIError; end
|
87
|
+
|
88
|
+
class DboReceiverAddressTitleEmptyError < APIError; end
|
89
|
+
|
90
|
+
class DboReceiverCityAmbiguousError < APIError; end
|
91
|
+
|
92
|
+
class DboReceiverCityEmptyError < APIError; end
|
93
|
+
|
94
|
+
class DboReceiverCityIncorrectError < APIError; end
|
95
|
+
|
96
|
+
class DboReceiverCityNotIntegerError < APIError; end
|
97
|
+
|
98
|
+
class DboResultEmptyError < APIError; end
|
99
|
+
|
100
|
+
class DboResultServiceEmptyError < APIError; end
|
101
|
+
|
102
|
+
class DboSenderAddressTitleEmptyError < APIError; end
|
103
|
+
|
104
|
+
class DboSenderCityAmbiguousError < APIError; end
|
105
|
+
|
106
|
+
class DboSenderCityEmptyError < APIError; end
|
107
|
+
|
108
|
+
class DboSenderCityIncorrectError < APIError; end
|
109
|
+
|
110
|
+
class DboSenderCityNotIntegerError < APIError; end
|
111
|
+
|
112
|
+
class DboServiceEmptyError < APIError; end
|
113
|
+
|
114
|
+
class DboTypeEmptyError < APIError; end
|
115
|
+
|
116
|
+
class DboWeightEmptyError < APIError; end
|
117
|
+
|
118
|
+
class DeleterequestOrderError < APIError; end
|
119
|
+
|
120
|
+
class DeleterequestOrderActnumberError < APIError; end
|
121
|
+
|
122
|
+
class DeleterequestOrderDeletedError < APIError; end
|
123
|
+
|
124
|
+
class DeleterequestOrderMoveError < APIError; end
|
125
|
+
|
126
|
+
class FileNotexistsError < APIError; end
|
127
|
+
|
128
|
+
class FileSaveError < APIError; end
|
129
|
+
|
130
|
+
class FirstDublExistsError < APIError; end
|
131
|
+
|
132
|
+
class InforequestError < APIError; end
|
133
|
+
|
134
|
+
class InforequestDatebegError < APIError; end
|
135
|
+
|
136
|
+
class InvalidAddressDeliveryError < APIError; end
|
137
|
+
|
138
|
+
class InvalidAmountError < APIError; end
|
139
|
+
|
140
|
+
class InvalidCostError < APIError; end
|
141
|
+
|
142
|
+
class InvalidCostexError < APIError; end
|
143
|
+
|
144
|
+
class InvalidDeliveryrecipientcostError < APIError; end
|
145
|
+
|
146
|
+
class InvalidDispachnumberError < APIError; end
|
147
|
+
|
148
|
+
class InvalidIntakeserviceError < APIError; end
|
149
|
+
|
150
|
+
class InvalidIntakeserviceTocityError < APIError; end
|
151
|
+
|
152
|
+
class InvalidNumberError < APIError; end
|
153
|
+
|
154
|
+
class InvalidNumberDeleteError < APIError; end
|
155
|
+
|
156
|
+
class InvalidPaymentError < APIError; end
|
157
|
+
|
158
|
+
class InvalidPaymentexError < APIError; end
|
159
|
+
|
160
|
+
class InvalidServicecodeError < APIError; end
|
161
|
+
|
162
|
+
class InvalidSizeError < APIError; end
|
163
|
+
|
164
|
+
class InvalidTarifftypecodeError < APIError; end
|
165
|
+
|
166
|
+
class InvalidWeightError < APIError; end
|
167
|
+
|
168
|
+
class InvalidXmlError < APIError; end
|
169
|
+
|
170
|
+
class ItemNotfindError < APIError; end
|
171
|
+
|
172
|
+
class NeedAttributeError < APIError; end
|
173
|
+
|
174
|
+
class NotfoundcurrencyError < APIError; end
|
175
|
+
|
176
|
+
class NotfoundtagError < APIError; end
|
177
|
+
|
178
|
+
class NotEqualCallcountError < APIError; end
|
179
|
+
|
180
|
+
class NotEqualOrdercountError < APIError; end
|
181
|
+
|
182
|
+
class NotFoundCostexError < APIError; end
|
183
|
+
|
184
|
+
class NotFoundPassportnumberError < APIError; end
|
185
|
+
|
186
|
+
class NotFoundPaymentexError < APIError; end
|
187
|
+
|
188
|
+
class NotFoundReccityError < APIError; end
|
189
|
+
|
190
|
+
class NotFoundRegistrationaddressError < APIError; end
|
191
|
+
|
192
|
+
class NotFoundSendcityError < APIError; end
|
193
|
+
|
194
|
+
class NotFoundTarifftypecodeError < APIError; end
|
195
|
+
|
196
|
+
class NotValidPassportnumberError < APIError; end
|
197
|
+
|
198
|
+
class OrderCountError < APIError; end
|
199
|
+
|
200
|
+
class OrderDeleteError < APIError; end
|
201
|
+
|
202
|
+
class OrderDublError < APIError; end
|
203
|
+
|
204
|
+
class OrderDublExistsError < APIError; end
|
205
|
+
|
206
|
+
class OrderNotfindError < APIError; end
|
207
|
+
|
208
|
+
class OrdersNotFoundError < APIError; end
|
209
|
+
|
210
|
+
class PackageNotfindError < APIError; end
|
211
|
+
|
212
|
+
class PackageNumDublError < APIError; end
|
213
|
+
|
214
|
+
class PrintOrderError < APIError; end
|
215
|
+
|
216
|
+
class PvzcodeError < APIError; end
|
217
|
+
|
218
|
+
class PvzcodeNotfoundError < APIError; end
|
219
|
+
|
220
|
+
class PvzClosedError < APIError; end
|
221
|
+
|
222
|
+
class PvzNotfoundError < APIError; end
|
223
|
+
|
224
|
+
class PvzNotfoundByPostcodeError < APIError; end
|
225
|
+
|
226
|
+
class PvzWeightError < APIError; end
|
227
|
+
|
228
|
+
class PvzWeightLimitError < APIError; end
|
229
|
+
|
230
|
+
class ReccitycodeError < APIError; end
|
231
|
+
|
232
|
+
class ReccitypostcodeError < APIError; end
|
233
|
+
|
234
|
+
class ReccitypostcodeDublError < APIError; end
|
235
|
+
|
236
|
+
class ScheduleChangeError < APIError; end
|
237
|
+
|
238
|
+
class ScheduleDateError < APIError; end
|
239
|
+
|
240
|
+
class ScheduleDublError < APIError; end
|
241
|
+
|
242
|
+
class SendcitycodeError < APIError; end
|
243
|
+
|
244
|
+
class SendcitypostcodeError < APIError; end
|
245
|
+
|
246
|
+
class SendcitypostcodeDublError < APIError; end
|
247
|
+
|
248
|
+
class UnknownDocTypeError < APIError; end
|
249
|
+
|
250
|
+
class UnknownVersionError < APIError; end
|
251
|
+
|
252
|
+
class WarekeyDublError < APIError; end
|
253
|
+
|
254
|
+
class WeightLimitError < APIError; end
|
255
|
+
|
256
|
+
class XmlEmptyError < APIError; end
|
257
|
+
|
258
|
+
def get_api_error(code, message)
|
259
|
+
klass = API_ERROR_MAPPINGS[code.to_sym] || UnkownAPIError
|
260
|
+
klass.new code, message
|
261
|
+
end
|
262
|
+
|
263
|
+
API_ERROR_MAPPINGS = {
|
264
|
+
ERR_API: APIError,
|
265
|
+
ERR_ATTRIBUTE_EMPTY: AttributeEmptyError,
|
266
|
+
ERR_AUTH: AuthError,
|
267
|
+
ERR_BARCODE_DUBL: BarcodeDublError,
|
268
|
+
ERR_CALLCOURIER_CITY: CallcourierCityError,
|
269
|
+
ERR_CALLCOURIER_COUNT: CallcourierCountError,
|
270
|
+
ERR_CALLCOURIER_DATETIME: CallcourierDatetimeError,
|
271
|
+
ERR_CALLCOURIER_DATE_DUBL: CallcourierDateDublError,
|
272
|
+
ERR_CALLCOURIER_DATE_EXISTS: CallcourierDateExistsError,
|
273
|
+
ERR_CALLCOURIER_TIME: CallcourierTimeError,
|
274
|
+
ERR_CALLCOURIER_TIMELUNCH: CallcourierTimelunchError,
|
275
|
+
ERR_CALLCOURIER_TIME_INTERVAL: CallcourierTimeIntervalError,
|
276
|
+
ERR_CALL_DUBL: CallDublError,
|
277
|
+
ERR_CASH_LIMIT: CashLimitError,
|
278
|
+
ERR_CASH_NO: CashNoError,
|
279
|
+
ERR_DATABASE: DatabaseError,
|
280
|
+
ERR_DATABASE_test: DatabaseTestError,
|
281
|
+
ERR_DATEFORMAT: DateformatError,
|
282
|
+
ERR_DATEINVOICE: DateinvoiceError,
|
283
|
+
ERR_DBO_AUTH: DboAuthError,
|
284
|
+
ERR_DBO_AUTH_HASH: DboAuthHashError,
|
285
|
+
ERR_DBO_CITY_INCORRECT_FOR_SERVICE: DboCityIncorrectForServiceError,
|
286
|
+
ERR_DBO_CLIENT_CURRENCY: DboClientCurrencyError,
|
287
|
+
ERR_DBO_DATE_CREATE_INVALID: DboDateCreateInvalidError,
|
288
|
+
ERR_DBO_FORBIDDEN_SUM_FOR_CASH: DboForbiddenSumForCashError,
|
289
|
+
ERR_DBO_INCORRECT_URL: DboIncorrectUrlError,
|
290
|
+
ERR_DBO_INVALID_ADDITIONALSERVICE: DboInvalidAdditionalserviceError,
|
291
|
+
ERR_DBO_NEED_AUTH: DboNeedAuthError,
|
292
|
+
ERR_DBO_NOT_FOUND: DboNotFoundError,
|
293
|
+
ERR_DBO_PACKAGE_NUMBER_EMPTY: DboPackageNumberEmptyError,
|
294
|
+
ERR_DBO_PARAM_EMPTY: DboParamEmptyError,
|
295
|
+
ERR_DBO_PARAM_MISTAKE: DboParamMistakeError,
|
296
|
+
ERR_DBO_PARAM_MISTAKE_PVZ: DboParamMistakePvzError,
|
297
|
+
ERR_DBO_PARAM_SERVICE_INTERFACE: DboParamServiceInterfaceError,
|
298
|
+
ERR_DBO_PAYER_EMPTY: DboPayerEmptyError,
|
299
|
+
ERR_DBO_RECEIVER_ADDRESS_TITLE_EMPTY: DboReceiverAddressTitleEmptyError,
|
300
|
+
ERR_DBO_RECEIVER_CITY_AMBIGUOUS: DboReceiverCityAmbiguousError,
|
301
|
+
ERR_DBO_RECEIVER_CITY_EMPTY: DboReceiverCityEmptyError,
|
302
|
+
ERR_DBO_RECEIVER_CITY_INCORRECT: DboReceiverCityIncorrectError,
|
303
|
+
ERR_DBO_RECEIVER_CITY_NOT_INTEGER: DboReceiverCityNotIntegerError,
|
304
|
+
ERR_DBO_RESULT_EMPTY: DboResultEmptyError,
|
305
|
+
ERR_DBO_RESULT_SERVICE_EMPTY: DboResultServiceEmptyError,
|
306
|
+
ERR_DBO_SENDER_ADDRESS_TITLE_EMPTY: DboSenderAddressTitleEmptyError,
|
307
|
+
ERR_DBO_SENDER_CITY_AMBIGUOUS: DboSenderCityAmbiguousError,
|
308
|
+
ERR_DBO_SENDER_CITY_EMPTY: DboSenderCityEmptyError,
|
309
|
+
ERR_DBO_SENDER_CITY_INCORRECT: DboSenderCityIncorrectError,
|
310
|
+
ERR_DBO_SENDER_CITY_NOT_INTEGER: DboSenderCityNotIntegerError,
|
311
|
+
ERR_DBO_SERVICE_EMPTY: DboServiceEmptyError,
|
312
|
+
ERR_DBO_TYPE_EMPTY: DboTypeEmptyError,
|
313
|
+
ERR_DBO_WEIGHT_EMPTY: DboWeightEmptyError,
|
314
|
+
ERR_DELETEREQUEST_ORDER: DeleterequestOrderError,
|
315
|
+
ERR_DELETEREQUEST_ORDER_ACTNUMBER: DeleterequestOrderActnumberError,
|
316
|
+
ERR_DELETEREQUEST_ORDER_DELETED: DeleterequestOrderDeletedError,
|
317
|
+
ERR_DELETEREQUEST_ORDER_MOVE: DeleterequestOrderMoveError,
|
318
|
+
ERR_FILE_NOTEXISTS: FileNotexistsError,
|
319
|
+
ERR_FILE_SAVE: FileSaveError,
|
320
|
+
ERR_FIRST_DUBL_EXISTS: FirstDublExistsError,
|
321
|
+
ERR_INFOREQUEST: InforequestError,
|
322
|
+
ERR_INFOREQUEST_DATEBEG: InforequestDatebegError,
|
323
|
+
ERR_INVALID_ADDRESS_DELIVERY: InvalidAddressDeliveryError,
|
324
|
+
ERR_INVALID_AMOUNT: InvalidAmountError,
|
325
|
+
ERR_INVALID_COST: InvalidCostError,
|
326
|
+
ERR_INVALID_COSTEX: InvalidCostexError,
|
327
|
+
ERR_INVALID_DELIVERYRECIPIENTCOST: InvalidDeliveryrecipientcostError,
|
328
|
+
ERR_INVALID_DISPACHNUMBER: InvalidDispachnumberError,
|
329
|
+
ERR_INVALID_INTAKESERVICE: InvalidIntakeserviceError,
|
330
|
+
ERR_INVALID_INTAKESERVICE_TOCITY: InvalidIntakeserviceTocityError,
|
331
|
+
ERR_INVALID_NUMBER: InvalidNumberError,
|
332
|
+
ERR_INVALID_NUMBER_DELETE: InvalidNumberDeleteError,
|
333
|
+
ERR_INVALID_PAYMENT: InvalidPaymentError,
|
334
|
+
ERR_INVALID_PAYMENTEX: InvalidPaymentexError,
|
335
|
+
ERR_INVALID_SERVICECODE: InvalidServicecodeError,
|
336
|
+
ERR_INVALID_SIZE: InvalidSizeError,
|
337
|
+
ERR_INVALID_TARIFFTYPECODE: InvalidTarifftypecodeError,
|
338
|
+
ERR_INVALID_WEIGHT: InvalidWeightError,
|
339
|
+
ERR_INVALID_XML: InvalidXmlError,
|
340
|
+
ERR_ITEM_NOTFIND: ItemNotfindError,
|
341
|
+
ERR_NEED_ATTRIBUTE: NeedAttributeError,
|
342
|
+
ERR_NOTFOUNDCURRENCY: NotfoundcurrencyError,
|
343
|
+
ERR_NOTFOUNDTAG: NotfoundtagError,
|
344
|
+
ERR_NOT_EQUAL_CALLCOUNT: NotEqualCallcountError,
|
345
|
+
ERR_NOT_EQUAL_ORDERCOUNT: NotEqualOrdercountError,
|
346
|
+
ERR_NOT_FOUND_COSTEX: NotFoundCostexError,
|
347
|
+
ERR_NOT_FOUND_PASSPORTNUMBER: NotFoundPassportnumberError,
|
348
|
+
ERR_NOT_FOUND_PAYMENTEX: NotFoundPaymentexError,
|
349
|
+
ERR_NOT_FOUND_RECCITY: NotFoundReccityError,
|
350
|
+
ERR_NOT_FOUND_REGISTRATIONADDRESS: NotFoundRegistrationaddressError,
|
351
|
+
ERR_NOT_FOUND_SENDCITY: NotFoundSendcityError,
|
352
|
+
ERR_NOT_FOUND_TARIFFTYPECODE: NotFoundTarifftypecodeError,
|
353
|
+
ERR_NOT_VALID_PASSPORTNUMBER: NotValidPassportnumberError,
|
354
|
+
ERR_ORDER_COUNT: OrderCountError,
|
355
|
+
ERR_ORDER_DELETE: OrderDeleteError,
|
356
|
+
ERR_ORDER_DUBL: OrderDublError,
|
357
|
+
ERR_ORDER_DUBL_EXISTS: OrderDublExistsError,
|
358
|
+
ERR_ORDER_NOTFIND: OrderNotfindError,
|
359
|
+
ERR_ORDERS_NOT_FOUND: OrdersNotFoundError,
|
360
|
+
ERR_PACKAGE_NOTFIND: PackageNotfindError,
|
361
|
+
ERR_PACKAGE_NUM_DUBL: PackageNumDublError,
|
362
|
+
ERR_PRINT_ORDER: PrintOrderError,
|
363
|
+
ERR_PVZCODE: PvzcodeError,
|
364
|
+
ERR_PVZCODE_NOTFOUND: PvzcodeNotfoundError,
|
365
|
+
ERR_PVZ_CLOSED: PvzClosedError,
|
366
|
+
ERR_PVZ_NOTFOUND: PvzNotfoundError,
|
367
|
+
ERR_PVZ_NOTFOUND_BY_POSTCODE: PvzNotfoundByPostcodeError,
|
368
|
+
ERR_PVZ_WEIGHT: PvzWeightError,
|
369
|
+
ERR_PVZ_WEIGHT_LIMIT: PvzWeightLimitError,
|
370
|
+
ERR_RECCITYCODE: ReccitycodeError,
|
371
|
+
ERR_RECCITYPOSTCODE: ReccitypostcodeError,
|
372
|
+
ERR_RECCITYPOSTCODE_DUBL: ReccitypostcodeDublError,
|
373
|
+
ERR_SCHEDULE_CHANGE: ScheduleChangeError,
|
374
|
+
ERR_SCHEDULE_DATE: ScheduleDateError,
|
375
|
+
ERR_SCHEDULE_DUBL: ScheduleDublError,
|
376
|
+
ERR_SENDCITYCODE: SendcitycodeError,
|
377
|
+
ERR_SENDCITYPOSTCODE: SendcitypostcodeError,
|
378
|
+
ERR_SENDCITYPOSTCODE_DUBL: SendcitypostcodeDublError,
|
379
|
+
ERR_UNKNOWN_DOC_TYPE: UnknownDocTypeError,
|
380
|
+
ERR_UNKNOWN_VERSION: UnknownVersionError,
|
381
|
+
ERR_WAREKEY_DUBL: WarekeyDublError,
|
382
|
+
ERR_WEIGHT_LIMIT: WeightLimitError,
|
383
|
+
ERR_XML_EMPTY: XmlEmptyError
|
384
|
+
}
|
385
|
+
|
386
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CdekClient
|
2
|
+
|
3
|
+
class Result
|
4
|
+
|
5
|
+
attr_reader :response, :data, :errors
|
6
|
+
|
7
|
+
def initialize(response, data, errors = [])
|
8
|
+
@response = response
|
9
|
+
@data = data
|
10
|
+
@errors = errors
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_data(data)
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_error(error)
|
18
|
+
errors.push error
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module CdekClient
|
4
|
+
module Util
|
5
|
+
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def xml_to_hash(xml_io)
|
9
|
+
result = Nokogiri::XML xml_io
|
10
|
+
return { result.root.name.to_sym => xml_node_to_hash(result.root)}
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash_to_xml(hash)
|
14
|
+
root_key = hash.keys.first
|
15
|
+
Nokogiri::XML::Builder.new do |xml|
|
16
|
+
process_hash_to_xml(root_key, hash[root_key], xml)
|
17
|
+
end.to_xml
|
18
|
+
end
|
19
|
+
|
20
|
+
def deep_symbolize_keys(data)
|
21
|
+
case data
|
22
|
+
when Hash
|
23
|
+
result = {}
|
24
|
+
data.each do |key, value|
|
25
|
+
result[key.to_sym] = deep_symbolize_keys value
|
26
|
+
end
|
27
|
+
return result
|
28
|
+
when Array
|
29
|
+
result = []
|
30
|
+
data.each do |value|
|
31
|
+
result.push deep_symbolize_keys(value)
|
32
|
+
end
|
33
|
+
return result
|
34
|
+
else
|
35
|
+
return data
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def hash_value_at_keypath(hash, keypath)
|
40
|
+
if keypath.length == 0 || !hash.is_a?(Hash)
|
41
|
+
return nil
|
42
|
+
elsif keypath.length == 1
|
43
|
+
return hash[keypath[0]]
|
44
|
+
else
|
45
|
+
return hash_value_at_keypath hash[keypath[0]], keypath[1..-1]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def array_wrap(value)
|
50
|
+
if value.is_a? Array
|
51
|
+
return value
|
52
|
+
elsif value.nil?
|
53
|
+
return []
|
54
|
+
else
|
55
|
+
return [value]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def blank?(value)
|
60
|
+
value.nil? ||
|
61
|
+
(value.is_a?(String) && value.strip == '') ||
|
62
|
+
((value.is_a?(Array) || (value.is_a?(Hash))) && value.empty?)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def xml_node_to_hash(node)
|
68
|
+
# If we are at the root of the document, start the hash
|
69
|
+
if node.element?
|
70
|
+
result_hash = {}
|
71
|
+
if node.attributes != {}
|
72
|
+
attributes = {}
|
73
|
+
node.attributes.keys.each do |key|
|
74
|
+
attributes[node.attributes[key].name.to_sym] = node.attributes[key].value
|
75
|
+
end
|
76
|
+
end
|
77
|
+
if node.children.size > 0
|
78
|
+
node.children.each do |child|
|
79
|
+
result = xml_node_to_hash(child)
|
80
|
+
|
81
|
+
if child.name == "text"
|
82
|
+
unless child.next_sibling || child.previous_sibling
|
83
|
+
return result unless attributes
|
84
|
+
result_hash[child.name.to_sym] = result
|
85
|
+
end
|
86
|
+
elsif result_hash[child.name.to_sym]
|
87
|
+
|
88
|
+
if result_hash[child.name.to_sym].is_a?(Object::Array)
|
89
|
+
result_hash[child.name.to_sym] << result
|
90
|
+
else
|
91
|
+
result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << result
|
92
|
+
end
|
93
|
+
else
|
94
|
+
result_hash[child.name.to_sym] = result
|
95
|
+
end
|
96
|
+
end
|
97
|
+
if attributes
|
98
|
+
#add code to remove non-data attributes e.g. xml schema, namespace here
|
99
|
+
#if there is a collision then node content supersets attributes
|
100
|
+
result_hash = attributes.merge(result_hash)
|
101
|
+
end
|
102
|
+
return result_hash
|
103
|
+
else
|
104
|
+
return attributes
|
105
|
+
end
|
106
|
+
else
|
107
|
+
return node.content.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def process_hash_to_xml(label, value, xml)
|
112
|
+
if value.is_a? Hash
|
113
|
+
children, attributes = value.partition{ |k, v| v.is_a?(Array) || v.is_a?(Hash) }
|
114
|
+
xml.send(label, Hash[attributes]) do
|
115
|
+
children.each{ |k, v| process_hash_to_xml k, v, xml }
|
116
|
+
end
|
117
|
+
elsif value.is_a? Array
|
118
|
+
value.each do |v|
|
119
|
+
process_hash_to_xml label, v, xml
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|