def monitor(self): self.in_stock = False self.browser.get(self.product) wait(self.browser, self.TIMEOUT_LONG).until( lambda _: self.browser.current_url == self.product) while not self.img_found: try: if not self.img_found: product_img = self.browser.find_elements_by_class_name( 'slideDeckPicture')[0].find_element_by_tag_name("img") self.image_signal.emit(product_img.get_attribute("src")) self.product_image = product_img.get_attribute("src") self.img_found = True except Exception as e: continue while not self.in_stock: try: self.in_stock = self.check_stock() if self.in_stock: self.status_signal.emit( create_msg("Item in stock...", "normal")) self.browser.save_screenshot( "screenshots/target_" + datetime.now().strftime('%s') + ".png") if self.MONITOR_ONLY: self.notify() time.sleep(15) self.in_stock = False continue else: self.status_signal.emit( create_msg("Waiting on Restock", "normal")) time.sleep( random_delay(self.monitor_delay, settings.random_delay_start, settings.random_delay_stop)) self.browser.refresh() except Exception as e: continue
def submit_order(self): did_submit = False self.status_signal.emit(create_msg("Submitting Order", "normal")) while not did_submit: try: if len(self.browser.find_elements_by_id( 'creditCardInput-cvv')) > 0: self.browser.find_element_by_id( 'creditCardInput-cvv').send_keys( self.profile["card_cvv"]) self.browser.find_element_by_xpath( '//button[@data-test= "placeOrderButton"]').click() self.status_signal.emit(create_msg("Order Placed", "success")) send_webhook("OP", "Target", self.profile["profile_name"], self.task_id, self.product_image) did_submit = True except: continue
def submit_order(self): did_submit = False self.status_signal.emit(create_msg("Submitting Order", "normal")) url = self.browser.current_url while not did_submit: try: cvv_field = self.browser.find_elements_by_id('creditCardInput-cvv') if cvv_field: if len(cvv_field[0].get_attribute('value')) == 0: cvv_field[0].send_keys(self.profile["card_cvv"]) self.browser.find_element_by_xpath('//button[@data-test="placeOrderButton"]').click() time.sleep(5) if url != self.browser.current_url: self.status_signal.emit(create_msg("Order Placed", "success")) send_webhook("OP", "Target", self.profile["profile_name"], self.task_id, self.product_image) did_submit = True except: continue
def submit_billing(self): wait(self.browser, self.LONG_TIMEOUT).until(lambda _: self.browser.current_url == "https://www.gamestop.com/checkout/?stage=payment#payment") self.status_signal.emit(create_msg("Entering CVV #", "normal")) wait(self.browser, self.LONG_TIMEOUT).until(EC.element_to_be_clickable((By.ID, "saved-payment-security-code"))) cvv_input = self.browser.find_element_by_id("saved-payment-security-code") cvv_input.send_keys(self.profile["card_cvv"]) order_review_btn = self.browser.find_element_by_class_name("btn.btn-primary.btn-block.submit-payment") order_review_btn.click()
def submit_billing(self): added_cc = False added_cvv = False self.status_signal.emit(create_msg("Entering CC #", "normal")) while not added_cc: try: cc_input = self.browser.find_element_by_id( "creditCardInput-cardNumber") cc_input.send_keys(self.profile["card_number"]) if len( self.browser.find_elements_by_xpath( '//button[@data-test= "verify-card-button"]')) > 0: self.browser.find_element_by_xpath( '//button[@data-test= "verify-card-button"]').click() added_cc = True except: self.status_signal.emit( create_msg("CC Verification not needed", "normal")) break while not added_cvv: try: cvv_input = self.browser.find_element_by_id( "creditCardInput-cvv") self.status_signal.emit( create_msg("Entering CC Last 3", "normal")) cvv_input.send_keys(self.profile["card_cvv"]) if len( self.browser.find_elements_by_xpath( '//button[@data-test= "save-and-continue-button"]') ) > 0: self.browser.find_element_by_xpath( '//button[@data-test= "save-and-continue-button"]' ).click() added_cvv = True except: self.status_signal.emit( create_msg("No need to enter last 3", "normal")) break
def login(self): self.status_signal.emit(create_msg("Logging in...", "normal")) self.browser.get("https://www.bestbuy.com/identity/global/signin") self.browser.find_element_by_xpath('//*[@id="fld-e"]').send_keys(settings.bestbuy_user) self.browser.find_element_by_xpath('//*[@id="fld-p1"]').send_keys(settings.bestbuy_pass) self.browser.find_element_by_xpath( "//button[contains(@class,'cia-form__controls__submit')]" ).click() WebDriverWait(self.browser, 10).until( lambda x: "Official Online Store" in self.browser.title )
def process_interruptions(self, attempt=0, silent=False): if not silent: self.status_signal.emit( create_msg( f'Interrupted, attempting to resolve ({attempt+1}/{self.retry_attempts})', 'error')) for xpath_step in self.xpath_sequence: if xpath_step['optional']: self.process_step(xpath_step, wait_after=True, silent=True) for xpath_step in self.possible_interruptions: self.process_step(xpath_step, wait_after=True, silent=True)
def get_tas_data(self): headers = { "accept": "*/*", "accept-encoding": "gzip, deflate, br", "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", "content-type": "application/json", "referer": "https://www.bestbuy.com/checkout/r/payment", "user-agent": settings.userAgent, } while True: try: self.status_signal.emit(create_msg("Getting TAS Data", "normal")) r = requests.get( "https://www.bestbuy.com/api/csiservice/v2/key/tas", headers=headers ) self.status_signal.emit(create_msg("Got TAS Data", "normal")) return json.loads(r.text) except Exception as e: sleep(5)
def checkout(self): did_checkout = False self.status_signal.emit(create_msg("Checking out", "normal")) while not did_checkout: try: self.browser.find_element_by_xpath('//button[@data-test= "checkout-button"]').click() did_checkout = True time.sleep(random_delay(self.monitor_delay, settings.random_delay_start, settings.random_delay_stop)) except: continue
def auto_add_to_cart(self): self.status_signal.emit(create_msg("Attempting to auto add to cart...", "normal")) self.browser.refresh() time.sleep(2) if self.browser.find_elements_by_xpath("//button[@class='btn btn-primary btn-lg btn-block btn-leading-ficon add-to-cart-button'][1]"): button = self.browser.find_element_by_xpath("//button[@class='btn btn-primary btn-lg btn-block btn-leading-ficon add-to-cart-button'][1]") else: button = None if button: self.browser.execute_script("return arguments[0].scrollIntoView(true);", button) button.click()
def monitor(self): wait(self.browser, self.LONG_TIMEOUT).until(lambda _: self.browser.current_url == "https://www.gamestop.com/account/") self.status_signal.emit(create_msg("Checking Stock..", "normal")) self.browser.set_window_size(900, 900) self.browser.get(self.product) wait(self.browser, self.LONG_TIMEOUT).until( lambda _: self.browser.current_url == self.product) in_stock = False while not in_stock: try: wait( self.browser, random_delay( self.monitor_delay, settings.random_delay_start, settings.random_delay_stop)).until( EC.element_to_be_clickable( (By.XPATH, '//button[@data-buttontext="Add to Cart"]'))) add_to_cart_btn = self.browser.find_element_by_xpath( '//button[@data-buttontext="Add to Cart"]') add_to_cart_btn.click() time.sleep(1) if not add_to_cart_btn.is_enabled(): self.status_signal.emit( create_msg("Waiting For Restock", "normal")) self.browser.refresh() continue in_stock = True self.status_signal.emit(create_msg("Added to cart", "normal")) self.browser.get("https://www.gamestop.com/cart/") except: self.status_signal.emit( create_msg("Waiting For Restock", "normal")) self.browser.refresh()
def add_to_cart(self): wait(self.browser, self.LONG_TIMEOUT).until(lambda _: self.browser.current_url == "https://www.gamestop.com/cart/") self.status_signal.emit(create_msg("Checking Age Verification", "normal")) try: seventeen_or_older_btn = self.browser.find_element_by_xpath('//*[@id="age-gate-modal"]/div/div/div[2]/div/div[2]/button') seventeen_or_older_btn.click() time.sleep(2) # short delay for age verification modal to disappear self.browser.get("https://www.gamestop.com/checkout/?stage=payment#payment") except: self.browser.get("https://www.gamestop.com/checkout/?stage=payment#payment")
def init_driver(self): options = Options() if settings.run_headless: self.status_signal.emit(create_msg("Running headless", "normal")) options.headless = True profile = webdriver.FirefoxProfile() profile.set_preference("general.useragent.override", settings.userAgent) if settings.geckodriver_path == "": self.status_signal.emit( create_msg("Install geckodriver & set folder location", "stopnow")) return False else: driver = webdriver.Firefox(firefox_profile=profile, firefox_options=options, executable_path='geckodriver') return driver
def submit_shipping(self): self.status_signal.emit(create_msg("Starting Checkout", "normal")) headers = { "accept": "application/json, text/javascript, */*; q=0.01", "accept-encoding": "gzip, deflate, br", "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", "content-type": "application/json", "origin": "https://www.bestbuy.com", "referer": "https://www.bestbuy.com/cart", "user-agent": settings.userAgent, "x-user-interface": "DotCom-Optimized", "x-order-id": self.order_id, } while True: self.status_signal.emit(create_msg("Submitting Shipping", "normal")) body = {"selected": "SHIPPING"} response = self.session.put( "https://www.bestbuy.com/cart/item/{item_id}/fulfillment". format(item_id=self.item_id), headers=headers, json=body, ) response_json = response.json() self.status_signal.emit( create_msg(f"{response.status_code}", "normal")) self.status_signal.emit(create_msg(f"{response_json}", "normal")) if (response.status_code == 200 and response_json["order"]["id"] == self.order_id): self.status_signal.emit( create_msg("Submitted Shipping", "normal")) return True else: self.status_signal.emit( create_msg("Error Submitting Shipping", "error"))
def submit_order(self): wait(self.browser, self.LONG_TIMEOUT).until( lambda _: self.browser.current_url == "https://www.gamestop.com/checkout/?stage=placeOrder#placeOrder") self.status_signal.emit(create_msg("Submitting Order..", "normal")) wait(self.browser, self.LONG_TIMEOUT).until( EC.element_to_be_clickable( (By.CLASS_NAME, 'btn.btn-primary.btn-block.place-order'))) if not settings.dont_buy: order_review_btn = self.browser.find_element_by_class_name( "btn.btn-primary.btn-block.place-order") order_review_btn.click() self.status_signal.emit(create_msg("Order Placed", "success")) send_webhook("OP", "GameStop", self.profile["profile_name"], self.task_id, self.product_image) else: self.status_signal.emit(create_msg("Mock Order Placed", "success")) send_webhook("OP", "GameStop", self.profile["profile_name"], self.task_id, self.product_image)
def submit_payment(self, tas_data): body = { "items": [{ "id": self.item_id, "type": "DEFAULT", "selectedFulfillment": { "shipping": { "address": {} } }, "giftMessageSelected": False, }] } headers = { "accept": "application/com.bestbuy.order+json", "accept-encoding": "gzip, deflate, br", "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", "content-type": "application/json", "origin": "https://www.bestbuy.com", "referer": "https://www.bestbuy.com/checkout/r/fulfillment", "user-agent": settings.userAgent, "x-user-interface": "DotCom-Optimized", } r = self.session.patch( "https://www.bestbuy.com/checkout/d/orders/{}/".format( self.order_id), json=body, headers=headers, ) [ self.status_signal.emit( create_msg( f"{{\"name\": {c.name}, \"value\": {c.value}, \"domain\": {c.domain}, \"path\": {c.path}}}", "normal")) for c in self.session.cookies ] self.status_signal.emit(create_msg(f"{r.status_code}", "normal")) self.status_signal.emit(create_msg(f"{r.text}", "normal"))
def atc(self): declined_ins = False at_checkout = False self.status_signal.emit(create_msg("Declining Insurance", "normal")) while not declined_ins: try: decline_ins_btn = self.browser.find_element_by_xpath('//button[@data-test= "espModalContent-declineCoverageButton"]') decline_ins_btn.click() declined_ins = True except: continue self.status_signal.emit(create_msg("Viewing Cart before Checkout", "normal")) while not at_checkout: try: checkout_btn = self.browser.find_element_by_xpath('//button[@data-test= "addToCartModalViewCartCheckout"]') checkout_btn.click() at_checkout = True except: continue
def change_driver(status_signal, loc): fin = open(loc, 'rb') data = fin.read() val = "$" + "".join(random.choices(string.ascii_lowercase, k=3)) + "_" + \ "".join(random.choices(string.ascii_letters + string.digits, k=22)) + "_" result = re.search(b"[$][a-z]{3}_[a-zA-Z0-9]{22}_", data) if result is not None: try: status_signal.emit( create_msg("Changing value in Chromedriver", "normal")) data = data.replace(result.group(0), val.encode()) fin.close() fin = open(loc, 'wb') fin.truncate() fin.write(data) fin.close() except: status_signal.emit( create_msg("Error modifying chromedriver", "error")) else: fin.close()
def start_checkout(self): headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", "upgrade-insecure-requests": "1", "user-agent": settings.userAgent } while True: self.status_signal.emit(create_msg("Starting Checkout", "normal")) response = self.session.post( "https://www.bestbuy.com/cart/d/checkout", headers=headers, timeout=5) if response.status_code == 200: response_json = response.json() self.status_signal.emit( create_msg(f"{response.json()}", "normal")) self.order_id = response_json["updateData"]["order"]["id"] self.item_id = response_json["updateData"]["order"][ "lineItems"][0]["id"] self.status_signal.emit( create_msg( f"Started Checkout for order id: {self.order_id}", "normal")) self.status_signal.emit( create_msg(f"{response.json()}", "normal")) if response_json["updateData"]["redirectUrl"]: self.session.get( response_json["updateData"]["redirectUrl"], headers=headers) return self.status_signal.emit( create_msg("Error Starting Checkout", "error")) sleep(5)
def __init__(self, task_id, status_signal, image_signal, product, profile, proxy, monitor_delay, error_delay): self.task_id, self.status_signal, self.image_signal, self.product, self.profile, self.monitor_delay, self.error_delay = task_id, status_signal, image_signal, product, profile, float( monitor_delay), float(error_delay) starting_msg = "Starting Target" self.browser = self.init_driver() self.product_image = None if settings.dont_buy: starting_msg = "Starting Target in dev mode; will not actually checkout" self.status_signal.emit(create_msg(starting_msg, "normal")) self.status_signal.emit(create_msg("Logging In..", "normal")) self.login() self.monitor() self.atc() self.checkout() self.submit_billing() if not settings.dont_buy: self.submit_order() send_webhook("OP", "Target", self.profile["profile_name"], self.task_id, self.product_image) else: self.status_signal.emit(create_msg("Mock Order Placed", "success"))
def process_step(self, xpath_step, wait_after=False, silent=False): if self.browser.find_elements_by_xpath(xpath_step['path']): if not silent: self.status_signal.emit( create_msg(xpath_step['message'], xpath_step['message_type'])) if xpath_step['type'] == 'button': self.find_and_click(xpath_step['path']) elif xpath_step['type'] == 'method': xpath_step['method']() elif xpath_step['type'] == 'input': self.fill_field_and_proceed(xpath_step['path'], xpath_step['args']) if wait_after: time.sleep(self.TIMEOUT_SHORT)
def submit_order(self): self.did_submit = False url = self.browser.current_url while not self.did_submit: try: self.process_interruptions(silent=True) if not settings.dont_buy: self.browser.find_element_by_xpath( '//button[@data-test="placeOrderButton"]').click() time.sleep(5) if 'https://www.target.com/co-thankyou' in self.browser.current_url or settings.dont_buy: if settings.dont_buy: self.status_signal.emit( create_msg("Mock Order Placed", "success")) else: self.status_signal.emit( create_msg("Order Placed", "success")) send_webhook("OP", "Target", self.profile["profile_name"], self.task_id, self.product_image) self.did_submit = True except: self.status_signal.emit( create_msg('Retrying submit order until success', 'normal'))
def monitor(self): ## verify we have signed successfully else we should abort the task or attempt sign-in again # (TODO: add max attempts to sign-in before exiting task) if "user-message-initial" in self.browser.page_source: self.status_signal.emit( create_msg("Gamestop Successfully logged in...", "normal")) else: self.status_signal.emit( create_msg("Error logging in... please restart task", "stopnow")) # TODO: Exit task if we are not signed in self.status_signal.emit(create_msg("Checking Stock..", "normal")) # self.browser.set_window_size(900, 900) self.browser.get(self.product) wait(self.browser, self.LONG_TIMEOUT).until( lambda _: self.browser.current_url == self.product) in_stock = False while not in_stock: try: wait( self.browser, random_delay( self.monitor_delay, settings.random_delay_start, settings.random_delay_stop)).until( EC.element_to_be_clickable( (By.XPATH, '//button[@data-buttontext="Add to Cart"]'))) add_to_cart_btn = self.browser.find_element_by_xpath( '//button[@data-buttontext="Add to Cart"]') add_to_cart_btn.click() time.sleep(1) if not add_to_cart_btn.is_enabled(): self.status_signal.emit( create_msg("Waiting For Restock", "normal")) self.browser.refresh() continue in_stock = True self.status_signal.emit(create_msg("Added to cart", "normal")) self.browser.maximize_window() # remove stop temporarily to see if gamestop captcha is an issue # self.status_signal.emit(create_msg("Added to cart, check for captcha","stopnow")) self.browser.get("https://www.gamestop.com/cart/") except: self.status_signal.emit( create_msg("Waiting For Restock", "normal")) self.browser.refresh()
def init_driver(self): chrome_options = Options() if settings.run_headless: self.status_signal.emit(create_msg("Running headless","normal")) chrome_options.add_argument("--headless") chrome_options.add_argument(f"User-Agent={settings.userAgent}") driver = webdriver.Chrome(ChromeDriverManager().install(),options=chrome_options) driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ }) return driver
def monitor(self): if not self.MONITOR_ONLY: logged_in = False while not logged_in: try: wait(self.browser, self.LONG_TIMEOUT).until(lambda _: self.browser.current_url == "https://www.gamestop.com/account/") self.status_signal.emit(create_msg("Successfully Logged In", "normal")) logged_in = True except: self.status_signal.emit(create_msg("Log in failed. Retrying.", "normal")) self.login() if self.MONITOR_ONLY: time.sleep(random.randint(1, 4)) self.status_signal.emit(create_msg("Checking Stock..", "normal")) self.browser.get(self.product) wait(self.browser, self.LONG_TIMEOUT).until(lambda _: self.browser.current_url == self.product) in_stock = False while not in_stock: try: wait(self.browser, random_delay(self.monitor_delay, settings.random_delay_start, settings.random_delay_stop)).until(EC.element_to_be_clickable((By.XPATH, '//button[@data-buttontext="Add to Cart"]'))) add_to_cart_btn = self.browser.find_element_by_xpath('//button[@data-buttontext="Add to Cart"]') home_delivery_option = self.browser.find_element_by_xpath('//input[@value="home"]') if not self.MONITOR_ONLY: add_to_cart_btn.click() time.sleep(1) if not home_delivery_option.is_enabled() & add_to_cart_btn.is_enabled(): self.status_signal.emit(create_msg("Out of stock. Rechecking soon.", "normal")) time.sleep(self.monitor_delay + random.randint(1, 4)) self.browser.refresh() continue in_stock = True self.browser.save_screenshot("screenshots/gamestop_"+datetime.now().strftime('%s')+".png") if not self.MONITOR_ONLY: self.status_signal.emit(create_msg("Added to cart", "normal")) self.browser.get("https://www.gamestop.com/cart/") else: self.status_signal.emit(create_msg("Item in stock. Sending notification", "normal")) self.notify() except: self.status_signal.emit(create_msg("Waiting For Restock", "normal")) self.browser.refresh()
def auto_add_to_cart(self): self.status_signal.emit( create_msg("Attempting to auto add to cart...", "normal")) body = {"items": [{"skuId": self.sku_id}]} headers = { "Accept": "application/json", "authority": "www.bestbuy.com", "User-Agent": settings.userAgent, "Content-Type": "application/json; charset=UTF-8", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "origin": "https://www.bestbuy.com", "referer": self.product, "Content-Length": str(len(json.dumps(body))), } [ self.status_signal.emit( create_msg( f"{{\"name\": {c.name}, \"value\": {c.value}, \"domain\": {c.domain}, \"path\": {c.path}}}", "normal")) for c in self.session.cookies ] self.status_signal.emit(create_msg("Making request", "normal")) response = self.session.post(BEST_BUY_ADD_TO_CART_API_URL, json=body, headers=headers, timeout=5) self.status_signal.emit(create_msg(f"{response.status_code}", "normal")) if (response.status_code == 200 and response.json()["cartCount"] > 0 and self.sku_id in response.text): self.status_signal.emit( create_msg(f"Added {self.sku_id} to cart!", "normal")) self.status_signal.emit(create_msg(f"{response.json()}", "normal")) else: self.status_signal.emit( create_msg(f"{response.status_code}", "normal")) self.status_signal.emit(create_msg(f"{response.json()}", "normal"))
def login(self): self.status_signal.emit(create_msg("Logging In..", "normal")) #load home page so we get the cookies and referrer crap self.browser.get('https://www.gamestop.com/') time.sleep(5) if not settings.run_headless: # self.browser.maximize_window() self.browser.get( "https://www.gamestop.com/?openLoginModal=accountModal") time.sleep(5) self.browser.find_element_by_xpath( '//a[@id="account-modal-link-nocache"]').click() else: self.browser.get("https://www.gamestop.com/login/") wait(self.browser, self.LONG_TIMEOUT).until( EC.element_to_be_clickable((By.ID, "login-form-email"))) email = self.browser.find_element_by_id("login-form-email") email.send_keys(settings.gamestop_user) wait(self.browser, self.LONG_TIMEOUT).until( EC.element_to_be_clickable((By.ID, "login-form-password"))) time.sleep(5) password = self.browser.find_element_by_id("login-form-password") password.send_keys(settings.gamestop_pass) time.sleep( 2 ) # slight delay for in-between filling out login info and clicking Sign In sign_in_btn = wait(self.browser, self.LONG_TIMEOUT).until( EC.presence_of_element_located( (By.XPATH, "//button[@class='btn btn-block mb-2 sign-in-submit']"))) sign_in_btn.click() time.sleep(10)
def init_driver(self): if settings.run_headless: self.status_signal.emit(create_msg("Running headless", "normal")) options.add_argument("--headless") ## Gamestop does not like it when we do not have a user-agent driver = webdriver.Chrome(ChromeDriverManager().install(), options=options) driver.execute_cdp_cmd( "Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ }) driver.minimize_window() return driver
def __init__(self, task_id, status_signal, image_signal, product, profile, proxy, monitor_delay, error_delay, max_price): self.task_id, self.status_signal, self.image_signal, self.product, self.profile, self.monitor_delay, self.error_delay, self.max_price = task_id, status_signal, image_signal, product, profile, float( monitor_delay), float(error_delay), max_price starting_msg = "Starting GameStop" self.browser = self.init_driver() self.product_image = None self.SHORT_TIMEOUT = 5 self.LONG_TIMEOUT = 20 if settings.dont_buy: starting_msg = "Starting GameStop in dev mode; will not actually checkout." self.status_signal.emit(create_msg(starting_msg, "normal")) self.login() self.monitor() self.add_to_cart() self.submit_billing() self.submit_order()
def in_stock(self): self.status_signal.emit(create_msg("Checking stock", "normal")) url = "https://www.bestbuy.com/api/tcfb/model.json?paths=%5B%5B%22shop%22%2C%22scds%22%2C%22v2%22%2C%22page%22%2C%22tenants%22%2C%22bbypres%22%2C%22pages%22%2C%22globalnavigationv5sv%22%2C%22header%22%5D%2C%5B%22shop%22%2C%22buttonstate%22%2C%22v5%22%2C%22item%22%2C%22skus%22%2C{}%2C%22conditions%22%2C%22NONE%22%2C%22destinationZipCode%22%2C%22%2520%22%2C%22storeId%22%2C%22%2520%22%2C%22context%22%2C%22cyp%22%2C%22addAll%22%2C%22false%22%5D%5D&method=get".format( self.sku_id) # TODO: Add random delay configuration response = self.session.get(url, headers=DEFAULT_HEADERS) self.status_signal.emit( create_msg(f"Stock check response code: {response.status_code}", "normal")) try: response_json = response.json() item_json = find_values(json.dumps(response_json), "buttonStateResponseInfos") item_state = item_json[0][0]["buttonState"] self.status_signal.emit( create_msg(f"Item state is: {item_state}", "normal")) if item_json[0][0]["skuId"] == self.sku_id and item_state in [ "ADD_TO_CART", "PRE_ORDER" ]: return True else: return False except Exception as e: self.status_signal.emit( create_msg( "Error parsing json. Using string search to determine state.", "error")) self.status_signal.emit(create_msg(f"{response_json}", "normal")) self.status_signal.emit(create_msg(f"{e}", "error")) if "ADD_TO_CART" in response.text: #TODO: Make this case insensitive self.status_signal.emit( create_msg("Item is in stock!", "normal")) return True else: self.status_signal.emit( create_msg("Item is out of stock", "normal")) return False