1
|
import os
|
2
|
import cPickle
|
3
|
|
4
|
from quixote import get_publisher
|
5
|
|
6
|
def lax_int(s):
|
7
|
try:
|
8
|
return int(s)
|
9
|
except ValueError:
|
10
|
return -1
|
11
|
|
12
|
def fix_key(k):
|
13
|
# insure key can be inserted in filesystem
|
14
|
if not k: return k
|
15
|
return str(k).replace('/', '-')
|
16
|
|
17
|
|
18
|
class StorableObject(object):
|
19
|
def __init__(self):
|
20
|
if get_publisher():
|
21
|
self.id = self.get_new_id()
|
22
|
|
23
|
def get_table_name(cls):
|
24
|
return cls._names
|
25
|
get_table_name = classmethod(get_table_name)
|
26
|
|
27
|
def get_objects_dir(cls):
|
28
|
return os.path.join(get_publisher().app_dir, cls.get_table_name())
|
29
|
get_objects_dir = classmethod(get_objects_dir)
|
30
|
|
31
|
def keys(cls):
|
32
|
if not os.path.exists(cls.get_objects_dir()):
|
33
|
return []
|
34
|
return [fix_key(x) for x in os.listdir(cls.get_objects_dir())]
|
35
|
keys = classmethod(keys)
|
36
|
|
37
|
def values(cls):
|
38
|
return [cls.get(x) for x in cls.keys()]
|
39
|
values = classmethod(values)
|
40
|
|
41
|
def items(cls):
|
42
|
return [(x, cls.get(x)) for x in cls.keys()]
|
43
|
items = classmethod(items)
|
44
|
|
45
|
def count(cls):
|
46
|
return len(cls.keys())
|
47
|
count = classmethod(count)
|
48
|
|
49
|
def select(cls, clause = None, order_by = None):
|
50
|
objects = [cls.get(k) for k in cls.keys()]
|
51
|
if clause:
|
52
|
objects = [x for x in objects if clause(x)]
|
53
|
if order_by:
|
54
|
order_by = str(order_by)
|
55
|
if order_by[0] == '-':
|
56
|
reverse = True
|
57
|
order_by = order_by[1:]
|
58
|
else:
|
59
|
reverse = False
|
60
|
objects.sort(lambda x,y: cmp(getattr(x, order_by), getattr(y, order_by)))
|
61
|
if reverse:
|
62
|
objects.reverse()
|
63
|
return objects
|
64
|
select = classmethod(select)
|
65
|
|
66
|
def has_key(cls, id):
|
67
|
return fix_key(id) in cls.keys()
|
68
|
has_key = classmethod(has_key)
|
69
|
|
70
|
def get_new_id(cls):
|
71
|
keys = cls.keys()
|
72
|
if not keys:
|
73
|
id = 1
|
74
|
else:
|
75
|
id = max([lax_int(x) for x in keys]) + 1
|
76
|
if id == 0:
|
77
|
id = len(keys)+1
|
78
|
return id
|
79
|
get_new_id = classmethod(get_new_id)
|
80
|
|
81
|
def get(cls, id):
|
82
|
if id is None:
|
83
|
raise KeyError()
|
84
|
try:
|
85
|
s = file(os.path.join(cls.get_objects_dir(), fix_key(id))).read()
|
86
|
except IOError:
|
87
|
raise KeyError()
|
88
|
try:
|
89
|
o = cPickle.loads(s)
|
90
|
except EOFError:
|
91
|
raise KeyError()
|
92
|
o._names = cls._names
|
93
|
if hasattr(cls, 'migrate'):
|
94
|
o.migrate()
|
95
|
return o
|
96
|
get = classmethod(get)
|
97
|
|
98
|
def store(self):
|
99
|
if not os.path.exists(self.get_objects_dir()):
|
100
|
os.mkdir(self.get_objects_dir())
|
101
|
s = cPickle.dumps(self)
|
102
|
file(os.path.join(self.get_objects_dir(), fix_key(self.id)), 'w').write(s)
|
103
|
|
104
|
def volatile(cls):
|
105
|
o = cls()
|
106
|
o.id = None
|
107
|
return o
|
108
|
volatile = classmethod(volatile)
|
109
|
|
110
|
def remove_object(cls, id):
|
111
|
os.unlink(os.path.join(cls.get_objects_dir(), fix_key(id)))
|
112
|
remove_object = classmethod(remove_object)
|
113
|
|
114
|
def remove_self(self):
|
115
|
os.unlink(os.path.join(self.get_objects_dir(), fix_key(self.id)))
|