diff --git a/core/doctype/documentation_tool/documentation_tool.py b/core/doctype/documentation_tool/documentation_tool.py index b052672ced..5c6525a790 100644 --- a/core/doctype/documentation_tool/documentation_tool.py +++ b/core/doctype/documentation_tool/documentation_tool.py @@ -447,7 +447,7 @@ def write_docs(data, build_sitemap=None, domain=None): sitemap.write(sitemap_frame_xml % content) def write_static(): - webnotes.session = webnotes._dict({"user":"Administrator"}) + webnotes.local.session = webnotes._dict({"user":"Administrator"}) from markdown2 import markdown diff --git a/core/doctype/profile/profile.py b/core/doctype/profile/profile.py index e822ec5d3f..b2099c17cb 100644 --- a/core/doctype/profile/profile.py +++ b/core/doctype/profile/profile.py @@ -38,7 +38,7 @@ class DocType: # clear sessions if disabled if not cint(self.doc.enabled) and getattr(webnotes, "login_manager", None): - webnotes.login_manager.logout(user=self.doc.name) + webnotes.local.login_manager.logout(user=self.doc.name) def validate_max_users(self): """don't allow more than max users if set in conf""" @@ -215,7 +215,7 @@ Thank you,
# disable the user and log him/her out self.doc.enabled = 0 if getattr(webnotes, "login_manager", None): - webnotes.login_manager.logout(user=self.doc.name) + webnotes.local.login_manager.logout(user=self.doc.name) # delete their password webnotes.conn.sql("""delete from __Auth where user=%s""", self.doc.name) @@ -319,7 +319,7 @@ def update_profile(fullname, password=None): return _("Name is required") webnotes.conn.set_value("Profile", webnotes.session.user, "first_name", fullname) - webnotes.add_cookies["full_name"] = fullname + webnotes._request.set_cookie("full_name", fullname) if password: from webnotes.auth import _update_password diff --git a/webnotes/__init__.py b/webnotes/__init__.py index 5ac03096ff..231e48cc4b 100644 --- a/webnotes/__init__.py +++ b/webnotes/__init__.py @@ -7,6 +7,10 @@ globals attached to webnotes module from __future__ import unicode_literals +from werkzeug.local import Local + +local = Local() + class _dict(dict): """dict like object that exposes keys as attributes""" def __getattr__(self, key): @@ -23,7 +27,10 @@ class _dict(dict): return self def copy(self): return _dict(super(_dict, self).copy()) - + +def __getattr__(self, key): + return webnotes.local.get("key", None) + def _(msg): """translate object in current lang, if exists""" from webnotes.translate import messages @@ -46,26 +53,36 @@ def load_translations(module, doctype, name): from webnotes.translate import load_doc_messages load_doc_messages(module, doctype, name) -request = form_dict = _dict() -conn = None + +# local-globals +conn = local("conn") +form = form_dict = local("form_dict") +request = local("request") +response = local("response") +_response = local("_response") +session = local("session") +user = local("user") + +error_log = local("error_log") +debug_log = local("debug_log") +message_log = local("message_log") + +lang = local("lang") + +def init(): + local.error_log = [] + local.message_log = [] + local.debug_log = [] + local.response = _dict({}) + local.lang = "en" + _memc = None -form = None -session = None -user = None -incoming_cookies = {} -add_cookies = {} # append these to outgoing request -cookies = {} -response = _dict({'message':'', 'exc':''}) -error_log = [] -debug_log = [] -message_log = [] mute_emails = False mute_messages = False test_objects = {} request_method = None print_messages = False user_lang = False -lang = 'en' in_import = False in_test = False rollback_on_exception = False @@ -165,15 +182,11 @@ def remove_file(path): def connect(db_name=None, password=None): import webnotes.db - global conn - conn = webnotes.db.Database(user=db_name, password=password) - - global session - session = _dict({'user':'Administrator'}) + local.conn = webnotes.db.Database(user=db_name, password=password) + local.session = _dict({'user':'Administrator'}) import webnotes.profile - global user - user = webnotes.profile.Profile('Administrator') + local.user = webnotes.profile.Profile('Administrator') def get_env_vars(env_var): import os diff --git a/webnotes/app.py b/webnotes/app.py new file mode 100644 index 0000000000..2299e90189 --- /dev/null +++ b/webnotes/app.py @@ -0,0 +1,58 @@ +import sys, os + +sys.path.extend(["..", "../app", "../lib"]) + +from werkzeug.wrappers import Request, Response +from werkzeug.local import LocalManager + +import mimetypes +import webnotes +import webnotes.handler +import webnotes.auth +import webnotes.webutils + +local_manager = LocalManager([webnotes.local]) + +@Request.application +def application(request): + path = os.path.join("public", request.path[1:]) + if os.path.exists(path) and not os.path.isdir(path) and not path.endswith(".py"): + with open(path, "r") as static: + content = static.read() + + response = Response() + response.response = content + response.headers["Content-type"] = mimetypes.guess_type(path)[0] + return response + + else: + webnotes.local.request = request + webnotes.init() + + webnotes.local.form_dict = webnotes._dict({ k:v[0] if isinstance(v, (list, tuple)) else v \ + for k, v in (request.form or request.args).iteritems() }) + + webnotes.local._response = Response() + + try: + webnotes.http_request = webnotes.auth.HTTPRequest() + except webnotes.AuthenticationError, e: + pass + + # cookies + print request.form + + if webnotes.form_dict.cmd: + webnotes.handler.handle() + else: + webnotes.webutils.render(webnotes.request.path[1:]) + + return webnotes._response + +application = local_manager.make_middleware(application) + +if __name__ == '__main__': + import sys + from werkzeug.serving import run_simple + + run_simple('localhost', 8000, application, use_reloader=True, use_debugger=True, use_evalex=True) \ No newline at end of file diff --git a/webnotes/auth.py b/webnotes/auth.py index 2ca71410eb..d907548da3 100644 --- a/webnotes/auth.py +++ b/webnotes/auth.py @@ -24,7 +24,7 @@ class HTTPRequest: webnotes.remote_ip = webnotes.get_env_vars('REMOTE_ADDR') # load cookies - webnotes.cookie_manager = CookieManager() + webnotes.local.cookie_manager = CookieManager() webnotes.request_method = webnotes.get_env_vars("REQUEST_METHOD") @@ -37,11 +37,11 @@ class HTTPRequest: self.connect() # login - webnotes.login_manager = LoginManager() + webnotes.local.login_manager = LoginManager() # start session - webnotes.session_obj = Session() - webnotes.session = webnotes.session_obj.data + webnotes.local.session_obj = Session() + webnotes.local.session = webnotes.local.session_obj.data # check status if webnotes.conn.get_global("__session_status")=='stop': @@ -53,10 +53,10 @@ class HTTPRequest: # run login triggers if webnotes.form_dict.get('cmd')=='login': - webnotes.login_manager.run_trigger('on_login_post_session') + webnotes.local.login_manager.run_trigger('on_login_post_session') # write out cookies - webnotes.cookie_manager.set_cookies() + webnotes.local.cookie_manager.set_cookies() def set_lang(self, lang): import translate @@ -94,7 +94,7 @@ class HTTPRequest: def connect(self, ac_name = None): """connect to db, from ac_name or db_name""" - webnotes.conn = webnotes.db.Database(user = self.get_db_name(), \ + webnotes.local.conn = webnotes.db.Database(user = self.get_db_name(), \ password = getattr(conf,'db_password', '')) class LoginManager: @@ -114,7 +114,7 @@ class LoginManager: full_name = " ".join(filter(None, [info.first_name, info.last_name])) webnotes.response["full_name"] = full_name - webnotes.add_cookies["full_name"] = full_name + webnotes._response.set_cookie("full_name", full_name) def post_login(self): self.run_trigger() @@ -212,25 +212,14 @@ class LoginManager: clear_sessions(user) if user == webnotes.session.user: - webnotes.add_cookies["full_name"] = "" - webnotes.add_cookies["sid"] = "" + webnotes._response.delete_cookie("full_name") + webnotes._response.delete_cookie("sid") + webnotes._response.set_cookie("full_name", "") + webnotes._response.set_cookie("sid", "") class CookieManager: def __init__(self): - import Cookie - webnotes.cookies = Cookie.SimpleCookie() - self.get_incoming_cookies() - - def get_incoming_cookies(self): - import os - cookies = {} - if 'HTTP_COOKIE' in os.environ: - c = os.environ['HTTP_COOKIE'] - webnotes.cookies.load(c) - for c in webnotes.cookies.values(): - cookies[c.key] = c.value - - webnotes.incoming_cookies = cookies + pass def set_cookies(self): if not webnotes.session.get('sid'): return @@ -238,12 +227,10 @@ class CookieManager: # sid expires in 3 days expires = datetime.datetime.now() + datetime.timedelta(days=3) - expires = expires.strftime('%a, %d %b %Y %H:%M:%S') - - webnotes.cookies[b'sid'] = webnotes.session['sid'].encode('utf-8') - webnotes.cookies[b'sid'][b'expires'] = expires.encode('utf-8') - - webnotes.cookies[b'country'] = webnotes.session.get("session_country") + if webnotes.session.sid: + webnotes._response.set_cookie("sid", webnotes.session.sid, expires = expires) + if webnotes.session.session_country: + webnotes._response.set_cookie('country', webnotes.session.get("session_country")) def set_remember_me(self): from webnotes.utils import cint @@ -256,11 +243,8 @@ class CookieManager: import datetime expires = datetime.datetime.now() + \ datetime.timedelta(days=remember_days) - expires = expires.strftime('%a, %d %b %Y %H:%M:%S') - webnotes.cookies[b'remember_me'] = 1 - for k in webnotes.cookies.keys(): - webnotes.cookies[k][b'expires'] = expires.encode('utf-8') + webnotes._response.set_cookie["remember_me"] = 1 def _update_password(user, password): diff --git a/webnotes/handler.py b/webnotes/handler.py index 6643d4c4c2..55001f163e 100755 --- a/webnotes/handler.py +++ b/webnotes/handler.py @@ -7,29 +7,6 @@ import webnotes import webnotes.utils import webnotes.sessions -form = webnotes.form -form_dict = webnotes.form_dict - -sql = None -session = None -errdoc = '' -errdoctype = '' -errmethod = '' - -def get_cgi_fields(): - """make webnotes.form_dict from cgi field storage""" - import cgi - import webnotes - from webnotes.utils import cstr - - # make the form_dict - webnotes.form = cgi.FieldStorage(keep_blank_values=True) - for key in webnotes.form.keys(): - # file upload must not be decoded as it is treated as a binary - # file and hence in any encoding (it does not matter) - if not getattr(webnotes.form[key], 'filename', None): - webnotes.form_dict[key] = cstr(webnotes.form.getvalue(key)) - @webnotes.whitelist(allow_guest=True) def startup(): webnotes.response.update(webnotes.sessions.get()) @@ -46,13 +23,13 @@ def runserverobj(arg=None): @webnotes.whitelist(allow_guest=True) def logout(): - webnotes.login_manager.logout() + webnotes.local.login_manager.logout() @webnotes.whitelist(allow_guest=True) def web_logout(): webnotes.repsond_as_web_page("Logged Out", """

You have been logged out.

Back to Home

""") - webnotes.login_manager.logout() + webnotes.local.login_manager.logout() @webnotes.whitelist() def uploadfile(): @@ -134,7 +111,7 @@ def execute_cmd(cmd): webnotes.response['message'] = ret # update session - webnotes.session_obj.update() + webnotes.local.session_obj.update() def call(fn, args): @@ -158,7 +135,6 @@ def get_method(cmd): def print_response(): print_map = { 'csv': print_csv, - 'iframe': print_iframe, 'download': print_raw, 'json': print_json, 'page': print_page @@ -168,64 +144,35 @@ def print_response(): def print_page(): """print web page""" - print_cookie_header() from webnotes.webutils import render render(webnotes.response['page_name']) -def eprint(content): - print content.encode('utf-8') - def print_json(): make_logs() cleanup_docs() - print_cookie_header() - eprint("Content-Type: text/html; charset: utf-8") + webnotes._response.headers["Content-Type"] = "text/html; charset: utf-8" import json - print_zip(json.dumps(webnotes.response, default=json_handler, separators=(',',':'))) + + print webnotes.response + + print_zip(json.dumps(webnotes.local.response, default=json_handler, separators=(',',':'))) def print_csv(): - eprint("Content-Type: text/csv; charset: utf-8") - eprint("Content-Disposition: attachment; filename=%s.csv" % webnotes.response['doctype'].replace(' ', '_')) - eprint("") - eprint(webnotes.response['result']) - -def print_iframe(): - eprint("Content-Type: text/html; charset: utf-8") - eprint("") - eprint(webnotes.response.get('result') or '') - - if webnotes.error_log: - import json - eprint("""\ - """ % { - 'messages': json.dumps(webnotes.message_log).replace("'", "\\'"), - 'errors': json.dumps(webnotes.error_log).replace("'", "\\'"), - }) + webnotes._response.headers["Content-Type"] = \ + "text/csv; charset: utf-8" + webnotes._response.headers["Content-Disposition"] = \ + "attachment; filename=%s.csv" % webnotes.response['doctype'].replace(' ', '_') + webnotes._response.response = webnotes.response['result'] def print_raw(): - eprint("Content-Type: %s" % \ - mimetypes.guess_type(webnotes.response['filename'])[0] \ - or 'application/unknown'), - eprint("Content-Disposition: filename=%s" % \ - webnotes.response['filename'].replace(' ', '_')) - eprint("") - eprint(webnotes.response['filecontent']) + webnotes._response.headers["Content-Type"] = \ + mimetypes.guess_type(webnotes.response['filename'])[0] or "application/unknown" + webnotes._response.headers["Content-Disposition"] = \ + "filename=%s" % webnotes.response['filename'].replace(' ', '_') + webnotes._response.response = webnotes.response['filecontent'] def make_logs(): """make strings for msgprint and errprint""" @@ -241,28 +188,15 @@ def make_logs(): if webnotes.debug_log and getattr(conf, "logging", False): webnotes.response['_debug_messages'] = json.dumps(webnotes.debug_log) -def print_cookie_header(): - """if there ar additional cookies defined during the request, add them""" - if webnotes.cookies or webnotes.add_cookies: - for c in webnotes.add_cookies.keys(): - webnotes.cookies[c.encode('utf-8')] = \ - webnotes.add_cookies[c].encode('utf-8') - - if webnotes.cookies: - print webnotes.cookies - def print_zip(response): response = response.encode('utf-8') orig_len = len(response) if accept_gzip() and orig_len>512: response = compressBuf(response) - eprint("Content-Encoding: gzip") - eprint("Original-Length: %d" % orig_len) + webnotes._response.headers["Content-Encoding"] = "gzip" - eprint("Content-Length: %d" % len(response)) - - eprint("") - print response + webnotes._response.headers["Content-Length"] = str(len(response)) + webnotes._response.response = response def json_handler(obj): """serialize non-serializable data for json""" diff --git a/webnotes/sessions.py b/webnotes/sessions.py index 3e63ea2657..ebc1fa3b1f 100644 --- a/webnotes/sessions.py +++ b/webnotes/sessions.py @@ -73,7 +73,7 @@ def get(): class Session: def __init__(self, user=None): self.user = user - self.sid = webnotes.form_dict.get('sid') or webnotes.incoming_cookies.get('sid', 'Guest') + self.sid = webnotes.form_dict.get('sid') or webnotes.request.cookies.get('sid', 'Guest') self.data = webnotes._dict({'user':user,'data': webnotes._dict({})}) self.time_diff = None @@ -90,14 +90,14 @@ class Session: import webnotes.utils # generate sid - if webnotes.login_manager.user=='Guest': + if webnotes.local.login_manager.user=='Guest': sid = 'Guest' else: sid = webnotes.generate_hash() - self.data['user'] = webnotes.login_manager.user + self.data['user'] = webnotes.local.login_manager.user self.data['sid'] = sid - self.data['data']['user'] = webnotes.login_manager.user + self.data['data']['user'] = webnotes.local.login_manager.user self.data['data']['session_ip'] = os.environ.get('REMOTE_ADDR') self.data['data']['last_updated'] = webnotes.utils.now() self.data['data']['session_expiry'] = self.get_expiry_period() @@ -113,7 +113,7 @@ class Session: webnotes.conn.commit() # set cookies to write - webnotes.session = self.data + webnotes.local.session = self.data def insert_session_record(self): webnotes.conn.sql("""insert into tabSessions @@ -196,7 +196,7 @@ class Session: def start_as_guest(self): """all guests share the same 'Guest' session""" - webnotes.login_manager.login_as_guest() + webnotes.local.login_manager.login_as_guest() self.start() def update(self): diff --git a/webnotes/webutils.py b/webnotes/webutils.py index 2af337d49c..ac965e66aa 100644 --- a/webnotes/webutils.py +++ b/webnotes/webutils.py @@ -19,10 +19,8 @@ def render(page_name): except Exception: html = render_page('error') - - from webnotes.handler import eprint, print_zip - eprint("Content-Type: text/html; charset: utf-8") - print_zip(html) + webnotes._response.headers["Content-Type"] = "text/html; charset: utf-8" + webnotes._response.response = html def render_page(page_name): """get page html""" diff --git a/webnotes/widgets/page.py b/webnotes/widgets/page.py index c9303a1e87..b1deb354a3 100644 --- a/webnotes/widgets/page.py +++ b/webnotes/widgets/page.py @@ -6,8 +6,6 @@ import webnotes import webnotes.model.doc import webnotes.model.code -conn = webnotes.conn - @webnotes.whitelist() def get(name): """ diff --git a/webnotes/widgets/query_builder.py b/webnotes/widgets/query_builder.py index 44de375df5..61991c7eb9 100644 --- a/webnotes/widgets/query_builder.py +++ b/webnotes/widgets/query_builder.py @@ -4,7 +4,6 @@ from __future__ import unicode_literals import webnotes -session = webnotes.session sql = webnotes.conn.sql out = webnotes.response @@ -219,7 +218,7 @@ def runquery(q='', ret=0, from_export=0): q = add_match_conditions(q, tl) webnotes # replace special variables - q = q.replace('__user', session['user']) + q = q.replace('__user', webnotes.session.user) q = q.replace('__today', webnotes.utils.nowdate()) res = sql(q, as_list=1, formatted=formatted)