[Zope3-checkins] CVS: Products3/bugtracker - bug.py:1.2 configure.zcml:1.5 exportimport.py:1.4 interfaces.py:1.2 template.xml:1.2 tracker.py:1.6 vocabulary.py:1.3
Stephan Richter
srichter@cosmos.phy.tufts.edu
Mon, 28 Jul 2003 13:14:19 -0400
Update of /cvs-repository/Products3/bugtracker
In directory cvs.zope.org:/tmp/cvs-serv11336
Modified Files:
bug.py configure.zcml exportimport.py interfaces.py
template.xml tracker.py vocabulary.py
Log Message:
I dunno what bit me, but I thought that having numeric bug ids would be
better. It turns out that a lot of the Zope 3 machinery depends on the
names being strings, so I useually convert the names to strings anyway.
Oh well.
I also implemented default values for the vocabularies. Updated the export/
import accordingly.
=== Products3/bugtracker/bug.py 1.1 => 1.2 ===
--- Products3/bugtracker/bug.py:1.1 Thu Jul 24 14:08:03 2003
+++ Products3/bugtracker/bug.py Mon Jul 28 13:13:41 2003
@@ -23,9 +23,12 @@
from zope.app.traversing import getParent, getName
from zope.app.container.btree import BTreeContainer
from zope.app.context import ContextWrapper
+from zope.context import ContextProperty
from zope.proxy import removeAllProxies
from zopeproducts.bugtracker.interfaces import IBug, IComment
from zopeproducts.bugtracker.interfaces import IBugDependencies
+from zopeproducts.bugtracker.vocabulary import \
+ VocabularyPropertyGetter, VocabularyPropertySetter
DependencyKey = 'http://www.zope.org/bugtracker#1.0/Dependencies'
@@ -35,16 +38,25 @@
implements(IBug)
# See zopeproducts.bugtracker.interfaces.IBug
- status = u'new'
+ status = ContextProperty(
+ VocabularyPropertyGetter('_status', 'Stati'),
+ VocabularyPropertySetter('_status', 'Stati'))
+
# See zopeproducts.bugtracker.interfaces.IBug
- priority = u'normal'
+ priority = ContextProperty(
+ VocabularyPropertyGetter('_priority', 'Priorities'),
+ VocabularyPropertySetter('_priority', 'Priorities'))
# See zopeproducts.bugtracker.interfaces.IBug
- type = u'bug'
+ type = ContextProperty(
+ VocabularyPropertyGetter('_type', 'BugTypes'),
+ VocabularyPropertySetter('_type', 'BugTypes'))
# See zopeproducts.bugtracker.interfaces.IBug
- release = u'None'
+ release = ContextProperty(
+ VocabularyPropertyGetter('_release', 'Releases'),
+ VocabularyPropertySetter('_release', 'Releases'))
def getOwners(self):
return getattr(self, '_owners', [])
=== Products3/bugtracker/configure.zcml 1.4 => 1.5 ===
--- Products3/bugtracker/configure.zcml:1.4 Sat Jul 26 17:25:52 2003
+++ Products3/bugtracker/configure.zcml Mon Jul 28 13:13:41 2003
@@ -109,10 +109,11 @@
<content class=".vocabulary.ManagableVocabulary">
<allow interface="zope.schema.interfaces.IVocabulary"/>
<allow interface="zope.schema.interfaces.IVocabularyTokenized"/>
- <allow attributes="__contains__"/>
+ <allow attributes="__contains__ default"/>
<require
permission="bugtracker.ManageBugTracker"
- attributes="add delete"/>
+ attributes="add delete"
+ set_attributes="default"/>
</content>
<content class=".vocabulary.StatusVocabulary">
=== Products3/bugtracker/exportimport.py 1.3 => 1.4 ===
--- Products3/bugtracker/exportimport.py:1.3 Mon Jul 28 07:49:31 2003
+++ Products3/bugtracker/exportimport.py Mon Jul 28 13:13:41 2003
@@ -22,17 +22,18 @@
from xml.sax import parse
from xml.sax.handler import ContentHandler
+from zope.app.content.file import File
+from zope.app.content.image import Image
from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.traversing import getParent
from zope.component import getAdapter, getService
from zope.i18n.locales import locales
from zope.schema.vocabulary import getVocabularyRegistry
+from zope.security.proxy import trustedRemoveSecurityProxy
from zopeproducts.bugtracker.interfaces import IBugDependencies, IComment
from zopeproducts.bugtracker.bug import Bug
from zopeproducts.bugtracker.comment import Comment
-from zope.app.content.file import File
-from zope.app.content.image import Image
class XMLExport:
@@ -55,8 +56,10 @@
registry = getVocabularyRegistry()
vocabs = []
for name in ('Stati', 'Priorities', 'BugTypes', 'Releases'):
+ vocab = registry.get(self.context, name)
vocabs.append({'name': name,
- 'terms' : iter(registry.get(self.context, name))})
+ 'terms' : iter(vocab),
+ 'default' : vocab.default})
return vocabs
def bugs(self):
@@ -227,6 +230,9 @@
registry = getVocabularyRegistry()
vocab = registry.get(self.context, self.vocab_name)
vocab.add(attrs.get('value'), attrs.get('title'))
+ if attrs.get('default', None) is not None:
+ # XXX: I do not understand why my security does not work here.
+ trustedRemoveSecurityProxy(vocab).default = attrs.get('value')
def startBug(self, attrs):
bug = Bug()
@@ -257,7 +263,7 @@
self.bug_name = attrs.get('id')
def endBug(self):
- self.context.setObject(self.bug_name, self.bug, True)
+ self.context.setObject(self.bug_name, self.bug)
def startDescription(self, attrs):
self.chars = u''
=== Products3/bugtracker/interfaces.py 1.1 => 1.2 ===
--- Products3/bugtracker/interfaces.py:1.1 Thu Jul 24 14:08:03 2003
+++ Products3/bugtracker/interfaces.py Mon Jul 28 13:13:41 2003
@@ -157,6 +157,11 @@
def delete(value):
"""Delete an entry from the vocabulary."""
+ default = TextLine(
+ title = _(u"Default"),
+ description = _(u"Default value of the vocabulary."),
+ required=True)
+
class IStatusVocabulary(IManagableVocabulary):
"""Manageable vocabulary that stores stati."""
=== Products3/bugtracker/template.xml 1.1 => 1.2 ===
--- Products3/bugtracker/template.xml:1.1 Sat Jul 26 09:40:43 2003
+++ Products3/bugtracker/template.xml Mon Jul 28 13:13:41 2003
@@ -8,10 +8,16 @@
<vocabulary
tal:repeat="vocab view/vocabularies"
tal:attributes="name vocab/name">
- <term
- tal:repeat="term vocab/terms"
+ <tal:block repeat="term vocab/terms">
+ <term value="" title=""
+ tal:condition="python: vocab['default'].value != term.value"
tal:attributes="value term/value;
title term/title" />
+ <term value="" title="" default=""
+ tal:condition="python: vocab['default'].value == term.value"
+ tal:attributes="value term/value;
+ title term/title" />
+ </tal:block>
</vocabulary>
</vocabularies>
=== Products3/bugtracker/tracker.py 1.5 => 1.6 ===
--- Products3/bugtracker/tracker.py:1.5 Mon Jul 28 07:49:31 2003
+++ Products3/bugtracker/tracker.py Mon Jul 28 13:13:41 2003
@@ -49,11 +49,11 @@
def keys(self):
"""See zope.interface.common.mapping.IEnumerableMapping"""
- return self.data.keys()
+ return map(lambda k: str(k), self.data.keys())
def __iter__(self):
"""See zope.interface.common.mapping.IEnumerableMapping"""
- return iter(self.data.keys())
+ return iter(self.keys())
def values(self):
"""See zope.interface.common.mapping.IEnumerableMapping"""
@@ -61,7 +61,7 @@
def items(self):
"""See zope.interface.common.mapping.IEnumerableMapping"""
- return self.data.items()
+ return map(lambda i: (str(i[0]), i[1]), self.data.items())
def __len__(self):
"""See zope.interface.common.mapping.IEnumerableMapping"""
@@ -91,13 +91,14 @@
# to each other. This is particualry important when importing XML
# data.
if forceName == False:
- name = max(list(self.keys())+[0])+1
+ name = max(list(self.data.keys())+[0])+1
else:
name = int(name)
if name in self:
raise ValueError, 'Name (%i) already in Bug Tracker.' %name
self.data[name] = object
- return name
+ # Too much code depends on this being a string type
+ return unicode(name)
def __delitem__(self, name):
"""Delete the named object from the folder. Raises a KeyError
=== Products3/bugtracker/vocabulary.py 1.2 => 1.3 ===
--- Products3/bugtracker/vocabulary.py:1.2 Thu Jul 24 17:39:07 2003
+++ Products3/bugtracker/vocabulary.py Mon Jul 28 13:13:41 2003
@@ -21,18 +21,18 @@
from persistence import Persistent
from persistence.dict import PersistentDict
-from zope.schema.interfaces import \
- ITokenizedTerm, IVocabulary, IVocabularyTokenized
from zope.app.interfaces.annotation import IAnnotatable, IAnnotations
from zope.app.interfaces.security import IAuthenticationService
-
from zope.app.services.servicenames import Authentication
+from zope.schema.interfaces import \
+ ITokenizedTerm, IVocabulary, IVocabularyTokenized
+from zope.schema.vocabulary import getVocabularyRegistry
from zope.security.proxy import trustedRemoveSecurityProxy
from zopeproducts.bugtracker.interfaces import IManagableVocabulary, IBugTracker
from zopeproducts.bugtracker.interfaces import \
IStatusVocabulary, IReleaseVocabulary, IPriorityVocabulary
from zopeproducts.bugtracker.interfaces import \
- IBugTypeVocabulary
+ IBugTypeVocabulary
class SimpleTerm(Persistent):
@@ -62,6 +62,7 @@
self.annotations = getAdapter(self.context, IAnnotations)
if not self.annotations.get(self.key):
self.annotations[self.key] = PersistentDict()
+ self.annotations[self.key+'/default'] = None
def __contains__(self, value):
return value in self.annotations[self.key].keys()
@@ -81,10 +82,14 @@
def getTermByToken(self, token):
return self.getTerm(token)
- def add(self, value, title):
+ def add(self, value, title, default=False):
self.annotations[self.key][value] = SimpleTerm(value, title)
+ if default:
+ self.default = value
def delete(self, value):
+ if value == self.default.value:
+ raise ValueError, "Cannot delete default value '%s'." %value
del self.annotations[self.key][value]
def _getRealContext(self, context):
@@ -93,6 +98,23 @@
return obj
return context
+ def getDefault(self):
+ value = self.annotations[self.key+'/default']
+ if value is None:
+ return None
+ return self.getTerm(self.annotations[self.key+'/default'])
+
+ def setDefault(self, value):
+ """Set the default value/term. Both, a token and a term are accepted."""
+ if ITokenizedTerm.isImplementedBy(value):
+ value = value.value
+ if value not in self:
+ raise ValueError, \
+ "The value '%s' was not found in the vocabulary" %value
+ self.annotations[self.key+'/default'] = value
+
+ default = property(getDefault, setDefault)
+
class StatusVocabulary(ManagableVocabulary):
@@ -176,6 +198,50 @@
def getTermByToken(self, token):
return self.getTerm(token)
+
+
+class VocabularyPropertyGetter(object):
+
+ def __init__(self, name, vocab_name):
+ self.name = name
+ self._vocab_name = vocab_name
+
+ def __call__(self, instance):
+ registry = getVocabularyRegistry()
+ try:
+ vocab = registry.get(instance, self._vocab_name)
+ default = vocab.default.value
+ except TypeError:
+ # We cannot assume that the bug will always have a context to
+ # find the vocabulary data. In these cases, we just skip the
+ # default lookup.
+ default = None
+ return getattr(instance, self.name, default)
+
+
+class VocabularyPropertySetter(object):
+ """This generic vocabulary property setter class ensures that the set
+ value is in the vocabulary."""
+
+ def __init__(self, name, vocab_name):
+ self.name = name
+ self._vocab_name = vocab_name
+
+ def __call__(self, instance, value):
+ registry = getVocabularyRegistry()
+ try:
+ vocab = registry.get(instance, self._vocab_name)
+ if value not in vocab:
+ raise ValueError, \
+ "The value '%s' was not found in vocabulary '%s'" %(
+ value, self._vocab_name)
+ except TypeError:
+ # We cannot assume that the bug will always have a context to
+ # find the vocabulary data. In these cases, we just skip the
+ # verification.
+ vocab = None
+
+ setattr(instance, self.name, value)
# Monkey Patching going on...