Skip to content

Commit c0eade6

Browse files
committed
Merge pull request timotheus#1 from bimusiek/clickcollect
Clickcollect
2 parents 45ae57a + 473bc4b commit c0eade6

5 files changed

Lines changed: 272 additions & 6 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ ebaysdk.egg-info/
66
*.swp
77
*.pyc
88
.svn
9+
.idea

ebaysdk/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import platform
1010
import logging
1111

12-
__version__ = '2.1.1-dev2'
12+
__version__ = '2.1.1-dev3'
1313
Version = __version__ # for backware compatibility
1414

1515
try:

ebaysdk/connection.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,7 @@ def build_request(self, verb, data, verb_attrs):
132132
self._request_dict = data
133133
self._request_id = uuid.uuid4()
134134

135-
url = "%s://%s%s" % (
136-
HTTP_SSL[self.config.get('https', False)],
137-
self.config.get('domain'),
138-
self.config.get('uri')
139-
)
135+
url = self.build_request_url(verb)
140136

141137
headers = self.build_request_headers(verb)
142138
headers.update({'User-Agent': UserAgent,
@@ -150,6 +146,14 @@ def build_request(self, verb, data, verb_attrs):
150146

151147
self.request = request.prepare()
152148

149+
def build_request_url(self, verb):
150+
url = "%s://%s%s" % (
151+
HTTP_SSL[self.config.get('https', False)],
152+
self.config.get('domain'),
153+
self.config.get('uri')
154+
)
155+
return url
156+
153157
def execute_request(self):
154158

155159
log.debug("REQUEST (%s): %s %s" \
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# -*- coding: utf-8 -*-
2+
3+
'''
4+
Authored by: Michal Hernas
5+
Licensed under CDDL 1.0
6+
'''
7+
8+
import os
9+
10+
from ebaysdk import log
11+
from ebaysdk.connection import BaseConnection
12+
from ebaysdk.exception import RequestPaginationError, PaginationLimit
13+
from ebaysdk.config import Config
14+
from ebaysdk.utils import dict2xml
15+
16+
class Connection(BaseConnection):
17+
"""Connection class for the Inventory Management service
18+
19+
API documentation:
20+
http://developer.ebay.com/Devzone/store-pickup/InventoryManagement/index.html
21+
22+
Supported calls:
23+
AddInventory
24+
AddInventoryLocation
25+
DeleteInventory
26+
DeleteInventoryLocation
27+
(all others, see API docs)
28+
29+
Doctests:
30+
Create location first
31+
>>> f = Connection(config_file=os.environ.get('EBAY_YAML'), debug=False)
32+
>>> retval = f.execute('AddInventoryLocation', {
33+
... 'Address1': u'Alexanderplatz 12',
34+
... 'Address2': u'Gebaude 6',
35+
... 'City': u'Berlin',
36+
... 'Country': u'DE',
37+
... 'PostalCode': u'13355',
38+
... 'Latitude': u'37.374488',
39+
... 'Longitude': u'-122.032876',
40+
... 'LocationID': u'ebaysdk_test',
41+
... 'LocationType': u'STORE',
42+
... 'Phone': u'(408)408-4080',
43+
... 'URL': u'http://store.com',
44+
... 'UTCOffset': u'+02:00',
45+
... 'Name': 'Test',
46+
... 'Region': 'Berlin',
47+
... 'PickupInstructions': 'Pick it up soon',
48+
... 'Hours': [{'Day': {'DayOfWeek': 1, 'Interval': {'Open': '08:00:00', 'Close': '10:00:00'}}}]
49+
... })
50+
>>> error = f.error()
51+
>>> if not f.error():
52+
... print(f.response.reply.LocationID.lower())
53+
ebaysdk_test
54+
55+
And now add item it it
56+
>>> f = Connection(config_file=os.environ.get('EBAY_YAML'), debug=False)
57+
>>> retval = f.execute('AddInventory', {"SKU": "SKU_TEST", "Locations": {"Location": [
58+
... {"Availability": "IN_STOCK", "LocationID": "ebaysdk_test", "Quantity": 10}
59+
... ]}})
60+
>>> error = f.error()
61+
>>> if not f.error():
62+
... print(f.response.reply.SKU.lower())
63+
sku_test
64+
65+
66+
Delete item from all locations
67+
>>> f = Connection(config_file=os.environ.get('EBAY_YAML'), debug=False)
68+
>>> retval = f.execute('DeleteInventory', {"SKU": "SKU_TEST", "Confirm": 'true'})
69+
>>> error = f.error()
70+
>>> if not f.error():
71+
... print(f.response.reply.SKU.lower())
72+
sku_test
73+
74+
75+
Delete location
76+
>>> f = Connection(config_file=os.environ.get('EBAY_YAML'), debug=False)
77+
>>> retval = f.execute('DeleteInventoryLocation', {"LocationID": "ebaysdk_test"})
78+
>>> error = f.error()
79+
>>> if not f.error():
80+
... print(f.response.reply.LocationID.lower())
81+
ebaysdk_test
82+
83+
"""
84+
85+
def __init__(self, **kwargs):
86+
"""Finding class constructor.
87+
88+
Keyword arguments:
89+
domain -- API endpoint (default: svcs.ebay.com)
90+
config_file -- YAML defaults (default: ebay.yaml)
91+
debug -- debugging enabled (default: False)
92+
warnings -- warnings enabled (default: False)
93+
uri -- API endpoint uri (default: /services/search/FindingService/v1)
94+
token -- eBay application/user token
95+
version -- version number (default: 1.0.0)
96+
https -- execute of https (default: False)
97+
proxy_host -- proxy hostname
98+
proxy_port -- proxy port number
99+
timeout -- HTTP request timeout (default: 20)
100+
parallel -- ebaysdk parallel object
101+
response_encoding -- API encoding (default: XML)
102+
request_encoding -- API encoding (default: XML)
103+
"""
104+
105+
super(Connection, self).__init__(method='POST', **kwargs)
106+
107+
self.config=Config(domain=kwargs.get('domain', 'api.ebay.com'),
108+
connection_kwargs=kwargs,
109+
config_file=kwargs.get('config_file', 'ebay.yaml'))
110+
111+
# override yaml defaults with args sent to the constructor
112+
self.config.set('domain', kwargs.get('domain', 'api.ebay.com'))
113+
self.config.set('uri', '/selling/inventory/v1')
114+
self.config.set('https', True)
115+
self.config.set('warnings', True)
116+
self.config.set('errors', True)
117+
self.config.set('siteid', None)
118+
self.config.set('response_encoding', 'XML')
119+
self.config.set('request_encoding', 'XML')
120+
self.config.set('proxy_host', None)
121+
self.config.set('proxy_port', None)
122+
self.config.set('token', None)
123+
self.config.set('iaf_token', None)
124+
self.config.set('appid', None)
125+
self.config.set('version', '1.0.0')
126+
self.config.set('service', 'InventoryManagement')
127+
self.config.set('doc_url', 'http://developer.ebay.com/Devzone/store-pickup/InventoryManagement/index.html')
128+
129+
self.datetime_nodes = ['starttimefrom', 'timestamp', 'starttime',
130+
'endtime']
131+
self.base_list_nodes = [
132+
]
133+
134+
endpoints = {
135+
'addinventorylocation': 'locations/delta/add',
136+
'addinventory': 'inventory/delta/add',
137+
'deleteinventory': 'inventory/delta/delete',
138+
'deleteinventorylocation': 'locations/delta/delete',
139+
}
140+
141+
def build_request_url(self, verb):
142+
url = super(Connection, self).build_request_url(verb)
143+
endpoint = self.endpoints[verb.lower()]
144+
return "{0}/{1}".format(url, endpoint)
145+
146+
def build_request_headers(self, verb):
147+
return {
148+
"Authorization": "TOKEN {0}".format(self.config.get('token')),
149+
"Content-Type": "application/xml"
150+
}
151+
152+
def build_request_data(self, verb, data, verb_attrs):
153+
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
154+
xml += "<" + verb + "Request>"
155+
xml += dict2xml(data)
156+
xml += "</" + verb + "Request>"
157+
158+
return xml
159+
160+
def warnings(self):
161+
warning_string = ""
162+
163+
if len(self._resp_body_warnings) > 0:
164+
warning_string = "%s: %s" \
165+
% (self.verb, ", ".join(self._resp_body_warnings))
166+
167+
return warning_string
168+
169+
170+
def _get_resp_body_errors(self):
171+
"""Parses the response content to pull errors.
172+
173+
Child classes should override this method based on what the errors in the
174+
XML response body look like. They can choose to look at the 'ack',
175+
'Errors', 'errorMessage' or whatever other fields the service returns.
176+
the implementation below is the original code that was part of error()
177+
"""
178+
179+
if self._resp_body_errors and len(self._resp_body_errors) > 0:
180+
return self._resp_body_errors
181+
182+
errors = []
183+
warnings = []
184+
resp_codes = []
185+
186+
if self.verb is None:
187+
return errors
188+
189+
dom = self.response.dom()
190+
if dom is None:
191+
return errors
192+
193+
for e in dom.findall('Errors'):
194+
eSeverity = None
195+
eClass = None
196+
eShortMsg = None
197+
eLongMsg = None
198+
eCode = None
199+
200+
try:
201+
eSeverity = e.findall('SeverityCode')[0].text
202+
except IndexError:
203+
pass
204+
205+
try:
206+
eClass = e.findall('ErrorClassification')[0].text
207+
except IndexError:
208+
pass
209+
210+
try:
211+
eCode = e.findall('ErrorCode')[0].text
212+
except IndexError:
213+
pass
214+
215+
try:
216+
eShortMsg = e.findall('ShortMessage')[0].text
217+
except IndexError:
218+
pass
219+
220+
try:
221+
eLongMsg = e.findall('LongMessage')[0].text
222+
except IndexError:
223+
pass
224+
225+
try:
226+
eCode = e.findall('ErrorCode')[0].text
227+
try:
228+
int_code = int(eCode)
229+
except ValueError:
230+
int_code = None
231+
232+
if int_code and int_code not in resp_codes:
233+
resp_codes.append(int_code)
234+
235+
except IndexError:
236+
pass
237+
238+
msg = "Class: %s, Severity: %s, Code: %s, %s%s" \
239+
% (eClass, eSeverity, eCode, eShortMsg, eLongMsg)
240+
241+
if eSeverity == 'Warning':
242+
warnings.append(msg)
243+
else:
244+
errors.append(msg)
245+
246+
self._resp_body_warnings = warnings
247+
self._resp_body_errors = errors
248+
self._resp_codes = resp_codes
249+
250+
if self.config.get('warnings') and len(warnings) > 0:
251+
log.warn("%s: %s\n\n" % (self.verb, "\n".join(warnings)))
252+
253+
if self.response.reply.Ack == 'Failure':
254+
if self.config.get('errors'):
255+
log.error("%s: %s\n\n" % (self.verb, "\n".join(errors)))
256+
257+
return errors
258+
259+
return []

tests/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import ebaysdk.soa.finditem
2121
import ebaysdk.finding
2222
import ebaysdk.poller.orders
23+
import ebaysdk.inventorymanagement
2324

2425
# does not pass with python3.3
2526
try:
@@ -41,6 +42,7 @@ def getTestSuite():
4142
suite.addTest(doctest.DocTestSuite(ebaysdk.trading))
4243
suite.addTest(doctest.DocTestSuite(ebaysdk.merchandising))
4344
suite.addTest(doctest.DocTestSuite(ebaysdk.finding))
45+
suite.addTest(doctest.DocTestSuite(ebaysdk.inventorymanagement))
4446

4547
if not sys.version_info[0] >= 3 \
4648
and sys.modules.has_key('grequests') is True:

0 commit comments

Comments
 (0)