/project.py
Python | 235 lines | 130 code | 31 blank | 74 comment | 14 complexity | e0d2dc81c3269eb8a02f89fef2f0f1a1 MD5 | raw file
- #!/usr/bin/env python
- ## ==================================
- ## === packages, modules, pragmas ===
- ## ==================================
- ## === built-ins ===
- #from http.server import BaseHTTPRequestHandler, HTTPServer
- from flask import Flask, request, render_template, url_for, redirect
- import cgi
- import sys
- import os # used to obtain environment host name & process web file paths
- import argparse # used when running as script; should be moved to DAO
- import logging
- import logging.config # pythons logging feature
- from mimetypes import types_map # for processing additional files
- # ## === 3rd party ===
- from sqlalchemy import create_engine
- from sqlalchemy.orm import sessionmaker
- from database_setup import Base, Restaurant, MenuItem, Employee, Address
- # import pymongo
- # import json
- # from tornado.ioloop import IOLoop
- # #from tornado.log import enable_pretty_logging
- # #import tornado.options
- # from tornado.web import RequestHandler, Application, url, RedirectHandler, StaticFileHandler
- # from tornado.httpclient import AsyncHTTPClient
- # from tornado.escape import json_decode
- # from tornado import gen
- # #import tornado.logging
- # #import tornado.web.authenticated (decorator for ensuring user is logged in)
- #
- # ## === custom ===
- #import restaurant as r
- import util
- # import rplace
- #
- ## ===============================
- ## === command-line processing ===
- ## ===============================
- parser = argparse.ArgumentParser()
- parser.add_argument('--port', default=8080, help="sets port number for web service")
- parser.add_argument('--host', default='www.rplace.org', help="sets host for web service")
- parser.add_argument('--log_file', default='log/web.log', help="path/file for logging")
- parser.add_argument('--start', dest='start', action='store_true', help="start the server")
- parser.add_argument('--app', default='restaurant_app', help="name of application")
- parser.add_argument('--debug', dest='debug', action='store_true', help="sets server debug, and level of logging")
- #parser.add_argument('--debug_off', dest='debug', action='store_false', help="sets server debug")
- #parser.add_argument('--mongo_server', default=2, help="server where mongodb resides")
- #parser.add_argument('--i_mode', dest='start', action='store_false', help="skip starting the server")
- args = parser.parse_args()
- def pargs():
- '''prints items in args object for ease of reading'''
- print('\n')
- for item in args._get_kwargs():
- k,v = item
- print('\t' + k + ': ' + str(v))
- ## ===================================
- ## === logging to file and console ===
- ## ===================================
- ERROR_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(message)s"
- INFO_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(message)s"
- CONSOLE_FORMAT = "\n\t%(message)s"
- if args.debug == True:
- DEBUG_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(filename)s->%(funcName)s line %(lineno)d: %(message)s"
- LOG_LEVEL = "DEBUG"
- else:
- DEBUG_FORMAT = INFO_FORMAT
- LOG_LEVEL = "INFO"
- LOG_CONFIG = {'version':1,
- 'formatters':{'error':{'format':ERROR_FORMAT},
- 'info':{'format':INFO_FORMAT},
- 'console':{'format':CONSOLE_FORMAT},
- 'debug':{'format':DEBUG_FORMAT}},
- 'handlers':{'console':{'class':'logging.StreamHandler',
- 'formatter':'console',
- 'level':logging.DEBUG},
- 'file':{'class':'logging.FileHandler',
- 'filename':args.log_file,
- 'formatter':'debug',
- 'level':logging.INFO}},
- 'root':{'handlers':['console', 'file'], 'level':LOG_LEVEL}}
- logging.config.dictConfig(LOG_CONFIG)
- logger = logging.getLogger(args.app)
- ## ====================
- ## == db connection ==
- ## ===================
- try:
- session = sessionmaker()(bind=create_engine('sqlite:///../data/restaurant.db'))
- # engine = create_engine('sqlite:///restaurant.db') # multi-line approach
- # Base.metadata.bind = engine
- # DBSession = sessionmaker(bind=engine) # can bind when creating sessionmaker instance
- # session = DBSession()
- # DBSession = sessionmaker() # or after
- # session = DBSession(bind=engine)
- emp = session.query(Employee) # load global objects for convenience
- rest = session.query(Restaurant)
- addr = session.query(Address)
- mi = session.query(MenuItem)
- # db = DB() # prefer to put in a class
- # emp = db.session.query(Employee)
- # rest = db.session.query(Restaurant)
- # addr = db.session.query(Address)
- # mi = db.session.query(MenuItem)
- except:
- logger.exception("issue loading restaurant database items", exc_info=1)
- # ## ============
- # ## == Routes ==
- # ## ============
- app = Flask(__name__)
- @app.route('/')
- @app.route('/restaurants')
- def showRestaurants_plain():
- '''show restaurants, no css template'''
- rest_list = []
- for item in rest:
- rest_list.append('<a href="/restaurants/{1}/">{0}</a>'.format(item.name, str(item.id)))
- output = '<br>'.join(sorted(rest_list))
- return output
- @app.route('/restaurants/', methods=['GET', 'POST'])
- def showRestaurants():
- '''show restaurants'''
- return render_template('restaurants.html', restaurants=rest)
- @app.route('/restaurants/<int:restaurant_id>/')
- def showMenu(restaurant_id):
- '''show restaurant menu'''
- restaurant = rest.filter_by(id = restaurant_id).one()
- rest_items = mi.filter_by(restaurant_id = restaurant.id)
- return render_template('menu.html', restaurant=restaurant, items=rest_items)
- @app.route('/restaurants/new/', methods=['GET', 'POST'])
- def newRestaurant():
- '''add new restaurant'''
- if request.method == 'POST':
- restaurant = Restaurant(name=request.form['name'])
- # newRestaurant = Restaurant(name=request.form['name'][0].decode('ascii'))
- logger.debug('adding new restaurant', restaurant.name)
- session.add(restaurant)
- session.commit()
- return redirect(url_for('showRestaurants'))
- else:
- return render_template('newRestaurant.html')
- return "page to create a new restaurant"
- @app.route('/restaurants/<int:restaurant_id>/edit/', methods=['GET', 'POST'])
- def editRestaurant(restaurant_id):
- '''edit restaurant'''
- if request.method == 'POST':
- restaurant = rest.filter_by(id = restaurant_id).one()
- restaurant.name = request.form['name']
- logger.debug('updating restaurant', restaurant.name)
- session.add(restaurant)
- session.commit()
- return redirect(url_for('showRestaurants'))
- else:
- return render_template('editRestaurant.html', restaurant=rest.filter_by(id=restaurant_id).one())
- return "page to edit restaurant"
- @app.route('/restaurants/<int:restaurant_id>/delete/', methods=['GET', 'POST'])
- def deleteRestaurant(restaurant_id):
- '''delete restaurant'''
- if request.method == 'POST':
- restaurant = rest.filter_by(id = restaurant_id).one()
- logger.debug('deleting restaurant', restaurant.name)
- session.delete(restaurant)
- session.commit()
- return redirect(url_for('showRestaurants'))
- else:
- return render_template('deleteRestaurant.html', restaurant=rest.filter_by(id=restaurant_id).one())
- return "page to delete restaurant"
- # Task 1: Create route for newMenuItem function here
- @app.route('/restaurants/<int:restaurant_id>/new/', methods=['GET', 'POST'])
- def newMenuItem(restaurant_id):
- '''add new menu items'''
- if request.method == 'POST':
- menuitem = MenuItem(name=request.form['name'], price=request.form['price'], desc=request.form['desc'])
- # newRestaurant = Restaurant(name=request.form['name'][0].decode('ascii'))
- logger.debug('adding new menu item', menuitem.name)
- session.add(menuitem)
- session.commit()
- # return redirect(url_for('showRestaurants'))
- return redirect(url_for('showMenu') + '/' + restaurant_id)
- else:
- return render_template('newmenuitem.html')
- return "page to create a new menu item. Task 1 complete!"
- # Task 2: Create route for editMenuItem function here
- @app.route('/restaurants/<int:restaurant_id>/<int:menu_id>/edit/', methods=['GET', 'POST'])
- def editMenuItem(restaurant_id, menu_id):
- '''edit menu items'''
- return "page to edit a menu item. Task 2 complete!"
- # Task 3: Create a route for deleteMenuItem function here
- @app.route('/restaurants/<int:restaurant_id>/<int:menu_id>/delete/', methods=['GET', 'POST'])
- def deleteMenuItem(restaurant_id, menu_id):
- '''delete menu items'''
- return "page to delete a menu item. Task 3 complete!"
- # ## =============
- # ## == classes ==
- # ## =============
- # ## ==========
- # ## == main ==
- # ## ==========
- def main():
- app.debug == args.debug
- app.run(host = args.host, port = args.port)
- # ## ============
- # ## == module ==
- # ## ============
- if args.start == True:
- main()