From 8628e4628e46d41978d610d418f4d013a335937d Mon Sep 17 00:00:00 2001 From: Michael Soileau Date: Sat, 19 Aug 2017 11:37:55 -0700 Subject: [PATCH 1/8] For python 3 --- Lesson4/step2/.gitignore | 1 + Lesson4/step2/lotsofmenus.py | 2 +- Lesson4/step2/lotsofmenus.py.bak | 386 ++++++++++++++++++++++++++ Lesson4/step2/project.py | 8 +- Lesson4/step2/project.py.bak | 459 +++++++++++++++++++++++++++++++ 5 files changed, 851 insertions(+), 5 deletions(-) create mode 100644 Lesson4/step2/.gitignore create mode 100644 Lesson4/step2/lotsofmenus.py.bak create mode 100644 Lesson4/step2/project.py.bak diff --git a/Lesson4/step2/.gitignore b/Lesson4/step2/.gitignore new file mode 100644 index 0000000..b2a5bad --- /dev/null +++ b/Lesson4/step2/.gitignore @@ -0,0 +1 @@ +*.idea/ \ No newline at end of file diff --git a/Lesson4/step2/lotsofmenus.py b/Lesson4/step2/lotsofmenus.py index 3e4460a..cbfbe51 100644 --- a/Lesson4/step2/lotsofmenus.py +++ b/Lesson4/step2/lotsofmenus.py @@ -383,4 +383,4 @@ session.commit() -print "added menu items!" +print("added menu items!") diff --git a/Lesson4/step2/lotsofmenus.py.bak b/Lesson4/step2/lotsofmenus.py.bak new file mode 100644 index 0000000..3e4460a --- /dev/null +++ b/Lesson4/step2/lotsofmenus.py.bak @@ -0,0 +1,386 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +from database_setup import Restaurant, Base, MenuItem, User + +engine = create_engine('sqlite:///restaurantmenuwithusers.db') +# Bind the engine to the metadata of the Base class so that the +# declaratives can be accessed through a DBSession instance +Base.metadata.bind = engine + +DBSession = sessionmaker(bind=engine) +# A DBSession() instance establishes all conversations with the database +# and represents a "staging zone" for all the objects loaded into the +# database session object. Any change made against the objects in the +# session won't be persisted into the database until you call +# session.commit(). If you're not happy about the changes, you can +# revert all of them back to the last commit by calling +# session.rollback() +session = DBSession() + + +# Create dummy user +User1 = User(name="Robo Barista", email="tinnyTim@udacity.com", + picture='https://pbs.twimg.com/profile_images/2671170543/18debd694829ed78203a5a36dd364160_400x400.png') +session.add(User1) +session.commit() + +# Menu for UrbanBurger +restaurant1 = Restaurant(user_id=1, name="Urban Burger") + +session.add(restaurant1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", + price="$7.50", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="French Fries", description="with garlic and parmesan", + price="$2.99", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Chicken Burger", description="Juicy grilled chicken patty with tomato mayo and lettuce", + price="$5.50", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Chocolate Cake", description="fresh baked and served with ice cream", + price="$3.99", course="Dessert", restaurant=restaurant1) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Sirloin Burger", description="Made with grade A beef", + price="$7.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem4) +session.commit() + +menuItem5 = MenuItem(user_id=1, name="Root Beer", description="16oz of refreshing goodness", + price="$1.99", course="Beverage", restaurant=restaurant1) + +session.add(menuItem5) +session.commit() + +menuItem6 = MenuItem(user_id=1, name="Iced Tea", description="with Lemon", + price="$.99", course="Beverage", restaurant=restaurant1) + +session.add(menuItem6) +session.commit() + +menuItem7 = MenuItem(user_id=1, name="Grilled Cheese Sandwich", + description="On texas toast with American Cheese", price="$3.49", course="Entree", restaurant=restaurant1) + +session.add(menuItem7) +session.commit() + +menuItem8 = MenuItem(user_id=1, name="Veggie Burger", description="Made with freshest of ingredients and home grown spices", + price="$5.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem8) +session.commit() + + +# Menu for Super Stir Fry +restaurant2 = Restaurant(user_id=1, name="Super Stir Fry") + +session.add(restaurant2) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Chicken Stir Fry", description="With your choice of noodles vegetables and sauces", + price="$7.99", course="Entree", restaurant=restaurant2) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Peking Duck", + description=" A famous duck dish from Beijing[1] that has been prepared since the imperial era. The meat is prized for its thin, crisp skin, with authentic versions of the dish serving mostly the skin and little meat, sliced in front of the diners by the cook", price="$25", course="Entree", restaurant=restaurant2) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Spicy Tuna Roll", description="Seared rare ahi, avocado, edamame, cucumber with wasabi soy sauce ", + price="15", course="Entree", restaurant=restaurant2) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Nepali Momo ", description="Steamed dumplings made with vegetables, spices and meat. ", + price="12", course="Entree", restaurant=restaurant2) + +session.add(menuItem4) +session.commit() + +menuItem5 = MenuItem(user_id=1, name="Beef Noodle Soup", description="A Chinese noodle soup made of stewed or red braised beef, beef broth, vegetables and Chinese noodles.", + price="14", course="Entree", restaurant=restaurant2) + +session.add(menuItem5) +session.commit() + +menuItem6 = MenuItem(user_id=1, name="Ramen", description="a Japanese noodle soup dish. It consists of Chinese-style wheat noodles served in a meat- or (occasionally) fish-based broth, often flavored with soy sauce or miso, and uses toppings such as sliced pork, dried seaweed, kamaboko, and green onions.", + price="12", course="Entree", restaurant=restaurant2) + +session.add(menuItem6) +session.commit() + + +# Menu for Panda Garden +restaurant1 = Restaurant(user_id=1, name="Panda Garden") + +session.add(restaurant1) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Pho", description="a Vietnamese noodle soup consisting of broth, linguine-shaped rice noodles called banh pho, a few herbs, and meat.", + price="$8.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Chinese Dumplings", description="a common Chinese dumpling which generally consists of minced meat and finely chopped vegetables wrapped into a piece of dough skin. The skin can be either thin and elastic or thicker.", + price="$6.99", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Gyoza", description="light seasoning of Japanese gyoza with salt and soy sauce, and in a thin gyoza wrapper", + price="$9.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Stinky Tofu", description="Taiwanese dish, deep fried fermented tofu served with pickled cabbage.", + price="$6.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem4) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", + price="$9.50", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + + +# Menu for Thyme for that +restaurant1 = Restaurant(user_id=1, name="Thyme for That Vegetarian Cuisine ") + +session.add(restaurant1) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Tres Leches Cake", description="Rich, luscious sponge cake soaked in sweet milk and topped with vanilla bean whipped cream and strawberries.", + price="$2.99", course="Dessert", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Mushroom risotto", description="Portabello mushrooms in a creamy risotto", + price="$5.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Honey Boba Shaved Snow", + description="Milk snow layered with honey boba, jasmine tea jelly, grass jelly, caramel, cream, and freshly made mochi", price="$4.50", course="Dessert", restaurant=restaurant1) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Cauliflower Manchurian", description="Golden fried cauliflower florets in a midly spiced soya,garlic sauce cooked with fresh cilantro, celery, chilies,ginger & green onions", + price="$6.95", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem4) +session.commit() + +menuItem5 = MenuItem(user_id=1, name="Aloo Gobi Burrito", description="Vegan goodness. Burrito filled with rice, garbanzo beans, curry sauce, potatoes (aloo), fried cauliflower (gobi) and chutney. Nom Nom", + price="$7.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem5) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", + price="$6.80", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + + +# Menu for Tony's Bistro +restaurant1 = Restaurant(user_id=1, name="Tony\'s Bistro ") + +session.add(restaurant1) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Shellfish Tower", description="Lobster, shrimp, sea snails, crawfish, stacked into a delicious tower", + price="$13.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Chicken and Rice", description="Chicken... and rice", + price="$4.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Mom's Spaghetti", description="Spaghetti with some incredible tomato sauce made by mom", + price="$6.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Choc Full O\' Mint (Smitten\'s Fresh Mint Chip ice cream)", + description="Milk, cream, salt, ..., Liquid nitrogen magic", price="$3.95", course="Dessert", restaurant=restaurant1) + +session.add(menuItem4) +session.commit() + +menuItem5 = MenuItem(user_id=1, name="Tonkatsu Ramen", description="Noodles in a delicious pork-based broth with a soft-boiled egg", + price="$7.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem5) +session.commit() + + +# Menu for Andala's +restaurant1 = Restaurant(user_id=1, name="Andala\'s") + +session.add(restaurant1) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Lamb Curry", description="Slow cook that thang in a pool of tomatoes, onions and alllll those tasty Indian spices. Mmmm.", + price="$9.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Chicken Marsala", description="Chicken cooked in Marsala wine sauce with mushrooms", + price="$7.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Potstickers", description="Delicious chicken and veggies encapsulated in fried dough.", + price="$6.50", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Nigiri Sampler", description="Maguro, Sake, Hamachi, Unagi, Uni, TORO!", + price="$6.75", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem4) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", + price="$7.00", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + + +# Menu for Auntie Ann's +restaurant1 = Restaurant(user_id=1, name="Auntie Ann\'s Diner' ") + +session.add(restaurant1) +session.commit() + +menuItem9 = MenuItem(user_id=1, name="Chicken Fried Steak", + description="Fresh battered sirloin steak fried and smothered with cream gravy", price="$8.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem9) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Boysenberry Sorbet", description="An unsettlingly huge amount of ripe berries turned into frozen (and seedless) awesomeness", + price="$2.99", course="Dessert", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Broiled salmon", description="Salmon fillet marinated with fresh herbs and broiled hot & fast", + price="$10.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem3 = MenuItem(user_id=1, name="Morels on toast (seasonal)", + description="Wild morel mushrooms fried in butter, served on herbed toast slices", price="$7.50", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem3) +session.commit() + +menuItem4 = MenuItem(user_id=1, name="Tandoori Chicken", description="Chicken marinated in yoghurt and seasoned with a spicy mix(chilli, tamarind among others) and slow cooked in a cylindrical clay or metal oven which gets its heat from burning charcoal.", + price="$8.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem4) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", + price="$9.50", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + +menuItem10 = MenuItem(user_id=1, name="Spinach Ice Cream", description="vanilla ice cream made with organic spinach leaves", + price="$1.99", course="Dessert", restaurant=restaurant1) + +session.add(menuItem10) +session.commit() + + +# Menu for Cocina Y Amor +restaurant1 = Restaurant(user_id=1, name="Cocina Y Amor ") + +session.add(restaurant1) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Super Burrito Al Pastor", + description="Marinated Pork, Rice, Beans, Avocado, Cilantro, Salsa, Tortilla", price="$5.95", course="Entree", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + +menuItem2 = MenuItem(user_id=1, name="Cachapa", description="Golden brown, corn-based Venezuelan pancake; usually stuffed with queso telita or queso de mano, and possibly lechon. ", + price="$7.99", course="Entree", restaurant=restaurant1) + +session.add(menuItem2) +session.commit() + + +restaurant1 = Restaurant(user_id=1, name="State Bird Provisions") +session.add(restaurant1) +session.commit() + +menuItem1 = MenuItem(user_id=1, name="Chantrelle Toast", description="Crispy Toast with Sesame Seeds slathered with buttery chantrelle mushrooms", + price="$5.95", course="Appetizer", restaurant=restaurant1) + +session.add(menuItem1) +session.commit + +menuItem1 = MenuItem(user_id=1, name="Guanciale Chawanmushi", + description="Japanese egg custard served hot with spicey Italian Pork Jowl (guanciale)", price="$6.95", course="Dessert", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + + +menuItem1 = MenuItem(user_id=1, name="Lemon Curd Ice Cream Sandwich", + description="Lemon Curd Ice Cream Sandwich on a chocolate macaron with cardamom meringue and cashews", price="$4.25", course="Dessert", restaurant=restaurant1) + +session.add(menuItem1) +session.commit() + + +print "added menu items!" diff --git a/Lesson4/step2/project.py b/Lesson4/step2/project.py index 529ff42..be52ee4 100644 --- a/Lesson4/step2/project.py +++ b/Lesson4/step2/project.py @@ -31,7 +31,7 @@ @app.route('/login') def showLogin(): state = ''.join(random.choice(string.ascii_uppercase + string.digits) - for x in xrange(32)) + for x in range(32)) login_session['state'] = state # return "The current session state is %s" % login_session['state'] return render_template('login.html', STATE=state) @@ -44,7 +44,7 @@ def fbconnect(): response.headers['Content-Type'] = 'application/json' return response access_token = request.data - print "access token received %s " % access_token + print("access token received %s " % access_token) app_id = json.loads(open('fb_client_secrets.json', 'r').read())[ @@ -165,7 +165,7 @@ def gconnect(): if result['issued_to'] != CLIENT_ID: response = make_response( json.dumps("Token's client ID does not match app's."), 401) - print "Token's client ID does not match app's." + print("Token's client ID does not match app's.") response.headers['Content-Type'] = 'application/json' return response @@ -208,7 +208,7 @@ def gconnect(): output += login_session['picture'] output += ' " style = "width: 300px; height: 300px;border-radius: 150px;-webkit-border-radius: 150px;-moz-border-radius: 150px;"> ' flash("you are now logged in as %s" % login_session['username']) - print "done!" + print("done!") return output # User Helper Functions diff --git a/Lesson4/step2/project.py.bak b/Lesson4/step2/project.py.bak new file mode 100644 index 0000000..529ff42 --- /dev/null +++ b/Lesson4/step2/project.py.bak @@ -0,0 +1,459 @@ +from flask import Flask, render_template, request, redirect, jsonify, url_for, flash +from sqlalchemy import create_engine, asc +from sqlalchemy.orm import sessionmaker +from database_setup import Base, Restaurant, MenuItem, User +from flask import session as login_session +import random +import string +from oauth2client.client import flow_from_clientsecrets +from oauth2client.client import FlowExchangeError +import httplib2 +import json +from flask import make_response +import requests + +app = Flask(__name__) + +CLIENT_ID = json.loads( + open('client_secrets.json', 'r').read())['web']['client_id'] +APPLICATION_NAME = "Restaurant Menu Application" + + +# Connect to Database and create database session +engine = create_engine('sqlite:///restaurantmenuwithusers.db') +Base.metadata.bind = engine + +DBSession = sessionmaker(bind=engine) +session = DBSession() + + +# Create anti-forgery state token +@app.route('/login') +def showLogin(): + state = ''.join(random.choice(string.ascii_uppercase + string.digits) + for x in xrange(32)) + login_session['state'] = state + # return "The current session state is %s" % login_session['state'] + return render_template('login.html', STATE=state) + + +@app.route('/fbconnect', methods=['POST']) +def fbconnect(): + if request.args.get('state') != login_session['state']: + response = make_response(json.dumps('Invalid state parameter.'), 401) + response.headers['Content-Type'] = 'application/json' + return response + access_token = request.data + print "access token received %s " % access_token + + + app_id = json.loads(open('fb_client_secrets.json', 'r').read())[ + 'web']['app_id'] + app_secret = json.loads( + open('fb_client_secrets.json', 'r').read())['web']['app_secret'] + url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=%s&client_secret=%s&fb_exchange_token=%s' % ( + app_id, app_secret, access_token) + h = httplib2.Http() + result = h.request(url, 'GET')[1] + + + # Use token to get user info from API + userinfo_url = "https://graph.facebook.com/v2.8/me" + ''' + Due to the formatting for the result from the server token exchange we have to + split the token first on commas and select the first index which gives us the key : value + for the server access token then we split it on colons to pull out the actual token value + and replace the remaining quotes with nothing so that it can be used directly in the graph + api calls + ''' + token = result.split(',')[0].split(':')[1].replace('"', '') + + url = 'https://graph.facebook.com/v2.8/me?access_token=%s&fields=name,id,email' % token + h = httplib2.Http() + result = h.request(url, 'GET')[1] + # print "url sent for API access:%s"% url + # print "API JSON result: %s" % result + data = json.loads(result) + login_session['provider'] = 'facebook' + login_session['username'] = data["name"] + login_session['email'] = data["email"] + login_session['facebook_id'] = data["id"] + + # The token must be stored in the login_session in order to properly logout + login_session['access_token'] = token + + # Get user picture + url = 'https://graph.facebook.com/v2.8/me/picture?access_token=%s&redirect=0&height=200&width=200' % token + h = httplib2.Http() + result = h.request(url, 'GET')[1] + data = json.loads(result) + + login_session['picture'] = data["data"]["url"] + + # see if user exists + user_id = getUserID(login_session['email']) + if not user_id: + user_id = createUser(login_session) + login_session['user_id'] = user_id + + output = '' + output += '

Welcome, ' + output += login_session['username'] + + output += '!

' + output += ' ' + + flash("Now logged in as %s" % login_session['username']) + return output + + +@app.route('/fbdisconnect') +def fbdisconnect(): + facebook_id = login_session['facebook_id'] + # The access token must me included to successfully logout + access_token = login_session['access_token'] + url = 'https://graph.facebook.com/%s/permissions?access_token=%s' % (facebook_id,access_token) + h = httplib2.Http() + result = h.request(url, 'DELETE')[1] + return "you have been logged out" + + +@app.route('/gconnect', methods=['POST']) +def gconnect(): + # Validate state token + if request.args.get('state') != login_session['state']: + response = make_response(json.dumps('Invalid state parameter.'), 401) + response.headers['Content-Type'] = 'application/json' + return response + # Obtain authorization code + code = request.data + + try: + # Upgrade the authorization code into a credentials object + oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='') + oauth_flow.redirect_uri = 'postmessage' + credentials = oauth_flow.step2_exchange(code) + except FlowExchangeError: + response = make_response( + json.dumps('Failed to upgrade the authorization code.'), 401) + response.headers['Content-Type'] = 'application/json' + return response + + # Check that the access token is valid. + access_token = credentials.access_token + url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s' + % access_token) + h = httplib2.Http() + result = json.loads(h.request(url, 'GET')[1]) + # If there was an error in the access token info, abort. + if result.get('error') is not None: + response = make_response(json.dumps(result.get('error')), 500) + response.headers['Content-Type'] = 'application/json' + return response + + # Verify that the access token is used for the intended user. + gplus_id = credentials.id_token['sub'] + if result['user_id'] != gplus_id: + response = make_response( + json.dumps("Token's user ID doesn't match given user ID."), 401) + response.headers['Content-Type'] = 'application/json' + return response + + # Verify that the access token is valid for this app. + if result['issued_to'] != CLIENT_ID: + response = make_response( + json.dumps("Token's client ID does not match app's."), 401) + print "Token's client ID does not match app's." + response.headers['Content-Type'] = 'application/json' + return response + + stored_access_token = login_session.get('access_token') + stored_gplus_id = login_session.get('gplus_id') + if stored_access_token is not None and gplus_id == stored_gplus_id: + response = make_response(json.dumps('Current user is already connected.'), + 200) + response.headers['Content-Type'] = 'application/json' + return response + + # Store the access token in the session for later use. + login_session['access_token'] = credentials.access_token + login_session['gplus_id'] = gplus_id + + # Get user info + userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo" + params = {'access_token': credentials.access_token, 'alt': 'json'} + answer = requests.get(userinfo_url, params=params) + + data = answer.json() + + login_session['username'] = data['name'] + login_session['picture'] = data['picture'] + login_session['email'] = data['email'] + # ADD PROVIDER TO LOGIN SESSION + login_session['provider'] = 'google' + + # see if user exists, if it doesn't make a new one + user_id = getUserID(data["email"]) + if not user_id: + user_id = createUser(login_session) + login_session['user_id'] = user_id + + output = '' + output += '

Welcome, ' + output += login_session['username'] + output += '!

' + output += ' ' + flash("you are now logged in as %s" % login_session['username']) + print "done!" + return output + +# User Helper Functions + + +def createUser(login_session): + newUser = User(name=login_session['username'], email=login_session[ + 'email'], picture=login_session['picture']) + session.add(newUser) + session.commit() + user = session.query(User).filter_by(email=login_session['email']).one() + return user.id + + +def getUserInfo(user_id): + user = session.query(User).filter_by(id=user_id).one() + return user + + +def getUserID(email): + try: + user = session.query(User).filter_by(email=email).one() + return user.id + except: + return None + +# DISCONNECT - Revoke a current user's token and reset their login_session + + +@app.route('/gdisconnect') +def gdisconnect(): + # Only disconnect a connected user. + access_token = login_session.get('access_token') + if access_token is None: + response = make_response( + json.dumps('Current user not connected.'), 401) + response.headers['Content-Type'] = 'application/json' + return response + url = 'https://accounts.google.com/o/oauth2/revoke?token=%s' % access_token + h = httplib2.Http() + result = h.request(url, 'GET')[0] + if result['status'] == '200': + del login_session['access_token'] + del login_session['gplus_id'] + del login_session['username'] + del login_session['email'] + del login_session['picture'] + response = make_response(json.dumps('Successfully disconnected.'), 200) + response.headers['Content-Type'] = 'application/json' + return response + else: + response = make_response(json.dumps('Failed to revoke token for given user.', 400)) + response.headers['Content-Type'] = 'application/json' + return response + + +# JSON APIs to view Restaurant Information +@app.route('/restaurant//menu/JSON') +def restaurantMenuJSON(restaurant_id): + restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() + items = session.query(MenuItem).filter_by( + restaurant_id=restaurant_id).all() + return jsonify(MenuItems=[i.serialize for i in items]) + + +@app.route('/restaurant//menu//JSON') +def menuItemJSON(restaurant_id, menu_id): + Menu_Item = session.query(MenuItem).filter_by(id=menu_id).one() + return jsonify(Menu_Item=Menu_Item.serialize) + + +@app.route('/restaurant/JSON') +def restaurantsJSON(): + restaurants = session.query(Restaurant).all() + return jsonify(restaurants=[r.serialize for r in restaurants]) + + +# Show all restaurants +@app.route('/') +@app.route('/restaurant/') +def showRestaurants(): + restaurants = session.query(Restaurant).order_by(asc(Restaurant.name)) + if 'username' not in login_session: + return render_template('publicrestaurants.html', restaurants=restaurants) + else: + return render_template('restaurants.html', restaurants=restaurants) + +# Create a new restaurant + + +@app.route('/restaurant/new/', methods=['GET', 'POST']) +def newRestaurant(): + if 'username' not in login_session: + return redirect('/login') + if request.method == 'POST': + newRestaurant = Restaurant( + name=request.form['name'], user_id=login_session['user_id']) + session.add(newRestaurant) + flash('New Restaurant %s Successfully Created' % newRestaurant.name) + session.commit() + return redirect(url_for('showRestaurants')) + else: + return render_template('newRestaurant.html') + +# Edit a restaurant + + +@app.route('/restaurant//edit/', methods=['GET', 'POST']) +def editRestaurant(restaurant_id): + editedRestaurant = session.query( + Restaurant).filter_by(id=restaurant_id).one() + if 'username' not in login_session: + return redirect('/login') + if editedRestaurant.user_id != login_session['user_id']: + return "" + if request.method == 'POST': + if request.form['name']: + editedRestaurant.name = request.form['name'] + flash('Restaurant Successfully Edited %s' % editedRestaurant.name) + return redirect(url_for('showRestaurants')) + else: + return render_template('editRestaurant.html', restaurant=editedRestaurant) + + +# Delete a restaurant +@app.route('/restaurant//delete/', methods=['GET', 'POST']) +def deleteRestaurant(restaurant_id): + restaurantToDelete = session.query( + Restaurant).filter_by(id=restaurant_id).one() + if 'username' not in login_session: + return redirect('/login') + if restaurantToDelete.user_id != login_session['user_id']: + return "" + if request.method == 'POST': + session.delete(restaurantToDelete) + flash('%s Successfully Deleted' % restaurantToDelete.name) + session.commit() + return redirect(url_for('showRestaurants', restaurant_id=restaurant_id)) + else: + return render_template('deleteRestaurant.html', restaurant=restaurantToDelete) + +# Show a restaurant menu + + +@app.route('/restaurant//') +@app.route('/restaurant//menu/') +def showMenu(restaurant_id): + restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() + creator = getUserInfo(restaurant.user_id) + items = session.query(MenuItem).filter_by( + restaurant_id=restaurant_id).all() + if 'username' not in login_session or creator.id != login_session['user_id']: + return render_template('publicmenu.html', items=items, restaurant=restaurant, creator=creator) + else: + return render_template('menu.html', items=items, restaurant=restaurant, creator=creator) + + +# Create a new menu item +@app.route('/restaurant//menu/new/', methods=['GET', 'POST']) +def newMenuItem(restaurant_id): + if 'username' not in login_session: + return redirect('/login') + restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() + if login_session['user_id'] != restaurant.user_id: + return "" + if request.method == 'POST': + newItem = MenuItem(name=request.form['name'], description=request.form['description'], price=request.form[ + 'price'], course=request.form['course'], restaurant_id=restaurant_id, user_id=restaurant.user_id) + session.add(newItem) + session.commit() + flash('New Menu %s Item Successfully Created' % (newItem.name)) + return redirect(url_for('showMenu', restaurant_id=restaurant_id)) + else: + return render_template('newmenuitem.html', restaurant_id=restaurant_id) + +# Edit a menu item + + +@app.route('/restaurant//menu//edit', methods=['GET', 'POST']) +def editMenuItem(restaurant_id, menu_id): + if 'username' not in login_session: + return redirect('/login') + editedItem = session.query(MenuItem).filter_by(id=menu_id).one() + restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() + if login_session['user_id'] != restaurant.user_id: + return "" + if request.method == 'POST': + if request.form['name']: + editedItem.name = request.form['name'] + if request.form['description']: + editedItem.description = request.form['description'] + if request.form['price']: + editedItem.price = request.form['price'] + if request.form['course']: + editedItem.course = request.form['course'] + session.add(editedItem) + session.commit() + flash('Menu Item Successfully Edited') + return redirect(url_for('showMenu', restaurant_id=restaurant_id)) + else: + return render_template('editmenuitem.html', restaurant_id=restaurant_id, menu_id=menu_id, item=editedItem) + + +# Delete a menu item +@app.route('/restaurant//menu//delete', methods=['GET', 'POST']) +def deleteMenuItem(restaurant_id, menu_id): + if 'username' not in login_session: + return redirect('/login') + restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() + itemToDelete = session.query(MenuItem).filter_by(id=menu_id).one() + if login_session['user_id'] != restaurant.user_id: + return "" + if request.method == 'POST': + session.delete(itemToDelete) + session.commit() + flash('Menu Item Successfully Deleted') + return redirect(url_for('showMenu', restaurant_id=restaurant_id)) + else: + return render_template('deleteMenuItem.html', item=itemToDelete) + + +# Disconnect based on provider +@app.route('/disconnect') +def disconnect(): + if 'provider' in login_session: + if login_session['provider'] == 'google': + gdisconnect() + del login_session['gplus_id'] + del login_session['credentials'] + if login_session['provider'] == 'facebook': + fbdisconnect() + del login_session['facebook_id'] + del login_session['username'] + del login_session['email'] + del login_session['picture'] + del login_session['user_id'] + del login_session['provider'] + flash("You have successfully been logged out.") + return redirect(url_for('showRestaurants')) + else: + flash("You were not logged in") + return redirect(url_for('showRestaurants')) + + +if __name__ == '__main__': + app.secret_key = 'super_secret_key' + app.debug = True + app.run(host='0.0.0.0', port=5000) From ac5b73e218160cdd9e1d2a84c9977aad22fefc40 Mon Sep 17 00:00:00 2001 From: Michael Soileau Date: Sat, 19 Aug 2017 12:53:52 -0700 Subject: [PATCH 2/8] Fix numerous errors and bad practices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds requirements.txt file - Fixed the ability to add a new restaurant menu item. - Fixed the broken OAuth code. - Sets up variables in the environment in a .env file rather than hard-coding them in and exposing student credentials. - Removed the public section, protected inside of if statements that use the login_session inside of jinja. - Removed the unused database - Added gitignore to the directory. - Added .python-version file so that pyenv can pick it up and so it can be easily seen. - Fixed formatting for Pep8. Use Flake8 instead, it’s better. - Removed the check for if Google Auth already exists. This isn’t tied to the session credentials, which means someone can be infinitely unable to use their Google login until they delete all their local storage. - Pushed all code into a single credentials file so that adding new credentials is easy. - Updated the base configuration so that it’s easier to add custom scripts and css to it. - Updated the login page to use extend the base class. - Updated the login page to use the credentials coming in from the server rather than hard-coding them in, so that there’s no mismatch or need to update multiple places. - Added CSS to style the main page a bit better. Also removed what looks like a css error. - Added html tag to show which files a user can edit. - Updated to Bootstrap 3.3.7 - Setup the secret on the app so that the user can run `flask run` to boot up the application - Added readme to give an idea of how to start the application. - Fixes numerous stylistic problems: Unused imports, pep8 coding violations, improper casing, etc. - Fixed issue where cancelling out still acted as if the result was successful. The attribute “type=button” needs to be added, as the specification for all buttons that are not given an explicit type is to be “submit”. - Removed redundant type declarations on buttons. --- .python-version | 1 + Lesson4/step2/.env.example | 7 + Lesson4/step2/.gitignore | 6 +- Lesson4/step2/.python-version | 1 + Lesson4/step2/README.md | 28 ++ Lesson4/step2/client_secrets.json | 1 - Lesson4/step2/database_setup.py | 3 +- Lesson4/step2/fb_client_secrets.json | 6 - Lesson4/step2/lotsofmenus.py | 143 +++--- Lesson4/step2/lotsofmenus.py.bak | 386 --------------- Lesson4/step2/project.py | 288 ++++++----- Lesson4/step2/project.py.bak | 459 ------------------ Lesson4/step2/requirements.txt | 19 + Lesson4/step2/restaurantmenu.db | 0 Lesson4/step2/restaurantmenuwithusers.db | Bin 11264 -> 11264 bytes Lesson4/step2/static/styles.css | 224 +++++---- Lesson4/step2/templates/deleteRestaurant.html | 22 +- Lesson4/step2/templates/deletemenuitem.html | 22 +- Lesson4/step2/templates/editRestaurant.html | 54 ++- Lesson4/step2/templates/editmenuitem.html | 113 +++-- Lesson4/step2/templates/header.html | 26 +- Lesson4/step2/templates/login.html | 261 +++++----- Lesson4/step2/templates/main.html | 29 +- Lesson4/step2/templates/menu.html | 235 ++++----- Lesson4/step2/templates/newRestaurant.html | 45 +- Lesson4/step2/templates/newmenuitem.html | 100 ++-- Lesson4/step2/templates/publicmenu.html | 95 ---- .../step2/templates/publicrestaurants.html | 53 -- Lesson4/step2/templates/restaurants.html | 107 ++-- Lesson4/step2/variables.py | 32 ++ 30 files changed, 963 insertions(+), 1803 deletions(-) create mode 100644 .python-version create mode 100644 Lesson4/step2/.env.example create mode 100644 Lesson4/step2/.python-version create mode 100644 Lesson4/step2/README.md delete mode 100644 Lesson4/step2/client_secrets.json delete mode 100644 Lesson4/step2/fb_client_secrets.json delete mode 100644 Lesson4/step2/lotsofmenus.py.bak delete mode 100644 Lesson4/step2/project.py.bak create mode 100644 Lesson4/step2/requirements.txt delete mode 100644 Lesson4/step2/restaurantmenu.db delete mode 100644 Lesson4/step2/templates/publicmenu.html delete mode 100644 Lesson4/step2/templates/publicrestaurants.html create mode 100644 Lesson4/step2/variables.py diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..9575d51 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.6.1 diff --git a/Lesson4/step2/.env.example b/Lesson4/step2/.env.example new file mode 100644 index 0000000..0a37f4f --- /dev/null +++ b/Lesson4/step2/.env.example @@ -0,0 +1,7 @@ +google_client_id= +google_project_id= +google_client_secret= +facebook_app_id= +facebook_app_secret= +app_secret_key= +debug= \ No newline at end of file diff --git a/Lesson4/step2/.gitignore b/Lesson4/step2/.gitignore index b2a5bad..40723b0 100644 --- a/Lesson4/step2/.gitignore +++ b/Lesson4/step2/.gitignore @@ -1 +1,5 @@ -*.idea/ \ No newline at end of file +*.idea/ +__pycache__/ +pyrepo/ +*.pyc +.env \ No newline at end of file diff --git a/Lesson4/step2/.python-version b/Lesson4/step2/.python-version new file mode 100644 index 0000000..9575d51 --- /dev/null +++ b/Lesson4/step2/.python-version @@ -0,0 +1 @@ +3.6.1 diff --git a/Lesson4/step2/README.md b/Lesson4/step2/README.md new file mode 100644 index 0000000..7a1325b --- /dev/null +++ b/Lesson4/step2/README.md @@ -0,0 +1,28 @@ +# Restaurants and Menus + +The first step is to setup the `.env` file to hold all of the environment variables that are needed to connect to the APIs. To do so, run `cp .env.example .env`, which will copy the example file to the .env file. This file is not committed to the Git repo. + +After signing up for an app on facebook and google, fill in the values in their appropriate places in the `.env` file. These will automatically cascade to the rest of the app. + +The database used by default is restaurantmenuwithusers.db. To change to another database engine, look in the `database_setup.py` file and change the engine to whatever is appropriate for your use case. + +To start using the program, run: +```shell +pip install -r requirements.txt +``` + +This will install all of the dependencies. + +To re-run the base seeds, run `python lotsofmenus.py`. + +To start up the app, run either: + +```shell +export FLASK_APP=project.py +flask run +``` + +Or +```shell +python project.py +``` \ No newline at end of file diff --git a/Lesson4/step2/client_secrets.json b/Lesson4/step2/client_secrets.json deleted file mode 100644 index f6bbfb7..0000000 --- a/Lesson4/step2/client_secrets.json +++ /dev/null @@ -1 +0,0 @@ -{"web":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","client_secret":"YOUR_CLIENT_SECRET_GOES_HERE","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"13140951618-15nik769cellkubaqnjk5facdib2dh4d@developer.gserviceaccount.com","redirect_uris":["https://localhost:5000/callback","http://localhost:5000/callback"],"client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/13140951618-15nik769cellkubaqnjk5facdib2dh4d@developer.gserviceaccount.com","client_id":"YOUR_CLIENT_ID_GOES_HERE.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","javascript_origins":["http://localhost","https://udacity-oauth.herokuapp.com","http://udacity-oauth.herokuapp.com","http://localhost:5000"]}} diff --git a/Lesson4/step2/database_setup.py b/Lesson4/step2/database_setup.py index f49c971..51c620b 100644 --- a/Lesson4/step2/database_setup.py +++ b/Lesson4/step2/database_setup.py @@ -1,7 +1,7 @@ from sqlalchemy import Column, ForeignKey, Integer, String +from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship -from sqlalchemy import create_engine Base = declarative_base() @@ -59,5 +59,4 @@ def serialize(self): engine = create_engine('sqlite:///restaurantmenuwithusers.db') - Base.metadata.create_all(engine) diff --git a/Lesson4/step2/fb_client_secrets.json b/Lesson4/step2/fb_client_secrets.json deleted file mode 100644 index bff14f0..0000000 --- a/Lesson4/step2/fb_client_secrets.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "web": { - "app_id": "PASTE_YOUR_APP_ID_HERE", - "app_secret": "PASTE_YOUR_CLIENT_SECRET_HERE" - } -} diff --git a/Lesson4/step2/lotsofmenus.py b/Lesson4/step2/lotsofmenus.py index cbfbe51..60ffc4c 100644 --- a/Lesson4/step2/lotsofmenus.py +++ b/Lesson4/step2/lotsofmenus.py @@ -1,9 +1,7 @@ -from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from database_setup import Restaurant, Base, MenuItem, User +from database_setup import Restaurant, Base, MenuItem, User, engine -engine = create_engine('sqlite:///restaurantmenuwithusers.db') # Bind the engine to the metadata of the Base class so that the # declaratives can be accessed through a DBSession instance Base.metadata.bind = engine @@ -18,7 +16,6 @@ # session.rollback() session = DBSession() - # Create dummy user User1 = User(name="Robo Barista", email="tinnyTim@udacity.com", picture='https://pbs.twimg.com/profile_images/2671170543/18debd694829ed78203a5a36dd364160_400x400.png') @@ -31,20 +28,21 @@ session.add(restaurant1) session.commit() -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", + description="Juicy grilled veggie patty with tomato mayo and lettuce", price="$7.50", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() - menuItem1 = MenuItem(user_id=1, name="French Fries", description="with garlic and parmesan", price="$2.99", course="Appetizer", restaurant=restaurant1) session.add(menuItem1) session.commit() -menuItem2 = MenuItem(user_id=1, name="Chicken Burger", description="Juicy grilled chicken patty with tomato mayo and lettuce", +menuItem2 = MenuItem(user_id=1, name="Chicken Burger", + description="Juicy grilled chicken patty with tomato mayo and lettuce", price="$5.50", course="Entree", restaurant=restaurant1) session.add(menuItem2) @@ -75,108 +73,116 @@ session.commit() menuItem7 = MenuItem(user_id=1, name="Grilled Cheese Sandwich", - description="On texas toast with American Cheese", price="$3.49", course="Entree", restaurant=restaurant1) + description="On texas toast with American Cheese", price="$3.49", course="Entree", + restaurant=restaurant1) session.add(menuItem7) session.commit() -menuItem8 = MenuItem(user_id=1, name="Veggie Burger", description="Made with freshest of ingredients and home grown spices", +menuItem8 = MenuItem(user_id=1, name="Veggie Burger", + description="Made with freshest of ingredients and home grown spices", price="$5.99", course="Entree", restaurant=restaurant1) session.add(menuItem8) session.commit() - # Menu for Super Stir Fry restaurant2 = Restaurant(user_id=1, name="Super Stir Fry") session.add(restaurant2) session.commit() - -menuItem1 = MenuItem(user_id=1, name="Chicken Stir Fry", description="With your choice of noodles vegetables and sauces", +menuItem1 = MenuItem(user_id=1, name="Chicken Stir Fry", + description="With your choice of noodles vegetables and sauces", price="$7.99", course="Entree", restaurant=restaurant2) session.add(menuItem1) session.commit() menuItem2 = MenuItem(user_id=1, name="Peking Duck", - description=" A famous duck dish from Beijing[1] that has been prepared since the imperial era. The meat is prized for its thin, crisp skin, with authentic versions of the dish serving mostly the skin and little meat, sliced in front of the diners by the cook", price="$25", course="Entree", restaurant=restaurant2) + description=" A famous duck dish from Beijing[1] that has been prepared since the imperial era. The meat is prized for its thin, crisp skin, with authentic versions of the dish serving mostly the skin and little meat, sliced in front of the diners by the cook", + price="$25", course="Entree", restaurant=restaurant2) session.add(menuItem2) session.commit() -menuItem3 = MenuItem(user_id=1, name="Spicy Tuna Roll", description="Seared rare ahi, avocado, edamame, cucumber with wasabi soy sauce ", +menuItem3 = MenuItem(user_id=1, name="Spicy Tuna Roll", + description="Seared rare ahi, avocado, edamame, cucumber with wasabi soy sauce ", price="15", course="Entree", restaurant=restaurant2) session.add(menuItem3) session.commit() -menuItem4 = MenuItem(user_id=1, name="Nepali Momo ", description="Steamed dumplings made with vegetables, spices and meat. ", +menuItem4 = MenuItem(user_id=1, name="Nepali Momo ", + description="Steamed dumplings made with vegetables, spices and meat. ", price="12", course="Entree", restaurant=restaurant2) session.add(menuItem4) session.commit() -menuItem5 = MenuItem(user_id=1, name="Beef Noodle Soup", description="A Chinese noodle soup made of stewed or red braised beef, beef broth, vegetables and Chinese noodles.", +menuItem5 = MenuItem(user_id=1, name="Beef Noodle Soup", + description="A Chinese noodle soup made of stewed or red braised beef, beef broth, vegetables and Chinese noodles.", price="14", course="Entree", restaurant=restaurant2) session.add(menuItem5) session.commit() -menuItem6 = MenuItem(user_id=1, name="Ramen", description="a Japanese noodle soup dish. It consists of Chinese-style wheat noodles served in a meat- or (occasionally) fish-based broth, often flavored with soy sauce or miso, and uses toppings such as sliced pork, dried seaweed, kamaboko, and green onions.", +menuItem6 = MenuItem(user_id=1, name="Ramen", + description="a Japanese noodle soup dish. It consists of Chinese-style wheat noodles served in a meat- or (occasionally) fish-based broth, often flavored with soy sauce or miso, and uses toppings such as sliced pork, dried seaweed, kamaboko, and green onions.", price="12", course="Entree", restaurant=restaurant2) session.add(menuItem6) session.commit() - # Menu for Panda Garden restaurant1 = Restaurant(user_id=1, name="Panda Garden") session.add(restaurant1) session.commit() - -menuItem1 = MenuItem(user_id=1, name="Pho", description="a Vietnamese noodle soup consisting of broth, linguine-shaped rice noodles called banh pho, a few herbs, and meat.", +menuItem1 = MenuItem(user_id=1, name="Pho", + description="a Vietnamese noodle soup consisting of broth, linguine-shaped rice noodles called banh pho, a few herbs, and meat.", price="$8.99", course="Entree", restaurant=restaurant1) session.add(menuItem1) session.commit() -menuItem2 = MenuItem(user_id=1, name="Chinese Dumplings", description="a common Chinese dumpling which generally consists of minced meat and finely chopped vegetables wrapped into a piece of dough skin. The skin can be either thin and elastic or thicker.", +menuItem2 = MenuItem(user_id=1, name="Chinese Dumplings", + description="a common Chinese dumpling which generally consists of minced meat and finely chopped vegetables wrapped into a piece of dough skin. The skin can be either thin and elastic or thicker.", price="$6.99", course="Appetizer", restaurant=restaurant1) session.add(menuItem2) session.commit() -menuItem3 = MenuItem(user_id=1, name="Gyoza", description="light seasoning of Japanese gyoza with salt and soy sauce, and in a thin gyoza wrapper", +menuItem3 = MenuItem(user_id=1, name="Gyoza", + description="light seasoning of Japanese gyoza with salt and soy sauce, and in a thin gyoza wrapper", price="$9.95", course="Entree", restaurant=restaurant1) session.add(menuItem3) session.commit() -menuItem4 = MenuItem(user_id=1, name="Stinky Tofu", description="Taiwanese dish, deep fried fermented tofu served with pickled cabbage.", +menuItem4 = MenuItem(user_id=1, name="Stinky Tofu", + description="Taiwanese dish, deep fried fermented tofu served with pickled cabbage.", price="$6.99", course="Entree", restaurant=restaurant1) session.add(menuItem4) session.commit() -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", + description="Juicy grilled veggie patty with tomato mayo and lettuce", price="$9.50", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() - # Menu for Thyme for that restaurant1 = Restaurant(user_id=1, name="Thyme for That Vegetarian Cuisine ") session.add(restaurant1) session.commit() - -menuItem1 = MenuItem(user_id=1, name="Tres Leches Cake", description="Rich, luscious sponge cake soaked in sweet milk and topped with vanilla bean whipped cream and strawberries.", +menuItem1 = MenuItem(user_id=1, name="Tres Leches Cake", + description="Rich, luscious sponge cake soaked in sweet milk and topped with vanilla bean whipped cream and strawberries.", price="$2.99", course="Dessert", restaurant=restaurant1) session.add(menuItem1) @@ -189,38 +195,41 @@ session.commit() menuItem3 = MenuItem(user_id=1, name="Honey Boba Shaved Snow", - description="Milk snow layered with honey boba, jasmine tea jelly, grass jelly, caramel, cream, and freshly made mochi", price="$4.50", course="Dessert", restaurant=restaurant1) + description="Milk snow layered with honey boba, jasmine tea jelly, grass jelly, caramel, cream, and freshly made mochi", + price="$4.50", course="Dessert", restaurant=restaurant1) session.add(menuItem3) session.commit() -menuItem4 = MenuItem(user_id=1, name="Cauliflower Manchurian", description="Golden fried cauliflower florets in a midly spiced soya,garlic sauce cooked with fresh cilantro, celery, chilies,ginger & green onions", +menuItem4 = MenuItem(user_id=1, name="Cauliflower Manchurian", + description="Golden fried cauliflower florets in a midly spiced soya,garlic sauce cooked with fresh cilantro, celery, chilies,ginger & green onions", price="$6.95", course="Appetizer", restaurant=restaurant1) session.add(menuItem4) session.commit() -menuItem5 = MenuItem(user_id=1, name="Aloo Gobi Burrito", description="Vegan goodness. Burrito filled with rice, garbanzo beans, curry sauce, potatoes (aloo), fried cauliflower (gobi) and chutney. Nom Nom", +menuItem5 = MenuItem(user_id=1, name="Aloo Gobi Burrito", + description="Vegan goodness. Burrito filled with rice, garbanzo beans, curry sauce, potatoes (aloo), fried cauliflower (gobi) and chutney. Nom Nom", price="$7.95", course="Entree", restaurant=restaurant1) session.add(menuItem5) session.commit() -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", + description="Juicy grilled veggie patty with tomato mayo and lettuce", price="$6.80", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() - # Menu for Tony's Bistro restaurant1 = Restaurant(user_id=1, name="Tony\'s Bistro ") session.add(restaurant1) session.commit() - -menuItem1 = MenuItem(user_id=1, name="Shellfish Tower", description="Lobster, shrimp, sea snails, crawfish, stacked into a delicious tower", +menuItem1 = MenuItem(user_id=1, name="Shellfish Tower", + description="Lobster, shrimp, sea snails, crawfish, stacked into a delicious tower", price="$13.95", course="Entree", restaurant=restaurant1) session.add(menuItem1) @@ -232,45 +241,49 @@ session.add(menuItem2) session.commit() -menuItem3 = MenuItem(user_id=1, name="Mom's Spaghetti", description="Spaghetti with some incredible tomato sauce made by mom", +menuItem3 = MenuItem(user_id=1, name="Mom's Spaghetti", + description="Spaghetti with some incredible tomato sauce made by mom", price="$6.95", course="Entree", restaurant=restaurant1) session.add(menuItem3) session.commit() menuItem4 = MenuItem(user_id=1, name="Choc Full O\' Mint (Smitten\'s Fresh Mint Chip ice cream)", - description="Milk, cream, salt, ..., Liquid nitrogen magic", price="$3.95", course="Dessert", restaurant=restaurant1) + description="Milk, cream, salt, ..., Liquid nitrogen magic", price="$3.95", course="Dessert", + restaurant=restaurant1) session.add(menuItem4) session.commit() -menuItem5 = MenuItem(user_id=1, name="Tonkatsu Ramen", description="Noodles in a delicious pork-based broth with a soft-boiled egg", +menuItem5 = MenuItem(user_id=1, name="Tonkatsu Ramen", + description="Noodles in a delicious pork-based broth with a soft-boiled egg", price="$7.95", course="Entree", restaurant=restaurant1) session.add(menuItem5) session.commit() - # Menu for Andala's restaurant1 = Restaurant(user_id=1, name="Andala\'s") session.add(restaurant1) session.commit() - -menuItem1 = MenuItem(user_id=1, name="Lamb Curry", description="Slow cook that thang in a pool of tomatoes, onions and alllll those tasty Indian spices. Mmmm.", +menuItem1 = MenuItem(user_id=1, name="Lamb Curry", + description="Slow cook that thang in a pool of tomatoes, onions and alllll those tasty Indian spices. Mmmm.", price="$9.95", course="Entree", restaurant=restaurant1) session.add(menuItem1) session.commit() -menuItem2 = MenuItem(user_id=1, name="Chicken Marsala", description="Chicken cooked in Marsala wine sauce with mushrooms", +menuItem2 = MenuItem(user_id=1, name="Chicken Marsala", + description="Chicken cooked in Marsala wine sauce with mushrooms", price="$7.95", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() -menuItem3 = MenuItem(user_id=1, name="Potstickers", description="Delicious chicken and veggies encapsulated in fried dough.", +menuItem3 = MenuItem(user_id=1, name="Potstickers", + description="Delicious chicken and veggies encapsulated in fried dough.", price="$6.50", course="Appetizer", restaurant=restaurant1) session.add(menuItem3) @@ -282,13 +295,13 @@ session.add(menuItem4) session.commit() -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", + description="Juicy grilled veggie patty with tomato mayo and lettuce", price="$7.00", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() - # Menu for Auntie Ann's restaurant1 = Restaurant(user_id=1, name="Auntie Ann\'s Diner' ") @@ -296,91 +309,97 @@ session.commit() menuItem9 = MenuItem(user_id=1, name="Chicken Fried Steak", - description="Fresh battered sirloin steak fried and smothered with cream gravy", price="$8.99", course="Entree", restaurant=restaurant1) + description="Fresh battered sirloin steak fried and smothered with cream gravy", price="$8.99", + course="Entree", restaurant=restaurant1) session.add(menuItem9) session.commit() - -menuItem1 = MenuItem(user_id=1, name="Boysenberry Sorbet", description="An unsettlingly huge amount of ripe berries turned into frozen (and seedless) awesomeness", +menuItem1 = MenuItem(user_id=1, name="Boysenberry Sorbet", + description="An unsettlingly huge amount of ripe berries turned into frozen (and seedless) awesomeness", price="$2.99", course="Dessert", restaurant=restaurant1) session.add(menuItem1) session.commit() -menuItem2 = MenuItem(user_id=1, name="Broiled salmon", description="Salmon fillet marinated with fresh herbs and broiled hot & fast", +menuItem2 = MenuItem(user_id=1, name="Broiled salmon", + description="Salmon fillet marinated with fresh herbs and broiled hot & fast", price="$10.95", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() menuItem3 = MenuItem(user_id=1, name="Morels on toast (seasonal)", - description="Wild morel mushrooms fried in butter, served on herbed toast slices", price="$7.50", course="Appetizer", restaurant=restaurant1) + description="Wild morel mushrooms fried in butter, served on herbed toast slices", price="$7.50", + course="Appetizer", restaurant=restaurant1) session.add(menuItem3) session.commit() -menuItem4 = MenuItem(user_id=1, name="Tandoori Chicken", description="Chicken marinated in yoghurt and seasoned with a spicy mix(chilli, tamarind among others) and slow cooked in a cylindrical clay or metal oven which gets its heat from burning charcoal.", +menuItem4 = MenuItem(user_id=1, name="Tandoori Chicken", + description="Chicken marinated in yoghurt and seasoned with a spicy mix(chilli, tamarind among others) and slow cooked in a cylindrical clay or metal oven which gets its heat from burning charcoal.", price="$8.95", course="Entree", restaurant=restaurant1) session.add(menuItem4) session.commit() -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", +menuItem2 = MenuItem(user_id=1, name="Veggie Burger", + description="Juicy grilled veggie patty with tomato mayo and lettuce", price="$9.50", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() -menuItem10 = MenuItem(user_id=1, name="Spinach Ice Cream", description="vanilla ice cream made with organic spinach leaves", +menuItem10 = MenuItem(user_id=1, name="Spinach Ice Cream", + description="vanilla ice cream made with organic spinach leaves", price="$1.99", course="Dessert", restaurant=restaurant1) session.add(menuItem10) session.commit() - # Menu for Cocina Y Amor restaurant1 = Restaurant(user_id=1, name="Cocina Y Amor ") session.add(restaurant1) session.commit() - menuItem1 = MenuItem(user_id=1, name="Super Burrito Al Pastor", - description="Marinated Pork, Rice, Beans, Avocado, Cilantro, Salsa, Tortilla", price="$5.95", course="Entree", restaurant=restaurant1) + description="Marinated Pork, Rice, Beans, Avocado, Cilantro, Salsa, Tortilla", price="$5.95", + course="Entree", restaurant=restaurant1) session.add(menuItem1) session.commit() -menuItem2 = MenuItem(user_id=1, name="Cachapa", description="Golden brown, corn-based Venezuelan pancake; usually stuffed with queso telita or queso de mano, and possibly lechon. ", +menuItem2 = MenuItem(user_id=1, name="Cachapa", + description="Golden brown, corn-based Venezuelan pancake; usually stuffed with queso telita or queso de mano, and possibly lechon. ", price="$7.99", course="Entree", restaurant=restaurant1) session.add(menuItem2) session.commit() - restaurant1 = Restaurant(user_id=1, name="State Bird Provisions") session.add(restaurant1) session.commit() -menuItem1 = MenuItem(user_id=1, name="Chantrelle Toast", description="Crispy Toast with Sesame Seeds slathered with buttery chantrelle mushrooms", +menuItem1 = MenuItem(user_id=1, name="Chantrelle Toast", + description="Crispy Toast with Sesame Seeds slathered with buttery chantrelle mushrooms", price="$5.95", course="Appetizer", restaurant=restaurant1) session.add(menuItem1) session.commit menuItem1 = MenuItem(user_id=1, name="Guanciale Chawanmushi", - description="Japanese egg custard served hot with spicey Italian Pork Jowl (guanciale)", price="$6.95", course="Dessert", restaurant=restaurant1) + description="Japanese egg custard served hot with spicey Italian Pork Jowl (guanciale)", + price="$6.95", course="Dessert", restaurant=restaurant1) session.add(menuItem1) session.commit() - menuItem1 = MenuItem(user_id=1, name="Lemon Curd Ice Cream Sandwich", - description="Lemon Curd Ice Cream Sandwich on a chocolate macaron with cardamom meringue and cashews", price="$4.25", course="Dessert", restaurant=restaurant1) + description="Lemon Curd Ice Cream Sandwich on a chocolate macaron with cardamom meringue and cashews", + price="$4.25", course="Dessert", restaurant=restaurant1) session.add(menuItem1) session.commit() - print("added menu items!") diff --git a/Lesson4/step2/lotsofmenus.py.bak b/Lesson4/step2/lotsofmenus.py.bak deleted file mode 100644 index 3e4460a..0000000 --- a/Lesson4/step2/lotsofmenus.py.bak +++ /dev/null @@ -1,386 +0,0 @@ -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker - -from database_setup import Restaurant, Base, MenuItem, User - -engine = create_engine('sqlite:///restaurantmenuwithusers.db') -# Bind the engine to the metadata of the Base class so that the -# declaratives can be accessed through a DBSession instance -Base.metadata.bind = engine - -DBSession = sessionmaker(bind=engine) -# A DBSession() instance establishes all conversations with the database -# and represents a "staging zone" for all the objects loaded into the -# database session object. Any change made against the objects in the -# session won't be persisted into the database until you call -# session.commit(). If you're not happy about the changes, you can -# revert all of them back to the last commit by calling -# session.rollback() -session = DBSession() - - -# Create dummy user -User1 = User(name="Robo Barista", email="tinnyTim@udacity.com", - picture='https://pbs.twimg.com/profile_images/2671170543/18debd694829ed78203a5a36dd364160_400x400.png') -session.add(User1) -session.commit() - -# Menu for UrbanBurger -restaurant1 = Restaurant(user_id=1, name="Urban Burger") - -session.add(restaurant1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$7.50", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="French Fries", description="with garlic and parmesan", - price="$2.99", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chicken Burger", description="Juicy grilled chicken patty with tomato mayo and lettuce", - price="$5.50", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Chocolate Cake", description="fresh baked and served with ice cream", - price="$3.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Sirloin Burger", description="Made with grade A beef", - price="$7.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem(user_id=1, name="Root Beer", description="16oz of refreshing goodness", - price="$1.99", course="Beverage", restaurant=restaurant1) - -session.add(menuItem5) -session.commit() - -menuItem6 = MenuItem(user_id=1, name="Iced Tea", description="with Lemon", - price="$.99", course="Beverage", restaurant=restaurant1) - -session.add(menuItem6) -session.commit() - -menuItem7 = MenuItem(user_id=1, name="Grilled Cheese Sandwich", - description="On texas toast with American Cheese", price="$3.49", course="Entree", restaurant=restaurant1) - -session.add(menuItem7) -session.commit() - -menuItem8 = MenuItem(user_id=1, name="Veggie Burger", description="Made with freshest of ingredients and home grown spices", - price="$5.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem8) -session.commit() - - -# Menu for Super Stir Fry -restaurant2 = Restaurant(user_id=1, name="Super Stir Fry") - -session.add(restaurant2) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Chicken Stir Fry", description="With your choice of noodles vegetables and sauces", - price="$7.99", course="Entree", restaurant=restaurant2) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Peking Duck", - description=" A famous duck dish from Beijing[1] that has been prepared since the imperial era. The meat is prized for its thin, crisp skin, with authentic versions of the dish serving mostly the skin and little meat, sliced in front of the diners by the cook", price="$25", course="Entree", restaurant=restaurant2) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Spicy Tuna Roll", description="Seared rare ahi, avocado, edamame, cucumber with wasabi soy sauce ", - price="15", course="Entree", restaurant=restaurant2) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Nepali Momo ", description="Steamed dumplings made with vegetables, spices and meat. ", - price="12", course="Entree", restaurant=restaurant2) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem(user_id=1, name="Beef Noodle Soup", description="A Chinese noodle soup made of stewed or red braised beef, beef broth, vegetables and Chinese noodles.", - price="14", course="Entree", restaurant=restaurant2) - -session.add(menuItem5) -session.commit() - -menuItem6 = MenuItem(user_id=1, name="Ramen", description="a Japanese noodle soup dish. It consists of Chinese-style wheat noodles served in a meat- or (occasionally) fish-based broth, often flavored with soy sauce or miso, and uses toppings such as sliced pork, dried seaweed, kamaboko, and green onions.", - price="12", course="Entree", restaurant=restaurant2) - -session.add(menuItem6) -session.commit() - - -# Menu for Panda Garden -restaurant1 = Restaurant(user_id=1, name="Panda Garden") - -session.add(restaurant1) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Pho", description="a Vietnamese noodle soup consisting of broth, linguine-shaped rice noodles called banh pho, a few herbs, and meat.", - price="$8.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chinese Dumplings", description="a common Chinese dumpling which generally consists of minced meat and finely chopped vegetables wrapped into a piece of dough skin. The skin can be either thin and elastic or thicker.", - price="$6.99", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Gyoza", description="light seasoning of Japanese gyoza with salt and soy sauce, and in a thin gyoza wrapper", - price="$9.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Stinky Tofu", description="Taiwanese dish, deep fried fermented tofu served with pickled cabbage.", - price="$6.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$9.50", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - - -# Menu for Thyme for that -restaurant1 = Restaurant(user_id=1, name="Thyme for That Vegetarian Cuisine ") - -session.add(restaurant1) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Tres Leches Cake", description="Rich, luscious sponge cake soaked in sweet milk and topped with vanilla bean whipped cream and strawberries.", - price="$2.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Mushroom risotto", description="Portabello mushrooms in a creamy risotto", - price="$5.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Honey Boba Shaved Snow", - description="Milk snow layered with honey boba, jasmine tea jelly, grass jelly, caramel, cream, and freshly made mochi", price="$4.50", course="Dessert", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Cauliflower Manchurian", description="Golden fried cauliflower florets in a midly spiced soya,garlic sauce cooked with fresh cilantro, celery, chilies,ginger & green onions", - price="$6.95", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem(user_id=1, name="Aloo Gobi Burrito", description="Vegan goodness. Burrito filled with rice, garbanzo beans, curry sauce, potatoes (aloo), fried cauliflower (gobi) and chutney. Nom Nom", - price="$7.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem5) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$6.80", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - - -# Menu for Tony's Bistro -restaurant1 = Restaurant(user_id=1, name="Tony\'s Bistro ") - -session.add(restaurant1) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Shellfish Tower", description="Lobster, shrimp, sea snails, crawfish, stacked into a delicious tower", - price="$13.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chicken and Rice", description="Chicken... and rice", - price="$4.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Mom's Spaghetti", description="Spaghetti with some incredible tomato sauce made by mom", - price="$6.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Choc Full O\' Mint (Smitten\'s Fresh Mint Chip ice cream)", - description="Milk, cream, salt, ..., Liquid nitrogen magic", price="$3.95", course="Dessert", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem(user_id=1, name="Tonkatsu Ramen", description="Noodles in a delicious pork-based broth with a soft-boiled egg", - price="$7.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem5) -session.commit() - - -# Menu for Andala's -restaurant1 = Restaurant(user_id=1, name="Andala\'s") - -session.add(restaurant1) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Lamb Curry", description="Slow cook that thang in a pool of tomatoes, onions and alllll those tasty Indian spices. Mmmm.", - price="$9.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chicken Marsala", description="Chicken cooked in Marsala wine sauce with mushrooms", - price="$7.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Potstickers", description="Delicious chicken and veggies encapsulated in fried dough.", - price="$6.50", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Nigiri Sampler", description="Maguro, Sake, Hamachi, Unagi, Uni, TORO!", - price="$6.75", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$7.00", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - - -# Menu for Auntie Ann's -restaurant1 = Restaurant(user_id=1, name="Auntie Ann\'s Diner' ") - -session.add(restaurant1) -session.commit() - -menuItem9 = MenuItem(user_id=1, name="Chicken Fried Steak", - description="Fresh battered sirloin steak fried and smothered with cream gravy", price="$8.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem9) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Boysenberry Sorbet", description="An unsettlingly huge amount of ripe berries turned into frozen (and seedless) awesomeness", - price="$2.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Broiled salmon", description="Salmon fillet marinated with fresh herbs and broiled hot & fast", - price="$10.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Morels on toast (seasonal)", - description="Wild morel mushrooms fried in butter, served on herbed toast slices", price="$7.50", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Tandoori Chicken", description="Chicken marinated in yoghurt and seasoned with a spicy mix(chilli, tamarind among others) and slow cooked in a cylindrical clay or metal oven which gets its heat from burning charcoal.", - price="$8.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$9.50", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem10 = MenuItem(user_id=1, name="Spinach Ice Cream", description="vanilla ice cream made with organic spinach leaves", - price="$1.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem10) -session.commit() - - -# Menu for Cocina Y Amor -restaurant1 = Restaurant(user_id=1, name="Cocina Y Amor ") - -session.add(restaurant1) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Super Burrito Al Pastor", - description="Marinated Pork, Rice, Beans, Avocado, Cilantro, Salsa, Tortilla", price="$5.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Cachapa", description="Golden brown, corn-based Venezuelan pancake; usually stuffed with queso telita or queso de mano, and possibly lechon. ", - price="$7.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - - -restaurant1 = Restaurant(user_id=1, name="State Bird Provisions") -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Chantrelle Toast", description="Crispy Toast with Sesame Seeds slathered with buttery chantrelle mushrooms", - price="$5.95", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem1) -session.commit - -menuItem1 = MenuItem(user_id=1, name="Guanciale Chawanmushi", - description="Japanese egg custard served hot with spicey Italian Pork Jowl (guanciale)", price="$6.95", course="Dessert", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - - -menuItem1 = MenuItem(user_id=1, name="Lemon Curd Ice Cream Sandwich", - description="Lemon Curd Ice Cream Sandwich on a chocolate macaron with cardamom meringue and cashews", price="$4.25", course="Dessert", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - - -print "added menu items!" diff --git a/Lesson4/step2/project.py b/Lesson4/step2/project.py index be52ee4..689a36b 100644 --- a/Lesson4/step2/project.py +++ b/Lesson4/step2/project.py @@ -1,26 +1,29 @@ -from flask import Flask, render_template, request, redirect, jsonify, url_for, flash -from sqlalchemy import create_engine, asc -from sqlalchemy.orm import sessionmaker -from database_setup import Base, Restaurant, MenuItem, User -from flask import session as login_session +import json import random import string -from oauth2client.client import flow_from_clientsecrets -from oauth2client.client import FlowExchangeError + import httplib2 -import json -from flask import make_response import requests +from flask import Flask, render_template, request, \ + redirect, jsonify, url_for, flash, make_response, \ + session as login_session +from oauth2client.client import FlowExchangeError, OAuth2WebServerFlow +from sqlalchemy import asc +from sqlalchemy.orm import sessionmaker + +from database_setup import Base, Restaurant, MenuItem, User, engine +from variables import facebook_web, google_web, main_app + +state = ''.join(random.choice(string.ascii_uppercase + string.digits) + for x in range(32)) app = Flask(__name__) +app.secret_key = state -CLIENT_ID = json.loads( - open('client_secrets.json', 'r').read())['web']['client_id'] +GOOGLE_CLIENT_ID = google_web.get('client_id') APPLICATION_NAME = "Restaurant Menu Application" - # Connect to Database and create database session -engine = create_engine('sqlite:///restaurantmenuwithusers.db') Base.metadata.bind = engine DBSession = sessionmaker(bind=engine) @@ -29,12 +32,10 @@ # Create anti-forgery state token @app.route('/login') -def showLogin(): - state = ''.join(random.choice(string.ascii_uppercase + string.digits) - for x in range(32)) +def show_login(): login_session['state'] = state # return "The current session state is %s" % login_session['state'] - return render_template('login.html', STATE=state) + return render_template('login.html', STATE=login_session['state'], google_web=google_web, facebook_web=facebook_web) @app.route('/fbconnect', methods=['POST']) @@ -44,21 +45,16 @@ def fbconnect(): response.headers['Content-Type'] = 'application/json' return response access_token = request.data - print("access token received %s " % access_token) - - app_id = json.loads(open('fb_client_secrets.json', 'r').read())[ - 'web']['app_id'] - app_secret = json.loads( - open('fb_client_secrets.json', 'r').read())['web']['app_secret'] - url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=%s&client_secret=%s&fb_exchange_token=%s' % ( - app_id, app_secret, access_token) + app_id = facebook_web.get('app_id') + app_secret = facebook_web.get('app_secret') + url = 'https://graph.facebook.com/oauth/access_token?' \ + 'grant_type=fb_exchange_token&client_id=%s&client_secret=%s&fb_exchange_token=%s' % ( + app_id, app_secret, str(access_token).split("'")[1]) h = httplib2.Http() result = h.request(url, 'GET')[1] - # Use token to get user info from API - userinfo_url = "https://graph.facebook.com/v2.8/me" ''' Due to the formatting for the result from the server token exchange we have to split the token first on commas and select the first index which gives us the key : value @@ -66,13 +62,13 @@ def fbconnect(): and replace the remaining quotes with nothing so that it can be used directly in the graph api calls ''' - token = result.split(',')[0].split(':')[1].replace('"', '') + str_result = str(result) + token = str_result.split(',')[0].split(':')[1].replace('"', '') url = 'https://graph.facebook.com/v2.8/me?access_token=%s&fields=name,id,email' % token h = httplib2.Http() result = h.request(url, 'GET')[1] - # print "url sent for API access:%s"% url - # print "API JSON result: %s" % result + data = json.loads(result) login_session['provider'] = 'facebook' login_session['username'] = data["name"] @@ -91,9 +87,9 @@ def fbconnect(): login_session['picture'] = data["data"]["url"] # see if user exists - user_id = getUserID(login_session['email']) + user_id = get_user_id(login_session['email']) if not user_id: - user_id = createUser(login_session) + user_id = create_user(login_session) login_session['user_id'] = user_id output = '' @@ -103,7 +99,8 @@ def fbconnect(): output += '!' output += ' ' + output += ' " style = "width: 300px; height: 300px;border-radius: ' \ + '150px;-webkit-border-radius: 150px;-moz-border-radius: 150px;"> ' flash("Now logged in as %s" % login_session['username']) return output @@ -114,7 +111,7 @@ def fbdisconnect(): facebook_id = login_session['facebook_id'] # The access token must me included to successfully logout access_token = login_session['access_token'] - url = 'https://graph.facebook.com/%s/permissions?access_token=%s' % (facebook_id,access_token) + url = 'https://graph.facebook.com/%s/permissions?access_token=%s' % (facebook_id, access_token) h = httplib2.Http() result = h.request(url, 'DELETE')[1] return "you have been logged out" @@ -132,8 +129,10 @@ def gconnect(): try: # Upgrade the authorization code into a credentials object - oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='') - oauth_flow.redirect_uri = 'postmessage' + oauth_flow = OAuth2WebServerFlow( + redirect_uri='postmessage', + **google_web + ) credentials = oauth_flow.step2_exchange(code) except FlowExchangeError: response = make_response( @@ -162,18 +161,9 @@ def gconnect(): return response # Verify that the access token is valid for this app. - if result['issued_to'] != CLIENT_ID: + if result['issued_to'] != GOOGLE_CLIENT_ID: response = make_response( json.dumps("Token's client ID does not match app's."), 401) - print("Token's client ID does not match app's.") - response.headers['Content-Type'] = 'application/json' - return response - - stored_access_token = login_session.get('access_token') - stored_gplus_id = login_session.get('gplus_id') - if stored_access_token is not None and gplus_id == stored_gplus_id: - response = make_response(json.dumps('Current user is already connected.'), - 200) response.headers['Content-Type'] = 'application/json' return response @@ -195,9 +185,9 @@ def gconnect(): login_session['provider'] = 'google' # see if user exists, if it doesn't make a new one - user_id = getUserID(data["email"]) + user_id = get_user_id(data["email"]) if not user_id: - user_id = createUser(login_session) + user_id = create_user(login_session) login_session['user_id'] = user_id output = '' @@ -206,35 +196,37 @@ def gconnect(): output += '!' output += ' ' + output += ' " style = "width: 300px; height: 300px;border-radius: 150px;' \ + '-webkit-border-radius: 150px;-moz-border-radius: 150px;"> ' flash("you are now logged in as %s" % login_session['username']) - print("done!") return output + # User Helper Functions -def createUser(login_session): - newUser = User(name=login_session['username'], email=login_session[ - 'email'], picture=login_session['picture']) - session.add(newUser) +def create_user(login_session_dict): + new_user = User(name=login_session_dict['username'], email=login_session_dict[ + 'email'], picture=login_session_dict['picture']) + session.add(new_user) session.commit() - user = session.query(User).filter_by(email=login_session['email']).one() + user = session.query(User).filter_by(email=login_session_dict['email']).one() return user.id -def getUserInfo(user_id): +def get_user_info(user_id): user = session.query(User).filter_by(id=user_id).one() return user -def getUserID(email): +def get_user_id(email): try: user = session.query(User).filter_by(email=email).one() return user.id except: return None + # DISCONNECT - Revoke a current user's token and reset their login_session @@ -251,37 +243,39 @@ def gdisconnect(): h = httplib2.Http() result = h.request(url, 'GET')[0] if result['status'] == '200': - del login_session['access_token'] - del login_session['gplus_id'] - del login_session['username'] - del login_session['email'] - del login_session['picture'] - response = make_response(json.dumps('Successfully disconnected.'), 200) + remove_session() + response = make_response(json.dumps('Successfully disconnected.')) response.headers['Content-Type'] = 'application/json' return response else: - response = make_response(json.dumps('Failed to revoke token for given user.', 400)) + response = make_response(json.dumps('Failed to revoke token for given user.')) response.headers['Content-Type'] = 'application/json' return response +def remove_session(): + # the dictionary needs to be copied to avoid a runtime error + sess = login_session.copy() + for (key, value) in sess.items(): + del login_session[key] + + # JSON APIs to view Restaurant Information @app.route('/restaurant//menu/JSON') -def restaurantMenuJSON(restaurant_id): - restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() +def restaurant_menu_json(restaurant_id): items = session.query(MenuItem).filter_by( restaurant_id=restaurant_id).all() return jsonify(MenuItems=[i.serialize for i in items]) @app.route('/restaurant//menu//JSON') -def menuItemJSON(restaurant_id, menu_id): - Menu_Item = session.query(MenuItem).filter_by(id=menu_id).one() - return jsonify(Menu_Item=Menu_Item.serialize) +def menu_item_json(restaurant_id, menu_id): + menu_item = session.query(MenuItem).filter_by(id=menu_id, restaurant_id=restaurant_id).one() + return jsonify(Menu_Item=menu_item.serialize) @app.route('/restaurant/JSON') -def restaurantsJSON(): +def restaurants_json(): restaurants = session.query(Restaurant).all() return jsonify(restaurants=[r.serialize for r in restaurants]) @@ -289,171 +283,167 @@ def restaurantsJSON(): # Show all restaurants @app.route('/') @app.route('/restaurant/') -def showRestaurants(): +def show_restaurants(): restaurants = session.query(Restaurant).order_by(asc(Restaurant.name)) - if 'username' not in login_session: - return render_template('publicrestaurants.html', restaurants=restaurants) - else: - return render_template('restaurants.html', restaurants=restaurants) + return render_template('restaurants.html', restaurants=restaurants, login_session=login_session) + # Create a new restaurant @app.route('/restaurant/new/', methods=['GET', 'POST']) -def newRestaurant(): +def new_restaurant(): if 'username' not in login_session: return redirect('/login') if request.method == 'POST': - newRestaurant = Restaurant( + new_restaurant_obj = Restaurant( name=request.form['name'], user_id=login_session['user_id']) - session.add(newRestaurant) - flash('New Restaurant %s Successfully Created' % newRestaurant.name) + session.add(new_restaurant_obj) + flash('New Restaurant %s Successfully Created' % new_restaurant_obj.name) session.commit() - return redirect(url_for('showRestaurants')) + return redirect(url_for('show_restaurants')) else: return render_template('newRestaurant.html') + # Edit a restaurant @app.route('/restaurant//edit/', methods=['GET', 'POST']) -def editRestaurant(restaurant_id): - editedRestaurant = session.query( +def edit_restaurant(restaurant_id): + edited_restaurant = session.query( Restaurant).filter_by(id=restaurant_id).one() if 'username' not in login_session: return redirect('/login') - if editedRestaurant.user_id != login_session['user_id']: - return "" + if edited_restaurant.user_id != login_session['user_id']: + return "" if request.method == 'POST': - if request.form['name']: - editedRestaurant.name = request.form['name'] - flash('Restaurant Successfully Edited %s' % editedRestaurant.name) - return redirect(url_for('showRestaurants')) + if request.form['name'] != edited_restaurant.name: + edited_restaurant.name = request.form['name'] + flash('Restaurant Successfully Edited %s' % edited_restaurant.name) + return redirect(url_for('show_restaurants')) else: - return render_template('editRestaurant.html', restaurant=editedRestaurant) + return render_template('editRestaurant.html', restaurant=edited_restaurant) # Delete a restaurant @app.route('/restaurant//delete/', methods=['GET', 'POST']) -def deleteRestaurant(restaurant_id): - restaurantToDelete = session.query( +def delete_restaurant(restaurant_id): + restaurant_to_delete = session.query( Restaurant).filter_by(id=restaurant_id).one() if 'username' not in login_session: return redirect('/login') - if restaurantToDelete.user_id != login_session['user_id']: - return "" + if restaurant_to_delete.user_id != login_session['user_id']: + return "" if request.method == 'POST': - session.delete(restaurantToDelete) - flash('%s Successfully Deleted' % restaurantToDelete.name) + session.delete(restaurant_to_delete) + flash('%s Successfully Deleted' % restaurant_to_delete.name) session.commit() - return redirect(url_for('showRestaurants', restaurant_id=restaurant_id)) + return redirect(url_for('show_restaurants', restaurant_id=restaurant_id)) else: - return render_template('deleteRestaurant.html', restaurant=restaurantToDelete) + return render_template('deleteRestaurant.html', restaurant=restaurant_to_delete) + # Show a restaurant menu @app.route('/restaurant//') @app.route('/restaurant//menu/') -def showMenu(restaurant_id): +def show_menu(restaurant_id): restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - creator = getUserInfo(restaurant.user_id) + creator = get_user_info(restaurant.user_id) items = session.query(MenuItem).filter_by( restaurant_id=restaurant_id).all() - if 'username' not in login_session or creator.id != login_session['user_id']: - return render_template('publicmenu.html', items=items, restaurant=restaurant, creator=creator) - else: - return render_template('menu.html', items=items, restaurant=restaurant, creator=creator) + return render_template('menu.html', items=items, restaurant=restaurant, creator=creator, + login_session=login_session) # Create a new menu item @app.route('/restaurant//menu/new/', methods=['GET', 'POST']) -def newMenuItem(restaurant_id): +def new_menu_item(restaurant_id): if 'username' not in login_session: return redirect('/login') restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() if login_session['user_id'] != restaurant.user_id: - return "" - if request.method == 'POST': - newItem = MenuItem(name=request.form['name'], description=request.form['description'], price=request.form[ - 'price'], course=request.form['course'], restaurant_id=restaurant_id, user_id=restaurant.user_id) - session.add(newItem) - session.commit() - flash('New Menu %s Item Successfully Created' % (newItem.name)) - return redirect(url_for('showMenu', restaurant_id=restaurant_id)) + return "" + if request.method == 'POST': + new_item = MenuItem(name=request.form['name'], description=request.form['description'], price=request.form[ + 'price'], course=request.form['course'], restaurant_id=restaurant_id, user_id=restaurant.user_id) + session.add(new_item) + session.commit() + flash('New Menu %s Item Successfully Created' % new_item.name) + return redirect(url_for('show_menu', restaurant_id=restaurant_id)) else: return render_template('newmenuitem.html', restaurant_id=restaurant_id) + # Edit a menu item @app.route('/restaurant//menu//edit', methods=['GET', 'POST']) -def editMenuItem(restaurant_id, menu_id): +def edit_menu_item(restaurant_id, menu_id): if 'username' not in login_session: return redirect('/login') - editedItem = session.query(MenuItem).filter_by(id=menu_id).one() + edited_item = session.query(MenuItem).filter_by(id=menu_id).one() restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() if login_session['user_id'] != restaurant.user_id: - return "" + return "" if request.method == 'POST': - if request.form['name']: - editedItem.name = request.form['name'] - if request.form['description']: - editedItem.description = request.form['description'] - if request.form['price']: - editedItem.price = request.form['price'] - if request.form['course']: - editedItem.course = request.form['course'] - session.add(editedItem) + for (key, value) in request.form.items(): + setattr(edited_item, key, value) + session.add(edited_item) session.commit() flash('Menu Item Successfully Edited') - return redirect(url_for('showMenu', restaurant_id=restaurant_id)) + return redirect(url_for('show_menu', restaurant_id=restaurant_id)) else: - return render_template('editmenuitem.html', restaurant_id=restaurant_id, menu_id=menu_id, item=editedItem) + return render_template('editmenuitem.html', restaurant_id=restaurant_id, menu_id=menu_id, item=edited_item) # Delete a menu item @app.route('/restaurant//menu//delete', methods=['GET', 'POST']) -def deleteMenuItem(restaurant_id, menu_id): +def delete_menu_item(restaurant_id, menu_id): if 'username' not in login_session: return redirect('/login') restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - itemToDelete = session.query(MenuItem).filter_by(id=menu_id).one() + item_to_delete = session.query(MenuItem).filter_by(id=menu_id).one() if login_session['user_id'] != restaurant.user_id: - return "" + return "" if request.method == 'POST': - session.delete(itemToDelete) + session.delete(item_to_delete) session.commit() flash('Menu Item Successfully Deleted') - return redirect(url_for('showMenu', restaurant_id=restaurant_id)) + return redirect(url_for('show_menu', restaurant_id=restaurant_id)) else: - return render_template('deleteMenuItem.html', item=itemToDelete) + return render_template('deleteMenuItem.html', item=item_to_delete) # Disconnect based on provider @app.route('/disconnect') def disconnect(): if 'provider' in login_session: - if login_session['provider'] == 'google': - gdisconnect() - del login_session['gplus_id'] - del login_session['credentials'] - if login_session['provider'] == 'facebook': - fbdisconnect() - del login_session['facebook_id'] - del login_session['username'] - del login_session['email'] - del login_session['picture'] - del login_session['user_id'] - del login_session['provider'] + remove_session() flash("You have successfully been logged out.") - return redirect(url_for('showRestaurants')) + return redirect(url_for('show_restaurants')) else: flash("You were not logged in") - return redirect(url_for('showRestaurants')) + return redirect(url_for('show_restaurants')) if __name__ == '__main__': - app.secret_key = 'super_secret_key' - app.debug = True - app.run(host='0.0.0.0', port=5000) + app.secret_key = main_app.get('secret_key', 'super_secret_key') + app.debug = main_app.get('debug', True) + app.config['SESSION_TYPE'] = main_app.get('session_type', 'filesystem') + app.run( + host=main_app.get('host', '0.0.0.0'), + port=main_app.get('port', 5000) + ) diff --git a/Lesson4/step2/project.py.bak b/Lesson4/step2/project.py.bak deleted file mode 100644 index 529ff42..0000000 --- a/Lesson4/step2/project.py.bak +++ /dev/null @@ -1,459 +0,0 @@ -from flask import Flask, render_template, request, redirect, jsonify, url_for, flash -from sqlalchemy import create_engine, asc -from sqlalchemy.orm import sessionmaker -from database_setup import Base, Restaurant, MenuItem, User -from flask import session as login_session -import random -import string -from oauth2client.client import flow_from_clientsecrets -from oauth2client.client import FlowExchangeError -import httplib2 -import json -from flask import make_response -import requests - -app = Flask(__name__) - -CLIENT_ID = json.loads( - open('client_secrets.json', 'r').read())['web']['client_id'] -APPLICATION_NAME = "Restaurant Menu Application" - - -# Connect to Database and create database session -engine = create_engine('sqlite:///restaurantmenuwithusers.db') -Base.metadata.bind = engine - -DBSession = sessionmaker(bind=engine) -session = DBSession() - - -# Create anti-forgery state token -@app.route('/login') -def showLogin(): - state = ''.join(random.choice(string.ascii_uppercase + string.digits) - for x in xrange(32)) - login_session['state'] = state - # return "The current session state is %s" % login_session['state'] - return render_template('login.html', STATE=state) - - -@app.route('/fbconnect', methods=['POST']) -def fbconnect(): - if request.args.get('state') != login_session['state']: - response = make_response(json.dumps('Invalid state parameter.'), 401) - response.headers['Content-Type'] = 'application/json' - return response - access_token = request.data - print "access token received %s " % access_token - - - app_id = json.loads(open('fb_client_secrets.json', 'r').read())[ - 'web']['app_id'] - app_secret = json.loads( - open('fb_client_secrets.json', 'r').read())['web']['app_secret'] - url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=%s&client_secret=%s&fb_exchange_token=%s' % ( - app_id, app_secret, access_token) - h = httplib2.Http() - result = h.request(url, 'GET')[1] - - - # Use token to get user info from API - userinfo_url = "https://graph.facebook.com/v2.8/me" - ''' - Due to the formatting for the result from the server token exchange we have to - split the token first on commas and select the first index which gives us the key : value - for the server access token then we split it on colons to pull out the actual token value - and replace the remaining quotes with nothing so that it can be used directly in the graph - api calls - ''' - token = result.split(',')[0].split(':')[1].replace('"', '') - - url = 'https://graph.facebook.com/v2.8/me?access_token=%s&fields=name,id,email' % token - h = httplib2.Http() - result = h.request(url, 'GET')[1] - # print "url sent for API access:%s"% url - # print "API JSON result: %s" % result - data = json.loads(result) - login_session['provider'] = 'facebook' - login_session['username'] = data["name"] - login_session['email'] = data["email"] - login_session['facebook_id'] = data["id"] - - # The token must be stored in the login_session in order to properly logout - login_session['access_token'] = token - - # Get user picture - url = 'https://graph.facebook.com/v2.8/me/picture?access_token=%s&redirect=0&height=200&width=200' % token - h = httplib2.Http() - result = h.request(url, 'GET')[1] - data = json.loads(result) - - login_session['picture'] = data["data"]["url"] - - # see if user exists - user_id = getUserID(login_session['email']) - if not user_id: - user_id = createUser(login_session) - login_session['user_id'] = user_id - - output = '' - output += '

Welcome, ' - output += login_session['username'] - - output += '!

' - output += ' ' - - flash("Now logged in as %s" % login_session['username']) - return output - - -@app.route('/fbdisconnect') -def fbdisconnect(): - facebook_id = login_session['facebook_id'] - # The access token must me included to successfully logout - access_token = login_session['access_token'] - url = 'https://graph.facebook.com/%s/permissions?access_token=%s' % (facebook_id,access_token) - h = httplib2.Http() - result = h.request(url, 'DELETE')[1] - return "you have been logged out" - - -@app.route('/gconnect', methods=['POST']) -def gconnect(): - # Validate state token - if request.args.get('state') != login_session['state']: - response = make_response(json.dumps('Invalid state parameter.'), 401) - response.headers['Content-Type'] = 'application/json' - return response - # Obtain authorization code - code = request.data - - try: - # Upgrade the authorization code into a credentials object - oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='') - oauth_flow.redirect_uri = 'postmessage' - credentials = oauth_flow.step2_exchange(code) - except FlowExchangeError: - response = make_response( - json.dumps('Failed to upgrade the authorization code.'), 401) - response.headers['Content-Type'] = 'application/json' - return response - - # Check that the access token is valid. - access_token = credentials.access_token - url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s' - % access_token) - h = httplib2.Http() - result = json.loads(h.request(url, 'GET')[1]) - # If there was an error in the access token info, abort. - if result.get('error') is not None: - response = make_response(json.dumps(result.get('error')), 500) - response.headers['Content-Type'] = 'application/json' - return response - - # Verify that the access token is used for the intended user. - gplus_id = credentials.id_token['sub'] - if result['user_id'] != gplus_id: - response = make_response( - json.dumps("Token's user ID doesn't match given user ID."), 401) - response.headers['Content-Type'] = 'application/json' - return response - - # Verify that the access token is valid for this app. - if result['issued_to'] != CLIENT_ID: - response = make_response( - json.dumps("Token's client ID does not match app's."), 401) - print "Token's client ID does not match app's." - response.headers['Content-Type'] = 'application/json' - return response - - stored_access_token = login_session.get('access_token') - stored_gplus_id = login_session.get('gplus_id') - if stored_access_token is not None and gplus_id == stored_gplus_id: - response = make_response(json.dumps('Current user is already connected.'), - 200) - response.headers['Content-Type'] = 'application/json' - return response - - # Store the access token in the session for later use. - login_session['access_token'] = credentials.access_token - login_session['gplus_id'] = gplus_id - - # Get user info - userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo" - params = {'access_token': credentials.access_token, 'alt': 'json'} - answer = requests.get(userinfo_url, params=params) - - data = answer.json() - - login_session['username'] = data['name'] - login_session['picture'] = data['picture'] - login_session['email'] = data['email'] - # ADD PROVIDER TO LOGIN SESSION - login_session['provider'] = 'google' - - # see if user exists, if it doesn't make a new one - user_id = getUserID(data["email"]) - if not user_id: - user_id = createUser(login_session) - login_session['user_id'] = user_id - - output = '' - output += '

Welcome, ' - output += login_session['username'] - output += '!

' - output += ' ' - flash("you are now logged in as %s" % login_session['username']) - print "done!" - return output - -# User Helper Functions - - -def createUser(login_session): - newUser = User(name=login_session['username'], email=login_session[ - 'email'], picture=login_session['picture']) - session.add(newUser) - session.commit() - user = session.query(User).filter_by(email=login_session['email']).one() - return user.id - - -def getUserInfo(user_id): - user = session.query(User).filter_by(id=user_id).one() - return user - - -def getUserID(email): - try: - user = session.query(User).filter_by(email=email).one() - return user.id - except: - return None - -# DISCONNECT - Revoke a current user's token and reset their login_session - - -@app.route('/gdisconnect') -def gdisconnect(): - # Only disconnect a connected user. - access_token = login_session.get('access_token') - if access_token is None: - response = make_response( - json.dumps('Current user not connected.'), 401) - response.headers['Content-Type'] = 'application/json' - return response - url = 'https://accounts.google.com/o/oauth2/revoke?token=%s' % access_token - h = httplib2.Http() - result = h.request(url, 'GET')[0] - if result['status'] == '200': - del login_session['access_token'] - del login_session['gplus_id'] - del login_session['username'] - del login_session['email'] - del login_session['picture'] - response = make_response(json.dumps('Successfully disconnected.'), 200) - response.headers['Content-Type'] = 'application/json' - return response - else: - response = make_response(json.dumps('Failed to revoke token for given user.', 400)) - response.headers['Content-Type'] = 'application/json' - return response - - -# JSON APIs to view Restaurant Information -@app.route('/restaurant//menu/JSON') -def restaurantMenuJSON(restaurant_id): - restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - items = session.query(MenuItem).filter_by( - restaurant_id=restaurant_id).all() - return jsonify(MenuItems=[i.serialize for i in items]) - - -@app.route('/restaurant//menu//JSON') -def menuItemJSON(restaurant_id, menu_id): - Menu_Item = session.query(MenuItem).filter_by(id=menu_id).one() - return jsonify(Menu_Item=Menu_Item.serialize) - - -@app.route('/restaurant/JSON') -def restaurantsJSON(): - restaurants = session.query(Restaurant).all() - return jsonify(restaurants=[r.serialize for r in restaurants]) - - -# Show all restaurants -@app.route('/') -@app.route('/restaurant/') -def showRestaurants(): - restaurants = session.query(Restaurant).order_by(asc(Restaurant.name)) - if 'username' not in login_session: - return render_template('publicrestaurants.html', restaurants=restaurants) - else: - return render_template('restaurants.html', restaurants=restaurants) - -# Create a new restaurant - - -@app.route('/restaurant/new/', methods=['GET', 'POST']) -def newRestaurant(): - if 'username' not in login_session: - return redirect('/login') - if request.method == 'POST': - newRestaurant = Restaurant( - name=request.form['name'], user_id=login_session['user_id']) - session.add(newRestaurant) - flash('New Restaurant %s Successfully Created' % newRestaurant.name) - session.commit() - return redirect(url_for('showRestaurants')) - else: - return render_template('newRestaurant.html') - -# Edit a restaurant - - -@app.route('/restaurant//edit/', methods=['GET', 'POST']) -def editRestaurant(restaurant_id): - editedRestaurant = session.query( - Restaurant).filter_by(id=restaurant_id).one() - if 'username' not in login_session: - return redirect('/login') - if editedRestaurant.user_id != login_session['user_id']: - return "" - if request.method == 'POST': - if request.form['name']: - editedRestaurant.name = request.form['name'] - flash('Restaurant Successfully Edited %s' % editedRestaurant.name) - return redirect(url_for('showRestaurants')) - else: - return render_template('editRestaurant.html', restaurant=editedRestaurant) - - -# Delete a restaurant -@app.route('/restaurant//delete/', methods=['GET', 'POST']) -def deleteRestaurant(restaurant_id): - restaurantToDelete = session.query( - Restaurant).filter_by(id=restaurant_id).one() - if 'username' not in login_session: - return redirect('/login') - if restaurantToDelete.user_id != login_session['user_id']: - return "" - if request.method == 'POST': - session.delete(restaurantToDelete) - flash('%s Successfully Deleted' % restaurantToDelete.name) - session.commit() - return redirect(url_for('showRestaurants', restaurant_id=restaurant_id)) - else: - return render_template('deleteRestaurant.html', restaurant=restaurantToDelete) - -# Show a restaurant menu - - -@app.route('/restaurant//') -@app.route('/restaurant//menu/') -def showMenu(restaurant_id): - restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - creator = getUserInfo(restaurant.user_id) - items = session.query(MenuItem).filter_by( - restaurant_id=restaurant_id).all() - if 'username' not in login_session or creator.id != login_session['user_id']: - return render_template('publicmenu.html', items=items, restaurant=restaurant, creator=creator) - else: - return render_template('menu.html', items=items, restaurant=restaurant, creator=creator) - - -# Create a new menu item -@app.route('/restaurant//menu/new/', methods=['GET', 'POST']) -def newMenuItem(restaurant_id): - if 'username' not in login_session: - return redirect('/login') - restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - if login_session['user_id'] != restaurant.user_id: - return "" - if request.method == 'POST': - newItem = MenuItem(name=request.form['name'], description=request.form['description'], price=request.form[ - 'price'], course=request.form['course'], restaurant_id=restaurant_id, user_id=restaurant.user_id) - session.add(newItem) - session.commit() - flash('New Menu %s Item Successfully Created' % (newItem.name)) - return redirect(url_for('showMenu', restaurant_id=restaurant_id)) - else: - return render_template('newmenuitem.html', restaurant_id=restaurant_id) - -# Edit a menu item - - -@app.route('/restaurant//menu//edit', methods=['GET', 'POST']) -def editMenuItem(restaurant_id, menu_id): - if 'username' not in login_session: - return redirect('/login') - editedItem = session.query(MenuItem).filter_by(id=menu_id).one() - restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - if login_session['user_id'] != restaurant.user_id: - return "" - if request.method == 'POST': - if request.form['name']: - editedItem.name = request.form['name'] - if request.form['description']: - editedItem.description = request.form['description'] - if request.form['price']: - editedItem.price = request.form['price'] - if request.form['course']: - editedItem.course = request.form['course'] - session.add(editedItem) - session.commit() - flash('Menu Item Successfully Edited') - return redirect(url_for('showMenu', restaurant_id=restaurant_id)) - else: - return render_template('editmenuitem.html', restaurant_id=restaurant_id, menu_id=menu_id, item=editedItem) - - -# Delete a menu item -@app.route('/restaurant//menu//delete', methods=['GET', 'POST']) -def deleteMenuItem(restaurant_id, menu_id): - if 'username' not in login_session: - return redirect('/login') - restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() - itemToDelete = session.query(MenuItem).filter_by(id=menu_id).one() - if login_session['user_id'] != restaurant.user_id: - return "" - if request.method == 'POST': - session.delete(itemToDelete) - session.commit() - flash('Menu Item Successfully Deleted') - return redirect(url_for('showMenu', restaurant_id=restaurant_id)) - else: - return render_template('deleteMenuItem.html', item=itemToDelete) - - -# Disconnect based on provider -@app.route('/disconnect') -def disconnect(): - if 'provider' in login_session: - if login_session['provider'] == 'google': - gdisconnect() - del login_session['gplus_id'] - del login_session['credentials'] - if login_session['provider'] == 'facebook': - fbdisconnect() - del login_session['facebook_id'] - del login_session['username'] - del login_session['email'] - del login_session['picture'] - del login_session['user_id'] - del login_session['provider'] - flash("You have successfully been logged out.") - return redirect(url_for('showRestaurants')) - else: - flash("You were not logged in") - return redirect(url_for('showRestaurants')) - - -if __name__ == '__main__': - app.secret_key = 'super_secret_key' - app.debug = True - app.run(host='0.0.0.0', port=5000) diff --git a/Lesson4/step2/requirements.txt b/Lesson4/step2/requirements.txt new file mode 100644 index 0000000..3bf07bd --- /dev/null +++ b/Lesson4/step2/requirements.txt @@ -0,0 +1,19 @@ +certifi==2017.7.27.1 +chardet==3.0.4 +click==6.7 +Flask==0.12.2 +httplib2==0.10.3 +idna==2.6 +itsdangerous==0.24 +Jinja2==2.9.6 +MarkupSafe==1.0 +oauth2client==4.1.2 +pyasn1==0.3.2 +pyasn1-modules==0.0.11 +python-dotenv==0.6.5 +requests==2.18.4 +rsa==3.4.2 +six==1.10.0 +SQLAlchemy==1.1.13 +urllib3==1.22 +Werkzeug==0.12.2 diff --git a/Lesson4/step2/restaurantmenu.db b/Lesson4/step2/restaurantmenu.db deleted file mode 100644 index e69de29..0000000 diff --git a/Lesson4/step2/restaurantmenuwithusers.db b/Lesson4/step2/restaurantmenuwithusers.db index 7bfdd06ce650a344e8ddd7a1d8a91c03bdcd3c58..10abe3986263c46f08cc4a3bf4f95c6acc071330 100644 GIT binary patch delta 444 zcmaivJ4?e*7>3U!RcVE`o6-))(OMI##oHj(TB<`@Xb^M|iODfJdXiI;6E8TZlekr9 z2mgZPHwgX#LHr4VqmzsAf_3woKEC&Rc;EMI<7}f>fX%C7J=FwiYU$3t#ls4G0r&*H zAqijNyz&fB&j*zOFfo7L(3$0$loLZRPR;0$?wEm85138GlH-|-tCsLwDZAl(m*{w3gHUn%wi%6N!?}EKJ|6eCoCjPlBAEV5@OKc zQ|HHOrP}aiKxta3P9?mSE&Sze8Yb1H5n1jRN`4O2m2V+Q3cxfNPh3m?+4h~{_fiUe E0OnGNhyVZp delta 104 zcmV-u0GI!OSb$iN8v#I(976>_04?Gnv1FhF3IhUk00Vmh^#XLWAqZvyvvdZK0T>Ab zEC2)T1K0z_1Dpeg19$^n14sib0}`_#4EX{98j(R3vn&hM918#d00IL000W5v`?Dbk K?*g;?Dg^=B`W%-4 diff --git a/Lesson4/step2/static/styles.css b/Lesson4/step2/static/styles.css index df225bb..679840e 100644 --- a/Lesson4/step2/static/styles.css +++ b/Lesson4/step2/static/styles.css @@ -1,163 +1,193 @@ * { - font-family: "Helvetica Neue Bold", Roboto, Helvetica, Arial, sans-serif; - font-weight: 700; + font-family: "Helvetica Neue Bold", Roboto, Helvetica, Arial, sans-serif; + font-weight: 700; } h1 { - font-family: "Helvetica Neue Light", Roboto, Helvetica, Arial, sans-serif; - font-size: 50px; - color: #51453B; - line-height: 60px; - font-weight: 300; + font-family: "Helvetica Neue Light", Roboto, Helvetica, Arial, sans-serif; + font-size: 50px; + color: #51453B; + line-height: 60px; + font-weight: 300; } h2 { - font-size: 24px; - color: #42C3C9; - line-height: 29px; + font-size: 24px; + color: #42C3C9; + line-height: 29px; } h3 { - font-size: 18px; - color: #4A4A4A; - line-height: 23px; -} - p { - font-family: "Helvetica Neue", Roboto, Helvetica, Arial, sans-serif; - font-size: 16px; - color: #7B7573; - line-height: 24px; - font-weight: 400; - } - - strong { - font-size: 16px; - color: #7B7573; - line-height: 24px; - } - - a { - font-size: 14px; - color: #0093B9; - line-height: 17px; - } + font-size: 18px; + color: #4A4A4A; + line-height: 23px; +} + +p { + font-family: "Helvetica Neue", Roboto, Helvetica, Arial, sans-serif; + font-size: 16px; + color: #7B7573; + line-height: 24px; + font-weight: 400; +} + +strong { + font-size: 16px; + color: #7B7573; + line-height: 24px; +} + +a { + font-size: 14px; + color: #0093B9; + line-height: 17px; +} + .padding-top { - padding-top: 30px; + padding-top: 30px; } + .padding-bottom { - padding-bottom: 30px; + padding-bottom: 30px; } + .margin-right { - margin-right: 30px; + margin-right: 30px; } + .padding-none { - padding: 0; + padding: 0; } + .btn { - padding: 20px; - margin: 0; - border-color: #9FB80A; - border-width: 2px; - color: #9FB80A;; + padding: 20px; + margin: 0; + border-color: #9FB80A; + border-width: 2px; + color: #9FB80A;; } + .btn:hover { - border-color: #9FB80A; + border-color: #9FB80A; } + .btn.delete { - border-color: #aaaaaa; - color: #aaaaaa; + border-color: #aaaaaa; + color: #aaaaaa; } + .btn.delete:hover { - border-color: #aaaaaa; - color: red; + border-color: #aaaaaa; + color: red; } + .glyphicon { - margin-right: 10px; + margin-right: 10px; } + .top-menu { - padding-top: 30px; - padding-bottom: 30px; + padding-top: 30px; + padding-bottom: 30px; } + .top-menu p { - margin-bottom: 0; - line-height: 16px; + margin-bottom: 0; + line-height: 16px; } + .top-menu a { - margin-bottom: 0; - line-height: 16px; - font-size: 16px; - color: #7B7573; - font-weight: 400; + margin-bottom: 0; + line-height: 16px; + font-size: 16px; + color: #7B7573; + font-weight: 400; } + .divider { - height: 15px; + height: 15px; } + .divider.blue { - background-color: #42C3C9; + background-color: #42C3C9; } + .divider.green { - background-color: #9FB80A; + background-color: #9FB80A; } + .banner.main { - height: 150px; - background: url("/static/top-banner.jpg"); - background-position: right; - background-repeat: no-repeat; - background-size: cover; + height: 150px; + background: url("/static/top-banner.jpg"); + background-position: right; + background-repeat: no-repeat; + background-size: cover; + border-bottom: solid 15px #42c3c9; + margin-bottom: 15px; } + .banner.menu { - height: 150px; - background-color: #E1E17F; + height: 150px; + background-color: #E1E17F; } + .banner.profile { - height: 150px; - background-color: #A6E8EB; + height: 150px; + background-color: #A6E8EB; } + .banner h1 { - margin: 45px 0; + margin: 45px 0; } - .restaurant-list { - background-color: #F0F0F0; - padding: 20px; -u } - .restaurant-list:hover { - background-color: #e1e17f; - padding: 20px; + +.restaurant-list { + background-color: #F0F0F0; + padding: 20px; } + +.restaurant-list:hover { + background-color: #e1e17f; + padding: 20px; +} + .menu-item { - background: #F0F0F0; - padding: 20px; - margin: 20px; - margin-left: -20px; + background: #F0F0F0; + padding: 20px; + margin: 20px; + margin-left: -20px; } + .menu-price { - font-weight: 700; + font-weight: 700; } + .creator { - padding-right: 20px; - margin-top: -20px; - text-align: right; - float:right; + padding-right: 20px; + margin-top: -20px; + text-align: right; + float: right; } + .creator img { - width: 100px; - border-radius: 50%; + width: 100px; + border-radius: 50%; } + .creator figcaption { - font-size: 14px; - color: #7B7573; - font-weight: 400; - margin-top: -20px; + font-size: 14px; + color: #7B7573; + font-weight: 400; + margin-top: -20px; } + .flash { - background-color: #98FB98; - width:100%; - text-decoration: none; + background-color: #98FB98; + width: 100%; + text-decoration: none; } .flash li { - list-style-type: none; - text-align: center; + list-style-type: none; + text-align: center; } \ No newline at end of file diff --git a/Lesson4/step2/templates/deleteRestaurant.html b/Lesson4/step2/templates/deleteRestaurant.html index f71b37a..20eb995 100644 --- a/Lesson4/step2/templates/deleteRestaurant.html +++ b/Lesson4/step2/templates/deleteRestaurant.html @@ -1,17 +1,19 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -

Are you sure you want to delete {{restaurant.name}}?

+ {% include "header.html" %} +

Are you sure you want to delete {{ restaurant.name }}?

-
+ - - - - + + + + -
+ {% endblock %} \ No newline at end of file diff --git a/Lesson4/step2/templates/deletemenuitem.html b/Lesson4/step2/templates/deletemenuitem.html index e49fd4a..bcef025 100644 --- a/Lesson4/step2/templates/deletemenuitem.html +++ b/Lesson4/step2/templates/deletemenuitem.html @@ -1,17 +1,19 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -

Are you sure you want to delete {{item.name}}?

+ {% include "header.html" %} +

Are you sure you want to delete {{ item.name }}?

-
+ - - - - + + + + -
+ {% endblock %} diff --git a/Lesson4/step2/templates/editRestaurant.html b/Lesson4/step2/templates/editRestaurant.html index 5ce142f..cd6cc37 100644 --- a/Lesson4/step2/templates/editRestaurant.html +++ b/Lesson4/step2/templates/editRestaurant.html @@ -1,29 +1,31 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -
-
-
- -
-
-
-
- - -
- - - - -
-
-
-
+ {% include "header.html" %} +
+
+
+ +
+
+
+
+ + +
+ + + + +
+
+
+
{% endblock %} \ No newline at end of file diff --git a/Lesson4/step2/templates/editmenuitem.html b/Lesson4/step2/templates/editmenuitem.html index e92fee7..41e0e02 100644 --- a/Lesson4/step2/templates/editmenuitem.html +++ b/Lesson4/step2/templates/editmenuitem.html @@ -1,58 +1,65 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -
-
-
- -
-
-
-
- - + {% include "header.html" %} +
+
+
+ +
+
+ +
+ + - - + + - -
-
$
- -
- -
- -
-
- -
-
- -
-
- -
- - - - -
- -
-
+ +
+
$
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+ + + + +
+ +
+
{% endblock %} \ No newline at end of file diff --git a/Lesson4/step2/templates/header.html b/Lesson4/step2/templates/header.html index e706801..1f7f1bb 100644 --- a/Lesson4/step2/templates/header.html +++ b/Lesson4/step2/templates/header.html @@ -1,15 +1,15 @@
- -
- {%if 'username' not in session %} - Click Here to Login - {% else %} - Logout - {% endif %} - -
+ +
+ {% if 'username' not in session %} + Click Here to Login + {% else %} + Logout + {% endif %} + +
\ No newline at end of file diff --git a/Lesson4/step2/templates/login.html b/Lesson4/step2/templates/login.html index ba2472a..ab7c7bc 100644 --- a/Lesson4/step2/templates/login.html +++ b/Lesson4/step2/templates/login.html @@ -1,147 +1,128 @@ - +{% extends "main.html" %} +{% block content %} - - - - - - - - - - - - - - - - - -
- +
+ +
+ + + + + +{% endblock %} + +{% block scripts %} + + + + + +{% endblock %} diff --git a/Lesson4/step2/templates/main.html b/Lesson4/step2/templates/main.html index 75de0c9..da8af1a 100644 --- a/Lesson4/step2/templates/main.html +++ b/Lesson4/step2/templates/main.html @@ -1,14 +1,21 @@ - - - - - - -
- {% block content %} - {% endblock %} -
- + + + + + {% block css %} + {% endblock %} + + +
+ {% block content %} + {% endblock %} +
+{% block scripts %} +{% endblock %} + \ No newline at end of file diff --git a/Lesson4/step2/templates/menu.html b/Lesson4/step2/templates/menu.html index b56a5f1..2b7c576 100644 --- a/Lesson4/step2/templates/menu.html +++ b/Lesson4/step2/templates/menu.html @@ -1,114 +1,133 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -
-
-
- -
- {% with messages = get_flashed_messages() %} - {% if messages %} - -
    - {% for message in messages %} -
  • {{ message }}
  • - {% endfor %} -
- {% endif %} - {% endwith %} +
+ {% with messages = get_flashed_messages() %} + {% if messages %} -
- - - {% if items !=[] %} -
-
-
-

Appetizers

- {% for i in items %} - {% if i.course == 'Appetizer' %} - - {% endif %} - {% endfor %} -
-
-

Entrees

- {% for i in items %} - {% if i.course == 'Entree' %} - - {% endif %} - {% endfor %} -
-
-

Desserts

- {% for i in items %} - {% if i.course == 'Dessert' %} - - {% endif %} - {% endfor %} -

Beverages

- {% for i in items %} - {% if i.course == 'Beverage' %} - - {% endif %} - {% endfor %} -
-
-
- {% endif %} +
    + {% for message in messages %} +
  • {{ message }}
  • + {% endfor %} +
+ {% endif %} + {% endwith %} + +
+ {% if login_session.user_id == restaurant.user_id %} + + {% endif %} + + {% if items !=[] %} +
+
+
+

Appetizers

+ {% for i in items %} + {% if i.course == 'Appetizer' %} + + {% endif %} + {% endfor %} +
+
+

Entrees

+ {% for i in items %} + {% if i.course == 'Entree' %} + + {% endif %} + {% endfor %} +
+
+

Desserts

+ {% for i in items %} + {% if i.course == 'Dessert' %} + + {% endif %} + {% endfor %} +

Beverages

+ {% for i in items %} + {% if i.course == 'Beverage' %} + + {% endif %} + {% endfor %} +
+
+
+ {% endif %} {% endblock %} diff --git a/Lesson4/step2/templates/newRestaurant.html b/Lesson4/step2/templates/newRestaurant.html index 978cfd4..e98e1ff 100644 --- a/Lesson4/step2/templates/newRestaurant.html +++ b/Lesson4/step2/templates/newRestaurant.html @@ -1,25 +1,26 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -
-
-
- -
-
-
-
- - -
- -
-
-
-
+ {% include "header.html" %} +
+
+
+ +
+
+
+
+ + +
+ +
+
+
+
{% endblock %} diff --git a/Lesson4/step2/templates/newmenuitem.html b/Lesson4/step2/templates/newmenuitem.html index 88a1d51..25b6c67 100644 --- a/Lesson4/step2/templates/newmenuitem.html +++ b/Lesson4/step2/templates/newmenuitem.html @@ -1,55 +1,57 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -
-
-
- -
-
-
-
- - + {% include "header.html" %} +
+
+
+ +
+
+ +
+ + - - + + - -
-
$
- -
- -
- -
-
- -
-
- -
-
- -
- -
- -
-
+ +
+
$
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
{% endblock %} diff --git a/Lesson4/step2/templates/publicmenu.html b/Lesson4/step2/templates/publicmenu.html deleted file mode 100644 index ac6dc5d..0000000 --- a/Lesson4/step2/templates/publicmenu.html +++ /dev/null @@ -1,95 +0,0 @@ -{% extends "main.html" %} -{% block content %} -{% include "header.html" %} - -
-
-
- -
-
-
- -
-
-
-
-
- {% with messages = get_flashed_messages() %} - {% if messages %} -
    - {% for message in messages %} -
  • {{ message }}
  • - {% endfor %} -
- {% endif %} - {% endwith %} -
-
- {% if items !=[] %} -
-
-
-

Appetizers

- {% for i in items %} - {% if i.course == 'Appetizer' %} - - {% endif %} - {% endfor %} -
-
-

Entrees

- {% for i in items %} - {% if i.course == 'Entree' %} - - {% endif %} - {% endfor %} -
-
-

Desserts

- {% for i in items %} - {% if i.course == 'Dessert' %} - - {% endif %} - {% endfor %} -

Beverages

- {% for i in items %} - {% if i.course == 'Beverage' %} - - {% endif %} - {% endfor %} -
-
-
- {% endif %} -{% endblock %} diff --git a/Lesson4/step2/templates/publicrestaurants.html b/Lesson4/step2/templates/publicrestaurants.html deleted file mode 100644 index 63c4ec7..0000000 --- a/Lesson4/step2/templates/publicrestaurants.html +++ /dev/null @@ -1,53 +0,0 @@ -{% extends "main.html" %} -{% block content %} - -
-
-
- - -
- {% with messages = get_flashed_messages() %} - {% if messages %} - -
    - {% for message in messages %} -
  • {{ message }}
  • - {% endfor %} -
- {% endif %} - {% endwith %} - -
- - - -
-
-
- -
-
-
- {% for restaurant in restaurants %} - -
-
-
-

{{restaurant.name}}

-
-
-
-
- {% endfor %} -{% endblock %} diff --git a/Lesson4/step2/templates/restaurants.html b/Lesson4/step2/templates/restaurants.html index 33de351..12d7193 100644 --- a/Lesson4/step2/templates/restaurants.html +++ b/Lesson4/step2/templates/restaurants.html @@ -1,55 +1,62 @@ {% extends "main.html" %} {% block content %} -{% include "header.html" %} -
-
-
-
-
-
-
-
- + {% include "header.html" %} +
+
+
+
+
+
+
+
+ -
- {% with messages = get_flashed_messages() %} - {% if messages %} - -
    - {% for message in messages %} -
  • {{ message }}
  • - {% endfor %} -
- {% endif %} - {% endwith %} +
+ {% with messages = get_flashed_messages() %} + {% if messages %} -
- - - {% for restaurant in restaurants %} - -
-
-
-

{{restaurant.name}}

-
-
-
-
- {% endfor %} +
    + {% for message in messages %} +
  • {{ message }}
  • + {% endfor %} +
+ {% endif %} + {% endwith %} + +
+ {% if login_session.user_id %} + + {% endif %} + {% for restaurant in restaurants %} + +
+
+
+

+ {% if login_session.user_id == restaurant.user_id %} +   + {% endif %} + {{ restaurant.name }} +

+ +
+
+
+
+ {% endfor %} {% endblock %} diff --git a/Lesson4/step2/variables.py b/Lesson4/step2/variables.py new file mode 100644 index 0000000..dd51958 --- /dev/null +++ b/Lesson4/step2/variables.py @@ -0,0 +1,32 @@ +from os import environ + +from dotenv import load_dotenv, find_dotenv + +load_dotenv(find_dotenv()) + +google_web = dict( + client_id=environ.get("google_client_id", "google_client_id_here"), + project_id=environ.get("google_project_id", "google_project_id_here"), + auth_uri=environ.get("google_auth_uri", "https://accounts.google.com/o/oauth2/auth"), + token_uri=environ.get("google_token_uri", "https://accounts.google.com/o/oauth2/token"), + auth_provider_x509_cert_url=environ.get("google_x509", "https://www.googleapis.com/oauth2/v1/certs"), + client_secret=environ.get("google_client_secret", "google_client_secret_here"), + javascript_origins=[ + "http://localhost:5000" + ], + scope='', + redirect_uris=[ + "https://localhost:5000/callback", + "http://localhost:5000/callback" + ] +) + +facebook_web = dict( + app_id=environ.get('facebook_app_id', 'facebook_app_id_goes_here'), + app_secret=environ.get('facebook_app_secret', 'facebook_app_secret_goes_here') +) + +main_app = dict( + secret_key=environ.get('app_secret_key', 'super secret key'), + debug=environ.get('debug', True) +) From cb89b5644fb672b7420e9f612ce50d4a9d239e47 Mon Sep 17 00:00:00 2001 From: markm1198 Date: Fri, 8 Sep 2017 19:24:19 -0700 Subject: [PATCH 3/8] Did not specify that a cascade delete was needed. It is. Who knew? --- Lesson4/step2/database_setup.py | 4 ++-- Lesson4/step2/project.py | 3 +++ Lesson4/step2/restaurantmenuwithusers.db | Bin 11264 -> 11264 bytes 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lesson4/step2/database_setup.py b/Lesson4/step2/database_setup.py index 51c620b..a77d643 100644 --- a/Lesson4/step2/database_setup.py +++ b/Lesson4/step2/database_setup.py @@ -41,9 +41,9 @@ class MenuItem(Base): price = Column(String(8)) course = Column(String(250)) restaurant_id = Column(Integer, ForeignKey('restaurant.id')) - restaurant = relationship(Restaurant) + restaurant = relationship(Restaurant, cascade="all, delete-orphan", single_parent=True) user_id = Column(Integer, ForeignKey('user.id')) - user = relationship(User) + user = relationship(User, cascade="all") @property def serialize(self): diff --git a/Lesson4/step2/project.py b/Lesson4/step2/project.py index 689a36b..f23eb08 100644 --- a/Lesson4/step2/project.py +++ b/Lesson4/step2/project.py @@ -341,6 +341,9 @@ def delete_restaurant(restaurant_id): "Please create your own restaurant in order to delete.');}" if request.method == 'POST': session.delete(restaurant_to_delete) + menu_items_to_delete = session.query(MenuItem).filter_by(restaurant_id=restaurant_id).all() + for del_menu in menu_items_to_delete: + session.delete(del_menu) flash('%s Successfully Deleted' % restaurant_to_delete.name) session.commit() return redirect(url_for('show_restaurants', restaurant_id=restaurant_id)) diff --git a/Lesson4/step2/restaurantmenuwithusers.db b/Lesson4/step2/restaurantmenuwithusers.db index 10abe3986263c46f08cc4a3bf4f95c6acc071330..1829249fd645012e9360825121d174832bc77090 100644 GIT binary patch delta 355 zcmZpOXo#2~&FjO!z`zZ}>_E&oQNx_ohe7vm!N!!i%!16-3@nTZ3`}2{N*G@;CNL&! z7G&{bRB2>qWn)lwY;^TaEXr2!&CJP3Ey@Kl^>V>XJwroFi^=_Lx|VrWnU#*Zr5=HS z`TCA<;E7=Sh3Z@CR^&Q+Rut(vn&=l~( z7?_VT&tYz7u3(O3_F&dw768G`iacMKCJS(%Z~&^-&}0lQEl4d=2rkJiQgAD(WCaQe zt1^ZbB_-x5IF%NqrxvlYGJj)WWqt&dVc=%|&HR!14fAv6N6e3aCLLj(7{EFCDL=mk zn;1}VHTICE z3Z4p<9{o57{s74j@S@q0}>N)4xVgBECpjM0m_!V{QH zbxmlRMYbOH);Z~C-`O|znSEsM*;{0K&Nk-zHs1{n9@??Tp`5pDZUEOD9VYAvtFfH- z%)8^wdHd-rdV>ycj%I$$U&{4P5Vd!h(i5Td7e(?%e?i(18YVMz1^sPb5)23x?lK$;M$ zTE#FcWb-KX%ZzKl%pm~ALP#yE+RM<6sW!3C_iEwr5G)fkt);1hK@-KUZ=NDcVx^CvX(Lr)-1G=X-Em}uUUH6OWo*>wNV>l}!xTwt qqpl$49AVA@;3sS%v5uunk{~Zsy1)8LEgqcOPNw~Hh-Mz|%l`uUIVs2h From f11668b963d2f5d20b1c6dbba0e724a563deacc2 Mon Sep 17 00:00:00 2001 From: markm1198 Date: Fri, 8 Sep 2017 19:37:02 -0700 Subject: [PATCH 4/8] More modifications --- Lesson4/step2/database_setup.py | 4 ++-- Lesson4/step2/project.py | 4 ++-- Lesson4/step2/restaurantmenuwithusers.db | Bin 11264 -> 11264 bytes 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Lesson4/step2/database_setup.py b/Lesson4/step2/database_setup.py index a77d643..51c620b 100644 --- a/Lesson4/step2/database_setup.py +++ b/Lesson4/step2/database_setup.py @@ -41,9 +41,9 @@ class MenuItem(Base): price = Column(String(8)) course = Column(String(250)) restaurant_id = Column(Integer, ForeignKey('restaurant.id')) - restaurant = relationship(Restaurant, cascade="all, delete-orphan", single_parent=True) + restaurant = relationship(Restaurant) user_id = Column(Integer, ForeignKey('user.id')) - user = relationship(User, cascade="all") + user = relationship(User) @property def serialize(self): diff --git a/Lesson4/step2/project.py b/Lesson4/step2/project.py index f23eb08..2e5aa88 100644 --- a/Lesson4/step2/project.py +++ b/Lesson4/step2/project.py @@ -311,10 +311,10 @@ def new_restaurant(): @app.route('/restaurant//edit/', methods=['GET', 'POST']) def edit_restaurant(restaurant_id): - edited_restaurant = session.query( - Restaurant).filter_by(id=restaurant_id).one() if 'username' not in login_session: return redirect('/login') + edited_restaurant = session.query( + Restaurant).filter_by(id=restaurant_id).one() if edited_restaurant.user_id != login_session['user_id']: return "" + "Please create your own restaurant in order to edit.');}" \ + "" if request.method == 'POST': if request.form['name'] != edited_restaurant.name: edited_restaurant.name = request.form['name'] flash('Restaurant Successfully Edited %s' % edited_restaurant.name) return redirect(url_for('show_restaurants')) else: - return render_template('editRestaurant.html', restaurant=edited_restaurant) + return render_template( + 'editRestaurant.html', + restaurant=edited_restaurant + ) # Delete a restaurant @app.route('/restaurant//delete/', methods=['GET', 'POST']) +@login_required def delete_restaurant(restaurant_id): restaurant_to_delete = session.query( Restaurant).filter_by(id=restaurant_id).one() - if 'username' not in login_session: - return redirect('/login') if restaurant_to_delete.user_id != login_session['user_id']: return "" + "Please create your own restaurant in order to delete.');}" \ + "" if request.method == 'POST': session.delete(restaurant_to_delete) - menu_items_to_delete = session.query(MenuItem).filter_by(restaurant_id=restaurant_id).all() + menu_items_to_delete = session.query(MenuItem).filter_by( + restaurant_id=restaurant_id + ).all() for del_menu in menu_items_to_delete: session.delete(del_menu) flash('%s Successfully Deleted' % restaurant_to_delete.name) session.commit() - return redirect(url_for('show_restaurants', restaurant_id=restaurant_id)) + return redirect( + url_for( + 'show_restaurants', + restaurant_id=restaurant_id + ) + ) else: - return render_template('deleteRestaurant.html', restaurant=restaurant_to_delete) + return render_template( + 'deleteRestaurant.html', + restaurant=restaurant_to_delete + ) # Show a restaurant menu @@ -363,23 +428,39 @@ def show_menu(restaurant_id): creator = get_user_info(restaurant.user_id) items = session.query(MenuItem).filter_by( restaurant_id=restaurant_id).all() - return render_template('menu.html', items=items, restaurant=restaurant, creator=creator, - login_session=login_session) + return render_template( + 'menu.html', + items=items, + restaurant=restaurant, + creator=creator, + login_session=login_session + ) # Create a new menu item -@app.route('/restaurant//menu/new/', methods=['GET', 'POST']) +@app.route( + '/restaurant//menu/new/', + methods=['GET', 'POST'] +) +@login_required def new_menu_item(restaurant_id): - if 'username' not in login_session: - return redirect('/login') restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() if login_session['user_id'] != restaurant.user_id: return "" + "alert(" \ + "'You are not authorized to add menu items " \ + "to this restaurant. " \ + "Please create your own restaurant in order to add items.');}" \ + "" if request.method == 'POST': - new_item = MenuItem(name=request.form['name'], description=request.form['description'], price=request.form[ - 'price'], course=request.form['course'], restaurant_id=restaurant_id, user_id=restaurant.user_id) + new_item = MenuItem( + name=request.form['name'], + description=request.form['description'], + price=request.form['price'], + course=request.form['course'], + restaurant_id=restaurant_id, + user_id=restaurant.user_id + ) session.add(new_item) session.commit() flash('New Menu %s Item Successfully Created' % new_item.name) @@ -391,16 +472,21 @@ def new_menu_item(restaurant_id): # Edit a menu item -@app.route('/restaurant//menu//edit', methods=['GET', 'POST']) +@app.route( + '/restaurant//menu//edit', + methods=['GET', 'POST'] +) +@login_required def edit_menu_item(restaurant_id, menu_id): - if 'username' not in login_session: - return redirect('/login') edited_item = session.query(MenuItem).filter_by(id=menu_id).one() restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() if login_session['user_id'] != restaurant.user_id: return "" + "alert('You are not authorized to edit menu items" \ + " to this restaurant. " \ + "Please create your own restaurant in order " \ + "to edit items.');}" \ + "" if request.method == 'POST': for (key, value) in request.form.items(): setattr(edited_item, key, value) @@ -409,20 +495,29 @@ def edit_menu_item(restaurant_id, menu_id): flash('Menu Item Successfully Edited') return redirect(url_for('show_menu', restaurant_id=restaurant_id)) else: - return render_template('editmenuitem.html', restaurant_id=restaurant_id, menu_id=menu_id, item=edited_item) + return render_template( + 'editmenuitem.html', + restaurant_id=restaurant_id, + menu_id=menu_id, + item=edited_item + ) # Delete a menu item -@app.route('/restaurant//menu//delete', methods=['GET', 'POST']) +@app.route( + '/restaurant//menu//delete', + methods=['GET', 'POST'] +) +@login_required def delete_menu_item(restaurant_id, menu_id): - if 'username' not in login_session: - return redirect('/login') restaurant = session.query(Restaurant).filter_by(id=restaurant_id).one() item_to_delete = session.query(MenuItem).filter_by(id=menu_id).one() if login_session['user_id'] != restaurant.user_id: return "" + "alert('You are not authorized to delete menu items " \ + "to this restaurant. " \ + "Please create your own restaurant in order to delete " \ + "items.');}" if request.method == 'POST': session.delete(item_to_delete) session.commit() From cbe1f024335ae5c776d8ec824e49cc00e5e36ed9 Mon Sep 17 00:00:00 2001 From: Michael Soileau Date: Mon, 11 Sep 2017 08:57:00 -0700 Subject: [PATCH 8/8] Wrap errors in try/except block - Adds in Faker data. --- Lesson4/step2/README.md | 11 +- Lesson4/step2/database_setup.py | 2 + Lesson4/step2/lotsofmenus.py | 495 ++--------------------- Lesson4/step2/project.py | 71 +++- Lesson4/step2/restaurantmenuwithusers.db | Bin 11264 -> 221184 bytes Lesson4/step2/static/styles.css | 2 +- Lesson4/step2/variables.py | 25 +- 7 files changed, 127 insertions(+), 479 deletions(-) diff --git a/Lesson4/step2/README.md b/Lesson4/step2/README.md index 3ca2864..2e7a9d2 100644 --- a/Lesson4/step2/README.md +++ b/Lesson4/step2/README.md @@ -27,4 +27,13 @@ flask run Or ```shell python project.py -``` \ No newline at end of file +``` + +All dependencies are kept in the .env file. To create the .env file, run + +```shell +cp .env.example .env +``` + +Then fill in the environment values with their required settings. + diff --git a/Lesson4/step2/database_setup.py b/Lesson4/step2/database_setup.py index 51c620b..4abe0c7 100644 --- a/Lesson4/step2/database_setup.py +++ b/Lesson4/step2/database_setup.py @@ -1,3 +1,5 @@ +#! /usr/bin/env python3 + from sqlalchemy import Column, ForeignKey, Integer, String from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base diff --git a/Lesson4/step2/lotsofmenus.py b/Lesson4/step2/lotsofmenus.py index 0092da9..8c96e69 100644 --- a/Lesson4/step2/lotsofmenus.py +++ b/Lesson4/step2/lotsofmenus.py @@ -1,5 +1,9 @@ -from sqlalchemy.orm import sessionmaker +#! /usr/bin/env python3 +import locale +import random +from faker import Faker +from sqlalchemy.orm import sessionmaker from database_setup import Restaurant, Base, MenuItem, User, engine # Bind the engine to the metadata of the Base class so that the @@ -15,471 +19,44 @@ # revert all of them back to the last commit by calling # session.rollback() session = DBSession() +locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') +fake = Faker() -# Create dummy user -User1 = User(name="Robo Barista", email="tinnyTim@udacity.com", - picture='https://pbs.twimg.com/profile_images/2671170543/' - '18debd694829ed78203a5a36dd364160_400x400.png') -session.add(User1) -session.commit() - -# Menu for UrbanBurger -restaurant1 = Restaurant(user_id=1, name="Urban Burger") - -session.add(restaurant1) -session.commit() - -menuItem2 = MenuItem( - user_id=1, - name="Veggie Burger", - description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$7.50", - course="Entree", - restaurant=restaurant1 -) - -session.add(menuItem2) -session.commit() - -menuItem1 = MenuItem( - user_id=1, - name="French Fries", - description="with garlic and parmesan", - price="$2.99", - course="Appetizer", - restaurant=restaurant1 -) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem( - user_id=1, - name="Chicken Burger", - description="Juicy grilled chicken patty with tomato mayo and lettuce", - price="$5.50", - course="Entree", - restaurant=restaurant1 -) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem( - user_id=1, - name="Chocolate Cake", - description="fresh baked and served with ice cream", - price="$3.99", - course="Dessert", - restaurant=restaurant1 -) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem( - user_id=1, - name="Sirloin Burger", - description="Made with grade A beef", - price="$7.99", - course="Entree", - restaurant=restaurant1 -) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem( - user_id=1, - name="Root Beer", - description="16oz of refreshing goodness", - price="$1.99", course="Beverage", restaurant=restaurant1) - -session.add(menuItem5) -session.commit() - -menuItem6 = MenuItem(user_id=1, name="Iced Tea", description="with Lemon", - price="$.99", course="Beverage", restaurant=restaurant1) - -session.add(menuItem6) -session.commit() - -menuItem7 = MenuItem(user_id=1, name="Grilled Cheese Sandwich", - description="On texas toast with American Cheese", price="$3.49", course="Entree", - restaurant=restaurant1) - -session.add(menuItem7) -session.commit() - -menuItem8 = MenuItem(user_id=1, name="Veggie Burger", - description="Made with freshest of ingredients and home grown spices", - price="$5.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem8) +for i in range(0, 10): + user = User( + name=fake.name(), + email=fake.email(), + picture='https://pbs.twimg.com/profile_images/2671170543/' + '18debd694829ed78203a5a36dd364160_400x400.png' + ) + session.add(user) session.commit() -# Menu for Super Stir Fry -restaurant2 = Restaurant(user_id=1, name="Super Stir Fry") - -session.add(restaurant2) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Chicken Stir Fry", - description="With your choice of noodles vegetables and sauces", - price="$7.99", course="Entree", restaurant=restaurant2) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Peking Duck", - description=" A famous duck dish from Beijing[1] that has been prepared " - "since the imperial era. The meat is prized for its thin, " - "crisp skin, with authentic versions of the dish serving " - "mostly the skin and little meat, sliced in front of the diners " - "by the cook", - price="$25", course="Entree", restaurant=restaurant2) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Spicy Tuna Roll", - description="Seared rare ahi, avocado, edamame, " - "cucumber with wasabi soy sauce ", - price="15", course="Entree", restaurant=restaurant2) - -session.add(menuItem3) +for i in range(0, 10): + restaurant = Restaurant( + user_id=i + 1, + name=fake.text() + ) + session.add(restaurant) session.commit() -menuItem4 = MenuItem(user_id=1, name="Nepali Momo ", - description="Steamed dumplings made with vegetables, spices and meat. ", - price="12", course="Entree", restaurant=restaurant2) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem(user_id=1, name="Beef Noodle Soup", - description="A Chinese noodle soup made of stewed or red braised beef, " - "sbeef broth, vegetables and Chinese noodles.", - price="14", course="Entree", restaurant=restaurant2) - -session.add(menuItem5) -session.commit() - -menuItem6 = MenuItem(user_id=1, name="Ramen", - description="a Japanese noodle soup dish. It consists of " - "Chinese-style wheat noodles served in a meat- or " - "s(occasionally) fish-based broth, often flavored with " - "soy sauce or miso, and uses toppings such as sliced pork, " - "dried seaweed, kamaboko, and green onions.", - price="12", course="Entree", restaurant=restaurant2) - -session.add(menuItem6) -session.commit() - -# Menu for Panda Garden -restaurant1 = Restaurant(user_id=1, name="Panda Garden") - -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Pho", - description="a Vietnamese noodle soup consisting of broth, " - "linguine-shaped rice noodles called banh pho, a few herbs, " - "and meat.", - price="$8.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chinese Dumplings", - description="a common Chinese dumpling which generally consists of " - "minced meat and finely chopped vegetables wrapped into a " - "piece of dough skin. The skin can be either thin and elastic " - "or thicker.", - price="$6.99", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Gyoza", - description="light seasoning of Japanese gyoza with salt and soy sauce, " - "and in a thin gyoza wrapper", - price="$9.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Stinky Tofu", - description="Taiwanese dish, deep fried fermented tofu served with pickled cabbage.", - price="$6.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", - description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$9.50", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -# Menu for Thyme for that -restaurant1 = Restaurant(user_id=1, name="Thyme for That Vegetarian Cuisine ") - -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Tres Leches Cake", - description="Rich, luscious sponge cake soaked in sweet milk and " - "topped with vanilla bean whipped cream and strawberries.", - price="$2.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Mushroom risotto", - description="Portabello mushrooms in a creamy risotto", - price="$5.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Honey Boba Shaved Snow", - description="Milk snow layered with honey boba, " - "jasmine tea jelly, grass jelly, caramel, cream, " - "and freshly made mochi", - price="$4.50", course="Dessert", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Cauliflower Manchurian", - description="Golden fried cauliflower florets in a midly spiced soya," - "sgarlic sauce cooked with fresh cilantro, celery, chilies,ginger & green onions", - price="$6.95", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() +course_elements = ["Entree", "Dessert", "Beverage", "Appetizer"] -menuItem5 = MenuItem(user_id=1, name="Aloo Gobi Burrito", - description="Vegan goodness. Burrito filled with rice, garbanzo beans, " - "curry sauce, potatoes (aloo), fried cauliflower (gobi) and chutney. Nom Nom", - price="$7.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem5) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", - description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$6.80", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -# Menu for Tony's Bistro -restaurant1 = Restaurant(user_id=1, name="Tony\'s Bistro ") - -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Shellfish Tower", - description="Lobster, shrimp, sea snails, crawfish, stacked into a delicious tower", - price="$13.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chicken and Rice", description="Chicken... and rice", - price="$4.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Mom's Spaghetti", - description="Spaghetti with some incredible tomato sauce made by mom", - price="$6.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Choc Full O\' Mint (Smitten\'s Fresh Mint Chip ice cream)", - description="Milk, cream, salt, ..., Liquid nitrogen magic", - price="$3.95", course="Dessert", - restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem5 = MenuItem(user_id=1, name="Tonkatsu Ramen", - description="Noodles in a delicious pork-based broth with a soft-boiled egg", - price="$7.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem5) -session.commit() - -# Menu for Andala's -restaurant1 = Restaurant(user_id=1, name="Andala\'s") - -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Lamb Curry", - description="Slow cook that thang in a pool of tomatoes, onions and " - "alllll those tasty Indian spices. Mmmm.", - price="$9.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Chicken Marsala", - description="Chicken cooked in Marsala wine sauce with mushrooms", - price="$7.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Potstickers", - description="Delicious chicken and veggies encapsulated in fried dough.", - price="$6.50", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Nigiri Sampler", - description="Maguro, Sake, Hamachi, Unagi, Uni, TORO!", - price="$6.75", course="Appetizer", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", - description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$7.00", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -# Menu for Auntie Ann's -restaurant1 = Restaurant(user_id=1, name="Auntie Ann\'s Diner' ") - -session.add(restaurant1) -session.commit() - -menuItem9 = MenuItem( - user_id=1, name="Chicken Fried Steak", - description="Fresh battered sirloin steak fried and smothered with cream gravy", - price="$8.99", - course="Entree", restaurant=restaurant1 -) - -session.add(menuItem9) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Boysenberry Sorbet", - description="An unsettlingly huge amount of ripe berries turned into " - "frozen (and seedless) awesomeness", - price="$2.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Broiled salmon", - description="Salmon fillet marinated with fresh herbs and broiled hot & fast", - price="$10.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem3 = MenuItem(user_id=1, name="Morels on toast (seasonal)", - description="Wild morel mushrooms fried in butter, served on herbed toast slices", price="$7.50", - course="Appetizer", restaurant=restaurant1) - -session.add(menuItem3) -session.commit() - -menuItem4 = MenuItem(user_id=1, name="Tandoori Chicken", - description="Chicken marinated in yoghurt and seasoned with a " - "spicy mix(chilli, tamarind among others) and slow " - "cooked in a cylindrical clay or metal oven which " - "gets its heat from burning charcoal.", - price="$8.95", course="Entree", restaurant=restaurant1) - -session.add(menuItem4) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Veggie Burger", - description="Juicy grilled veggie patty with tomato mayo and lettuce", - price="$9.50", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -menuItem10 = MenuItem(user_id=1, name="Spinach Ice Cream", - description="vanilla ice cream made with organic spinach leaves", - price="$1.99", course="Dessert", restaurant=restaurant1) - -session.add(menuItem10) -session.commit() - -# Menu for Cocina Y Amor -restaurant1 = Restaurant(user_id=1, name="Cocina Y Amor ") - -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem(user_id=1, name="Super Burrito Al Pastor", - description="Marinated Pork, Rice, Beans, Avocado, Cilantro, Salsa, Tortilla", price="$5.95", - course="Entree", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem2 = MenuItem(user_id=1, name="Cachapa", - description="Golden brown, corn-based Venezuelan pancake; " - "usually stuffed with queso telita or queso de mano, " - "and possibly lechon. ", - price="$7.99", course="Entree", restaurant=restaurant1) - -session.add(menuItem2) -session.commit() - -restaurant1 = Restaurant(user_id=1, name="State Bird Provisions") -session.add(restaurant1) -session.commit() - -menuItem1 = MenuItem( - user_id=1, - name="Chantrelle Toast", - description="Crispy Toast with Sesame Seeds slathered with buttery chantrelle mushrooms", - price="$5.95", - course="Appetizer", restaurant=restaurant1) - -session.add(menuItem1) -session.commit() - -menuItem1 = MenuItem( - user_id=1, - name="Guanciale Chawanmushi", - description="Japanese egg custard served hot with spicey Italian Pork Jowl (guanciale)", - price="$6.95", - course="Dessert", - restaurant=restaurant1 -) - -session.add(menuItem1) -session.commit() +for i in range(0, 1000): + restaurant = session.query(Restaurant).filter_by( + id=random.randint(1, 10) + ).first() -menuItem1 = MenuItem( - user_id=1, - name="Lemon Curd Ice Cream Sandwich", - description="Lemon Curd Ice Cream Sandwich on a chocolate macaron " - "with cardamom meringue and cashews", - price="$4.25", - course="Dessert", - restaurant=restaurant1 -) + menuItem = MenuItem( + user_id=restaurant.user_id, + name=fake.lexify("???????? ??????"), + description=fake.text(), + price=locale.currency(round(random.randint(100, 10000) / 100, 2)), + course=fake.random_element(course_elements), + restaurant=restaurant + ) + session.add(menuItem) -session.add(menuItem1) session.commit() -print("added menu items!") +print("added all the items items!") diff --git a/Lesson4/step2/project.py b/Lesson4/step2/project.py index 917c4a1..6bcf186 100644 --- a/Lesson4/step2/project.py +++ b/Lesson4/step2/project.py @@ -309,14 +309,19 @@ def remove_session(): def restaurant_menu_json(restaurant_id): items = session.query(MenuItem).filter_by( restaurant_id=restaurant_id).all() + if not items: + return jsonify("No such restaurant exists") return jsonify(MenuItems=[i.serialize for i in items]) @app.route('/restaurant//menu//JSON') def menu_item_json(restaurant_id, menu_id): - menu_item = session.query(MenuItem).filter_by( - id=menu_id, restaurant_id=restaurant_id - ).one() + try: + menu_item = session.query(MenuItem).filter_by( + id=menu_id, restaurant_id=restaurant_id + ).one() + except: + return jsonify("No such menu exists") return jsonify(Menu_Item=menu_item.serialize) @@ -366,8 +371,13 @@ def new_restaurant(): @app.route('/restaurant//edit/', methods=['GET', 'POST']) @login_required def edit_restaurant(restaurant_id): - edited_restaurant = session.query( - Restaurant).filter_by(id=restaurant_id).one() + try: + edited_restaurant = session.query( + Restaurant).filter_by( + id=restaurant_id + ).one() + except: + return "No such restaurant exists." if edited_restaurant.user_id != login_session['user_id']: return "