-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinventory_checker.py
133 lines (122 loc) · 4.83 KB
/
inventory_checker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/python3
import bs4
import time
import os
import requests
import smtplib
import sys
# Settings
DELAY = 300 # 5 minutes
EMAIL_SERVER_PORT = 465
EMAIL_SERVER_SSL = 'smtp.gmail.com'
# Objects
class Store():
AVAIL = {
"In Stock",
"Limited Stock",
"Out of Stock"
}
def __init__(self, row):
self.store = {
"Name": row.select_one(".address-location-name").text.strip(),
"Street": row.select_one("address").contents[0].strip(),
"City": " ".join(row.select_one("address").contents[2].strip().split(" ")[:-2]),
"State": row.select_one("address").contents[2].strip().split(" ")[-2],
"Zip": row.select_one("address").contents[2].strip().split(" ")[-1],
"Distance": row.select_one(".address__below").text.strip(),
}
self.address = f"{self.store['Street']}\n\
{self.store['City']}, {self.store['State']} {self.store['Zip']}"
self.availability = row.select_one(".availability-status-indicator__text").text.strip()
self.price = float(row.select_one(".price-formatted").text.strip().replace("$",""))
def __repr__(self):
return f"\n{self.store['Name']}\n \
{self.address}\n \
{self.availability}\n \
{self.price}"
class Inventory():
def __init__(self, SKU, ZIP):
URL = f"https://brickseek.com/walmart-inventory-checker/?sku={SKU}&zip={ZIP}"
data = {
'store_type': '3',
'sku': SKU,
'zip': ZIP,
'sort': 'quan'
}
res = requests.post(URL, data=data)
page = bs4.BeautifulSoup(res.text, features="html.parser")
rows = page.select(".inventory-checker-table--store-availability-price .table__body .table__row")
self.name = page.select_one(".section-title").text.strip()
self.msrp = float(page.select_one(".item-overview__meta-item .price-formatted").text.replace("$",""))
self.stores = []
for row in rows:
self.stores.append(Store(row))
def __repr__(self):
return self.stores
def lowest_price(self):
min_price = min([x.price for x in self.stores if x.availability != "Out of Stock"])
return [x for x in self.stores if x.price == min_price]
def beat_price(self, price):
return [x for x in self.stores if x.price <= price and x.availability != "Out of Stock"]
def beat_discount(self, discount):
return [x for x in self.stores if x.price <= self.msrp*(1-discount/100) and x.availability != "Out of Stock"]
# Functions
def mail(subject, body):
sender = "[email protected]"
recipient = os.environ['EMAIL_DEST']
subject = f"{subject}"
body = f"{body}"
email_content = f"\
From: {sender}\n\
To: {recipient}\n\
Subject: {subject}\n\n\
{body}"
try:
with smtplib.SMTP_SSL(EMAIL_SERVER_SSL, EMAIL_SERVER_PORT) as server:
server.ehlo()
server.login(os.environ['EMAIL_USER'], os.environ['EMAIL_PASS'])
server.sendmail(sender, recipient, email_content)
print('Email sent!')
except SMTPAuthenticationError as e:
print(f"Bad password! -- {e}")
except:
print('Something went wrong...')
def main():
SKU = sys.argv[1]
ZIP = sys.argv[2]
if len(sys.argv) > 3:
OPTION = sys.argv[3]
else:
OPTION = ""
while True:
inventory = Inventory(SKU, ZIP)
if not OPTION:
print(inventory)
exit(0)
if "price" in OPTION:
price = int(OPTION.split(":")[1])
stores = inventory.beat_price(price)
if len(stores) > 0:
print(f"The following stores beat the price of ${stores[0].price}.")
print(inventory.stores)
subject = f"Sale on {inventory.name}, ${stores[0].price}"
body = f"The following stores beat the price of ${price} on {inventory.name}:\n\n{stores}"
mail(subject, body)
exit(0)
else:
print(f"No stores in area beat the price of ${price}, will check again.")
if "discount" in OPTION:
discount = int(OPTION.split(":")[1])
stores = inventory.beat_discount(discount)
if len(stores) > 0:
print(f"The following stores beat the discount of {stores[0].price}%.")
print(inventory.stores)
subject = f"Sale on {inventory.name}, ${stores[0].price}"
body = f"The following stores beat the discount of {discount}% on {inventory.name}:\n\n{stores}"
mail(subject, body)
exit(0)
else:
print(f"No stores in area beat the discount of {discount}%, will check again.")
time.sleep(DELAY)
if __name__ == "__main__":
main()