Selaa lähdekoodia

Merged with develop

version-14
Rushabh Mehta 11 vuotta sitten
vanhempi
commit
cf71e3725a
21 muutettua tiedostoa jossa 163 lisäystä ja 88 poistoa
  1. +21
    -12
      webnotes/__init__.py
  2. +2
    -2
      webnotes/app.py
  3. +5
    -0
      webnotes/client.py
  4. +16
    -8
      webnotes/core/page/permission_manager/permission_manager.py
  5. +8
    -4
      webnotes/core/page/user_properties/user_properties.py
  6. +3
    -2
      webnotes/country_info.json
  7. +1
    -0
      webnotes/modules/__init__.py
  8. +5
    -2
      webnotes/profile.py
  9. +9
    -11
      webnotes/public/js/legacy/datetime.js
  10. +1
    -1
      webnotes/public/js/wn/app.js
  11. +6
    -0
      webnotes/public/js/wn/assets.js
  12. +1
    -1
      webnotes/public/js/wn/print/print_table.js
  13. +12
    -1
      webnotes/public/js/wn/ui/appframe.js
  14. +2
    -10
      webnotes/public/js/wn/views/listview.js
  15. +22
    -7
      webnotes/public/js/wn/views/query_report.js
  16. +7
    -5
      webnotes/public/js/wn/views/reportview.js
  17. +5
    -3
      webnotes/sessions.py
  18. +6
    -2
      webnotes/templates/base.html
  19. +1
    -0
      webnotes/templates/pages/login.html
  20. +8
    -4
      webnotes/utils/email_lib/smtp.py
  21. +22
    -13
      webnotes/utils/scheduler.py

+ 21
- 12
webnotes/__init__.py Näytä tiedosto

@@ -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


+ 2
- 2
webnotes/app.py Näytä tiedosto

@@ -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


+ 5
- 0
webnotes/client.py Näytä tiedosto

@@ -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):


+ 16
- 8
webnotes/core/page/permission_manager/permission_manager.py Näytä tiedosto

@@ -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


+ 8
- 4
webnotes/core/page/user_properties/user_properties.py Näytä tiedosto

@@ -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):


+ 3
- 2
webnotes/country_info.json Näytä tiedosto

@@ -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": "#,###.##"
}
}
}

+ 1
- 0
webnotes/modules/__init__.py Näytä tiedosto

@@ -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']


+ 5
- 2
webnotes/profile.py Näytä tiedosto

@@ -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)


+ 9
- 11
webnotes/public/js/legacy/datetime.js Näytä tiedosto

@@ -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() {


+ 1
- 1
webnotes/public/js/wn/app.js Näytä tiedosto

@@ -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();
}
},


+ 6
- 0
webnotes/public/js/wn/assets.js Näytä tiedosto

@@ -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


+ 1
- 1
webnotes/public/js/wn/print/print_table.js Näytä tiedosto

@@ -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];


+ 12
- 1
webnotes/public/js/wn/ui/appframe.js Näytä tiedosto

@@ -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;


+ 2
- 10
webnotes/public/js/wn/views/listview.js Näytä tiedosto

@@ -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;


+ 22
- 7
webnotes/public/js/wn/views/query_report.js Näytä tiedosto

@@ -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 = {};


+ 7
- 5
webnotes/public/js/wn/views/reportview.js Näytä tiedosto

@@ -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);
});



+ 5
- 3
webnotes/sessions.py Näytä tiedosto

@@ -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']),


+ 6
- 2
webnotes/templates/base.html Näytä tiedosto

@@ -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
- 0
webnotes/templates/pages/login.html Näytä tiedosto

@@ -1,5 +1,6 @@
{% extends base_template %}

{% block banner %}{% endblock %}
{% block navbar %}{% endblock %}
{% block footer %}{% endblock %}



+ 8
- 4
webnotes/utils/email_lib/smtp.py Näytä tiedosto

@@ -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 []),


+ 22
- 13
webnotes/utils/scheduler.py Näytä tiedosto

@@ -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()

Ladataan…
Peruuta
Tallenna