Code

Added time logging and file uploading to the templates.
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Mon, 30 Jul 2001 08:12:17 +0000 (08:12 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Mon, 30 Jul 2001 08:12:17 +0000 (08:12 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@173 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
roundup-admin
roundup/cgi_client.py
roundup/htmltemplate.py
roundup/templatebuilder.py
roundup/templates/classic/html/file.newitem [new file with mode: 0644]
roundup/templates/classic/html/issue.item
roundup/templates/classic/htmlbase.py
roundup/templates/extended/htmlbase.py
roundup/templates/extended/interfaces.py

index 36b5ad85c011d60d6068bfe8bf8f0af7e902180f..3fd36f75eedd64d4d37f779d94fb2a36aa7b652c 100644 (file)
@@ -1,6 +1,18 @@
 This file contains the changes to the Roundup system over time. The entries
 are given with the most recent entry first.
 
+2001-08-?? - 0.2.4
+Features:
+ . Added ability for cgi newblah forms to indicate that the new node
+   should be linked somewhere.
+ . Added time logging and file uploading to the templates.
+
+Fixed:
+ . Fixed the agument handling for the roundup-admin find command.
+ . Fixed handling of summary when no note supplied for newblah. Again.
+ . Fixed detection of no form in htmltemplate Field display.
+
+
 2001-07-30 - 0.2.3
 Big change:
  . I've split off the support class from the issue class in "extended".
index 1ec3994ec98195e05afe8f906990cf6de922a9e6..9a39bc66c7f75f77c86b390b347e12a67ba77277 100755 (executable)
@@ -1,12 +1,12 @@
 #! /usr/bin/python
-# $Id: roundup-admin,v 1.9 2001-07-30 03:52:55 richard Exp $
+# $Id: roundup-admin,v 1.10 2001-07-30 08:12:17 richard Exp $
 
 import sys
 if int(sys.version[0]) < 2:
     print 'Roundup requires python 2.0 or later.'
     sys.exit(1)
 
-import string, os, getpass, getopt
+import string, os, getpass, getopt, re
 from roundup import date, roundupdb, init
 
 def usage(message=''):
@@ -173,19 +173,25 @@ def do_find(db, args):
     '''Usage: find classname propname=value ...
     Find the nodes of the given class with a given property value.
 
-    Find the nodes of the given class with a given property value.
+    Find the nodes of the given class with a given property value. The
+    value may be either the nodeid of the linked node, or its key value.
     '''
     classname = args[0]
     cl = db.getclass(classname)
 
     # look up the linked-to class and get the nodeid that has the value
-    propname, value = args[1:].split('=')
-    propcl = cl[propname].classname
-    nodeid = propcl.lookup(value)
+    propname, value = args[1].split('=')
+    num_re = re.compile('^\d+$')
+    if num_re.match(value):
+        nodeid = value
+    else:
+        propcl = cl.properties[propname].classname
+        propcl = db.getclass(propcl)
+        nodeid = propcl.lookup(value)
 
     # now do the find
     # TODO: handle the -c option
-    print cl.find(propname, nodeid)
+    print cl.find(**{propname: nodeid})
     return 0
 
 def do_spec(db, args):
@@ -236,7 +242,6 @@ def do_list(db, args):
     in order: the key, "name", "title" and then the first property,
     alphabetically.
     '''
-    db = instance.open()
     classname = args[0]
     cl = db.getclass(classname)
     if len(args) > 1:
@@ -404,6 +409,9 @@ if __name__ == '__main__':
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.9  2001/07/30 03:52:55  richard
+# init help now lists templates and backends
+#
 # Revision 1.8  2001/07/30 02:37:07  richard
 # Freshen is really broken. Commented out.
 #
index ff515ded3f9553a8374f99ca6832bf2acdf7d0c2..3e2361e6c53500ef29b397c414f477a0ecf84f5b 100644 (file)
@@ -1,6 +1,6 @@
-# $Id: cgi_client.py,v 1.12 2001-07-30 06:26:31 richard Exp $
+# $Id: cgi_client.py,v 1.13 2001-07-30 08:12:17 richard Exp $
 
-import os, cgi, pprint, StringIO, urlparse, re, traceback
+import os, cgi, pprint, StringIO, urlparse, re, traceback, mimetypes
 
 import roundupdb, htmltemplate, date
 
@@ -226,71 +226,7 @@ class Client:
                         props[key] = value
                 cl.set(self.nodeid, **props)
 
-                # if this item has messages, generate an edit message
-                # TODO: don't send the edit message to the person who
-                # performed the edit
-                if (cl.getprops().has_key('messages') and
-                        cl.getprops()['messages'].isMultilinkType and
-                        cl.getprops()['messages'].classname == 'msg'):
-                    nid = self.nodeid
-                    m = []
-                    for name, prop in cl.getprops().items():
-                        # TODO: the None default is only here because we
-                        # don't have schema migration :(
-                        if prop.isMultilinkType:
-                            value = cl.get(nid, name, [])
-                        else:
-                            value = cl.get(nid, name, None)
-                        if prop.isLinkType:
-                            link = self.db.classes[prop.classname]
-                            key = link.getkey()
-                            if value is not None and key:
-                                value = link.get(value, key)
-                            else:
-                                value = '-'
-                        elif prop.isMultilinkType:
-                            l = []
-                            link = self.db.classes[prop.classname]
-                            for entry in value:
-                                key = link.getkey()
-                                if key:
-                                    l.append(link.get(entry, link.getkey()))
-                                else:
-                                    l.append(entry)
-                            value = ', '.join(l)
-                        if name in changed:
-                            chg = '*'
-                        else:
-                            chg = ' '
-                        m.append('%s %s: %s'%(chg, name, value))
-
-                    # handle the note
-                    if self.form.has_key('__note'):
-                        note = self.form['__note'].value
-                        if '\n' in note:
-                            summary = re.split(r'\n\r?', note)[0]
-                        else:
-                            summary = note
-                        m.insert(0, '%s\n\n'%note)
-                    else:
-                        if len(changed) > 1:
-                            plural = 's were'
-                        else:
-                            plural = ' was'
-                        summary = 'This %s has been edited through the web '\
-                            'and the %s value%s changed.'%(cn,
-                            ', '.join(changed), plural)
-                        m.insert(0, '%s\n\n'%summary)
-
-                    # now create the message
-                    content = '\n'.join(m)
-                    message_id = self.db.msg.create(author='1', recipients=[],
-                        date=date.Date('.'), summary=summary, content=content)
-                    messages = cl.get(nid, 'messages')
-                    messages.append(message_id)
-                    props = {'messages': messages}
-                    cl.set(nid, **props)
-
+                self._post_editnode(self.nodeid)
                 # and some nice feedback for the user
                 message = '%s edited ok'%', '.join(changed)
             except:
@@ -312,6 +248,153 @@ class Client:
     showissue = shownode
     showmsg = shownode
 
+    def showuser(self, message=None):
+        ''' display an item
+        '''
+        if self.user in ('admin', self.db.user.get(self.nodeid, 'username')):
+            self.shownode(message)
+        else:
+            raise Unauthorised
+
+    def showfile(self):
+        ''' display a file
+        '''
+        nodeid = self.nodeid
+        cl = self.db.file
+        type = cl.get(nodeid, 'type')
+        if type == 'message/rfc822':
+            type = 'text/plain'
+        self.header(headers={'Content-Type': type})
+        self.write(cl.get(nodeid, 'content'))
+
+    def _createnode(self):
+        ''' create a node based on the contents of the form
+        '''
+        cn = self.classname
+        cl = self.db.classes[cn]
+        props = {}
+        keys = self.form.keys()
+        num_re = re.compile('^\d+$')
+        for key in keys:
+            if not cl.properties.has_key(key):
+                continue
+            proptype = cl.properties[key]
+            if proptype.isStringType:
+                value = self.form[key].value.strip()
+            elif proptype.isDateType:
+                value = date.Date(self.form[key].value.strip())
+            elif proptype.isIntervalType:
+                value = date.Interval(self.form[key].value.strip())
+            elif proptype.isLinkType:
+                value = self.form[key].value.strip()
+                # handle key values
+                link = cl.properties[key].classname
+                if not num_re.match(value):
+                    try:
+                        value = self.db.classes[link].lookup(value)
+                    except:
+                        raise ValueError, 'property "%s": %s not a %s'%(
+                            key, value, link)
+            elif proptype.isMultilinkType:
+                value = self.form[key]
+                if type(value) != type([]):
+                    value = [i.strip() for i in value.value.split(',')]
+                else:
+                    value = [i.value.strip() for i in value]
+                link = cl.properties[key].classname
+                l = []
+                for entry in map(str, value):
+                    if not num_re.match(entry):
+                        try:
+                            entry = self.db.classes[link].lookup(entry)
+                        except:
+                            raise ValueError, \
+                                'property "%s": %s not a %s'%(key,
+                                entry, link)
+                    l.append(entry)
+                l.sort()
+                value = l
+            props[key] = value
+        return cl.create(**props)
+
+    def _post_editnode(self, nid):
+        ''' do the linking and message sending part of the node creation
+        '''
+        cn = self.classname
+        cl = self.db.classes[cn]
+        # link if necessary
+        keys = self.form.keys()
+        for key in keys:
+            if key == ':multilink':
+                value = self.form[key].value
+                if type(value) != type([]): value = [value]
+                for value in value:
+                    designator, property = value.split(':')
+                    link, nodeid = roundupdb.splitDesignator(designator)
+                    link = self.db.classes[link]
+                    value = link.get(nodeid, property)
+                    value.append(nid)
+                    link.set(nodeid, **{property: value})
+            elif key == ':link':
+                value = self.form[key].value
+                if type(value) != type([]): value = [value]
+                for value in value:
+                    designator, property = value.split(':')
+                    link, nodeid = roundupdb.splitDesignator(designator)
+                    link = self.db.classes[link]
+                    link.set(nodeid, **{property: nid})
+
+        # if this item has messages, 
+        if (cl.getprops().has_key('messages') and
+                cl.getprops()['messages'].isMultilinkType and
+                cl.getprops()['messages'].classname == 'msg'):
+            # generate an edit message - nosyreactor will send it
+            m = []
+            for name, prop in cl.getprops().items():
+                value = cl.get(nid, name)
+                if prop.isLinkType:
+                    link = self.db.classes[prop.classname]
+                    key = link.getkey()
+                    if value is not None and key:
+                        value = link.get(value, key)
+                    else:
+                        value = '-'
+                elif prop.isMultilinkType:
+                    l = []
+                    link = self.db.classes[prop.classname]
+                    for entry in value:
+                        key = link.getkey()
+                        if key:
+                            l.append(link.get(entry, link.getkey()))
+                        else:
+                            l.append(entry)
+                    value = ', '.join(l)
+                m.append('%s: %s'%(name, value))
+
+            # handle the note
+            note = None
+            if self.form.has_key('__note'):
+                note = self.form['__note']
+            if note is not None and note.value:
+                note = note.value
+                if '\n' in note:
+                    summary = re.split(r'\n\r?', note)[0]
+                else:
+                    summary = note
+                m.append('\n%s\n'%note)
+            else:
+                summary = 'This %s has been created through the web.'%cn
+                m.append('\n%s\s'%summary)
+
+            # now create the message
+            content = '\n'.join(m)
+            message_id = self.db.msg.create(author='1', recipients=[],
+                date=date.Date('.'), summary=summary, content=content)
+            messages = cl.get(nid, 'messages')
+            messages.append(message_id)
+            props = {'messages': messages}
+            cl.set(nid, **props)
+
     def newnode(self, message=None):
         ''' Add a new node to the database.
         
@@ -339,130 +422,11 @@ class Client:
 
         # possibly perform a create
         keys = self.form.keys()
-        num_re = re.compile('^\d+$')
         if [i for i in keys if i[0] != ':']:
             props = {}
             try:
-                keys = self.form.keys()
-                for key in keys:
-                    if not cl.properties.has_key(key):
-                        continue
-                    proptype = cl.properties[key]
-                    if proptype.isStringType:
-                        value = self.form[key].value.strip()
-                    elif proptype.isDateType:
-                        value = date.Date(self.form[key].value.strip())
-                    elif proptype.isIntervalType:
-                        value = date.Interval(self.form[key].value.strip())
-                    elif proptype.isLinkType:
-                        value = self.form[key].value.strip()
-                        # handle key values
-                        link = cl.properties[key].classname
-                        if not num_re.match(value):
-                            try:
-                                value = self.db.classes[link].lookup(value)
-                            except:
-                                raise ValueError, 'property "%s": %s not a %s'%(
-                                    key, value, link)
-                    elif proptype.isMultilinkType:
-                        value = self.form[key]
-                        if type(value) != type([]):
-                            value = [i.strip() for i in value.value.split(',')]
-                        else:
-                            value = [i.value.strip() for i in value]
-                        link = cl.properties[key].classname
-                        l = []
-                        for entry in map(str, value):
-                            if not num_re.match(entry):
-                                try:
-                                    entry = self.db.classes[link].lookup(entry)
-                                except:
-                                    raise ValueError, \
-                                        'property "%s": %s not a %s'%(key,
-                                        entry, link)
-                            l.append(entry)
-                        l.sort()
-                        value = l
-                    props[key] = value
-                nid = cl.create(**props)
-
-                # link if necessary
-                for key in keys:
-                    print key,
-                    if key == ':multilink':
-                        value = self.form[key].value
-                        if type(value) != type([]): value = [value]
-                        for value in value:
-                            designator, property = value.split(':')
-                            print 'miltilinking to ', designator, property
-                            link, nodeid = roundupdb.splitDesignator(designator)
-                            link = self.db.classes[link]
-                            value = link.get(nodeid, property)
-                            value.append(nid)
-                            link.set(nodeid, **{property: value})
-                    elif key == ':link':
-                        value = self.form[key].value
-                        if type(value) != type([]): value = [value]
-                        for value in value:
-                            designator, property = value.split(':')
-                            print 'linking to ', designator, property
-                            link, nodeid = roundupdb.splitDesignator(designator)
-                            link = self.db.classes[link]
-                            link.set(nodeid, **{property: nid})
-                    else:
-                        print 'ignoring'
-
-                # if this item has messages, 
-                if (cl.getprops().has_key('messages') and
-                        cl.getprops()['messages'].isMultilinkType and
-                        cl.getprops()['messages'].classname == 'msg'):
-                    # generate an edit message - nosyreactor will send it
-                    m = []
-                    for name, prop in cl.getprops().items():
-                        value = cl.get(nid, name)
-                        if prop.isLinkType:
-                            link = self.db.classes[prop.classname]
-                            key = link.getkey()
-                            if value is not None and key:
-                                value = link.get(value, key)
-                            else:
-                                value = '-'
-                        elif prop.isMultilinkType:
-                            l = []
-                            link = self.db.classes[prop.classname]
-                            for entry in value:
-                                key = link.getkey()
-                                if key:
-                                    l.append(link.get(entry, link.getkey()))
-                                else:
-                                    l.append(entry)
-                            value = ', '.join(l)
-                        m.append('%s: %s'%(name, value))
-
-                    # handle the note
-                    note = None
-                    if self.form.has_key('__note'):
-                        note = self.form['__note']
-                    if note and note.value:
-                        note = note.value
-                        if '\n' in note:
-                            summary = re.split(r'\n\r?', note)[0]
-                        else:
-                            summary = note
-                        m.append('\n%s\n'%note)
-                    else:
-                        summary = 'This %s has been created through the web.'%cn
-                        m.append('\n%s\s'%summary)
-
-                    # now create the message
-                    content = '\n'.join(m)
-                    message_id = self.db.msg.create(author='1', recipients=[],
-                        date=date.Date('.'), summary=summary, content=content)
-                    messages = cl.get(nid, 'messages')
-                    messages.append(message_id)
-                    props = {'messages': messages}
-                    cl.set(nid, **props)
-
+                nid = self._createnode()
+                self._post_editnode(nid)
                 # and some nice feedback for the user
                 message = '%s created ok'%cn
             except:
@@ -476,24 +440,34 @@ class Client:
     newissue = newnode
     newuser = newnode
 
-    def showuser(self, message=None):
-        ''' display an item
+    def newfile(self, message=None):
+        ''' Add a new file to the database.
+        
+        This form works very much the same way as newnode - it just has a
+        file upload.
         '''
-        if self.user in ('admin', self.db.user.get(self.nodeid, 'username')):
-            self.shownode(message)
-        else:
-            raise Unauthorised
+        cn = self.classname
+        cl = self.db.classes[cn]
 
-    def showfile(self):
-        ''' display a file
-        '''
-        nodeid = self.nodeid
-        cl = self.db.file
-        type = cl.get(nodeid, 'type')
-        if type == 'message/rfc822':
-            type = 'text/plain'
-        self.header(headers={'Content-Type': type})
-        self.write(cl.get(nodeid, 'content'))
+        # possibly perform a create
+        keys = self.form.keys()
+        if [i for i in keys if i[0] != ':']:
+            try:
+                file = self.form['content']
+                self._post_editnode(cl.create(content=file.file.read(),
+                    type=mimetypes.guess_type(file.filename)[0],
+                    name=file.filename))
+                # and some nice feedback for the user
+                message = '%s created ok'%cn
+            except:
+                s = StringIO.StringIO()
+                traceback.print_exc(None, s)
+                message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
+
+        self.pagehead('New %s'%self.classname.capitalize(), message)
+        htmltemplate.newitem(self, self.TEMPLATES, self.db, self.classname,
+            self.form)
+        self.pagefoot()
 
     def classes(self, message=None):
         ''' display a list of all the classes in the database
@@ -545,6 +519,9 @@ class Client:
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.12  2001/07/30 06:26:31  richard
+# Added some documentation on how the newblah works.
+#
 # Revision 1.11  2001/07/30 06:17:45  richard
 # Features:
 #  . Added ability for cgi newblah forms to indicate that the new node
index 18204319d9d131c8ecd3235963f96b5bc50561b9..1ce86ca759890ee3297bce19362493ed7122a69d 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: htmltemplate.py,v 1.14 2001-07-30 06:17:45 richard Exp $
+# $Id: htmltemplate.py,v 1.15 2001-07-30 08:12:17 richard Exp $
 
 import os, re, StringIO, urllib, cgi, errno
 
@@ -710,7 +710,7 @@ def newitem(client, templates, db, classname, form, replace=re.compile(
         s = open(os.path.join(templates, classname+'.newitem')).read()
     except:
         s = open(os.path.join(templates, classname+'.item')).read()
-    w('<form action="new%s">'%classname)
+    w('<form action="new%s" method="POST" enctype="multipart/form-data">'%classname)
     for key in form.keys():
         if key[0] == ':':
             value = form[key].value
@@ -723,6 +723,15 @@ def newitem(client, templates, db, classname, form, replace=re.compile(
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.14  2001/07/30 06:17:45  richard
+# Features:
+#  . Added ability for cgi newblah forms to indicate that the new node
+#    should be linked somewhere.
+# Fixed:
+#  . Fixed the agument handling for the roundup-admin find command.
+#  . Fixed handling of summary when no note supplied for newblah. Again.
+#  . Fixed detection of no form in htmltemplate Field display.
+#
 # Revision 1.13  2001/07/30 02:37:53  richard
 # Temporary measure until we have decent schema migration.
 #
index 90c8f4996d1e447b1bf55bc7ac4709bf07be92ea..bd47d0c7f1eedb63e236927c7706f9e4625c1f87 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: templatebuilder.py,v 1.7 2001-07-30 00:06:52 richard Exp $
+# $Id: templatebuilder.py,v 1.8 2001-07-30 08:12:17 richard Exp $
 import errno
 
 preamble = """ 
@@ -18,6 +18,8 @@ def makeHtmlBase(templateDir):
     fd = open(os.path.join(templateDir, 'htmlbase.py'), 'w')
     fd.write(preamble)
     for file in filelist:
+        # skip the backup files created by richard's vim
+        if file[-1] == '~': continue
         mangled_name = os.path.basename(re.sub(r'\.', 'DOT', file))
         fd.write('%s = """'%mangled_name)
         fd.write(open(file).read())
@@ -65,6 +67,9 @@ if __name__ == "__main__":
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.7  2001/07/30 00:06:52  richard
+# Hrm - had IOError instead of OSError. Not sure why there's two. Ho hum.
+#
 # Revision 1.6  2001/07/29 07:01:39  richard
 # Added vim command to all source so that we don't get no steenkin' tabs :)
 #
diff --git a/roundup/templates/classic/html/file.newitem b/roundup/templates/classic/html/file.newitem
new file mode 100644 (file)
index 0000000..be795cf
--- /dev/null
@@ -0,0 +1,18 @@
+<!-- $Id: file.newitem,v 1.1 2001-07-30 08:12:17 richard Exp $-->
+<table border=0 cellspacing=0 cellpadding=2>
+
+<tr class="strong-header">
+  <td colspan=2>File upload details</td>
+</td>
+
+<tr bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">File:</span></td>
+    <td class="form-text"><input type="file" name="content" size="40"></td>
+</tr>
+
+<tr bgcolor="ffffea">
+    <td>&nbsp;</td>
+    <td class="form-text"><display call="submit()"></td>
+</tr>
+
+</table>
index c1f1ea9c1f991bab28f089ade40750f125415103..22dc0ec3fdbf4d2031d68c6fbfa4c8ff9a3d05dd 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: issue.item,v 1.2 2001-07-29 04:07:37 richard Exp $-->
+<!-- $Id: issue.item,v 1.3 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
     <td colspan=3 class="form-text"><display call="submit()"></td>
 </tr>
 
-<property name="messages">
 <tr class="strong-header">
     <td colspan=4><b>Messages</b></td>
 </tr>
+<property name="messages">
 <tr>            
     <td colspan=4><display call="list('messages')"></td>
 </tr>
 </property>
 
+<tr class="strong-header">
+  <td colspan=4><b>Files</b></td>
+</tr>
+<tr class="form-help">
+ <td colspan=4>
+   <a href="newfile?:multilink=issue<display call="plain('id')">:files">Attach a file to this issue</a>
+ </td>
+</tr>
 <property name="files">
- <tr class="strong-header">
-     <td colspan=4><b>Files</b></td>
- </tr>
  <tr>            
      <td colspan=4><display call="list('files')"></td>
  </tr>
index 99f32f8b59adbc81f1f9993dae9b6d35f6032c28..cccb5732a1aedb66df99f826cf14f64e4140cf31 100644 (file)
@@ -2,7 +2,7 @@
 # Do Not Edit (Unless You Want To)
 # This file automagically generated by roundup.htmldata.makeHtmlBase
 # 
-fileDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+fileDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="name">
         <td><display call="link('name')"></td>
@@ -13,7 +13,27 @@ fileDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
 </tr>
 """
 
-issueDOTfilter = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+fileDOTnewitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
+<table border=0 cellspacing=0 cellpadding=2>
+
+<tr class="strong-header">
+  <td colspan=2>File upload details</td>
+</td>
+
+<tr bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">File:</span></td>
+    <td class="form-text"><input type="file" name="content" size="40"></td>
+</tr>
+
+<tr bgcolor="ffffea">
+    <td>&nbsp;</td>
+    <td class="form-text"><display call="submit()"></td>
+</tr>
+
+</table>
+"""
+
+issueDOTfilter = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <property name="title">
  <tr><th width="1%" align="right" class="location-bar">Title</th>
  <td><display call="field('title')"></td></tr>
@@ -28,7 +48,7 @@ issueDOTfilter = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp
 </property>
 """
 
-issueDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+issueDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr class="row-<display call="plain('status')">">
     <property name="id">
         <td valign="top"><display call="plain('id')"></td>
@@ -51,7 +71,7 @@ issueDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $
 </tr>
 """
 
-issueDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+issueDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
@@ -95,19 +115,24 @@ issueDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
     <td colspan=3 class="form-text"><display call="submit()"></td>
 </tr>
 
-<property name="messages">
 <tr class="strong-header">
     <td colspan=4><b>Messages</b></td>
 </tr>
+<property name="messages">
 <tr>            
     <td colspan=4><display call="list('messages')"></td>
 </tr>
 </property>
 
+<tr class="strong-header">
+  <td colspan=4><b>Files</b></td>
+</tr>
+<tr class="form-help">
+ <td colspan=4>
+   <a href="newfile?:multilink=issue<display call="plain('id')">:files">Attach a file to this issue</a>
+ </td>
+</tr>
 <property name="files">
- <tr class="strong-header">
-     <td colspan=4><b>Files</b></td>
- </tr>
  <tr>            
      <td colspan=4><display call="list('files')"></td>
  </tr>
@@ -117,7 +142,7 @@ issueDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
 
 """
 
-msgDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+msgDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="date">
         <td><display call="link('date')"></td>
@@ -131,7 +156,7 @@ msgDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $--
 </tr>
 """
 
-msgDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+msgDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
@@ -378,7 +403,7 @@ th {
 }
 """
 
-userDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+userDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="username">
         <td><display call="link('username')"></td>
@@ -398,7 +423,7 @@ userDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
 </tr>
 """
 
-userDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+userDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
index 40722514d29b425647a1aa0e4aab495affdc171e..91a39529af53b7c637c4b1fa5e9ddbd3d51dea28 100644 (file)
@@ -2,7 +2,7 @@
 # Do Not Edit (Unless You Want To)
 # This file automagically generated by roundup.htmldata.makeHtmlBase
 # 
-fileDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+fileDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="name">
         <td><display call="link('name')"></td>
@@ -13,7 +13,27 @@ fileDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
 </tr>
 """
 
-issueDOTfilter = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+fileDOTnewitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
+<table border=0 cellspacing=0 cellpadding=2>
+
+<tr class="strong-header">
+  <td colspan=2>File upload details</td>
+</td>
+
+<tr bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">File:</span></td>
+    <td class="form-text"><input type="file" name="content" size="40"></td>
+</tr>
+
+<tr bgcolor="ffffea">
+    <td>&nbsp;</td>
+    <td class="form-text"><display call="submit()"></td>
+</tr>
+
+</table>
+"""
+
+issueDOTfilter = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <property name="title">
  <tr><th width="1%" align="right" class="location-bar">Title</th>
  <td><display call="field('title')"></td></tr>
@@ -44,7 +64,7 @@ issueDOTfilter = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp
 </property>
 """
 
-issueDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+issueDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="id">
         <td valign="top"><display call="field('id')"></td>
@@ -76,7 +96,7 @@ issueDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $
 </tr>
 """
 
-issueDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+issueDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
@@ -135,19 +155,24 @@ issueDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
     <td colspan=3 class="form-text"><display call="submit()"></td>
 </tr>
 
-<property name="messages">
 <tr class="strong-header">
     <td colspan=4><b>Messages</b></td>
 </tr>
+<property name="messages">
 <tr>            
     <td colspan=4><display call="list('messages')"></td>
 </tr>
 </property>
 
+<tr class="strong-header">
+  <td colspan=4><b>Files</b></td>
+</tr>
+<tr class="form-help">
+ <td colspan=4>
+   <a href="newfile?:multilink=issue<display call="plain('id')">:files">Attach a file to this issue</a>
+ </td>
+</tr>
 <property name="files">
- <tr class="strong-header">
-     <td colspan=4><b>Files</b></td>
- </tr>
  <tr>            
      <td colspan=4><display call="list('files')"></td>
  </tr>
@@ -157,7 +182,7 @@ issueDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
 
 """
 
-msgDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+msgDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="date">
         <td><display call="link('date')"></td>
@@ -171,7 +196,7 @@ msgDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $--
 </tr>
 """
 
-msgDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+msgDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
@@ -375,7 +400,7 @@ th {
 }
 """
 
-supportDOTfilter = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+supportDOTfilter = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <property name="title">
  <tr><th width="1%" align="right" class="location-bar">Title</th>
  <td><display call="field('title')"></td></tr>
@@ -410,7 +435,7 @@ supportDOTfilter = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Ex
 </property>
 """
 
-supportDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+supportDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="id">
         <td valign="top"><display call="field('id')"></td>
@@ -445,7 +470,7 @@ supportDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp
 </tr>
 """
 
-supportDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+supportDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
@@ -511,19 +536,38 @@ supportDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp
     <td colspan=3 class="form-text"><display call="submit()"></td>
 </tr>
 
-<property name="messages">
 <tr class="strong-header">
     <td colspan=4><b>Messages</b></td>
 </tr>
+<property name="messages">
 <tr>            
     <td colspan=4><display call="list('messages')"></td>
 </tr>
 </property>
 
-<property name="files">
- <tr class="strong-header">
-     <td colspan=4><b>Files</b></td>
+<tr class="strong-header">
+  <td colspan=4><b>Timelog</b></td>
+</tr>
+<tr class="form-help">
+ <td colspan=4>
+  <a href="newtimelog?:multilink=support<display call="plain('id')">:timelog">Log time against this support call</a>
+ </td>
+</tr>
+<property name="timelog">
+ <tr>            
+   <td colspan=4><display call="list('timelog')"></td>
  </tr>
+</property>
+
+<tr class="strong-header">
+  <td colspan=4><b>Files</b></td>
+</tr>
+<tr class="form-help">
+ <td colspan=4>
+   <a href="newfile?:multilink=support<display call="plain('id')">:files">Attach a file to support call</a>
+ </td>
+</tr>
+<property name="files">
  <tr>            
      <td colspan=4><display call="list('files')"></td>
  </tr>
@@ -533,7 +577,64 @@ supportDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp
 
 """
 
-userDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+timelogDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
+<tr>
+    <property name="date">
+        <td><display call="link('date')"></td>
+    </property>
+    <property name="performedby">
+        <td><display call="plain('performedby')"></td>
+    </property>
+    <property name="time">
+        <td><display call="plain('time')"></td>
+    </property>
+    <property name="description">
+        <td><display call="plain('description')"></td>
+    </property>
+</tr>
+"""
+
+timelogDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
+<table border=0 cellspacing=0 cellpadding=2>
+
+<tr class="strong-header">
+  <td colspan=2>Time log details</td>
+</td>
+
+<tr  bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">Time spent</span></td>
+    <td class="form-text"><display call="field('time', size=40)"></td>
+</tr>
+<tr  bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">Description</span></td>
+    <td class="form-text"><display call="field('description', size=40)"></td>
+</tr>
+<tr  bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">Date</span></td>
+    <td class="form-text"><display call="field('date', size=40)"></td>
+</tr>
+<tr  bgcolor="ffffea">
+    <td width=1% nowrap align=right><span class="form-label">Performed by</span></td>
+    <td class="form-text"><display call="field('performedby', size=40)"></td>
+</tr>
+
+<tr bgcolor="ffffea">
+    <td>&nbsp;</td>
+    <td class="form-text"><display call="submit()"></td>
+</tr>
+
+<tr class="strong-header">
+    <td colspan=2><b>History</b></td>
+</tr>
+<tr>
+    <td colspan=2><display call="history()"></td>
+</tr>
+
+</table>
+
+"""
+
+userDOTindex = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <tr>
     <property name="username">
         <td><display call="link('username')"></td>
@@ -553,7 +654,7 @@ userDOTindex = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-
 </tr>
 """
 
-userDOTitem = """<!-- $Id: htmlbase.py,v 1.4 2001-07-30 02:38:49 richard Exp $-->
+userDOTitem = """<!-- $Id: htmlbase.py,v 1.5 2001-07-30 08:12:17 richard Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
index 03624971f138a963f580379b53293e5c47ebd56e..071e4ab1af55fb9ffccc5751514e1d3cdd643727 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: interfaces.py,v 1.3 2001-07-30 01:26:59 richard Exp $
+# $Id: interfaces.py,v 1.4 2001-07-30 08:12:17 richard Exp $
 
 import instance_config, urlparse, os
 from roundup import cgi_client, mailgw 
@@ -8,8 +8,10 @@ class Client(cgi_client.Client):
         with any specific extensions 
     ''' 
     TEMPLATES = instance_config.TEMPLATES
-    showsupport = cgi_client.Client.showitem
-    newsupport = cgi_client.Client.newissue
+    showsupport = cgi_client.Client.shownode
+    showtimelog = cgi_client.Client.shownode
+    newsupport = cgi_client.Client.newnode
+    newtimelog = cgi_client.Client.newnode
 
     default_index_sort = ['-activity']
     default_index_group = ['priority']
@@ -65,6 +67,12 @@ class MailGW(mailgw.MailGW):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.3  2001/07/30 01:26:59  richard
+# Big changes:
+#  . split off the support priority into its own class
+#  . added "new support, new user" to the page head
+#  . fixed the display options for the heading links
+#
 # Revision 1.2  2001/07/29 07:01:39  richard
 # Added vim command to all source so that we don't get no steenkin' tabs :)
 #