import os import re import requests import urllib.parse from bs4 import BeautifulSoup from flask import flash, redirect, render_template, request, session from functools import wraps # Display apology message in case of an error def apology(message, code=400): def escape(s): """ Escape special characters. https://github.com/jacebrowning/memegen#special-characters """ for old, new in [("-", "--"), (" ", "-"), ("_", "__"), ("?", "~q"), ("%", "~p"), ("#", "~h"), ("/", "~s"), ("\"", "''")]: s = s.replace(old, new) return s flash("Apologies, something went wrong...") return render_template("apology.html", top=code, bottom=escape(message)), code def deal_finder(item): """ Scraping best deals on ebay for the user-specified item """ # https://www.networkinghowtos.com/howto/common-user-agent-list/ header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'} # https://stackoverflow.com/questions/1549641/how-can-i-capitalize-the-first-letter-of-each-word-in-a-string item_spelling = " ".join(word[0].upper() + word[1:] for word in item.split()) # Setup for displaying ebay results with the filter option "Price + Shipping: lowest first" search_term = item.replace(" ", "+") url = f"https://www.ebay.com/sch/i.html?_from=R40&_trksid=p2380057.m570.l1313&_nkw={search_term}&_sacat=0&_sop=15" webpage = requests.get(url, headers=header).text soup = BeautifulSoup(webpage, "lxml") offers = {} # getting a list of all divs that contain the info on each individual offer all_offers = soup.find_all("div", class_="s-item__info clearfix") for item in all_offers: # checking for matches in all caps too if item.find(text=re.compile(item_spelling)) != None and item.find(text=re.compile(item_spelling.upper())) == None: name = item.find(text=re.compile(item_spelling)) elif item.find(text=re.compile(item_spelling)) == None and item.find(text=re.compile(item_spelling.upper())) != None: name = item.find(text=re.compile(item_spelling.upper())) else: continue # getting the price of each item if item.find("span", class_="s-item__price").string == None: continue price = item.find("span", class_="s-item__price").string.replace("$", "") # getting the link to the page of each item if item.a["href"] == None: continue link = item.a["href"] # the following code for "offers" & "best_deals" is based on: https://www.youtube.com/watch?v=zAEfWiC_KBU&t=1232s offers[name] = {"price": float(price.replace(",", "")), "link": link} best_deals = sorted(offers.items(), key=lambda x: x[1]["price"]) return(best_deals) def login_required(f): """ Decorate routes to require login. https://flask.palletsprojects.com/en/1.1.x/patterns/viewdecorators/ """ @wraps(f) def decorated_function(*args, **kwargs): if session.get("user_id") is None: return redirect("/login") return f(*args, **kwargs) return decorated_function def passw_requirements(password): """ Password requirements for registrating an account """ pw_length = len(password) if pw_length in range(6,25) and password.isalpha() == False and password.isnumeric() == False: return "valid" else: return "invalid" # Display a float as US-Dollar def usd(value): return f"${value:,.2f}"