[Zope3-checkins] CVS: zopeproducts/bugtracker - exportimport.py:1.1 template.xml:1.1 TODO.txt:1.3 VERSION.txt:1.2 configure.zcml:1.3 mail.py:1.2 tracker.py:1.2
Stephan Richter
srichter@cosmos.phy.tufts.edu
Sat, 26 Jul 2003 09:41:20 -0400
Update of /cvs-repository/zopeproducts/bugtracker
In directory cvs.zope.org:/tmp/cvs-serv13760
Modified Files:
TODO.txt VERSION.txt configure.zcml mail.py tracker.py
Added Files:
exportimport.py template.xml
Log Message:
- Added XML Export/Import capabilities
- User Vocabularies now only store informational data about the principal,
since exposing the entire principal is just too dangerous.
- Made Bug Tracker title the same attribute at the DC title and corrected
permissions.
=== Added File zopeproducts/bugtracker/exportimport.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""XML Import/Export facility
$Id: exportimport.py,v 1.1 2003/07/26 13:40:43 srichter Exp $
"""
VERSION = '1.0'
import base64
from xml.sax import parse
from xml.sax.handler import ContentHandler
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 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:
template = ViewPageTemplateFile('template.xml')
def __init__(self, tracker):
self.context = tracker
self.request = None
def getXML(self):
return self.template()
def title(self):
return self.context.title
def version(self):
return VERSION
def vocabularies(self):
registry = getVocabularyRegistry()
vocabs = []
for name in ('Stati', 'Priorities', 'BugTypes', 'Releases'):
vocabs.append({'name': name,
'terms' : iter(registry.get(self.context, name))})
return vocabs
def bugs(self):
return map(lambda item: BugInfo(item[0], item[1]), self.context.items())
class BugInfo:
def __init__(self, name, bug):
self.context = bug
self.name = name
self.locale = locales.getLocale()
def id(self):
return self.name
def title(self):
return self.context.title
def description(self):
return '\n'+self.context.description+'\n '
def submitter(self):
return self.context.submitter
def created(self):
dc = getAdapter(self.context, IZopeDublinCore)
return self.locale.getDateTimeFormatter('medium').format(dc.created)
def modified(self):
dc = getAdapter(self.context, IZopeDublinCore)
if dc.modified is None:
return self.created()
return self.locale.getDateTimeFormatter('medium').format(dc.modified)
def status(self):
return self.context.status
def type(self):
return self.context.type
def release(self):
return self.context.release
def priority(self):
return self.context.priority
def owners(self):
return ', '.join(self.context.owners)
def dependencies(self):
deps = getAdapter(self.context, IBugDependencies)
return ", ".join(deps.dependencies)
def comments(self):
comments = []
for name, obj in self.context.items():
if IComment.isImplementedBy(obj):
comments.append(CommentInfo(name, obj))
return comments
def attachments(self):
attachs = []
for name, obj in self.context.items():
if not IComment.isImplementedBy(obj):
attachs.append(AttachmentInfo(name, obj))
return attachs
class CommentInfo:
def __init__(self, name, comment):
self.context = comment
self.name = name
self.locale = locales.getLocale()
def id(self):
return self.name
def body(self):
return '\n'+self.context.body+'\n '
def creator(self):
dc = getAdapter(self.context, IZopeDublinCore)
return dc.creators[0]
def created(self):
dc = getAdapter(self.context, IZopeDublinCore)
return self.locale.getDateTimeFormatter('medium').format(dc.created)
class AttachmentInfo:
def __init__(self, name, attach):
self.context = attach
self.name = name
self.locale = locales.getLocale()
def id(self):
return self.name
def type(self):
if isinstance(self.context, Image):
return 'Image'
return 'File'
def data(self):
return base64.encodestring(self.context.data)
def creator(self):
dc = getAdapter(self.context, IZopeDublinCore)
return dc.creators[0]
def created(self):
dc = getAdapter(self.context, IZopeDublinCore)
return self.locale.getDateTimeFormatter('medium').format(dc.created)
class XMLImporter(ContentHandler):
def __init__(self, context, encoding='latin-1'):
self.context = context
self.encoding = encoding
self.locale = locales.getLocale()
self.parser = self.locale.getDateTimeFormatter('medium')
self.chars = u''
def startElement(self, name, attrs):
handler = getattr(self, 'start' + name.title().replace('-', ''), None)
if not handler:
raise ValueError, 'Unknown element %s' % name
handler(attrs)
def endElement(self, name):
handler = getattr(self, 'end' + name.title().replace('-', ''), None)
if handler:
handler()
def characters(self, content):
self.chars += content
def noop(*args):
pass
startVocabularies = noop
startBugs = noop
startComments = noop
startAttachments = noop
def startBugtracker(self, attrs):
assert attrs.get('version') == VERSION
self.context.title = attrs.get('title')
def startVocabulary(self, attrs):
self.vocab_name = attrs.get('name', None)
def endVocabulary(self):
self.vocab_name = None
def startTerm(self, attrs):
registry = getVocabularyRegistry()
vocab = registry.get(self.context, self.vocab_name)
vocab.add(attrs.get('value'), attrs.get('title'))
def startBug(self, attrs):
bug = Bug()
bug.title = attrs.get('title')
bug.status = attrs.get('status')
bug.priority = attrs.get('priority')
bug.type = attrs.get('type')
bug.release = attrs.get('release')
owners = attrs.get('owners').split(', ')
bug.owners = filter(lambda o: o.strip() != u'', owners)
deps_adapter = getAdapter(bug, IBugDependencies)
deps = attrs.get('dependencies').split(', ')
deps_adapter.setDependencies(filter(lambda o: o.strip() != u'', deps))
dc = getAdapter(bug, IZopeDublinCore)
dc.created = self.parser.parse(attrs.get('created'))
dc.modified = self.parser.parse(attrs.get('modified'))
dc.creators = [attrs.get('submitter')]
self.bug = bug
self.bug_name = attrs.get('id')
def endBug(self):
self.context.setObject(self.bug_name, self.bug)
def startDescription(self, attrs):
self.chars = u''
def endDescription(self):
self.bug.description = self.chars.strip()
def startComment(self, attrs):
self.chars = u''
comment = Comment()
dc = getAdapter(comment, IZopeDublinCore)
dc.created = self.parser.parse(attrs.get('created'))
dc.creators = [attrs.get('creator')]
self.comment = comment
self.comment_name = attrs.get('id')
def endComment(self):
# Stripping off whitespace and first and last newline
self.comment.body = self.chars.strip(' ')[1:-1]
self.bug.setObject(self.comment_name, self.comment)
def startAttachment(self, attrs):
self.chars = u''
type = attrs.get('type')
if type == 'Image':
attach = Image()
else:
attach = File()
dc = getAdapter(attach, IZopeDublinCore)
dc.created = self.parser.parse(attrs.get('created'))
dc.creators = [attrs.get('creator')]
self.attach = attach
self.attach_name = attrs.get('id')
def endAttachment(self):
self.attach.data = base64.decodestring(self.chars.strip(' '))
self.bug.setObject(self.attach_name, self.attach)
class XMLImport:
def __init__(self, tracker):
self.context = tracker
def processXML(self, xml):
parse(xml, XMLImporter(self.context))
=== Added File zopeproducts/bugtracker/template.xml ===
<?xml version="1.0"?>
<bugtracker version="1.0"
xmlns:tal="http://xml.zope.org/namespaces/tal"
tal:attributes="version view/version;
title view/title">
<vocabularies>
<vocabulary
tal:repeat="vocab view/vocabularies"
tal:attributes="name vocab/name">
<term
tal:repeat="term vocab/terms"
tal:attributes="value term/value;
title term/title" />
</vocabulary>
</vocabularies>
<bugs>
<bug
id="1"
title="Title of Bug"
submitter="srichter"
status="new"
priority="normal"
type="bug"
release="zope_x3"
owners="srichter, jim"
dependencies="2, 3"
created="Jan 01, 2003 12:00:00 AM"
modified="Jan 01, 2003 12:00:00 AM"
tal:repeat="bug view/bugs"
tal:attributes="id bug/id;
title bug/title;
submitter bug/submitter;
status bug/status;
priority bug/priority;
type bug/type;
release bug/release;
owners bug/owners;
dependencies bug/dependencies;
created bug/created;
modified bug/modified;
">
<description tal:content="bug/description" >
</description>
<comments>
<comment
tal:repeat="comment bug/comments"
tal:attributes="creator comment/creator;
created comment/created;
id comment/id"
tal:content="structure comment/body" />
</comments>
<attachments>
<attachment
tal:repeat="attachment bug/attachments"
tal:attributes="type attachment/type;
creator attachment/creator;
created attachment/created;
id attachment/id"
tal:content="attachment/data" />
</attachments>
</bug>
</bugs>
</bugtracker>
=== zopeproducts/bugtracker/TODO.txt 1.2 => 1.3 ===
--- zopeproducts/bugtracker/TODO.txt:1.2 Thu Jul 24 17:39:07 2003
+++ zopeproducts/bugtracker/TODO.txt Sat Jul 26 09:40:43 2003
@@ -17,13 +17,6 @@
- Provide a sample translation (probably German).
- UI
-
- - Display Term title instead of value in the drop-down elements.
-
-
Other Features
- Improve Mailings (use some sort of diff library)
-
- - XML Import and Export
\ No newline at end of file
=== zopeproducts/bugtracker/VERSION.txt 1.1 => 1.2 ===
--- zopeproducts/bugtracker/VERSION.txt:1.1 Thu Jul 24 14:08:03 2003
+++ zopeproducts/bugtracker/VERSION.txt Sat Jul 26 09:40:43 2003
@@ -1 +1 @@
-0.1
\ No newline at end of file
+0.2
\ No newline at end of file
=== zopeproducts/bugtracker/configure.zcml 1.2 => 1.3 ===
--- zopeproducts/bugtracker/configure.zcml:1.2 Thu Jul 24 17:39:07 2003
+++ zopeproducts/bugtracker/configure.zcml Sat Jul 26 09:40:43 2003
@@ -178,6 +178,10 @@
interface="zope.app.interfaces.container.IWriteContainer"/>
<require
+ permission="bugtracker.ViewBugTracker"
+ attributes="title" />
+
+ <require
permission="zope.ManageContent"
set_schema=".interfaces.IBugTracker" />
=== zopeproducts/bugtracker/mail.py 1.1 => 1.2 ===
--- zopeproducts/bugtracker/mail.py:1.1 Thu Jul 24 14:08:03 2003
+++ zopeproducts/bugtracker/mail.py Sat Jul 26 09:40:43 2003
@@ -90,7 +90,7 @@
def handleRemoved(self, object):
subject = 'Removed: %s (%s)' %(object.title, getName(object))
emails = self.getAllSubscribers(object)
- body = self.description
+ body = object.description
self.mail(emails, subject, body)
def getAllSubscribers(self, object):
=== zopeproducts/bugtracker/tracker.py 1.1 => 1.2 ===
--- zopeproducts/bugtracker/tracker.py:1.1 Thu Jul 24 14:08:03 2003
+++ zopeproducts/bugtracker/tracker.py Sat Jul 26 09:40:43 2003
@@ -15,8 +15,10 @@
$Id$
"""
-from zope.interface import implements
from zope.app.content.folder import Folder
+from zope.app.interfaces.dublincore import IZopeDublinCore
+from zope.component import queryAdapter
+from zope.interface import implements
from zopeproducts.bugtracker.interfaces import IBugTracker
@@ -24,5 +26,15 @@
implements(IBugTracker)
+ def setTitle(self, title):
+ """Set bug tracker title."""
+ dc = queryAdapter(self, IZopeDublinCore)
+ dc.title = title
+
+ def getTitle(self):
+ """Get bug tracker title."""
+ dc = queryAdapter(self, IZopeDublinCore)
+ return dc.title
+
# See zopeproducts.bugtracker.interfaces.IBugTracker
- title = u''
+ title = property(getTitle, setTitle)