PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/project.py

https://bitbucket.org/diverdano/mls
Python | 235 lines | 130 code | 31 blank | 74 comment | 14 complexity | e0d2dc81c3269eb8a02f89fef2f0f1a1 MD5 | raw file
  1. #!/usr/bin/env python
  2. ## ==================================
  3. ## === packages, modules, pragmas ===
  4. ## ==================================
  5. ## === built-ins ===
  6. #from http.server import BaseHTTPRequestHandler, HTTPServer
  7. from flask import Flask, request, render_template, url_for, redirect
  8. import cgi
  9. import sys
  10. import os # used to obtain environment host name & process web file paths
  11. import argparse # used when running as script; should be moved to DAO
  12. import logging
  13. import logging.config # pythons logging feature
  14. from mimetypes import types_map # for processing additional files
  15. # ## === 3rd party ===
  16. from sqlalchemy import create_engine
  17. from sqlalchemy.orm import sessionmaker
  18. from database_setup import Base, Restaurant, MenuItem, Employee, Address
  19. # import pymongo
  20. # import json
  21. # from tornado.ioloop import IOLoop
  22. # #from tornado.log import enable_pretty_logging
  23. # #import tornado.options
  24. # from tornado.web import RequestHandler, Application, url, RedirectHandler, StaticFileHandler
  25. # from tornado.httpclient import AsyncHTTPClient
  26. # from tornado.escape import json_decode
  27. # from tornado import gen
  28. # #import tornado.logging
  29. # #import tornado.web.authenticated (decorator for ensuring user is logged in)
  30. #
  31. # ## === custom ===
  32. #import restaurant as r
  33. import util
  34. # import rplace
  35. #
  36. ## ===============================
  37. ## === command-line processing ===
  38. ## ===============================
  39. parser = argparse.ArgumentParser()
  40. parser.add_argument('--port', default=8080, help="sets port number for web service")
  41. parser.add_argument('--host', default='www.rplace.org', help="sets host for web service")
  42. parser.add_argument('--log_file', default='log/web.log', help="path/file for logging")
  43. parser.add_argument('--start', dest='start', action='store_true', help="start the server")
  44. parser.add_argument('--app', default='restaurant_app', help="name of application")
  45. parser.add_argument('--debug', dest='debug', action='store_true', help="sets server debug, and level of logging")
  46. #parser.add_argument('--debug_off', dest='debug', action='store_false', help="sets server debug")
  47. #parser.add_argument('--mongo_server', default=2, help="server where mongodb resides")
  48. #parser.add_argument('--i_mode', dest='start', action='store_false', help="skip starting the server")
  49. args = parser.parse_args()
  50. def pargs():
  51. '''prints items in args object for ease of reading'''
  52. print('\n')
  53. for item in args._get_kwargs():
  54. k,v = item
  55. print('\t' + k + ': ' + str(v))
  56. ## ===================================
  57. ## === logging to file and console ===
  58. ## ===================================
  59. ERROR_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(message)s"
  60. INFO_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(message)s"
  61. CONSOLE_FORMAT = "\n\t%(message)s"
  62. if args.debug == True:
  63. DEBUG_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(filename)s->%(funcName)s line %(lineno)d: %(message)s"
  64. LOG_LEVEL = "DEBUG"
  65. else:
  66. DEBUG_FORMAT = INFO_FORMAT
  67. LOG_LEVEL = "INFO"
  68. LOG_CONFIG = {'version':1,
  69. 'formatters':{'error':{'format':ERROR_FORMAT},
  70. 'info':{'format':INFO_FORMAT},
  71. 'console':{'format':CONSOLE_FORMAT},
  72. 'debug':{'format':DEBUG_FORMAT}},
  73. 'handlers':{'console':{'class':'logging.StreamHandler',
  74. 'formatter':'console',
  75. 'level':logging.DEBUG},
  76. 'file':{'class':'logging.FileHandler',
  77. 'filename':args.log_file,
  78. 'formatter':'debug',
  79. 'level':logging.INFO}},
  80. 'root':{'handlers':['console', 'file'], 'level':LOG_LEVEL}}
  81. logging.config.dictConfig(LOG_CONFIG)
  82. logger = logging.getLogger(args.app)
  83. ## ====================
  84. ## == db connection ==
  85. ## ===================
  86. try:
  87. session = sessionmaker()(bind=create_engine('sqlite:///../data/restaurant.db'))
  88. # engine = create_engine('sqlite:///restaurant.db') # multi-line approach
  89. # Base.metadata.bind = engine
  90. # DBSession = sessionmaker(bind=engine) # can bind when creating sessionmaker instance
  91. # session = DBSession()
  92. # DBSession = sessionmaker() # or after
  93. # session = DBSession(bind=engine)
  94. emp = session.query(Employee) # load global objects for convenience
  95. rest = session.query(Restaurant)
  96. addr = session.query(Address)
  97. mi = session.query(MenuItem)
  98. # db = DB() # prefer to put in a class
  99. # emp = db.session.query(Employee)
  100. # rest = db.session.query(Restaurant)
  101. # addr = db.session.query(Address)
  102. # mi = db.session.query(MenuItem)
  103. except:
  104. logger.exception("issue loading restaurant database items", exc_info=1)
  105. # ## ============
  106. # ## == Routes ==
  107. # ## ============
  108. app = Flask(__name__)
  109. @app.route('/')
  110. @app.route('/restaurants')
  111. def showRestaurants_plain():
  112. '''show restaurants, no css template'''
  113. rest_list = []
  114. for item in rest:
  115. rest_list.append('<a href="/restaurants/{1}/">{0}</a>'.format(item.name, str(item.id)))
  116. output = '<br>'.join(sorted(rest_list))
  117. return output
  118. @app.route('/restaurants/', methods=['GET', 'POST'])
  119. def showRestaurants():
  120. '''show restaurants'''
  121. return render_template('restaurants.html', restaurants=rest)
  122. @app.route('/restaurants/<int:restaurant_id>/')
  123. def showMenu(restaurant_id):
  124. '''show restaurant menu'''
  125. restaurant = rest.filter_by(id = restaurant_id).one()
  126. rest_items = mi.filter_by(restaurant_id = restaurant.id)
  127. return render_template('menu.html', restaurant=restaurant, items=rest_items)
  128. @app.route('/restaurants/new/', methods=['GET', 'POST'])
  129. def newRestaurant():
  130. '''add new restaurant'''
  131. if request.method == 'POST':
  132. restaurant = Restaurant(name=request.form['name'])
  133. # newRestaurant = Restaurant(name=request.form['name'][0].decode('ascii'))
  134. logger.debug('adding new restaurant', restaurant.name)
  135. session.add(restaurant)
  136. session.commit()
  137. return redirect(url_for('showRestaurants'))
  138. else:
  139. return render_template('newRestaurant.html')
  140. return "page to create a new restaurant"
  141. @app.route('/restaurants/<int:restaurant_id>/edit/', methods=['GET', 'POST'])
  142. def editRestaurant(restaurant_id):
  143. '''edit restaurant'''
  144. if request.method == 'POST':
  145. restaurant = rest.filter_by(id = restaurant_id).one()
  146. restaurant.name = request.form['name']
  147. logger.debug('updating restaurant', restaurant.name)
  148. session.add(restaurant)
  149. session.commit()
  150. return redirect(url_for('showRestaurants'))
  151. else:
  152. return render_template('editRestaurant.html', restaurant=rest.filter_by(id=restaurant_id).one())
  153. return "page to edit restaurant"
  154. @app.route('/restaurants/<int:restaurant_id>/delete/', methods=['GET', 'POST'])
  155. def deleteRestaurant(restaurant_id):
  156. '''delete restaurant'''
  157. if request.method == 'POST':
  158. restaurant = rest.filter_by(id = restaurant_id).one()
  159. logger.debug('deleting restaurant', restaurant.name)
  160. session.delete(restaurant)
  161. session.commit()
  162. return redirect(url_for('showRestaurants'))
  163. else:
  164. return render_template('deleteRestaurant.html', restaurant=rest.filter_by(id=restaurant_id).one())
  165. return "page to delete restaurant"
  166. # Task 1: Create route for newMenuItem function here
  167. @app.route('/restaurants/<int:restaurant_id>/new/', methods=['GET', 'POST'])
  168. def newMenuItem(restaurant_id):
  169. '''add new menu items'''
  170. if request.method == 'POST':
  171. menuitem = MenuItem(name=request.form['name'], price=request.form['price'], desc=request.form['desc'])
  172. # newRestaurant = Restaurant(name=request.form['name'][0].decode('ascii'))
  173. logger.debug('adding new menu item', menuitem.name)
  174. session.add(menuitem)
  175. session.commit()
  176. # return redirect(url_for('showRestaurants'))
  177. return redirect(url_for('showMenu') + '/' + restaurant_id)
  178. else:
  179. return render_template('newmenuitem.html')
  180. return "page to create a new menu item. Task 1 complete!"
  181. # Task 2: Create route for editMenuItem function here
  182. @app.route('/restaurants/<int:restaurant_id>/<int:menu_id>/edit/', methods=['GET', 'POST'])
  183. def editMenuItem(restaurant_id, menu_id):
  184. '''edit menu items'''
  185. return "page to edit a menu item. Task 2 complete!"
  186. # Task 3: Create a route for deleteMenuItem function here
  187. @app.route('/restaurants/<int:restaurant_id>/<int:menu_id>/delete/', methods=['GET', 'POST'])
  188. def deleteMenuItem(restaurant_id, menu_id):
  189. '''delete menu items'''
  190. return "page to delete a menu item. Task 3 complete!"
  191. # ## =============
  192. # ## == classes ==
  193. # ## =============
  194. # ## ==========
  195. # ## == main ==
  196. # ## ==========
  197. def main():
  198. app.debug == args.debug
  199. app.run(host = args.host, port = args.port)
  200. # ## ============
  201. # ## == module ==
  202. # ## ============
  203. if args.start == True:
  204. main()