mirror of
https://github.com/c0de-archive/ebay-testing.git
synced 2024-12-22 12:42:41 +00:00
Add CSV support, start work on checkRevisedItems, Add switchDateRange
The CSV support is going to be for exporting the itemData from our database to use with external services that can import CSV files checkRevisedItems will check a dateRange and return a list containing the ItemIDs that need to be fetched again wigh getItems because they were revised in some way switchDateRange - More abstractions to other functions - This is because we use that specific switch statement multiple times now
This commit is contained in:
parent
35e45e5e1a
commit
5bd3f0b85b
165
ebay.py
165
ebay.py
@ -7,6 +7,7 @@ from ebaysdk.exception import ConnectionError, ConnectionResponseError
|
|||||||
from ebaysdk.parallel import Parallel
|
from ebaysdk.parallel import Parallel
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import csv
|
||||||
|
|
||||||
# Application Settings
|
# Application Settings
|
||||||
app_id = ''
|
app_id = ''
|
||||||
@ -17,6 +18,11 @@ domain = 'api.sandbox.ebay.com'
|
|||||||
# User Identification
|
# User Identification
|
||||||
usr_token = ''
|
usr_token = ''
|
||||||
|
|
||||||
|
# CSV file data
|
||||||
|
csv_path = ''
|
||||||
|
csv_delimiter = ','
|
||||||
|
csv_quote = '\''
|
||||||
|
|
||||||
# Creates a dateRange list for use with glue
|
# Creates a dateRange list for use with glue
|
||||||
def setDateRange(days=None, start=None, rangeType=None):
|
def setDateRange(days=None, start=None, rangeType=None):
|
||||||
# Default to searching for listings ending today
|
# Default to searching for listings ending today
|
||||||
@ -59,12 +65,52 @@ def setDateRange(days=None, start=None, rangeType=None):
|
|||||||
future = today+delta
|
future = today+delta
|
||||||
# Convert our dates into a format that ebay can recognize (ISO 8601)
|
# Convert our dates into a format that ebay can recognize (ISO 8601)
|
||||||
today = today.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
today = today.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||||||
|
# Force the future to be the absolute end of the day
|
||||||
future = future.strftime("%Y-%m-%dT23:59:59.999Z")
|
future = future.strftime("%Y-%m-%dT23:59:59.999Z")
|
||||||
|
|
||||||
# If we want to manipulate either today or future, the following converts from a string back into a datetime object
|
# If we want to manipulate either today or future, the following converts from a string back into a datetime object
|
||||||
# datetime.datetime.strptime(today, '%Y-%m-%dT%H:%M:%S.%fZ')
|
# datetime.datetime.strptime(today, '%Y-%m-%dT%H:%M:%S.%fZ')
|
||||||
return {'from': today, 'to': future, 'type': rangeType}
|
return {'from': today, 'to': future, 'type': rangeType}
|
||||||
|
|
||||||
|
# We call this a couple times, so it gets its own function
|
||||||
|
def switchDateRange(range=None, list=None):
|
||||||
|
# Switch statement to check which type of dateRange to search by
|
||||||
|
# This can be start/mod/end
|
||||||
|
def rangeType(condition):
|
||||||
|
# Cast the condition to a string
|
||||||
|
condition = str(condition)
|
||||||
|
switch = {
|
||||||
|
'start': 'Start', # Covers StartTimeFrom and StartTimeTo - Items that started in this date range
|
||||||
|
'mod': 'Mod', # Covers ModTimeFrom and ModTimeTo - Items modified in this date range
|
||||||
|
'end': 'End' # Covers EndTimeFrom and EndTimeTo - Items that end within this date range
|
||||||
|
}
|
||||||
|
# Return the approiate text or End if no ID matches
|
||||||
|
return switch.get(condition, 'End')
|
||||||
|
|
||||||
|
|
||||||
|
# Override the dates in sellerList with values from dateRange, if provided
|
||||||
|
if ('from' in range) & ('type' in range):
|
||||||
|
# Remove the list of keys from sellerList - We can only have one search range
|
||||||
|
for o in ['EndTimeFrom','ModTimeFrom','StartTimeFrom']:
|
||||||
|
try:
|
||||||
|
del list[o]
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
list[rangeType(range['type'])+'TimeFrom'] = range['from']
|
||||||
|
|
||||||
|
if ('to' in range) & ('type' in range):
|
||||||
|
# Remove the list of keys from sellerList - We can only have one search range
|
||||||
|
for o in ['EndTimeTo','ModTimeTo','StartTimeTo']:
|
||||||
|
try:
|
||||||
|
del list[o]
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
list[rangeType(range['type'])+'TimeTo'] = range['to']
|
||||||
|
|
||||||
|
return list
|
||||||
|
|
||||||
# Here are the error codes that we currently have
|
# Here are the error codes that we currently have
|
||||||
# None - No events have happened yet
|
# None - No events have happened yet
|
||||||
# 0 - Everything is fine
|
# 0 - Everything is fine
|
||||||
@ -83,15 +129,15 @@ def getSeller(api, list):
|
|||||||
|
|
||||||
# Set our error conditions
|
# Set our error conditions
|
||||||
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'getSeller' }, 'apiResponse': {} }
|
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'getSeller' }, 'apiResponse': {} }
|
||||||
if(api == None):
|
if api == None:
|
||||||
res['error']['code'] = '1'
|
res['error']['code'] = '1'
|
||||||
res['error']['msg'] = 'api is not set'
|
res['error']['msg'] = 'api is not set'
|
||||||
return res
|
return res
|
||||||
if(list == None) | (isinstance(list, dict) != True):
|
if (list == None) | (isinstance(list, dict) != True):
|
||||||
res['error']['code'] = '2'
|
res['error']['code'] = '2'
|
||||||
res['error']['msg'] = 'list doesn\'t exist or is of wrong type, must be dict'
|
res['error']['msg'] = 'list doesn\'t exist or is of wrong type, must be dict'
|
||||||
return res
|
return res
|
||||||
if('EndTimeFrom' not in list) | ('EndTimeTo' not in list):
|
if ('EndTimeFrom' not in list) | ('EndTimeTo' not in list):
|
||||||
res['error']['code'] = '3'
|
res['error']['code'] = '3'
|
||||||
res['error']['msg'] = 'either "EndTimeFrom" or "EndTimeTo" is not set in list'
|
res['error']['msg'] = 'either "EndTimeFrom" or "EndTimeTo" is not set in list'
|
||||||
return res
|
return res
|
||||||
@ -135,15 +181,15 @@ def getItems(api, itemList, itemArgs={}):
|
|||||||
|
|
||||||
# Set our error conditions
|
# Set our error conditions
|
||||||
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'getItems' }, 'apiResponse': {} }
|
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'getItems' }, 'apiResponse': {} }
|
||||||
if(api == None):
|
if api == None:
|
||||||
res['error']['code'] = '1'
|
res['error']['code'] = '1'
|
||||||
res['error']['msg'] = 'api is not set'
|
res['error']['msg'] = 'api is not set'
|
||||||
return res
|
return res
|
||||||
if(itemList == None) | (type(itemList) != type([])):
|
if (itemList == None) | (type(itemList) != type([])):
|
||||||
res['error']['code'] = '2'
|
res['error']['code'] = '2'
|
||||||
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be list containing one or more dicts'
|
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be list containing one or more dicts'
|
||||||
return res
|
return res
|
||||||
if(itemArgs == None) | (isinstance(itemArgs, dict) != True):
|
if (itemArgs == None) | (isinstance(itemArgs, dict) != True):
|
||||||
res['error']['code'] = '2'
|
res['error']['code'] = '2'
|
||||||
res['error']['msg'] = 'itemArgs doesn\'t exist or is of wrong type, must be dict'
|
res['error']['msg'] = 'itemArgs doesn\'t exist or is of wrong type, must be dict'
|
||||||
return res
|
return res
|
||||||
@ -171,6 +217,37 @@ def getItems(api, itemList, itemArgs={}):
|
|||||||
# After the loop is complete, return the whole res
|
# After the loop is complete, return the whole res
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
# Use the modTime range and only return data for items that have been modified in the timerange
|
||||||
|
# Args we want are the modTime and NewItemFilter=True to get only items that have changed in this timerange
|
||||||
|
def checkRevisedItems(api, itemArgs={}, dateRange={}):
|
||||||
|
# api is the connection to the Trading API
|
||||||
|
# itemList is a list containing itemIDs to check for updates
|
||||||
|
# itemArgs is an optional dict that contains extra details to refine the search returned by ebay
|
||||||
|
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'checkRevisedItems' }, 'apiResponse': {} }
|
||||||
|
if api == None:
|
||||||
|
res['error']['code'] = '1'
|
||||||
|
res['error']['msg'] = 'api is not set'
|
||||||
|
return res
|
||||||
|
if (itemList == None) | (isinstance(itemList, dict) != True):
|
||||||
|
res['error']['code'] = '2'
|
||||||
|
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be list containing one or more dicts'
|
||||||
|
return res
|
||||||
|
if (itemArgs == None) | (isinstance(itemArgs, dict) != True):
|
||||||
|
res['error']['code'] = '2'
|
||||||
|
res['error']['msg'] = 'itemArgs doesn\'t exist or is of wrong type, must be dict'
|
||||||
|
return res
|
||||||
|
|
||||||
|
itemArgs['NewItemFilter'] = 'True'
|
||||||
|
|
||||||
|
# Switch statement to select the proper dateRange
|
||||||
|
itemArgs = switchDateRange(itemArgs, dateRange)
|
||||||
|
|
||||||
|
#
|
||||||
|
response = api.execute('GetSellerEvents', itemArgs)
|
||||||
|
|
||||||
|
for i in itemList:
|
||||||
|
|
||||||
|
|
||||||
# storeItems uses the dict of Items provided by getItems and stores the information we want
|
# storeItems uses the dict of Items provided by getItems and stores the information we want
|
||||||
def storeItems(itemList):
|
def storeItems(itemList):
|
||||||
# itemList is the apiRequest value presented as a result of getItems
|
# itemList is the apiRequest value presented as a result of getItems
|
||||||
@ -178,7 +255,7 @@ def storeItems(itemList):
|
|||||||
|
|
||||||
# Set our error conditions
|
# Set our error conditions
|
||||||
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'storeItems' }, 'apiResponse': {} }
|
res = { 'error': { 'code': None, 'msg': None, 'fnc': 'storeItems' }, 'apiResponse': {} }
|
||||||
if(itemList == None) | (isinstance(itemList, dict) != True):
|
if (itemList == None) | (isinstance(itemList, dict) != True):
|
||||||
res['error']['code'] = '2'
|
res['error']['code'] = '2'
|
||||||
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be dict'
|
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be dict'
|
||||||
return res
|
return res
|
||||||
@ -260,66 +337,32 @@ def storeItems(itemList):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
# Glue logic to run all the functions above properly
|
# Glue logic to run all the functions above properly
|
||||||
def glue(api, sellerList, dateRange={}):
|
def glue(api=None, sellerList={}, dateRange={}):
|
||||||
# api is the connection to the api, this is passed to the functions as called
|
# api is the connection to the api, this is passed to the functions as called
|
||||||
# sellerList is the options that you can present ebay for searching (http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetSellerEvents.html)
|
# sellerList is the options that you can present ebay for searching (http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetSellerEvents.html)
|
||||||
# dateRange overrides EndTimeFrom and EndTimeTo from sellerList for ease of passing these required data with nothing else
|
# dateRange overrides EndTimeFrom and EndTimeTo from sellerList for ease of passing these required data with nothing else
|
||||||
|
|
||||||
# Set our error conditions
|
# Set our error conditions
|
||||||
res = { 'error': { 'code': '0', 'msg': None, 'fnc': 'glue' }, 'apiResponse': {} }
|
res = { 'error': { 'code': '0', 'msg': None, 'fnc': 'glue' }, 'apiResponse': {} }
|
||||||
if(api == None):
|
if api == None:
|
||||||
res['error']['code'] = '1'
|
res['error']['code'] = '1'
|
||||||
res['error']['msg'] = 'api is not set'
|
res['error']['msg'] = 'api is not set'
|
||||||
return res
|
return res
|
||||||
if(sellerList == None) | (isinstance(sellerList, dict) != True):
|
if (sellerList == None) | (isinstance(sellerList, dict) != True):
|
||||||
res['error']['code'] = '2'
|
res['error']['code'] = '2'
|
||||||
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be dict'
|
res['error']['msg'] = 'itemList doesn\'t exist or is of wrong type, must be dict'
|
||||||
return res
|
return res
|
||||||
if(dateRange == None) | (isinstance(dateRange, dict) != True):
|
if (dateRange == None) | (isinstance(dateRange, dict) != True):
|
||||||
res['error']['code'] = '2'
|
res['error']['code'] = '2'
|
||||||
res['error']['msg'] = 'dateRange doesn\'t exist or is of wrong type, must be dict'
|
res['error']['msg'] = 'dateRange doesn\'t exist or is of wrong type, must be dict'
|
||||||
return res
|
return res
|
||||||
|
|
||||||
# Switch statement to check which type of dateRange to search by
|
# Switch statement to select the proper dateRange
|
||||||
# This can be start/mod/end
|
sellerList = switchDateRange(sellerList, dateRange)
|
||||||
def rangeType(condition):
|
|
||||||
# Cast the condition to a string
|
|
||||||
condition = str(condition)
|
|
||||||
switch = {
|
|
||||||
'start': 'Start', # Covers StartTimeFrom and StartTimeTo - Items that started in this date range
|
|
||||||
'mod': 'Mod', # Covers ModTimeFrom and ModTimeTo - Items modified in this date range
|
|
||||||
'end': 'End' # Covers EndTimeFrom and EndTimeTo - Items that end within this date range
|
|
||||||
}
|
|
||||||
# Return the approiate text or End if no ID matches
|
|
||||||
return switch.get(condition, 'End')
|
|
||||||
|
|
||||||
|
|
||||||
# Override the dates in sellerList with values from dateRange, if provided
|
|
||||||
if ('from' in dateRange) & ('type' in dateRange):
|
|
||||||
# Remove the list of keys from sellerList - We can only have one search range
|
|
||||||
for o in ['EndTimeFrom','ModTimeFrom','StartTimeFrom']:
|
|
||||||
try:
|
|
||||||
del sellerList[o]
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
sellerList[rangeType(dateRange['type'])+'TimeFrom'] = dateRange['from']
|
|
||||||
|
|
||||||
if ('to' in dateRange) & ('type' in dateRange):
|
|
||||||
# Remove the list of keys from sellerList - We can only have one search range
|
|
||||||
for o in ['EndTimeTo','ModTimeTo','StartTimeTo']:
|
|
||||||
try:
|
|
||||||
del sellerList[o]
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
sellerList[rangeType(dateRange['type'])+'TimeTo'] = dateRange['to']
|
|
||||||
|
|
||||||
|
|
||||||
seller = getSeller(api, sellerList)
|
seller = getSeller(api, sellerList)
|
||||||
if seller['error']['code'] == '0':
|
if seller['error']['code'] == '0':
|
||||||
sellerList = seller['apiResponse']
|
sellerList = seller['apiResponse']
|
||||||
print seller['apiResponse']
|
|
||||||
seller = None # Unset any data we no-longer need - Saves on memory
|
seller = None # Unset any data we no-longer need - Saves on memory
|
||||||
|
|
||||||
items = getItems(api, sellerList)
|
items = getItems(api, sellerList)
|
||||||
@ -346,15 +389,29 @@ try:
|
|||||||
api = Trading(domain=domain, appid=app_id, devid=dev_id, certid=crt_id, token=usr_token, config_file=None, debug=False, parellel=p)
|
api = Trading(domain=domain, appid=app_id, devid=dev_id, certid=crt_id, token=usr_token, config_file=None, debug=False, parellel=p)
|
||||||
|
|
||||||
# Example usage, returns a dict containing all items of interst (based on the functions above)
|
# Example usage, returns a dict containing all items of interst (based on the functions above)
|
||||||
itemData = glue(api=api, sellerList={'Pagination': {'EntriesPerPage':'1', 'PageNumber':'1'}}, dateRange=setDateRange())
|
itemData = glue(api=api, sellerList={}, dateRange=setDateRange())
|
||||||
|
|
||||||
# Store the itemIDs so that we can use them to check which ones were modified
|
|
||||||
itemlist = []
|
itemlist = []
|
||||||
for i in itemData:
|
|
||||||
itemlist.append(i)
|
|
||||||
|
|
||||||
|
# Write a CSV file containing some of the data we're interested in
|
||||||
|
with open(csv_path, 'wb') as csvfile:
|
||||||
|
Part Number Manufacturer Condition Price Quantity Description
|
||||||
|
fieldnames = ['Part Number', 'Manufacturer', 'Condition', 'Price', 'Quantity', 'Description']
|
||||||
|
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=csv_delimiter, quotechar=csv_quote, quoting=csv.QUOTE_MINIMAL)
|
||||||
|
|
||||||
|
for i in itemData:
|
||||||
|
data = {
|
||||||
|
'Part Number': i['mpn'],
|
||||||
|
'Manufacturer': i['mfg'],
|
||||||
|
'Condition': i['condition']['msg'],
|
||||||
|
'Price': i['price']['val']+' '+i['price']['cur'],
|
||||||
|
'Quantity': str(int(i['quantity']['total'])-int(i['quantity']['sold'])),
|
||||||
|
'Description': i['title']
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writerow(data)
|
||||||
|
|
||||||
|
# Store the itemIDs so that we can use them to check which ones were modified
|
||||||
|
itemlist.append(i)
|
||||||
|
|
||||||
except ConnectionError as e:
|
except ConnectionError as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user