コード例 #1
0
async def main():  ##asyncio is for concurrent programming
    colorama.init()
    print(const.HEADER)  ##esto va al archivo constants.py que tiene ascii art
    setup_logger()

    notification_config, customer = read_config(
    )  ##la funcion regresa dos variables notification_config y customer

    driver = webdriver.create()
    user_agent = driver.execute_script(
        'return navigator.userAgent;'
    )  ##esto regresa el User agent header; por ejemplo: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0

    gpu_data = read_json(data_path / 'gpus.json')
    target_gpu_name, _ = pick(list(gpu_data.keys()),
                              'Which GPU are you targeting?',
                              indicator='=>')

    payment_method, _ = pick(['credit-card', 'paypal'],
                             'Which payment method do you want to use?',
                             indicator='=>')

    auto_submit = None
    if payment_method == 'credit-card':
        auto_submit, _ = pick(['Yes', 'No'],
                              'Do you want to automatically submit the order?',
                              indicator='=>',
                              default_index=1)
        auto_submit = auto_submit == 'Yes'

    timeout, _ = pick(
        [' 4 seconds', ' 8 seconds', '16 seconds', '32 seconds', '64 seconds'],
        'Please choose a timout / refresh interval',
        indicator='=>',
        default_index=1)
    timeout = int(timeout.replace('seconds', '').strip())

    target_gpu = gpu_data[target_gpu_name]

    notifications = notification_config['notifications']
    notification_queue = queue.Queue()
    notifier = notify.Notifier(notification_config, notification_queue,
                               target_gpu)
    notifier.start_worker()

    locale = customer['locale']
    locales = read_json(data_path / 'locales.json')
    api_currency = locales[locale]['apiCurrency']
    dr_locale = locales[locale]['DRlocale']
    promo_locale = locales[locale]['PromoLocale'].replace('_', '-').lower()
    api_client = api.Client(user_agent, promo_locale, dr_locale, api_currency,
                            target_gpu)
    api_up = True

    product_ids = read_json(data_path / 'skus.json')
    target_id = product_ids[promo_locale][target_gpu_name]

    logger.info('|---------------------------|')
    logger.info('| Starting Nvidia Sniper 🎯 |')
    logger.info(f'|  Customer locale: {locale}   |')
    logger.info(f'|    Nvidia locale: {promo_locale}   |')
    logger.info(f'|        DR locale: {dr_locale}   |')
    logger.info(f'|         Currency: {api_currency}     |')
    logger.info('|---------------------------|')

    if notifications['started']['enabled']:
        checkout.get_product_page(driver, promo_locale, target_gpu)
        WebDriverWait(driver, timeout).until(
            EC.visibility_of_element_located(
                (By.CSS_SELECTOR, f'.{const.BANNER_CLASS} .lazyloaded')))
        sleep(1)
        driver.save_screenshot(const.SCREENSHOT_FILE)
        notification_queue.put('started')

    while True:
        in_stock = False
        try:
            logger.info(
                f"Checking {promo_locale} availability for {target_gpu['name']} using API..."
            )
            status = await api_client.check_availability(target_id)
            if not api_up:
                api_up = True
                if notifications['api-up']['enabled']:
                    notification_queue.put('api-up')
            logger.info(f'Inventory status for {target_id}: {status}')
            in_stock = status != 'PRODUCT_INVENTORY_OUT_OF_STOCK'
        except PermissionError:
            logger.error(
                f'Access to inventory API was denied, clearing cookies and trying again...'
            )
            api_client.session.cookie_jar.clear()
            sleep(timeout)
        except LookupError:
            logger.error(
                f'Failed to get inventory status for {target_id}, updating product ID...'
            )
            target_id = None
            while target_id is None:
                target_id = await api_client.get_product_id()
                if target_id is None:
                    logger.warning(
                        f"Product ID for {target_gpu['name']} is not available yet, refreshing product page..."
                    )
                    sleep(timeout)
                else:
                    logger.success(
                        f"Found product ID for {target_gpu['name']}: {target_id}"
                    )
                    product_ids[promo_locale][target_gpu_name] = target_id
                    logger.info('Updating product ID file...')
                    update_sku_file(product_ids)
        except SystemError as ex:
            error_name = type(ex).__name__
            error_message = '\n'.join(map(str, ex.args)).rstrip()
            logger.error(f'Internal API error - {error_name}: {error_message}')
            if api_up:
                api_up = False
                if notifications['api-down']['enabled']:
                    notification_queue.put('api-down')

        if in_stock:
            logger.success(f"Found available GPU: {target_gpu['name']}")
            if notifications['availability']['enabled']:
                notification_queue.put('availability')
            store_token = None
            while store_token is None:
                try:
                    logger.info('Fetching API token...')
                    store_token = await api_client.get_token()
                    logger.success('API Token: ' + store_token)
                    logger.info('Overiding store cookies for driver...')
                    store_cookies = api_client.get_cookies(const.STORE_URL)
                    driver.get(const.CART_URL)
                    for key, value in store_cookies.items():
                        driver.add_cookie({'name': key, 'value': value})
                except SystemError:
                    logger.error('Failed to fetch API token, trying again...')

            addded_to_cart = False
            while not addded_to_cart:
                try:
                    logger.info(f'Calling add to cart API for {target_id}...')
                    add_to_cart_response = await api_client.add_to_cart(
                        store_token, target_id)
                    addded_to_cart = True
                    response = add_to_cart_response['message']
                    logger.success(f'Add to cart response: {response}')
                except Exception as ex:
                    error_name = type(ex).__name__
                    error_message = '\n'.join(map(str, ex.args)).rstrip()
                    logger.error(
                        f'Failed to add item to cart - {error_name}: {error_message}'
                    )

            checkout_reached = False
            while not checkout_reached:
                try:
                    logger.info('Going to checkout page...')
                    driver.get(const.CHECKOUT_URL)
                    checkout_reached = True
                    if notifications['add-to-cart']['enabled']:
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        notification_queue.put('add-to-cart')
                except (TimeoutException, WebDriverException):
                    logger.error(
                        'Failed to load checkout page, trying again...')

            if payment_method == 'credit-card':
                checkout.checkout_guest(driver, timeout, customer, auto_submit)
            else:
                checkout.checkout_paypal(driver, timeout)

            logger.success('Checkout successfully completed!')
            if notifications['checkout']['enabled']:
                driver.save_screenshot(const.SCREENSHOT_FILE)
                notification_queue.put('checkout')

            if auto_submit:
                checkout.click_recaptcha(driver, timeout)
                order_submitted = checkout.submit_order(driver, timeout)
                if order_submitted:
                    logger.success('Auto buy successfully submitted!')
                    if notifications['submit']['enabled']:
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        notification_queue.put('submit')
                else:
                    logger.error(
                        'Failed to auto buy! Please solve the reCAPTCHA and submit manually...'
                    )
                    if notifications['captcha-fail']['enabled']:
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        while not order_submitted:
                            notification_queue.put('captcha-fail')
                            order_submitted = checkout.submit_order(
                                driver, timeout)
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        notification_queue.put('submit')
            break
        else:
            sleep(timeout)

    await api_client.session.close(
    )  ##from asyncio: checkpoint where its safe for asyncio to go to another coroutine
    notification_queue.join()
コード例 #2
0
ファイル: __main__.py プロジェクト: nediaH/nvidia-sniper
async def main():
    colorama.init()
    print(const.HEADER)
    log_format = '%(asctime)s nvidia-sniper: %(message)s'
    fh = logging.FileHandler('sniper.log', encoding='utf-8')
    sh = logging.StreamHandler(sys.stdout)
    logging.basicConfig(level=logging.INFO,
                        format=log_format,
                        handlers=[fh, sh])

    notification_config, customer = read_config()

    driver = webdriver.create()
    user_agent = driver.execute_script('return navigator.userAgent;')

    gpu_data = read_json(data_path / 'gpus.json')
    target_gpu_name, _ = pick(list(gpu_data.keys()),
                              'Which GPU are you targeting?',
                              indicator='=>')

    payment_method, _ = pick(['credit-card', 'paypal'],
                             'Which payment method do you want to use?',
                             indicator='=>')

    auto_submit = None
    if payment_method == 'credit-card':
        auto_submit, _ = pick(['Yes', 'No'],
                              'Do you want to automatically submit the order?',
                              indicator='=>',
                              default_index=1)
        auto_submit = auto_submit == 'Yes'

    timeout, _ = pick(
        [' 4 seconds', ' 8 seconds', '16 seconds', '32 seconds', '64 seconds'],
        'Please choose a timout / refresh interval',
        indicator='=>',
        default_index=1)
    timeout = int(timeout.replace('seconds', '').strip())

    target_gpu = gpu_data[target_gpu_name]

    notifications = notification_config['notifications']
    notification_queue = queue.Queue()
    notifier = notify.Notifier(notification_config, notification_queue,
                               target_gpu)
    notifier.start_worker()

    locale = customer['locale']
    locales = read_json(data_path / 'locales.json')
    api_currency = locales[locale]['apiCurrency']
    dr_locale = locales[locale]['DRlocale']
    promo_locale = locales[locale]['PromoLocale'].replace('_', '-').lower()
    api_client = api.Client(user_agent, promo_locale, dr_locale, api_currency,
                            target_gpu)
    api_up = True

    product_ids = read_json(data_path / 'skus.json')
    target_id = product_ids[promo_locale][target_gpu_name]

    logging.info('|---------------------------|')
    logging.info('| Starting Nvidia Sniper 🎯 |')
    logging.info(f'|  Customer locale: {locale}   |')
    logging.info(f'|    Nvidia locale: {promo_locale}   |')
    logging.info(f'|        DR locale: {dr_locale}   |')
    logging.info(f'|         Currency: {api_currency}     |')
    logging.info('|---------------------------|')

    if notifications['started']['enabled']:
        checkout.get_product_page(driver, promo_locale, target_gpu)
        WebDriverWait(driver, timeout).until(
            EC.visibility_of_element_located(
                (By.CSS_SELECTOR, f'.{const.BANNER_CLASS} .lazyloaded')))
        sleep(1)
        driver.save_screenshot(const.SCREENSHOT_FILE)
        notification_queue.put('started')

    while True:
        in_stock = False
        try:
            logging.info(
                f"Checking {promo_locale} availability for {target_gpu['name']} using API..."
            )
            status = await api_client.check_availability(target_id)
            if not api_up:
                api_up = True
                if notifications['api-up']['enabled']:
                    notification_queue.put('api-up')
            logging.info(f'Inventory status for {target_id}: {status}')
            in_stock = status != 'PRODUCT_INVENTORY_OUT_OF_STOCK'
        except PermissionError:
            logging.error(
                f'Access to inventory API was denied, clearing cookies and trying again...'
            )
            api_client.session.cookie_jar.clear()
            sleep(timeout)
        except LookupError:
            logging.error(
                f'Failed to get inventory status for {target_id}, updating product ID...'
            )
            target_id = None
            while target_id is None:
                target_id = await api_client.get_product_id()
                if target_id is None:
                    logging.error(
                        f"Failed to locate product ID for {target_gpu['name']}, trying again..."
                    )
                    sleep(timeout)
                else:
                    logging.info(
                        f"Found product ID for {target_gpu['name']}: {target_id}"
                    )
                    product_ids[promo_locale][target_gpu_name] = target_id
                    logging.info('Updating product ID file...')
                    update_sku_file(product_ids)
        except SystemError as ex:
            logging.error(f'Internal API error, {type(ex).__name__}: ' +
                          ','.join(ex.args))
            if api_up:
                api_up = False
                if notifications['api-down']['enabled']:
                    notification_queue.put('api-down')

        if in_stock:
            logging.info(f"Found available GPU: {target_gpu['name']}")
            if notifications['availability']['enabled']:
                notification_queue.put('availability')
            store_token = None
            while store_token is None:
                try:
                    logging.info('Fetching API token...')
                    store_token = await api_client.get_token()
                    logging.info('API Token: ' + store_token)
                    logging.info('Overiding store cookies for driver...')
                    store_cookies = api_client.get_cookies(const.STORE_URL)
                    driver.get(const.STORE_URL)
                    for key, value in store_cookies.items():
                        driver.add_cookie({'name': key, 'value': value})
                except SystemError:
                    logging.error('Failed to fetch API token, trying again...')

            addded_to_cart = False
            while not addded_to_cart:
                try:
                    logging.info('Calling add to cart API...')
                    add_to_cart_response = await api_client.add_to_cart(
                        store_token, target_id)
                    addded_to_cart = True
                    response = add_to_cart_response['message']
                    logging.info(f'Add to cart response: {response}')
                except Exception as ex:
                    logging.error(
                        f'Failed to add item to cart, {type(ex).__name__}: ' +
                        ','.join(ex.args))

            checkout_reached = False
            while not checkout_reached:
                try:
                    logging.info('Going to checkout page...')
                    driver.get(const.CHECKOUT_URL)
                    checkout_reached = True
                    if notifications['add-to-cart']['enabled']:
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        notification_queue.put('add-to-cart')
                except (TimeoutException, WebDriverException):
                    logging.error(
                        'Failed to load checkout page, trying again...')

            if payment_method == 'credit-card':
                checkout.checkout_guest(driver, timeout, customer, auto_submit)
            else:
                checkout.checkout_paypal(driver, timeout),

            logging.info('Checkout successful!')
            if notifications['checkout']['enabled']:
                driver.save_screenshot(const.SCREENSHOT_FILE)
                notification_queue.put('checkout')

            if auto_submit:
                checkout.click_recaptcha(driver, timeout)
                order_submitted = checkout.submit_order(driver, timeout)
                if order_submitted:
                    logging.info('Auto buy successfully submitted!')
                    if notifications['submit']['enabled']:
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        notification_queue.put('submit')
                else:
                    logging.error(
                        'Failed to auto buy! Please solve the reCAPTCHA and submit manually...'
                    )
                    if notifications['captcha-fail']['enabled']:
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        while not order_submitted:
                            notification_queue.put('captcha-fail')
                            order_submitted = checkout.submit_order(
                                driver, timeout)
                        driver.save_screenshot(const.SCREENSHOT_FILE)
                        notification_queue.put('submit')
            break
        else:
            sleep(timeout)

    await api_client.session.close()
    notification_queue.join()