1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Framework object disk serializer module}.
10
11 This module contains Entropy Python object serialization functions and
12 disk dumpers.
13
14 Serialized objects are stored to disk with proper permissions by default
15 into path given by entropy.const's etpConst['dumpstoragedir'].
16
17 Permissions are set using entropy.const's const_setup_perms and
18 const_setup_file functions.
19
20 Objects are serialized using Python's cPickle/pickle modules, thus
21 they must be "pickable". Please read Python Library reference for
22 more information.
23
24 """
25
26 from __future__ import with_statement
27 import os
28 from entropy.const import etpConst, const_setup_perms, const_setup_file
29 try:
30 import cPickle as pickle
31 except ImportError:
32 import pickle
33
34 D_EXT = etpConst['cachedumpext']
35 D_DIR = etpConst['dumpstoragedir']
36 E_GID = etpConst['entropygid']
37 if E_GID == None:
38 E_GID = 0
39
40
41 -def dumpobj(name, my_object, complete_path = False, ignore_exceptions = True):
42 """
43 Dump pickable object to file
44
45 @param name: name of the object
46 @type name: string
47 @param my_object: object to dump
48 @type my_object: any Python "pickable" object
49 @keyword complete_path: consider "name" argument as
50 a complete path (this overrides the default dump
51 path given by etpConst['dumpstoragedir'])
52 @type complete_path: bool
53 @keyword ignore_exceptions: ignore any possible exception
54 (EOFError, IOError, OSError,)
55 @type ignore_exceptions: bool
56 @return: None
57 @rtype: None
58 @raise EOFError: could be caused by pickle.dump, ignored if
59 ignore_exceptions is True
60 @raise IOError: could be caused by pickle.dump, ignored if
61 ignore_exceptions is True
62 @raise OSError: could be caused by pickle.dump, ignored if
63 ignore_exceptions is True
64 """
65 while 1:
66 try:
67 if complete_path:
68 dmpfile = name
69 else:
70 dump_path = os.path.join(D_DIR, name)
71 dump_dir = os.path.dirname(dump_path)
72
73 my_dump_dir = dump_dir
74 d_paths = []
75 while not os.path.isdir(my_dump_dir):
76 d_paths.append(my_dump_dir)
77 my_dump_dir = os.path.dirname(my_dump_dir)
78 if d_paths:
79 d_paths = sorted(d_paths)
80 for d_path in d_paths:
81 os.mkdir(d_path)
82 const_setup_file(d_path, E_GID, 0775)
83
84 dmpfile = dump_path+D_EXT
85 with open(dmpfile,"wb") as dmp_f:
86 pickle.dump(my_object, dmp_f)
87 dmp_f.flush()
88 const_setup_file(dmpfile, E_GID, 0664)
89 except RuntimeError:
90 try:
91 os.remove(dmpfile)
92 except OSError:
93 pass
94 except (EOFError, IOError, OSError):
95 if not ignore_exceptions:
96 raise
97 break
98
100 """
101 Serialize object to ser_f (file)
102
103 @param myobj: Python object to serialize
104 @type myobj: any Python picklable object
105 @param ser_f: file object to write to
106 @type ser_f: file object
107 @keyword do_seek: move file cursor back to the beginning
108 of ser_f
109 @type do_seek: bool
110 @return: file object where data has been written
111 @rtype: file object
112 @raise RuntimeError: caused by pickle.dump in case of
113 system errors
114 @raise EOFError: caused by pickle.dump in case of
115 race conditions on multi-processing or multi-threading
116 @raise IOError: caused by pickle.dump in case of
117 race conditions on multi-processing or multi-threading
118 @raise pickle.PicklingError: when object cannot be recreated
119 """
120 pickle.dump(myobj, ser_f)
121 ser_f.flush()
122 if do_seek:
123 ser_f.seek(0)
124 return ser_f
125
127 """
128 Unserialize file to object (file)
129
130 @param serial_f: file object which data will be read from
131 @type serial_f: file object
132 @return: rebuilt object
133 @rtype: any Python pickable object
134 @raise pickle.UnpicklingError: when object cannot be recreated
135 """
136 return pickle.load(serial_f)
137
139 """
140 Unserialize pickle string to object
141
142 @param mystring: data stream in string form to reconstruct
143 @type mystring: string
144 @return: reconstructed object
145 @rtype: any Python pickable object
146 @raise pickle.UnpicklingError: when object cannot be recreated
147 """
148 return pickle.loads(mystring)
149
151 """
152 Serialize object to string
153
154 @param myobj: object to serialize
155 @type myobj: any Python picklable object
156 @return: serialized string
157 @rtype: string
158 @raise pickle.PicklingError: when object cannot be recreated
159 """
160 return pickle.dumps(myobj)
161
162 -def loadobj(name, complete_path = False):
163 """
164 Load object from a file
165 @param name: name of the object to load
166 @type name: string
167 @keyword complete_path: determine whether name argument
168 is a complete disk path to serialized object
169 @type complete_path: bool
170 @return: object or None
171 @rtype: any Python pickable object or None
172 """
173 while 1:
174 if complete_path:
175 dmpfile = name
176 else:
177 dump_path = os.path.join(D_DIR, name)
178
179
180 dmpfile = dump_path+D_EXT
181 if os.path.isfile(dmpfile) and os.access(dmpfile, os.R_OK):
182 try:
183 with open(dmpfile,"rb") as dmp_f:
184 obj = None
185 try:
186 obj = pickle.load(dmp_f)
187 except (ValueError, EOFError, IOError,
188 OSError, pickle.UnpicklingError, TypeError,
189 AttributeError,):
190 pass
191 return obj
192 except (IOError, OSError,):
193 pass
194 break
195
197 """
198 Get dumped object mtime
199
200 @param name: object name
201 @type name: string
202 @return: mtime of the file containing the serialized object or 0
203 if not found
204 @rtype: int
205 """
206 mtime = 0
207 dump_path = os.path.join(D_DIR, name+D_EXT)
208 if os.path.isfile(dump_path) and os.access(dump_path, os.R_OK):
209 mtime = os.path.getmtime(dump_path)
210 return int(mtime)
211
213 """
214 Remove cached object referenced by its object name
215
216 @param name: object name
217 @type name: string
218 @return: bool representing whether object has been
219 removed or not
220 @rtype: bool
221 @raise OSError: in case of troubles with os.remove()
222 """
223 filepath = D_DIR+"/"+name+D_EXT
224 if os.path.isfile(filepath) and os.access(filepath, os.W_OK):
225 os.remove(filepath)
226 return True
227 return False
228