PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/webserver.py

https://bitbucket.org/diverdano/mls
Python | 619 lines | 534 code | 13 blank | 72 comment | 32 complexity | 20d3019b2b19cc082b86fa46ee583089 MD5 | raw file
  1. #!/usr/bin/env python
  2. ## ==================================
  3. ## === packages, modules, pragmas ===
  4. ## ==================================
  5. ## === built-ins ===
  6. import cgi
  7. import sys
  8. import os # used to obtain environment host name & process web file paths
  9. import argparse # used when running as script; should be moved to DAO
  10. import logging
  11. import logging.config # pythons logging feature
  12. from mimetypes import types_map # for processing additional files
  13. from http.server import BaseHTTPRequestHandler, HTTPServer
  14. # ## === 3rd party ===
  15. from sqlalchemy import create_engine
  16. from sqlalchemy.orm import sessionmaker
  17. from database_setup import Restaurant, MenuItem, Employee, Address
  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('--log_file', default='log/web.log', help="path/file for logging")
  42. parser.add_argument('--start', dest='start', action='store_true', help="start the server")
  43. parser.add_argument('--app', default='restaurant_app', help="name of application")
  44. parser.add_argument('--debug', dest='debug', action='store_true', help="sets server debug, and level of logging")
  45. #parser.add_argument('--debug_off', dest='debug', action='store_false', help="sets server debug")
  46. #parser.add_argument('--mongo_server', default=2, help="server where mongodb resides")
  47. #parser.add_argument('--i_mode', dest='start', action='store_false', help="skip starting the server")
  48. args = parser.parse_args()
  49. def pargs():
  50. '''prints items in args object for ease of reading'''
  51. print('\n')
  52. for item in args._get_kwargs():
  53. k,v = item
  54. print('\t' + k + ': ' + str(v))
  55. ## ===================================
  56. ## === logging to file and console ===
  57. ## ===================================
  58. ERROR_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(message)s"
  59. INFO_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(message)s"
  60. CONSOLE_FORMAT = "\n\t%(message)s"
  61. if args.debug == True:
  62. DEBUG_FORMAT = "%(asctime)s %(name)s %(levelname)-8s %(filename)s->%(funcName)s line %(lineno)d: %(message)s"
  63. LOG_LEVEL = "DEBUG"
  64. else:
  65. DEBUG_FORMAT = INFO_FORMAT
  66. LOG_LEVEL = "INFO"
  67. LOG_CONFIG = {'version':1,
  68. 'formatters':{'error':{'format':ERROR_FORMAT},
  69. 'info':{'format':INFO_FORMAT},
  70. 'console':{'format':CONSOLE_FORMAT},
  71. 'debug':{'format':DEBUG_FORMAT}},
  72. 'handlers':{'console':{'class':'logging.StreamHandler',
  73. 'formatter':'console',
  74. 'level':logging.DEBUG},
  75. 'file':{'class':'logging.FileHandler',
  76. 'filename':args.log_file,
  77. 'formatter':'debug',
  78. 'level':logging.INFO}},
  79. 'root':{'handlers':['console', 'file'], 'level':LOG_LEVEL}}
  80. logging.config.dictConfig(LOG_CONFIG)
  81. logger = logging.getLogger(args.app)
  82. # ## =============
  83. # ## == classes ==
  84. # ## =============
  85. class DB(object):
  86. '''custom class for loading menu items from json'''
  87. def __init__(self, db = 'sqlite:///restaurant.db'):
  88. self.engine = create_engine(db)
  89. Base.metadata.bind = self.engine # is this really used?
  90. self.DBSession = sessionmaker(bind=self.engine)
  91. self.session = self.DBSession()
  92. # self.session = sessionmaker(bind=self.engine)
  93. def loadJSON(self, file='menu_items.json'):
  94. '''bulk upload menu items using JSON file'''
  95. self.items = util.readFile(file)
  96. for item in self.items:
  97. self.loadItem(item)
  98. def loadItem(self, menu):
  99. '''create/add and commit items to db
  100. TODO: make this a generic loader for any underlying db table'''
  101. restaurant = Restaurant(name = menu['restaurant']) # TODO: read attributes from JSON entry to determine type
  102. self.session.add(restaurant)
  103. self.session.commit()
  104. for item in menu['menu_items']:
  105. menu_item = MenuItem(name = item['name'], desc = item['desc'], price = item['price'], course = item['course'], restaurant = restaurant)
  106. self.session.add(menu_item)
  107. self.session.commit()
  108. def getMenuItems(self, name = None, id = None):
  109. '''method for fetching items from db'''
  110. if name != None:
  111. items = self.session.query(MenuItem).filter_by(name = name)
  112. for item in items:
  113. print(item.id, item.price, item.restaurant.name, item.name)
  114. print('thats all folks...')
  115. if id != None:
  116. item = self.session.query(MenuItem).filter_by(id = id).one()
  117. self.result = item
  118. class webserverHandler(BaseHTTPRequestHandler):
  119. def do_GET(self):
  120. self.cwd = os.environ['PWD']
  121. try:
  122. if self.path == "/":
  123. self.path = "/index.html"
  124. fname,ext = os.path.splitext(self.path)
  125. if ext in (".ico", ".jpg",".png"): # binary files (images)
  126. with open('.'+self.path, 'rb') as f:
  127. self.send_response(200)
  128. self.send_header('Content-type', types_map[ext])
  129. self.end_headers()
  130. self.wfile.write(f.read())
  131. if ext in (".html", ".css",".js"): # text files only, not binary (images)
  132. with open('.'+self.path) as f:
  133. self.send_response(200)
  134. self.send_header('Content-type', types_map[ext])
  135. self.end_headers()
  136. self.wfile.write(bytes(f.read(), 'utf-8'))
  137. if self.path.endswith("/hello"):
  138. self.send_response(200)
  139. self.send_header('Content-type', 'text/html')
  140. self.end_headers()
  141. ho = htmlizer()
  142. ho.title = 'Hello form'
  143. ho.head = 'Hello'
  144. ho.body = 'some text here'
  145. ho.foot = 'little test footnote'
  146. ho.prompt = 'what should I say?'
  147. ho.action = '/hello'
  148. ho.renderForm()
  149. output = bytes(ho.__repr__(), 'utf-8')
  150. self.wfile.write(output)
  151. # logger.debug(output)
  152. return
  153. if self.path.endswith("/hola"):
  154. self.send_response(200)
  155. self.send_header('Content-type', 'text/html')
  156. self.end_headers()
  157. ho = htmlizer()
  158. ho.title = 'Hola form'
  159. ho.head = '&#161Hola <a href = "/hello" ">Back to Hello</a>'
  160. ho.body = 'some text here'
  161. ho.foot = 'little test footnote'
  162. ho.prompt = 'what should I say?'
  163. ho.action = '/hola'
  164. ho.renderForm()
  165. output = bytes(ho.__repr__(), 'utf-8')
  166. self.wfile.write(output)
  167. # logger.debug(output)
  168. return
  169. if self.path.endswith("/restaurants"):
  170. self.send_response(200)
  171. self.send_header('Content-type', 'text/html')
  172. self.end_headers()
  173. ho = htmlizer()
  174. ho.renderRest(rest)
  175. output = bytes(ho.__repr__(), 'utf-8')
  176. self.wfile.write(output)
  177. # logger.debug(output)
  178. return
  179. if self.path.endswith("/restaurants/new"):
  180. self.send_response(200)
  181. self.send_header('Content-type', 'text/html')
  182. self.end_headers()
  183. ho = htmlizer()
  184. ho.title = 'New Restaurant'
  185. ho.head = 'Make a New Restaurant'
  186. ho.body = 'please enter restaurant name'
  187. ho.foot = 'new restaurant form'
  188. ho.prompt = "enter name"
  189. ho.action = '/restaurants/new'
  190. ho.placeholder = 'new restaurant name'
  191. ho.name = 'NewRestaurantName'
  192. ho.value = 'Create'
  193. ho.renderForm()
  194. # logger.debug('do_GET' + ho.__repr__())
  195. output = bytes(ho.__repr__(), 'utf-8')
  196. self.wfile.write(output)
  197. return
  198. # if self.path.endswith(r"/restaurants/([0-9]+)/edit"):
  199. if self.path.endswith("/edit"):
  200. rest_ID = self.path.split('/')[-2]
  201. curRest = rest.filter_by(id=rest_ID).one()
  202. self.send_response(200)
  203. self.send_header('Content-type', 'text/html')
  204. self.end_headers()
  205. ho = htmlizer()
  206. ho.title = curRest.name
  207. ho.head = 'Restaurant: {0}'.format(curRest.name)
  208. ho.body = 'update restaurant name'
  209. ho.foot = 'update restaurant form'
  210. ho.prompt = "enter name"
  211. ho.action = '/restaurants/{0}/edit'.format(rest_ID)
  212. ho.placeholder = 'updated restaurant name'
  213. ho.name = 'NewRestaurantName'
  214. ho.value = 'Update'
  215. ho.renderForm()
  216. output = bytes(ho.__repr__(), 'utf-8')
  217. self.wfile.write(output)
  218. logger.debug(output)
  219. return
  220. if self.path.endswith("/delete"):
  221. rest_ID = self.path.split('/')[-2]
  222. curRest = rest.filter_by(id=rest_ID).one()
  223. self.send_response(200)
  224. self.send_header('Content-type', 'text/html')
  225. self.end_headers()
  226. ho = htmlizer()
  227. ho.title = curRest.name
  228. ho.head = 'Delete Restaurant: {0}'.format(curRest.name)
  229. ho.body = 'Delete Restaurant'
  230. ho.foot = 'delete restaurant form'
  231. ho.prompt = "delete restaurant?"
  232. ho.action = '/restaurants/{0}/delete'.format(rest_ID)
  233. # ho.placeholder = 'updated restaurant name'
  234. # ho.name = 'NewRestaurantName'
  235. ho.value = 'Delete'
  236. ho.renderForm()
  237. output = bytes(ho.__repr__(), 'utf-8')
  238. self.wfile.write(output)
  239. logger.debug(output)
  240. return
  241. if self.path.endswith("/restaurant_list"):
  242. self.send_response(200)
  243. self.send_header('Content-type', 'text/html')
  244. self.end_headers()
  245. rest_list = sorted([item.name for item in rest])
  246. output = bytes(htmlizer(list = rest_list, title='Restaurant List', head='List of Restaurants', body='additional body text...', foot='end of list').__repr__(), 'utf-8')
  247. self.wfile.write(output)
  248. # logger.debug(output)
  249. return
  250. except IOError:
  251. self.send_error(404, "File Not Found %s" % self.path)
  252. def do_POST(self):
  253. try:
  254. if self.path.endswith("/restaurants/new"):
  255. ctype, pdict = cgi.parse_header(self.headers.get('content-type'))
  256. logger.debug('do_POST (ctype): ' + str(ctype))
  257. pdict['boundary'] = pdict['boundary'].encode('utf-8')
  258. if ctype == 'multipart/form-data':
  259. fields=cgi.parse_multipart(self.rfile, pdict)
  260. messagecontent = fields.get('NewRestaurantName')
  261. restName = messagecontent[0].decode('ascii')
  262. logger.debug('do_POST (restName): ' + restName)
  263. newRestaurant = Restaurant(name=restName)
  264. session.add(newRestaurant)
  265. session.commit()
  266. self.send_response(200)
  267. # self.send_response(301)
  268. # self.send_header('Content-type', 'text/html')
  269. # self.send_header('Location', '/restaurants')
  270. self.end_headers()
  271. ho = htmlizer()
  272. ho.title = 'New Restaurant'
  273. ho.head = 'Restaurant Added'
  274. ho.body = restName
  275. ho.foot = '<a href = "/restaurants">Back to Restaurants</a>'
  276. ho.renderHTML()
  277. output = bytes(ho.__repr__(), 'utf-8')
  278. self.wfile.write(output)
  279. return
  280. if self.path.endswith("/edit"):
  281. rest_ID = self.path.split('/')[-2]
  282. curRest = rest.filter_by(id=rest_ID).one()
  283. ctype, pdict = cgi.parse_header(self.headers.get('content-type'))
  284. logger.debug('do_POST (ctype): ' + str(ctype))
  285. pdict['boundary'] = pdict['boundary'].encode('utf-8')
  286. if ctype == 'multipart/form-data':
  287. fields=cgi.parse_multipart(self.rfile, pdict)
  288. messagecontent = fields.get('NewRestaurantName')
  289. newRestName = messagecontent[0].decode('ascii')
  290. logger.debug('do_POST (restName): ' + newRestName)
  291. curRest.name = newRestName
  292. session.add(curRest)
  293. session.commit()
  294. self.send_response(200)
  295. # self.send_response(301)
  296. # self.send_header('Content-type', 'text/html')
  297. # self.send_header('Location', '/restaurants')
  298. self.end_headers()
  299. ho = htmlizer()
  300. ho.title = 'Edit Restaurant'
  301. ho.head = 'Restaurant Name Updated'
  302. ho.body = newRestName
  303. ho.foot = '<a href = "/restaurants">Back to Restaurants</a>'
  304. ho.renderHTML()
  305. output = bytes(ho.__repr__(), 'utf-8')
  306. self.wfile.write(output)
  307. return
  308. if self.path.endswith("/delete"):
  309. rest_ID = self.path.split('/')[-2]
  310. curRest = rest.filter_by(id=rest_ID).one()
  311. # ctype, pdict = cgi.parse_header(self.headers.get('content-type'))
  312. # logger.debug('do_POST (ctype): ' + str(ctype))
  313. # pdict['boundary'] = pdict['boundary'].encode('utf-8')
  314. # if ctype == 'multipart/form-data':
  315. # fields=cgi.parse_multipart(self.rfile, pdict)
  316. # messagecontent = fields.get('NewRestaurantName')
  317. # newRestName = messagecontent[0].decode('ascii')
  318. # logger.debug('do_POST (restName): ' + newRestName)
  319. # curRest.name = newRestName
  320. # session.add(curRest)
  321. session.delete(curRest)
  322. session.commit()
  323. self.send_response(200)
  324. # self.send_response(301)
  325. # self.send_header('Content-type', 'text/html')
  326. # self.send_header('Location', '/restaurants')
  327. self.end_headers()
  328. ho = htmlizer()
  329. ho.title = 'Restaurant Deleted'
  330. ho.head = 'Restaurant Deleted'
  331. ho.body = curRest.name
  332. ho.foot = '<a href = "/restaurants">Back to Restaurants</a>'
  333. ho.renderHTML()
  334. output = bytes(ho.__repr__(), 'utf-8')
  335. self.wfile.write(output)
  336. return
  337. if self.path.endswith("/hello"):
  338. # if self.path.endswith("/hello") or self.path.endswith("/hola"):
  339. self.send_response(301)
  340. self.end_headers()
  341. ctype, pdict = cgi.parse_header(self.headers.get('content-type'))
  342. logger.debug(type(ctype), ctype)
  343. logger.debug(type(pdict), pdict)
  344. pdict['boundary'] = pdict['boundary'].encode('utf-8')
  345. if ctype == 'multipart/form-data':
  346. fields=cgi.parse_multipart(self.rfile, pdict)
  347. messagecontent = fields.get('message')
  348. ho = htmlizer()
  349. ho.title = 'Echo'
  350. ho.head = 'How about this...?'
  351. ho.body = messagecontent[0].decode('ascii')
  352. ho.foot = 'echo messages'
  353. ho.prompt = 'what else should I say?'
  354. ho.action = '/hello'
  355. ho.placeholder = 'message'
  356. ho.name = 'message'
  357. ho.value = 'Submit'
  358. ho.renderForm()
  359. output = bytes(ho.__repr__(), 'utf-8')
  360. self.wfile.write(output)
  361. return
  362. except IOError:
  363. logger.exception("IOError", exc_info=1)
  364. pass
  365. class htmlizer(object):
  366. '''to structure html page'''
  367. title = 'test_title'
  368. head = 'header_text'
  369. body = 'body_text'
  370. foot = 'footer_stuff'
  371. list = None
  372. prompt = None
  373. action = None
  374. placeholder = 'message'
  375. name = None
  376. value = 'Submit'
  377. form = ''
  378. doc = ''
  379. def __init__(self):
  380. pass
  381. def __repr__(self):
  382. '''method for generating page'''
  383. return self.doc
  384. def renderList(self, list):
  385. '''simple list replaced body'''
  386. self.body = str('<br>'.join(list))
  387. self.renderHTML()
  388. def renderRest(self, rest):
  389. '''use restaurant_id as key for edit and delete replaces body'''
  390. self.title='Restaurants'
  391. self.head='List of Restaurants'
  392. self.foot='<a href = "/restaurants/new">Add new restaurant</a>'
  393. self.rest_list = []
  394. for item in rest:
  395. self.rest_list.append('{0}&nbsp<a href="/restaurants/{1}/edit">edit</a>&nbsp<a href="/restaurants/{1}/delete">delete</a>'.format(item.name, str(item.id)))
  396. self.body = '<br>'.join(sorted(self.rest_list))
  397. # self.body = ""
  398. # for item in rest:
  399. # self.body += '<br>{0}&nbsp<a href="/restaurants/{1}/edit">edit</a>&nbsp<a href="/restaurants/{1}/delete">delete</a>'.format(item.name, str(item.id))
  400. self.renderHTML()
  401. def renderForm(self):
  402. '''form appended to body'''
  403. self.body += '<form method="POST" enctype="multipart/form-data" action="{0}">'.format(self.action)
  404. if self.name != None:
  405. self.body += '<br><input name="{0}" type="text" placeholder="{1}">'.format(self.name, self.placeholder)
  406. self.body += '<input type="submit" value="{0}"></form>'.format(self.value)
  407. # self.body += str(
  408. # '<form method="POST" enctype="multipart/form-data" ' +
  409. # 'action="%s"><br><input name="%s" type="text" placeholder="%s">' % (self.action, self.name, self.placeholder) +
  410. # '<input type="submit" value="%s"></form>' % self.value)
  411. self.renderHTML()
  412. def renderHTML(self):
  413. self.doc = str(
  414. '<!DOCTYPE html>' +
  415. '<meta charset="utf-8">' +
  416. '<html>' +
  417. '<head>' +
  418. ' <title>' + self.title + '</title>' +
  419. ' <link rel="icon" href="/image/favicon.ico">' +
  420. ' <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" />' +
  421. ' <link rel="stylesheet" type="text/css" href="/css/restaurant.css" />' +
  422. '</head>' +
  423. '<body>' +
  424. ' <div class="container-fluid">' +
  425. self.head +
  426. ' <p>' +
  427. self.body +
  428. ' </p>' +
  429. ' <script src="/js/jquery.min.js"></script>' +
  430. ' <script src="/js/bootstrap.min.js"></script>' +
  431. ' </div>' +
  432. '</body>' +
  433. ' <div class="container-fluid">' +
  434. self.foot +
  435. ' </div>' +
  436. '</html>')
  437. def renderTable(self, dict):
  438. pass
  439. # <table class="table table-condensed">
  440. # <thead>
  441. # <tr>
  442. # <th>'Restaurant'</th>
  443. # <th>QF Name</th>
  444. # <th>Versions</th>
  445. # </tr>
  446. # </thead>
  447. # {%for model in models%}
  448. # <tbody>
  449. # <tr>
  450. # <td>{{model['class']}}</td>
  451. # <td>{{model['qf_name']}}</td>
  452. # <td>{{model['versions']}}</td>
  453. # </tr>
  454. # </tbody>
  455. # {%end%}
  456. # </table>
  457. # class Server(object):
  458. # '''server object for assembling model objects'''
  459. # freshness = 3600
  460. # def __init__(self, db=args.mongo_server):
  461. # args.mongo_server = db or args.mongo_server
  462. # # self.db = args.mongo_server
  463. # self.r = rplace.RPLACE(args.mongo_server)
  464. # self.h = html_obj()
  465. # self.refreshed = 0
  466. # self.refresh()
  467. # self.r.setChildNodes()
  468. # self.r.setMiniNodes()
  469. # self.setRouteTable()
  470. # if args.start == False: pargs()
  471. # def load(self):
  472. # self.r.setObjViv()
  473. # def refresh(self, force=False):
  474. # '''refresh models from DAO, store in sorted order based on sort keys'''
  475. # print(util.logger('IO read') + 'refreshing server objects...')
  476. # force = bool(force)
  477. # if force == True or self.refreshed < int(util.strftime('%s',util.localtime())) - self.freshness:
  478. # self.load()
  479. # self.refreshed = int(util.strftime('%s',util.localtime()))
  480. # print(util.logger('Status') + 'server objects last refreshed: ' + str(util.strftime('%Y-%m-%d %H:%M:%S',util.localtime(self.refreshed))))
  481. # logger.error('server objects last refreshed: ' + str(util.strftime('%Y-%m-%d %H:%M:%S',util.localtime(self.refreshed))))
  482. # return
  483. # def getRefreshedTime(self): return util.displayTime(option=1, value=self.refreshed)
  484. # def setRouteTable(self):
  485. # self.route_table = Application([
  486. # # -- pages --#
  487. # url(r"/", MainHandler),
  488. # url(r"/(robots.txt|sitemap.xml)", StaticFileHandler, {"path": "admin/"}),
  489. # url(r"/objectives", ObjectiveHandler),
  490. # # -- data --#
  491. # url(r"/data/(.*)", StaticFileHandler, {"path": "data/"}),
  492. # url(r"/objective_json", ObjectiveJSONHandler),
  493. # url(r"/mini_nodes", MiniNodeHandler),
  494. # url(r"/obj_nodes", ObjectiveNodeHandler),
  495. # # -- files --#
  496. # url(r"/html/(.*)", StaticFileHandler, {"path": "html/"}),
  497. # url(r"/fonts/(.*)", StaticFileHandler, {"path": "fonts/"}),
  498. # url(r"/image/(.*)", StaticFileHandler, {"path": "image/"}),
  499. # url(r"/css/(.*)", StaticFileHandler, {"path": "css/"}),
  500. # url(r"/js/(.*)", StaticFileHandler, {"path": "js/"}),
  501. # # -- test --#
  502. # url(r"/app", RedirectHandler, dict(url="http://itunes.apple.com/my-app-id")),
  503. # url(r"/co", CoHandler),
  504. # url(r"/api/", ApiHandler),
  505. # url(r"/hello", HelloHandler),
  506. # url(r"/hello_body", HelloBodyHandler),
  507. # url(r"/myform", FormHandler),
  508. # url(r"/static/(.*)", StaticFileHandler, {"path": "html/"}),
  509. # url(r"/example/([0-9]+)", ExampleHandler, dict(db=None), name="example"),
  510. # url(r"/story/([0-9]+)", StoryHandler, dict(db=None), name="story"),
  511. # url(r"/template", TemplateHandler),
  512. # url(r"/template_html", TemplateHandler, {"path": "html/"}),
  513. # # url(r"/photos/(.*)", MyPhotoHandler),
  514. # # url(r"/pictures/(.*)", tornado.web.RedirectHandler, dict(url=r"/photos/\1")),
  515. # ],debug=args.debug)
  516. #
  517. # ## =====================
  518. # ## == handler classes ==
  519. # ## =====================
  520. #
  521. # class MainHandler(RequestHandler):
  522. # '''main route'''
  523. # def get(self):
  524. # self.render('html/index.html')
  525. # # self.write('<a href="%s">link to story 1</a>' % self.reverse_url("story", "1"))
  526. #
  527. # class ObjectiveHandler(RequestHandler):
  528. # '''starburst route'''
  529. # def get(self):
  530. # self.render('html/sunburst.html')
  531. #
  532. # class ObjectiveJSONHandler(RequestHandler):
  533. # '''autoviv derived json built from objectives'''
  534. # def get(self):
  535. # self.write(s.r.objective_viv)
  536. #
  537. # class MiniNodeHandler(RequestHandler):
  538. # '''children node derived json built from objectives'''
  539. # def get(self):
  540. # self.write(s.r.obj_mini)
  541. #
  542. # class ObjectiveNodeHandler(RequestHandler):
  543. # '''children node derived json built from objectives'''
  544. # def get(self):
  545. # self.write(s.r.obj_children)
  546. ## ====================
  547. ## == db connection ==
  548. ## ===================
  549. try:
  550. session = sessionmaker()(bind=create_engine('sqlite:///restaurant.db'))
  551. # engine = create_engine('sqlite:///restaurant.db') # multi-line approach
  552. # Base.metadata.bind = engine
  553. # DBSession = sessionmaker(bind=engine) # can bind when creating sessionmaker instance
  554. # session = DBSession()
  555. # DBSession = sessionmaker() # or after
  556. # session = DBSession(bind=engine)
  557. emp = session.query(Employee) # load global objects for convenience
  558. rest = session.query(Restaurant)
  559. addr = session.query(Address)
  560. mi = session.query(MenuItem)
  561. # db = DB() # prefer to put in a class
  562. # emp = db.session.query(Employee)
  563. # rest = db.session.query(Restaurant)
  564. # addr = db.session.query(Address)
  565. # mi = db.session.query(MenuItem)
  566. except:
  567. logger.exception("issue loading restaurant database items", exc_info=1)
  568. ## ====================================================
  569. ## == create server object and run bottle -> tornado ==
  570. ## ====================================================
  571. def main():
  572. try:
  573. server = HTTPServer(('', args.port), webserverHandler)
  574. log_info = "HTTPServer started " + os.environ['HOSTNAME'] + ':' + str(args.port) + ' debug=' + str(args.debug) + ' log_file=' + str(args.log_file)
  575. logger.info(log_info)
  576. server.serve_forever()
  577. except KeyboardInterrupt:
  578. logger.info("HTTPServer stopped via control-C")
  579. server.socket.close() # server not in scope...
  580. except OSError:
  581. logger.exception("HTTPServer server already running?", exc_info=1)
  582. except:
  583. logger.exception("hmmm, we have a problem", exc_info=1)
  584. # server.socket.close() # server not in scope...
  585. if args.start == True:
  586. #if __name__== '__main__':
  587. main()
  588. # def main
  589. # if args.start == True:
  590. # global s
  591. # s = Server(db=args.mongo_server)
  592. # logger.info('Tornado server running on: ' + os.environ['HOSTNAME'] + ':' + str(args.port) + ' debug = ' + str(args.debug))
  593. # s.route_table.listen(args.port)
  594. # IOLoop.current().start()
  595. # enable_pretty_logging()