Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #-----Imported Functions---------------------------------------------#
- #
- # Below are various import statements for helpful functions. You
- # should be able to complete this assignment using these
- # functions only. Note that not all of these functions are
- # needed to successfully complete this assignment.
- #
- # The function for opening a web document given its URL.
- # (You WILL need to use this function in your solution,
- # either directly or via our "download" function.)
- from urllib.request import urlopen
- # Import the standard Tkinter functions. (You WILL need to use
- # these functions in your solution.)
- from tkinter import *
- # Functions for finding all occurrences of a pattern
- # defined via a regular expression, as well as
- # the "multiline" and "dotall" flags. (You do NOT need to
- # use these functions in your solution, because the problem
- # can be solved with the string "find" function, but it will
- # be difficult to produce a concise and robust solution
- # without using regular expressions.)
- from re import findall, finditer, MULTILINE, DOTALL
- # Import the standard SQLite functions (just in case they're
- # needed).
- from sqlite3 import *
- #
- #--------------------------------------------------------------------#
- #-----Downloader Function--------------------------------------------#
- #
- # This is our function for downloading a web page's content and both
- # saving it on a local file and returning its source code
- # as a Unicode string. The function tries to produce
- # a meaningful error message if the attempt fails. WARNING: This
- # function will silently overwrite the target file if it
- # already exists! NB: You should change the filename extension to
- # "xhtml" when downloading an XML document. (You do NOT need to use
- # this function in your solution if you choose to call "urlopen"
- # directly, but it is provided for your convenience.)
- #
- def download(url = 'http://www.wikipedia.org/',
- target_filename = 'download',
- filename_extension = 'html'):
- # Import an exception raised when a web server denies access
- # to a document
- from urllib.error import HTTPError
- # Open the web document for reading
- try:
- web_page = urlopen(url)
- except ValueError:
- raise Exception("Download error - Cannot find document at URL '" + url + "'")
- except HTTPError:
- raise Exception("Download error - Access denied to document at URL '" + url + "'")
- except:
- raise Exception("Download error - Something went wrong when trying to download " + \
- "the document at URL '" + url + "'")
- # Read its contents as a Unicode string
- try:
- web_page_contents = web_page.read().decode('UTF-8')
- except UnicodeDecodeError:
- raise Exception("Download error - Unable to decode document at URL '" + \
- url + "' as Unicode text")
- # Write the contents to a local text file as Unicode
- # characters (overwriting the file if it
- # already exists!)
- try:
- text_file = open(target_filename + '.' + filename_extension,
- 'w', encoding = 'UTF-8')
- text_file.write(web_page_contents)
- text_file.close()
- except:
- raise Exception("Download error - Unable to write to file '" + \
- target_file + "'")
- # Return the downloaded document to the caller
- return web_page_contents
- #
- #--------------------------------------------------------------------#
- #-----Student's Solution---------------------------------------------#
- #
- # Put your solution at the end of this file.
- #
- #download('https://www.amazon.com.au/gp/rss/bestsellers/books', 'amazon_books', 'html')
- #download('http://www.beaversportswear.com/rss.php?type=rss', 'beaver_sportswear', 'html')
- # Backend Web Functions
- def currency_convert(url, expression): # In the event a currency conversion is needed for a US webpage
- source = urlopen(url) # Retrieves website that maintains updated currency conversions, specific to US to AUD
- source = source.read().decode('UTF-8')
- conversion_rate = re.findall(expression, source)
- conversion_rate = float(conversion_rate[0])
- return conversion_rate
- def extract_from_page(address, webpage_name, method, expression_list):
- global sites
- if method == 'live': # Determines whether to open from downloaded source or to pull from a live webpage
- source = urlopen(address).read().decode('UTF-8')
- else:
- source = open(address).read()
- source_items = re.findall(expression_list[0], source)
- if webpage_name in source_items:
- source_items.remove(webpage_name) # Item names are marked up with <title> in the source but so is the title of the webpage -
- # this removes it from the list
- source_prices = re.findall(expression_list[1], source)
- for price in range(len(source_prices)): # Fixes a bug where certain items' prices were marked up with <span class...>
- if 'class' in source_prices[price]:
- source_prices[price] = re.findall('>(.+?)<', source_prices[price])[0]
- source_images = re.findall(expression_list[2], source)
- source_combined = []
- if len(source_items) == len(source_prices) == len(source_images): # Ensures all lists have the same amount of items
- for product in range(len(source_items)):
- source_combined.append([source_items[product], source_prices[product], source_images[product]])
- sites.append(webpage_name)
- else:
- print('The expressions of "' + webpage_name + '" have matched an unequeal amount of items in each list.')
- return source_combined
- # Page Backend Retrieval
- sites = [] # Put this down here so the sites list doesn't reset everytime I call 'extract_from_page(...)'
- conversion_rate = currency_convert('https://www.xe.com/currencyconverter/convert/?Amount=1&From=USD&To=AUD', 'data-amount="(\d\..+?)"')
- photo_equipment = extract_from_page('http://www.photoequipmentstore.com.au/rss.php?type=rss', 'Photo Equipment Store Australia: New Products', 'live',
- ['<title><\!\[CDATA\[(.+?)\]', '<isc:price><\!\[CDATA\[(.+?)\]', '<isc:image><\!\[CDATA\[(.+[jpg|png])'])
- kitchen_shelf = extract_from_page('http://www.thekitchenshelf.com.au/rss.php?type=rss', 'The Kitchen Shelf: New Products', 'live',
- ['<title><\!\[CDATA\[(.+?)\]', '<isc:price><\!\[CDATA\[(.+?)\]', '<isc:image><\!\[CDATA\[(.+jpg|png)'])
- amazon_books = extract_from_page('static_pages/amazon_books.html', 'Amazon.com.au: Bestsellers in Books', 'static',
- ['<title>#\d+:\s(.+?)<', '"price">(.+?)<', 'src="(https://images-fe.+?)"'])
- beaver_sportswear = extract_from_page('static_pages/beaver_sportswear.html', 'Beaver Sportswear (The Beaver Dam): New Products', 'static',
- ['<title><\!\[CDATA\[(.+?)\]', '<isc:price><\!\[CDATA\[(.+?)\]', '<isc:image><\!\[CDATA\[(.+jpg|png)'])
- # UI Backend Functions
- def radio_1():
- global active_site
- active_site = 1
- items_box.delete(0, END)
- for item in photo_equipment:
- items_box.insert(END, item[0] + ' | AU' + item[1])
- def radio_2():
- global active_site
- active_site = 2
- items_box.delete(0, END)
- for item in kitchen_shelf:
- items_box.insert(END, item[0] + ' | AU' + item[1])
- def radio_3():
- global active_site
- active_site = 3
- items_box.delete(0, END)
- for item in amazon_books:
- items_box.insert(END, item[0] + ' | AU' + item[1])
- def radio_4():
- global active_site
- active_site = 4
- items_box.delete(0, END)
- for item in beaver_sportswear:
- items_box.insert(END, item[0] + ' | AU' + item[1])
- def add_to_cart():
- if items_box.curselection() != ():
- if active_site == 1:
- cart.append(photo_equipment[items_box.curselection()[0]])
- elif active_site == 2:
- cart.append(kitchen_shelf[items_box.curselection()[0]])
- elif active_site == 3:
- cart.append(amazon_books[items_box.curselection()[0]])
- else:
- cart.append(beaver_sportswear[items_box.curselection()[0]])
- def clear_cart():
- global cart
- cart = []
- def print_to_database(cart, database_file):
- global cart_quantity
- global cart_total
- db_connection = connect(database = database_file)
- cart_db = db_connection.cursor()
- cart_db.execute("DELETE FROM ShoppingCart") # Clears Database
- for item in cart:
- try:
- # Had an issue with inserting a particular item that had an apostrophe in the name so I just remove any
- # occurences of apostrophes from item name strings to prevent SQL errors
- cart_db.execute("INSERT INTO ShoppingCart VALUES('" + item[0].replace("'", "") + "', '" + item[1][1:].replace(",", "") + "')")
- except:
- print('Error inserting data into table.')
- # Wrote some queries to replace the for loop method of calculating certain information from the cart list
- cart_db.execute("SELECT COUNT(Item) FROM ShoppingCart")
- cart_quantity = str(cart_db.fetchall()[0][0])
- cart_db.execute("SELECT SUM(Price) FROM ShoppingCart")
- cart_total = str(cart_db.fetchall()[0][0])
- db_connection.commit()
- db_connection.close()
- # Name of the invoice file. To simplify marking, your program should
- # generate its invoice using this file name.
- invoice_file = 'invoice.html'
- database_file = 'shopping_cart.db'
- logo_image = 'logo.gif'
- cart = []
- def print_invoice():
- print_to_database(cart, database_file)
- invoice = open(invoice_file, 'w')
- invoice.write('''<!DOCTYPE html>
- <html>
- <head>
- <title>Keeto's Store</title>
- </head>
- <body> \n''')
- invoice.write(' <h1>Keeto\'s Store Invoice!</h1> \n')
- invoice.write(' <img src="' + logo_image + '"> \n')
- if len(cart) > 0:
- invoice.write(' <h2>Your cart consists of ' + cart_quantity + ' item')
- if len(cart) > 1: # Ensures proper pluralisation
- invoice.write('s')
- invoice.write('. \n')
- invoice.write(' <h2>Your total cost is: <u>AU$' + cart_total + '</u></h2> \n')
- invoice.write(' <br> \n')
- for item in cart:
- invoice.write(' <h3>' + item[0] + '</h3> \n')
- invoice.write(' <img src="' + item[2] + '" alt="' + item[0] + '" width = 200 height = 200> \n')
- invoice.write(' <p>Item Price: AU' + item[1] + '</p> \n')
- else:
- invoice.write(' <h2>Your cart is empty.</h2> \n')
- invoice.write(' <br> \n')
- invoice.write(' </body> \n')
- invoice.write(' <footer> \n')
- invoice.write(' <p>Items retrieved from:</p> \n')
- invoice.write(' <ul> \n')
- for site in sites:
- invoice.write(' <li>' + site + '</li> \n')
- invoice.write(' </ul> \n')
- invoice.write(' </footer> \n')
- invoice.write('</html>')
- invoice.close()
- # User Interface
- root_window = Tk()
- root_window.title('Keeto\'s Store')
- # Widgets
- window_title = Label(root_window, text = 'Keeto\'s Online Shop').pack()
- logo = PhotoImage(file = logo_image)
- image_label = Label(root_window, image = logo).pack()
- live_label = Label(root_window, text="Live Sites").pack(anchor = W)
- v = IntVar() # Necessary for radio buttons
- site1_button = Radiobutton(root_window, text = sites[0], variable = v, value = 1, command = radio_1).pack(anchor = W)
- site2_button = Radiobutton(root_window, text = sites[1], variable = v, value = 2, command = radio_2).pack(anchor = W)
- static_label = Label(root_window, text = "Archived Sites").pack(anchor = W)
- site3_button = Radiobutton(root_window, text = sites[2], variable = v, value = 3, command=radio_3).pack(anchor = W)
- site4_button = Radiobutton(root_window, text = sites[3], variable = v, value = 4, command=radio_4).pack(anchor = W)
- items_label = Label(root_window, text = "Items").pack(anchor = W)
- items_box = Listbox(root_window, width = 100)
- items_box.pack(anchor = W)
- cart_button = Button(root_window, text = "Add to Cart", command = add_to_cart).pack()
- invoice_button = Button(root_window, text = "Print Invoice", command = print_invoice).pack()
- clear_button = Button(root_window, text = "Clear Cart", command = clear_cart).pack()
- root_window.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement