web.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. # -*- coding: utf-8 -*-
  2. """
  3. demeter
  4. name:web.py
  5. author:rabin
  6. """
  7. from gevent import monkey
  8. monkey.patch_all()
  9. import gevent
  10. import functools
  11. import os
  12. import json
  13. from demeter.core import *
  14. import tornado.web
  15. import tornado.ioloop
  16. import tornado.httpserver
  17. import tornado.httpclient
  18. import tornado.concurrent
  19. class Base(tornado.web.RequestHandler):
  20. def initialize(self):
  21. try:
  22. Demeter.request = self
  23. self.assign()
  24. self.page()
  25. self.cookie()
  26. self.setting()
  27. except Exception as e:
  28. return
  29. def get_current_user(self):
  30. return self.get_secure_cookie(self.KEYS[0])
  31. def assign(self):
  32. self.data = {}
  33. self.data['setting'] = Demeter.config['setting']
  34. self.data['base'] = Demeter.config['base']
  35. def cookie(self):
  36. for key in self.KEYS:
  37. cookie = None
  38. """
  39. if key in self.data['base']:
  40. cookie = self.data['base'][key]
  41. """
  42. if not cookie:
  43. cookie = self.get_secure_cookie(key)
  44. #cookie = self.get_cookie(key)
  45. if not cookie:
  46. value = self.input(key)
  47. if value:
  48. #self.set_secure_cookie(key, value)
  49. self.data['setting'][key] = value
  50. else:
  51. self.data['setting'][key] = 0
  52. else:
  53. self.data['setting'][key] = cookie
  54. def page(self):
  55. Demeter.config['page'] = {}
  56. page = self.input('page')
  57. if page:
  58. Demeter.config['page']['ajax'] = True
  59. else:
  60. Demeter.config['page']['ajax'] = False
  61. page = 1
  62. Demeter.config['page']['current'] = page
  63. Demeter.config['page']['total'] = 0
  64. self.data['page'] = Demeter.config['page']
  65. def search(self):
  66. data = self.request.arguments
  67. self.data['search'] = {}
  68. self.data['update'] = {}
  69. for key in data:
  70. if 'search_' in key:
  71. index = key.replace('search_', '')
  72. self.data['search'][index] = ",".join(data[key])
  73. if 'update_' in key:
  74. index = key.replace('update_', '')
  75. self.data['update'][index] = ",".join(data[key])
  76. def input(self, key, value=None):
  77. return self.get_argument(key, value)
  78. def inputs(self, key):
  79. return self.get_arguments(key)
  80. def service(self, name):
  81. return Demeter.service(name)
  82. def model(self, name):
  83. return Demeter.model(name)
  84. def set(self, **kwd):
  85. self.data['common'] = kwd
  86. self.data['common']['argvs'] = ''
  87. def show(self, name):
  88. self.view('common/'+name+'.html')
  89. def list(self, model, order = 'cdate desc'):
  90. self.data['state'] = self.input('state', True)
  91. self.data['list'] = self.service('common').list(model, state=self.data['state'], search=self.data['search'], page=True, order=order)
  92. def one(self, model, **kwd):
  93. id = self.input('id')
  94. self.data['info'] = {}
  95. if id:
  96. kwd['id'] = id
  97. if kwd:
  98. self.data['info'] = self.service('common').one(model, **kwd)
  99. def update(self, model, msg='', id=0, **kwd):
  100. if not self.data['auth']:
  101. self.auth()
  102. else:
  103. if id <= 0:
  104. id = self.input('id')
  105. if kwd:
  106. info = self.service('common').one(model, **kwd)
  107. if info and (id != info['id']):
  108. self.out(msg)
  109. return
  110. state = self.service('common').update(model, id, self.data['update'])
  111. self.log(model, 'update', self.data['update'])
  112. self.out('yes', {'id':state})
  113. return state
  114. def delete(self, model):
  115. if not self.data['auth']:
  116. self.auth()
  117. else:
  118. id = self.input('id')
  119. state = self.input('state', False)
  120. state = self.service('common').delete(model, id, state)
  121. self.log(model, 'delete', {id:id, state:state})
  122. self.out('yes', {'state':state})
  123. def log(self, model, method, data):
  124. if 'admin' in self.data['setting'] and self.data['setting']['admin'] > 0:
  125. insert = {}
  126. insert['admin_id'] = self.data['setting']['admin']
  127. insert['model'] = model
  128. insert['method'] = method
  129. insert['data'] = json.dumps(data)
  130. self.service('common').update('manage_log', None, insert)
  131. def view(self, name):
  132. if not self.data['auth']:
  133. self.auth()
  134. else:
  135. config = Demeter.config[Demeter.web]
  136. path = ''
  137. if 'mobile' in config:
  138. mobile = Demeter.checkMobile(self.request)
  139. if mobile:
  140. path = 'mobile/'
  141. else:
  142. path = 'pc/'
  143. self.render(path + name, data=self.data, Demeter=Demeter)
  144. def auth(self):
  145. self.out('您没有权限')
  146. def out(self, msg='', data={}, code=0):
  147. if data:
  148. if 'page' in data and data['page']['total'] <= 0:
  149. del data['page']
  150. if 'update' in data and not data['update']:
  151. del data['update']
  152. if 'search' in data and not data['search']:
  153. del data['search']
  154. callback = self.input('callback')
  155. function = self.input('function')
  156. result = ''
  157. send = {}
  158. send['status'] = 1
  159. send['msg'] = msg
  160. send['data'] = data
  161. send['code'] = code
  162. if not send['data']:
  163. send['status'] = 2
  164. result = json.dumps(send)
  165. if callback:
  166. result = callback + '(' + result + ')'
  167. elif function:
  168. result = '<script>parent.' + function + '(' + result + ')' + '</script>';
  169. self.write(result)
  170. self.finish()
  171. class Web(object):
  172. @classmethod
  173. def auth(self, method):
  174. return tornado.web.authenticated(method)
  175. @classmethod
  176. def setting(self, method):
  177. return self.async(method)
  178. @staticmethod
  179. def async(method):
  180. @tornado.web.asynchronous
  181. @tornado.gen.coroutine
  182. @functools.wraps(method)
  183. def callback(self, *args, **kwargs):
  184. #self._auto_finish = False
  185. try:
  186. result = method(self, *args, **kwargs)
  187. return result
  188. except Exception as e:
  189. import traceback
  190. tracebak.print_exc()
  191. try:
  192. return self.view('404.html')
  193. except Exception as e:
  194. return self.out('404')
  195. #return gevent.spawn(method, self, *args, **kwargs)
  196. return callback
  197. @classmethod
  198. def init(self, application):
  199. for v in application:
  200. self.load(v)
  201. @classmethod
  202. def load(self, package):
  203. """
  204. path = os.path.split(os.path.realpath(file))[0] + '/'
  205. sys.path.append(path)
  206. files = self.file(path)
  207. """
  208. url = []
  209. for key in Demeter.getPackage(package):
  210. module = Demeter.getObject(key)
  211. url = self.url(module, key, url)
  212. Demeter.route = Demeter.route + url
  213. """
  214. @staticmethod
  215. def file(path):
  216. files = os.listdir(path)
  217. result = []
  218. for key in files:
  219. if key and '.DS_Store' not in key and '__' not in key and 'pyc' not in key:
  220. key = key.replace('.py', '')
  221. result.append(key)
  222. return result
  223. """
  224. @staticmethod
  225. def url(module, key, url):
  226. str = Demeter.getMethod(module)
  227. key = key.split('.')[-1]
  228. for i,j in str:
  229. act = ''
  230. if '_path' in i:
  231. act = i.replace('_path', '')
  232. if '_html' in i:
  233. act = i.replace('_html', '.html')
  234. if act:
  235. attr = getattr(module, i)
  236. if key == 'main' and act == 'index':
  237. url.append((r'/', attr))
  238. elif key == act or act == 'index':
  239. url.append((r'/'+key, attr))
  240. url.append((r'/'+key+'/'+act, attr))
  241. return url
  242. @classmethod
  243. def start(self, application=[]):
  244. self.init(application)
  245. if 'route' in Demeter.config['setting']:
  246. Demeter.echo(Demeter.route)
  247. config = Demeter.config[Demeter.web]
  248. cookie = False
  249. if 'tornado' not in Demeter.config:
  250. Demeter.config['tornado'] = {}
  251. if 'xsrf_cookies' in config:
  252. cookie = Demeter.bool(config['xsrf_cookies'])
  253. settings = dict({
  254. "static_path": Demeter.webPath + 'static',
  255. "template_path": Demeter.webPath + 'templates',
  256. "cookie_secret": 'demeter',
  257. "login_url": '/user/login',
  258. "xsrf_cookies": cookie,
  259. "debug": Demeter.bool(config['debug']),
  260. #"autoreload": Demeter.bool(config['autoreload']),
  261. "port": config['port'],
  262. "max_buffer_size": int(config['max_buffer_size']),
  263. "process": int(config['process'])
  264. }, **Demeter.config['tornado'])
  265. com = ('cookie_secret', 'login_url', 'static_path', 'template_path')
  266. for v in com:
  267. if v in config:
  268. settings[v] = config[v]
  269. handlers = []
  270. def application_setting():
  271. handlers.append((r"/upload/(.*)", tornado.web.StaticFileHandler, {"path": Demeter.path + 'runtime/upload/'}))
  272. handlers.append((r"/qrcode/(.*)", tornado.web.StaticFileHandler, {"path": Demeter.path + 'runtime/qrcode/'}))
  273. handlers.append((r"/camera/(.*)", tornado.web.StaticFileHandler, {"path": Demeter.path + 'runtime/camera/'}))
  274. handlers.append((r"/static/(.*)", tornado.web.StaticFileHandler, {"path": "static"}))
  275. handlers.append((r"/(apple-touch-icon\.png)", tornado.web.StaticFileHandler, dict(path=settings['static_path'])))
  276. handlers.extend(Demeter.route)
  277. application_setting()
  278. application = tornado.web.Application(handlers=handlers, **settings)
  279. if settings['debug'] == True:
  280. application.listen(settings['port'])
  281. tornado.ioloop.IOLoop.instance().start()
  282. else:
  283. server = tornado.httpserver.HTTPServer(application, settings['max_buffer_size'])
  284. server.bind(settings['port'])
  285. server.start(settings['process'])
  286. try:
  287. Demeter.echo('running on port %s' % settings['port'])
  288. tornado.ioloop.IOLoop.instance().start()
  289. except KeyboardInterrupt:
  290. tornado.ioloop.IOLoop.instance().stop()