Skip to content

Instantly share code, notes, and snippets.

@sleepntsheep
Last active October 27, 2024 12:58
Show Gist options
  • Save sleepntsheep/c5966a21bff8568459472fdc2541e196 to your computer and use it in GitHub Desktop.
Save sleepntsheep/c5966a21bff8568459472fdc2541e196 to your computer and use it in GitHub Desktop.
Architect Search + Cost Management Software
import tkinter as tk
from tkinter import messagebox, ttk, simpledialog, filedialog
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import webbrowser
import json
def scrape_homepro(query):
chrome_options = Options()
#chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
service = Service('chromedriver')
driver = webdriver.Chrome(service=service, options=chrome_options)
url = f"https://www.homepro.co.th/search?searchtype=&q={query}"
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'product-plp-card')))
materials = []
items = driver.find_elements(By.CLASS_NAME, 'product-plp-card ')
for item in items:
name = item.find_element(By.CLASS_NAME, 'item-title').text.strip()
price_text = item.find_element(By.CLASS_NAME, 'item-price').text.strip().replace('฿', '').split(' ')[0].replace(',', '')
price = float(price_text) if price_text else 0
url = item.get_attribute('data-value')
url = f"https://www.homepro.co.th/p/{url}"
materials.append((name, price, "HomePro", url))
driver.quit()
return materials
def scrape_thaiwatsadu(query):
chrome_options = Options()
#chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
service = Service('chromedriver')
driver = webdriver.Chrome(service=service, options=chrome_options)
url = f"https://www.thaiwatsadu.com/search/{query}"
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'font-price')))
time.sleep(10)
materials = []
items = driver.find_elements(By.CLASS_NAME, 'MuiGrid-root')
for item in items:
try:
name = item.find_element(By.CLASS_NAME, 'text-base').text.strip()
price_element = WebDriverWait(item, 10).until(
EC.visibility_of_element_located((By.CLASS_NAME, 'font-price'))
)
price_text = price_element.text.strip().replace('฿', '').replace(',', '')
price = float(price_text) if price_text else 0
url = item.find_element(By.CSS_SELECTOR, 'a.select-none').get_attribute('href')
materials.append((name, price, "ThaiWatsadu", url))
except Exception:
continue
driver.quit()
return materials
class ShoppingCartApp:
def __init__(self, root):
self.root = root
self.root.title("Shopping Cart")
self.items = []
self.cart = []
self.search_label = tk.Label(root, text="Search Query:")
self.search_label.pack()
self.search_entry = tk.Entry(root)
self.search_entry.pack()
self.search_button = tk.Button(root, text="Search", command=self.search_items)
self.search_button.pack()
self.clear_button = tk.Button(root, text="Clear Search Table", command=self.clear_search_table)
self.clear_button.pack()
self.item_tree = ttk.Treeview(root, columns=("Name", "Price", "Source"), show="headings")
self.item_tree.heading("Name", text="Name")
self.item_tree.heading("Price", text="Price (฿)")
self.item_tree.heading("Source", text="Source")
self.item_tree.pack()
self.add_to_cart_button = tk.Button(root, text="Add to Cart", command=self.add_to_cart)
self.add_to_cart_button.pack()
self.cart_label = tk.Label(root, text="Cart:")
self.cart_label.pack()
self.cart_tree = ttk.Treeview(root, columns=("Name", "Price", "Quantity", "Source", "Link"), show="headings")
self.cart_tree.heading("Name", text="Name")
self.cart_tree.heading("Price", text="Price (฿)")
self.cart_tree.heading("Quantity", text="Quantity")
self.cart_tree.heading("Source", text="Source")
self.cart_tree.heading("Link", text="Link")
self.cart_tree.pack()
self.cart_buttons_frame = tk.Frame(root)
self.cart_buttons_frame.pack()
self.edit_quantity_button = tk.Button(self.cart_buttons_frame, text="Edit Quantity", command=self.edit_quantity)
self.edit_quantity_button.pack(side=tk.LEFT)
self.delete_item_button = tk.Button(self.cart_buttons_frame, text="Delete Item", command=self.delete_item)
self.delete_item_button.pack(side=tk.LEFT)
self.export_button = tk.Button(self.cart_buttons_frame, text="Export Cart", command=self.export_cart)
self.export_button.pack(side=tk.LEFT)
self.import_button = tk.Button(self.cart_buttons_frame, text="Import Cart", command=self.import_cart)
self.import_button.pack(side=tk.LEFT)
self.total_label = tk.Label(root, text="Total Price: ฿0.00")
self.total_label.pack()
self.cart_tree.bind("<Double-1>", self.open_cart_link)
def search_items(self):
query = self.search_entry.get()
self.items = scrape_homepro(query) + scrape_thaiwatsadu(query)
self.items = [x for x in self.items if x[1] != 0]
for row in self.item_tree.get_children():
self.item_tree.delete(row)
for name, price, source, url in sorted(self.items, key=lambda x: x[1]):
self.item_tree.insert("", "end", values=(name, f"{price:.2f}", source))
self.item_tree.bind("<Double-1>", self.open_link)
def add_to_cart(self):
selected_items = self.item_tree.selection()
for item_id in selected_items:
item_values = self.item_tree.item(item_id, "values")
name, price_text, source = item_values
price = float(price_text)
quantity = simpledialog.askinteger("Quantity", f"Enter quantity for {name}:", minvalue=1)
if quantity is not None:
url = next((url for n, p, s, url in self.items if n == name), None)
self.cart.append({"name": name, "price": price, "quantity": quantity, "source": source, "url": url})
self.cart_tree.insert("", "end", values=(name, price_text, quantity, source, url))
self.update_total()
def open_link(self, event):
selected_item = self.item_tree.selection()[0]
item_values = self.item_tree.item(selected_item, "values")
if item_values:
for name, price, source, url in self.items:
if name == item_values[0]:
webbrowser.open(url)
break
def clear_search_table(self):
for row in self.item_tree.get_children():
self.item_tree.delete(row)
def edit_quantity(self):
selected_items = self.cart_tree.selection()
if not selected_items:
messagebox.showwarning("Warning", "Please select an item to edit.")
return
for item_id in selected_items:
item_values = self.cart_tree.item(item_id, "values")
name, price_text, quantity_text, source, link = item_values
quantity = simpledialog.askinteger("Quantity", f"Edit quantity for {name}:", minvalue=1)
if quantity is not None:
for item in self.cart:
if item["name"] == name:
item["quantity"] = quantity
break
self.update_cart_display()
self.update_total()
def delete_item(self):
selected_items = self.cart_tree.selection()
for item_id in selected_items:
item_values = self.cart_tree.item(item_id, "values")
name = item_values[0]
self.cart = [item for item in self.cart if item["name"] != name]
self.cart_tree.delete(item_id)
self.update_total()
def update_cart_display(self):
for row in self.cart_tree.get_children():
self.cart_tree.delete(row)
for item in self.cart:
self.cart_tree.insert("", "end", values=(item["name"], f"{item['price']:.2f}", item["quantity"], item["source"], item["url"]))
def open_cart_link(self, event):
selected_item = self.cart_tree.selection()
if selected_item:
item_values = self.cart_tree.item(selected_item, "values")
if item_values:
url = item_values[4]
webbrowser.open(url)
def update_total(self):
total_price = sum(item["price"] * item["quantity"] for item in self.cart)
self.total_label.config(text=f"Total Price: ฿{total_price:.2f}")
def export_cart(self):
file_path = filedialog.asksaveasfilename(defaultextension=".json", filetypes=[("JSON files", "*.json")])
if not file_path:
return
with open(file_path, 'w') as file:
json.dump(self.cart, file)
messagebox.showinfo("Export Cart", "Cart exported successfully!")
def import_cart(self):
file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
if not file_path:
return
with open(file_path, 'r') as file:
self.cart = json.load(file)
self.update_cart_display()
self.update_total()
messagebox.showinfo("Import Cart", "Cart imported successfully!")
if __name__ == "__main__":
root = tk.Tk()
app = ShoppingCartApp(root)
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment