Code

fixes and release announcement
[roundup.git] / roundup / cgi / templating.py
index de9d09605072cd78e789705e5f4634a33e2a468b..68abcaa04c1c382a40f5d2b260eeb8a146f58213 100644 (file)
@@ -124,7 +124,7 @@ class Templates:
                 raise
 
         if self.templates.has_key(src) and \
-                stime < self.templates[src].mtime:
+                stime <= self.templates[src].mtime:
             # compiled template is up to date
             return self.templates[src]
 
@@ -134,7 +134,7 @@ class Templates:
         content_type = mimetypes.guess_type(filename)[0] or 'text/html'
         pt.pt_edit(open(src).read(), content_type)
         pt.id = filename
-        pt.mtime = time.time()
+        pt.mtime = stime
         return pt
 
     def __getitem__(self, name):
@@ -195,6 +195,7 @@ class RoundupPageTemplate(PageTemplate.PageTemplate):
              'tracker': client.instance,
              'utils': utils(client),
              'templates': Templates(client.instance.config.TEMPLATES),
+             'template': self,
         }
         # add in the item if there is one
         if client.nodeid:
@@ -269,14 +270,14 @@ class HTMLDatabase:
     def classes(self):
         l = self._client.db.classes.keys()
         l.sort()
-        r = []
+        m = []
         for item in l:
             if item == 'user':
                 m.append(HTMLUserClass(self._client, item))
             m.append(HTMLClass(self._client, item))
-        return r
+        return m
 
-def lookupIds(db, prop, ids, fail_ok=False, num_re=re.compile('-?\d+')):
+def lookupIds(db, prop, ids, fail_ok=0, num_re=re.compile('-?\d+')):
     ''' "fail_ok" should be specified if we wish to pass through bad values
         (most likely form values that we wish to represent back to the user)
     '''
@@ -294,6 +295,18 @@ def lookupIds(db, prop, ids, fail_ok=False, num_re=re.compile('-?\d+')):
                     l.append(entry)
     return l
 
+def lookupKeys(linkcl, key, ids, num_re=re.compile('-?\d+')):
+    ''' Look up the "key" values for "ids" list - though some may already
+    be key values, not ids.
+    '''
+    l = []
+    for entry in ids:
+        if num_re.match(entry):
+            l.append(linkcl.get(entry, key))
+        else:
+            l.append(entry)
+    return l
+
 class HTMLPermissions:
     ''' Helpers that provide answers to commonly asked Permission questions.
     '''
@@ -376,7 +389,10 @@ class HTMLClass(HTMLInputMixin, HTMLPermissions):
             return None
 
         # get the property
-        prop = self._props[item]
+        try:
+            prop = self._props[item]
+        except KeyError:
+            raise KeyError, 'No such property "%s" on %s'%(item, self.classname)
 
         # look up the correct HTMLProperty class
         form = self._client.form
@@ -386,12 +402,12 @@ class HTMLClass(HTMLInputMixin, HTMLPermissions):
             if form.has_key(item):
                 if isinstance(prop, hyperdb.Multilink):
                     value = lookupIds(self._db, prop,
-                        handleListCGIValue(form[item]), fail_ok=True)
+                        handleListCGIValue(form[item]), fail_ok=1)
                 elif isinstance(prop, hyperdb.Link):
                     value = form[item].value.strip()
                     if value:
                         value = lookupIds(self._db, prop, [value],
-                            fail_ok=True)[0]
+                            fail_ok=1)[0]
                     else:
                         value = None
                 else:
@@ -629,6 +645,10 @@ class HTMLItem(HTMLInputMixin, HTMLPermissions):
     def designator(self):
         """Return this item's designator (classname + id)."""
         return '%s%s'%(self._classname, self._nodeid)
+
+    def is_retired(self):
+        """Is this item retired?"""
+        return self._klass.is_retired(self._nodeid)
     
     def submit(self, label="Submit Changes"):
         """Generate a submit button.
@@ -1190,7 +1210,7 @@ class BooleanHTMLProperty(HTMLProperty):
         '''
         self.view_check()
 
-        if not is_edit_ok():
+        if not self.is_edit_ok():
             return self.plain()
 
         checked = self._value and "checked" or ""
@@ -1242,7 +1262,7 @@ class DateHTMLProperty(HTMLProperty):
             tz = self._db.getUserTimezone()
             value = cgi.escape(str(self._value.local(tz)))
 
-        if is_edit_ok():
+        if self.is_edit_ok():
             value = '&quot;'.join(value.split('"'))
             return self.input(name=self._formname,value=value,size=size)
         
@@ -1383,13 +1403,13 @@ class LinkHTMLProperty(HTMLProperty):
         else:
             k = linkcl.getkey()
             if k:
-                label = linkcl.get(self._value, k)
+                value = linkcl.get(self._value, k)
             else:
-                label = self._value
-            value = cgi.escape(str(self._value))
+                value = self._value
+            value = cgi.escape(str(value))
             value = '&quot;'.join(value.split('"'))
         return '<input name="%s" value="%s" size="%s">'%(self._formname,
-            label, size)
+            value, size)
 
     def menu(self, size=None, height=None, showid=0, additional=[],
             sort_on=None, **conditions):
@@ -1535,7 +1555,7 @@ class MultilinkHTMLProperty(HTMLProperty):
             showid=1
         if not showid:
             k = linkcl.labelprop(1)
-            value = [linkcl.get(v, k) for v in value]
+            value = lookupKeys(linkcl, k, value)
         value = cgi.escape(','.join(value))
         return self.input(name=self._formname,size=size,value=value)