set up basic notification functionality
This commit is contained in:
parent
4229e24ff8
commit
9f9df6599f
3 changed files with 155 additions and 18 deletions
|
@ -2,8 +2,6 @@
|
||||||
loops - Linked Objects for Organization and Processing Services
|
loops - Linked Objects for Organization and Processing Services
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
($Id$)
|
|
||||||
|
|
||||||
Let's do some basic setup
|
Let's do some basic setup
|
||||||
|
|
||||||
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
|
@ -75,7 +73,7 @@ So we are now ready to query the favorites.
|
||||||
|
|
||||||
>>> favs = list(favorites.query(userName=johnCId))
|
>>> favs = list(favorites.query(userName=johnCId))
|
||||||
>>> favs
|
>>> favs
|
||||||
[<Favorite ['27', 1, '33', '...']: {}>]
|
[<Favorite ['27', 1, '33', '...']: {'type': 'favorite'}>]
|
||||||
|
|
||||||
>>> list(favAdapted.list(johnC))
|
>>> list(favAdapted.list(johnC))
|
||||||
['27']
|
['27']
|
||||||
|
@ -117,6 +115,41 @@ Let's now trigger the saving of a favorite.
|
||||||
1
|
1
|
||||||
|
|
||||||
|
|
||||||
|
Notifications
|
||||||
|
=============
|
||||||
|
|
||||||
|
>>> from loops.organize.personal.notification import Notifications
|
||||||
|
>>> from loops.common import adapted
|
||||||
|
|
||||||
|
>>> person = adapted(setupData.johnC)
|
||||||
|
>>> d001 = resources['d001.txt']
|
||||||
|
|
||||||
|
>>> notifications = Notifications(person)
|
||||||
|
|
||||||
|
We can now add a notification.
|
||||||
|
|
||||||
|
>>> notifications.add(d001, person, 'I send myself a letter.')
|
||||||
|
|
||||||
|
>>> notif = list(notifications.listTracks())[0]
|
||||||
|
>>> notif
|
||||||
|
<Favorite ['27', 1, '33', '...']:
|
||||||
|
{'text': 'I send myself a letter.', 'type': 'notification', 'sender': '33'}>
|
||||||
|
|
||||||
|
When the notification is marked as read the read timestamp will be set.
|
||||||
|
|
||||||
|
>>> notifications.read(notif)
|
||||||
|
>>> notif
|
||||||
|
<Favorite ['27', 1, '33', '...']:
|
||||||
|
{'text': 'I send myself a letter.', 'read_ts': ..., 'type': 'notification',
|
||||||
|
'sender': '33'}>
|
||||||
|
|
||||||
|
It's possible to store more than one notification concerning the same object.
|
||||||
|
|
||||||
|
>>> notifications.add(d001, person, 'I send myself another letter.')
|
||||||
|
>>> len(list(notifications.listTracks()))
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
Filters - Show only Certain Parts of the Concept Map
|
Filters - Show only Certain Parts of the Concept Map
|
||||||
====================================================
|
====================================================
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2015 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,9 +17,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base classes for a notification framework.
|
A framework for storing personal favorites and settings.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
|
@ -39,39 +37,45 @@ class Favorites(object):
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
def list(self, person, sortKey=None):
|
def list(self, person, sortKey=None, type='favorite'):
|
||||||
for item in self.listTracks(person, sortKey):
|
for item in self.listTracks(person, sortKey, type):
|
||||||
yield item.taskId
|
yield item.taskId
|
||||||
|
|
||||||
def listTracks(self, person, sortKey=None):
|
def listTracks(self, person, sortKey=None, type='favorite'):
|
||||||
if person is None:
|
if person is None:
|
||||||
return
|
return
|
||||||
personUid = util.getUidForObject(person)
|
personUid = util.getUidForObject(person)
|
||||||
if sortKey is None:
|
if sortKey is None:
|
||||||
sortKey = lambda x: -x.timeStamp
|
sortKey = lambda x: -x.timeStamp
|
||||||
for item in sorted(self.context.query(userName=personUid), key=sortKey):
|
for item in sorted(self.context.query(userName=personUid), key=sortKey):
|
||||||
|
if type is not None:
|
||||||
|
if item.type != type:
|
||||||
|
continue
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
def add(self, obj, person, data=None):
|
def add(self, obj, person, data=None, nodups=True):
|
||||||
if None in (obj, person):
|
if None in (obj, person):
|
||||||
return False
|
return False
|
||||||
uid = util.getUidForObject(obj)
|
uid = util.getUidForObject(obj)
|
||||||
personUid = util.getUidForObject(person)
|
personUid = util.getUidForObject(person)
|
||||||
if self.context.query(userName=personUid, taskId=uid):
|
|
||||||
return False
|
|
||||||
if data is None:
|
if data is None:
|
||||||
data = {}
|
data = {'type': 'favorite'}
|
||||||
|
if nodups:
|
||||||
|
for track in self.context.query(userName=personUid, taskId=uid):
|
||||||
|
if track.type == data['type']: # already present
|
||||||
|
return False
|
||||||
return self.context.saveUserTrack(uid, 0, personUid, data)
|
return self.context.saveUserTrack(uid, 0, personUid, data)
|
||||||
|
|
||||||
def remove(self, obj, person):
|
def remove(self, obj, person, type='favorite'):
|
||||||
if None in (obj, person):
|
if None in (obj, person):
|
||||||
return False
|
return False
|
||||||
uid = util.getUidForObject(obj)
|
uid = util.getUidForObject(obj)
|
||||||
personUid = util.getUidForObject(person)
|
personUid = util.getUidForObject(person)
|
||||||
changed = False
|
changed = False
|
||||||
for t in self.context.query(userName=personUid, taskId=uid):
|
for track in self.context.query(userName=personUid, taskId=uid):
|
||||||
changed = True
|
if track.type == type:
|
||||||
self.context.removeTrack(t)
|
changed = True
|
||||||
|
self.context.removeTrack(track)
|
||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,3 +85,46 @@ class Favorite(Track):
|
||||||
|
|
||||||
typeName = 'Favorite'
|
typeName = 'Favorite'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self):
|
||||||
|
return self.data.get('type') or 'favorite'
|
||||||
|
|
||||||
|
|
||||||
|
def updateSortInfo(person, task, data):
|
||||||
|
if person is not None:
|
||||||
|
favorites = task.getLoopsRoot().getRecordManager().get('favorites')
|
||||||
|
if favorites is None:
|
||||||
|
return data
|
||||||
|
personUid = util.getUidForObject(person)
|
||||||
|
taskUid = util.getUidForObject(task)
|
||||||
|
for fav in favorites.query(userName=personUid, taskId=taskUid):
|
||||||
|
if fav.data.get('type') == 'sort':
|
||||||
|
fdata = fav.data['sortInfo']
|
||||||
|
if not data:
|
||||||
|
data = fdata
|
||||||
|
else:
|
||||||
|
if data != fdata:
|
||||||
|
newData = fav.data
|
||||||
|
newData['sortInfo'] = data
|
||||||
|
fav.data = newData
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if data:
|
||||||
|
Favorites(favorites).add(task, person,
|
||||||
|
dict(type='sort', sortInfo=data))
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def setInstitution(person, inst):
|
||||||
|
if person is not None:
|
||||||
|
favorites = inst.getLoopsRoot().getRecordManager().get('favorites')
|
||||||
|
if favorites is None:
|
||||||
|
return
|
||||||
|
personUid = util.getUidForObject(person)
|
||||||
|
taskUid = util.getUidForObject(inst)
|
||||||
|
for fav in favorites.query(userName=personUid):
|
||||||
|
if fav.type == 'institution':
|
||||||
|
fav.taskId = taskUid
|
||||||
|
favorites.indexTrack(None, fav, 'taskId')
|
||||||
|
else:
|
||||||
|
Favorites(favorites).add(inst, person, dict(type='institution'))
|
||||||
|
|
57
organize/personal/notification.py
Normal file
57
organize/personal/notification.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Helmut Merz helmutm@cy55.de
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Storing and retrieving notifications.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cybertools.util.date import getTimeStamp
|
||||||
|
from loops.common import baseObject
|
||||||
|
from loops.organize.personal.favorite import Favorites
|
||||||
|
from loops import util
|
||||||
|
|
||||||
|
|
||||||
|
class Notifications(Favorites):
|
||||||
|
|
||||||
|
def __init__(self, person):
|
||||||
|
self.person = person
|
||||||
|
self.context = (baseObject(person).
|
||||||
|
getLoopsRoot().getRecordManager()['favorites'])
|
||||||
|
|
||||||
|
def listTracks(self):
|
||||||
|
return super(Notifications, self).listTracks(
|
||||||
|
self.person, type='notification')
|
||||||
|
|
||||||
|
def add(self, obj, sender, text):
|
||||||
|
senderUid = util.getUidForObject(baseObject(sender))
|
||||||
|
super(Notifications, self).add(obj, self.person,
|
||||||
|
dict(type='notification', sender=senderUid, text=text),
|
||||||
|
nodups=False)
|
||||||
|
|
||||||
|
def read(self, track):
|
||||||
|
data = track.data
|
||||||
|
data['read_ts'] = getTimeStamp()
|
||||||
|
track.data = data
|
||||||
|
|
||||||
|
def unread(self, track):
|
||||||
|
data = track.data
|
||||||
|
data['read_ts'] = None
|
||||||
|
track.data = data
|
||||||
|
|
||||||
|
def remove(self, track):
|
||||||
|
self.context.removeTrack(track)
|
Loading…
Add table
Reference in a new issue