Package web2py :: Package gluon :: Module storage
[hide private]
[frames] | no frames]

Source Code for Module web2py.gluon.storage

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  """ 
  5  This file is part of the web2py Web Framework 
  6  Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> 
  7  License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) 
  8   
  9  Provides: 
 10   
 11  - List; like list but returns None instead of IndexOutOfBounds 
 12  - Storage; like dictionary allowing also for `obj.foo` for `obj['foo']` 
 13  """ 
 14   
 15  import cPickle 
 16  import portalocker 
 17   
 18  __all__ = ['List', 'Storage', 'Settings', 'Messages', 
 19             'StorageList', 'load_storage', 'save_storage'] 
 20   
 21   
22 -class List(list):
23 """ 24 Like a regular python list but a[i] if i is out of bounds return None 25 instead of IndexOutOfBounds 26 """ 27
28 - def __call__(self, i, default=None):
29 if 0<=i<len(self): 30 return self[i] 31 else: 32 return default
33
34 -class Storage(dict):
35 36 """ 37 A Storage object is like a dictionary except `obj.foo` can be used 38 in addition to `obj['foo']`. 39 40 >>> o = Storage(a=1) 41 >>> print o.a 42 1 43 44 >>> o['a'] 45 1 46 47 >>> o.a = 2 48 >>> print o['a'] 49 2 50 51 >>> del o.a 52 >>> print o.a 53 None 54 55 """ 56
57 - def __getattr__(self, key):
58 if key in self: 59 return self[key] 60 else: 61 return None
62
63 - def __setattr__(self, key, value):
64 if value == None: 65 if key in self: 66 del self[key] 67 else: 68 self[key] = value
69
70 - def __delattr__(self, key):
71 if key in self: 72 del self[key] 73 else: 74 raise AttributeError, "missing key=%s" % key
75
76 - def __repr__(self):
77 return '<Storage ' + dict.__repr__(self) + '>'
78
79 - def __getstate__(self):
80 return dict(self)
81
82 - def __setstate__(self, value):
83 for (k, v) in value.items(): 84 self[k] = v
85
86 - def getlist(self, key):
87 """Return a Storage value as a list. 88 89 If the value is a list it will be returned as-is. 90 If object is None, an empty list will be returned. 91 Otherwise, [value] will be returned. 92 93 Example output for a query string of ?x=abc&y=abc&y=def 94 >>> request = Storage() 95 >>> request.vars = Storage() 96 >>> request.vars.x = 'abc' 97 >>> request.vars.y = ['abc', 'def'] 98 >>> request.vars.getlist('x') 99 ['abc'] 100 >>> request.vars.getlist('y') 101 ['abc', 'def'] 102 >>> request.vars.getlist('z') 103 [] 104 105 """ 106 value = self.get(key, None) 107 if isinstance(value, (list, tuple)): 108 return value 109 elif value is None: 110 return [] 111 return [value]
112
113 - def getfirst(self, key):
114 """Return the first or only value when given a request.vars-style key. 115 116 If the value is a list, its first item will be returned; 117 otherwise, the value will be returned as-is. 118 119 Example output for a query string of ?x=abc&y=abc&y=def 120 >>> request = Storage() 121 >>> request.vars = Storage() 122 >>> request.vars.x = 'abc' 123 >>> request.vars.y = ['abc', 'def'] 124 >>> request.vars.getfirst('x') 125 'abc' 126 >>> request.vars.getfirst('y') 127 'abc' 128 >>> request.vars.getfirst('z') 129 130 """ 131 value = self.getlist(key) 132 if len(value): 133 return value[0] 134 return None
135
136 - def getlast(self, key):
137 """Returns the last or only single value when given a request.vars-style key. 138 139 If the value is a list, the last item will be returned; 140 otherwise, the value will be returned as-is. 141 142 Simulated output with a query string of ?x=abc&y=abc&y=def 143 >>> request = Storage() 144 >>> request.vars = Storage() 145 >>> request.vars.x = 'abc' 146 >>> request.vars.y = ['abc', 'def'] 147 >>> request.vars.getlast('x') 148 'abc' 149 >>> request.vars.getlast('y') 150 'def' 151 >>> request.vars.getlast('z') 152 153 """ 154 value = self.getlist(key) 155 if len(value): 156 return value[-1] 157 return None
158
159 -class StorageList(Storage):
160 """ 161 like Storage but missing elements default to [] instead of None 162 """
163 - def __getattr__(self, key):
164 if key in self: 165 return self[key] 166 else: 167 self[key] = [] 168 return self[key]
169
170 -def load_storage(filename):
171 fp = open(filename, 'rb') 172 try: 173 portalocker.lock(fp, portalocker.LOCK_EX) 174 storage = cPickle.load(fp) 175 portalocker.unlock(fp) 176 finally: 177 fp.close() 178 return Storage(storage)
179 180
181 -def save_storage(storage, filename):
182 fp = open(filename, 'wb') 183 try: 184 portalocker.lock(fp, portalocker.LOCK_EX) 185 cPickle.dump(dict(storage), fp) 186 portalocker.unlock(fp) 187 finally: 188 fp.close()
189 190
191 -class Settings(Storage):
192
193 - def __setattr__(self, key, value):
194 if key != 'lock_keys' and self.get('lock_keys', None)\ 195 and not key in self: 196 raise SyntaxError, 'setting key \'%s\' does not exist' % key 197 if key != 'lock_values' and self.get('lock_values', None): 198 raise SyntaxError, 'setting value cannot be changed: %s' % key 199 self[key] = value
200 201
202 -class Messages(Storage):
203
204 - def __init__(self, T):
205 self['T'] = T
206
207 - def __setattr__(self, key, value):
208 if key != 'lock_keys' and self.get('lock_keys', None)\ 209 and not key in self: 210 raise SyntaxError, 'setting key \'%s\' does not exist' % key 211 if key != 'lock_values' and self.get('lock_values', None): 212 raise SyntaxError, 'setting value cannot be changed: %s' % key 213 self[key] = value
214
215 - def __getattr__(self, key):
216 value = self[key] 217 if isinstance(value, str): 218 return str(self['T'](value)) 219 return value
220 221 if __name__ == '__main__': 222 import doctest 223 doctest.testmod() 224