Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2018
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.17 KB | None | 0 0
  1. #-----Imported Functions---------------------------------------------#
  2. #
  3. # Below are various import statements for helpful functions.  You
  4. # should be able to complete this assignment using these
  5. # functions only.  Note that not all of these functions are
  6. # needed to successfully complete this assignment.
  7. #
  8.  
  9. # The function for opening a web document given its URL.
  10. # (You WILL need to use this function in your solution,
  11. # either directly or via our "download" function.)
  12. from urllib.request import urlopen
  13.  
  14. # Import the standard Tkinter functions. (You WILL need to use
  15. # these functions in your solution.)
  16. from tkinter import *
  17.  
  18. # Functions for finding all occurrences of a pattern
  19. # defined via a regular expression, as well as
  20. # the "multiline" and "dotall" flags.  (You do NOT need to
  21. # use these functions in your solution, because the problem
  22. # can be solved with the string "find" function, but it will
  23. # be difficult to produce a concise and robust solution
  24. # without using regular expressions.)
  25. from re import findall, finditer, MULTILINE, DOTALL
  26.  
  27. # Import the standard SQLite functions (just in case they're
  28. # needed).
  29. from sqlite3 import *
  30.  
  31. #
  32. #--------------------------------------------------------------------#
  33.  
  34.  
  35.  
  36. #-----Downloader Function--------------------------------------------#
  37. #
  38. # This is our function for downloading a web page's content and both
  39. # saving it on a local file and returning its source code
  40. # as a Unicode string. The function tries to produce
  41. # a meaningful error message if the attempt fails.  WARNING: This
  42. # function will silently overwrite the target file if it
  43. # already exists!  NB: You should change the filename extension to
  44. # "xhtml" when downloading an XML document.  (You do NOT need to use
  45. # this function in your solution if you choose to call "urlopen"
  46. # directly, but it is provided for your convenience.)
  47. #
  48. def download(url = 'http://www.wikipedia.org/',
  49.              target_filename = 'download',
  50.              filename_extension = 'html'):
  51.  
  52.     # Import an exception raised when a web server denies access
  53.     # to a document
  54.     from urllib.error import HTTPError
  55.  
  56.     # Open the web document for reading
  57.     try:
  58.         web_page = urlopen(url)
  59.     except ValueError:
  60.         raise Exception("Download error - Cannot find document at URL '" + url + "'")
  61.     except HTTPError:
  62.         raise Exception("Download error - Access denied to document at URL '" + url + "'")
  63.     except:
  64.         raise Exception("Download error - Something went wrong when trying to download " + \
  65.                         "the document at URL '" + url + "'")
  66.  
  67.     # Read its contents as a Unicode string
  68.     try:
  69.         web_page_contents = web_page.read().decode('UTF-8')
  70.     except UnicodeDecodeError:
  71.         raise Exception("Download error - Unable to decode document at URL '" + \
  72.                         url + "' as Unicode text")
  73.  
  74.     # Write the contents to a local text file as Unicode
  75.     # characters (overwriting the file if it
  76.     # already exists!)
  77.     try:
  78.         text_file = open(target_filename + '.' + filename_extension,
  79.                          'w', encoding = 'UTF-8')
  80.         text_file.write(web_page_contents)
  81.         text_file.close()
  82.     except:
  83.         raise Exception("Download error - Unable to write to file '" + \
  84.                         target_file + "'")
  85.  
  86.     # Return the downloaded document to the caller
  87.     return web_page_contents
  88.  
  89. #
  90. #--------------------------------------------------------------------#
  91.  
  92.  
  93.  
  94. #-----Student's Solution---------------------------------------------#
  95. #
  96. # Put your solution at the end of this file.
  97. #
  98.  
  99. #download('https://www.amazon.com.au/gp/rss/bestsellers/books', 'amazon_books', 'html')
  100. #download('http://www.beaversportswear.com/rss.php?type=rss', 'beaver_sportswear', 'html')
  101.  
  102. # Backend Web Functions
  103. def currency_convert(url, expression): # In the event a currency conversion is needed for a US webpage
  104.     source = urlopen(url) # Retrieves website that maintains updated currency conversions, specific to US to AUD
  105.     source = source.read().decode('UTF-8')
  106.     conversion_rate = re.findall(expression, source)
  107.     conversion_rate = float(conversion_rate[0])
  108.     return conversion_rate
  109.  
  110. def extract_from_page(address, webpage_name, method, expression_list):
  111.     global sites
  112.     if method == 'live': # Determines whether to open from downloaded source or to pull from a live webpage
  113.         source = urlopen(address).read().decode('UTF-8')
  114.     else:
  115.         source = open(address).read()
  116.     source_items = re.findall(expression_list[0], source)
  117.     if webpage_name in source_items:
  118.         source_items.remove(webpage_name) # Item names are marked up with <title> in the source but so is the title of the webpage -
  119.         # this removes it from the list
  120.     source_prices = re.findall(expression_list[1], source)
  121.     for price in range(len(source_prices)): # Fixes a bug where certain items' prices were marked up with <span class...>
  122.         if 'class' in source_prices[price]:
  123.             source_prices[price] = re.findall('>(.+?)<', source_prices[price])[0]
  124.     source_images = re.findall(expression_list[2], source)
  125.     source_combined = []
  126.     if len(source_items) == len(source_prices) == len(source_images): # Ensures all lists have the same amount of items
  127.         for product in range(len(source_items)):
  128.             source_combined.append([source_items[product], source_prices[product], source_images[product]])
  129.         sites.append(webpage_name)
  130.     else:
  131.         print('The expressions of "' + webpage_name + '" have matched an unequeal amount of items in each list.')
  132.     return source_combined
  133.  
  134. # Page Backend Retrieval
  135. sites = [] # Put this down here so the sites list doesn't reset everytime I call 'extract_from_page(...)'
  136. conversion_rate = currency_convert('https://www.xe.com/currencyconverter/convert/?Amount=1&From=USD&To=AUD', 'data-amount="(\d\..+?)"')
  137. photo_equipment = extract_from_page('http://www.photoequipmentstore.com.au/rss.php?type=rss', 'Photo Equipment Store Australia: New Products', 'live',
  138.         ['<title><\!\[CDATA\[(.+?)\]', '<isc:price><\!\[CDATA\[(.+?)\]', '<isc:image><\!\[CDATA\[(.+[jpg|png])'])
  139. kitchen_shelf = extract_from_page('http://www.thekitchenshelf.com.au/rss.php?type=rss', 'The Kitchen Shelf: New Products', 'live',
  140.         ['<title><\!\[CDATA\[(.+?)\]', '<isc:price><\!\[CDATA\[(.+?)\]', '<isc:image><\!\[CDATA\[(.+jpg|png)'])
  141. amazon_books = extract_from_page('static_pages/amazon_books.html', 'Amazon.com.au: Bestsellers in Books', 'static',
  142.         ['<title>#\d+:\s(.+?)<', '"price">(.+?)<', 'src="(https://images-fe.+?)"'])
  143. beaver_sportswear = extract_from_page('static_pages/beaver_sportswear.html', 'Beaver Sportswear (The Beaver Dam): New Products', 'static',
  144.         ['<title><\!\[CDATA\[(.+?)\]', '<isc:price><\!\[CDATA\[(.+?)\]', '<isc:image><\!\[CDATA\[(.+jpg|png)'])
  145.  
  146.  
  147. # UI Backend Functions
  148. def radio_1():
  149.     global active_site
  150.     active_site = 1
  151.     items_box.delete(0, END)
  152.     for item in photo_equipment:
  153.         items_box.insert(END, item[0] + ' |  AU' + item[1])
  154.  
  155. def radio_2():
  156.     global active_site
  157.     active_site = 2
  158.     items_box.delete(0, END)
  159.     for item in kitchen_shelf:
  160.         items_box.insert(END, item[0] + ' | AU' + item[1])
  161.  
  162. def radio_3():
  163.     global active_site
  164.     active_site = 3
  165.     items_box.delete(0, END)
  166.     for item in amazon_books:
  167.         items_box.insert(END, item[0] + ' | AU' + item[1])
  168.  
  169. def radio_4():
  170.     global active_site
  171.     active_site = 4
  172.     items_box.delete(0, END)
  173.     for item in beaver_sportswear:
  174.         items_box.insert(END, item[0] + ' | AU' + item[1])
  175.        
  176. def add_to_cart():
  177.     if items_box.curselection() != ():
  178.         if active_site == 1:
  179.             cart.append(photo_equipment[items_box.curselection()[0]])
  180.         elif active_site == 2:
  181.             cart.append(kitchen_shelf[items_box.curselection()[0]])
  182.         elif active_site == 3:
  183.             cart.append(amazon_books[items_box.curselection()[0]])
  184.         else:
  185.             cart.append(beaver_sportswear[items_box.curselection()[0]])
  186.  
  187. def clear_cart():
  188.     global cart
  189.     cart = []
  190.  
  191. def print_to_database(cart, database_file):
  192.     global cart_quantity
  193.     global cart_total
  194.     db_connection = connect(database = database_file)
  195.     cart_db = db_connection.cursor()
  196.     cart_db.execute("DELETE FROM ShoppingCart") # Clears Database
  197.     for item in cart:
  198.         try:
  199.             # Had an issue with inserting a particular item that had an apostrophe in the name so I just remove any
  200.             # occurences of apostrophes from item name strings to prevent SQL errors
  201.             cart_db.execute("INSERT INTO ShoppingCart VALUES('" + item[0].replace("'", "") + "', '" + item[1][1:].replace(",", "") + "')")
  202.         except:
  203.             print('Error inserting data into table.')
  204.     # Wrote some queries to replace the for loop method of calculating certain information from the cart list
  205.     cart_db.execute("SELECT COUNT(Item) FROM ShoppingCart")
  206.     cart_quantity = str(cart_db.fetchall()[0][0])
  207.     cart_db.execute("SELECT SUM(Price) FROM ShoppingCart")
  208.     cart_total = str(cart_db.fetchall()[0][0])
  209.     db_connection.commit()
  210.     db_connection.close()
  211.    
  212. # Name of the invoice file. To simplify marking, your program should
  213. # generate its invoice using this file name.
  214. invoice_file = 'invoice.html'
  215. database_file = 'shopping_cart.db'
  216. logo_image = 'logo.gif'
  217. cart = []
  218.  
  219. def print_invoice():
  220.     print_to_database(cart, database_file)
  221.     invoice = open(invoice_file, 'w')
  222.     invoice.write('''<!DOCTYPE html>
  223. <html>
  224.     <head>
  225.         <title>Keeto's Store</title>
  226.     </head>
  227.    <body> \n''')
  228.     invoice.write('        <h1>Keeto\'s Store Invoice!</h1> \n')
  229.     invoice.write('     <img src="' + logo_image + '"> \n')
  230.     if len(cart) > 0:
  231.         invoice.write('        <h2>Your cart consists of ' + cart_quantity + ' item')
  232.         if len(cart) > 1: # Ensures proper pluralisation
  233.             invoice.write('s')
  234.         invoice.write('. \n')
  235.         invoice.write('        <h2>Your total cost is: <u>AU$' + cart_total + '</u></h2> \n')
  236.         invoice.write('        <br> \n')
  237.         for item in cart:
  238.             invoice.write('        <h3>' + item[0] + '</h3> \n')
  239.             invoice.write('        <img src="' + item[2] + '" alt="' + item[0] + '" width = 200 height = 200> \n')
  240.             invoice.write('        <p>Item Price: AU' + item[1] + '</p> \n')
  241.     else:
  242.         invoice.write('        <h2>Your cart is empty.</h2> \n')
  243.     invoice.write('        <br> \n')
  244.     invoice.write('    </body> \n')
  245.     invoice.write('    <footer> \n')
  246.     invoice.write('        <p>Items retrieved from:</p> \n')
  247.     invoice.write('        <ul> \n')
  248.     for site in sites:
  249.         invoice.write('            <li>' + site + '</li> \n')
  250.     invoice.write('        </ul> \n')
  251.     invoice.write('    </footer> \n')
  252.     invoice.write('</html>')
  253.     invoice.close()
  254.  
  255. # User Interface
  256. root_window = Tk()
  257. root_window.title('Keeto\'s Store')
  258.  
  259. # Widgets
  260. window_title = Label(root_window, text = 'Keeto\'s Online Shop').pack()
  261. logo = PhotoImage(file = logo_image)
  262. image_label = Label(root_window, image = logo).pack()
  263. live_label = Label(root_window, text="Live Sites").pack(anchor = W)
  264. v = IntVar() # Necessary for radio buttons
  265. site1_button = Radiobutton(root_window, text = sites[0], variable = v, value = 1, command = radio_1).pack(anchor = W)
  266. site2_button = Radiobutton(root_window, text = sites[1], variable = v, value = 2, command = radio_2).pack(anchor = W)
  267. static_label = Label(root_window, text = "Archived Sites").pack(anchor = W)
  268. site3_button = Radiobutton(root_window, text = sites[2], variable = v, value = 3, command=radio_3).pack(anchor = W)
  269. site4_button = Radiobutton(root_window, text = sites[3], variable = v, value = 4, command=radio_4).pack(anchor = W)
  270. items_label = Label(root_window, text = "Items").pack(anchor = W)
  271. items_box = Listbox(root_window, width = 100)
  272. items_box.pack(anchor = W)
  273. cart_button = Button(root_window, text = "Add to Cart", command = add_to_cart).pack()
  274. invoice_button = Button(root_window, text = "Print Invoice", command = print_invoice).pack()
  275. clear_button = Button(root_window, text = "Clear Cart", command = clear_cart).pack()
  276.  
  277. root_window.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement