#-*- coding: UTF-8 -*- # # Copyright (c) 2011 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 # """ Common functionality. $Id$ """ from zope import component from zope.intid.interfaces import IIntIds class ContainerAttribute(object): def __init__(self, factory, idAttr='name'): self.factory = factory self.idAttr = idAttr self.data = {} def create(self, id, **kw): if self.idAttr not in kw: kw[self.idAttr] = id obj = self.factory(id) for k, v in kw.items(): setattr(obj, k, v) self.data[id] = obj component.getUtility(IIntIds).register(obj) return obj def remove(self, id): component.getUtility(IIntIds).unregister(self.data[id]) del self.data[id] def get(self, id, default=None): return self.data.get(id, default) def __iter__(self): return iter(self.data.values()) class RelationSet(object): def __init__(self, parent, attributeName=None): self.parent = parent self.attributeName = attributeName self.data = {} def add(self, related): self.data[related.name] = related if self.attributeName: value = getattr(related, self.attributeName) if isinstance(value, RelationSet): relatedData = value.data relatedData[self.parent.name] = self.parent else: setattr(related, self.attributeName, self.parent) def remove(self, related): name = related.name del self.data[name] if self.attributeName: value = getattr(related, self.attributeName) if isinstance(value, RelationSet): relatedData = value.data del relatedData[self.parent.name] else: setattr(related, self.attributeName, None) def __iter__(self): for obj in self.data.values(): yield obj class Relation(object): def __init__(self, name, otherName): self.name = name self.otherName = otherName def __get__(self, inst, class_=None): if inst is None: return self return getattr(inst, self.name) def __set__(self, inst, value): existing = getattr(inst, self.name, None) if existing is not None: other = getattr(existing, self.otherName).data for k, v in other.items(): if v != inst: del other[k] if value is not None: other = getattr(value, self.otherName).data other[inst.name] = inst setattr(inst, self.name, value) class BaseObject(object): collection = RelationSet class FloatValue(float): # TODO: rename to CurrencyValue def __nonzero__(self): return True # even when value is 0.0 def __init__(self, value, decimals=2, currency=u'€'): self.decimals = decimals self.currency = currency def __str__(self): format = '%%.%if' % self.decimals value = (format % self).replace('.', ',') if self.currency: value = value + ' ' + self.currency return value def rawValue(self): return float(self) def rawFormatted(self): format = '%%.%if' % self.decimals return (format % self) # utility functions def getUidForObject(obj, intIds=None): if intIds is None: intIds = component.getUtility(IIntIds) return intIds.getId(obj) def getObjectForUid(uid, intIds=None): if intIds is None: intIds = component.getUtility(IIntIds) return intIds.getObject(uid)