From 6c64bdc30e26ade373cfeb1dbd014191257b50d0 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Dec 2024 20:36:12 -0700 Subject: [PATCH] converted full script to classes and methods --- depop.py | 14 ++ id_update.py | 1 + xlister.py | 558 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 370 insertions(+), 203 deletions(-) create mode 100644 depop.py diff --git a/depop.py b/depop.py new file mode 100644 index 0000000..1c3fc09 --- /dev/null +++ b/depop.py @@ -0,0 +1,14 @@ +import json +import os +import concurrent.futures +import wget +from ebaysdk.trading import Connection as Trading +from selenium import webdriver +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.by import By +import argparse +import id_update +import xlister + +login_url = 'https://www.depop.com/login/' diff --git a/id_update.py b/id_update.py index 71f30d4..3918d9a 100644 --- a/id_update.py +++ b/id_update.py @@ -30,6 +30,7 @@ def id_up(n): itemID = item['itemId'] #response = tapi.execute('GetItem',{'ItemID':itemID}).dict() ids.append(itemID) + print(ids) return ids '''def sku_up(itemID): diff --git a/xlister.py b/xlister.py index 6a9dad2..92c2bd2 100644 --- a/xlister.py +++ b/xlister.py @@ -1,236 +1,388 @@ -import os -import requests +#import os +#import requests +#import json +#import wget +#from selenium import webdriver +#from selenium.webdriver.common.keys import Keys +#from selenium.webdriver.support.select import Select +#from selenium.webdriver.common.by import By +#from selenium.webdriver.support.ui import WebDriverWait +#from selenium.webdriver.support import expected_conditions as EC +#from selenium.webdriver.common.action_chains import ActionChains +#from selenium.common.exceptions import TimeoutException +#import ebaysdk +#from ebaysdk.trading import Connection as Trading +#from ebaysdk.finding import Connection as Finding +#import concurrent.futures +#import id_update +# +## update ebay_ids.txt file: +# +#id_update.main() +# +## start selenium and log in to posh: +# +#browser = webdriver.Chrome("C:/Users/unknown/Desktop/projects/chromedriver") +# +#browser.get('https://poshmark.com/login') +#usename = browser.find_element_by_id('login_form_username_email') +#usename.send_keys('user') +#psw = browser.find_element_by_id('login_form_password') +#psw.send_keys('password') +#psw.submit() +#input('press "enter" to continue') +#browser.get('https://poshmark.com/create-listing') +# +# +# +#wait = WebDriverWait(browser, 120) +# +## Loop through each itemID to get relevant data to be used in posh listing: +# +#tapi = Trading(config_file = 'ebay1.yaml') +# +#img_num = [] # for use in ThreadPoolExecutor +#for i in range(-1, 11): +# i += 1 +# img_num.append(i) +# +## Cross-reference ebay and posh txt files to sync posh listings: +# +#with open('ebay_ids.txt') as jf: +# ebay_ids = json.load(jf) +#for i in range(0,len(ebay_ids)): +# id = ebay_ids[i] +# with open('posh_ids.txt') as jf: +# posh_ids = json.load(jf) +# with open('posh_skus.txt') as jf: +# posh_skus = json.load(jf) +# if id not in posh_ids: +# itemID = id +# response = tapi.execute('GetItem',{'ItemID':itemID,'DetailLevel': 'ReturnAll', 'IncludeItemSpecifics':'True'}).dict() +# print(itemID) +# +# # download first 8 ebay pics and temporarily hold until listing is done: +# +# def img_download(i): +# try: +# pic = response['Item']['PictureDetails']['PictureURL'][i] +# except IndexError: +# pass +# else: +# wget.download(pic, 'C:/Users/unknown/Desktop/projects/tempics/' + str(i) + '.jpg') +# img = 'C:/Users/unknown/Desktop/projects//tempics/' + str(i) + '.jpg' +# return img +# pics = [] +# with concurrent.futures.ThreadPoolExecutor() as executor: +# for future in executor.map(img_download, img_num): +# pics.append(future) +# pics_path = '\n'.join(pics) +# +# #begin image upload: +# +# fileup = browser.find_element_by_id('img-file-input') +# fileup.send_keys(pics_path) +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-name='apply']"))) +# apply = browser.find_element_by_xpath("//button[@data-et-name='apply']") +# apply.click() +# for image in pics: +# os.remove(image) # Delete images from local storage +# +# +# # consider creating a function that just takes the ebay id as input and returns the details below so that the function doesn't have to be redefined every iteration but merely called. +# cond_desc = response['Item']['ConditionDescription'] + ' Props not included' +# item_specs = response['Item']['ItemSpecifics'] +# nvl = item_specs['NameValueList'] +# nvl_dict = {d['Name']:d['Value'] for d in nvl} +# brand = nvl_dict['Brand'] +# cat = response['Item']['PrimaryCategory']['CategoryName'] +# try: +# color = nvl_dict['Color'] +# except KeyError: +# color = 'no color' +# +# posh_colors = ['Red', 'Pink', 'Orange', 'Yellow', 'Green', 'Blue', 'Purple', 'Gold', 'Silver', 'Black', 'Gray', 'White', 'Cream', 'Brown', 'Tan'] # (needed for cross-referencing) +# +# try: +# sku = response['Item']['SKU'] +# except KeyError: +# sku = 'missing' +# +# posh_title_specs_list = ['Model', 'Style'] +# posh_desc_specs_list = ['Boot Shaft Height', 'Calf Circumference', 'Material', 'Heel Height', 'Exact Heel Height', 'Country/Region of Manufacture'] # Consider adding 'Heel Type' and 'Toe Type' to the list +# +# posh_title = brand + ' ' +# for spec in posh_title_specs_list: +# if spec in nvl_dict: +# posh_title += nvl_dict[spec] + ' ' +# +# posh_desc = cond_desc + '\n'*2 +# for spec in posh_desc_specs_list: +# if spec in nvl_dict: +# posh_desc += spec + ': ' + nvl_dict[spec] + '\n'*2 +# +# # retrieve size listed in ebay +# +# us_sz = 'US ' + nvl_dict["US Shoe Size (Women's)"].replace('US', ' ').replace(' ', '') +# +# # Begin size disclaimer to include in posh description +# sz_spec_list = ["EUR Shoe Size (Women's)", "UK Shoe Size (Women's)"] +# size_disclaimer = '* Manufacture Sizing: ' + us_sz +# +# n = -1 +# for sz in sz_spec_list: +# n+=1 +# if sz in nvl_dict: +# size_disclaimer += ' = ' + sz_spec_list[n] + ' ' + nvl_dict[sz] + '\n'*2 +# +# ebay_title = response['Item']['Title'] # Might use this later for something +# print(ebay_title) +# +# price = response['Item']['ListingDetails']['ConvertedStartPrice']['value'] +# price = str(round(float(price)/.75)) # 33.33 % bump from original price +# +# +# # Begin creating poshmark lising: +# +# +# # Select Dropdown Category and Dismiss Subcategory +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Select a Category')]"))) +# drop_cat = browser.find_element_by_xpath("//*[contains(text(), 'Select a Category')]").click() +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Shoes')]"))) +# drop_cat = browser.find_element_by_xpath("//*[contains(text(), 'Shoes')]").click() +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Select Subcategory (optional)')]"))) +# sub_cat = browser.find_element_by_xpath("//*[contains(text(), 'Select Subcategory (optional)')]").click() +# +# # Fill in Custom Posh Size +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Select Size']"))) +# drop_sz = browser.find_element_by_xpath("//span[text()='Select Size']").click() +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Custom')]"))) +# drop_sz = browser.find_element_by_xpath("//*[contains(text(), 'Custom')]").click() +# +# custom_size = browser.find_element_by_xpath("//input[@data-vv-name='customSize']").send_keys(us_sz) +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Save')]"))) +# save_size = browser.find_element_by_xpath("//*[contains(text(), 'Save')]").click() +# +# # Begin Posh Title +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@data-vv-name='title']"))) +# title = browser.find_element_by_xpath("//input[@data-vv-name='title']") +# title.send_keys(posh_title) +# +# # Begin Item Description +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//textarea[@data-vv-name='description']"))) +# desc = browser.find_element_by_xpath("//textarea[@data-vv-name='description']") +# desc.send_keys(posh_desc + '\n' + size_disclaimer + '\n'*2 + sku) +# +# # Begin Brand Input +# +# brand_input = browser.find_element_by_xpath("//input[@placeholder='Enter the Brand/Designer']") +# brand_input.send_keys(brand) +# +# # Fill Original Price and List Price +# +# msrp = browser.find_element_by_xpath("//input[@data-vv-name='originalPrice']") +# msrp.send_keys('0') +# +# list_price = browser.find_element_by_xpath("//input[@data-vv-name='listingPrice']").send_keys(price) +# +# # Select Color +# +# if color in posh_colors: +# wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Select up to 2 colors']"))) +# browser.find_element_by_xpath("//span[text()='Select up to 2 colors']").click() +# wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), '" + color + "')]"))) +# browser.find_element_by_xpath("//*[contains(text(), '" + color + "')]").click() +# wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-on-name='color_tile']"))) +# browser.find_element_by_xpath("//button[@data-et-on-name='color_tile']").click() +# +# # Begin Listing Publishing +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-name='next']"))) +# browser.find_element_by_xpath("//button[@data-et-name='next']").click() +# +# wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-name='list_item']"))) +# browser.find_element_by_xpath("//button[@data-et-name='list_item']").click() +# try: +# wait.until(EC.presence_of_element_located((By.XPATH, "//title[text()='Feed - Poshmark']"))) +# except TimeoutException: +# input("press 'enter' to continue") +# +# # Begin New Listing +# +# browser.get('https://poshmark.com/create-listing') +# +# # update posh data files: +# +# posh_ids.append(itemID) +# with open('posh_ids.txt', 'w') as jf: +# json.dump(posh_ids, jf) +# posh_skus.append(sku) +# with open('posh_skus.txt', 'w') as jf: +# json.dump(posh_skus, jf) +# posh_sku_dict = dict(zip(posh_skus, posh_ids)) +# with open('posh_sku_dict.txt', 'w') as jf: +# json.dump(posh_sku_dict, jf) +# else: +# pass +## End for loop import json +import os +import concurrent.futures import wget +from ebaysdk.trading import Connection as Trading from selenium import webdriver -from selenium.webdriver.common.keys import Keys -from selenium.webdriver.support.select import Select -from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC -from selenium.webdriver.common.action_chains import ActionChains -from selenium.common.exceptions import TimeoutException -import ebaysdk -from ebaysdk.trading import Connection as Trading -from ebaysdk.finding import Connection as Finding -import concurrent.futures +from selenium.webdriver.common.by import By +import argparse import id_update -# update ebay_ids.txt file: -id_update.main() - -# start selenium and log in to posh: - -browser = webdriver.Chrome("C:/Users/unknown/Desktop/projects/chromedriver") - -browser.get('https://poshmark.com/login') -usename = browser.find_element_by_id('login_form_username_email') -usename.send_keys('SpeanutButter') -psw = browser.find_element_by_id('login_form_password') -psw.send_keys('***REMOVED***') -psw.submit() -input('press "enter" to continue') -browser.get('https://poshmark.com/create-listing') +class FileHandler: + @staticmethod + def load_json(filename): + with open(filename) as f: + return json.load(f) + + @staticmethod + def save_json(data, filename): + with open(filename, 'w') as f: + json.dump(data, f) +class EbayAPI: + def __init__(self, config_file): + self.tapi = Trading(config_file=config_file) + + def get_item_details(self, item_id): + response = self.tapi.execute('GetItem', {'ItemID': item_id, 'DetailLevel': 'ReturnAll', 'IncludeItemSpecifics': 'True'}).dict() + return response['Item'] -wait = WebDriverWait(browser, 120) + def get_details_with_images(self, item_id, image_downloader): + item_details = self.get_item_details(item_id) + image_urls = item_details['PictureDetails']['PictureURL'][:8] # Getting the first 8 images + images_paths = image_downloader.download_images(image_urls) -# Loop through each itemID to get relevant data to be used in posh listing: + # Add image paths to details + item_details['ImagePaths'] = images_paths + return item_details -tapi = Trading(config_file = 'ebay1.yaml') -img_num = [] # for use in ThreadPoolExecutor -for i in range(-1, 11): - i += 1 - img_num.append(i) +class ImageDownloader: + def __init__(self, temp_dir='tempics/'): + self.temp_dir = temp_dir + os.makedirs(self.temp_dir, exist_ok=True) -# Cross-reference ebay and posh txt files to sync posh listings: + def download_images(self, image_urls): + return self._download(image_urls, self.temp_dir) -with open('ebay_ids.txt') as jf: - ebay_ids = json.load(jf) -for i in range(0,len(ebay_ids)): - id = ebay_ids[i] - with open('posh_ids.txt') as jf: - posh_ids = json.load(jf) - with open('posh_skus.txt') as jf: - posh_skus = json.load(jf) - if id not in posh_ids: - itemID = id - response = tapi.execute('GetItem',{'ItemID':itemID,'DetailLevel': 'ReturnAll', 'IncludeItemSpecifics':'True'}).dict() - print(itemID) + def _download(self, image_urls, folder_path): + def download(url, index): + filepath = os.path.join(folder_path, f'{index}.jpg') + wget.download(url, filepath) + return filepath - # download first 8 ebay pics and temporarily hold until listing is done: - - def img_download(i): - try: - pic = response['Item']['PictureDetails']['PictureURL'][i] - except IndexError: - pass - else: - wget.download(pic, 'C:/Users/unknown/Desktop/projects/tempics/' + str(i) + '.jpg') - img = 'C:/Users/unknown/Desktop/projects//tempics/' + str(i) + '.jpg' - return img - pics = [] with concurrent.futures.ThreadPoolExecutor() as executor: - for future in executor.map(img_download, img_num): - pics.append(future) - pics_path = '\n'.join(pics) + image_paths = list(executor.map(download, image_urls, range(len(image_urls)))) + return image_paths - #begin image upload: - - fileup = browser.find_element_by_id('img-file-input') - fileup.send_keys(pics_path) - - wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-name='apply']"))) - apply = browser.find_element_by_xpath("//button[@data-et-name='apply']") - apply.click() - for image in pics: - os.remove(image) # Delete images from local storage + def cleanup(self): + for file in os.listdir(self.temp_dir): + os.remove(os.path.join(self.temp_dir, file)) - # consider creating a function that just takes the ebay id as input and returns the details below so that the function doesn't have to be redefined every iteration but merely called. - cond_desc = response['Item']['ConditionDescription'] + ' Props not included' - item_specs = response['Item']['ItemSpecifics'] - nvl = item_specs['NameValueList'] - nvl_dict = {d['Name']:d['Value'] for d in nvl} - brand = nvl_dict['Brand'] - cat = response['Item']['PrimaryCategory']['CategoryName'] - try: - color = nvl_dict['Color'] - except KeyError: - color = 'no color' +class PoshmarkAutomator: + def __init__(self, driver_path): + self.driver = webdriver.Chrome(driver_path) + self.wait = WebDriverWait(self.driver, 120) - posh_colors = ['Red', 'Pink', 'Orange', 'Yellow', 'Green', 'Blue', 'Purple', 'Gold', 'Silver', 'Black', 'Gray', 'White', 'Cream', 'Brown', 'Tan'] # (needed for cross-referencing) + def login(self, username, password): + self.driver.get('https://poshmark.com/login') + self.driver.find_element(By.ID, 'login_form_username_email').send_keys(username) + self.driver.find_element(By.ID, 'login_form_password').send_keys(password).submit() + input('press "enter" to continue') - try: - sku = response['Item']['SKU'] - except KeyError: - sku = 'missing' - - posh_title_specs_list = ['Model', 'Style'] - posh_desc_specs_list = ['Boot Shaft Height', 'Calf Circumference', 'Material', 'Heel Height', 'Exact Heel Height', 'Country/Region of Manufacture'] # Consider adding 'Heel Type' and 'Toe Type' to the list - - posh_title = brand + ' ' - for spec in posh_title_specs_list: - if spec in nvl_dict: - posh_title += nvl_dict[spec] + ' ' - - posh_desc = cond_desc + '\n'*2 - for spec in posh_desc_specs_list: - if spec in nvl_dict: - posh_desc += spec + ': ' + nvl_dict[spec] + '\n'*2 - - # retrieve size listed in ebay - - us_sz = 'US ' + nvl_dict["US Shoe Size (Women's)"].replace('US', ' ').replace(' ', '') - - # Begin size disclaimer to include in posh description - sz_spec_list = ["EUR Shoe Size (Women's)", "UK Shoe Size (Women's)"] - size_disclaimer = '* Manufacture Sizing: ' + us_sz - - n = -1 - for sz in sz_spec_list: - n+=1 - if sz in nvl_dict: - size_disclaimer += ' = ' + sz_spec_list[n] + ' ' + nvl_dict[sz] + '\n'*2 - - ebay_title = response['Item']['Title'] # Might use this later for something - print(ebay_title) - - price = response['Item']['ListingDetails']['ConvertedStartPrice']['value'] - price = str(round(float(price)/.75)) # 33.33 % bump from original price + def create_listing(self, item_details, image_paths): + self.driver.get('https://poshmark.com/create-listing') + # Add logic here to fill out and submit the listing form using item_details and image_paths + + def close(self): + self.driver.quit() - # Begin creating poshmark lising: +def fetch_ebay_data(image_dir): + ebay_handler = FileHandler() + ebay_api = EbayAPI(config_file='ebay1.yaml') + image_downloader = ImageDownloader(temp_dir=image_dir) + ebay_ids = ebay_handler.load_json('ebay_ids.txt') + all_details = [] - # Select Dropdown Category and Dismiss Subcategory + for ebay_id in ebay_ids: + # Get item details and images + item_details = ebay_api.get_details_with_images(ebay_id, image_downloader) + + # Append details including image paths to final list + all_details.append(item_details) - wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Select a Category')]"))) - drop_cat = browser.find_element_by_xpath("//*[contains(text(), 'Select a Category')]").click() + # Optionally save each item's details with their images + item_detail_path = f'ebay_item_{ebay_id}.json' + ebay_handler.save_json(item_details, item_detail_path) + print(f'Detailed data for item {ebay_id} has been saved.') - wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Shoes')]"))) - drop_cat = browser.find_element_by_xpath("//*[contains(text(), 'Shoes')]").click() +def create_listing(): + # Update eBay IDs + id_update.main() - wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Select Subcategory (optional)')]"))) - sub_cat = browser.find_element_by_xpath("//*[contains(text(), 'Select Subcategory (optional)')]").click() + ebay_handler = FileHandler() + posh_handler = FileHandler() + + ebay_api = EbayAPI(config_file='ebay1.yaml') + image_downloader = ImageDownloader() + posh_automator = PoshmarkAutomator(driver_path="C:/Users/unknown/Desktop/projects/chromedriver") + + ebay_ids = ebay_handler.load_json('ebay_ids.txt') + posh_ids = posh_handler.load_json('posh_ids.txt') + + posh_automator.login('user', 'password') + + for ebay_id in ebay_ids: + if ebay_id not in posh_ids: + # Get item details and images + item_details = ebay_api.get_details_with_images(ebay_id, image_downloader) + + # Create Poshmark listing + posh_automator.create_listing(item_details, item_details.get('ImagePaths')) + + # Clean up downloaded images + image_downloader.cleanup() + + # Update Posh IDs and SKUs + posh_ids.append(ebay_id) + posh_handler.save_json(posh_ids, 'posh_ids.txt') + + posh_automator.close() - # Fill in Custom Posh Size +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--action', choices=['list', 'fetch'], default='list', help='Choose to `fetch` eBay data or `list` items on Poshmark.') + parser.add_argument('--image-dir', default='downloaded_images', help='The directory where the images will be saved.') - wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Select Size']"))) - drop_sz = browser.find_element_by_xpath("//span[text()='Select Size']").click() + args = parser.parse_args() + + if args.action == 'fetch': + fetch_ebay_data(args.image_dir) + elif args.action == 'list': + create_listing() - wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Custom')]"))) - drop_sz = browser.find_element_by_xpath("//*[contains(text(), 'Custom')]").click() - - custom_size = browser.find_element_by_xpath("//input[@data-vv-name='customSize']").send_keys(us_sz) - - wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Save')]"))) - save_size = browser.find_element_by_xpath("//*[contains(text(), 'Save')]").click() - - # Begin Posh Title - - wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@data-vv-name='title']"))) - title = browser.find_element_by_xpath("//input[@data-vv-name='title']") - title.send_keys(posh_title) - - # Begin Item Description - - wait.until(EC.element_to_be_clickable((By.XPATH, "//textarea[@data-vv-name='description']"))) - desc = browser.find_element_by_xpath("//textarea[@data-vv-name='description']") - desc.send_keys(posh_desc + '\n' + size_disclaimer + '\n'*2 + sku) - - # Begin Brand Input - - brand_input = browser.find_element_by_xpath("//input[@placeholder='Enter the Brand/Designer']") - brand_input.send_keys(brand) - - # Fill Original Price and List Price - - msrp = browser.find_element_by_xpath("//input[@data-vv-name='originalPrice']") - msrp.send_keys('0') - - list_price = browser.find_element_by_xpath("//input[@data-vv-name='listingPrice']").send_keys(price) - - # Select Color - - if color in posh_colors: - wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Select up to 2 colors']"))) - browser.find_element_by_xpath("//span[text()='Select up to 2 colors']").click() - wait.until(EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), '" + color + "')]"))) - browser.find_element_by_xpath("//*[contains(text(), '" + color + "')]").click() - wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-on-name='color_tile']"))) - browser.find_element_by_xpath("//button[@data-et-on-name='color_tile']").click() - - # Begin Listing Publishing - - wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-name='next']"))) - browser.find_element_by_xpath("//button[@data-et-name='next']").click() - - wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-et-name='list_item']"))) - browser.find_element_by_xpath("//button[@data-et-name='list_item']").click() - try: - wait.until(EC.presence_of_element_located((By.XPATH, "//title[text()='Feed - Poshmark']"))) - except TimeoutException: - input("press 'enter' to continue") - - # Begin New Listing - - browser.get('https://poshmark.com/create-listing') - - # update posh data files: - - posh_ids.append(itemID) - with open('posh_ids.txt', 'w') as jf: - json.dump(posh_ids, jf) - posh_skus.append(sku) - with open('posh_skus.txt', 'w') as jf: - json.dump(posh_skus, jf) - posh_sku_dict = dict(zip(posh_skus, posh_ids)) - with open('posh_sku_dict.txt', 'w') as jf: - json.dump(posh_sku_dict, jf) - else: - pass -# End for loop +if __name__ == "__main__": + main()