Exemplo n.º 1
0
    def check_stock(self, asin, reserve, retry=0):
        if retry > DEFAULT_MAX_ATC_TRIES:
            log.info("max add to cart retries hit, returning to asin check")
            return False
        if self.checkshipping:
            if self.used:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin)
            else:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin +
                         "/ref=olp_f_new&f_new=true")
        else:
            if self.used:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin +
                         "/f_freeShipping=on")
            else:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin +
                         "/ref=olp_f_new&f_new=true&f_freeShipping=on")
        try:
            while True:
                try:
                    try:
                        searching_update()
                    except Exception:
                        pass
                    self.driver.get(f.url)
                    break
                except Exception:
                    log.error(
                        "Failed to get the URL, were in the exception now.")
                    time.sleep(3)
                    pass
            elements = self.driver.find_elements_by_xpath(
                '//*[@name="submit.addToCart"]')
            prices = self.driver.find_elements_by_xpath(
                '//*[@class="a-size-large a-color-price olpOfferPrice a-text-bold"]'
            )
            shipping = self.driver.find_elements_by_xpath(
                '//*[@class="a-color-secondary"]')
        except Exception as e:
            log.error(e)
            return None

        in_stock = False
        for i in range(len(elements)):
            price = parse_price(prices[i].text)
            if SHIPPING_ONLY_IF in shipping[i].text:
                ship_price = parse_price("0")
            else:
                ship_price = parse_price(shipping[i].text)
            ship_float = ship_price.amount
            price_float = price.amount
            if price_float is None:
                return False
            if ship_float is None or not self.checkshipping:
                ship_float = 0

            if (ship_float + price_float) <= reserve or math.isclose(
                (price_float + ship_float), reserve, abs_tol=0.01):
                log.info("Item in stock and under reserve!")
                log.info("clicking add to cart")
                try:
                    buy_update()
                except:
                    pass
                elements[i].click()
                time.sleep(self.page_wait_delay())
                if self.driver.title in SHOPING_CART_TITLES:
                    return True
                else:
                    log.info("did not add to cart, trying again")
                    log.debug(f"failed title was {self.driver.title}")
                    if self.no_screenshots:
                        self.notification_handler.send_notification(
                            "failed-atc")
                    else:
                        self.save_screenshot("failed-atc")
                    self.save_page_source("failed-atc")
                    in_stock = self.check_stock(asin=asin,
                                                reserve=reserve,
                                                retry=retry + 1)
        return in_stock
Exemplo n.º 2
0
    def check_stock(self, asin, reserve_min, reserve_max, retry=0):
        if retry > DEFAULT_MAX_ATC_TRIES:
            log.info("max add to cart retries hit, returning to asin check")
            return False
        if self.checkshipping:
            if self.used:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin)
            else:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin + "/ref=olp_f_new&f_new=true")
        else:
            if self.used:
                f = furl(AMAZON_URLS["OFFER_URL"] + asin + "/f_freeShipping=on")
            else:
                f = furl(
                    AMAZON_URLS["OFFER_URL"]
                    + asin
                    + "/ref=olp_f_new&f_new=true&f_freeShipping=on"
                )
        fail_counter = 0
        presence.searching_update()

        while True:
            try:
                self.get_page(f.url)
                break
            except Exception:
                fail_counter += 1
                log.error(f"Failed to load the offer URL {fail_counter} times.")
                if fail_counter < DEFAULT_MAX_URL_FAIL:
                    log.error(
                        f"WebDriver will restart if it fails {DEFAULT_MAX_URL_FAIL} times. Retrying now..."
                    )
                    time.sleep(3)
                else:
                    log.info(
                        "Attempting to delete and recreate current chrome instance"
                    )
                    if not self.delete_driver():
                        log.error("Failed to delete chrome processes")
                        log.error("Please restart bot")
                        self.send_notification(
                            message="Bot Failed, please restart bot",
                            page_name="Bot Failed",
                            take_screenshot=False,
                        )
                        raise RuntimeError("Failed to restart bot")
                    elif not self.create_driver():
                        log.error("Failed to recreate webdriver processes")
                        log.error("Please restart bot")
                        self.send_notification(
                            message="Bot Failed, please restart bot",
                            page_name="Bot Failed",
                            take_screenshot=False,
                        )
                        raise RuntimeError("Failed to restart bot")
                    else:  # deleted driver and recreated it succesfully
                        log.info(
                            "WebDriver recreated successfully. Returning back to stock check"
                        )
                        return False

        timeout = self.get_timeout()
        while True:
            atc_buttons = self.driver.find_elements_by_xpath(
                '//*[@name="submit.addToCart"]'
            )
            if atc_buttons:
                # Early out if we found buttons
                break

            test = None
            try:
                test = self.driver.find_element_by_xpath(
                    '//*[@id="olpOfferList"]/div/p'
                )
            except exceptions.NoSuchElementException:
                pass

            if test and (test.text in NO_SELLERS):
                return False
            if time.time() > timeout:
                log.info(f"failed to load page for {asin}, going to next ASIN")
                return False

        timeout = self.get_timeout()
        while True:
            prices = self.driver.find_elements_by_xpath(
                '//*[@class="a-size-large a-color-price olpOfferPrice a-text-bold"]'
            )
            if prices:
                break
            if time.time() > timeout:
                log.info(f"failed to load prices for {asin}, going to next ASIN")
                return False
        shipping = []
        if self.checkshipping:
            timeout = self.get_timeout()
            while True:
                shipping = self.driver.find_elements_by_xpath(
                    '//*[@class="a-color-secondary"]'
                )
                if shipping:
                    break
                if time.time() > timeout:
                    log.info(f"failed to load shipping for {asin}, going to next ASIN")
                    return False

        in_stock = False

        for idx, atc_button in enumerate(atc_buttons):
            try:
                price = parse_price(prices[idx].text)
            except IndexError:
                log.debug("Price index error")
                return False
            try:
                if self.checkshipping:
                    if SHIPPING_ONLY_IF in shipping[idx].text:
                        ship_price = parse_price("0")
                    else:
                        ship_price = parse_price(shipping[idx].text)
                else:
                    ship_price = parse_price("0")
            except IndexError:
                log.debug("shipping index error")
                return False
            ship_float = ship_price.amount
            price_float = price.amount
            if price_float is None:
                return False
            if ship_float is None or not self.checkshipping:
                ship_float = 0

            if (
                (ship_float + price_float) <= reserve_max
                or math.isclose((price_float + ship_float), reserve_max, abs_tol=0.01)
            ) and (
                (ship_float + price_float) >= reserve_min
                or math.isclose((price_float + ship_float), reserve_min, abs_tol=0.01)
            ):
                log.info("Item in stock and in reserve range!")
                log.info("clicking add to cart")
                self.notification_handler.play_notify_sound()
                if self.detailed:
                    self.send_notification(
                        message=f"Found Stock ASIN:{asin}",
                        page_name="Stock Alert",
                        take_screenshot=self.take_screenshots,
                    )

                presence.buy_update()
                current_title = self.driver.title
                # log.info(f"current page title is {current_title}")
                try:
                    atc_button.click()
                except IndexError:
                    log.debug("Index Error")
                    return False
                self.wait_for_page_change(current_title)
                # log.info(f"page title is {self.driver.title}")
                if self.driver.title in SHOPING_CART_TITLES:
                    return True
                else:
                    log.info("did not add to cart, trying again")
                    log.debug(f"failed title was {self.driver.title}")
                    self.send_notification(
                        "Failed Add to Cart", "failed-atc", self.take_screenshots
                    )
                    self.save_page_source("failed-atc")
                    in_stock = self.check_stock(
                        asin=asin,
                        reserve_max=reserve_max,
                        reserve_min=reserve_min,
                        retry=retry + 1,
                    )
        return in_stock