Added Notification Control for caching notifications probably causing the freezing problem
This commit is contained in:
parent
458bf6e330
commit
27e7158fc4
17 changed files with 203 additions and 120 deletions
|
|
@ -7,8 +7,6 @@ import webnotes
|
|||
from webnotes import msgprint
|
||||
import os
|
||||
|
||||
import MySQLdb
|
||||
|
||||
from webnotes.utils import now, cint
|
||||
from webnotes.model import no_value_fields
|
||||
|
||||
|
|
@ -307,7 +305,7 @@ def make_module_and_roles(doclist, perm_doctype="DocPerm"):
|
|||
r.insert()
|
||||
except webnotes.DoesNotExistError, e:
|
||||
pass
|
||||
except MySQLdb.ProgrammingError, e:
|
||||
except webnotes.SQLError, e:
|
||||
if e.args[0]==1146:
|
||||
pass
|
||||
else:
|
||||
|
|
|
|||
0
core/doctype/notification_count/__init__.py
Normal file
0
core/doctype/notification_count/__init__.py
Normal file
105
core/doctype/notification_count/notification_count.py
Normal file
105
core/doctype/notification_count/notification_count.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# MIT License. See license.txt
|
||||
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
try:
|
||||
from startup.open_count import for_doctype, for_module, for_module_doctypes
|
||||
all_doctypes = for_doctype.keys() + for_module_doctypes.keys()
|
||||
except ImportError:
|
||||
for_doctype = {}
|
||||
for_module = {}
|
||||
for_module_doctypes = []
|
||||
all_doctypes = []
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get():
|
||||
can_read = webnotes.user.get_can_read()
|
||||
open_count_doctype = {}
|
||||
open_count_module = {}
|
||||
|
||||
notification_count = dict(webnotes.conn.sql("""select for_doctype, open_count
|
||||
from `tabNotification Count` where owner=%s""", webnotes.session.user))
|
||||
|
||||
for d in for_doctype:
|
||||
if d in can_read:
|
||||
condition = for_doctype[d]
|
||||
key = condition.keys()[0]
|
||||
|
||||
|
||||
if d in notification_count:
|
||||
open_count_doctype[d] = notification_count[d]
|
||||
else:
|
||||
result = webnotes.get_list(d, fields=["count(*)"],
|
||||
filters=[[d, key, "=", condition[key]]], as_list=True, limit_page_length=1)[0][0]
|
||||
|
||||
webnotes.doc({"doctype":"Notification Count", "for_doctype":d,
|
||||
"open_count":result}).insert()
|
||||
|
||||
open_count_doctype[d] = result
|
||||
|
||||
for m in for_module:
|
||||
if m in notification_count:
|
||||
open_count_module[m] = notification_count[m]
|
||||
else:
|
||||
open_count_module[m] = for_module[m]()
|
||||
webnotes.doc({"doctype":"Notification Count", "for_doctype":m,
|
||||
"open_count":open_count_module[m]}).insert()
|
||||
|
||||
return {
|
||||
"open_count_doctype": open_count_doctype,
|
||||
"open_count_module": open_count_module
|
||||
}
|
||||
|
||||
def delete_notification_count_for(doctype):
|
||||
try:
|
||||
webnotes.conn.sql("""delete from `tabNotification Count` where for_doctype = %s""", doctype)
|
||||
except webnotes.SQLError:
|
||||
pass # during install
|
||||
|
||||
def clear_doctype_notifications(controller, method=None):
|
||||
doctype = controller.doc.doctype
|
||||
if doctype in all_doctypes:
|
||||
delete_notification_count_for(for_module_doctypes[doctype] if doctype in \
|
||||
for_module_doctypes else doctype)
|
||||
|
||||
def get_notification_info_for_boot():
|
||||
out = get()
|
||||
|
||||
can_read = webnotes.user.get_can_read()
|
||||
conditions = {}
|
||||
module_doctypes = {}
|
||||
doctype_info = dict(webnotes.conn.sql("""select name, module from tabDocType"""))
|
||||
|
||||
try:
|
||||
from startup.open_count import for_doctype
|
||||
except ImportError:
|
||||
for_doctype = {}
|
||||
|
||||
for d in list(set(can_read + for_doctype.keys())):
|
||||
if d in for_doctype:
|
||||
conditions[d] = for_doctype[d]
|
||||
|
||||
if d in doctype_info:
|
||||
module_doctypes.setdefault(doctype_info[d], []).append(d)
|
||||
|
||||
out.update({
|
||||
"conditions": conditions,
|
||||
"module_doctypes": module_doctypes,
|
||||
})
|
||||
|
||||
return out
|
||||
|
||||
def on_doctype_update():
|
||||
if not webnotes.conn.sql("""show index from `tabNotification Count`
|
||||
where Key_name="notification_count_owner_index" """):
|
||||
webnotes.conn.commit()
|
||||
webnotes.conn.sql("""alter table `tabNotification Count`
|
||||
add index notification_count_owner_index(owner)""")
|
||||
|
||||
46
core/doctype/notification_count/notification_count.txt
Normal file
46
core/doctype/notification_count/notification_count.txt
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
[
|
||||
{
|
||||
"creation": "2013-11-18 05:31:03",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-11-18 06:26:35",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"module": "Core",
|
||||
"name": "__common__"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"name": "__common__",
|
||||
"parent": "Notification Count",
|
||||
"parentfield": "fields",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
"name": "Notification Count"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "for_doctype",
|
||||
"fieldtype": "Data",
|
||||
"label": "For DocType",
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "count",
|
||||
"fieldtype": "Int",
|
||||
"label": "Count"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "open_count",
|
||||
"fieldtype": "Int",
|
||||
"label": "Open Count"
|
||||
}
|
||||
]
|
||||
|
|
@ -95,6 +95,7 @@ class DocType:
|
|||
def on_update(self):
|
||||
# owner is always name
|
||||
webnotes.conn.set(self.doc, 'owner', self.doc.name)
|
||||
webnotes.clear_cache(user=self.doc.name)
|
||||
|
||||
def reset_password(self):
|
||||
from webnotes.utils import random_string, get_url
|
||||
|
|
@ -207,6 +208,7 @@ Thank you,<br>
|
|||
raise_exception=True)
|
||||
|
||||
def on_trash(self):
|
||||
webnotes.clear_cache(user=self.doc.name)
|
||||
if self.doc.name in ["Administrator", "Guest"]:
|
||||
webnotes.msgprint("""Hey! You cannot delete user: %s""" % (self.name, ),
|
||||
raise_exception=1)
|
||||
|
|
@ -234,8 +236,10 @@ Thank you,<br>
|
|||
# delete messages
|
||||
webnotes.conn.sql("""delete from `tabComment` where comment_doctype='Message'
|
||||
and (comment_docname=%s or owner=%s)""", (self.doc.name, self.doc.name))
|
||||
|
||||
|
||||
def on_rename(self,newdn,olddn, merge=False):
|
||||
webnotes.clear_cache(user=olddn)
|
||||
self.validate_rename(newdn, olddn)
|
||||
|
||||
tables = webnotes.conn.sql("show tables")
|
||||
|
|
|
|||
|
|
@ -68,14 +68,21 @@ def update_match(name, doctype, match=""):
|
|||
def validate_and_reset(doctype, for_remove=False):
|
||||
from core.doctype.doctype.doctype import validate_permissions_for_doctype
|
||||
validate_permissions_for_doctype(doctype, for_remove)
|
||||
webnotes.clear_cache(doctype=doctype)
|
||||
clear_doctype_cache(doctype)
|
||||
|
||||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"])
|
||||
def reset(doctype):
|
||||
webnotes.reset_perms(doctype)
|
||||
webnotes.clear_cache(doctype=doctype)
|
||||
clear_doctype_cache(doctype)
|
||||
webnotes.defaults.clear_cache()
|
||||
|
||||
def clear_doctype_cache(doctype):
|
||||
webnotes.clear_cache(doctype=doctype)
|
||||
for user in webnotes.conn.sql_list("""select distinct tabUserRole.parent from tabUserRole, tabDocPerm
|
||||
where tabDocPerm.parent = %s
|
||||
and tabDocPerm.role = tabUserRole.role""", doctype):
|
||||
webnotes.clear_cache(user=user)
|
||||
|
||||
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"])
|
||||
def get_users_with_role(role):
|
||||
return [p[0] for p in webnotes.conn.sql("""select distinct tabProfile.name
|
||||
|
|
|
|||
|
|
@ -19,26 +19,28 @@ def edit(arg=None):
|
|||
import markdown2
|
||||
args = webnotes.local.form_dict
|
||||
|
||||
d = Document('ToDo', args.get('name') or None)
|
||||
d.description = args['description']
|
||||
d.date = args['date']
|
||||
d.priority = args['priority']
|
||||
d.checked = args.get('checked', 0)
|
||||
if not d.owner: d.owner = webnotes.session['user']
|
||||
d.save(not args.get('name') and 1 or 0)
|
||||
if args.name:
|
||||
b = webnotes.bean("ToDo", args.name)
|
||||
else:
|
||||
b = webnotes.new_bean("ToDo")
|
||||
|
||||
if args.get('name') and d.checked:
|
||||
for key in ("description", "date", "priority", "checked"):
|
||||
b.doc.fields[key] = args.get(key)
|
||||
|
||||
b.insert_or_update()
|
||||
|
||||
if args.name and args.checked:
|
||||
notify_assignment(d)
|
||||
|
||||
return d.name
|
||||
return b.doc.name
|
||||
|
||||
@webnotes.whitelist()
|
||||
def delete(arg=None):
|
||||
name = webnotes.form_dict['name']
|
||||
name = webnotes.local.form_dict.name
|
||||
d = Document('ToDo', name)
|
||||
if d and d.name and d.owner != webnotes.session['user']:
|
||||
notify_assignment(d)
|
||||
webnotes.conn.sql("delete from `tabToDo` where name = %s", name)
|
||||
webnotes.delete_doc("ToDo", d.name, ignore_permissions=True)
|
||||
|
||||
def notify_assignment(d):
|
||||
doc_type = d.reference_type
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ wn.Application = Class.extend({
|
|||
refresh_notifications: function() {
|
||||
if(wn.session_alive) {
|
||||
return wn.call({
|
||||
method: "webnotes.widgets.notification.get",
|
||||
method: "core.doctype.notification_count.notification_count.get",
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
$.extend(wn.boot.notification_info, r.message);
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ wn.views.moduleview.ModuleView = Class.extend({
|
|||
$(me.wrapper).find(".badge-important").remove();
|
||||
if(wn.boot.notification_info.open_count_doctype) {
|
||||
$.each(wn.boot.notification_info.open_count_doctype, function(doctype, count) {
|
||||
if(in_list(me.doctypes, doctype)) {
|
||||
if(count && in_list(me.doctypes, doctype)) {
|
||||
me.set_top_item_count(doctype, null, count);
|
||||
$('<span>')
|
||||
.css({
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from __future__ import unicode_literals
|
|||
|
||||
from werkzeug.local import Local
|
||||
from werkzeug.exceptions import NotFound
|
||||
from MySQLdb import ProgrammingError as SQLError
|
||||
|
||||
import os
|
||||
import json
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ import webnotes
|
|||
from webnotes import _, msgprint
|
||||
from webnotes.utils import cint, cstr, flt
|
||||
from webnotes.model.doc import Document
|
||||
try:
|
||||
from startup.bean_handlers import on_method
|
||||
except ImportError:
|
||||
on_method = None
|
||||
|
||||
class DocstatusTransitionError(webnotes.ValidationError): pass
|
||||
class BeanPermissionError(webnotes.ValidationError): pass
|
||||
|
|
@ -236,7 +240,7 @@ class Bean:
|
|||
if hasattr(self.controller, 'custom_' + method):
|
||||
getattr(self.controller, 'custom_' + method)(*args, **kwargs)
|
||||
|
||||
notify(self.controller, method)
|
||||
notify(self, method)
|
||||
|
||||
self.set_doclist(self.controller.doclist)
|
||||
|
||||
|
|
@ -256,7 +260,7 @@ class Bean:
|
|||
return self.save()
|
||||
|
||||
def insert_or_update(self):
|
||||
if webnotes.conn.exists( self.doc.doctype, self.doc.name):
|
||||
if self.doc.name and webnotes.conn.exists(self.doc.doctype, self.doc.name):
|
||||
return self.save()
|
||||
else:
|
||||
return self.insert()
|
||||
|
|
@ -461,33 +465,12 @@ def clone(source_wrapper):
|
|||
|
||||
return new_wrapper
|
||||
|
||||
|
||||
def notify(controller, caller_method):
|
||||
try:
|
||||
from startup.observers import observer_map
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
doctype = controller.doc.doctype
|
||||
|
||||
def call_observers(key):
|
||||
if key in observer_map:
|
||||
observer_list = observer_map[key]
|
||||
if isinstance(observer_list, basestring):
|
||||
observer_list = [observer_list]
|
||||
for observer_method in observer_list:
|
||||
webnotes.get_method(observer_method)(controller, caller_method)
|
||||
|
||||
call_observers("*:*")
|
||||
call_observers(doctype + ":*")
|
||||
call_observers("*:" + caller_method)
|
||||
call_observers(doctype + ":" + caller_method)
|
||||
def notify(bean, method):
|
||||
if on_method:
|
||||
on_method(bean, method)
|
||||
|
||||
# for bc
|
||||
def getlist(doclist, parentfield):
|
||||
"""
|
||||
Return child records of a particular type
|
||||
"""
|
||||
import webnotes.model.utils
|
||||
return webnotes.model.utils.getlist(doclist, parentfield)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ _toc = ["webnotes.model.doc.Document"]
|
|||
|
||||
import webnotes
|
||||
import webnotes.model.meta
|
||||
import MySQLdb
|
||||
|
||||
from webnotes.utils import *
|
||||
|
||||
|
|
@ -132,7 +131,7 @@ class Document:
|
|||
else:
|
||||
try:
|
||||
dataset = webnotes.conn.sql('select * from `tab%s` where name="%s"' % (self.doctype, self.name.replace('"', '\"')))
|
||||
except MySQLdb.ProgrammingError, e:
|
||||
except webnotes.SQLError, e:
|
||||
if e.args[0]==1146:
|
||||
dataset = None
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -244,7 +244,11 @@ def clear_cache(doctype=None):
|
|||
for dt in webnotes.conn.sql("""select parent from tabDocField
|
||||
where fieldtype="Table" and options=%s""", doctype):
|
||||
clear_single(dt[0])
|
||||
|
||||
|
||||
# clear all notifications
|
||||
from core.doctype.notification_count.notification_count import delete_notification_count_for
|
||||
delete_notification_count_for(doctype)
|
||||
|
||||
else:
|
||||
# clear all
|
||||
for dt in webnotes.conn.sql("""select name from tabDocType"""):
|
||||
|
|
|
|||
|
|
@ -179,12 +179,11 @@ def check_permission_and_not_submitted(doctype, name, ignore_permissions=False):
|
|||
def run_on_trash(doctype, name, doclist):
|
||||
# call on_trash if required
|
||||
if doclist:
|
||||
obj = webnotes.get_obj(doclist=doclist)
|
||||
bean = webnotes.bean(doclist)
|
||||
else:
|
||||
obj = webnotes.get_obj(doctype, name)
|
||||
|
||||
if hasattr(obj,'on_trash'):
|
||||
obj.on_trash()
|
||||
bean = webnotes.bean(doctype, name)
|
||||
|
||||
bean.run_method("on_trash")
|
||||
|
||||
class LinkExistsError(webnotes.ValidationError): pass
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,10 @@ def exec_code(code, namespace=None):
|
|||
|
||||
return namespace
|
||||
|
||||
def get_code(module, doctype, docname, plugin=None):
|
||||
import MySQLdb
|
||||
|
||||
def get_code(module, doctype, docname, plugin=None):
|
||||
try:
|
||||
code = read_file(module, doctype, docname, plugin, cache=True)
|
||||
except MySQLdb.OperationalError:
|
||||
# this happens when syncing
|
||||
except webnotes.SQLError:
|
||||
return None
|
||||
|
||||
return code
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ def clear_sessions(user=None, keep_current=False):
|
|||
|
||||
def get():
|
||||
"""get session boot info"""
|
||||
from webnotes.widgets.notification import get_notification_info_for_boot
|
||||
from core.doctype.notification_count.notification_count import get_notification_info_for_boot
|
||||
|
||||
bootinfo = None
|
||||
if not getattr(conf,'auto_cache_clear',None):
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get():
|
||||
try:
|
||||
from startup.open_count import for_doctype, for_module
|
||||
except ImportError, e:
|
||||
return {}
|
||||
|
||||
can_read = webnotes.user.get_can_read()
|
||||
open_count_doctype = {}
|
||||
open_count_module = {}
|
||||
|
||||
for d in for_doctype:
|
||||
if d in can_read:
|
||||
condition = for_doctype[d]
|
||||
key = condition.keys()[0]
|
||||
|
||||
result = webnotes.get_list(d, fields=["count(*)"],
|
||||
filters=[[d, key, "=", condition[key]]], as_list=True)[0][0]
|
||||
if result:
|
||||
open_count_doctype[d] = result
|
||||
|
||||
for m in for_module:
|
||||
open_count_module[m] = for_module[m]()
|
||||
|
||||
return {
|
||||
"open_count_doctype": open_count_doctype,
|
||||
"open_count_module": open_count_module
|
||||
}
|
||||
|
||||
def get_notification_info_for_boot():
|
||||
out = get()
|
||||
|
||||
can_read = webnotes.user.get_can_read()
|
||||
conditions = {}
|
||||
module_doctypes = {}
|
||||
doctype_info = dict(webnotes.conn.sql("""select name, module from tabDocType"""))
|
||||
|
||||
try:
|
||||
from startup.open_count import for_doctype
|
||||
except ImportError:
|
||||
for_doctype = {}
|
||||
|
||||
for d in list(set(can_read + for_doctype.keys())):
|
||||
if d in for_doctype:
|
||||
conditions[d] = for_doctype[d]
|
||||
|
||||
if d in doctype_info:
|
||||
module_doctypes.setdefault(doctype_info[d], []).append(d)
|
||||
|
||||
out.update({
|
||||
"conditions": conditions,
|
||||
"module_doctypes": module_doctypes,
|
||||
})
|
||||
|
||||
return out
|
||||
|
||||
Loading…
Add table
Reference in a new issue