loops/organize/personal/favorite.py

136 lines
4.6 KiB
Python

# loops.organize.personal.favorite
"""A framework for storing personal favorites and settings.
"""
from zope.component import adapts
from zope.interface import implementer
from cybertools.util.date import date2TimeStamp
from cybertools.tracking.btree import Track
from cybertools.tracking.interfaces import ITrackingStorage
from loops.organize.personal.interfaces import IFavorites, IFavorite
from loops import util
@implementer(IFavorites)
class Favorites(object):
adapts(ITrackingStorage)
def __init__(self, context):
self.context = context
def list(self, person, sortKey=None, type='favorite'):
for item in self.listTracks(person, sortKey, type):
yield item.taskId
def listWithTracks(self, person, sortKey=None, type='favorite'):
for item in self.listTracks(person, sortKey, type):
yield util.getUidForObject(item), item.taskId
def listTracks(self, person, sortKey=None, type='favorite'):
if person is None:
return
personUid = util.getUidForObject(person)
if sortKey is None:
sortKey = lambda x: (x.data.get('order', 100), -date2TimeStamp(x.timeStamp))
for item in sorted(self.context.query(userName=personUid), key=sortKey):
if type is not None:
if item.type != type:
continue
yield item
def add(self, obj, person, data=None, nodups=True):
if None in (obj, person):
return False
uid = util.getUidForObject(obj)
personUid = util.getUidForObject(person)
if data is None:
data = {'type': 'favorite', 'order': 100}
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)
def remove(self, obj, person, type='favorite'):
if None in (obj, person):
return False
uid = util.getUidForObject(obj)
personUid = util.getUidForObject(person)
changed = False
for track in self.context.query(userName=personUid, taskId=uid):
if track.type == type:
changed = True
self.context.removeTrack(track)
return changed
def reorder(self, uids):
offset = 0
for idx, uid in enumerate(uids):
#track = util.getObjectForUid(uid)
track = util.getItem(uid, storage=self.context.storage)
if track is not None:
data = track.data
order = data.get('order', 100)
if order < idx or (order >= 100 and order < idx + 100):
offset = 100
data['order'] = idx + offset
#track.data = data
self.context.setTrackData(track, data)
@implementer(IFavorite)
class BaseFavorite(object):
typeName = 'Favorite'
@property
def type(self):
return self.data.get('type') or 'favorite'
class Favorite(BaseFavorite, Track):
pass
def updateSortInfo(person, task, data):
if person is not None:
favorites = task.getLoopsRoot().getRecordManager().get('favorites')
#favorites = util.records(task, 'favorites', FavContainer)
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'))