server/sources/storages.py
changeset 5396 78d92a47a4e5
parent 5219 35d44017c72b
child 5397 cdbf823450aa
equal deleted inserted replaced
5387:aed0c441923a 5396:78d92a47a4e5
     2 from os import unlink, path as osp
     2 from os import unlink, path as osp
     3 
     3 
     4 from yams.schema import role_name
     4 from yams.schema import role_name
     5 
     5 
     6 from cubicweb import Binary
     6 from cubicweb import Binary
     7 from cubicweb.server.hook import Operation
     7 from cubicweb.server import hook
     8 
     8 
     9 def set_attribute_storage(repo, etype, attr, storage):
     9 def set_attribute_storage(repo, etype, attr, storage):
    10     repo.system_source.set_storage(etype, attr, storage)
    10     repo.system_source.set_storage(etype, attr, storage)
    11 
    11 
    12 def unset_attribute_storage(repo, etype, attr):
    12 def unset_attribute_storage(repo, etype, attr):
    97             binary = entity.pop(attr)
    97             binary = entity.pop(attr)
    98             fpath = self.new_fs_path(entity, attr)
    98             fpath = self.new_fs_path(entity, attr)
    99             # bytes storage used to store file's path
    99             # bytes storage used to store file's path
   100             entity[attr] = Binary(fpath)
   100             entity[attr] = Binary(fpath)
   101             file(fpath, 'w').write(binary.getvalue())
   101             file(fpath, 'w').write(binary.getvalue())
   102             AddFileOp(entity._cw, filepath=fpath)
   102             hook.set_operation(entity._cw, 'bfss_added', fpath, AddFileOp)
   103         return binary
   103         return binary
   104 
   104 
   105     def entity_updated(self, entity, attr):
   105     def entity_updated(self, entity, attr):
   106         """an entity using this storage for attr has been updatded"""
   106         """an entity using this storage for attr has been updatded"""
   107         if entity._cw.transaction_data.get('fs_importing'):
   107         if entity._cw.transaction_data.get('fs_importing'):
   108             oldpath = self.current_fs_path(entity, attr)
   108             oldpath = self.current_fs_path(entity, attr)
   109             fpath = entity[attr].getvalue()
   109             fpath = entity[attr].getvalue()
   110             if oldpath != fpath:
   110             if oldpath != fpath:
   111                 DeleteFileOp(entity._cw, filepath=oldpath)
   111                 hook.set_operation(entity._cw, 'bfss_deleted', oldpath,
       
   112                                    DeleteFileOp)
   112             binary = Binary(file(fpath).read())
   113             binary = Binary(file(fpath).read())
   113         else:
   114         else:
   114             binary = entity.pop(attr)
   115             binary = entity.pop(attr)
   115             fpath = self.current_fs_path(entity, attr)
   116             fpath = self.current_fs_path(entity, attr)
   116             UpdateFileOp(entity._cw, filepath=fpath, filedata=binary.getvalue())
   117             UpdateFileOp(entity._cw, filepath=fpath, filedata=binary.getvalue())
   117         return binary
   118         return binary
   118 
   119 
   119     def entity_deleted(self, entity, attr):
   120     def entity_deleted(self, entity, attr):
   120         """an entity using this storage for attr has been deleted"""
   121         """an entity using this storage for attr has been deleted"""
   121         DeleteFileOp(entity._cw, filepath=self.current_fs_path(entity, attr))
   122         fpath = self.current_fs_path(entity, attr)
       
   123         hook.set_operation(entity._cw, 'bfss_deleted', fpath, DeleteFileOp)
   122 
   124 
   123     def new_fs_path(self, entity, attr):
   125     def new_fs_path(self, entity, attr):
   124         # We try to get some hint about how to name the file using attribute's
   126         # We try to get some hint about how to name the file using attribute's
   125         # name metadata, so we use the real file name and extension when
   127         # name metadata, so we use the real file name and extension when
   126         # available. Keeping the extension is useful for example in the case of
   128         # available. Keeping the extension is useful for example in the case of
   147             return self.new_fs_path(entity, attr)
   149             return self.new_fs_path(entity, attr)
   148         return sysource._process_value(rawvalue, cu.description[0],
   150         return sysource._process_value(rawvalue, cu.description[0],
   149                                        binarywrap=str)
   151                                        binarywrap=str)
   150 
   152 
   151 
   153 
   152 class AddFileOp(Operation):
   154 
       
   155 class AddFileOp(hook.Operation):
   153     def rollback_event(self):
   156     def rollback_event(self):
   154         try:
   157         for filepath in self.session.transaction_data.pop('bfss_added'):
   155             unlink(self.filepath)
   158             try:
   156         except:
   159                 unlink(filepath)
   157             pass
   160             except Exception, ex:
       
   161                 self.error('cant remove %s: %s' % (filepath, ex))
   158 
   162 
   159 class DeleteFileOp(Operation):
   163 class DeleteFileOp(hook.Operation):
   160     def commit_event(self):
   164     def commit_event(self):
   161         try:
   165         for filepath in self.session.transaction_data.pop('bfss_deleted'):
   162             unlink(self.filepath)
   166             try:
   163         except:
   167                 unlink(filepath)
   164             pass
   168             except Exception, ex:
       
   169                 self.error('cant remove %s: %s' % (filepath, ex))
   165 
   170 
   166 class UpdateFileOp(Operation):
   171 class UpdateFileOp(hook.Operation):
   167     def precommit_event(self):
   172     def precommit_event(self):
   168         try:
   173         try:
   169             file(self.filepath, 'w').write(self.filedata)
   174             file(self.filepath, 'w').write(self.filedata)
   170         except Exception, ex:
   175         except Exception, ex:
   171             self.exception(str(ex))
   176             self.exception(str(ex))