Fixed Website Response, Startup JS loading,
Conditions involving STANDARD_USERS, removed Validate Max Users, Cast Floats and Ints for Single DocTypes, Ability to Disable Scheduler
This commit is contained in:
parent
0a43add3d3
commit
cec016be2a
14 changed files with 126 additions and 91 deletions
|
|
@ -54,7 +54,6 @@ def get_bootinfo():
|
|||
add_allowed_pages(bootinfo)
|
||||
load_translations(bootinfo)
|
||||
load_conf_settings(bootinfo)
|
||||
load_startup_js(bootinfo)
|
||||
|
||||
# ipinfo
|
||||
if frappe.session['data'].get('ipinfo'):
|
||||
|
|
@ -120,10 +119,11 @@ def get_fullnames():
|
|||
|
||||
return d
|
||||
|
||||
def load_startup_js(bootinfo):
|
||||
bootinfo.startup_js = ""
|
||||
def get_startup_js():
|
||||
startup_js = []
|
||||
for method in frappe.get_hooks().startup_js or []:
|
||||
bootinfo.startup_js += frappe.get_attr(method)()
|
||||
startup_js.append(frappe.get_attr(method)() or "")
|
||||
return "\n".join(startup_js)
|
||||
|
||||
def get_user(bootinfo):
|
||||
"""get user info"""
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||
import frappe
|
||||
|
||||
from frappe.utils import getdate, cint, add_months, date_diff, add_days, nowdate
|
||||
from frappe.core.doctype.user.user import STANDARD_USERS
|
||||
|
||||
weekdays = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
|
||||
|
||||
|
|
@ -52,7 +53,9 @@ def send_event_digest():
|
|||
today = nowdate()
|
||||
for user in frappe.db.sql("""select name, email, language
|
||||
from tabUser where ifnull(enabled,0)=1
|
||||
and user_type='System User' and name not in ('Guest', 'Administrator')""", as_dict=1):
|
||||
and user_type='System User' and name not in ({})""".format(", ".join(["%s"]*len(STANDARD_USERS))),
|
||||
STANDARD_USERS, as_dict=1):
|
||||
|
||||
events = get_events(today, today, user.name, for_reminder=True)
|
||||
if events:
|
||||
text = ""
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ from frappe.utils import cint, now, cstr
|
|||
from frappe import throw, msgprint, _
|
||||
from frappe.auth import _update_password
|
||||
|
||||
STANDARD_USERS = ("Guest", "Administrator")
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist):
|
||||
self.doc = doc
|
||||
|
|
@ -14,7 +16,7 @@ class DocType:
|
|||
|
||||
def autoname(self):
|
||||
"""set name as email id"""
|
||||
if self.doc.name not in ('Guest','Administrator'):
|
||||
if self.doc.name not in STANDARD_USERS:
|
||||
self.doc.email = self.doc.email.strip()
|
||||
self.doc.name = self.doc.email
|
||||
|
||||
|
|
@ -23,31 +25,16 @@ class DocType:
|
|||
|
||||
def validate(self):
|
||||
self.in_insert = self.doc.fields.get("__islocal")
|
||||
if self.doc.name not in ('Guest','Administrator'):
|
||||
if self.doc.name not in STANDARD_USERS:
|
||||
self.validate_email_type(self.doc.email)
|
||||
self.validate_max_users()
|
||||
self.add_system_manager_role()
|
||||
self.check_enable_disable()
|
||||
if self.in_insert:
|
||||
if self.doc.name not in ("Guest", "Administrator"):
|
||||
if self.doc.new_password:
|
||||
# new password given, no email required
|
||||
_update_password(self.doc.name, self.doc.new_password)
|
||||
if not getattr(self, "no_welcome_mail", False):
|
||||
self.send_welcome_mail()
|
||||
msgprint(_("Welcome Email Sent"))
|
||||
else:
|
||||
try:
|
||||
self.email_new_password()
|
||||
except frappe.OutgoingEmailError:
|
||||
pass # email server not set, don't send email
|
||||
|
||||
self.doc.new_password = ""
|
||||
self.update_gravatar()
|
||||
|
||||
def check_enable_disable(self):
|
||||
# do not allow disabling administrator/guest
|
||||
if not cint(self.doc.enabled) and self.doc.name in ["Administrator", "Guest"]:
|
||||
if not cint(self.doc.enabled) and self.doc.name in STANDARD_USERS:
|
||||
throw("{msg}: {name}".format(**{
|
||||
"msg": _("Hey! You cannot disable user"),
|
||||
"name": self.doc.name
|
||||
|
|
@ -60,26 +47,6 @@ class DocType:
|
|||
if not cint(self.doc.enabled) and getattr(frappe, "login_manager", None):
|
||||
frappe.local.login_manager.logout(user=self.doc.name)
|
||||
|
||||
def validate_max_users(self):
|
||||
"""don't allow more than max users if set in conf"""
|
||||
from frappe import conf
|
||||
# check only when enabling a user
|
||||
if 'max_users' in conf and self.doc.enabled and \
|
||||
self.doc.name not in ["Administrator", "Guest"] and \
|
||||
cstr(self.doc.user_type).strip() in ("", "System User"):
|
||||
active_users = frappe.db.sql("""select count(*) from tabUser
|
||||
where ifnull(enabled, 0)=1 and docstatus<2
|
||||
and ifnull(user_type, "System User") = "System User"
|
||||
and name not in ('Administrator', 'Guest', %s)""", (self.doc.name,))[0][0]
|
||||
if active_users >= conf.max_users and conf.max_users:
|
||||
throw("""
|
||||
You already have <b>%(active_users)s</b> active users, \
|
||||
which is the maximum number that you are currently allowed to add. <br /><br /> \
|
||||
So, to add more users, you can:<br /> \
|
||||
1. <b>Upgrade to the unlimited users plan</b>, or<br /> \
|
||||
2. <b>Disable one or more of your existing users and try again</b>""" \
|
||||
% {'active_users': active_users})
|
||||
|
||||
def add_system_manager_role(self):
|
||||
# if adding system manager, do nothing
|
||||
if not cint(self.doc.enabled) or ("System Manager" in [user_role.role for user_role in
|
||||
|
|
@ -107,6 +74,21 @@ class DocType:
|
|||
frappe.db.set(self.doc, 'owner', self.doc.name)
|
||||
frappe.clear_cache(user=self.doc.name)
|
||||
|
||||
try:
|
||||
if self.in_insert:
|
||||
if self.doc.name not in STANDARD_USERS:
|
||||
if self.doc.new_password:
|
||||
# new password given, no email required
|
||||
_update_password(self.doc.name, self.doc.new_password)
|
||||
if not getattr(self, "no_welcome_mail", False):
|
||||
self.send_welcome_mail()
|
||||
msgprint(_("Welcome Email Sent"))
|
||||
else:
|
||||
self.email_new_password()
|
||||
|
||||
except frappe.OutgoingEmailError:
|
||||
pass # email server not set, don't send email
|
||||
|
||||
def update_gravatar(self):
|
||||
import md5
|
||||
if not self.doc.user_image:
|
||||
|
|
@ -168,7 +150,7 @@ class DocType:
|
|||
|
||||
args.update(add_args)
|
||||
|
||||
sender = frappe.session.user not in ("Administrator", "Guest") and frappe.session.user or None
|
||||
sender = frappe.session.user not in STANDARD_USERS and frappe.session.user or None
|
||||
|
||||
frappe.sendmail(recipients=self.doc.email, sender=sender, subject=subject,
|
||||
message=frappe.get_template(template).render(args))
|
||||
|
|
@ -179,7 +161,7 @@ class DocType:
|
|||
|
||||
def on_trash(self):
|
||||
frappe.clear_cache(user=self.doc.name)
|
||||
if self.doc.name in ["Administrator", "Guest"]:
|
||||
if self.doc.name in STANDARD_USERS:
|
||||
throw("{msg}: {name}".format(**{
|
||||
"msg": _("Hey! You cannot delete user"),
|
||||
"name": self.doc.name
|
||||
|
|
@ -215,7 +197,7 @@ class DocType:
|
|||
|
||||
def validate_rename(self, olddn, newdn):
|
||||
# do not allow renaming administrator and guest
|
||||
if olddn in ["Administrator", "Guest"]:
|
||||
if olddn in STANDARD_USERS:
|
||||
throw("{msg}: {name}".format(**{
|
||||
"msg": _("Hey! You are restricted from renaming the user"),
|
||||
"name": olddn
|
||||
|
|
@ -357,35 +339,50 @@ def reset_password(user):
|
|||
|
||||
def user_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
from frappe.widgets.reportview import get_match_cond
|
||||
txt = "%{}%".format(txt)
|
||||
return frappe.db.sql("""select name, concat_ws(' ', first_name, middle_name, last_name)
|
||||
from `tabUser`
|
||||
where ifnull(enabled, 0)=1
|
||||
and docstatus < 2
|
||||
and name not in ('Administrator', 'Guest')
|
||||
and name not in ({standard_users})
|
||||
and user_type != 'Website User'
|
||||
and (%(key)s like "%(txt)s"
|
||||
or concat_ws(' ', first_name, middle_name, last_name) like "%(txt)s")
|
||||
%(mcond)s
|
||||
and ({key} like %s
|
||||
or concat_ws(' ', first_name, middle_name, last_name) like %s)
|
||||
{mcond}
|
||||
order by
|
||||
case when name like "%(txt)s" then 0 else 1 end,
|
||||
case when concat_ws(' ', first_name, middle_name, last_name) like "%(txt)s"
|
||||
case when name like %s then 0 else 1 end,
|
||||
case when concat_ws(' ', first_name, middle_name, last_name) like %s
|
||||
then 0 else 1 end,
|
||||
name asc
|
||||
limit %(start)s, %(page_len)s""" % {'key': searchfield, 'txt': "%%%s%%" % txt,
|
||||
'mcond':get_match_cond(doctype), 'start': start, 'page_len': page_len})
|
||||
limit %s, %s""".format(standard_users=", ".join(["%s"]*len(STANDARD_USERS)),
|
||||
key=searchfield, mcond=get_match_cond(doctype)),
|
||||
tuple(list(STANDARD_USERS) + [txt, txt, txt, txt, start, page_len]))
|
||||
|
||||
def get_total_users():
|
||||
def get_total_users(exclude_users=None):
|
||||
"""Returns total no. of system users"""
|
||||
return frappe.db.sql("""select count(*) from `tabUser`
|
||||
where enabled = 1 and user_type != 'Website User'
|
||||
and name not in ('Administrator', 'Guest')""")[0][0]
|
||||
return len(get_system_users(exclude_users=exclude_users))
|
||||
|
||||
def get_system_users(exclude_users=None):
|
||||
if not exclude_users:
|
||||
exclude_users = []
|
||||
elif not isinstance(exclude_users, (list, tuple)):
|
||||
exclude_users = [exclude_users]
|
||||
|
||||
exclude_users += list(STANDARD_USERS)
|
||||
|
||||
system_users = frappe.db.sql_list("""select name from `tabUser`
|
||||
where enabled=1 and user_type != 'Website User'
|
||||
and name not in ({})""".format(", ".join(["%s"]*len(exclude_users))),
|
||||
exclude_users)
|
||||
|
||||
return system_users
|
||||
|
||||
def get_active_users():
|
||||
"""Returns No. of system users who logged in, in the last 3 days"""
|
||||
return frappe.db.sql("""select count(*) from `tabUser`
|
||||
where enabled = 1 and user_type != 'Website User'
|
||||
and name not in ('Administrator', 'Guest')
|
||||
and hour(timediff(now(), last_login)) < 72""")[0][0]
|
||||
and name not in ({})
|
||||
and hour(timediff(now(), last_login)) < 72""".format(", ".join(["%s"]*len(STANDARD_USERS))), STANDARD_USERS)[0][0]
|
||||
|
||||
def get_website_users():
|
||||
"""Returns total no. of website users"""
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.core.doctype.notification_count.notification_count import delete_notification_count_for
|
||||
|
||||
from frappe.core.doctype.user.user import STANDARD_USERS
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_list(arg=None):
|
||||
|
|
@ -51,8 +51,8 @@ def get_active_users():
|
|||
from tabUser
|
||||
where ifnull(enabled,0)=1 and
|
||||
ifnull(user_type, '')!='Website User' and
|
||||
name not in ('Administrator', 'Guest')
|
||||
order by first_name""", as_dict=1)
|
||||
name not in ({})
|
||||
order by first_name""".format(", ".join(["%s"]*len(STANDARD_USERS))), STANDARD_USERS, as_dict=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def post(arg=None):
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ from __future__ import unicode_literals
|
|||
import frappe
|
||||
import frappe.defaults
|
||||
import frappe.permissions
|
||||
from frappe.core.doctype.user.user import get_system_users
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_users_and_links():
|
||||
return {
|
||||
"users": frappe.db.sql_list("""select name from tabUser where
|
||||
ifnull(enabled,0)=1 and
|
||||
name not in ("Administrator", "Guest")"""),
|
||||
"users": get_system_users(),
|
||||
"link_fields": get_restrictable_doctypes()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,9 +68,6 @@ class Bean:
|
|||
|
||||
self.set_doclist(doclist)
|
||||
|
||||
if dt == dn:
|
||||
self.convert_type(self.doc)
|
||||
|
||||
def __iter__(self):
|
||||
return self.doclist.__iter__()
|
||||
|
||||
|
|
@ -91,6 +88,10 @@ class Bean:
|
|||
|
||||
self.doclist = frappe.doclist(doclist)
|
||||
self.doc = self.doclist[0]
|
||||
|
||||
if self.doc.get_meta().issingle:
|
||||
self.doc.cast_floats_and_ints()
|
||||
|
||||
if self.obj:
|
||||
self.obj.doclist = self.doclist
|
||||
self.obj.doc = self.doc
|
||||
|
|
@ -444,16 +445,6 @@ class Bean:
|
|||
|
||||
raise frappe.MandatoryError, ", ".join([fieldname for msg, fieldname in missing])
|
||||
|
||||
def convert_type(self, doc):
|
||||
if doc.doctype==doc.name and doc.doctype!="DocType":
|
||||
for df in self.meta.get({"doctype": "DocField", "parent": doc.doctype}):
|
||||
if df.fieldtype in ("Int", "Check"):
|
||||
doc.fields[df.fieldname] = cint(doc.fields.get(df.fieldname))
|
||||
elif df.fieldtype in ("Float", "Currency"):
|
||||
doc.fields[df.fieldname] = flt(doc.fields.get(df.fieldname))
|
||||
|
||||
doc.docstatus = cint(doc.docstatus)
|
||||
|
||||
def extract_images_from_text_editor(self):
|
||||
from frappe.utils.file_manager import extract_images_from_html
|
||||
if self.doc.doctype != "DocType":
|
||||
|
|
|
|||
|
|
@ -161,7 +161,18 @@ class Document:
|
|||
def _loadsingle(self):
|
||||
self.name = self.doctype
|
||||
self.fields.update(getsingle(self.doctype))
|
||||
|
||||
self.cast_floats_and_ints()
|
||||
|
||||
def cast_floats_and_ints(self):
|
||||
for df in frappe.get_doctype(self.doctype).get_docfields():
|
||||
if df.fieldtype in ("Int", "Check"):
|
||||
self.fields[df.fieldname] = cint(self.fields.get(df.fieldname))
|
||||
elif df.fieldtype in ("Float", "Currency"):
|
||||
self.fields[df.fieldname] = flt(self.fields.get(df.fieldname))
|
||||
|
||||
if self.docstatus is not None:
|
||||
self.docstatus = cint(self.docstatus)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
# normal attribute
|
||||
if not self.__dict__.has_key('_Document__initialized'):
|
||||
|
|
|
|||
|
|
@ -380,10 +380,12 @@ class DocTypeDocList(frappe.model.doclist.DocList):
|
|||
return fieldname in self.get_fieldnames()
|
||||
|
||||
def get_fieldnames(self, filters=None):
|
||||
return map(lambda df: df.fieldname, self.get_docfields(filters))
|
||||
|
||||
def get_docfields(self, filters=None):
|
||||
if not filters: filters = {}
|
||||
filters.update({"doctype": "DocField", "parent": self[0].name})
|
||||
|
||||
return map(lambda df: df.fieldname, self.get(filters))
|
||||
return self.get(filters)
|
||||
|
||||
def get_options(self, fieldname, parent=None, parentfield=None):
|
||||
return self.get_field(fieldname, parent, parentfield).options
|
||||
|
|
|
|||
|
|
@ -68,24 +68,26 @@ def get():
|
|||
"""get session boot info"""
|
||||
from frappe.core.doctype.notification_count.notification_count import \
|
||||
get_notification_info_for_boot, get_notifications
|
||||
from frappe.boot import get_bootinfo, get_startup_js
|
||||
|
||||
bootinfo = None
|
||||
if not getattr(frappe.conf,'disable_session_cache',None):
|
||||
if not getattr(frappe.conf,'disable_session_cache', None):
|
||||
# check if cache exists
|
||||
bootinfo = frappe.cache().get_value('bootinfo:' + frappe.session.user)
|
||||
if bootinfo:
|
||||
bootinfo['from_cache'] = 1
|
||||
bootinfo["user"]["recent"] = json.dumps(frappe.cache().get_value("recent:" + frappe.session.user))
|
||||
bootinfo["notification_info"].update(get_notifications())
|
||||
bootinfo["startup_js"] = get_startup_js()
|
||||
|
||||
if not bootinfo:
|
||||
if not frappe.cache().get_stats():
|
||||
frappe.msgprint("memcached is not working / stopped. Please start memcached for best results.")
|
||||
|
||||
# if not create it
|
||||
from frappe.boot import get_bootinfo
|
||||
bootinfo = get_bootinfo()
|
||||
bootinfo["notification_info"] = get_notification_info_for_boot()
|
||||
bootinfo["startup_js"] = get_startup_js()
|
||||
frappe.cache().set_value('bootinfo:' + frappe.session.user, bootinfo)
|
||||
|
||||
return bootinfo
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ from __future__ import unicode_literals
|
|||
import unittest
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.core.doctype.user.user import STANDARD_USERS
|
||||
|
||||
class TestDB(unittest.TestCase):
|
||||
def test_get_value(self):
|
||||
from frappe.utils import now_datetime
|
||||
import time
|
||||
frappe.db.sql("""delete from `tabUser` where name not in ('Administrator', 'Guest')""")
|
||||
frappe.db.sql("""delete from `tabUser` where name not in ({})""".format(", ".join(["%s"]*len(STANDARD_USERS))),
|
||||
STANDARD_USERS)
|
||||
|
||||
now = now_datetime()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ def send(email, as_bulk=False):
|
|||
if frappe.flags.mute_emails or frappe.conf.get("mute_emails") or False:
|
||||
frappe.msgprint("Emails are muted")
|
||||
return
|
||||
|
||||
|
||||
try:
|
||||
smtpserver = SMTPServer()
|
||||
if hasattr(smtpserver, "always_use_login_id_as_sender") and \
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ from datetime import datetime
|
|||
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
def enqueue_events(site):
|
||||
if is_scheduler_disabled():
|
||||
return
|
||||
|
||||
# lock before queuing begins
|
||||
try:
|
||||
lock = create_lock('scheduler')
|
||||
|
|
@ -103,6 +106,15 @@ def log(method, message=None):
|
|||
|
||||
return message
|
||||
|
||||
def is_scheduler_disabled():
|
||||
return frappe.utils.cint(frappe.db.get_global("disable_scheduler"))
|
||||
|
||||
def enable_scheduler():
|
||||
frappe.db.set_global("disable_scheduler", 0)
|
||||
|
||||
def disable_scheduler():
|
||||
frappe.db.set_global("disable_scheduler", 1)
|
||||
|
||||
def get_errors(from_date, to_date, limit):
|
||||
errors = frappe.db.sql("""select modified, method, error from `tabScheduler Log`
|
||||
where date(modified) between %s and %s
|
||||
|
|
@ -127,6 +139,6 @@ def get_error_report(from_date=None, to_date=None, limit=10):
|
|||
limit=limit, url=get_url(), errors="<hr>".join(errors))
|
||||
else:
|
||||
return 0, "<p>Scheduler didn't encounter any problems.</p>"
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
execute()
|
||||
|
|
|
|||
|
|
@ -179,13 +179,15 @@ def get_user_fullname(user):
|
|||
def get_system_managers(only_name=False):
|
||||
"""returns all system manager's user details"""
|
||||
import email.utils
|
||||
from frappe.core.doctype.user.user import STANDARD_USERS
|
||||
system_managers = frappe.db.sql("""select distinct name,
|
||||
concat_ws(" ", if(first_name="", null, first_name), if(last_name="", null, last_name))
|
||||
as fullname from tabUser p
|
||||
where docstatus < 2 and enabled = 1
|
||||
and name not in ("Administrator", "Guest")
|
||||
and name not in ({})
|
||||
and exists (select * from tabUserRole ur
|
||||
where ur.parent = p.name and ur.role="System Manager")""", as_dict=True)
|
||||
where ur.parent = p.name and ur.role="System Manager")""".format(", ".join(["%s"]*len(STANDARD_USERS))),
|
||||
STANDARD_USERS, as_dict=True)
|
||||
|
||||
if only_name:
|
||||
return [p.name for p in system_managers]
|
||||
|
|
|
|||
|
|
@ -16,16 +16,28 @@ def render(path):
|
|||
"""render html page"""
|
||||
frappe.local.is_ajax = frappe.get_request_header("X-Requested-With")=="XMLHttpRequest"
|
||||
path = resolve_path(path.lstrip("/"))
|
||||
http_status_code = 200
|
||||
|
||||
try:
|
||||
data = render_page(path)
|
||||
|
||||
except frappe.DoesNotExistError, e:
|
||||
path = "404"
|
||||
data = render_page(path)
|
||||
http_status_code = e.http_status_code
|
||||
|
||||
except Exception:
|
||||
path = "error"
|
||||
data = render_page(path)
|
||||
http_status_code = 500
|
||||
|
||||
return build_response(path, data, http_status_code)
|
||||
|
||||
def build_response(path, data, http_status_code):
|
||||
# build response
|
||||
response = Response()
|
||||
response.data = set_content_type(response, data, path)
|
||||
response.status_code = http_status_code
|
||||
response.headers[b"X-Page-Name"] = path.encode("utf-8")
|
||||
response.headers[b"X-From-Cache"] = frappe.local.response.from_cache or False
|
||||
return response
|
||||
|
|
@ -53,14 +65,16 @@ def build(path):
|
|||
frappe.connect()
|
||||
|
||||
build_method = (build_json if is_ajax() else build_page)
|
||||
|
||||
try:
|
||||
return build_method(path)
|
||||
except frappe.DoesNotExistError:
|
||||
hooks = frappe.get_hooks()
|
||||
if hooks.website_catch_all:
|
||||
return build_method(hooks.website_catch_all[0])
|
||||
path = hooks.website_catch_all[0]
|
||||
return build_method(path)
|
||||
else:
|
||||
return build_method("404")
|
||||
raise
|
||||
|
||||
def build_json(path):
|
||||
return get_context(path).data
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue