@@ -11,7 +11,7 @@ from werkzeug.local import Local, release_local | |||||
from werkzeug.exceptions import NotFound | from werkzeug.exceptions import NotFound | ||||
from MySQLdb import ProgrammingError as SQLError | from MySQLdb import ProgrammingError as SQLError | ||||
import os, sys, importlib | |||||
import os, sys, importlib, inspect | |||||
import json | import json | ||||
import semantic_version | import semantic_version | ||||
@@ -459,6 +459,18 @@ def get_attr(method_string): | |||||
modulename = '.'.join(method_string.split('.')[:-1]) | modulename = '.'.join(method_string.split('.')[:-1]) | ||||
methodname = method_string.split('.')[-1] | methodname = method_string.split('.')[-1] | ||||
return getattr(get_module(modulename), methodname) | return getattr(get_module(modulename), methodname) | ||||
def call(fn, *args, **kwargs): | |||||
if hasattr(fn, 'fnargs'): | |||||
fnargs = fn.fnargs | |||||
else: | |||||
fnargs, varargs, varkw, defaults = inspect.getargspec(fn) | |||||
newargs = {} | |||||
for a in fnargs: | |||||
if a in kwargs: | |||||
newargs[a] = kwargs.get(a) | |||||
return fn(*args, **newargs) | |||||
def make_property_setter(args): | def make_property_setter(args): | ||||
args = _dict(args) | args = _dict(args) | ||||
@@ -0,0 +1,97 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
import webnotes | |||||
import webnotes.handler | |||||
import webnotes.client | |||||
import webnotes.widgets.reportview | |||||
from webnotes.utils.response import build_response, report_error | |||||
def handle(): | |||||
""" | |||||
/api/method/{methodname} will call a whitelisted method | |||||
/api/resource/{doctype} will query a table | |||||
examples: | |||||
?fields=["name", "owner"] | |||||
?filters=[["Task", "name", "like", "%005"]] | |||||
?limit_start=0 | |||||
?limit_page_length=20 | |||||
/api/resource/{doctype}/{name} will point to a resource | |||||
GET will return doclist | |||||
POST will insert | |||||
PUT will update | |||||
DELETE will delete | |||||
/api/resource/{doctype}/{name}?run_method={method} will run a whitelisted controller method | |||||
""" | |||||
parts = webnotes.request.path[1:].split("/") | |||||
call = doctype = name = None | |||||
if len(parts) > 1: | |||||
call = parts[1] | |||||
if len(parts) > 2: | |||||
doctype = parts[2] | |||||
if len(parts) > 3: | |||||
name = parts[3] | |||||
try: | |||||
if call=="method": | |||||
webnotes.local.form_dict.cmd = doctype | |||||
webnotes.handler.handle() | |||||
return | |||||
elif call=="resource": | |||||
if "run_method" in webnotes.local.form_dict: | |||||
bean = webnotes.bean(doctype, name) | |||||
if webnotes.local.request.method=="GET": | |||||
if not bean.has_permission("read"): | |||||
webnotes.throw("No Permission", webnotes.PermissionError) | |||||
webnotes.local.response.update({"data": bean.run_method(webnotes.local.form_dict.run_method, | |||||
**webnotes.local.form_dict)}) | |||||
if webnotes.local.request.method=="POST": | |||||
if not bean.has_permission("write"): | |||||
webnotes.throw("No Permission", webnotes.PermissionError) | |||||
webnotes.local.response.update({"data":bean.run_method(webnotes.local.form_dict.run_method, | |||||
**webnotes.local.form_dict)}) | |||||
webnotes.conn.commit() | |||||
else: | |||||
if name: | |||||
if webnotes.local.request.method=="GET": | |||||
webnotes.local.response.update({ | |||||
"doclist": webnotes.client.get(doctype, | |||||
name)}) | |||||
if webnotes.local.request.method=="POST": | |||||
webnotes.local.response.update({ | |||||
"doclist": webnotes.client.insert(webnotes.local.form_dict.doclist)}) | |||||
webnotes.conn.commit() | |||||
if webnotes.local.request.method=="PUT": | |||||
webnotes.local.response.update({ | |||||
"doclist":webnotes.client.save(webnotes.local.form_dict.doclist)}) | |||||
webnotes.conn.commit() | |||||
if webnotes.local.request.method=="DELETE": | |||||
webnotes.client.delete(doctype, name) | |||||
webnotes.local.response.message = "ok" | |||||
elif doctype: | |||||
if webnotes.local.request.method=="GET": | |||||
webnotes.local.response.update({ | |||||
"data": webnotes.call(webnotes.widgets.reportview.execute, | |||||
doctype, **webnotes.local.form_dict)}) | |||||
else: | |||||
raise Exception("Bad API") | |||||
else: | |||||
raise Exception("Bad API") | |||||
except Exception, e: | |||||
report_error(500) | |||||
build_response() |
@@ -18,6 +18,7 @@ import mimetypes | |||||
import webnotes | import webnotes | ||||
import webnotes.handler | import webnotes.handler | ||||
import webnotes.auth | import webnotes.auth | ||||
import webnotes.api | |||||
import webnotes.webutils | import webnotes.webutils | ||||
from webnotes.utils import get_site_name | from webnotes.utils import get_site_name | ||||
@@ -56,8 +57,10 @@ def application(request): | |||||
webnotes.local._response = Response() | webnotes.local._response = Response() | ||||
webnotes.http_request = webnotes.auth.HTTPRequest() | webnotes.http_request = webnotes.auth.HTTPRequest() | ||||
if webnotes.form_dict.cmd: | |||||
if webnotes.local.form_dict.cmd: | |||||
webnotes.handler.handle() | webnotes.handler.handle() | ||||
elif webnotes.request.path.startswith("/api/"): | |||||
webnotes.api.handle() | |||||
elif webnotes.local.request.method in ('GET', 'HEAD'): | elif webnotes.local.request.method in ('GET', 'HEAD'): | ||||
webnotes.webutils.render(webnotes.request.path[1:]) | webnotes.webutils.render(webnotes.request.path[1:]) | ||||
else: | else: | ||||
@@ -87,11 +87,11 @@ class HTTPRequest: | |||||
class LoginManager: | class LoginManager: | ||||
def __init__(self): | def __init__(self): | ||||
self.user = None | self.user = None | ||||
if webnotes.form_dict.get('cmd')=='login': | |||||
if webnotes.local.form_dict.get('cmd')=='login' or webnotes.local.request.path=="/api/method/login": | |||||
self.login() | self.login() | ||||
else: | else: | ||||
self.make_session(resume=True) | self.make_session(resume=True) | ||||
def login(self): | def login(self): | ||||
# clear cache | # clear cache | ||||
webnotes.clear_cache(user = webnotes.form_dict.get('usr')) | webnotes.clear_cache(user = webnotes.form_dict.get('usr')) | ||||
@@ -109,16 +109,16 @@ class LoginManager: | |||||
info = webnotes.conn.get_value("Profile", self.user, | info = webnotes.conn.get_value("Profile", self.user, | ||||
["user_type", "first_name", "last_name"], as_dict=1) | ["user_type", "first_name", "last_name"], as_dict=1) | ||||
if info.user_type=="Website User": | if info.user_type=="Website User": | ||||
webnotes._response.set_cookie("system_user", "no") | |||||
webnotes.response["message"] = "No App" | |||||
webnotes.local._response.set_cookie("system_user", "no") | |||||
webnotes.local.response["message"] = "No App" | |||||
else: | else: | ||||
webnotes._response.set_cookie("system_user", "yes") | |||||
webnotes.response['message'] = 'Logged In' | |||||
webnotes.local._response.set_cookie("system_user", "yes") | |||||
webnotes.local.response['message'] = 'Logged In' | |||||
full_name = " ".join(filter(None, [info.first_name, info.last_name])) | full_name = " ".join(filter(None, [info.first_name, info.last_name])) | ||||
webnotes.response["full_name"] = full_name | |||||
webnotes._response.set_cookie("full_name", full_name) | |||||
webnotes._response.set_cookie("user_id", self.user) | |||||
webnotes.local.response["full_name"] = full_name | |||||
webnotes.local._response.set_cookie("full_name", full_name) | |||||
webnotes.local._response.set_cookie("user_id", self.user) | |||||
def make_session(self, resume=False): | def make_session(self, resume=False): | ||||
# start session | # start session | ||||
@@ -154,7 +154,7 @@ class LoginManager: | |||||
return user[0][0] # in correct case | return user[0][0] # in correct case | ||||
def fail(self, message): | def fail(self, message): | ||||
webnotes.response['message'] = message | |||||
webnotes.local.response['message'] = message | |||||
raise webnotes.AuthenticationError | raise webnotes.AuthenticationError | ||||
@@ -213,12 +213,12 @@ class LoginManager: | |||||
if user == webnotes.session.user: | if user == webnotes.session.user: | ||||
webnotes.session.sid = "" | webnotes.session.sid = "" | ||||
webnotes._response.delete_cookie("full_name") | |||||
webnotes._response.delete_cookie("user_id") | |||||
webnotes._response.delete_cookie("sid") | |||||
webnotes._response.set_cookie("full_name", "") | |||||
webnotes._response.set_cookie("user_id", "") | |||||
webnotes._response.set_cookie("sid", "") | |||||
webnotes.local._response.delete_cookie("full_name") | |||||
webnotes.local._response.delete_cookie("user_id") | |||||
webnotes.local._response.delete_cookie("sid") | |||||
webnotes.local._response.set_cookie("full_name", "") | |||||
webnotes.local._response.set_cookie("user_id", "") | |||||
webnotes.local._response.set_cookie("sid", "") | |||||
class CookieManager: | class CookieManager: | ||||
def __init__(self): | def __init__(self): | ||||
@@ -231,9 +231,9 @@ class CookieManager: | |||||
# sid expires in 3 days | # sid expires in 3 days | ||||
expires = datetime.datetime.now() + datetime.timedelta(days=3) | expires = datetime.datetime.now() + datetime.timedelta(days=3) | ||||
if webnotes.session.sid: | if webnotes.session.sid: | ||||
webnotes._response.set_cookie("sid", webnotes.session.sid, expires = expires) | |||||
webnotes.local._response.set_cookie("sid", webnotes.session.sid, expires = expires) | |||||
if webnotes.session.session_country: | if webnotes.session.session_country: | ||||
webnotes._response.set_cookie('country', webnotes.session.get("session_country")) | |||||
webnotes.local._response.set_cookie('country', webnotes.session.get("session_country")) | |||||
def set_remember_me(self): | def set_remember_me(self): | ||||
from webnotes.utils import cint | from webnotes.utils import cint | ||||
@@ -247,7 +247,7 @@ class CookieManager: | |||||
expires = datetime.datetime.now() + \ | expires = datetime.datetime.now() + \ | ||||
datetime.timedelta(days=remember_days) | datetime.timedelta(days=remember_days) | ||||
webnotes._response.set_cookie["remember_me"] = 1 | |||||
webnotes.local._response.set_cookie["remember_me"] = 1 | |||||
def _update_password(user, password): | def _update_password(user, password): | ||||
@@ -56,12 +56,12 @@ def delete_notification_count_for(doctype): | |||||
def delete_event_notification_count(): | def delete_event_notification_count(): | ||||
delete_notification_count_for("Event") | delete_notification_count_for("Event") | ||||
def clear_doctype_notifications(controller, method=None): | |||||
def clear_doctype_notifications(bean, method=None): | |||||
if webnotes.flags.in_import: | if webnotes.flags.in_import: | ||||
return | return | ||||
config = get_notification_config() | config = get_notification_config() | ||||
doctype = controller.doc.doctype | |||||
doctype = bean.doc.doctype | |||||
if doctype in config.for_doctype: | if doctype in config.for_doctype: | ||||
delete_notification_count_for(doctype) | delete_notification_count_for(doctype) | ||||
@@ -2,23 +2,20 @@ | |||||
# MIT License. See license.txt | # MIT License. See license.txt | ||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import sys, os | |||||
import json | |||||
import webnotes | import webnotes | ||||
import webnotes.utils | import webnotes.utils | ||||
import webnotes.sessions | import webnotes.sessions | ||||
import webnotes.utils.file_manager | |||||
import webnotes.widgets.form.run_method | |||||
from webnotes.utils.response import build_response, report_error | |||||
@webnotes.whitelist(allow_guest=True) | @webnotes.whitelist(allow_guest=True) | ||||
def startup(): | def startup(): | ||||
webnotes.response.update(webnotes.sessions.get()) | webnotes.response.update(webnotes.sessions.get()) | ||||
def cleanup_docs(): | |||||
import webnotes.model.utils | |||||
if webnotes.response.get('docs') and type(webnotes.response['docs'])!=dict: | |||||
webnotes.response['docs'] = webnotes.model.utils.compress(webnotes.response['docs']) | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def runserverobj(arg=None): | def runserverobj(arg=None): | ||||
import webnotes.widgets.form.run_method | |||||
webnotes.widgets.form.run_method.runserverobj() | webnotes.widgets.form.run_method.runserverobj() | ||||
@webnotes.whitelist(allow_guest=True) | @webnotes.whitelist(allow_guest=True) | ||||
@@ -38,16 +35,12 @@ def run_custom_method(doctype, name, custom_method): | |||||
bean = webnotes.bean(doctype, name) | bean = webnotes.bean(doctype, name) | ||||
controller = bean.get_controller() | controller = bean.get_controller() | ||||
if getattr(controller, custom_method, webnotes._dict()).is_whitelisted: | if getattr(controller, custom_method, webnotes._dict()).is_whitelisted: | ||||
call(getattr(controller, custom_method), webnotes.local.form_dict) | |||||
webnotes.call(getattr(controller, custom_method), **webnotes.local.form_dict) | |||||
else: | else: | ||||
webnotes.throw("Not Allowed") | webnotes.throw("Not Allowed") | ||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def uploadfile(): | def uploadfile(): | ||||
import webnotes.utils | |||||
import webnotes.utils.file_manager | |||||
import json | |||||
try: | try: | ||||
if webnotes.form_dict.get('from_form'): | if webnotes.form_dict.get('from_form'): | ||||
try: | try: | ||||
@@ -67,19 +60,9 @@ def uploadfile(): | |||||
def handle(): | def handle(): | ||||
"""handle request""" | """handle request""" | ||||
cmd = webnotes.form_dict['cmd'] | |||||
cmd = webnotes.local.form_dict.cmd | |||||
def _error(status_code): | |||||
webnotes.errprint(webnotes.utils.get_traceback()) | |||||
webnotes._response.status_code = status_code | |||||
if webnotes.request_method == "POST": | |||||
webnotes.conn.rollback() | |||||
if cmd!='login': | |||||
# login executed in webnotes.auth | |||||
if webnotes.request_method == "POST": | |||||
webnotes.conn.begin() | |||||
if cmd!='login': | |||||
status_codes = { | status_codes = { | ||||
webnotes.PermissionError: 403, | webnotes.PermissionError: 403, | ||||
webnotes.AuthenticationError: 401, | webnotes.AuthenticationError: 401, | ||||
@@ -91,12 +74,12 @@ def handle(): | |||||
try: | try: | ||||
execute_cmd(cmd) | execute_cmd(cmd) | ||||
except Exception, e: | except Exception, e: | ||||
_error(status_codes.get(e.__class__, 500)) | |||||
report_error(status_codes.get(e.__class__, 500)) | |||||
else: | else: | ||||
if webnotes.request_method == "POST" and webnotes.conn: | |||||
if webnotes.local.request.method in ("POST", "PUT") and webnotes.conn: | |||||
webnotes.conn.commit() | webnotes.conn.commit() | ||||
print_response() | |||||
build_response() | |||||
if webnotes.conn: | if webnotes.conn: | ||||
webnotes.conn.close() | webnotes.conn.close() | ||||
@@ -117,7 +100,7 @@ def execute_cmd(cmd): | |||||
webnotes.msgprint('Not Allowed, %s' % str(method)) | webnotes.msgprint('Not Allowed, %s' % str(method)) | ||||
raise webnotes.PermissionError('Not Allowed, %s' % str(method)) | raise webnotes.PermissionError('Not Allowed, %s' % str(method)) | ||||
ret = call(method, webnotes.form_dict) | |||||
ret = webnotes.call(method, **webnotes.form_dict) | |||||
# returns with a message | # returns with a message | ||||
if ret: | if ret: | ||||
@@ -128,20 +111,6 @@ def execute_cmd(cmd): | |||||
webnotes.local.session_obj.update() | webnotes.local.session_obj.update() | ||||
def call(fn, args): | |||||
import inspect | |||||
if hasattr(fn, 'fnargs'): | |||||
fnargs = fn.fnargs | |||||
else: | |||||
fnargs, varargs, varkw, defaults = inspect.getargspec(fn) | |||||
newargs = {} | |||||
for a in fnargs: | |||||
if a in args: | |||||
newargs[a] = args.get(a) | |||||
return fn(**newargs) | |||||
def get_attr(cmd): | def get_attr(cmd): | ||||
"""get method object from cmd""" | """get method object from cmd""" | ||||
if '.' in cmd: | if '.' in cmd: | ||||
@@ -151,93 +120,3 @@ def get_attr(cmd): | |||||
webnotes.log("method:" + cmd) | webnotes.log("method:" + cmd) | ||||
return method | return method | ||||
def print_response(): | |||||
print_map = { | |||||
'csv': print_csv, | |||||
'download': print_raw, | |||||
'json': print_json, | |||||
'page': print_page | |||||
} | |||||
print_map.get(webnotes.response.get('type'), print_json)() | |||||
def print_page(): | |||||
"""print web page""" | |||||
from webnotes.webutils import render | |||||
render(webnotes.response['page_name']) | |||||
def print_json(): | |||||
make_logs() | |||||
cleanup_docs() | |||||
webnotes._response.headers["Content-Type"] = "text/json; charset: utf-8" | |||||
import json | |||||
print_zip(json.dumps(webnotes.local.response, default=json_handler, separators=(',',':'))) | |||||
def print_csv(): | |||||
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.data = webnotes.response['result'] | |||||
def print_raw(): | |||||
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.data = webnotes.response['filecontent'] | |||||
def make_logs(): | |||||
"""make strings for msgprint and errprint""" | |||||
import json | |||||
from webnotes import conf | |||||
from webnotes.utils import cstr | |||||
if webnotes.error_log: | |||||
# webnotes.response['exc'] = json.dumps("\n".join([cstr(d) for d in webnotes.error_log])) | |||||
webnotes.response['exc'] = json.dumps([cstr(d) for d in webnotes.local.error_log]) | |||||
if webnotes.local.message_log: | |||||
webnotes.response['_server_messages'] = json.dumps([cstr(d) for d in webnotes.local.message_log]) | |||||
if webnotes.debug_log and conf.get("logging") or False: | |||||
webnotes.response['_debug_messages'] = json.dumps(webnotes.local.debug_log) | |||||
def print_zip(response): | |||||
response = response.encode('utf-8') | |||||
orig_len = len(response) | |||||
if accept_gzip() and orig_len>512: | |||||
response = compressBuf(response) | |||||
webnotes._response.headers["Content-Encoding"] = "gzip" | |||||
webnotes._response.headers["Content-Length"] = str(len(response)) | |||||
webnotes._response.data = response | |||||
def json_handler(obj): | |||||
"""serialize non-serializable data for json""" | |||||
import datetime | |||||
from werkzeug.local import LocalProxy | |||||
# serialize date | |||||
if isinstance(obj, (datetime.date, datetime.timedelta, datetime.datetime)): | |||||
return unicode(obj) | |||||
elif isinstance(obj, LocalProxy): | |||||
return unicode(obj) | |||||
else: | |||||
raise TypeError, """Object of type %s with value of %s is not JSON serializable""" % \ | |||||
(type(obj), repr(obj)) | |||||
def accept_gzip(): | |||||
if "gzip" in webnotes.get_request_header("HTTP_ACCEPT_ENCODING", ""): | |||||
return True | |||||
def compressBuf(buf): | |||||
import gzip, cStringIO | |||||
zbuf = cStringIO.StringIO() | |||||
zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) | |||||
zfile.write(buf) | |||||
zfile.close() | |||||
return zbuf.getvalue() |
@@ -220,17 +220,28 @@ class Bean: | |||||
idx_map[d.parentfield] = d.idx | idx_map[d.parentfield] = d.idx | ||||
def run_method(self, method, *args, **kwargs): | def run_method(self, method, *args, **kwargs): | ||||
if not args: | |||||
args = [] | |||||
self.make_controller() | self.make_controller() | ||||
def add_to_response(out, new_response): | |||||
if isinstance(new_response, dict): | |||||
out.update(new_response) | |||||
if hasattr(self.controller, method): | if hasattr(self.controller, method): | ||||
getattr(self.controller, method)(*args, **kwargs) | |||||
add_to_response(webnotes.local.response, webnotes.call(getattr(self.controller, method), *args, **kwargs)) | |||||
if hasattr(self.controller, 'custom_' + method): | if hasattr(self.controller, 'custom_' + method): | ||||
getattr(self.controller, 'custom_' + method)(*args, **kwargs) | |||||
add_to_response(webnotes.local.response, webnotes.call(getattr(self.controller, 'custom_' + method), *args, **kwargs)) | |||||
args = [self, method] + args | |||||
for handler in webnotes.get_hooks("bean_event:" + self.doc.doctype + ":" + method) \ | |||||
+ webnotes.get_hooks("bean_event:*:" + method): | |||||
add_to_response(webnotes.local.response, webnotes.call(webnotes.get_attr(handler), *args, **kwargs)) | |||||
notify(self, method, *args, **kwargs) | |||||
self.set_doclist(self.controller.doclist) | self.set_doclist(self.controller.doclist) | ||||
return webnotes.local.response | |||||
def get_attr(self, method): | def get_attr(self, method): | ||||
self.make_controller() | self.make_controller() | ||||
return getattr(self.controller, method, None) | return getattr(self.controller, method, None) | ||||
@@ -273,7 +284,10 @@ class Bean: | |||||
self.set_doclist(new_doclist) | self.set_doclist(new_doclist) | ||||
def has_read_perm(self): | def has_read_perm(self): | ||||
return webnotes.has_permission(self.doc.doctype, "read", self.doc) | |||||
return self.has_permission("read") | |||||
def has_permission(self, permtype): | |||||
return webnotes.has_permission(self.doc.doctype, permtype, self.doc) | |||||
def save(self, check_links=1, ignore_permissions=None): | def save(self, check_links=1, ignore_permissions=None): | ||||
if ignore_permissions: | if ignore_permissions: | ||||
@@ -494,12 +508,6 @@ def clone(source_wrapper): | |||||
return new_wrapper | return new_wrapper | ||||
def notify(bean, caller, *args, **kwargs): | |||||
for hook in webnotes.get_hooks().bean_event or []: | |||||
doctype, trigger, handler = hook.split(":") | |||||
if ((doctype=="*") or (doctype==bean.doc.doctype)) and caller==trigger: | |||||
webnotes.get_attr(handler)(bean, trigger, *args, **kwargs) | |||||
# for bc | # for bc | ||||
def getlist(doclist, parentfield): | def getlist(doclist, parentfield): | ||||
import webnotes.model.utils | import webnotes.model.utils | ||||
@@ -148,8 +148,7 @@ class Session: | |||||
data = self.get_session_record() | data = self.get_session_record() | ||||
if data: | if data: | ||||
# set language | # set language | ||||
self.data = webnotes._dict({'data': data, | |||||
'user':data.user, 'sid': self.sid}) | |||||
self.data = webnotes._dict({'data': data, 'user':data.user, 'sid': self.sid}) | |||||
else: | else: | ||||
self.start_as_guest() | self.start_as_guest() | ||||
@@ -0,0 +1,102 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
from __future__ import unicode_literals | |||||
import json, inspect | |||||
import datetime | |||||
import gzip, cStringIO | |||||
import webnotes | |||||
import webnotes.utils | |||||
import webnotes.sessions | |||||
import webnotes.model.utils | |||||
from werkzeug.local import LocalProxy | |||||
def report_error(status_code): | |||||
webnotes.errprint(webnotes.utils.get_traceback()) | |||||
webnotes._response.status_code = status_code | |||||
if webnotes.request_method == "POST": | |||||
webnotes.conn.rollback() | |||||
def build_response(): | |||||
print_map = { | |||||
'csv': print_csv, | |||||
'download': print_raw, | |||||
'json': print_json, | |||||
'page': print_page | |||||
} | |||||
print_map.get(webnotes.response.get('type'), print_json)() | |||||
def print_page(): | |||||
"""print web page""" | |||||
from webnotes.webutils import render | |||||
render(webnotes.response['page_name']) | |||||
def print_json(): | |||||
make_logs() | |||||
cleanup_docs() | |||||
webnotes._response.headers["Content-Type"] = "text/json; charset: utf-8" | |||||
print_zip(json.dumps(webnotes.local.response, default=json_handler, separators=(',',':'))) | |||||
def cleanup_docs(): | |||||
if webnotes.response.get('docs') and type(webnotes.response['docs'])!=dict: | |||||
webnotes.response['docs'] = webnotes.model.utils.compress(webnotes.response['docs']) | |||||
def print_csv(): | |||||
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.data = webnotes.response['result'] | |||||
def print_raw(): | |||||
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.data = webnotes.response['filecontent'] | |||||
def make_logs(): | |||||
"""make strings for msgprint and errprint""" | |||||
if webnotes.error_log: | |||||
# webnotes.response['exc'] = json.dumps("\n".join([cstr(d) for d in webnotes.error_log])) | |||||
webnotes.response['exc'] = json.dumps([webnotes.utils.cstr(d) for d in webnotes.local.error_log]) | |||||
if webnotes.local.message_log: | |||||
webnotes.response['_server_messages'] = json.dumps([webnotes.utils.cstr(d) for d in webnotes.local.message_log]) | |||||
if webnotes.debug_log and webnotes.conf.get("logging") or False: | |||||
webnotes.response['_debug_messages'] = json.dumps(webnotes.local.debug_log) | |||||
def print_zip(response): | |||||
response = response.encode('utf-8') | |||||
orig_len = len(response) | |||||
if accept_gzip() and orig_len>512: | |||||
response = compressBuf(response) | |||||
webnotes._response.headers["Content-Encoding"] = "gzip" | |||||
webnotes._response.headers["Content-Length"] = str(len(response)) | |||||
webnotes._response.data = response | |||||
def json_handler(obj): | |||||
"""serialize non-serializable data for json""" | |||||
# serialize date | |||||
if isinstance(obj, (datetime.date, datetime.timedelta, datetime.datetime)): | |||||
return unicode(obj) | |||||
elif isinstance(obj, LocalProxy): | |||||
return unicode(obj) | |||||
else: | |||||
raise TypeError, """Object of type %s with value of %s is not JSON serializable""" % \ | |||||
(type(obj), repr(obj)) | |||||
def accept_gzip(): | |||||
if "gzip" in webnotes.get_request_header("HTTP_ACCEPT_ENCODING", ""): | |||||
return True | |||||
def compressBuf(buf): | |||||
zbuf = cStringIO.StringIO() | |||||
zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 5) | |||||
zfile.write(buf) | |||||
zfile.close() | |||||
return zbuf.getvalue() |
@@ -29,12 +29,25 @@ def get_form_params(): | |||||
def execute(doctype, query=None, filters=None, fields=None, docstatus=None, | def execute(doctype, query=None, filters=None, fields=None, docstatus=None, | ||||
group_by=None, order_by=None, limit_start=0, limit_page_length=None, | group_by=None, order_by=None, limit_start=0, limit_page_length=None, | ||||
as_list=False, with_childnames=False, debug=False): | as_list=False, with_childnames=False, debug=False): | ||||
""" | |||||
fields as list ["name", "owner"] or ["tabTask.name", "tabTask.owner"] | |||||
filters as list of list [["Task", "name", "=", "TASK00001"]] | |||||
""" | |||||
if query: | if query: | ||||
return run_custom_query(query) | return run_custom_query(query) | ||||
if not filters: filters = [] | |||||
if not docstatus: docstatus = [] | |||||
if not filters: | |||||
filters = [] | |||||
if isinstance(filters, basestring): | |||||
filters = json.loads(filters) | |||||
if not docstatus: | |||||
docstatus = [] | |||||
if not fields: | |||||
fields = ["name"] | |||||
if isinstance(fields, basestring): | |||||
filters = json.loads(fields) | |||||
args = prepare_args(doctype, filters, fields, docstatus, group_by, order_by, with_childnames) | args = prepare_args(doctype, filters, fields, docstatus, group_by, order_by, with_childnames) | ||||
args.limit = add_limit(limit_start, limit_page_length) | args.limit = add_limit(limit_start, limit_page_length) | ||||