def revise_ebay_price(item_code, new_price, is_auction): """Given item_code and (inc vat) price, revise the listing on eBay""" #get the ebay id given the item_code ebay_id = frappe.get_value('Item', item_code, 'ebay_id') if ebay_id and item_code and new_price: try: new_price_inc = float(new_price) api_trading = Trading(config_file=PATH_TO_YAML, warnings=True, timeout=20) if is_auction: api_trading.execute('ReviseItem', {'Item':{'ItemID':ebay_id, \ 'StartPrice':new_price_inc}}) else: # ReviseInventoryStatus enables change to price and/or quantity of an active, fixed-price listing. # The fixed-price listing is identified with the ItemID of the listing or the SKUvalue of the item api_trading.execute('ReviseInventoryStatus', {'InventoryStatus':{'ItemID':ebay_id, \ 'StartPrice':new_price_inc}}) except ConnectionError: return ("Connection Error - possibly ebay.yaml file not found") except Exception: return ("Price sync. There was a problem using the eBay Api") #raise else: return ("Price sync success - eBay listing updated!") else: return ("Price Sync Error: There was a problem getting with the item_code, price or ebayid")
def get_item(item_id=None, item_code=None, site_id=default_site_id): """Returns a single listing from the eBay TradingAPI.""" if not (item_code or item_id): raise ValueError('No item_code or item_id passed to get_item!') api_dict = {'IncludeWatchCount': True} if item_code: api_dict['SKU'] = item_code if item_id: api_dict['ItemID'] = item_id try: # Initialize TradingAPI; default timeout is 20. api = Trading(config_file=PATH_TO_YAML, siteid=site_id, warnings=True, timeout=20) api.execute('GetItem', api_dict) listing = api.response.dict() test_for_message(listing) except ConnectionError as e: handle_ebay_error(e) if six.PY2: # Convert all strings to unicode listing = convert_to_unicode(listing) return listing['Item']
def get_myebay_selling_request(page): """get_myebay_selling_request""" try: api_trading = Trading(config_file=PATH_TO_YAML, warnings=True, timeout=20) api_request = { "ActiveList": { "Include": True, "Pagination": { "EntriesPerPage": 100, "PageNumber": page }, "IncludeWatchCount": True }, 'DetailLevel': 'ReturnAll' } api_trading.execute('GetMyeBaySelling', api_request) products = api_trading.response.dict() except ConnectionError as e: print(e) print(e.response.dict()) raise e return products
def memberMessages(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True) now = datetime.datetime.now() memberData = { "WarningLevel": "High", "MailMessageType": "All", # "MessageStatus": "Unanswered", "StartCreationTime": now - datetime.timedelta(days=60), "EndCreationTime": now, "Pagination": { "EntriesPerPage": "5", "PageNumber": "1" } } api.execute('GetMemberMessages', memberData) dump(api) if api.response_dict().MemberMessage: messages = api.response_dict().MemberMessage.MemberMessageExchange if type(messages) != list: messages = [ messages ] for m in messages: print("%s: %s" % (m.CreationDate, m.Question.Subject[:50])) except ConnectionError as e: print e
def get_orders(): """Returns a list of recent orders from the eBay TradingAPI. This list is NOT filtered by a siteid as the API call does not filter by siteid. """ num_days = frappe.db.get_value( 'eBay Manager Settings', filters=None, fieldname='ebay_sync_days') try: if num_days < 1: frappe.msgprint('Invalid number of days: ' + str(num_days)) except TypeError: raise ValueError('Invalid type in ebay_sync_days') orders = [] page = 1 try: # Initialize TradingAPI; default timeout is 20. # Always use the US site for GetOrders as it returns fields we need # (which the UK site, for example, doesn't) and it doesn't filter by # siteID anyway api = Trading(config_file=PATH_TO_YAML, siteid=0, warnings=True, timeout=20) while True: # TradingAPI results are paginated, so loop until # all pages have been obtained api.execute('GetOrders', { 'NumberOfDays': num_days, 'Pagination': { 'EntriesPerPage': 50, 'PageNumber': page} }) orders_api = api.response.dict() test_for_message(orders_api) n_orders = int(orders_api['ReturnedOrderCountActual']) if n_orders == 1: orders.append(orders_api['OrderArray']['Order']) elif n_orders > 0: orders.extend(orders_api['OrderArray']['Order']) if orders_api['HasMoreOrders'] == 'false': break page += 1 except ConnectionError as e: handle_ebay_error(e) if six.PY2: # Convert all strings to unicode orders = convert_to_unicode(orders) return orders, num_days
def verifyAddItemErrorCodes(opts): """http://www.utilities-online.info/xmltojson/#.UXli2it4avc """ try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=False) myitem = { "Item": { "Title": "Harry Potter and the Philosopher's Stone", "Description": "This is the first book in the Harry Potter series. In excellent condition!", "PrimaryCategory": {"CategoryID": "377aaaaaa"}, "StartPrice": "1.0", "CategoryMappingAllowed": "true", "Country": "US", "ConditionID": "3000", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": "Days_7", "ListingType": "Chinese", "PaymentMethods": "PayPal", "PayPalEmailAddress": "*****@*****.**", "PictureDetails": {"PictureURL": "http://i1.sandbox.ebayimg.com/03/i/00/30/07/20_1.JPG?set_id=8800005007"}, "PostalCode": "95125", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the book for refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "USPSMedia", "ShippingServiceCost": "2.50" } }, "Site": "US" } } api.execute('VerifyAddItem', myitem) except ConnectionError as e: # traverse the DOM to look for error codes for node in api.response.dom().findall('ErrorCode'): print("error code: %s" % node.text) # check for invalid data - error code 37 if 37 in api.response_codes(): print("Invalid data in request") print(e) print(e.response.dict())
def getOrders(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True, timeout=20) api.execute('GetOrders', {'NumberOfDays': 30}) dump(api, full=False) except ConnectionError as e: print e
def getTokenStatus(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=False) api.execute('GetTokenStatus') dump(api) except ConnectionError as e: print e
def getUser(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True, timeout=20, siteid=101) api.execute('GetUser', {'UserID': 'biddergoat'}) dump(api, full=False) except ConnectionError as e: print e
def run(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid) api.execute('GetCharities', {'CharityID': 3897}) dump(api) print(api.response_dict().Charity.Name) except ConnectionError as e: print e
def check_ebay_item_exists(itemID): ''' True if Item exists ''' try: api = Trading(debug=False, config_file=config_file, appid=appid, certid=certid, devid=devid,warnings=False) api.execute('GetItem', {'ItemID': itemID}) return True except ConnectionError as e: return False
def getUser(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True, timeout=20, siteid='101') api.execute('GetUser', {'UserID': 'sallyma789'}) dump(api, full=False) except ConnectionError as e: print(e) print(e.response.dict())
def get_ebay_item_price(itemID): ''' searches for itemID and returns the start price. ''' try: api = Trading(debug=False, config_file=config_file, appid=appid, certid=certid, devid=devid,warnings=False) api.execute('GetItem', {'ItemID': itemID}) return float(api.response.reply.Item.StartPrice.value) except ConnectionError as e: print(e) print(e.response.dict()) return False
def feedback(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=False) api.execute('GetFeedback', {'UserID': 'tim0th3us'}) dump(api) if int(api.response_dict().FeedbackScore) > 50: print("Doing good!") else: print("Sell more, buy more..") except ConnectionError as e: print e
def get_seller_list(item_codes=None, site_id=default_site_id): """Runs GetSellerList to obtain a list of items.""" # Create eBay acceptable datetime stamps for EndTimeTo and EndTimeFrom end_from = datetime.utcnow().isoformat()[:-3] + 'Z' end_to = (datetime.utcnow() + timedelta(days=119)).isoformat()[:-3] + 'Z' listings = [] try: # Initialize TradingAPI; default timeout is 20. api = Trading(config_file=PATH_TO_YAML, siteid=site_id, warnings=True, timeout=20) page = 1 while True: # TradingAPI results are paginated, so loop until # all pages have been obtained api.execute('GetSellerList', { 'SKUArray': {'SKU': item_codes}, 'EndTimeTo': end_to, 'EndTimeFrom': end_from, 'Pagination': { 'EntriesPerPage': 50, 'PageNumber': page} }) listings_api = api.response.dict() test_for_message(listings_api) n_listings = int(listings_api['ReturnedItemCountActual']) if n_listings == 1: listings.append(listings_api['ItemArray']['Item']) elif int(listings_api['ReturnedItemCountActual']) > 0: listings.extend(listings_api['ItemArray']['Item']) if listings_api['HasMoreItems'] == 'false': break page += 1 except ConnectionError as e: handle_ebay_error(e) if six.PY2: # Convert all strings to unicode listings = convert_to_unicode(listings) return listings
def get_eBay_details(site_id=default_site_id, detail_name=None): """Perform a GeteBayDetails call.""" try: # Initialize TradingAPI; default timeout is 20. api = Trading(config_file=PATH_TO_YAML, siteid=site_id, warnings=True, timeout=20) api_options = {} if detail_name is not None: api_options['DetailName'] = detail_name response = api.execute('GeteBayDetails', api_options) except ConnectionError as e: handle_ebay_error(e) response_dict = response.dict() test_for_message(response_dict) if six.PY2: # Convert all strings to unicode response_dict = convert_to_unicode(response_dict) return response_dict
def uploadPicture(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True) pictureData = { "WarningLevel": "High", "ExternalPictureURL": "http://developer.ebay.com/DevZone/XML/docs/images/hp_book_image.jpg", "PictureName": "WorldLeaders" } api.execute('UploadSiteHostedPictures', pictureData) dump(api) except ConnectionError as e: print e
def categories(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True, timeout=20, siteid=101) callData = { 'DetailLevel': 'ReturnAll', 'CategorySiteID': 101, 'LevelLimit': 4, } api.execute('GetCategories', callData) dump(api, full=False) except ConnectionError as e: print e
def test_get_user(item): api = Connection(config_file='ebay.yaml') details_dict = dict() try: response = api.execute('GetUser',{"UserID":item,"DetailLevel":"ReturnAll"}) details = response.reply print details except Exception as e: print e
def test_get_item(item): api = Connection(config_file='ebay.yaml') details_dict = dict() try: response = api.execute('GetItem',{"ItemID":item,"OutputSelector":"Seller","DetailLevel":"ReturnAll"}) details = response.reply.Item print details except Exception as e: print e
def get_categories(site_id=default_site_id): """Load the eBay categories for the categories cache.""" try: # Initialize TradingAPI; default timeout is 20. api = Trading(config_file=PATH_TO_YAML, siteid=site_id, warnings=True, timeout=60) response = api.execute('GetCategories', {'DetailLevel': 'ReturnAll', 'ViewAllNodes': 'true'}) except ConnectionError as e: handle_ebay_error(e) categories_data = response.dict() if six.PY2: # Convert all strings to unicode categories_data = convert_to_unicode(categories_data) # Process the remaining categories data cl = categories_data['CategoryArray']['Category'] # Use one dictionary element per level, to store each Category against its # CategoryID. For simplicity don't use the first [0] level as CategoryLevel # is one-indexed. levels = [] for cat in cl: cat['Children'] = [] cat_level = int(cat['CategoryLevel']) while cat_level > len(levels)-1: levels.append({}) # Add the category to the relevant level dictionary levels[cat_level][cat['CategoryID']] = cat max_level = len(levels) - 1 # Loop over all deeper levels; connect categories to their parents for parent_level, level_dict in enumerate(levels[2:], start=1): for cat in level_dict.values(): parent = levels[parent_level][cat['CategoryParentID']] parent['Children'].append(cat) # Sort the Children list of each category according to its CategoryName for cat in cl: cat['Children'].sort(key=operator.itemgetter('CategoryName')) # Sort the top level list according to the CategoryName of the categories top_level = levels[1].values() top_level.sort(key=operator.itemgetter('CategoryName')) categories_data['TopLevel'] = top_level del categories_data['CategoryArray'] # Return the new categories return categories_data, max_level
class ItemRequest: def __init__(self, credentials): self.trading = Trading(config_file=None, **credentials) def get_items(self, fields): for page_num in itertools.count(1): response = self._get_page(page_num, fields) activelist = response.reply.ActiveList page_count = int(activelist.PaginationResult.TotalNumberOfPages) print('Page {} of {}'.format(page_num, page_count)) for item in response.dict()['ActiveList']['ItemArray']['Item']: yield item if page_count == page_num: break def get_item_ids(self): for item in self.get_items(fields=[]): yield item['ItemID'] def get_item(self, item_id, params): params.update({'ItemID': item_id}) response = self.trading.execute('GetItem', params) return response.dict()['Item'] def _get_page(self, page_num, fields=[]): fields = fields + [ 'ActiveList.PaginationResult', 'ActiveList.ItemArray.Item.ItemID', ] return self.trading.execute('GetMyeBaySelling', { 'ActiveList': { 'Include': True, 'Pagination': { 'PageNumber': page_num } }, 'OutputSelector': fields, })
def getxml(myset): mycon = Connection(domain='api.ebay.com', appid='ZhouPeng-3242-4cc7-88fd-310f513fcd71', devid='df3f2898-65b1-4e15-afd5-172b989903aa', certid='a0e19cf9-9b2b-457f-b6f1-87f3f600ca63', token='AgAAAA**AQAAAA**aAAAAA**cJyLVQ**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wMkoqiC5mHoQmdj6x9nY+seQ**N+QCAA**AAMAAA**nLCwNt4AQt1TRtd2ydNIMuZ2JYnQZKVVYarn41QQfBSqccEDld22ltKr+C/HJTN8AKD4+jn/nIEqtjNMkmh9sxTIa6jVVLAH5sN/93X7gTCmTkOsE/Av612U90nRoyQJ5bX1+NO25tMDZs9U0aTJIwVVu1BAB8/nsjL0pTCWw7KZACJ+a/aQ6swXLvSvOCWIBjFyCaWibKZseT2LoJMvJQmC2QpIuDsQ8cTYozLUYZqC88uKAjo7DNWIvaPVCdwkp/Vux3arR1Asin4ewX1l+LWCamWsXeBiVyaYq/oEUXABgknieVAPEpaFAfSzlrcTNmTWLBDDRwRGI/8hJCwK6/eJWexGrLk7U7p0kRltktNseTckAKT7g1ED4C5gUeQ4/nTHsNQBejUPTzTlwBWTJpwRaBFD7dAlbagH+TKaEJK41Esf/ZpL2599LUMolsO8tBgo0BhtCF/bYtdUUfopksIKNUwPXikadUxx6TurknnTtR1WDD229uUJIIf9BCS68WB56OfDTdXcZ8rdPZ0zdHuw5+BRxrumpFUzTQb5fJeHRDLPtQbLdX5rFPrS+NPJl6Qzi7bWNxUCydNQcIzKv7xLquIPoPx8bD1PRCoQbzjTQsOqhe9PBvLtcJ0Ggve78YjQKb5nDt6YThZ6D+1EOKdcthU03VizDfBKBLJ/NPqktDTx74tsS3l4feAjblGDoQ2RZXefJ9Jk3t+Qc4khlvl4mKpjZ4sCakh4qPWr9H6t3CN80hz5MO1Y7uHPUY61', ) for ele in myset: myrequest={'ItemID':ele,'IncludeWatchCount':True} myresponse=mycon.execute('GetItem',myrequest) yield myresponse.text
def run(api_request, params): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid) response = api.execute(api_request, params) dump(api) # print(api.response.reply.Charity.Name) return response.dict() except ConnectionError as e: print(e) print(e.response.dict())
def uploadPictureFromFilesystem(opts, filepath): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=True) # pass in an open file # the Requests module will close the file files = {'file': ('EbayImage', open(filepath, 'rb'))} pictureData = { "WarningLevel": "High", "PictureName": "WorldLeaders" } api.execute('UploadSiteHostedPictures', pictureData, files=files) dump(api) except ConnectionError as e: print(e) print(e.response.dict())
def GetOrders( CreateTimeFrom=None, CreateTimeTo=None, IncludeFinalValueFee=False, ModTimeFrom=None, ModTimeTo=None, NumberOfDays=None, OrderID=None, DetailLevel=None ): options = {} if CreateTimeFrom: options['CreateTimeFrom'] = CreateTimeFrom if CreateTimeTo: options['CreateTimeTo'] = CreateTimeTo if IncludeFinalValueFee: options['IncludeFinalValueFee'] = str(IncludeFinalValueFee).lower() if ModTimeFrom: options['ModTimeFrom'] = ModTimeFrom if ModTimeTo: options['ModTimeTo'] = ModTimeTo if NumberOfDays: options['NumberOfDays'] = int(NumberOfDays) if OrderID: options['OrderIDArray'] = { 'OrderID': OrderID } if DetailLevel: options['DetailLevel'] = DetailLevel trading = Trading() options['Pagination'] = { 'EntriesPerPage': '1000', 'PageNumber': 0 } has_more = True while has_more: options['Pagination']['PageNumber'] += 1 try: response = trading.execute('GetOrders', options) except ConnectionError as e: raise Exception('ConnectionError:\n%s' % json.dumps(e.response.dict(), sort_keys=True, indent=5)) else: yield response has_more = response.dict().get('HasMoreEntries') == "true"
def get_categories_versions(site_id=default_site_id): """Load the version number of the current eBay categories and category features. """ try: # Initialize TradingAPI; default timeout is 20. api = Trading(config_file=PATH_TO_YAML, siteid=site_id, warnings=True, timeout=20) response1 = api.execute('GetCategories', {'LevelLimit': 1, 'ViewAllNodes': False}) test_for_message(response1.dict()) response2 = api.execute('GetCategoryFeatures', {}) test_for_message(response2.dict()) except ConnectionError as e: handle_ebay_error(e) categories_version = response1.reply.CategoryVersion features_version = response2.reply.CategoryVersion return (categories_version, features_version)
def test_AddFixedPriceItem(): try: api = Trading(config_file=config_file, appid=appid, certid=certid, devid=devid, warnings=False) myitem = { "Item": { "Title": "Harry Potter and the Philosopher's Stone", "Description": "This is the first book in the Harry Potter series. In excellent condition!", "PrimaryCategory": {"CategoryID": "377"}, "StartPrice": "100", "CategoryMappingAllowed": "true", "Country": "US", "ConditionID": "3000", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": "Days_7", "ListingType": "FixedPriceItem", "PaymentMethods": "PayPal", "PayPalEmailAddress": "*****@*****.**", "PictureDetails": {"PictureURL": "https://upload.wikimedia.org/wikipedia/en/b/bf/Harry_Potter_and_the_Sorcerer's_Stone.jpg"}, "PostalCode": "95125", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the book for refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "UPS3rdDay", "ShippingServiceCost": "2.50" } }, "Site": "US" } } return(api.execute('VerifyAddFixedPriceItem', myitem)) except ConnectionError as e: print(e) print(e.response.dict())
class GetList(object): # faieldlisting=Queue.Queue() def __init__(self, domain='api.ebay.com', appid='ZhouPeng-3242-4cc7-88fd-310f513fcd71', devid='df3f2898-65b1-4e15-afd5-172b989903aa', certid='a0e19cf9-9b2b-457f-b6f1-87f3f600ca63', token='AgAAAA**AQAAAA**aAAAAA**cJyLVQ**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wMkoqiC5mHoQmdj6x9nY+seQ**N+QCAA**AAMAAA**nLCwNt4AQt1TRtd2ydNIMuZ2JYnQZKVVYarn41QQfBSqccEDld22ltKr+C/HJTN8AKD4+jn/nIEqtjNMkmh9sxTIa6jVVLAH5sN/93X7gTCmTkOsE/Av612U90nRoyQJ5bX1+NO25tMDZs9U0aTJIwVVu1BAB8/nsjL0pTCWw7KZACJ+a/aQ6swXLvSvOCWIBjFyCaWibKZseT2LoJMvJQmC2QpIuDsQ8cTYozLUYZqC88uKAjo7DNWIvaPVCdwkp/Vux3arR1Asin4ewX1l+LWCamWsXeBiVyaYq/oEUXABgknieVAPEpaFAfSzlrcTNmTWLBDDRwRGI/8hJCwK6/eJWexGrLk7U7p0kRltktNseTckAKT7g1ED4C5gUeQ4/nTHsNQBejUPTzTlwBWTJpwRaBFD7dAlbagH+TKaEJK41Esf/ZpL2599LUMolsO8tBgo0BhtCF/bYtdUUfopksIKNUwPXikadUxx6TurknnTtR1WDD229uUJIIf9BCS68WB56OfDTdXcZ8rdPZ0zdHuw5+BRxrumpFUzTQb5fJeHRDLPtQbLdX5rFPrS+NPJl6Qzi7bWNxUCydNQcIzKv7xLquIPoPx8bD1PRCoQbzjTQsOqhe9PBvLtcJ0Ggve78YjQKb5nDt6YThZ6D+1EOKdcthU03VizDfBKBLJ/NPqktDTx74tsS3l4feAjblGDoQ2RZXefJ9Jk3t+Qc4khlvl4mKpjZ4sCakh4qPWr9H6t3CN80hz5MO1Y7uHPUY61', # timeout=3 ): self.idomain=domain self.iappid=appid self.idevid=devid self.icertid=certid self.itoken=token # self.timeout= self.mycon=Connection(domain=self.idomain, appid=self.iappid, devid=self.idevid, certid=self.icertid, token=self.itoken, timeout=3 ) def get_list(self,userid,starttimefrom,starttimeto): request={'UserID':userid,"StartTimeFrom":starttimefrom,'StartTimeTo':starttimeto} pattern=re.compile(r'<ItemID>(.*?)</ItemID>') fails=0 # tstart=time.time while fails<8: try: myresponse=self.mycon.execute('GetSellerList',request) itemarry=re.findall(pattern,myresponse.text) if itemarry: return itemarry else: print '%s between %s and %s :empty itemarry' (userid,starttimefrom,starttimeto) fails+=1 # except Exception as e: except: # print(e) print '%s between %s and %s :fails %s' % (userid,starttimefrom,starttimeto,fails) with open('/home/james/getlist.log','a') as log: log.write(time.ctime()+':'+userid+'between'+starttimefrom+'and'+starttimeto+':fails'+str(fails)+'\n') fails+=1
def get_item_details(itemid): api = Connection(config_file="ebay.yaml") request = { "ItemID":itemid, "OutputSelector":"Item", } item_details = dict() try: response = api.execute("GetItem",request) item_details_tree = response.reply.Item item_details["itemid"]=itemid item_details["quantitysold"] = item_details_tree.SellingStatus.QuantitySold item_details["hitcount"] = item_details_tree.HitCount # print item_details except Exception as e: print e return item_details
while True: data = {} try: api = Trading( debug=False, config_file=None, appid='appid', # replace certid='certid', # replace devid='devid', # replace token='token' # replace ) activeList = api.execute('GetMyeBaySelling', { 'ActiveList': True, 'DetailLevel': 'ReturnAll' }) if activeList.reply.Ack == 'Success': for index, item in enumerate( activeList.reply.ActiveList.ItemArray.Item): data = tryToAdd(data, 'shop', 'shopName') # replace data = tryToAdd(data, 'title', item.Title) if 'BuyItNowPrice' in activeList._dict.get( 'ActiveList').get('ItemArray').get( 'Item')[index].keys(): data = tryToAdd(data, 'buyPrice', item.BuyItNowPrice.get('value'))
def revise_generic_items(item_code): """Generic Revise eBay listings """ #get the ebay id given the item_code ebay_id = frappe.get_value('Item', item_code, 'ebay_id') if ebay_id and item_code: frappe.msgprint('This Item is on eBay. Please wait while the listing is revised...') item_name,\ description,\ function_grade,\ grade_details,\ condition,\ tech_details,\ delivery_type,\ accessories_extras,\ power_cable_included,\ power_supply_included,\ remote_control_included,\ case_included,\ warranty_period\ = get_item_revisions(item_code) version = 0 body = """<![CDATA[""" body += jtemplate(version, description, function_grade, grade_details, condition, \ tech_details, delivery_type, accessories_extras, \ power_cable_included, power_supply_included, remote_control_included, \ case_included, warranty_period) body += "<br></br>The price includes VAT and we can provide VAT invoices." body += "<br></br>Universities and colleges - purchase orders accepted - please contact us." body += "<br></br>sku: " + item_code body += """]]>""" condition_description = '' #grade_details condition_id_text, condition_id = lookup_condition(condition, 0) new_gsp = (delivery_type == 'Standard Parcel') try: api_trading = Trading(config_file=PATH_TO_YAML, warnings=True, timeout=20) #EXAMPLE api.execute('ReviseItem',{'Item':{'ItemID':ItemID},'Title':words} api_trading.execute('ReviseItem',{ 'Item':{'ItemID': ebay_id}, 'GlobalShipping': new_gsp, 'Title': item_name, 'Description': body, 'ConditionDescription': condition_description, 'ConditionID': condition_id } ) except ConnectionError: frappe.msgprint("Config file ebay.yaml file not found") raise except Exception: frappe.msgprint("There was a problem using the eBay Api") raise else: frappe.msgprint("Success eBay listing updated!") else: frappe.msgprint("There was a problem getting the data")
def upload_template(self, row): try: api = Trading(config_file=self.config) params = {} task_id = row['_id'] params['task_id'] = str(task_id) params['template_id'] = str(row['template_id']) params['suffix'] = row['suffix'] params['sku'] = '' params['type'] = self.log_type[1] task_params = {'id': task_id, 'status': 'success'} # 获取模板和token信息 template = self.get_ebay_template(row['template_id']) if template: # 检验模板是否有问题 flag = self.pre_check(template) if not flag: # 标记为刊登失败 task_params['item_id'] = '' task_params['status'] = 'failed' self.update_task_status(task_params) message = f"template of {row['template_id']} is invalid" params['info'] = message self.add_log(params) self.logger.error(message) return parent_sku = template['Item']['SKU'] params['sku'] = parent_sku # 判断ebay后台是否有该产品 # print(template) check = self.check_ebay_template(api, template) print(check) if not check: # try: trade_response = api.execute( 'VerifyAddFixedPriceItem', # 'AddFixedPriceItem', template) ret = trade_response.dict() print(ret) # if ret['Ack'] == 'Success': # task_params['item_id'] = ret['data']['Item']['ItemID'] # # self.upload_variation(template['variants'], template['access_token'], parent_sku, params) # self.update_task_status(task_params) # self.update_template_status(row['template_id'], ret['data']['Product']['id']) # else: # params['info'] = ret['message'] # self.add_log(params) # self.logger.error(f"failed to upload product {parent_sku} cause of {ret['message']}") # except Exception as why: # self.logger.error(f"fail to upload of product {parent_sku} cause of {why}") # else: # task_params['item_id'] = check # self.update_task_status(task_params) # self.update_template_status(row['template_id'], check) # params['info'] = f'products {parent_sku} already exists' # self.add_log(params) # self.logger.error(f"fail cause of products {parent_sku} already exists") # else: # task_params['item_id'] = '' # task_params['status'] = 'failed' # self.update_task_status(task_params) # params['info'] = f"can not find template {row['template_id']} Maybe the account is not available" # self.add_log(params) # self.logger.error(f"fail cause of can not find template {row['template_id']}") except Exception as e: self.logger.error( f"upload {str(row['template_id'])} error cause of {e}")
def escape(str): str = str.replace("&", "-") return str api = Trading(config_file='ebay.yaml', siteid='203') request = {} request["ActiveList"] = {"Include": "true"} request["ActiveList"] = {"ListingType": "FixedPriceItem"} request["ActiveList"] = {"Pagination": {"EntriesPerPage": 1}} request["ActiveList"] = {"Pagination": {"PageNumber": 1}} db = MySQLdb.connect("localhost", "root", "", "ameb") cursor = db.cursor() response = api.execute("GetMyeBaySelling", request) xml = response.dict() print xml pages = xml["ActiveList"]["PaginationResult"]["TotalNumberOfPages"] print "pages=" + str(pages) items = xml["ActiveList"]["ItemArray"]["Item"] cnt = len(items) for idx in range(0, cnt): itemid = items[idx]["ItemID"] price = items[idx]["BuyItNowPrice"]["value"] sql_query = "SELECT id,ebayprice from ft_product WHERE itemID='" + str( itemid) + "'" cursor.execute(sql_query) results = cursor.fetchall() if len(results) == 0: continue
def main(): try: api = Trading( config_file=None, domain='api.ebay.com', appid="SatyaPra-MyEBPrac-PRD-abce464fb-dd2ae5fe", devid="6c042b69-e90f-4897-9045-060858248665", certid= "AgAAAA**AQAAAA**aAAAAA**zY2pXg**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6MElIuoC5CEpAydj6x9nY+seQ**/0kGAA**AAMAAA**7/kuig0GXA6zyrQ/D6lHcXQVtH2z/rLeU4EzvA4jqRnDtBEXlUMdK5ZuE0EpkrfiI7bUcY6xVnn9C/6Iajfk9uhKoayDerpacV7wwRbELehUna4jXa57klixCENuF6UbPprzmnbIVt0pdoWNw5Yfa9dSEZb6FKw4eVwWwwABNUOIxd7ozBMVoZwywBQ5JwOKl2U8wzfnxzNH/tiSn5NSkiqOJztVlOT5XZWPB1wlaoZsLrGBxZDEeAQ3C+fKOm5NJIpEn6YCZF7u0SPulv2I4gcXCJVUQ8en7bClXajs4c/Qfo+gelpYHKKeTWVInQbqcEF+OoUcA0deqjYgIxsJ6J0iRXQoaESYV1tZ1zLVvNcxrysuwVpV7Iwjs5alfKQmAgVlBFjstbi3Pgr/NFR3s3srGR6DLoBNfF6w2yP6LE7+KVK+rxbzz8hE0yAJ06WpOrgJmmkZd0jxaLlImTsNHB2CxmwkWimoEEwwq/DirLhNxS4SHs34LMxeoRVOxDG39VrQcDe0q+18aCX2SPHRmBcGvcV4x+a6JqwhenMVZiKypQq/RQpeD7PeVSQAh1Vd3zvRB8w1zvoUAHmL9JWCfrnwe2fVDBr/DfE9IpPmYNCbvLhpxAMMYMMS0RzwPCpriCdleJi7wBqKJ/jseQOndNWb028A8jnWzXPMkgbF+P5sj+Tu48XY56E7Oe1NmynMg0EswO3PwdFd9Cevdkbn6CbuSGloK2JQ3P28rnRjzh8LEdYSR+iL3mMpuR7N9BgF" ) items = list() inputObj = { "RequesterCredentials": { "eBayAuthToken": "AgAAAA**AQAAAA**aAAAAA**zY2pXg**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6MElIuoC5CEpAydj6x9nY+seQ**/0kGAA**AAMAAA**7/kuig0GXA6zyrQ/D6lHcXQVtH2z/rLeU4EzvA4jqRnDtBEXlUMdK5ZuE0EpkrfiI7bUcY6xVnn9C/6Iajfk9uhKoayDerpacV7wwRbELehUna4jXa57klixCENuF6UbPprzmnbIVt0pdoWNw5Yfa9dSEZb6FKw4eVwWwwABNUOIxd7ozBMVoZwywBQ5JwOKl2U8wzfnxzNH/tiSn5NSkiqOJztVlOT5XZWPB1wlaoZsLrGBxZDEeAQ3C+fKOm5NJIpEn6YCZF7u0SPulv2I4gcXCJVUQ8en7bClXajs4c/Qfo+gelpYHKKeTWVInQbqcEF+OoUcA0deqjYgIxsJ6J0iRXQoaESYV1tZ1zLVvNcxrysuwVpV7Iwjs5alfKQmAgVlBFjstbi3Pgr/NFR3s3srGR6DLoBNfF6w2yP6LE7+KVK+rxbzz8hE0yAJ06WpOrgJmmkZd0jxaLlImTsNHB2CxmwkWimoEEwwq/DirLhNxS4SHs34LMxeoRVOxDG39VrQcDe0q+18aCX2SPHRmBcGvcV4x+a6JqwhenMVZiKypQq/RQpeD7PeVSQAh1Vd3zvRB8w1zvoUAHmL9JWCfrnwe2fVDBr/DfE9IpPmYNCbvLhpxAMMYMMS0RzwPCpriCdleJi7wBqKJ/jseQOndNWb028A8jnWzXPMkgbF+P5sj+Tu48XY56E7Oe1NmynMg0EswO3PwdFd9Cevdkbn6CbuSGloK2JQ3P28rnRjzh8LEdYSR+iL3mMpuR7N9BgF" }, "ErrorLanguage": "en_US", "WarningLevel": "High", "GranularityLevel": "Coarse", "StartTimeFrom": "2020-01-30 23:29:25.354049", "StartTimeTo": "2020-04-29 23:29:25.354038", "IncludeWatchCount": "true", "UserID": "aroundmountain", "OutputSelector": [ "Title", "ViewItemURL", "SellingStatus", "ListingDuration", "StartTime", "EndTime", "WatchCount", "ItemsPerPage", "PrimaryCategory", "HasMoreItems", "PageNumber", "ReturnedItemCountActual", "PaginationResult", "itemId", "HitCount", "HitCounter", "TimeLeft" ], "Pagination": { "EntriesPerPage": "100", "PageNumber": "1" } } startDateTo = datetime.datetime.now() startDateFrom = startDateTo - datetime.timedelta(90) for i in range(5): inputObj["StartTimeTo"] = startDateTo inputObj["StartTimeFrom"] = startDateFrom inputObj["Pagination"]["PageNumber"] = 1 print("iteration number ", i) #print(inputObj["StartTimeTo"], " ", inputObj["StartTimeFrom"]) while True: #print(inputObj) print('\n') response = api.execute('GetSellerList', inputObj).dict() #file=open("1.txt","w") #print(response) if response["ItemArray"] is None: print("no result at i ", i) break currentItems = response["ItemArray"]["Item"] items.extend(currentItems) print("page number is ", response["PageNumber"]) print("remaining pages", response["PaginationResult"]) print("has more number ", response["HasMoreItems"]) if response["HasMoreItems"] != "true": break inputObj["Pagination"]["PageNumber"] = int( response["PageNumber"]) + 1 if i == 3: startDateFrom = startDateFrom - datetime.timedelta( 6) #just for last 6 days in 365/366 days else: startDateFrom = startDateFrom - datetime.timedelta(90) startDateTo = startDateTo - datetime.timedelta(90) #print(items,file=open("1.txt","w")) print("setting hitcount etc") items = getGood(items) updateToGSheet(items) except Exception as error: traceback.print_exc() print(sys.exc_info()) updateToGSheet(None, error=error)
def getItem(opts): try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid) try: conn = psycopg2.connect("dbname={} user={} host={}".format(dbname, user, host)) print '\nConnected to {} with user:{} on host:{}\n'.format(dbname, user, host) except: print "ERROR: Unable to connect to the database." sys.exit("Check database connection settings and try again.") cur = conn.cursor() #----------- GRAB ALL ITEM IDs IN TABLE ----------# query = '''SELECT ci."itemId" FROM category_specifics as ci ORDER BY ci."Model" ASC OFFSET {offset};'''.format(offset=offset) # 4745 cur.execute(query) item_ids = cur.fetchall() for i,itemId in enumerate(item_ids[:]): itemId = itemId[0] # itemId is a tuple print 'Updating item #{} out of {}'.format(i+1, len(item_ids)) print 'calling getItem for itemID:{}'.format(itemId) api_request = { 'itemID':itemId, 'IncludeItemSpecifics':1, } try: response = api.execute('GetItem', api_request) except ConnectionError as e: print(e) print(e.response.dict()) continue dic = response.dict() # pprint(dic) # debug allowed_columns = ['Type','Brand','MPN','Series','Model',\ 'Megapixels','Optical Zoom','Features',\ 'Color','Bundled Items','Connectivity',\ 'Battery Type','Manufacturer Warranty',\ 'Screen Size','Digital Zoom'] newDict = {} try: if not isinstance(dic['Item']['ItemSpecifics']['NameValueList'], list): # if only one item # print dic['Item']['ItemSpecifics']['NameValueList'] name = dic['Item']['ItemSpecifics']['NameValueList']['Name'] if name in allowed_columns: value = dic['Item']['ItemSpecifics']['NameValueList']['Value'] newDict[name] = value else: for nameValueDict in dic['Item']['ItemSpecifics']['NameValueList']: # print nameValueDict name = nameValueDict['Name'] if name in allowed_columns: value = nameValueDict['Value'] if isinstance(value, list): value = ','.join(value) # join the lists into a string seperated by commas try: newDict[name] = value.decode('unicode_escape').encode('ascii','ignore') except: print 'Problem with value, could not decode for some reason.' continue except KeyError as e: # no item specifics in response print 'No ItemSpecifics field in response.', e continue keys = ['"{}"'.format(key.decode('unicode_escape').encode('ascii','ignore')) for key in newDict.keys()] insert_statement = '''UPDATE {table_name} SET (%s) = %s WHERE "itemId"={item_id}; '''.format(table_name=tablename, item_id=itemId) query = cur.mogrify(insert_statement, (psycopg2.extensions.AsIs(','.join(keys)), tuple(newDict.values()))) # print query try: cur.execute(query) # execute SQL, and commit changes conn.commit() except: print '\nError with executing SQL statement at item #{}, itemId={}.\n'.format(i, itemId) print query conn.rollback() # time.sleep(0.04) # throttle except ConnectionError as e: print(e) print(e.response.dict())
def AddFixedPriceItemShoe(shoe_info_class, post_debug=True, ebay_debug=True): Variation_list = [] for size in shoe_info_class.SIZES: Variation_list.append({ "Quantity": "1", "StartPrice": str(shoe_info_class.PRICE), "VariationSpecifics": { "NameValueList": { "Name": "US Shoe Size (Men's)", "Value": str(size) } } }) api = Connection(config_file="ebay.yaml", debug=True) request = { "Item": { "BuyerRequirementDetails": { "ShipToRegistrationCountry": True }, "Title": str(shoe_info_class.BRAND + str(" ") + shoe_info_class.MODEL), "Country": "US", "Location": "USA", "Site": "US", "ConditionID": "1000", "PaymentMethods": "PayPal", "PictureDetails": { "PictureURL": shoe_info_class.PICTURES }, "PayPalEmailAddress": "*****@*****.**", "PrimaryCategory": { "CategoryID": "24087" }, "ProductListingDetails": { "BrandMPN": { "Brand": str(shoe_info_class.BRAND), "MPN": str(shoe_info_class.SKU) } }, "Description": html_description(shoe_info_class), "ListingDuration": "Days_10", "StartPrice": str(shoe_info_class.PRICE), "Currency": "USD", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsNotAccepted" }, "ShippingDetails": { "ShippingServiceOptions": { "FreeShipping": "True", "ShippingService": "USPSMedia" }, "ExcludeShipToLocation": "none" }, "ItemSpecifics": { "NameValueList": [{ "Name": "Brand", "Value": str(shoe_info_class.BRAND) }, { "Name": "Style", "Value": "Fashion Shoe" }] }, "Variations": { "VariationSpecificsSet": { "NameValueList": { "Name": "US Shoe Size (Men's)", "Value": [ 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0 ], } }, "Variation": Variation_list }, "DispatchTimeMax": '5', } } output = api.execute("AddFixedPriceItem", request) ItemID = output.reply.ItemID if post_debug: display_info(shoe_info_class) return ItemID
def on_import(self): api = Trading(domain='api.ebay.com', appid=self.app_id, devid=self.dev_id, certid=self.cert_id, token=self.token, config_file=None, timeout=300) # Первый запрос, обрабатываем незаврешенные заказы unfinished_order_id_list = [] for order in TrdOrder.objects.filter( id_trade_system=self.circuit.id_trade_system, id_state__n_order__lt=TrdOrderState. get_is_finished_state_number()): unfinished_order_id_list.append(order.s_reg_num) if unfinished_order_id_list: response = api.execute( 'GetOrders', { 'OrderIDArray': { 'OrderID': unfinished_order_id_list }, 'OrderRole': 'Seller', }) response_order_list = self._get_order_list_from_response(response) response_order_id_set = set() # Обрабатываем заказы for response_order in response_order_list: self.handle_object( self.import_direction, lambda obj_info: self.import_order( response_order, obj_info)) response_order_id_set.add(response_order.get('OrderID')) # Проверим, что все заказы были в запросе for unfinished_order_id in unfinished_order_id_list: if unfinished_order_id not in response_order_id_set: self.write_error_log( unfinished_order_id, "Для заказа " + unfinished_order_id + " не пришла информация от Ebay", self.import_direction) # Второй запрос, обрабатываем новые заказы # Получаем дату последнего запроса circuit_runtime_data = IntgCircuitRunTimeData.register_by_circuit( self.circuit) json_runtime_data = None key_last_import_date = 'lastImportDate' if circuit_runtime_data.s_json_data: json_runtime_data = json.loads(circuit_runtime_data.s_json_data) else: json_runtime_data = {} last_import_date = json_runtime_data.get(key_last_import_date) new_last_import_date = None order_array = [] if not last_import_date: # Если это первая выгрузка? возмем все заказы за последние 30 дней, и загрузим только не завершенные? response = api.execute( 'GetOrders', { 'OrderRole': 'Seller', 'NumberOfDays ': 30, 'OrderStatus': 'Completed' }) order_array = filter( lambda _order: self._is_response_order_not_shipped(_order), self._get_order_list_from_response(response)) response_time_str = response.dict()['Timestamp'] new_last_import_date = self.__str_to_date(response_time_str) else: # Рассчет даты окончания. Ebay рекоменлдует делать текущее вермя минус 2 минуты response = api.execute('GetUser') response_time_str = response.dict()['Timestamp'] response_time = self.__str_to_date(response_time_str) create_to_time = response_time - timedelta(minutes=2) response = api.execute( 'GetOrders', { 'CreateTimeFrom': last_import_date, 'CreateTimeTo': self.__date_to_str(create_to_time), 'OrderRole': 'Seller', 'OrderStatus': 'Completed' }) order_array = self._get_order_list_from_response(response) new_last_import_date = create_to_time for order in order_array: self.handle_object( self.import_direction, lambda obj_info: self.import_order(order, obj_info)) # Сохраняем дату последней выгрузки json_runtime_data[key_last_import_date] = self.__date_to_str( new_last_import_date) circuit_runtime_data.s_json_data = json.dumps(json_runtime_data) circuit_runtime_data.save()
def verifyAddItemErrorCodes(opts): """http://www.utilities-online.info/xmltojson/#.UXli2it4avc """ try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=False) myitem = { "Item": { "Title": "Harry Potter and the Philosopher's Stone", "Description": "This is the first book in the Harry Potter series. In excellent condition!", "PrimaryCategory": { "CategoryID": "377aaaaaa" }, "StartPrice": "1.0", "CategoryMappingAllowed": "true", "Country": "US", "ConditionID": "3000", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": "Days_7", "ListingType": "Chinese", "PaymentMethods": "PayPal", "PayPalEmailAddress": "*****@*****.**", "PictureDetails": { "PictureURL": "http://i1.sandbox.ebayimg.com/03/i/00/30/07/20_1.JPG?set_id=8800005007" }, "PostalCode": "95125", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the book for refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "USPSMedia", "ShippingServiceCost": "2.50" } }, "Site": "US" } } motors_item = { 'Item': { 'Category': '101', 'Title': 'My Title', 'ItemCompatibilityList': { 'Compatibility': [ { 'CompatibilityNotes': 'Fits for all trims and engines.', 'NameValueList': [{ 'Name': 'Year', 'Value': '2001' }, { 'Name': 'Make', 'Value': 'Honda' }, { 'Name': 'Model', 'Value': 'Accord' }] }, ] } } } api.execute('VerifyAddItem', myitem) except ConnectionError as e: # traverse the DOM to look for error codes for node in api.response.dom().findall('ErrorCode'): print("error code: %s" % node.text) # check for invalid data - error code 37 if 37 in api.response_codes(): print("Invalid data in request") print(e) print(e.response.dict())
def verifyAddItem(opts): """http://www.utilities-online.info/xmltojson/#.UXli2it4avc """ try: api = Trading(debug=opts.debug, config_file=opts.yaml, appid=opts.appid, certid=opts.certid, devid=opts.devid, warnings=False) myitem = { "Item": { "Title": "Harry Potter and the Philosopher's Stone", "Description": "This is the first book in the Harry Potter series. In excellent condition!", "PrimaryCategory": { "CategoryID": "377" }, "StartPrice": "1.0", "CategoryMappingAllowed": "true", "Country": "US", "ConditionID": "3000", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": "Days_7", "ListingType": "Chinese", "PaymentMethods": "PayPal", "PayPalEmailAddress": "*****@*****.**", "PictureDetails": { "PictureURL": "http://i1.sandbox.ebayimg.com/03/i/00/30/07/20_1.JPG?set_id=8800005007" }, "PostalCode": "95125", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the book for refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "USPSMedia", "ShippingServiceCost": "2.50" } }, "Site": "US" } } api.execute('VerifyAddItem', myitem) dump(api) except ConnectionError as e: print(e) print(e.response.dict())
import datetime import json from ebaysdk.exception import ConnectionError from ebaysdk.trading import Connection as Trading print("started") try: api = Trading(domain='api.ebay.com', config_file='ebay.yaml') response = api.execute( 'GetSellerList', { 'IncludeVariations': "true", 'EndTimeFrom': datetime.datetime.today(), 'EndTimeTo': datetime.datetime.now() + datetime.timedelta(days=120) }) file = open("latest_response.json", "w") print(json.dumps(response.dict(), indent=4), file=file) ItemsOut = {} for Item in response.reply.ItemArray.Item: ItemResponse = api.execute('GetItem', {'ItemID': Item.ItemID}) ItemsOut[Item.ItemID] = ItemResponse.dict() outfile = open("output.json", "w") print(json.dumps(ItemsOut, indent=4), file=outfile) assert (response.reply.Ack == 'Success') assert (type(response.reply.Timestamp) == datetime.datetime) # assert(type(response.searchResult.item) == list)
additem = api.execute( 'VerifyAddItem', { "Item": { "Title": "Harry Potter and the Philosopher's Stone", "Description": "This is the first book in the Harry Potter series. In excellent condition!", "PrimaryCategory": { "CategoryID": "377" }, "StartPrice": "1.0", "CategoryMappingAllowed": "true", "ConditionID": "4000", "Country": "US", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": "Days_7", "ListingType": "Chinese", "PaymentMethods": "PayPal", "PayPalEmailAddress": "*****@*****.**", "PictureDetails": { "PictureURL": "http://i1.sandbox.ebayimg.com/03/i/00/30/07/20_1.JPG?set_id=8800005007" }, "PostalCode": "95125", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the book for refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "USPSMedia", "ShippingServiceCost": "2.50" } }, "Site": "UK" } })
class GetFields(object): failedqueue = Queue.Queue() def __init__( self, domain='api.ebay.com', appid='ZhouPeng-3242-4cc7-88fd-310f513fcd71', devid='df3f2898-65b1-4e15-afd5-172b989903aa', certid='a0e19cf9-9b2b-457f-b6f1-87f3f600ca63', # token='AgAAAA**AQAAAA**aAAAAA**cJyLVQ**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wMkoqiC5mHoQmdj6x9nY+seQ**N+QCAA**AAMAAA**nLCwNt4AQt1TRtd2ydNIMuZ2JYnQZKVVYarn41QQfBSqccEDld22ltKr+C/HJTN8AKD4+jn/nIEqtjNMkmh9sxTIa6jVVLAH5sN/93X7gTCmTkOsE/Av612U90nRoyQJ5bX1+NO25tMDZs9U0aTJIwVVu1BAB8/nsjL0pTCWw7KZACJ+a/aQ6swXLvSvOCWIBjFyCaWibKZseT2LoJMvJQmC2QpIuDsQ8cTYozLUYZqC88uKAjo7DNWIvaPVCdwkp/Vux3arR1Asin4ewX1l+LWCamWsXeBiVyaYq/oEUXABgknieVAPEpaFAfSzlrcTNmTWLBDDRwRGI/8hJCwK6/eJWexGrLk7U7p0kRltktNseTckAKT7g1ED4C5gUeQ4/nTHsNQBejUPTzTlwBWTJpwRaBFD7dAlbagH+TKaEJK41Esf/ZpL2599LUMolsO8tBgo0BhtCF/bYtdUUfopksIKNUwPXikadUxx6TurknnTtR1WDD229uUJIIf9BCS68WB56OfDTdXcZ8rdPZ0zdHuw5+BRxrumpFUzTQb5fJeHRDLPtQbLdX5rFPrS+NPJl6Qzi7bWNxUCydNQcIzKv7xLquIPoPx8bD1PRCoQbzjTQsOqhe9PBvLtcJ0Ggve78YjQKb5nDt6YThZ6D+1EOKdcthU03VizDfBKBLJ/NPqktDTx74tsS3l4feAjblGDoQ2RZXefJ9Jk3t+Qc4khlvl4mKpjZ4sCakh4qPWr9H6t3CN80hz5MO1Y7uHPUY61' token='AgAAAA**AQAAAA**aAAAAA**aCRbWA**nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wDmYShCJCHogmdj6x9nY+seQ**N+QCAA**AAMAAA**ktFg8zDYputToOiGDvTfZku93pjbVq3rGn7AR53h1eWAByiTLP+Gd8uKuDof0BQ0prvskMARI/nHxkjFYUp7IUsQkZ6sH/E2UmmvRRwqDHZ/XsXt0+meLqS6ZHMjw7v/CpISJqnZjGChDSYPFRe6RboawkjPi8ial5wEXojlvNWvHl02yT92ih6dTYj44g2xprmmyOSyTYC8l8oG+YLKZ+FPzOj5zxO3Qm8rhVtQwc1KGGtHnthz2ZwHwbeFDh8cVp1qaFQmCaHc27ftM8/to2U22mccon5zRk6yf59EiN88WPzag/ii0XpkwELXWRsHKBfl/9pepWUqWZvgjhQ9jcGQsrYyQfS6T54dLcaJ7a2IrCxOvpdkv4Z26T7CpTpUBbYzG4olJI42jFMZBu5quqOanio2qbHNFov5Jq85jMR9Zx51KlKezNaauIW16upj7P2gvCwDt+E7xCQMoqKDrIyx7J0g0KLHKhSavzeC0vnrF0H9NAfqxVEdYtLUgbR9A8JQagPAYp+vPuMpSEbhc5/fTLBfD6YFSoJ+izMzx0n6Gj2df5n77hS3X1850eLzqzCREtUClZfJ7tcTMR+oU8i0aB75rWDr/sFKsfgW/rAe8hcuMzYBms+rsL4i7ddt5KWfCieMksAfabdUrPF5Owfr/24en/omwHXtBrb39u/oMKTfGZOS2JKyXdbpmpV1YWsJ8eDzxNIN0hJfG6wqrjdEJAUX5dkg4j5L5UXE6deogb9MUYHJgkP3nch5yPfS', ): self.idomain = domain self.iappid = appid self.idevid = devid self.icertid = certid self.itoken = token self.mycon = Connection( domain=self.idomain, appid=self.iappid, devid=self.idevid, certid=self.icertid, token=self.itoken, timeout=15, config_file=None, #proxy_host='127.0.0.1', #proxy_port='1080' ) def get_xml(self, set): for ele in set: try: myrequest = {'ItemID': ele, 'IncludeWatchCount': True} myresponse = self.mycon.execute('GetItem', myrequest) yield myresponse.text except ConnectionError as e: print(e) print 'the GetItem Call of %s is die' % ele except (ssl.SSLError, requests.RequestException): print 'the request of %s via GetItem failed' % ele def parse(self, sellerid, timefrom, timeto): getlist = GetList() myset = getlist.get_list(sellerid, starttimefrom=timefrom, starttimeto=timeto) patternCad = re.compile(r"<CategoryID>(.*?)</CategoryID>") patternCae = re.compile(r"<CategoryName>(.*?)</CategoryName>") patternCoy = re.compile(r'<Country>(.*?)</Country>') patternCuy = re.compile(r"<Currency>(.*?)</Currency>") patternCue = re.compile(r'>(\d+\.\d+)</CurrentPrice>') patternFee = re.compile(r'<FeedbackScore>(.*?)</FeedbackScore>') patternFer = re.compile( r"<FeedbackRatingStar>(.*?)</FeedbackRatingStar>") patternGal = re.compile(r"<GalleryURL>(.*?)</GalleryURL>") patternHit = re.compile(r"<HitCount>(.*?)</HitCount>") patternHir = re.compile(r'<HitCounter>(.*?)</HitCounter>') patternItd = re.compile(r"<ItemID>(.*?)</ItemID>") patternLon = re.compile(r"<Location>(.*?)</Location>") patternQud = re.compile(r"<QuantitySold>(.*?)</QuantitySold>") patternQue = re.compile( r"<QuantitySoldByPickupInStore>(.*?)</QuantitySoldByPickupInStore>" ) patternSht = re.compile(r'>(\d+\.\d+)</ShippingServiceCost>') patternShe = re.compile(r"<ShippingService>(.*?)</ShippingService>") patternSku = re.compile(r"<SKU>(.*?)</SKU>") patternSte = re.compile(r"<StartTime>(.*?)</StartTime>") patternStr = re.compile(r"<StoreOwner>(.*?)</StoreOwner>") patternStl = re.compile(r"<StoreURL>(.*?)</StoreURL>") patternTie = re.compile(r'<Title>(.*?)</Title>') patternUsd = re.compile(r'<UserID>(.*?)</UserID>') patternUse = re.compile(r'<Site>(.*?)</Site>') patternVil = re.compile(r'<ViewItemURL>(.*?)</ViewItemURL>') patternLin = re.compile(r'<ListingDuration>(.*?)</ListingDuration>') patternPrg = re.compile(r'<PrivateListing>(.*?)</PrivateListing>') if isinstance(myset, type(None)): print 'So I get nothing from Getlist Call' # failedlist=[] # failedlist.append(sellerid) # failedlist.append(timefrom) # failedlist.append(timeto) # self.failedqueue.put(failedlist) # print 'And this request have been put into the failed queue' elif len(myset) == 0: print 'No listings occur between %s and %s' % (timefrom, timeto) else: for xml in self.get_xml(myset): expfileds = Fields() expfileds.fielddic['categoryid'] = re.findall(patternCad, xml)[0] expfileds.fielddic['sku'] = re.findall(patternSku, xml)[0][:11] expfileds.fielddic['categoryname'] = re.findall( patternCae, xml)[0] expfileds.fielddic['country'] = re.findall(patternCoy, xml)[0] expfileds.fielddic['currency'] = re.findall(patternCuy, xml)[0] try: expfileds.fielddic['currentprice'] = re.findall( patternCue, xml)[0] except IndexError: print xml expfileds.fielddic['feedbackscore'] = re.findall( patternFee, xml)[0] expfileds.fielddic['feedbackstar'] = re.findall( patternFer, xml)[0] expfileds.fielddic['galleryurl'] = re.findall(patternGal, xml)[0] expfileds.fielddic['hitcount'] = re.findall(patternHit, xml)[0] expfileds.fielddic['hitcounter'] = re.findall(patternHir, xml)[0] expfileds.fielddic['itemid'] = re.findall(patternItd, xml)[0] expfileds.fielddic['location'] = re.findall(patternLon, xml)[0] expfileds.fielddic['quantitysold'] = re.findall( patternQud, xml)[0] expfileds.fielddic['quantitysoldinstore'] = re.findall( patternQue, xml)[0] try: expfileds.fielddic['shippingcost'] = re.findall( patternSht, xml)[0] except IndexError: print xml expfileds.fielddic['shippingservice'] = re.findall( patternShe, xml)[0] expfileds.fielddic['starttime'] = re.findall(patternSte, xml)[0] expfileds.fielddic['storeowner'] = re.findall(patternStr, xml)[0] expfileds.fielddic['storeurl'] = re.findall(patternStl, xml)[0] expfileds.fielddic['title'] = re.findall(patternTie, xml)[0] expfileds.fielddic['userid'] = re.findall(patternUsd, xml)[0] expfileds.fielddic['usersite'] = re.findall(patternUse, xml)[0] expfileds.fielddic['viewitemurl'] = re.findall( patternVil, xml)[0] expfileds.fielddic['listduration'] = re.findall( patternLin, xml)[0] expfileds.fielddic['privatelisting'] = re.findall( patternPrg, xml)[0] yield expfileds.fielddic
from ebaysdk.trading import Connection if __name__ == '__main__': try: api = Connection(config_file='ebay.yaml') except ConnectionError as e: print(e) print(e.response.dict()) log.error('Attempting to get an API object failed with %s', e) acitvelist = api.execute('GetMyeBaySelling', { 'ActiveList': True, 'DetailLevel': 'ReturnAll', 'PageNumber': 1 }) print(acitvelist)
def AutoSendKeys(config): #(AutoSendKey and filled Marked as sent key in key.csv) api = Trading(config_file=config, domain='api.ebay.com') Today = datetime.now() response = api.execute('GetOrders',{'CreateTimeFrom': Today - timedelta(days=1),'CreateTimeTo': Today,'OrderStatus': 'Completed'}) try: Order = response.reply.OrderArray.Order except AttributeError: Order = None if Order != None: for order in Order: #Check for Transaction_obj in order.TransactionArray.Transaction: Account = str(config).replace('.yaml','') OrderID = order.OrderID try: VariantSKU = Transaction_obj.Variation.SKU except AttributeError: VariantSKU = '' if VariantSKU == '': try: SKU = Transaction_obj.Item.SKU except AttributeError: SKU ='' else: SKU = VariantSKU UserID = order.BuyerUserID Quantity = int(Transaction_obj.QuantityPurchased) INVOICE = f'{Account}|{UserID}|{OrderID}' FILTER = SKU.split('|')[0] #DROPSHIP if FILTER == 'DI' and Sku(SKU)[0] != None: with open('key.csv', mode = 'r',newline = '') as file: ListKeys = [raw for raw in csv.DictReader(file)] TotalKeys = sum(1 for raw in ListKeys) OrderID_SentKeys = [] #Check OrderID nay de sent key chua(within file key stored) for i in range(0, TotalKeys): try: OrderIDCheck = ListKeys[i]['STATUS'].split(':')[1].split('|')[2] except IndexError: OrderIDCheck = None if OrderIDCheck != None: OrderID_SentKeys.append(OrderIDCheck) if OrderID not in OrderID_SentKeys: if Stock(SKU) > Quantity: Code = [] KEY = '' print({INVOICE}) for i in range(0, TotalKeys): if ListKeys[i]['SKU'] == SKU and ListKeys[i]['STATUS'] == '': Code.append(ListKeys[i]['KEY']) for qtt in range(0, Quantity): if (sum(1 for x in Code)) > 1: KEY += f' The code {qtt + 1} => {Code[qtt]}\n' elif (sum(1 for x in Code)) == 1: KEY = Code[0] for i in range(0, TotalKeys): if ListKeys[i]['KEY'] == Code[qtt]: ListKeys[i]['STATUS'] = f'USED:{INVOICE}' ListKeys[i]['DATE SOLD'] = f'{order.CreatedTime.strftime("%Y-%m-%d")}' with open('key.csv', 'w', newline='') as file: Update = csv.DictWriter(file, fieldnames = ListKeys[0].keys()) Update.writeheader() Update.writerows(ListKeys) ItemID = order.TransactionArray.Transaction[0].Item.ItemID TransactionID = Transaction_obj.TransactionID Body = f'Thanks for shopping with us.\n\ Your {Quantity} x {Sku(SKU)[0]} Retail License Key:\n\ {KEY}\ 1) Go to {Sku(SKU)[2]} - ms official\n\ 2) Login with your email and enter the code\n\ 3) Download and Install {Sku(SKU)[1]}\n\ 4) Active product via {Sku(SKU)[3]}!\n\ If you can\'t do it,please don\'t make a ebay case, just contact me! i will full support to you!\n\ Please do not open any dispute or issue, if you encounter any problems just contact us and we will solve all the problems!\n\ Thank you!' ImportMessage = {'ItemID': ItemID, # Item ID that buyer purchase 'MemberMessage': { 'Body': Body, 'EmailCopyToSender': 1, 'QuestionType': 'General', 'RecipientID': UserID } } api.execute('AddMemberMessageAAQToPartner', ImportMessage) #add key to User Note (SetUserNotes): api.execute('SetUserNotes', {'Action': 'AddOrUpdate','ItemID': ItemID,'NoteText': f'{KEY}','TransactionID': TransactionID}) break
excel_year = excel_all_date.split('T')[0].split('-')[0] # year excel_month = excel_all_date.split('T')[0].split('-')[1] # month excel_day = excel_all_date.split('T')[0].split('-')[2] # day excel_hour = excel_all_date.split('T')[1].split(':')[0] # hour excel_min = excel_all_date.split('T')[1].split(':')[1] # minute # accessing to the ebay API try: api = Trading(appid="enter your appid here", devid="enter your devid here", certid="enter your certid here", token="enter your token here", config_file=None) soldlists = api.execute('GetMyeBaySelling', { 'SoldList': True, 'DetailLevel': 'ReturnAll', 'PageNumber': 0 }) response_ebay = api.execute('GetUser', {}) ebay_api = soldlists.dict() allsells = ebay_api['SoldList']['OrderTransactionArray'][ 'OrderTransaction'] allsells_count = -1 row_x = excel_row_count row_y = excel_row_count + 5 # Defines the selling date of each item from the eBay API for i in allsells: try: if allsells[allsells_count]['Transaction'][
template = row[0] sql = "SELECT id,title,description,features,img,ebayprice,brand FROM ft_product WHERE active=1 AND ebaylisted=0" cursor.execute(sql) result = cursor.fetchall() for row in result: id = row[0] title = row[1] description = row[2] features = row[3] img = row[4] price = row[5] brand = row[6] response = api.execute("GetSuggestedCategories", {"Query": escape(title)}) dict = response.dict() cnt = dict["CategoryCount"] cnt = int(cnt) if cnt == 0: categoryid = "11104" else: categoryid = dict["SuggestedCategoryArray"]["SuggestedCategory"][0][ "Category"]["CategoryID"] myitem["Item"]["PrimaryCategory"]["CategoryID"] = categoryid myitem["Item"]["Title"] = "<![CDATA[" + title[:79] + "]]>" template = template.replace("{title}", title) template = template.replace("{description}", "<p>" + description + "</p>") features = features.split("~") cnt = len(features)
import json; from ebaysdk.trading import Connection as Trading; from ebaysdk.exception import ConnectionError; #Test Variables exchangeRate = 1.24 UKPrice = 1000.00 try: #"Get" Calls api = Trading(domain='api.sandbox.ebay.com', config_file='ebay.yaml') getItem = api.execute('GetItem', {'ItemID' : 110192114640}) getItemDictionary = json.loads(getItem.json()) ItemID = getItemDictionary["Item"]["ItemID"] Price = getItemDictionary["Item"]["ListingDetails"]["ConvertedStartPrice"]["value"] Currency = getItemDictionary["Item"]["Currency"] print ("ItemID: " + ItemID) print ("Price: " + Price) print ("Currency " + Currency) def priceCheck(Price, UKPrice, exchangeRate): Price = float(Price) UKPrice = float(UKPrice) exchangeRate = float(exchangeRate) correctPrice = UKPrice * exchangeRate if (Price != correctPrice): try: api = Trading(domain='api.sandbox.ebay.com', config_file='ebay.yaml')
def verifyAddItemErrorCodes(args): """http://www.utilities-online.info/xmltojson/#.UXli2it4avc """ try: api = Trading(debug=args.debug, appid=app_id, token=token_id, config_file=None, certid=cert_id, devid=dev_id) myitem = { "Item": { "Title": "PYTHON TEST", "Description": "This is the first book in the Harry Potter series. In excellent condition!", "PrimaryCategory": { "CategoryID": "377" }, "StartPrice": "1.0", "CategoryMappingAllowed": "true", "ConditionID": "4000", "Country": "US", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": "Days_7", "ListingType": "Chinese", "PaymentMethods": "PayPal", "PayPalEmailAddress": "*****@*****.**", "PictureDetails": { "PictureURL": "http://www.itcircleconsult.com/eb2017/hottub/pics/left2.png" }, "PostalCode": "95125", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the book for refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "USPSMedia", "ShippingServiceCost": "2.50" } }, "Site": "US" } } api.execute('VerifyAddItem', myitem) except ConnectionError as e: # traverse the DOM to look for error codes for node in api.response.dom().findall('ErrorCode'): print("error code: %s" % node.text) # check for invalid data - error code 37 if 37 in api.response_codes(): print("Invalid data in request") print(e) print(e.response.dict())
class Ebay(object): def __init__(self): try: self.production_connection = Trading( devid=settings.EBAY_PRODUCTION_DEVID, appid=settings.EBAY_PRODUCTION_APPID, certid=settings.EBAY_PRODUCTION_CERTID, token=settings.EBAY_PRODUCTION_TOKEN, config_file=None ) logger.info(u'Established Ebay Production API connection') self.sandbox_connection = Trading( domain='api.sandbox.ebay.com', devid=settings.EBAY_SANDBOX_DEVID, appid=settings.EBAY_SANDBOX_APPID, certid=settings.EBAY_SANDBOX_CERTID, token=settings.EBAY_SANDBOX_TOKEN, config_file=None ) logger.info(u'Established Ebay Sandbox API connection') except: self.production_connection = self.sandbox_connection = None logger.error(traceback.format_exc()) logger.error(u'Failed to establish Ebay API connection') self.total_count = 0 def category_search(self, query): response = self.production_connection.execute( 'GetSuggestedCategories', {'Query': query} ) response = response.dict() logger.info( u'Got {} suggested categories for query {}'.format( response['SuggestedCategoryArray']['SuggestedCategory'], query ) ) return [ (int(c['Category']['CategoryID']), c['Category']['CategoryName']) for c in response['SuggestedCategoryArray']['SuggestedCategory'] ] def list(self, item_obj): if settings.USE_SANDBOX: connection = self.sandbox_connection url = 'http://cgi.sandbox.ebay.com/ws/eBayISAPI.dll?ViewItem&item'\ '={}&ssPageName=STRK:MESELX:IT' else: connection = self.produiction_connection url = 'http://www.ebay.com/itm/-/{}?ssPageName=ADME:L:LCA:US:1123' item_dict = { 'Item': { 'Title': item_obj.title, 'Description': u'<![CDATA[{}]]>'.format(item_obj.html), 'PrimaryCategory': {'CategoryID': item_obj.category_id}, 'StartPrice': item_obj.price, 'CategoryMappingAllowed': 'true', 'ConditionID': '1000', 'Country': 'US', 'Currency': 'USD', 'DispatchTimeMax': '3', 'ListingDuration': 'Days_30', 'ListingType': 'FixedPriceItem', 'Location': 'Los Angeles, CA', 'PaymentMethods': 'PayPal', 'PayPalEmailAddress': '*****@*****.**', 'PictureDetails': { 'PictureURL': item_obj.get_image_list(), }, 'ItemSpecifics': { 'NameValueList': [ {'Name': 'Brand', 'Value': item_obj.manufacturer}, {'Name': 'MPN', 'Value': item_obj.mpn}, ] }, 'PostalCode': '90001', 'Quantity': '1', 'ShippingDetails': { 'ShippingType': 'Flat', 'ShippingServiceOptions': { 'ShippingServicePriority': '1', 'ShippingService': 'USPSMedia', 'ShippingServiceCost': '0.00' } }, 'ReturnPolicy': { 'Description': '14 days money back, you pay return shippin' 'g', 'ReturnsAcceptedOption': 'ReturnsAccepted', 'RefundOption': 'MoneyBack', 'ReturnsWithinOption': 'Days_14', 'ShippingCostPaidByOption': 'Buyer' }, 'Site': 'US', } } if item_obj.upc: item_dict['Item'] = { 'ProductListingDetails': { 'UPC': item_obj.upc, 'ListIfNoProduct': 'true', }, } try: response = connection.execute('AddFixedPriceItem', item_dict) logger.info(u'Listed Ebay item {}'.format(item_obj.title)) item_obj.url = url.format(response.dict()['ItemID']) item_obj.is_listed = True item_obj.date_listed = timezone.now() except: logger.info(u'Failed to list Ebay item {}'.format(item_obj.title)) item_obj.error = traceback.format_exc() try: item_obj.save() logger.info(u'Saved Ebay item {}'.format(item_obj.title)) self.total_count += 1 except: logger.info(u'Failed to save Ebay item {}'.format(item_obj.title))
class EbayAPI(object): def __init__(self, storefront): self.storefront = storefront if storefront == 'old_glory': self.token = og_token elif storefront == 'animalworld': self.token = aw_token else: self.token = sandbox_token self.api = Trading( # domain='api.sandbox.ebay.com', appid="RedRocke-e380-4b45-ba54-78fb6c6832f5", devid="f7e7239f-2cf9-4e4f-9413-1e08b524944c", certid="7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", token=self.token, config_file=None) def create_active_ebay_inventory_file(self): fname = self.storefront + "_active_ebay_inventory.csv" f = open(fname, "w") writer = csv.writer(f) page_number = 1 # TODO handle connection timeout error results = self.get_my_ebay_selling(page_number) results_dict = results.dict() total_number_of_pages = int(results_dict['ActiveList'] ['PaginationResult']['TotalNumberOfPages']) active_items_array = results_dict['ActiveList']['ItemArray']['Item'] while page_number <= total_number_of_pages: print page_number for item in active_items_array: item_id = item['ItemID'] quantity = item.get('Quantity', '') sku = item.get('SKU', '') try: variations = item['Variations']['Variation'] # if there are variations then this is an ebay parent writer.writerow([item_id, sku, quantity, '', '', 'parent']) except KeyError: variations = None # if there are no variations this is a lone writer.writerow([item_id, sku, quantity, '', '', 'lone']) if variations: if type(variations) is list: for variation in variations: var_sku = variation.get("SKU", '') var_quantity = variation.get('Quantity', '') name_value_list = variation['VariationSpecifics'][ 'NameValueList'] name = name_value_list['Name'] value = name_value_list['Value'] writer.writerow([ item_id, var_sku, var_quantity, name, value, 'child' ]) else: var_sku = variations.get('SKU', '') var_quantity = variations.get('Quantity', '') # name_value_list = variation['VariationSpecifics']['NameValueList'] # if type(name_value_list) is list: # for name_value in name_value_list: # name = name_value['Name'] # value = name_value['Value'] # writer.writerow([item_id, var_sku, var_quantity, name, value]) # else: # name = name_value_list['Name'] # value = name_value_list['Value'] # writer.writerow([item_id, var_sku, var_quantity, name, value]) name_value_list = variations['VariationSpecifics'][ 'NameValueList'] name = name_value_list['Name'] value = name_value_list['Value'] writer.writerow([ item_id, var_sku, var_quantity, name, value, 'child' ]) page_number += 1 results = self.get_my_ebay_selling(page_number) results_dict = results.dict() total_number_of_pages = int( results_dict['ActiveList']['PaginationResult'] ['TotalNumberOfPages']) active_items_array = results_dict['ActiveList']['ItemArray'][ 'Item'] return fname def create_upload_job_for_revise_fixed_price_item(self, upload_job_type): ''' :return: job id str ''' headers = { "X-EBAY-SOA-OPERATION-NAME": "createUploadJob", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '83t', "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", "X-EBAY-API-CALL-NAME": 'ReviseFixedPriceItem', 'X-EBAY-API-DETAIL-LEVEL': '0', "X-EBAY-API-SITEID": '0', "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", "Content-Type": 'application/xml', } # url = "https://api.ebay.com/ws/api.dll" url = "https://webservices.ebay.com/BulkDataExchangeService" # ebay needs some unique identifier uuid = ''.join([random.choice('abcdef123456') for _ in range(12)]) xml = """<?xml version="1.0" encoding="utf-8"?> <createUploadJobRequest xmlns="http://www.ebay.com/marketplace/services"> <RequesterCredentials> <eBayAuthToken>{token}</eBayAuthToken> </RequesterCredentials> <fileType>XML</fileType> <uploadJobType>{upload_job_type}</uploadJobType> <UUID>{uuid}</UUID> </createUploadJobRequest> """.format(token=self.token, uuid=uuid, upload_job_type=upload_job_type) r = requests.post(url, headers=headers, data=xml) print 'Content', r.content nsmap = {'services': 'http://www.ebay.com/marketplace/services'} root = etree.fromstring(r.content) job_id = root.find('services:jobId', nsmap).text file_reference_id = root.find('services:fileReferenceId', nsmap).text return {'job_id': job_id, 'file_reference_id': file_reference_id} def create_active_inventory_report(self): ''' :return: job id str ''' headers = { "X-EBAY-SOA-OPERATION-NAME": "startDownloadJob", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '83t', "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", "X-EBAY-API-CALL-NAME": 'ActiveInventoryReport', 'X-EBAY-API-DETAIL-LEVEL': '0', "X-EBAY-API-SITEID": '0', "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", "Content-Type": 'application/xml', } # url = "https://api.ebay.com/ws/api.dll" url = "https://webservices.ebay.com/BulkDataExchangeService" # ebay needs some unique identifier uuid = ''.join([random.choice('abcdef123456') for _ in range(12)]) xml = """<?xml version="1.0" encoding="utf-8"?> <startDownloadJobRequest xmlns="http://www.ebay.com/marketplace/services"> <RequesterCredentials> <eBayAuthToken>{token}</eBayAuthToken> </RequesterCredentials> <ActiveList> <Sort>TimeLeft</Sort> <Pagination> <EntriesPerPage>50</EntriesPerPage> <PageNumber>1</PageNumber> </Pagination> </ActiveList> <UUID>{uuid}</UUID> <downloadJobType>ActiveInventoryReport</downloadJobType> </startDownloadJobRequest> """.format(token=self.token, uuid=uuid) r = requests.post(url, headers=headers, data=xml) print 'Content', r.content nsmap = {'services': 'http://www.ebay.com/marketplace/services'} root = etree.fromstring(r.content) job_id = root.find('services:jobId', nsmap).text return job_id def get_job_status_request(self, job_id): headers = { "X-EBAY-SOA-OPERATION-NAME": "getJobStatus", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '837', "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", 'X-EBAY-API-DETAIL-LEVEL': '0', "X-EBAY-API-SITEID": '0', "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", "Content-Type": 'application/xml', } # url = "https://api.ebay.com/ws/api.dll" url = "https://webservices.ebay.com/BulkDataExchangeService" xml = """<?xml version="1.0" encoding="utf-8"?> <getJobsStatusRequest xmlns="http://www.ebay.com/marketplace/services"> <RequesterCredentials> <eBayAuthToken>{token}</eBayAuthToken> </RequesterCredentials> <jobId>{job_id}</jobId> </getJobsStatusRequest>""".format(token=self.token, job_id=job_id) r = requests.post(url, headers=headers, data=xml) nsmap = {'services': 'http://www.ebay.com/marketplace/services'} root = etree.fromstring(r.content) print r.status_code print r.text try: file_reference_id = root.find('services:fileReferenceId', nsmap).text return file_reference_id except AttributeError: return None def abort_job(self, job_id): headers = { "X-EBAY-SOA-OPERATION-NAME": "abortJob", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '837', "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", 'X-EBAY-API-DETAIL-LEVEL': '0', "X-EBAY-API-SITEID": '0', "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", "Content-Type": 'application/xml', } # url = "https://api.ebay.com/ws/api.dll" url = "https://webservices.ebay.com/BulkDataExchangeService" xml = """<?xml version="1.0" encoding="utf-8"?> <abortJobRequest xmlns="http://www.ebay.com/marketplace/services"> <RequesterCredentials> <eBayAuthToken>{token}</eBayAuthToken> </RequesterCredentials> <jobId>{job_id}</jobId> </abortJobRequest>""".format(token=self.token, job_id=job_id) r = requests.post(url, headers=headers, data=xml) print r.status_code print r.text def get_all_created_jobs(self): headers = { "X-EBAY-SOA-OPERATION-NAME": "getJobs", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '837', "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", 'X-EBAY-API-DETAIL-LEVEL': '0', "X-EBAY-API-SITEID": '0', "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", "Content-Type": 'application/xml', } # url = "https://api.ebay.com/ws/api.dll" url = "https://webservices.ebay.com/BulkDataExchangeService" xml = """<?xml version="1.0" encoding="utf-8"?> <getJobsRequest xmlns="http://www.ebay.com/marketplace/services"> <RequesterCredentials> <eBayAuthToken>{token}</eBayAuthToken> </RequesterCredentials> <jobType>ReviseFixedPriceItem</jobType> </getJobsRequest>""".format(token=self.token) r = requests.post(url, headers=headers, data=xml) print r.status_code print r.text def upload_file_request(self, job_id, file_reference_id, file_name): headers = { "X-EBAY-SOA-OPERATION-NAME": "uploadFile", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '837', 'X-EBAY-SOA-SERVICE-NAME': 'FileTransferService', 'X-EBAY-SOA-REQUEST-DATA-FORMAT': 'XML', 'X-EBAY-SOA-RESPONSE-DATA-FORMAT': 'XML', } url = "https://storage.ebay.com/FileTransferService" f = open(file_name, 'r') data = f.read() f.close() data = base64.b64encode(data) xml = """<?xml version="1.0" encoding="UTF-8"?> <uploadFileRequest xmlns="http://www.ebay.com/marketplace/services"> <fileAttachment> <Data>{data}</Data> <Size>{size}</Size> </fileAttachment> <fileFormat>gzip</fileFormat> <fileReferenceId>{file_reference_id}</fileReferenceId> <taskReferenceId>{job_id}</taskReferenceId> </uploadFileRequest>""".format(data=data, job_id=job_id, file_reference_id=file_reference_id, size=len(data)) print xml r = requests.post(url, headers=headers, data=xml) print r.status_code print r.text def start_upload_job(self, job_id): headers = { "X-EBAY-SOA-OPERATION-NAME": "startUploadJob", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '837', "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", "X-EBAY-API-CALL-NAME": 'ReviseFixedPriceItem', 'X-EBAY-API-DETAIL-LEVEL': '0', "X-EBAY-API-SITEID": '0', "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", "Content-Type": 'application/xml', } # url = "https://api.ebay.com/ws/api.dll" url = "https://webservices.ebay.com/BulkDataExchangeService" xml = """<?xml version="1.0" encoding="utf-8"?> <startUploadJobRequest xmlns="http://www.ebay.com/marketplace/services"> <RequesterCredentials> <eBayAuthToken>{token}</eBayAuthToken> </RequesterCredentials> <jobId>{job_id}</jobId> </startUploadJobRequest> """.format(job_id=job_id, token=self.token) r = requests.post(url, headers=headers, data=xml) print r.status_code print r.text def download_file(self, job_id, file_reference_id): headers = { "X-EBAY-SOA-OPERATION-NAME": "downloadFile", "X-EBAY-SOA-SECURITY-TOKEN": self.token, "X-EBAY-API-COMPATIBILITY-LEVEL": '837', 'X-EBAY-SOA-SERVICE-NAME': 'FileTransferService', 'X-EBAY-SOA-REQUEST-DATA-FORMAT': 'XML', 'X-EBAY-SOA-RESPONSE-DATA-FORMAT': 'XML', # "X-EBAY-API-APP-NAME": "RedRocke-e380-4b45-ba54-78fb6c6832f5", # "X-EBAY-API-CALL-NAME": 'ReviseFixedPriceItem', # 'X-EBAY-API-DETAIL-LEVEL': '0', # "X-EBAY-API-SITEID": '0', # "X-EBAY-APE-CERT-NAME": "7a07bf5a-3385-4a5b-bdc9-2a66b045f0b7", # "X-EBAY-API-DEV-NAME": "f7e7239f-2cf9-4e4f-9413-1e08b524944c", # "Content-Type": 'application/xml', } url = "https://storage.ebay.com/FileTransferService" xml = """<?xml version="1.0" encoding="utf-8"?> <downloadFileRequest xmlns="http://www.ebay.com/marketplace/services"> <fileReferenceId>{file_reference_id}</fileReferenceId> <taskReferenceId>{job_id}</taskReferenceId> </downloadFileRequest>""".format(job_id=job_id, file_reference_id=file_reference_id) # r = requests.post(url, headers=headers, data=xml, stream=True) # with open("data_dump.response", 'w') as f: # r.raw.decode_content = True # data = r.raw.read() # f.write(data) r = requests.post(url, headers=headers, data=xml, stream=True) ebay_download_response = EbayFileDownloadResponse(StringIO(r.content)) fname = ebay_download_response.write_file() return fname def add_item(self, data): """ item_data = { 'Item': { 'StartPrice': '0.01', 'ListingDuration': 'Days_1', 'Currency': 'USD', 'Country': 'US', 'PrimaryCategory': {'CategoryID': '1033'}, 'Location': 'US', 'Title': 'Ninja Gaiden', 'Description': 'Ninja Gaiden for NES', 'PaymentMethods': 'PayPal', 'PayPalEmailAddress': '*****@*****.**', 'DispatchTimeMax': '3', 'ReturnPolicy': { 'ReturnsAcceptedOption': 'ReturnsAccepted', 'RefundOption': 'MoneyBack', 'ReturnWithinOption': 'Days_30', }, 'ShippingDetails': { 'ShippingServiceOptions': { 'ShippingServicePriority': '1', 'ShippingService': 'UPSGround', 'ShippingServiceCost': '0.00', 'ShippingServiceAdditionalCost': '0.00', } } } } """ response = self.api.execute('AddItem', data) return response def add_fixed_price_item(self, data): """ data schema looks like this: fixed_price_data = { 'Item': { 'ListingDuration': 'Days_5', 'StartPrice': '1.01', 'Currency': 'USD', 'Country': 'US', 'PrimaryCategory': {'CategoryID': '1033'}, 'Location': 'US', 'Title': 'Ninja Gaiden', 'Description': 'Ninja Gaiden for NES', 'PaymentMethods': 'PayPal', 'PayPalEmailAddress': '*****@*****.**', 'DispatchTimeMax': '3', 'ReturnPolicy': { 'ReturnsAcceptedOption': 'ReturnsAccepted', 'RefundOption': 'MoneyBack', 'ReturnWithinOption': 'Days_30', }, 'ShippingDetails': { 'ShippingServiceOptions': { 'ShippingServicePriority': '1', 'ShippingService': 'UPSGround', 'ShippingServiceCost': '0.00', 'ShippingServiceAdditionalCost': '0.00', } } } } """ response = self.api.execute('AddFixedPriceItem', data) return response def revise_fixed_price_item(self, data): response = self.api.execute('ReviseFixedPriceItem', data) return response def get_my_ebay_selling(self, page_number=None): my_ebay_selling_request = { 'ActiveList': { 'Include': 'true', 'ListingType': 'FixedPriceItem', } } if page_number: pagination = {'Pagination': {'PageNumber': page_number}} my_ebay_selling_request.update({'ActiveList': pagination}) response = self.api.execute('GetMyeBaySelling', my_ebay_selling_request) return response def update_inventory(self, item_id, quantity): inventory_status = { 'InventoryStatus': { 'ItemID': item_id, 'Quantity': quantity, } } response = self.api.execute('ReviseInventoryStatus', inventory_status) return response def update_inventory_by_sku(self, sku, quantity): inventory_status = { 'InventoryStatus': { 'SKU': sku, 'Quantity': quantity, } } response = self.api.execute('ReviseInventoryStatus', inventory_status) return response def get_item_by_id(self, _id): get_item = {'ItemID': _id} response = self.api.execute('GetItem', get_item) return response def get_item_by_sku(self, sku): get_item = {'SKU': sku} response = self.api.execute('GetItem', get_item) return response def update_image_by_id(self, item_id, url): item = { 'Item': { 'ItemID': item_id, 'PictureDetails': { 'PictureURL': url, } } } response = self.api.execute('ReviseFixedPriceItem', item) return response def relist_fixed_price_item(self, item_id, sku=None): if sku: item = { 'Item': { 'ItemID': item_id, 'InventoryTrackingMethod': 'SKU', 'SKU': sku } } else: item = { 'Item': { 'ItemID': item_id, } } response = self.api.execute('RelistFixedPriceItem', item) return response def revise_tracking_method_to_sku(self, item_id, sku): item = { 'Item': { 'ItemID': item_id, 'InventoryTrackingMethod': 'SKU', 'SKU': sku, } } response = self.api.execute('RelistFixedPriceItem', item) return response def end_fixed_price_item(self, item_id): item = { 'ItemID': item_id, 'EndingReason': 'OtherListingError', } response = self.api.execute('EndFixedPriceItem', item) return response def end_item_variation(self, item_id, sku, name, value): item = { 'Item': { 'ItemID': item_id, 'SKU': sku, 'Variations': { 'Variation': { 'SKU': sku, 'VariationSpecifics': { 'NameValueList': { 'Name': name, 'Value': value, } } }, } } } print item response = self.api.execute('EndFixedPriceItem', item) return response def update_item_variation(self, item_id, quantity, name, value): item = { 'Item': { 'ItemID': item_id, 'Variations': { 'Variation': { 'Quantity': quantity, 'VariationSpecifics': { 'NameValueList': { 'Name': name, 'Value': value, } } }, } } } response = self.api.execute('ReviseFixedPriceItem', item) return response def add_upc_code_to_item(self, item_id, upc): item = { 'Item': { 'ItemID': item_id, 'ProductListingDetails': upc, } } response = self.api.execute('ReviseFixedPriceItem', item) return response def add_upc_code_to_item_variation(self, item_id, upc, name, value): item = { 'Item': { 'ItemID': item_id, 'Variations': { 'Variation': { 'VariationProductListingDetails': { 'UPC': upc, }, 'VariationSpecifics': { 'NameValueList': { 'Name': name, 'Value': value, } } }, } } } response = self.api.execute('ReviseFixedPriceItem', item) return response def bulk_add_upc(self, items): request_data = [] for item in items: item_id, upc, name, value = item element = { 'Item': { 'ItemID': item_id, 'Variations': { 'Variation': { 'VariationProductListingDetails': { 'UPC': upc, }, 'VariationSpecifics': { 'NameValueList': { 'Name': name, 'Value': value, } } }, } } } request_data.append(element) response = self.api.execute('ReviseFixedPriceItem', request_data) return response def update_item_variation_quantity_by_item_id_and_sku( self, item_id, sku, quantity): item = { 'Item': { 'ItemID': item_id, 'Variations': { 'Variation': { 'SKU': sku, 'Quantity': quantity, }, } } } response = self.api.execute('ReviseFixedPriceItem', item) return response def update_item_variation2(self, item_id, varsku): item = {'ItemID': item_id, 'VariationSKU': varsku} response = self.api.execute('ReviseFixedPriceItem', item) return response def end_item(self, item_id): end = {'EndingReason': 'NotAvailable', 'ItemID': item_id} response = self.api.execute('EndItem', end) return response def get_all_active_orders(self, days=30): get_orders_request = { 'OrderStatus': 'Active', 'NumberOfDays': days, } response = self.api.execute('GetOrders', get_orders_request) return response def get_all_completed_orders(self, page=1, days=30): get_orders_request = { 'OrderStatus': 'Completed', 'Pagination': { 'PageNumber': page, }, 'NumberOfDays': days, } response = self.api.execute('GetOrders', get_orders_request) return response def get_orders(self, status, page=1, days=30): get_orders_request = { 'OrderStatus': status, 'Pagination': { 'PageNumber': page, }, 'NumberOfDays': days, } response = self.api.execute('GetOrders', get_orders_request) return response def complete_sale(self, tracking_code, carrier, transaction_id, item_id): # complete_sale_request = { # 'OrderLineItemId': order_line_item_id, # 'ShipmentTrackingDetails': { # 'ShipmentTrackingNumber': tracking_code, # 'ShippingCarrierUsed': carrier # }, # 'Shipped': 'true', # 'TransactionID': transaction_id # } complete_sale_request = { 'Shipment': { 'ShipmentTrackingDetails': { 'ShipmentTrackingNumber': tracking_code, 'ShippingCarrierUsed': carrier } }, 'Shipped': 'true', 'TransactionID': transaction_id, 'ItemID': item_id } response = self.api.execute('CompleteSale', complete_sale_request) return response def complete_sale_by_sku(self, tracking_code, carrier, transaction_id, sku): # complete_sale_request = { # 'OrderLineItemId': order_line_item_id, # 'ShipmentTrackingDetails': { # 'ShipmentTrackingNumber': tracking_code, # 'ShippingCarrierUsed': carrier # }, # 'Shipped': 'true', # 'TransactionID': transaction_id # } complete_sale_request = { 'Shipment': { 'ShipmentTrackingDetails': { 'ShipmentTrackingNumber': tracking_code, 'ShippingCarrierUsed': carrier } }, 'Shipped': 'true', 'TransactionID': transaction_id, 'SKU': sku } response = self.api.execute('CompleteSale', complete_sale_request) return response # def complete_multiple_sale(self, order_id,): # # complete_sale_request = { # 'ShipmentTrackingDetails': { # 'ShipmentTrackingNumber': tracking_code, # 'ShippingCarrierUsed': carrier # }, # 'Shipped': 'true', # 'TransactionID': transaction_id, # 'ItemID': item_id # } # # response = self.api.execute('CompleteSale', complete_sale_request) # return response def get_order_by_order_id(self, order_id): get_orders_request = {'OrderIDArray': [{'OrderID': order_id}]} response = self.api.execute('GetOrders', get_orders_request) return response
def get_my_ebay_selling(listings_type='Summary', api_options=None, api_inner_options=None, site_id=default_site_id): """Returns a list of listings from the GetMyeBaySelling eBay TradingAPI.""" INNER_PAGINATE = ('ActiveList', 'ScheduledList', 'SoldList', 'UnsoldList') RESPONSE_FIELDS = { 'ActiveList': ('ItemArray', 'Item'), 'DeletedFromSoldList': ('OrderTransactionArray', 'OrderTransaction'), 'DeletedFromUnsoldList': ('ItemArray', 'Item'), 'ScheduledList': ('ItemArray', 'Item'), 'SellingSummary': ('SellingSummary', None), 'SoldList': ('OrderTransactionArray', 'OrderTransaction'), 'UnsoldList': ('ItemArray', 'Item'), 'Summary': (None, None) } if api_options and listings_type in api_options: raise ValueError('Set listing type and inner options separately!') listings = [] page = 1 n_pages = None if api_options is None: api_options = {} if api_inner_options is None: api_inner_options = {} if listings_type != 'Summary': # Summary is not a real option, just a placeholder to get summary # information. api_inner_options['Include'] = True api_options[listings_type] = api_inner_options try: # Initialize TradingAPI; default timeout is 20. api = Trading(config_file=PATH_TO_YAML, siteid=site_id, warnings=True, timeout=20) while True: # TradingAPI results are often paginated, so loop until # all pages have been obtained if listings_type in INNER_PAGINATE: api_options[listings_type]['Pagination'] = { 'EntriesPerPage': 100, 'PageNumber': page } api.execute('GetMyeBaySelling', api_options) listings_api = api.response.dict() test_for_message(listings_api) # If appropriate on our first time around, find the total # number of pages. if n_pages is None: # Get Summary if it exists if 'Summary' in listings_api: summary = listings_api['Summary'] else: summary = None if listings_type in INNER_PAGINATE: if 'PaginationResult' in listings_api[listings_type]: n_pages = int( (listings_api[listings_type]['PaginationResult'] ['TotalNumberOfPages'])) else: n_pages = 1 print('n_pages = ', n_pages) if ('ItemArray' in listings_api[listings_type] and listings_api[listings_type]['ItemArray'] and 'Item' in listings_api[listings_type]['ItemArray']): n_items = len( listings_api[listings_type]['ItemArray']['Item']) else: n_items = 0 print(f'n_items per page = {n_items}') if n_pages > 1: print('page {} / {}'.format(page, n_pages)) # Locate the appropriate results field, array = RESPONSE_FIELDS[listings_type] if field is None: listings = listings_api elif array is None: listings = (listings_api[field] if field in listings_api else None) else: entries = listings_api[listings_type][field][array] # Check for single (non-list) entry if isinstance(entries, Sequence): listings.extend(entries) else: listings.append(entries) # If we are on the last page or there are no pages, break. if page >= (n_pages or 0): break page += 1 except ConnectionError as e: handle_ebay_error(e) return listings, summary
def GetSellerList( EndTimeFrom=None, EndTimeTo=None, GranularityLevel=None, IncludeVariations=False, IncludeWatchCount=False, StartTimeFrom=None, StartTimeTo=None, update_firebase=False, firebase_url=None ): options = {} if EndTimeFrom: options['EndTimeFrom'] = EndTimeFrom if EndTimeTo: options['EndTimeTo'] = EndTimeTo if GranularityLevel: options['GranularityLevel'] = GranularityLevel if IncludeVariations: options['IncludeVariations'] = str(IncludeVariations).lower() if IncludeWatchCount: options['IncludeWatchCount'] = str(IncludeWatchCount).lower() if StartTimeFrom: options['StartTimeFrom'] = StartTimeFrom if StartTimeTo: options['StartTimeTo'] = StartTimeTo if update_firebase and not firebase_url: raise Exception('if --update_firebase set to True, --firebase_url is required') fb = None if update_firebase: fb = firebase.FirebaseApplication(firebase_url, None) trading = Trading() num_executions = 0 options['Pagination'] = { 'EntriesPerPage': '200', 'PageNumber': 0 } has_more = True while has_more and num_executions < 10: options['Pagination']['PageNumber'] += 1 try: response = trading.execute('GetSellerList', options).dict() except ConnectionError as e: sys.stderr.write(json.dumps(e.response.dict()) + "\n") break # safety measure to make sure we dont have an infinite loop num_executions += 1 print 'PageNumber: %s' % options['Pagination']['PageNumber'] print json.dumps(response, sort_keys=True, indent=5) if update_firebase: _add_item_to_firebase(response, fb) has_more = response.get('HasMoreEntries') == "true"
from ebaysdk.trading import Connection as Trading from ebaysdk.exception import ConnectionError try: api = Trading(domain='api.sandbox.ebay.com', config_file='ebay.yaml') response = api.execute('GetUser', {}) print(response.dict()) #print(response.reply) except ConnectionError as e: print(e) print(e.response.dict())
class OrderRequest: def __init__(self, credentials): self.credentials = credentials self.api = Trading(config_file=None, **self.credentials) def get_orders_awaiting_shipment(self): for order in self.get_orders(days_back=2): # Only yield orders that haven't yet been shipped. if 'ShippedTime' not in order: yield order def get_shipped_orders(self): for order in self.get_orders(days_back=2): # Only yield orders that have been shipped. if 'ShippedTime' in order: yield order def get_orders(self, days_back=DAYS_BACK): self.start = arrow.utcnow().replace(days=-days_back) # The API doesn't like time values that it thinks are in the future. self.end = arrow.utcnow().replace(seconds=-5) for page in itertools.count(1): response = self._get_orders_for_page(page) reply = response.reply print('Page {}, {} items'.format(page, reply.ReturnedOrderCountActual)) rdict = response.dict() if 'OrderArray' in rdict: orders = rdict['OrderArray']['Order'] else: orders = () for order in orders: # Ignore orders that haven't been paid. if 'PaidTime' not in order: continue yield order if reply.PageNumber == reply.PaginationResult.TotalNumberOfPages: break def get_orders_detail(self): "Return orders awaiting shipment, including item and address info." orders = list(self.get_orders_awaiting_shipment()) for order in orders: order['items'] = list(get_items(order)) order['address'] = get_address(order) if '-' in order['OrderID']: item_id, transaction_id = order['OrderID'].split('-') url = SHIPPING_URL_TEMPLATE.format( transaction_id=transaction_id, item_id=item_id) else: url = SHIPPING_URL_TEMPLATE_2.format(order_id=order['OrderID']) order['shipping_url'] = url log('{user}: {items}'.format(user=order['BuyerUserID'], items=', '.join( get_items_text(order['items'])))) return orders def get_order(self, order_id): api = Trading(config_file=None, **self.credentials) response = api.execute('GetOrders', {'OrderIDArray': [{ 'OrderID': order_id }]}) return response.reply.OrderArray.Order[0] def _get_orders_for_page(self, page): """ Return the response object for a single page. """ response = self.api.execute( 'GetOrders', { 'CreateTimeFrom': self.start, 'CreateTimeTo': self.end, 'OrderStatus': 'Completed', 'Pagination': { 'PageNumber': page, 'EntriesPerPage': 100, } }) if page == 1: pagination = response.reply.PaginationResult print('Found {} orders over {} pages'.format( pagination.TotalNumberOfEntries, pagination.TotalNumberOfPages)) return response
def get_item_details(args, username, password, dbname, tablename): f = open('appId.txt') appId = f.read() connection_to_db = connect_to_database(username, password, dbname) cursor = connection_to_db.cursor() current_time = datetime.datetime.now() try: query = '''SELECT "itemId" FROM {}'''.format(tablename) cursor.execute(query) list_of_itemids = cursor.fetchall() list_of_itemids = [ list(list_of_itemids[i]) for i in range(len(list_of_itemids)) ] list_of_itemids.sort() except psycopg2.Error as error: print("Unable to retrieve itemID's from database : {}".format(dbname)) print(error) sys.exit try: f = open('5000itemid.txt', 'r') lines = f.readlines() item_id = lines[0] start_time = lines[1] start_time = start_time.split("\n")[0] start_time_datetime = datetime.datetime.strptime( start_time, '%Y-%m-%d %H:%M:%S') print("Starting from itemid : {}".format(item_id)) item_index = list_of_itemids.index([int(item_id)]) print("Starting from item index {}".format(item_index)) except: item_index = 0 start_time_datetime = datetime.datetime.now() - datetime.timedelta( seconds=1) if (current_time > start_time_datetime): try: api = Trading(config_file=args.yaml) except ConnectionError as e: print("There has been a connection error") print(e) print(e.response.dict()) for counter, itemid in enumerate(list_of_itemids[item_index:]): if (counter % 500 == 0): start = time.time() print("Getting Information from Item : {} out of : {}".format( counter, len(list_of_itemids[item_index:]))) itemid = str(itemid).split('[')[1].split(']')[0] api_request = { 'ItemID': itemid, 'IncludeItemSpecifics': True, 'DetailLevel': 'ReturnAll' } if (counter == 5000): now = datetime.datetime.now() + datetime.timedelta(days=1) now = now.strftime('%Y-%m-%d %H:%M:%S') print("""You've reached the 5,000, per 24 hours, call limit! Start the program again at {}, The timestamp of the last item has been saved to a file and will automatically be called the next time you run this program! """.format(now)) export = open("5000itemid.txt", 'w') export.write('{}\n{}'.format(str(itemid), now)) export.close() break try: response = api.execute('GetItem', api_request) item_information = response.dict()['Item'] item_specifics = item_information.pop('ItemSpecifics', None) if (item_specifics is not None): keys_to_keep = [ 'ListingDetails', 'Description', 'PictureDetails' ] relevant_information = {} for key in keys_to_keep: relevant_information[key] = item_information.pop(key) relevant_information = item_to_flat_dictionary( relevant_information) item_specifics = specifics_to_dict(item_specifics) relevant_information.update( item_specifics ) ##combines the three dictionaries together insert_value_into_db(connection_to_db, cursor, relevant_information, tablename, itemid) if (counter % 500 == 0): end = time.time() time_taken = (end - start) * counter time_remaining = (end - start) * len( list_of_itemids ) - time_taken ##change to list_of_itemids[index] hours = int(time_remaining / 3600) mins = (time_remaining / 60) % 60 print( "Time Remaining Roughly : {} Hours and {} Minutes". format(hours, mins)) else: print( "Item specifics for item : {} does not exist! ".format( itemid)) pass except ConnectionError as e: print("There has been a connection error") print(e) print(e.response.dict()) pass cursor.close() connection_to_db.close() else: print( "Your 24 Hour call period has not expired please run the program at {}" .format(start_time_datetime))
def get_orders(order_status='All', include_final_value_fees=True): """Returns a list of recent orders from the eBay TradingAPI. This list is NOT filtered by a siteid as the API call does not filter by siteid. """ num_days = int( frappe.get_value('eBay Manager Settings', filters=None, fieldname='ebay_sync_days')) try: if num_days < 1: frappe.msgprint('Invalid number of days: ' + str(num_days)) except TypeError: raise ValueError('Invalid type in ebay_sync_days') orders = [] page = 1 try: # Initialize TradingAPI; default timeout is 20. # Always use the US site for GetOrders as it returns fields we need # (which the UK site, for example, doesn't) and it doesn't filter by # siteID anyway api = Trading(config_file=PATH_TO_YAML, siteid=0, warnings=True, timeout=20) while True: # TradingAPI results are paginated, so loop until # all pages have been obtained api_options = { 'NumberOfDays': num_days, 'OrderStatus': order_status, 'Pagination': { 'EntriesPerPage': 50, 'PageNumber': page } } if include_final_value_fees: api_options['IncludeFinalValueFee'] = 'true' api.execute('GetOrders', api_options) orders_api = api.response.dict() test_for_message(orders_api) n_orders = int(orders_api['ReturnedOrderCountActual']) if n_orders > 0: if not isinstance(orders_api['OrderArray']['Order'], list): raise AssertionError('Invalid type in get_orders!') orders.extend(orders_api['OrderArray']['Order']) if orders_api['HasMoreOrders'] == 'false': break page += 1 except ConnectionError as e: handle_ebay_error(e) return orders, num_days
def dev_AddFixedPriceItem( PrimaryCategory, StartPrice, amazon_item=dict(), #Title="Harry Potter and the Philosopher's Stone", #Description="This is the first book in the Harry Potter series. In excellent condition!", #PictureURL="https://upload.wikimedia.org/wikipedia/en/b/bf/Harry_Potter_and_the_Sorcerer's_Stone.jpg", ListingDuration="GTC", PayPalEmailAddress="*****@*****.**", #UPC=None, #EAN=None, #Brand=None, #MPN=None, #Subtitle=None, action='VerifyAddFixedPriceItem'): try: api = Trading(config_file=config_file, appid=appid, certid=certid, devid=devid, warnings=False) myitem = { "Item": { "Title": amazon_item['title'], "Description": amazon_item['description'], "PrimaryCategory": { "CategoryID": str(PrimaryCategory) }, "StartPrice": StartPrice, "CategoryMappingAllowed": "true", "Country": "US", "ConditionID": "1000", "Currency": "USD", "DispatchTimeMax": "3", "ListingDuration": ListingDuration, "ListingType": "FixedPriceItem", "PaymentMethods": "PayPal", "PayPalEmailAddress": PayPalEmailAddress, "PictureDetails": { "PictureURL": amazon_item['pictureURL'] }, "PostalCode": "48105", "Quantity": "1", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": "If you are not satisfied, return the item for a refund.", "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingType": "Flat", "ShippingServiceOptions": { "ShippingServicePriority": "1", "ShippingService": "UPS3rdDay", "ShippingServiceCost": "2.50" } }, "Site": "US" } } if 'UPC' in amazon_item.keys(): myitem['UPC'] = amazon_item['UPC'] if 'EAN' in amazon_item.keys(): myitem['EAN'] = amazon_item['EAN'] if 'Brand' in amazon_item.keys() or 'MPN' in amazon_item.keys(): myitem['ProductListingDetails'] = dict() if 'Brand' in amazon_item.keys(): myitem['ProductListingDetails']['Brand'] = amazon_item['Brand'] if 'MPN' in amazon_item.keys(): myitem['ProductListingDetails']['MPN'] = amazon_item['MPN'] if 'Subtitle' in amazon_item.keys(): myitem["SubTitle"] = amazon_item["SubTitle"] return (api.execute(action, myitem)) #dump(api) except ConnectionError as e: print(e) print(e.response.dict())
class TheEbayAsmund: def connect_and_execute(self): '''''' self.api = Connection(config_file='ebay.yaml', domain='api.sandbox.ebay.com', debug=False) def xmltojson(self, function): self.output_dict = json.loads(json.dumps(xmltodict.parse(function))) def list(self): """ CREATE AN EBAY LISTING """ self.connect_and_execute() self.item_info = open("item_info.json", "r") self.item_info = json.load(self.item_info) self.item_title = self.item_info['item_name'] self.location = self.item_info['location'] self.site = self.item_info['Site'] self.PayPal_EMAIL = self.item_info['PayPal_EMAIL'] self.description = self.item_info['Description'] self.return_description = self.item_info['ReturnDescription'] self.handling_time = self.item_info['handling_time'] self.Price = self.item_info['Price'] self.request = { "Item": { "Title": self.item_title, "Country": "US", "Location": self.location, "Site": "US", "ConditionID": "1000", "PaymentMethods": "PayPal", "PayPalEmailAddress": self.PayPal_EMAIL, "PrimaryCategory": {"CategoryID": "33963"}, "Description": self.description, "ListingDuration": "GTC", "StartPrice": self.Price, "Currency": "USD", "ReturnPolicy": { "ReturnsAcceptedOption": "ReturnsAccepted", "RefundOption": "MoneyBack", "ReturnsWithinOption": "Days_30", "Description": self.return_description, "ShippingCostPaidByOption": "Buyer" }, "ShippingDetails": { "ShippingServiceOptions": { "FreeShipping": "True", "ShippingService": "USPSMedia" # you can put others aswell, such as FedEx Home Delivery/Smart Post, etc. } }, "DispatchTimeMax": self.handling_time } } def gather_info(self): '''GATHER INFO ABOUT THE SELLER & THE USER''' self.connect_and_execute() self.api.execute("GetSellerTransactions") self.seller_transactions = self.api.response_content() self.xmltojson(function=self.seller_transactions) #["Buyer"]["Email"] if int(self.output_dict["GetSellerTransactionsResponse"]["ReturnedTransactionCountActual"]) > 1: self.seller_id = self.output_dict['GetSellerTransactionsResponse']['Seller']['UserID'] self.buyer_mail = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Buyer']['Email'] self.buyer_feedback = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Buyer'][ 'FeedbackScore'] self.buyer_id = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Buyer']['UserID'] self.buyer_country = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Buyer'][ 'BuyerInfo']['ShippingAddress']['CountryName'] self.item_id = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Item']['ItemID'] self.transaction_id = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['TransactionID'] self.quantity = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Item']['Quantity'] self.price = \ self.output_dict["GetSellerTransactionsResponse"]['TransactionArray']['Transaction'][0]['Item'][ 'SellingStatus']['CurrentPrice']['#text'] print( f"Buyer ID: {self.buyer_id} | Buyer Email: {self.buyer_mail} | Buyer Feedback: {self.buyer_feedback} | Country: {self.buyer_country} | Item ID: {self.item_id} | Quantity: {self.quantity} | Transaction ID: {self.transaction_id} | Price: $%s" % self.price) else: print("EBAY: Sorry, but we found no transactions.") def send_message(self): try: self.gather_info() self.api.execute('AddMemberMessageAAQToPartner', {"ItemID": self.item_id, "MemberMessage": {"Body": "test", "RecipientID": self.buyer_id, "Subject": "No man, you are bad fsafsaafsfsafsafsa.", "Question": "You're befasfsafsaafssst", "QuestionType": "General"}}) self.message_response = self.api.response_content() self.xmltojson(function=self.message_response) except: print("EBAY SERVER ERROR [FAILED TO SEND MESSAGE]: Code 10007") def completesale(self): self.gather_info() self.api.execute('CompleteSale', {"ItemID": self.item_id, "TransactionID": self.transaction_id, "Shipped": True}).text self.completesale_info = self.api.response_content() self.xmltojson(function=self.completesale_info) if self.output_dict["CompleteSaleResponse"]["Ack"] == "Success": print("EBAY RESPONSE: Marked shipment as sent.") def getaccount(self): ''' GETS DATA FROM THE SELLER DASHBOARD SUCH AS LEVEL :return: ''' self.gather_info() try: self.api.execute('GetSellerDashboard') self.xmltojson(self.api.response_content()) self.SellerDashboard = self.output_dict["GetSellerDashboardResponse"] if self.output_dict["GetSellerDashboardResponse"]["Ack"] == "Success": print( f"User ID: {self.seller_id} | Power Level Status: {self.SellerDashboard['PowerSellerStatus']['Level']}") except: print("EBAY ERROR: Either an error occured or you don't have access to seller dashboard which means you haven't opened an seller account.") def get_messages(self): self.connect_and_execute() try: self.api.execute('GetMemberMessages', {"MailMessageType": "All", "DetailLevel": "ReturnSummary" }) self.xmltojson(self.api.response_content()) print(self.output_dict) except Exception as e: print(e) def lists(self): self.items = [] self.item_ids = [] self.prices = [] def get_allorders(self): self.lists() self.connect_and_execute() self.api.execute('GetMyeBaySelling', {"ActiveList": True}) self.xmltojson(self.api.response_content()) for key in self.output_dict["GetMyeBaySellingResponse"]["ActiveList"]["ItemArray"]['Item']: self.prices.append(f"${key['SellingStatus']['CurrentPrice']['#text']}") self.item_ids.append(key["ItemID"]) self.items.append(key["Title"]) panda = {"Item": self.items, "Item ID": self.item_ids, "Price": self.prices} dataframe = pd.DataFrame(data=panda) dataframe.to_excel("test.xlsx")
# Get ItemID for each item in Active List import json from ebaysdk.trading import Connection as Trading from ebaysdk.exception import ConnectionError try: # Connect to API and select all active listings api = Trading(domain='api.sandbox.ebay.com', config_file='ebay.yaml') response = api.execute('GetMyeBaySelling', {'ActiveList': 'ReturnAll'}) # Convert response into Python JSON object responseDictionary = json.loads(response.json()) # Get the count of how many active listings have been returned responseCount = responseDictionary["ActiveList"]["PaginationResult"][ "TotalNumberOfEntries"] # Iterate through each returned listing starting from 0 to responseCount - 1 for i in range(int(responseCount)): ItemID = responseDictionary["ActiveList"]["ItemArray"]["Item"][int( i)]["ItemID"] # ItemTitle = responseDictionary["ActiveList"]["ItemArray"]["Item"][int(i)]["SellingStatus"]["Title"] print("Item " + str(i) + " : " + ItemID) except ConnectionError as e: print(e) print(e.response.content)