Move CodeError and InvalidInput into invirt.common
[invirt/packages/invirt-web.git] / code / webcommon.py
1 """Exceptions for the web interface."""
2
3 import time
4 from invirt import database
5 from invirt.database import Machine, MachineAccess
6
7 import controls
8
9 def cachedproperty(func):
10     name = '__cache_' + func.__name__ + '_' + str(id(func))
11     def getter(self):
12         try:
13             return getattr(self, name)
14         except AttributeError:
15             value = func(self)
16             setattr(self, name, value)
17             return value
18     return property(getter)
19
20 class State(object):
21     """State for a request"""
22     def __init__(self, user, isadmin=False):
23         self.username = user
24         self.isadmin = isadmin
25
26     def getMachines(self):
27         if self.isadmin:
28             return Machine.query().join('acl').filter(
29                 database.or_(MachineAccess.user==self.username,
30                              Machine.adminable==True))
31         else:
32             return Machine.query().join('acl').filter_by(user=self.username)
33
34     machines = cachedproperty(getMachines)
35     xmlist_raw = cachedproperty(lambda self: controls.getList())
36     xmlist = cachedproperty(lambda self:
37                                 dict((m, self.xmlist_raw[m.name])
38                                      for m in self.machines
39                                      if m.name in self.xmlist_raw))
40
41     def clear(self):
42         """Clear the state so future accesses reload it."""
43         for attr in list(self.__dict__):
44             if attr.startswith('__cache_'):
45                 delattr(self, attr)