ソースを参照

Added Notification Control for caching notifications probably causing the freezing problem

version-14
Rushabh Mehta 11年前
コミット
27e7158fc4
17個のファイルの変更204行の追加121行の削除
  1. +1
    -3
      core/doctype/doctype/doctype.py
  2. +0
    -0
      core/doctype/notification_count/__init__.py
  3. +105
    -0
      core/doctype/notification_count/notification_count.py
  4. +46
    -0
      core/doctype/notification_count/notification_count.txt
  5. +4
    -0
      core/doctype/profile/profile.py
  6. +9
    -2
      core/page/permission_manager/permission_manager.py
  7. +14
    -12
      core/page/todo/todo.py
  8. +1
    -1
      public/js/wn/app.js
  9. +1
    -1
      public/js/wn/views/moduleview.js
  10. +1
    -0
      webnotes/__init__.py
  11. +9
    -26
      webnotes/model/bean.py
  12. +1
    -2
      webnotes/model/doc.py
  13. +5
    -1
      webnotes/model/doctype.py
  14. +4
    -5
      webnotes/model/utils.py
  15. +2
    -5
      webnotes/plugins.py
  16. +1
    -1
      webnotes/sessions.py
  17. +0
    -62
      webnotes/widgets/notification.py

+ 1
- 3
core/doctype/doctype/doctype.py ファイルの表示

@@ -7,8 +7,6 @@ import webnotes
from webnotes import msgprint from webnotes import msgprint
import os import os


import MySQLdb

from webnotes.utils import now, cint from webnotes.utils import now, cint
from webnotes.model import no_value_fields from webnotes.model import no_value_fields


@@ -307,7 +305,7 @@ def make_module_and_roles(doclist, perm_doctype="DocPerm"):
r.insert() r.insert()
except webnotes.DoesNotExistError, e: except webnotes.DoesNotExistError, e:
pass pass
except MySQLdb.ProgrammingError, e:
except webnotes.SQLError, e:
if e.args[0]==1146: if e.args[0]==1146:
pass pass
else: else:


+ 0
- 0
core/doctype/notification_count/__init__.py ファイルの表示


+ 105
- 0
core/doctype/notification_count/notification_count.py ファイルの表示

@@ -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
- 0
core/doctype/notification_count/notification_count.txt ファイルの表示

@@ -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"
}
]

+ 4
- 0
core/doctype/profile/profile.py ファイルの表示

@@ -95,6 +95,7 @@ class DocType:
def on_update(self): def on_update(self):
# owner is always name # owner is always name
webnotes.conn.set(self.doc, 'owner', self.doc.name) webnotes.conn.set(self.doc, 'owner', self.doc.name)
webnotes.clear_cache(user=self.doc.name)
def reset_password(self): def reset_password(self):
from webnotes.utils import random_string, get_url from webnotes.utils import random_string, get_url
@@ -207,6 +208,7 @@ Thank you,<br>
raise_exception=True) raise_exception=True)
def on_trash(self): def on_trash(self):
webnotes.clear_cache(user=self.doc.name)
if self.doc.name in ["Administrator", "Guest"]: if self.doc.name in ["Administrator", "Guest"]:
webnotes.msgprint("""Hey! You cannot delete user: %s""" % (self.name, ), webnotes.msgprint("""Hey! You cannot delete user: %s""" % (self.name, ),
raise_exception=1) raise_exception=1)
@@ -234,8 +236,10 @@ Thank you,<br>
# delete messages # delete messages
webnotes.conn.sql("""delete from `tabComment` where comment_doctype='Message' webnotes.conn.sql("""delete from `tabComment` where comment_doctype='Message'
and (comment_docname=%s or owner=%s)""", (self.doc.name, self.doc.name)) and (comment_docname=%s or owner=%s)""", (self.doc.name, self.doc.name))
def on_rename(self,newdn,olddn, merge=False): def on_rename(self,newdn,olddn, merge=False):
webnotes.clear_cache(user=olddn)
self.validate_rename(newdn, olddn) self.validate_rename(newdn, olddn)
tables = webnotes.conn.sql("show tables") tables = webnotes.conn.sql("show tables")


+ 9
- 2
core/page/permission_manager/permission_manager.py ファイルの表示

@@ -68,14 +68,21 @@ def update_match(name, doctype, match=""):
def validate_and_reset(doctype, for_remove=False): def validate_and_reset(doctype, for_remove=False):
from core.doctype.doctype.doctype import validate_permissions_for_doctype from core.doctype.doctype.doctype import validate_permissions_for_doctype
validate_permissions_for_doctype(doctype, for_remove) validate_permissions_for_doctype(doctype, for_remove)
webnotes.clear_cache(doctype=doctype)
clear_doctype_cache(doctype)
@webnotes.whitelist(allow_roles=["System Manager", "Administrator"]) @webnotes.whitelist(allow_roles=["System Manager", "Administrator"])
def reset(doctype): def reset(doctype):
webnotes.reset_perms(doctype) webnotes.reset_perms(doctype)
webnotes.clear_cache(doctype=doctype)
clear_doctype_cache(doctype)
webnotes.defaults.clear_cache() 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"]) @webnotes.whitelist(allow_roles=["System Manager", "Administrator"])
def get_users_with_role(role): def get_users_with_role(role):
return [p[0] for p in webnotes.conn.sql("""select distinct tabProfile.name return [p[0] for p in webnotes.conn.sql("""select distinct tabProfile.name


+ 14
- 12
core/page/todo/todo.py ファイルの表示

@@ -19,26 +19,28 @@ def edit(arg=None):
import markdown2 import markdown2
args = webnotes.local.form_dict 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.get('name') and d.checked:
if args.name:
b = webnotes.bean("ToDo", args.name)
else:
b = webnotes.new_bean("ToDo")

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) notify_assignment(d)


return d.name
return b.doc.name


@webnotes.whitelist() @webnotes.whitelist()
def delete(arg=None): def delete(arg=None):
name = webnotes.form_dict['name']
name = webnotes.local.form_dict.name
d = Document('ToDo', name) d = Document('ToDo', name)
if d and d.name and d.owner != webnotes.session['user']: if d and d.name and d.owner != webnotes.session['user']:
notify_assignment(d) 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): def notify_assignment(d):
doc_type = d.reference_type doc_type = d.reference_type


+ 1
- 1
public/js/wn/app.js ファイルの表示

@@ -114,7 +114,7 @@ wn.Application = Class.extend({
refresh_notifications: function() { refresh_notifications: function() {
if(wn.session_alive) { if(wn.session_alive) {
return wn.call({ return wn.call({
method: "webnotes.widgets.notification.get",
method: "core.doctype.notification_count.notification_count.get",
callback: function(r) { callback: function(r) {
if(r.message) { if(r.message) {
$.extend(wn.boot.notification_info, r.message); $.extend(wn.boot.notification_info, r.message);


+ 1
- 1
public/js/wn/views/moduleview.js ファイルの表示

@@ -248,7 +248,7 @@ wn.views.moduleview.ModuleView = Class.extend({
$(me.wrapper).find(".badge-important").remove(); $(me.wrapper).find(".badge-important").remove();
if(wn.boot.notification_info.open_count_doctype) { if(wn.boot.notification_info.open_count_doctype) {
$.each(wn.boot.notification_info.open_count_doctype, function(doctype, count) { $.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); me.set_top_item_count(doctype, null, count);
$('<span>') $('<span>')
.css({ .css({


+ 1
- 0
webnotes/__init__.py ファイルの表示

@@ -9,6 +9,7 @@ from __future__ import unicode_literals


from werkzeug.local import Local from werkzeug.local import Local
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from MySQLdb import ProgrammingError as SQLError


import os import os
import json import json


+ 9
- 26
webnotes/model/bean.py ファイルの表示

@@ -13,6 +13,10 @@ import webnotes
from webnotes import _, msgprint from webnotes import _, msgprint
from webnotes.utils import cint, cstr, flt from webnotes.utils import cint, cstr, flt
from webnotes.model.doc import Document 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 DocstatusTransitionError(webnotes.ValidationError): pass
class BeanPermissionError(webnotes.ValidationError): pass class BeanPermissionError(webnotes.ValidationError): pass
@@ -236,7 +240,7 @@ class Bean:
if hasattr(self.controller, 'custom_' + method): if hasattr(self.controller, 'custom_' + method):
getattr(self.controller, 'custom_' + method)(*args, **kwargs) getattr(self.controller, 'custom_' + method)(*args, **kwargs)


notify(self.controller, method)
notify(self, method)
self.set_doclist(self.controller.doclist) self.set_doclist(self.controller.doclist)
@@ -256,7 +260,7 @@ class Bean:
return self.save() return self.save()
def insert_or_update(self): 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() return self.save()
else: else:
return self.insert() return self.insert()
@@ -461,33 +465,12 @@ def clone(source_wrapper):
return new_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 # for bc
def getlist(doclist, parentfield): def getlist(doclist, parentfield):
"""
Return child records of a particular type
"""
import webnotes.model.utils import webnotes.model.utils
return webnotes.model.utils.getlist(doclist, parentfield) return webnotes.model.utils.getlist(doclist, parentfield)




+ 1
- 2
webnotes/model/doc.py ファイルの表示

@@ -10,7 +10,6 @@ _toc = ["webnotes.model.doc.Document"]


import webnotes import webnotes
import webnotes.model.meta import webnotes.model.meta
import MySQLdb


from webnotes.utils import * from webnotes.utils import *


@@ -132,7 +131,7 @@ class Document:
else: else:
try: try:
dataset = webnotes.conn.sql('select * from `tab%s` where name="%s"' % (self.doctype, self.name.replace('"', '\"'))) 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: if e.args[0]==1146:
dataset = None dataset = None
else: else:


+ 5
- 1
webnotes/model/doctype.py ファイルの表示

@@ -244,7 +244,11 @@ def clear_cache(doctype=None):
for dt in webnotes.conn.sql("""select parent from tabDocField for dt in webnotes.conn.sql("""select parent from tabDocField
where fieldtype="Table" and options=%s""", doctype): where fieldtype="Table" and options=%s""", doctype):
clear_single(dt[0]) 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: else:
# clear all # clear all
for dt in webnotes.conn.sql("""select name from tabDocType"""): for dt in webnotes.conn.sql("""select name from tabDocType"""):


+ 4
- 5
webnotes/model/utils.py ファイルの表示

@@ -179,12 +179,11 @@ def check_permission_and_not_submitted(doctype, name, ignore_permissions=False):
def run_on_trash(doctype, name, doclist): def run_on_trash(doctype, name, doclist):
# call on_trash if required # call on_trash if required
if doclist: if doclist:
obj = webnotes.get_obj(doclist=doclist)
bean = webnotes.bean(doclist)
else: 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 class LinkExistsError(webnotes.ValidationError): pass




+ 2
- 5
webnotes/plugins.py ファイルの表示

@@ -16,13 +16,10 @@ def exec_code(code, namespace=None):
return namespace return namespace
def get_code(module, doctype, docname, plugin=None):
import MySQLdb
def get_code(module, doctype, docname, plugin=None):
try: try:
code = read_file(module, doctype, docname, plugin, cache=True) code = read_file(module, doctype, docname, plugin, cache=True)
except MySQLdb.OperationalError:
# this happens when syncing
except webnotes.SQLError:
return None return None
return code return code


+ 1
- 1
webnotes/sessions.py ファイルの表示

@@ -57,7 +57,7 @@ def clear_sessions(user=None, keep_current=False):


def get(): def get():
"""get session boot info""" """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 bootinfo = None
if not getattr(conf,'auto_cache_clear',None): if not getattr(conf,'auto_cache_clear',None):


+ 0
- 62
webnotes/widgets/notification.py ファイルの表示

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

読み込み中…
キャンセル
保存