You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

handler.py 9.3 KiB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. # Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. #
  3. # MIT License (MIT)
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the "Software"),
  7. # to deal in the Software without restriction, including without limitation
  8. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #
  22. from __future__ import unicode_literals
  23. import sys, os
  24. import webnotes
  25. import webnotes.utils
  26. import webnotes.sessions
  27. form = webnotes.form
  28. form_dict = webnotes.form_dict
  29. sql = None
  30. session = None
  31. errdoc = ''
  32. errdoctype = ''
  33. errmethod = ''
  34. def get_cgi_fields():
  35. """make webnotes.form_dict from cgi field storage"""
  36. import cgi
  37. import webnotes
  38. from webnotes.utils import cstr
  39. # make the form_dict
  40. webnotes.form = cgi.FieldStorage(keep_blank_values=True)
  41. for key in webnotes.form.keys():
  42. # file upload must not be decoded as it is treated as a binary
  43. # file and hence in any encoding (it does not matter)
  44. if not getattr(webnotes.form[key], 'filename', None):
  45. webnotes.form_dict[key] = cstr(webnotes.form.getvalue(key))
  46. @webnotes.whitelist(allow_guest=True)
  47. def startup():
  48. webnotes.response.update(webnotes.sessions.get())
  49. def cleanup_docs():
  50. import webnotes.model.utils
  51. if webnotes.response.get('docs') and type(webnotes.response['docs'])!=dict:
  52. webnotes.response['docs'] = webnotes.model.utils.compress(webnotes.response['docs'])
  53. @webnotes.whitelist()
  54. def runserverobj(arg=None):
  55. import webnotes.widgets.form.run_method
  56. webnotes.widgets.form.run_method.runserverobj()
  57. @webnotes.whitelist(allow_guest=True)
  58. def logout():
  59. webnotes.login_manager.logout()
  60. @webnotes.whitelist(allow_guest=True)
  61. def web_logout():
  62. webnotes.repsond_as_web_page("Logged Out", """<p>You have been logged out.</p>
  63. <p><a href='index'>Back to Home</a></p>""")
  64. webnotes.login_manager.logout()
  65. @webnotes.whitelist()
  66. def uploadfile():
  67. import webnotes.utils
  68. import webnotes.utils.file_manager
  69. import json
  70. try:
  71. if webnotes.form_dict.get('from_form'):
  72. try:
  73. ret = webnotes.utils.file_manager.upload()
  74. except webnotes.DuplicateEntryError, e:
  75. # ignore pass
  76. ret = None
  77. webnotes.conn.rollback()
  78. else:
  79. if webnotes.form_dict.get('method'):
  80. ret = webnotes.get_method(webnotes.form_dict.method)()
  81. except Exception, e:
  82. webnotes.errprint(webnotes.utils.getTraceback())
  83. ret = None
  84. return ret
  85. @webnotes.whitelist(allow_guest=True)
  86. def reset_password(user):
  87. from webnotes.model.code import get_obj
  88. from webnotes.utils import random_string
  89. user = webnotes.form_dict.get('user', '')
  90. if user in ["demo@erpnext.com", "Administrator"]:
  91. return "Not allowed"
  92. if webnotes.conn.sql("""select name from tabProfile where name=%s""", user):
  93. new_password = random_string(8)
  94. webnotes.conn.sql("""update `__Auth` set password=password(%s)
  95. where `user`=%s""", (new_password, user))
  96. # Hack!
  97. webnotes.session["user"] = "Administrator"
  98. profile = get_obj("Profile", user)
  99. profile.password_reset_mail(new_password)
  100. return "Password has been reset and sent to your email id."
  101. else:
  102. return "No such user (%s)" % user
  103. def handle():
  104. """handle request"""
  105. cmd = webnotes.form_dict['cmd']
  106. if cmd!='login':
  107. # login executed in webnotes.auth
  108. if webnotes.request_method == "POST":
  109. webnotes.conn.begin()
  110. try:
  111. execute_cmd(cmd)
  112. except webnotes.ValidationError, e:
  113. webnotes.errprint(webnotes.utils.getTraceback())
  114. if webnotes.request_method == "POST":
  115. webnotes.conn.rollback()
  116. except webnotes.PermissionError, e:
  117. webnotes.errprint(webnotes.utils.getTraceback())
  118. webnotes.response['403'] = 1
  119. if webnotes.request_method == "POST":
  120. webnotes.conn.rollback()
  121. except:
  122. webnotes.errprint(webnotes.utils.getTraceback())
  123. if webnotes.request_method == "POST":
  124. webnotes.conn and webnotes.conn.rollback()
  125. if webnotes.request_method == "POST" and webnotes.conn:
  126. webnotes.conn.commit()
  127. print_response()
  128. if webnotes.conn:
  129. webnotes.conn.close()
  130. if webnotes._memc:
  131. webnotes._memc.disconnect_all()
  132. def execute_cmd(cmd):
  133. """execute a request as python module"""
  134. method = get_method(cmd)
  135. # check if whitelisted
  136. if webnotes.session['user'] == 'Guest':
  137. if (method not in webnotes.guest_methods):
  138. webnotes.response['403'] = 1
  139. raise Exception, 'Not Allowed, %s' % str(method)
  140. else:
  141. if not method in webnotes.whitelisted:
  142. webnotes.response['403'] = 1
  143. webnotes.msgprint('Not Allowed, %s' % str(method))
  144. raise Exception, 'Not Allowed, %s' % str(method)
  145. ret = call(method, webnotes.form_dict)
  146. # returns with a message
  147. if ret:
  148. webnotes.response['message'] = ret
  149. # update session
  150. webnotes.session_obj.update()
  151. def call(fn, args):
  152. import inspect
  153. fnargs, varargs, varkw, defaults = inspect.getargspec(fn)
  154. newargs = {}
  155. for a in fnargs:
  156. if a in args:
  157. newargs[a] = args.get(a)
  158. return fn(**newargs)
  159. def get_method(cmd):
  160. """get method object from cmd"""
  161. if '.' in cmd:
  162. method = webnotes.get_method(cmd)
  163. else:
  164. method = globals()[cmd]
  165. webnotes.log("method:" + cmd)
  166. return method
  167. def print_response():
  168. print_map = {
  169. 'csv': print_csv,
  170. 'iframe': print_iframe,
  171. 'download': print_raw,
  172. 'json': print_json,
  173. 'page': print_page
  174. }
  175. print_map.get(webnotes.response.get('type'), print_json)()
  176. def print_page():
  177. """print web page"""
  178. print_cookie_header()
  179. from webnotes.webutils import render
  180. render(webnotes.response['page_name'])
  181. def eprint(content):
  182. print content.encode('utf-8')
  183. def print_json():
  184. make_logs()
  185. cleanup_docs()
  186. print_cookie_header()
  187. eprint("Content-Type: text/html; charset: utf-8")
  188. import json
  189. print_zip(json.dumps(webnotes.response, default=json_handler, separators=(',',':')))
  190. def print_csv():
  191. eprint("Content-Type: text/csv; charset: utf-8")
  192. eprint("Content-Disposition: attachment; filename=%s.csv" % webnotes.response['doctype'].replace(' ', '_'))
  193. eprint("")
  194. eprint(webnotes.response['result'])
  195. def print_iframe():
  196. eprint("Content-Type: text/html; charset: utf-8")
  197. eprint("")
  198. eprint(webnotes.response.get('result') or '')
  199. if webnotes.error_log:
  200. import json
  201. eprint("""\
  202. <script>
  203. var messages = %(messages)s;
  204. if (messages.length) {
  205. for (var i in messages) {
  206. window.parent.msgprint(messages[i]);
  207. }
  208. }
  209. var errors = %(errors)s;
  210. if (errors.length) {
  211. for (var i in errors) {
  212. window.parent.console.log(errors[i]);
  213. }
  214. }
  215. </script>""" % {
  216. 'messages': json.dumps(webnotes.message_log).replace("'", "\\'"),
  217. 'errors': json.dumps(webnotes.error_log).replace("'", "\\'"),
  218. })
  219. def print_raw():
  220. eprint("Content-Type: %s" % \
  221. mimetypes.guess_type(webnotes.response['filename'])[0] \
  222. or 'application/unknown'),
  223. eprint("Content-Disposition: filename=%s" % \
  224. webnotes.response['filename'].replace(' ', '_'))
  225. eprint("")
  226. eprint(webnotes.response['filecontent'])
  227. def make_logs():
  228. """make strings for msgprint and errprint"""
  229. import json, conf
  230. from webnotes.utils import cstr
  231. if webnotes.error_log:
  232. # webnotes.response['exc'] = json.dumps("\n".join([cstr(d) for d in webnotes.error_log]))
  233. webnotes.response['exc'] = json.dumps([cstr(d) for d in webnotes.error_log])
  234. if webnotes.message_log:
  235. webnotes.response['_server_messages'] = json.dumps([cstr(d) for d in webnotes.message_log])
  236. if webnotes.debug_log and getattr(conf, "logging", False):
  237. webnotes.response['_debug_messages'] = json.dumps(webnotes.debug_log)
  238. def print_cookie_header():
  239. """if there ar additional cookies defined during the request, add them"""
  240. if webnotes.cookies or webnotes.add_cookies:
  241. for c in webnotes.add_cookies.keys():
  242. webnotes.cookies[c.encode('utf-8')] = \
  243. webnotes.add_cookies[c].encode('utf-8')
  244. if webnotes.cookies:
  245. print webnotes.cookies
  246. def print_zip(response):
  247. response = response.encode('utf-8')
  248. orig_len = len(response)
  249. if accept_gzip() and orig_len>512:
  250. response = compressBuf(response)
  251. eprint("Content-Encoding: gzip")
  252. eprint("Original-Length: %d" % orig_len)
  253. eprint("Content-Length: %d" % len(response))
  254. eprint("")
  255. print response
  256. def json_handler(obj):
  257. """serialize non-serializable data for json"""
  258. import datetime
  259. # serialize date
  260. if isinstance(obj, (datetime.date, datetime.timedelta, datetime.datetime)):
  261. return unicode(obj)
  262. else:
  263. raise TypeError, """Object of type %s with value of %s is not JSON serializable""" % \
  264. (type(obj), repr(obj))
  265. def accept_gzip():
  266. if "gzip" in os.environ.get("HTTP_ACCEPT_ENCODING", ""):
  267. return True
  268. def compressBuf(buf):
  269. import gzip, cStringIO
  270. zbuf = cStringIO.StringIO()
  271. zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5)
  272. zfile.write(buf)
  273. zfile.close()
  274. return zbuf.getvalue()