2016-03-22 21:43:40 +00:00
# Imports first
# This is the sdk found at https://github.com/timotheus/ebaysdk-python
2016-03-24 19:17:31 +00:00
from ebaysdk . trading import Connection as Trading
from ebaysdk . exception import ConnectionError , ConnectionResponseError
# Parallel requires Gevent and Grequests modules to be available on the server (requires at least 2.7.5)
from ebaysdk . parallel import Parallel
2016-03-22 21:43:40 +00:00
import datetime
2016-03-25 19:05:04 +00:00
import csv
2016-03-22 21:43:40 +00:00
# Application Settings
app_id = ' '
dev_id = ' '
crt_id = ' '
domain = ' api.sandbox.ebay.com '
# User Identification
usr_token = ' '
2016-03-25 19:05:04 +00:00
# CSV file data
csv_path = ' '
csv_delimiter = ' , '
csv_quote = ' \' '
2016-03-25 20:28:08 +00:00
# We can probably put the DateRange functions into a class
2016-03-24 19:17:31 +00:00
# Creates a dateRange list for use with glue
2016-03-28 19:07:01 +00:00
def setDateRange ( days = None , start = None , stop = None , rangeType = None ) :
2016-03-29 14:59:10 +00:00
# Default to searching for the current 24 hours, minus 1ms
# Formats the date presented to it according to what we need, defaults to today
def checkDate ( theDate = None ) :
if theDate != None :
if type ( theDate ) == type ( datetime . datetime . today ( ) ) :
return theDate
elif type ( theDate ) == type ( ' ' ) :
try :
return datetime . datetime . strptime ( theDate , ' % Y- % m- %d ' )
except ValueError :
return datetime . datetime . today ( )
else :
return datetime . datetime . today ( )
else :
return datetime . datetime . today ( )
# Set our days to an int, defaults to 0
try :
days = int ( days )
except ( TypeError , ValueError ) :
2016-03-24 19:40:29 +00:00
days = 0
2016-03-28 19:07:01 +00:00
2016-03-29 14:59:10 +00:00
# Set our rangeType to str, defaults to 'end'
if rangeType != None :
rangeType = str ( rangeType )
else :
2016-03-24 19:40:29 +00:00
rangeType = ' end '
2016-03-24 19:17:31 +00:00
2016-03-29 14:59:10 +00:00
# Set the days argument to search forward/backward more than one day
2016-03-28 19:07:01 +00:00
delta = datetime . timedelta ( days )
2016-03-29 14:59:10 +00:00
start_time = checkDate ( start )
2016-03-24 19:17:31 +00:00
2016-03-28 19:07:01 +00:00
if stop != None :
2016-03-29 14:59:10 +00:00
end_time = checkDate ( stop )
2016-03-28 19:07:01 +00:00
else :
2016-03-29 14:59:10 +00:00
end_time = start_time + delta
2016-03-24 19:40:29 +00:00
2016-03-29 14:59:10 +00:00
# Convert our dates into a format that the api can recognize (ISO 8601)
start_time = start_time . strftime ( " % Y- % m- %d T00:00:00.000Z " )
2016-03-25 19:05:04 +00:00
# Force the future to be the absolute end of the day
2016-03-29 14:59:10 +00:00
end_time = end_time . strftime ( " % Y- % m- %d T23:59:59.999Z " )
# if the end_time is in the past, reverse order (EG, the delta is a negative number)
if end_time < start_time :
start_time_old = start_time
start_time = end_time
end_time = start_time_old
return { ' from ' : start_time , ' to ' : end_time , ' type ' : rangeType }
2016-03-24 19:17:31 +00:00
2016-03-22 21:43:40 +00:00
2016-03-25 19:05:04 +00:00
# We call this a couple times, so it gets its own function
2016-03-25 19:14:35 +00:00
def switchDateRange ( list = None , range = None ) :
2016-03-25 19:05:04 +00:00
# Switch statement to check which type of dateRange to search by
2016-03-25 20:28:08 +00:00
# Will always return a valid dateRange for use as various itemArgs
# Defaults to a dateRange ending today
if ( range == None ) | ( isinstance ( range , dict ) != True ) :
# Sets the default range (items that are ending today)
range = setDateRange ( )
if ( list == None ) | ( isinstance ( list , dict ) != True ) :
list = { }
2016-03-25 19:05:04 +00:00
# This can be start/mod/end
2016-03-25 20:28:08 +00:00
def rangeType ( condition = None ) :
# No condition to check, defaults to End
if condition == None :
return ' End '
2016-03-25 19:05:04 +00:00
# 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
2016-03-22 21:43:40 +00:00
# Here are the error codes that we currently have
# None - No events have happened yet
# 0 - Everything is fine
# 1 - The API variable is either unset, or is not a valid connection to the ebay API
# 2 - The required list is either unset, or is not the required type - Usually dict, but can be a list of dicts
# 3 - EndTimeFrom or EndTimeTo were not set in the list - getSeller only
# 4 - Relates to 3, but specifically refers to a dateRange not being available for glue
# 5 - No data (useful) returned by API - A field of data we need is None
# minor logic checking - We don't want to get trackbacks for silly reasons
# getSeller gets a list of our itemIDs
2016-03-25 19:14:35 +00:00
def getSeller ( api = None , list = None ) :
2016-03-24 19:40:29 +00:00
# api is the connection to the Trading API
# list is a dict containing required information for ebay to search for (http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetSellerEvents.html)
# - The datapoints that MUST be defined are EndTimeFrom and EndTimeTo - These select the dateRange that items end on ebay
# Set our error conditions
res = { ' error ' : { ' code ' : None , ' msg ' : None , ' fnc ' : ' getSeller ' } , ' apiResponse ' : { } }
2016-03-25 19:05:04 +00:00
if api == None :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 1 '
res [ ' error ' ] [ ' msg ' ] = ' api is not set '
return res
2016-03-25 19:05:04 +00:00
if ( list == None ) | ( isinstance ( list , dict ) != True ) :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 2 '
res [ ' error ' ] [ ' msg ' ] = ' list doesn \' t exist or is of wrong type, must be dict '
return res
2016-03-28 19:07:01 +00:00
if ( ( ' EndTimeFrom ' not in list ) | ( ' EndTimeTo ' not in list ) ) & ( ( ' StartTimeFrom ' not in list ) | ( ' StartTimeTo ' not in list ) ) :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 3 '
2016-03-28 19:07:01 +00:00
res [ ' error ' ] [ ' msg ' ] = ' either " StartTime " or " EndTime " is not set in list '
2016-03-24 19:40:29 +00:00
return res
2016-03-25 20:28:08 +00:00
res [ ' apiResponse ' ] = api . execute ( ' GetSellerEvents ' , list ) . dict ( )
2016-03-24 19:40:29 +00:00
# Verify that the search returned information
if res [ ' apiResponse ' ] [ ' ItemArray ' ] != None :
# Check if the itemArray is setup the way we want it (list containing one or more dicts)
try :
for k in res [ ' apiResponse ' ] [ ' ItemArray ' ] [ ' Item ' ] :
itemid = k [ ' ItemID ' ]
except TypeError :
# The itemArray is not, force it to be then
res [ ' apiResponse ' ] = [ res [ ' apiResponse ' ] [ ' ItemArray ' ] [ ' Item ' ] ]
else :
# No need to encase the list in another list
res [ ' apiResponse ' ] = res [ ' apiResponse ' ] [ ' ItemArray ' ] [ ' Item ' ]
# Yay no errors
if res [ ' error ' ] [ ' code ' ] == None :
res [ ' error ' ] [ ' code ' ] = ' 0 '
else :
# drop the response as it contains no useful information anymore
res [ ' apiResponse ' ] = { }
res [ ' error ' ] [ ' code ' ] = ' 5 '
res [ ' error ' ] [ ' msg ' ] = ' no items found - maybe the dateRange is too narrow? '
return res
2016-03-22 21:43:40 +00:00
# getItems uses the list of ItemIDs provided by getSeller to get specific information about each ItemID
2016-03-25 19:14:35 +00:00
def getItems ( api = None , itemList = None , itemArgs = None ) :
2016-03-24 19:40:29 +00:00
# api is the connection to the Trading API
# itemList is a dict containing ItemIDs and other info as a result of getSeller
# itemArgs is an optional dict that contains extra details to refine the search returned by ebay (http://developer.ebay.com/DevZone/XML/docs/Reference/ebay/GetItem.html)
# - The two required datapoints in itemArgs are IncludeItemSpecifics and ItemID, both are defined below in the loop
# Set our error conditions
res = { ' error ' : { ' code ' : None , ' msg ' : None , ' fnc ' : ' getItems ' } , ' apiResponse ' : { } }
2016-03-25 19:05:04 +00:00
if api == None :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 1 '
res [ ' error ' ] [ ' msg ' ] = ' api is not set '
return res
2016-03-25 19:05:04 +00:00
if ( itemList == None ) | ( type ( itemList ) != type ( [ ] ) ) :
2016-03-24 19:40:29 +00:00
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
2016-03-28 19:07:01 +00:00
if isinstance ( itemArgs , dict ) != True :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 2 '
res [ ' error ' ] [ ' msg ' ] = ' itemArgs doesn \' t exist or is of wrong type, must be dict '
return res
# For each ItemID
for k in itemList :
# Extra arguments that should be applied anyways
itemArgs [ ' IncludeItemSpecifics ' ] = ' True '
# Search for specific ItemID
itemArgs [ ' ItemID ' ] = k [ ' ItemID ' ]
# If the Item is not active, we don't want it - Prevents sending extra API resquests for data we don't want
if ( k [ ' SellingStatus ' ] [ ' ListingStatus ' ] != ' Active ' ) :
continue
2016-03-25 20:28:08 +00:00
res [ ' apiResponse ' ] [ k [ ' ItemID ' ] ] = api . execute ( ' GetItem ' , itemArgs ) . dict ( )
2016-03-24 19:40:29 +00:00
# We want the error code to only be changed on the first successful iteration
if res [ ' error ' ] [ ' code ' ] == None :
res [ ' error ' ] [ ' code ' ] = ' 0 '
# After the loop is complete, return the whole res
return res
2016-03-25 19:05:04 +00:00
# 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
2016-03-25 19:14:35 +00:00
def checkRevisedItems ( api = None , itemArgs = None , dateRange = None ) :
2016-03-25 19:05:04 +00:00
# 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
2016-03-25 20:28:08 +00:00
res = { ' error ' : { ' code ' : None , ' msg ' : None , ' fnc ' : ' checkRevisedItems ' } , ' apiResponse ' : { ' itemIDs ' : [ ] } }
2016-03-25 19:05:04 +00:00
if api == None :
res [ ' error ' ] [ ' code ' ] = ' 1 '
res [ ' error ' ] [ ' msg ' ] = ' api is not set '
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
2016-03-25 19:14:35 +00:00
if ( dateRange == None ) | ( isinstance ( dateRange , dict ) != True ) :
2016-03-25 20:28:08 +00:00
dateRange = setDateRange ( )
2016-03-25 19:05:04 +00:00
itemArgs [ ' NewItemFilter ' ] = ' True '
# Switch statement to select the proper dateRange
itemArgs = switchDateRange ( itemArgs , dateRange )
2016-03-25 20:28:08 +00:00
response = api . execute ( ' GetSellerEvents ' , itemArgs ) . dict ( )
try :
items = response [ ' ItemArray ' ] [ ' Item ' ]
2016-03-25 19:05:04 +00:00
2016-03-25 20:28:08 +00:00
# Store the ItemIDs that need to be updated again with getItem
for i in items :
res [ ' apiResponse ' ] [ ' itemIDs ' ] . append ( i [ ' ItemID ' ] )
except TypeError :
res [ ' apiResponse ' ] = { ' code ' : ' 1 ' , ' msg ' : ' No items were revised in the selected dateRange ' }
2016-03-25 19:05:04 +00:00
2016-03-25 20:28:08 +00:00
response = None
# No Errors found
if res [ ' error ' ] [ ' code ' ] == None :
res [ ' error ' ] [ ' code ' ] = ' 0 '
return res
2016-03-25 19:05:04 +00:00
2016-03-24 19:40:29 +00:00
2016-03-22 21:43:40 +00:00
# storeItems uses the dict of Items provided by getItems and stores the information we want
2016-03-25 19:14:35 +00:00
def storeItems ( itemList = None ) :
2016-03-24 19:40:29 +00:00
# itemList is the apiRequest value presented as a result of getItems
# - This contains every item that matches getItems criteria with the ItemID as the key of further dicts
2016-03-22 21:43:40 +00:00
2016-03-24 19:40:29 +00:00
# Set our error conditions
res = { ' error ' : { ' code ' : None , ' msg ' : None , ' fnc ' : ' storeItems ' } , ' apiResponse ' : { } }
2016-03-25 19:05:04 +00:00
if ( itemList == None ) | ( isinstance ( itemList , dict ) != True ) :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 2 '
res [ ' error ' ] [ ' msg ' ] = ' itemList doesn \' t exist or is of wrong type, must be dict '
return res
# Now that we've stored all the data in a really big dictionary, lets pull only the information we want out of it
for k in itemList :
res [ ' apiResponse ' ] [ k ] = { ' price ' : { } , ' condition ' : { } , ' quantity ' : { } }
condition = ' 0 '
# Switch statement - Sets condition.msg based on conditionID - based on table from http://developer.ebay.com/devzone/finding/callref/Enums/conditionIdList.html
def conCheck ( condition ) :
# Cast the condition to a string
condition = str ( condition )
switch = {
' 1000 ' : ' New ' ,
' 1500 ' : ' New Other ' ,
' 1750 ' : ' New with defects ' ,
' 2000 ' : ' Manufacturer Refurbished ' ,
' 2500 ' : ' Seller Refurbished ' ,
' 3000 ' : ' Used ' ,
' 4000 ' : ' Used/Very Good Condition ' ,
' 5000 ' : ' Used/Good Condition ' ,
' 6000 ' : ' Used/Acceptable Condition ' ,
' 7000 ' : ' For Parts/Not Working '
}
# Return the approiate text or N/A if no ID matches
return switch . get ( condition , ' N/A ' )
res [ ' apiResponse ' ] [ k ] [ ' title ' ] = itemList [ k ] [ ' Item ' ] [ ' Title ' ]
if ' ConditionID ' in itemList [ k ] [ ' Item ' ] :
# Override the condition defined at the start of the loop
condition = itemList [ k ] [ ' Item ' ] [ ' ConditionID ' ]
if ' SellingStatus ' in itemList [ k ] [ ' Item ' ] :
# Store current price + currency the price is in
res [ ' apiResponse ' ] [ k ] [ ' price ' ] [ ' cur ' ] = itemList [ k ] [ ' Item ' ] [ ' SellingStatus ' ] [ ' CurrentPrice ' ] [ ' _currencyID ' ]
res [ ' apiResponse ' ] [ k ] [ ' price ' ] [ ' val ' ] = itemList [ k ] [ ' Item ' ] [ ' SellingStatus ' ] [ ' CurrentPrice ' ] [ ' value ' ]
# Store the quantity - Subtract sold from total to get current value
res [ ' apiResponse ' ] [ k ] [ ' quantity ' ] [ ' sold ' ] = itemList [ k ] [ ' Item ' ] [ ' SellingStatus ' ] [ ' QuantitySold ' ]
res [ ' apiResponse ' ] [ k ] [ ' quantity ' ] [ ' total ' ] = itemList [ k ] [ ' Item ' ] [ ' Quantity ' ]
else :
res [ ' apiRequest ' ] [ k ] [ ' price ' ] [ ' cur ' ] = None
res [ ' apiRequest ' ] [ k ] [ ' price ' ] [ ' val ' ] = None
res [ ' apiRequest ' ] [ k ] [ ' quantity ' ] [ ' sold ' ] = None
res [ ' apiRequest ' ] [ k ] [ ' quantity ' ] [ ' total ' ] = None
# Get the item specifics - Special fields pertaining to the item, such as manufacturer and part number
if ' ItemSpecifics ' in itemList [ k ] [ ' Item ' ] :
# Try to for loop our data, if that fails, assume it's a dict with only one ItemSpecific
try :
for i in itemList [ k ] [ ' Item ' ] [ ' ItemSpecifics ' ] [ ' NameValueList ' ] :
name = i [ ' Name ' ]
if ( name == ' Brand ' ) :
res [ ' apiResponse ' ] [ k ] [ ' mfg ' ] = i [ ' Value ' ]
if ( name == ' MPN ' ) :
res [ ' apiResponse ' ] [ k ] [ ' mpn ' ] = i [ ' Value ' ]
except TypeError :
if itemList [ k ] [ ' Item ' ] [ ' ItemSpecifics ' ] [ ' NameValueList ' ] [ ' Name ' ] == ' Brand ' :
res [ ' apiResponse ' ] [ k ] [ ' mfg ' ] = itemList [ k ] [ ' Item ' ] [ ' ItemSpecifics ' ] [ ' NameValueList ' ] [ ' Value ' ]
res [ ' apiResponse ' ] [ k ] [ ' mpn ' ] = None
elif itemList [ k ] [ ' Item ' ] [ ' ItemSpecifics ' ] [ ' NameValueList ' ] [ ' Name ' ] == ' MPN ' :
res [ ' apiResponse ' ] [ k ] [ ' mpn ' ] = itemList [ k ] [ ' Item ' ] [ ' ItemSpecifics ' ] [ ' NameValueList ' ] [ ' Value ' ]
res [ ' apiResponse ' ] [ k ] [ ' mfg ' ] = None
else :
res [ ' apiResponse ' ] [ k ] [ ' mpn ' ] = None
res [ ' apiResponse ' ] [ k ] [ ' mfg ' ] = None
# Store the condition
res [ ' apiResponse ' ] [ k ] [ ' condition ' ] [ ' code ' ] = condition
res [ ' apiResponse ' ] [ k ] [ ' condition ' ] [ ' msg ' ] = conCheck ( condition )
# We want the error code to only be changed on the first successful iteration
if res [ ' error ' ] [ ' code ' ] == None :
res [ ' error ' ] [ ' code ' ] = ' 0 '
2016-03-22 21:43:40 +00:00
2016-03-24 19:40:29 +00:00
# After the loop is complete, return the whole res
return res
2016-03-22 21:43:40 +00:00
# Glue logic to run all the functions above properly
2016-03-25 19:14:35 +00:00
def glue ( api = None , sellerList = None , dateRange = None ) :
2016-03-24 19:40:29 +00:00
# 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)
# dateRange overrides EndTimeFrom and EndTimeTo from sellerList for ease of passing these required data with nothing else
2016-03-22 21:43:40 +00:00
2016-03-24 19:40:29 +00:00
# Set our error conditions
res = { ' error ' : { ' code ' : ' 0 ' , ' msg ' : None , ' fnc ' : ' glue ' } , ' apiResponse ' : { } }
2016-03-25 19:05:04 +00:00
if api == None :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 1 '
res [ ' error ' ] [ ' msg ' ] = ' api is not set '
return res
2016-03-25 19:05:04 +00:00
if ( sellerList == None ) | ( isinstance ( sellerList , dict ) != True ) :
2016-03-24 19:40:29 +00:00
res [ ' error ' ] [ ' code ' ] = ' 2 '
res [ ' error ' ] [ ' msg ' ] = ' itemList doesn \' t exist or is of wrong type, must be dict '
return res
2016-03-25 19:05:04 +00:00
if ( dateRange == None ) | ( isinstance ( dateRange , dict ) != True ) :
2016-03-25 20:28:08 +00:00
dateRange = setDateRange ( )
2016-03-23 18:06:15 +00:00
2016-03-25 19:05:04 +00:00
# Switch statement to select the proper dateRange
sellerList = switchDateRange ( sellerList , dateRange )
2016-03-24 19:40:29 +00:00
seller = getSeller ( api , sellerList )
if seller [ ' error ' ] [ ' code ' ] == ' 0 ' :
sellerList = seller [ ' apiResponse ' ]
seller = None # Unset any data we no-longer need - Saves on memory
2016-03-28 19:07:01 +00:00
items = getItems ( api , sellerList , { } )
2016-03-24 19:40:29 +00:00
if items [ ' error ' ] [ ' code ' ] == ' 0 ' :
sellerList = items [ ' apiResponse ' ]
items = storeItems ( sellerList )
storedItems = items [ ' apiResponse ' ]
items = None
return storedItems
else :
res [ ' error ' ] = items [ ' error ' ]
return res
else :
res [ ' error ' ] = seller [ ' error ' ]
return res
2016-03-22 21:43:40 +00:00
try :
2016-03-24 19:40:29 +00:00
p = Parallel ( )
2016-03-24 19:17:31 +00:00
2016-03-24 19:40:29 +00:00
api = Trading ( domain = domain , appid = app_id , devid = dev_id , certid = crt_id , token = usr_token , config_file = None , debug = False , parellel = p )
2016-03-22 21:43:40 +00:00
2016-03-24 19:40:29 +00:00
# Example usage, returns a dict containing all items of interst (based on the functions above)
2016-03-29 14:59:10 +00:00
# To import a whole lot of data from ebay, we need to pull in dateRange increments of ~20 days
# Easiest way would be to have a starting date and then look forward 20 days with the delta
itemData = glue ( api = api , sellerList = { } , dateRange = { ' from ' : ' 2016-03-01T00:00:00.000Z ' , ' to ' : ' 2016-03-28T23:59:59.999Z ' , ' type ' : ' start ' } )
2016-03-24 19:40:29 +00:00
itemlist = [ ]
2016-03-22 21:43:40 +00:00
2016-03-25 19:05:04 +00:00
# Write a CSV file containing some of the data we're interested in
with open ( csv_path , ' wb ' ) as csvfile :
fieldnames = [ ' Part Number ' , ' Manufacturer ' , ' Condition ' , ' Price ' , ' Quantity ' , ' Description ' ]
writer = csv . DictWriter ( csvfile , fieldnames = fieldnames , delimiter = csv_delimiter , quotechar = csv_quote , quoting = csv . QUOTE_MINIMAL )
2016-03-24 19:17:31 +00:00
2016-03-28 19:07:01 +00:00
writer . writerow ( { ' Part Number ' : ' Part Number ' , ' Manufacturer ' : ' Manufacturer ' , ' Condition ' : ' Condition ' , ' Price ' : ' Price ' , ' Quantity ' : ' Quantity ' , ' Description ' : ' Description ' } )
2016-03-25 19:05:04 +00:00
for i in itemData :
2016-03-28 19:07:01 +00:00
def keyCheck ( key ) :
try :
data = itemData [ i ] [ key ]
return data
except KeyError :
data = ' N/a '
return data
try :
price = itemData [ i ] [ ' price ' ] [ ' val ' ]
except KeyError :
price = ' N/a '
try :
quantity = str ( int ( itemData [ i ] [ ' quantity ' ] [ ' total ' ] ) - int ( itemData [ i ] [ ' quantity ' ] [ ' sold ' ] ) )
except KeyError :
quantity = ' N/a '
2016-03-25 19:05:04 +00:00
data = {
2016-03-28 19:07:01 +00:00
' Part Number ' : keyCheck ( ' mpn ' ) ,
' Manufacturer ' : keyCheck ( ' mfg ' ) ,
' Condition ' : itemData [ i ] [ ' condition ' ] [ ' msg ' ] ,
' Price ' : price ,
' Quantity ' : quantity ,
' Description ' : keyCheck ( ' title ' ) . encode ( ' utf-8 ' )
2016-03-25 19:05:04 +00:00
}
writer . writerow ( data )
2016-03-24 19:40:29 +00:00
2016-03-25 19:05:04 +00:00
# Store the itemIDs so that we can use them to check which ones were modified
itemlist . append ( i )
except ConnectionError as e :
print ( e )