16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
18 """custom storages for the system source""" |
18 """custom storages for the system source""" |
19 |
19 |
20 import os |
20 import os |
|
21 import sys |
21 from os import unlink, path as osp |
22 from os import unlink, path as osp |
22 from contextlib import contextmanager |
23 from contextlib import contextmanager |
23 |
24 |
24 from yams.schema import role_name |
25 from yams.schema import role_name |
25 |
26 |
110 del session.transaction_data['fs_importing'] |
111 del session.transaction_data['fs_importing'] |
111 |
112 |
112 |
113 |
113 class BytesFileSystemStorage(Storage): |
114 class BytesFileSystemStorage(Storage): |
114 """store Bytes attribute value on the file system""" |
115 """store Bytes attribute value on the file system""" |
115 def __init__(self, defaultdir, fsencoding='utf-8'): |
116 def __init__(self, defaultdir, fsencoding='utf-8', wmode=0444): |
116 if type(defaultdir) is unicode: |
117 if type(defaultdir) is unicode: |
117 defaultdir = defaultdir.encode(fsencoding) |
118 defaultdir = defaultdir.encode(fsencoding) |
118 self.default_directory = defaultdir |
119 self.default_directory = defaultdir |
119 self.fsencoding = fsencoding |
120 self.fsencoding = fsencoding |
|
121 # extra umask to use when creating file |
|
122 # 0444 as in "only allow read bit in permission" |
|
123 self._wmode = wmode |
|
124 |
|
125 def _writecontent(self, path, binary): |
|
126 """write the content of a binary in readonly file |
|
127 |
|
128 As the bfss never alter a create file it does not prevent it to work as |
|
129 intended. This is a beter safe than sorry approach. |
|
130 """ |
|
131 write_flag = os.O_WRONLY | os.O_CREAT | os.O_EXCL |
|
132 if sys.platform == 'win32': |
|
133 write_flag |= os.O_BINARY |
|
134 fd = os.open(path, write_flag, self._wmode) |
|
135 fileobj = os.fdopen(fd, 'wb') |
|
136 binary.to_file(fileobj) |
|
137 fileobj.close() |
|
138 |
120 |
139 |
121 def callback(self, source, session, value): |
140 def callback(self, source, session, value): |
122 """sql generator callback when some attribute with a custom storage is |
141 """sql generator callback when some attribute with a custom storage is |
123 accessed |
142 accessed |
124 """ |
143 """ |
136 else: |
155 else: |
137 binary = entity.cw_edited.pop(attr) |
156 binary = entity.cw_edited.pop(attr) |
138 fpath = self.new_fs_path(entity, attr) |
157 fpath = self.new_fs_path(entity, attr) |
139 # bytes storage used to store file's path |
158 # bytes storage used to store file's path |
140 entity.cw_edited.edited_attribute(attr, Binary(fpath)) |
159 entity.cw_edited.edited_attribute(attr, Binary(fpath)) |
141 binary.to_file(fpath) |
160 self._writecontent(fpath, binary) |
142 AddFileOp.get_instance(entity._cw).add_data(fpath) |
161 AddFileOp.get_instance(entity._cw).add_data(fpath) |
143 return binary |
162 return binary |
144 |
163 |
145 def entity_updated(self, entity, attr): |
164 def entity_updated(self, entity, attr): |
146 """an entity using this storage for attr has been updated""" |
165 """an entity using this storage for attr has been updated""" |
169 else: |
188 else: |
170 # Get filename for it |
189 # Get filename for it |
171 fpath = self.new_fs_path(entity, attr) |
190 fpath = self.new_fs_path(entity, attr) |
172 assert not osp.exists(fpath) |
191 assert not osp.exists(fpath) |
173 # write attribute value on disk |
192 # write attribute value on disk |
174 binary.to_file(fpath) |
193 self._writecontent(fpath, binary) |
175 # Mark the new file as added during the transaction. |
194 # Mark the new file as added during the transaction. |
176 # The file will be removed on rollback |
195 # The file will be removed on rollback |
177 AddFileOp.get_instance(entity._cw).add_data(fpath) |
196 AddFileOp.get_instance(entity._cw).add_data(fpath) |
178 if oldpath != fpath: |
197 if oldpath != fpath: |
179 # register the new location for the file. |
198 # register the new location for the file. |