Last active
November 24, 2021 02:50
-
-
Save badboybeyer/d80214619dd8ad7af3cd1c1343f4cd4a to your computer and use it in GitHub Desktop.
A script for checking availability of the RTX 3080FE on nvidia.com on 2020-10-08; uses selenium and firefox; sends a text message via twilio if stock found; edited to ignore the best buy stock option
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
MIT License | |
Copyright (c) 2020 Erich Beyer | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
SOFTWARE. | |
Requirements: | |
Python version 3.6 or greater | |
python library selenium | |
python library twilio | |
twilio account, auth_token, and phone number | |
geckodriver and firefox compatible with selenium (https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html) | |
How to: | |
1. fill out defines below | |
2. install requirements | |
3. execute script: python 3080FE_check_nvidia_stock_2020-10-08.py | |
""" | |
import selenium | |
from selenium import webdriver | |
import sys | |
from time import time | |
# FILL OUT THIS SECTION | |
TWILIO_ACCOUNT_SID = '' | |
TWILIO_AUTH_TOKEN = '' | |
# phone number to send sms to | |
PHONE_NUM = '' | |
# from number in your twilio account | |
TWILIO_NUM = '' | |
# Specify your firefox binary only if the one provided by your | |
# system's package manager does not support your geckodriver | |
PATH_TO_FIREFOX = '' | |
# Make sure the locale is correct for you! | |
NVIDIA_STORE_URI = 'https://www.nvidia.com/en-us/shop/geforce/gpu/?page=1&limit=9&locale=en-us&category=GPU&gpu=RTX%203080' | |
# Only change these if you know what you are doing! | |
TIMEOUT = 10 | |
CHECK_AVAILABLE_XPATH = "//img[@title='Nvidia RTX 3080']/../../..//span[contains(., 'Check Availability')]" | |
POPUP_XPATH = "//div[@class='popContent']" | |
STOCK_XPATH = "//img[@alt='Nvidia.com']/../..//div[@class='popCell cellBtn']" | |
# constants | |
UNKNOWN = 'unknown' | |
FOUND_STOCK_RET_CODE = 0 | |
OOS_RET_CODE = 1 | |
FAILED_STOCK_RET_CODE = 2 | |
FAILED_CHECK_AVAIL_RET_CODE = 3 | |
def main(): | |
ret = OOS_RET_CODE | |
while ret == OOS_RET_CODE: | |
(ret, text) = check_3080_stock() | |
print(text) | |
alert_if_stock_or_error(ret, text) | |
sys.exit(int(ret)) | |
return | |
def alert_if_stock_or_error(ret, text): | |
if ret != OOS_RET_CODE: | |
from twilio.rest import Client | |
client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) | |
if ret == FOUND_STOCK_RET_CODE: | |
msg = f'3080 stock available at nvidia.com "{text}"' | |
elif ret == FAILED_CHECK_AVAIL_RET_CODE: | |
msg = "failed to check available stock of 3080 at nvidia.com" | |
elif ret == FAILED_STOCK_RET_CODE: | |
msg = "failed to find stock for 3080 at nvidia.com" | |
else: | |
msg = f'3080 stock unknown at nvidia.com "{text}" "{ret}"' | |
client.messages.create(to=PHONE_NUM, from_=TWILIO_NUM, | |
body='3080 stock available at nvidia.com') | |
return | |
def check_3080_stock(): | |
ret = FOUND_STOCK_RET_CODE | |
stock_text = UNKNOWN | |
if len(PATH_TO_FIREFOX): | |
driver = webdriver.Firefox(firefox_binary=PATH_TO_FIREFOX) | |
else: | |
driver = webdriver.Firefox() | |
driver.implicitly_wait(3) | |
driver.get(NVIDIA_STORE_URI) | |
try: | |
check_btn = driver.find_element_by_xpath(CHECK_AVAILABLE_XPATH) | |
except selenium.common.exceptions.NoSuchElementException: | |
stock_text = 'FAILED to find check availability button' | |
ret = FAILED_CHECK_AVAIL_RET_CODE | |
driver.close() | |
return (ret, stock_text) | |
check_btn.text | |
check_btn.click() | |
begin = time() | |
while stock_text == UNKNOWN: | |
try: | |
popup_div = driver.find_element_by_xpath(POPUP_XPATH) | |
stock_elem = popup_div.find_element_by_xpath(STOCK_XPATH) | |
stock_text = stock_elem.text | |
except selenium.common.exceptions.NoSuchElementException: | |
check_btn.text | |
check_btn.click() | |
if time() - begin > TIMEOUT: | |
stock_text = 'FAILED to find stock level' | |
ret = FAILED_STOCK_RET_CODE | |
driver.close() | |
return (ret, stock_text) | |
driver.close() | |
if stock_text == 'OUT OF STOCK': | |
ret = OOS_RET_CODE | |
return (ret, stock_text) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment