Index: trunk/packages/sipb-xen-www/code/controls.py
===================================================================
--- trunk/packages/sipb-xen-www/code/controls.py	(revision 526)
+++ trunk/packages/sipb-xen-www/code/controls.py	(revision 535)
@@ -12,4 +12,5 @@
 import re
 import cache_acls
+import cPickle
 
 # ... and stolen from xend/uuid.py
@@ -114,5 +115,5 @@
         machine.type_id = machine_type.type_id
         ctx.current.save(machine)
-        disk = Disk(machine_id=machine.machine_id, 
+        disk = Disk(machine_id=machine.machine_id,
                     guest_device_name='hda', size=disk_size)
         open_nics = NIC.select_by(machine_id=None)
@@ -123,5 +124,5 @@
         nic.machine_id = machine.machine_id
         nic.hostname = name
-        ctx.current.save(nic)    
+        ctx.current.save(nic)
         ctx.current.save(disk)
         cache_acls.refreshMachine(machine)
@@ -137,18 +138,11 @@
     return machine
 
-def getUptimes(machines=None):
-    """Return a dictionary mapping machine names to uptime strings"""
-    value_string = remctl('web', 'listvms')
-    lines = value_string.splitlines()
-    d = {}
-    for line in lines:
-        lst = line.split()
-        name, id = lst[:2]
-        uptime = ' '.join(lst[2:])
-        d[name] = uptime
-    ans = {}
-    for m in machines:
-        ans[m] = d.get(m.name)
-    return ans
+def getList(machines):
+    """Return a dictionary mapping machine  to dicts."""
+    value_string = remctl('web', 'listvms', '--pickle')
+    value_dict = cPickle.loads(value_string)
+
+    d = dict((m, value_dict[m.name]) for m in machines if m.name in value_dict)
+    return d
 
 def parseStatus(s):
Index: trunk/packages/sipb-xen-www/code/main.py
===================================================================
--- trunk/packages/sipb-xen-www/code/main.py	(revision 526)
+++ trunk/packages/sipb-xen-www/code/main.py	(revision 535)
@@ -197,18 +197,23 @@
 def getListDict(user):
     """Gets the list of local variables used by list.tmpl."""
+    checkpoint.checkpoint('Starting')
     machines = g.machines
     checkpoint.checkpoint('Got my machines')
     on = {}
     has_vnc = {}
-    on = g.uptimes
+    xmlist = g.xmlist
     checkpoint.checkpoint('Got uptimes')
     for m in machines:
-        m.uptime = g.uptimes.get(m)
-        if not on[m]:
+        if m not in xmlist:
             has_vnc[m] = 'Off'
-        elif m.type.hvm:
-            has_vnc[m] = True
+            m.uptime = None
         else:
-            has_vnc[m] = "ParaVM"+helppopup("paravm_console")
+            m.uptime = xmlist[m]['uptime']
+            if xmlist[m]['console']:
+                has_vnc[m] = True
+            elif m.type.hvm:
+                has_vnc[m] = "WTF?"
+            else:
+                has_vnc[m] = "ParaVM"+helppopup("paravm_console")
     max_memory = validation.maxMemory(user)
     max_disk = validation.maxDisk(user)
@@ -228,6 +233,5 @@
              defaults=defaults,
              machines=machines,
-             has_vnc=has_vnc,
-             uptimes=g.uptimes)
+             has_vnc=has_vnc)
     return d
 
@@ -652,5 +656,6 @@
         checkpoint.checkpoint('output as a string')
         print output_string
-        print '<!-- <pre>%s</pre> -->' % checkpoint
+        if fields.has_key('timedebug'):
+            print '<pre>%s</pre>' % checkpoint
     except Exception, err:
         if not fields.has_key('js'):
@@ -676,4 +681,11 @@
 if __name__ == '__main__':
     fields = cgi.FieldStorage()
+
+    if fields.has_key('sqldebug'):
+        import logging
+        logging.basicConfig()
+        logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
+        logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.INFO)
+
     u = getUser()
     g.user = u
Index: trunk/packages/sipb-xen-www/code/templates/list.tmpl
===================================================================
--- trunk/packages/sipb-xen-www/code/templates/list.tmpl	(revision 526)
+++ trunk/packages/sipb-xen-www/code/templates/list.tmpl	(revision 535)
@@ -1,4 +1,5 @@
 #from skeleton import skeleton
 #extends skeleton
+#import datetime
 
 
@@ -119,5 +120,5 @@
 <td>#slurp
 #if $machine.uptime
-$machine.uptime#slurp
+${datetime.timedelta(seconds=int(machine.uptime))}#slurp
 #end if
 </td>
Index: trunk/packages/sipb-xen-www/code/validation.py
===================================================================
--- trunk/packages/sipb-xen-www/code/validation.py	(revision 526)
+++ trunk/packages/sipb-xen-www/code/validation.py	(revision 535)
@@ -5,5 +5,5 @@
 import re
 import string
-from sipb_xen_database import Machine, NIC, Type
+from sipb_xen_database import Machine, NIC, Type, Disk
 from webcommon import InvalidInput, g
 
@@ -45,5 +45,5 @@
         return MAX_MEMORY_SINGLE
     machines = getMachinesByOwner(user, machine)
-    active_machines = [x for x in machines if g.uptimes.get(x)]
+    active_machines = [x for x in machines if g.xmlist.get(x)]
     mem_usage = sum([x.memory for x in active_machines if x != machine])
     return min(MAX_MEMORY_SINGLE, MAX_MEMORY_TOTAL-mem_usage)
@@ -55,12 +55,15 @@
     return the maximum that a given machine can be changed to.
     """
-    machines = getMachinesByOwner(user, machine)
-    disk_usage = sum([sum([y.size for y in x.disks])
-                      for x in machines if x != machine])
+    if machine is not None:
+        machine_id = machine.machine_id
+    else:
+        machine_id = None
+    disk_usage = Disk.query().filter_by(Disk.c.machine_id != machine_id,
+                                        owner=user).sum(Disk.c.size)
     return min(MAX_DISK_SINGLE, MAX_DISK_TOTAL-disk_usage/1024.)
 
 def cantAddVm(user):
     machines = getMachinesByOwner(user)
-    active_machines = [x for x in machines if g.uptimes.get(x)]
+    active_machines = [x for x in machines if g.xmlist.get(x)]
     if len(machines) >= MAX_VMS_TOTAL:
         return 'You have too many VMs to create a new one.'
Index: trunk/packages/sipb-xen-www/code/webcommon.py
===================================================================
--- trunk/packages/sipb-xen-www/code/webcommon.py	(revision 526)
+++ trunk/packages/sipb-xen-www/code/webcommon.py	(revision 535)
@@ -1,4 +1,5 @@
 """Exceptions for the web interface."""
 
+import time
 from sipb_xen_database import Machine, MachineAccess
 
@@ -40,10 +41,9 @@
     def __init__(self, user):
         self.user = user
-    
-    machines = cachedproperty(lambda self: 
-                             [ma.machine for ma in 
-                              MachineAccess.select_by(user=self.user)])
-    uptimes = cachedproperty(lambda self: 
-                             controls.getUptimes(self.machines))
+
+    machines = cachedproperty(lambda self:
+                                  Machine.query().join('acl').select_by(user=self.user))
+    xmlist = cachedproperty(lambda self:
+                                controls.getList(self.machines))
 
     def clear(self):
