@@ -216,7 +216,7 @@ def get_request_header(key, default=None): | |||
logger = None | |||
whitelisted = [] | |||
guest_methods = [] | |||
def whitelist(allow_guest=False, allow_roles=None): | |||
def whitelist(allow_guest=False): | |||
""" | |||
decorator for whitelisting a function | |||
@@ -232,21 +232,18 @@ def whitelist(allow_guest=False, allow_roles=None): | |||
if allow_guest: | |||
guest_methods.append(fn) | |||
if allow_roles: | |||
roles = get_roles() | |||
allowed = False | |||
for role in allow_roles: | |||
if role in roles: | |||
allowed = True | |||
break | |||
if not allowed: | |||
raise PermissionError, "Method not allowed" | |||
return fn | |||
return innerfn | |||
def only_for(roles): | |||
if not isinstance(roles, (tuple, list)): | |||
roles = (roles,) | |||
roles = set(roles) | |||
myroles = set(get_roles()) | |||
if not roles.intersection(myroles): | |||
raise PermissionError | |||
def clear_cache(user=None, doctype=None): | |||
"""clear cache""" | |||
import webnotes.sessions | |||
@@ -544,6 +541,18 @@ def repsond_as_web_page(title, html): | |||
local.message = "<h3>" + title + "</h3>" + html | |||
local.response['type'] = 'page' | |||
local.response['page_name'] = 'message.html' | |||
<<<<<<< HEAD | |||
======= | |||
def load_json(obj): | |||
if isinstance(obj, basestring): | |||
try: | |||
obj = json.loads(obj) | |||
except ValueError: | |||
pass | |||
return obj | |||
>>>>>>> 55003f860c12c6b77a4d21d0ccf41573e7e3e545 | |||
def build_match_conditions(doctype, fields=None, as_condition=True): | |||
import webnotes.widgets.reportview | |||
@@ -52,10 +52,10 @@ def application(request): | |||
webnotes.http_request = webnotes.auth.HTTPRequest() | |||
except webnotes.AuthenticationError, e: | |||
pass | |||
if webnotes.form_dict.cmd: | |||
webnotes.handler.handle() | |||
elif webnotes.local.request.method == 'GET': | |||
elif webnotes.local.request.method in ('GET', 'HEAD'): | |||
webnotes.webutils.render(webnotes.request.path[1:]) | |||
else: | |||
raise NotFound | |||
@@ -61,6 +61,11 @@ def save(doclist): | |||
return [d.fields for d in doclist] | |||
@webnotes.whitelist() | |||
def rename_doc(doctype, old_name, new_name, merge=False): | |||
new_name = webnotes.rename_doc(doctype, old_name, new_name, merge=merge) | |||
return new_name | |||
@webnotes.whitelist() | |||
def submit(doclist): | |||
if isinstance(doclist, basestring): | |||
@@ -5,8 +5,9 @@ from __future__ import unicode_literals | |||
import webnotes | |||
import webnotes.defaults | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def get_roles_and_doctypes(): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
return { | |||
"doctypes": [d[0] for d in webnotes.conn.sql("""select name from `tabDocType` dt where | |||
ifnull(istable,0)=0 and | |||
@@ -16,16 +17,18 @@ def get_roles_and_doctypes(): | |||
('Guest', 'Administrator')""")] | |||
} | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def get_permissions(doctype=None, role=None): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
return webnotes.conn.sql("""select * from tabDocPerm | |||
where %s%s order by parent, permlevel, role""" % (\ | |||
doctype and (" parent='%s'" % doctype) or "", | |||
role and ((doctype and " and " or "") + " role='%s'" % role) or "", | |||
), as_dict=True) | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def remove(doctype, name): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
match = webnotes.conn.get_value("DocPerm", name, "`match`") | |||
webnotes.conn.sql("""delete from tabDocPerm where name=%s""", name) | |||
@@ -34,8 +37,9 @@ def remove(doctype, name): | |||
if match: | |||
webnotes.defaults.clear_cache() | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def add(parent, role, permlevel): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
webnotes.doc(fielddata={ | |||
"doctype":"DocPerm", | |||
"__islocal": 1, | |||
@@ -49,8 +53,9 @@ def add(parent, role, permlevel): | |||
validate_and_reset(parent) | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def update(name, doctype, ptype, value=0): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
webnotes.conn.sql("""update tabDocPerm set `%s`=%s where name=%s"""\ | |||
% (ptype, '%s', '%s'), (value, name)) | |||
validate_and_reset(doctype) | |||
@@ -58,8 +63,9 @@ def update(name, doctype, ptype, value=0): | |||
if ptype == "read" and webnotes.conn.get_value("DocPerm", name, "`match`"): | |||
webnotes.defaults.clear_cache() | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def update_match(name, doctype, match=""): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
webnotes.conn.sql("""update tabDocPerm set `match`=%s where name=%s""", | |||
(match, name)) | |||
validate_and_reset(doctype) | |||
@@ -70,8 +76,9 @@ def validate_and_reset(doctype, for_remove=False): | |||
validate_permissions_for_doctype(doctype, for_remove) | |||
clear_doctype_cache(doctype) | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def reset(doctype): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
webnotes.reset_perms(doctype) | |||
clear_doctype_cache(doctype) | |||
webnotes.defaults.clear_cache() | |||
@@ -83,8 +90,9 @@ def clear_doctype_cache(doctype): | |||
and tabDocPerm.role = tabUserRole.role""", doctype): | |||
webnotes.clear_cache(user=user) | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def get_users_with_role(role): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
return [p[0] for p in webnotes.conn.sql("""select distinct tabProfile.name | |||
from tabUserRole, tabProfile where | |||
tabUserRole.role=%s | |||
@@ -5,8 +5,9 @@ from __future__ import unicode_literals | |||
import webnotes | |||
import webnotes.defaults | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def get_users_and_links(): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
links, all_fields = [], [] | |||
for l in webnotes.conn.sql("""select tabDocField.fieldname, tabDocField.options | |||
@@ -31,8 +32,9 @@ def get_users_and_links(): | |||
"link_fields": links | |||
} | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def get_properties(user=None, key=None): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
return webnotes.conn.sql("""select name, parent, defkey, defvalue | |||
from tabDefaultValue | |||
where parent!='Control Panel' | |||
@@ -41,12 +43,14 @@ def get_properties(user=None, key=None): | |||
user and (" and parent='%s'" % user) or "", | |||
key and (" and defkey='%s'" % key) or ""), as_dict=True) | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def remove(user, name): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
webnotes.defaults.clear_default(name=name) | |||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) | |||
@webnotes.whitelist() | |||
def add(parent, defkey, defvalue): | |||
webnotes.only_for(("System Manager", "Administrator")) | |||
webnotes.defaults.add_user_default(defkey, defvalue, parent) | |||
def get_defvalue(doctype, txt, searchfield, start, page_len, filters): | |||
@@ -306,11 +306,12 @@ | |||
"number_format": "#,###.##" | |||
}, | |||
"Brazil": { | |||
"currency": "BRL", | |||
"currency_fraction": "Centavo", | |||
"currency_fraction_units": 100, | |||
"currency_symbol": "R$", | |||
"date_format": "dd/mm/yyyy", | |||
"number_format": "#,###.##", | |||
"number_format": "#.###,##", | |||
"timezones": [ | |||
"America/Araguaina", | |||
"America/Bahia", | |||
@@ -2382,4 +2383,4 @@ | |||
"\u00c5land Islands": { | |||
"number_format": "#,###.##" | |||
} | |||
} | |||
} |
@@ -7,6 +7,7 @@ from __future__ import unicode_literals | |||
""" | |||
import webnotes, os | |||
from webnotes import conf | |||
import webnotes.utils | |||
lower_case_files_for = ['DocType', 'Page', 'Report', | |||
"Workflow", 'Module Def', 'Desktop Item', 'Workflow State', 'Workflow Action'] | |||
@@ -160,7 +160,7 @@ def get_user_fullname(user): | |||
fullname = webnotes.conn.sql("SELECT CONCAT_WS(' ', first_name, last_name) FROM `tabProfile` WHERE name=%s", user) | |||
return fullname and fullname[0][0] or '' | |||
def get_system_managers(): | |||
def get_system_managers(only_name=False): | |||
"""returns all system manager's profile details""" | |||
import email.utils | |||
system_managers = webnotes.conn.sql("""select distinct name, | |||
@@ -171,7 +171,10 @@ def get_system_managers(): | |||
and exists (select * from tabUserRole ur | |||
where ur.parent = p.name and ur.role="System Manager")""", as_dict=True) | |||
return [email.utils.formataddr((p.fullname, p.name)) for p in system_managers] | |||
if only_name: | |||
return [p.name for p in system_managers] | |||
else: | |||
return [email.utils.formataddr((p.fullname, p.name)) for p in system_managers] | |||
def add_role(profile, role): | |||
profile_wrapper = webnotes.bean("Profile", profile) | |||
@@ -83,20 +83,18 @@ wn.datetime = { | |||
return dateutil.obj_to_str(new_dt); | |||
}, | |||
month_start: function() { | |||
var d = new Date(); | |||
return d.getFullYear() + '-' + int_to_str(d.getMonth()+1,2) + '-01'; | |||
month_start: function(d, month) { | |||
if(!d)var d = new Date(); | |||
var m = month ? cint(month) : d.getMonth() + 1; | |||
return d.getFullYear() + '-' + int_to_str(m, 2) + '-01'; | |||
}, | |||
month_end: function(d) { | |||
if(!d)var d = new Date(); | |||
var m = d.getMonth() + 1; | |||
month_end: function(d, month) { | |||
if(!d)var d = new Date(); | |||
var m = month ? cint(month) : d.getMonth() + 1; | |||
var y = d.getFullYear(); | |||
last_date = month_last[m]; | |||
if(m==2 && (y % 4)==0 && ((y % 100)!=0 || (y % 400)==0)) // leap year test | |||
last_date = 29; | |||
return y+'-'+int_to_str(m,2)+'-'+last_date; | |||
var last_date = new Date(y, m, 0).getDate(); | |||
return y + '-' + int_to_str(m, 2) + '-' + int_to_str(last_date, 2); | |||
}, | |||
get_user_fmt: function() { | |||
@@ -92,7 +92,7 @@ wn.Application = Class.extend({ | |||
if(wn.boot.metadata_version != localStorage.metadata_version) { | |||
localStorage.clear(); | |||
console.log("Cleared Cache - New Metadata"); | |||
localStorage.metadata_version = wn.boot.metadata_version; | |||
wn.assets.init_local_storage(); | |||
} | |||
}, | |||
@@ -38,8 +38,14 @@ wn.assets = { | |||
localStorage.clear(); | |||
console.log("Cleared localstorage"); | |||
} | |||
wn.assets.init_local_storage(); | |||
}, | |||
init_local_storage: function() { | |||
localStorage._last_load = new Date(); | |||
localStorage._version_number = window._version_number; | |||
if(wn.boot) localStorage.metadata_version = wn.boot.metadata_version; | |||
}, | |||
// check if the asset exists in | |||
@@ -118,7 +118,7 @@ wn.print.Table = Class.extend({ | |||
var tr = $("<tr>").appendTo(table); | |||
$.each(me.columns, function(ci, fieldname) { | |||
if(fieldname==="Sr") | |||
if(fieldname.toLowerCase()==="sr") | |||
var value = row.idx; | |||
else | |||
var value = row[fieldname]; | |||
@@ -275,12 +275,17 @@ wn.ui.AppFrame = Class.extend({ | |||
.appendTo(this.parent.find(".appframe-form .container")) | |||
.find("input"); | |||
}, | |||
add_break: function() { | |||
// add further fields in the next line | |||
this.parent.find(".appframe-form .container") | |||
.append('<div class="clearfix invisible-xs"></div>'); | |||
}, | |||
add_field: function(df) { | |||
this.show_form(); | |||
var f = wn.ui.form.make_control({ | |||
df: df, | |||
parent: this.parent.find(".appframe-form .container"), | |||
only_input: true, | |||
only_input: df.fieldtype=="Check" ? false : true, | |||
}) | |||
f.refresh(); | |||
$(f.wrapper) | |||
@@ -292,6 +297,12 @@ wn.ui.AppFrame = Class.extend({ | |||
}) | |||
.attr("title", wn._(df.label)).tooltip(); | |||
f.$input.attr("placeholder", wn._(df.label)); | |||
if(df.fieldtype==="Check") { | |||
$(f.wrapper).find(":first-child") | |||
.removeClass("col-md-offset-4 col-md-8"); | |||
} | |||
if(df["default"]) | |||
f.set_input(df["default"]) | |||
this.fields_dict[df.fieldname || df.label] = f; | |||
@@ -114,14 +114,6 @@ wn.views.ListView = Class.extend({ | |||
me.columns.push(d); | |||
}); | |||
} | |||
// expand "name" if there are few columns | |||
var total_colspan = 0; | |||
$.each(this.columns, function(i, c) { total_colspan += cint(c.colspan); }); | |||
if(total_colspan < 8) { | |||
$.each(this.columns, | |||
function(i, c) { if(c.content==="name") { c.colspan = 4; return false; } }); | |||
} | |||
}, | |||
render: function(row, data) { | |||
this.prepare_data(data); | |||
@@ -137,9 +129,9 @@ wn.views.ListView = Class.extend({ | |||
var body = $('<div class="doclist-row row">\ | |||
<div class="list-row-id-area col-sm-3" style="white-space: nowrap;\ | |||
<div class="list-row-id-area col-sm-4" style="white-space: nowrap;\ | |||
text-overflow: ellipsis; max-height: 30px"></div>\ | |||
<div class="list-row-content-area col-sm-9"></div>\ | |||
<div class="list-row-content-area col-sm-8"></div>\ | |||
</div>').appendTo($(row).css({"position":"relative"})), | |||
colspans = 0, | |||
me = this; | |||
@@ -111,21 +111,36 @@ wn.views.QueryReport = Class.extend({ | |||
this.clear_filters(); | |||
var me = this; | |||
$.each(wn.query_reports[this.report_name].filters || [], function(i, df) { | |||
var f = me.appframe.add_field(df); | |||
$(f.wrapper).addClass("filters pull-left"); | |||
me.filters.push(f); | |||
if(df["default"]) { | |||
f.set_input(df["default"]); | |||
} | |||
if(df.fieldtype==="Break") { | |||
me.appframe.add_break(); | |||
} else { | |||
var f = me.appframe.add_field(df); | |||
$(f.wrapper).addClass("filters pull-left"); | |||
me.filters.push(f); | |||
if(df["default"]) { | |||
f.set_input(df["default"]); | |||
} | |||
if(df.get_query) f.get_query = df.get_query; | |||
if(df.get_query) f.get_query = df.get_query; | |||
} | |||
}); | |||
this.set_route_filters() | |||
this.set_filters_by_name(); | |||
}, | |||
clear_filters: function() { | |||
this.filters = []; | |||
this.appframe.parent.find('.appframe-form .filters').remove(); | |||
}, | |||
set_route_filters: function() { | |||
var me = this; | |||
if(wn.route_options) { | |||
$.each(this.filters || [], function(i, f) { | |||
if(wn.route_options[f.df.fieldname]!=null) | |||
f.set_input(wn.route_options[f.df.fieldname]); | |||
}); | |||
} | |||
wn.route_options = null; | |||
}, | |||
set_filters_by_name: function() { | |||
this.filters_by_name = {}; | |||
@@ -125,11 +125,13 @@ wn.views.ReportView = wn.ui.Listing.extend({ | |||
var me = this; | |||
if(opts.columns) this.columns = opts.columns; | |||
if(opts.filters) $.each(opts.filters, function(i, f) { | |||
// fieldname, condition, value | |||
if (wn.meta.get_docfield(f[0], f[1]).fieldtype == "Check") | |||
value = f[3] ? "Yes" : "No"; | |||
else | |||
value = f[3]; | |||
// f = [doctype, fieldname, condition, value] | |||
var df = wn.meta.get_docfield(f[0], f[1]); | |||
if (df && df.fieldtype == "Check") { | |||
var value = f[3] ? "Yes" : "No"; | |||
} else { | |||
var value = f[3]; | |||
} | |||
me.filter_list.add_filter(f[0], f[1], f[2], value); | |||
}); | |||
@@ -17,6 +17,8 @@ import webnotes.translate | |||
@webnotes.whitelist() | |||
def clear(user=None): | |||
webnotes.local.session_obj.update(force=True) | |||
webnotes.local.conn.commit() | |||
clear_cache(webnotes.session.user) | |||
webnotes.response['message'] = "Cache Cleared" | |||
@@ -217,7 +219,7 @@ class Session: | |||
webnotes.local.login_manager.login_as_guest() | |||
self.start() | |||
def update(self): | |||
def update(self, force=False): | |||
"""extend session expiry""" | |||
self.data['data']['last_updated'] = webnotes.utils.now() | |||
self.data['data']['lang'] = unicode(webnotes.lang) | |||
@@ -231,8 +233,8 @@ class Session: | |||
time_diff = webnotes.utils.time_diff_in_seconds(webnotes.utils.now(), | |||
last_updated) | |||
if webnotes.session['user'] != 'Guest' and \ | |||
((time_diff==None) or (time_diff > 1800)): | |||
if force or (webnotes.session['user'] != 'Guest' and \ | |||
((time_diff==None) or (time_diff > 1800))): | |||
# database persistence is secondary, don't update it too often | |||
webnotes.conn.sql("""update tabSessions set sessiondata=%s, | |||
lastupdate=NOW() where sid=%s""" , (str(self.data['data']), | |||
@@ -26,8 +26,12 @@ | |||
{%- endblock %} | |||
</head> | |||
<body> | |||
{% block banner %}{{ banner_html or "" }}{% endblock %} | |||
{% block navbar %}{% include "templates/includes/navbar.html" %}{% endblock %} | |||
{% block banner %} | |||
{% if banner_html -%} | |||
<header class="container">{{ banner_html or "" }}</header> | |||
{%- endif %} | |||
{% endblock %} | |||
{% block navbar %}{% include "lib/website/templates/includes/navbar.html" %}{% endblock %} | |||
<div class="page-container" id="page-{{ name }}"> | |||
{% block content %}{% endblock %} | |||
</div> | |||
@@ -1,5 +1,6 @@ | |||
{% extends base_template %} | |||
{% block banner %}{% endblock %} | |||
{% block navbar %}{% endblock %} | |||
{% block footer %}{% endblock %} | |||
@@ -11,6 +11,7 @@ import webnotes | |||
from webnotes import conf | |||
from webnotes import msgprint | |||
from webnotes.utils import cint, expand_partial_links | |||
import email.utils | |||
class OutgoingEmailError(webnotes.ValidationError): pass | |||
@@ -195,12 +196,13 @@ class EMail: | |||
self.msg_root['Subject'] = self.subject.encode("utf-8") | |||
self.msg_root['From'] = self.sender.encode("utf-8") | |||
self.msg_root['To'] = ', '.join([r.strip() for r in self.recipients]).encode("utf-8") | |||
if self.reply_to and self.reply_to != self.sender: | |||
self.msg_root['Reply-To'] = self.reply_to.encode("utf-8") | |||
self.msg_root['Date'] = email.utils.formatdate() | |||
if not self.reply_to: | |||
self.reply_to = self.sender | |||
self.msg_root['Reply-To'] = self.reply_to.encode("utf-8") | |||
if self.cc: | |||
self.msg_root['CC'] = ', '.join([r.strip() for r in self.cc]).encode("utf-8") | |||
def as_string(self): | |||
"""validate, build message and convert to string""" | |||
self.validate() | |||
@@ -219,6 +221,8 @@ class EMail: | |||
smtpserver = SMTPServer() | |||
if hasattr(smtpserver, "always_use_login_id_as_sender") and \ | |||
cint(smtpserver.always_use_login_id_as_sender) and smtpserver.login: | |||
if not self.reply_to: | |||
self.reply_to = self.sender | |||
self.sender = smtpserver.login | |||
smtpserver.sess.sendmail(self.sender, self.recipients + (self.cc or []), | |||
@@ -99,22 +99,31 @@ def log(method, message=None): | |||
webnotes.conn.commit() | |||
return message | |||
def report_errors(): | |||
from webnotes.utils.email_lib import sendmail_to_system_managers | |||
from webnotes.utils import get_url | |||
errors = [("""<p>Time: %(modified)s</p> | |||
<pre><code>%(error)s</code></pre>""" % d) for d in webnotes.conn.sql("""select modified, error | |||
from `tabScheduler Log` where DATEDIFF(NOW(), modified) < 1 | |||
and error not like '%%[Errno 110] Connection timed out%%' | |||
limit 10""", as_dict=True)] | |||
def get_errors(from_date, to_date, limit): | |||
errors = webnotes.conn.sql("""select modified, method, error from `tabScheduler Log` | |||
where date(modified) between %s and %s | |||
and error not like '%%[Errno 110] Connection timed out%%' | |||
order by modified limit %s""", (from_date, to_date, limit), as_dict=True) | |||
return ["""<p>Time: {modified}</p><pre><code>Method: {method}\n{error}</code></pre>""".format(**e) | |||
for e in errors] | |||
def get_error_report(from_date=None, to_date=None, limit=10): | |||
from webnotes.utils import get_url, now_datetime, add_days | |||
if not from_date: | |||
from_date = add_days(now_datetime().date(), -1) | |||
if not to_date: | |||
to_date = add_days(now_datetime().date(), -1) | |||
errors = get_errors(from_date, to_date, limit) | |||
if errors: | |||
sendmail_to_system_managers("ERPNext Scheduler Failure Report", (""" | |||
<p>Dear System Managers,</p> | |||
<p>Reporting ERPNext failed scheduler events for the day (max 10):</p> | |||
<p>URL: <a href="%(url)s" target="_blank">%(url)s</a></p><hr>""" % {"url":get_url()}) + "<hr>".join(errors)) | |||
return 1, """<h4>Scheduler Failed Events (max {limit}):</h4> | |||
<p>URL: <a href="{url}" target="_blank">{url}</a></p><hr>{errors}""".format( | |||
limit=limit, url=get_url(), errors="<hr>".join(errors)) | |||
else: | |||
return 0, "<p>Scheduler didn't encounter any problems.</p>" | |||
if __name__=='__main__': | |||
execute() |