index 9292c49f194433f66a3d12bd28ef7dfbe4d35205..f1b78b448790ed8da5cf57b7dc7e219f38a89e1b 100644 (file)
l = self._client.db.classes.keys()
l.sort()
return [HTMLClass(self._client, cn) for cn in l]
-
+
+def lookupIds(db, prop, ids, num_re=re.compile('-?\d+')):
+ cl = db.getclass(prop.classname)
+ l = []
+ for entry in ids:
+ if num_re.match(entry):
+ l.append(entry)
+ else:
+ l.append(cl.lookup(entry))
+ return l
+
class HTMLClass:
''' Accesses through a class (either through *class* or *db.<classname>*)
'''
def __getitem__(self, item):
''' return an HTMLProperty instance
'''
- #print 'getitem', (self, item)
+ #print 'HTMLClass.getitem', (self, item)
# we don't exist
if item == 'id':
return None
- if item == 'creator':
- # but we will be created by this user...
- return HTMLUser(self._client, 'user', self._client.userid)
# get the property
prop = self._props[item]
# look up the correct HTMLProperty class
+ form = self._client.form
for klass, htmlklass in propclasses:
- if isinstance(prop, hyperdb.Multilink):
- value = []
+ if not isinstance(prop, klass):
+ continue
+ if form.has_key(item):
+ if isinstance(prop, hyperdb.Multilink):
+ value = lookupIds(self._db, prop,
+ handleListCGIValue(form[item]))
+ elif isinstance(prop, hyperdb.Link):
+ value = form[item].value.strip()
+ if value:
+ value = lookupIds(self._db, prop, [value])[0]
+ else:
+ value = None
+ else:
+ value = form[item].value.strip() or None
else:
- value = None
- if isinstance(prop, klass):
- return htmlklass(self._client, '', prop, item, value)
+ if isinstance(prop, hyperdb.Multilink):
+ value = []
+ else:
+ value = None
+ print (prop, value)
+ return htmlklass(self._client, '', prop, item, value)
# no good
raise KeyError, item
for x in self._klass.filter(None, filterspec, sort, group)]
return l
- def classhelp(self, properties, label='?', width='400', height='400'):
- '''pop up a javascript window with class help
+ def classhelp(self, properties=None, label='list', width='500',
+ height='400'):
+ ''' Pop up a javascript window with class help
- This generates a link to a popup window which displays the
- properties indicated by "properties" of the class named by
- "classname". The "properties" should be a comma-separated list
- (eg. 'id,name,description').
+ This generates a link to a popup window which displays the
+ properties indicated by "properties" of the class named by
+ "classname". The "properties" should be a comma-separated list
+ (eg. 'id,name,description'). Properties defaults to all the
+ properties of a class (excluding id, creator, created and
+ activity).
- You may optionally override the label displayed, the width and
- height. The popup window will be resizable and scrollable.
+ You may optionally override the label displayed, the width and
+ height. The popup window will be resizable and scrollable.
'''
+ if properties is None:
+ properties = self._klass.getprops(protected=0).keys()
+ properties.sort()
+ properties = ','.join(properties)
return '<a href="javascript:help_window(\'%s?:template=help&' \
':contentonly=1&properties=%s\', \'%s\', \'%s\')"><b>'\
'(%s)</b></a>'%(self.classname, properties, width, height, label)
# new template, using the specified classname and request
pt = getTemplate(self._db.config.TEMPLATES, self.classname, name)
- # XXX handle PT rendering errors here nicely
- try:
- # use our fabricated request
- return pt.render(self._client, self.classname, req)
- except PageTemplate.PTRuntimeError, message:
- return '<strong>%s</strong><ol>%s</ol>'%(message,
- cgi.escape('<li>'.join(pt._v_errors)))
+ # use our fabricated request
+ return pt.render(self._client, self.classname, req)
class HTMLItem:
''' Accesses through an *item*
def __getitem__(self, item):
''' return an HTMLProperty instance
'''
- #print 'getitem', (self, item)
+ #print 'HTMLItem.getitem', (self, item)
if item == 'id':
return self._nodeid
return ' <input type="hidden" name=":action" value="edit">\n'\
' <input type="submit" name="submit" value="%s">'%label
- # XXX this probably should just return the history items, not the HTML
+ def journal(self, direction='descending'):
+ ''' Return a list of HTMLJournalEntry instances.
+ '''
+ # XXX do this
+ return []
+
def history(self, direction='descending'):
l = ['<table class="history">'
'<tr><th colspan="4" class="header">',
l.append('</table>')
return '\n'.join(l)
+ def renderQueryForm(self):
+ ''' Render this item, which is a query, as a search form.
+ '''
+ # create a new request and override the specified args
+ req = HTMLRequest(self._client)
+ req.classname = self._klass.get(self._nodeid, 'klass')
+ req.updateFromURL(self._klass.get(self._nodeid, 'url'))
+
+ # new template, using the specified classname and request
+ pt = getTemplate(self._db.config.TEMPLATES, req.classname, 'search')
+
+ # use our fabricated request
+ return pt.render(self._client, req.classname, req)
+
class HTMLUser(HTMLItem):
''' Accesses through the *user* (a special case of item)
'''
class HTMLProperty:
''' String, Number, Date, Interval HTMLProperty
+ Hase useful attributes:
+
+ _name the name of the property
+ _value the value of the property if any
+
A wrapper object which may be stringified for the plain() behaviour.
'''
def __init__(self, client, nodeid, prop, name, value):
def email(self, escape=1):
''' fudge email '''
- if self.value is None: value = ''
+ if self._value is None: value = ''
else: value = str(self._value)
value = value.replace('@', ' at ')
value = value.replace('.', ' ')
'''
def __getattr__(self, attr):
''' return a new HTMLItem '''
- #print 'getattr', (self, attr, self._value)
+ #print 'Link.getattr', (self, attr, self._value)
if not self._value:
raise AttributeError, "Can't access missing value"
if self._prop.classname == 'user':
- klass = HTMLItem
- else:
klass = HTMLUser
+ else:
+ klass = HTMLItem
i = klass(self._client, self._prop.classname, self._value)
return getattr(i, attr)
def plain(self, escape=0):
if self._value is None:
- return _('[unselected]')
+ return ''
linkcl = self._db.classes[self._prop.classname]
k = linkcl.labelprop(1)
value = str(linkcl.get(self._value, k))
l.append('</select>')
return '\n'.join(l)
- def download(self, showid=0):
- linkname = self._prop.classname
- linkcl = self._db.getclass(linkname)
- k = linkcl.labelprop(1)
- linkvalue = cgi.escape(str(linkcl.get(self._value, k)))
- if showid:
- label = value
- title = ' title="%s"'%linkvalue
- # note ... this should be urllib.quote(linkcl.get(value, k))
- else:
- label = linkvalue
- title = ''
- return '<a href="%s%s/%s"%s>%s</a>'%(linkname, self._value,
- linkvalue, title, label)
-
def menu(self, size=None, height=None, showid=0, additional=[],
**conditions):
value = self._value
l.append('<option %svalue="%s">%s</option>'%(s, optionid, lab))
l.append('</select>')
return '\n'.join(l)
-
# def checklist(self, ...)
class MultilinkHTMLProperty(HTMLProperty):
def __getitem__(self, num):
''' iterate and return a new HTMLItem
'''
- #print 'getitem', (self, num)
+ #print 'Multi.getitem', (self, num)
value = self._value[num]
if self._prop.classname == 'user':
klass = HTMLUser
klass = HTMLItem
return klass(self._client, self._prop.classname, value)
+ def __contains__(self, value):
+ ''' Support the "in" operator
+ '''
+ return value in self._value
+
def reverse(self):
''' return the list in reverse order
'''
if isinstance(value, type([])):
return [value.value for value in value]
else:
- return value.value.split(',')
+ value = value.value.strip()
+ if not value:
+ return []
+ return value.split(',')
class ShowDict:
''' A convenience access to the :columns index parameters
self.classname = client.classname
self.template = client.template
+ self._post_init()
+
+ def _post_init(self):
+ ''' Set attributes based on self.form
+ '''
# extract the index display information from the form
self.columns = []
if self.form.has_key(':columns'):
else:
self.startwith = 0
+ def updateFromURL(self, url):
+ ''' Parse the URL for query args, and update my attributes using the
+ values.
+ '''
+ self.form = {}
+ for name, value in cgi.parse_qsl(url):
+ if self.form.has_key(name):
+ if isinstance(self.form[name], type([])):
+ self.form[name].append(cgi.MiniFieldStorage(name, value))
+ else:
+ self.form[name] = [self.form[name],
+ cgi.MiniFieldStorage(name, value)]
+ else:
+ self.form[name] = cgi.MiniFieldStorage(name, value)
+ self._post_init()
+
def update(self, kwargs):
+ ''' Update my attributes using the keyword args
+ '''
self.__dict__.update(kwargs)
if kwargs.has_key('columns'):
self.show = ShowDict(self.columns)
def description(self):
''' Return a description of the request - handle for the page title.
'''
- s = [self.client.db.config.INSTANCE_NAME]
+ s = [self.client.db.config.TRACKER_NAME]
if self.classname:
if self.client.nodeid:
s.append('- %s%s'%(self.classname, self.client.nodeid))