Document: fix realstore with open/close, rename.
Put the path computation of realstore in a helper function, and use that in all places where a file is opened/created/moved. bzr revid: p_christ@hol.gr-20100713205359-jn0bo6fcw9lwdyge
This commit is contained in:
@@ -157,7 +157,10 @@ class document_file(osv.osv):
|
||||
return False
|
||||
if not self._check_duplication(cr, uid, vals, ids, 'write'):
|
||||
raise osv.except_osv(_('ValidateError'), _('File name must be unique!'))
|
||||
if ('parent_id' in vals) or ('name' in vals):
|
||||
|
||||
# if nodes call this write(), they must skip the code below
|
||||
from_node = context and context.get('__from_node', False)
|
||||
if (('parent_id' in vals) or ('name' in vals)) and not from_node:
|
||||
# perhaps this file is renaming or changing directory
|
||||
nctx = nodes.get_node_context(cr,uid,context={})
|
||||
dirobj = self.pool.get('document.directory')
|
||||
|
||||
@@ -154,7 +154,6 @@ class nodefd_file(nodes.node_descriptor):
|
||||
" WHERE id = %s",
|
||||
(fsize, par.file_id))
|
||||
par.content_length = fsize
|
||||
par.content_type = mime
|
||||
cr.commit()
|
||||
cr.close()
|
||||
except Exception:
|
||||
@@ -367,6 +366,37 @@ class document_storage(osv.osv):
|
||||
filename = random_name()
|
||||
return os.path.join(flag, filename)
|
||||
|
||||
def __prepare_realpath(self, cr, file_node, ira, store_path, do_create=True):
|
||||
""" Cleanup path for realstore, create dirs if needed
|
||||
|
||||
@param file_node the node
|
||||
@param ira ir.attachment browse of the file_node
|
||||
@param store_path the path of the parent storage object, list
|
||||
@param do_create create the directories, if needed
|
||||
|
||||
@return tuple(path "/var/filestore/real/dir/", npath ['dir','fname.ext'] )
|
||||
"""
|
||||
file_node.fix_ppath(cr, ira)
|
||||
npath = file_node.full_path() or []
|
||||
# npath may contain empty elements, for root directory etc.
|
||||
npath = filter(lambda x: x is not None, npath)
|
||||
|
||||
# if self._debug:
|
||||
# self._doclog.debug('Npath: %s', npath)
|
||||
for n in npath:
|
||||
if n == '..':
|
||||
raise ValueError("Invalid '..' element in path")
|
||||
for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?',):
|
||||
if ch in n:
|
||||
raise ValueError("Invalid char %s in path %s" %(ch, n))
|
||||
dpath = [store_path,]
|
||||
dpath += npath[:-1]
|
||||
path = os.path.join(*dpath)
|
||||
if not os.path.isdir(path):
|
||||
self._doclog.debug("Create dirs: %s", path)
|
||||
os.makedirs(path)
|
||||
return path, npath
|
||||
|
||||
def get_data(self, cr, uid, id, file_node, context=None, fil_obj=None):
|
||||
""" retrieve the contents of some file_node having storage_id = id
|
||||
optionally, fil_obj could point to the browse object of the file
|
||||
@@ -416,15 +446,15 @@ class document_storage(osv.osv):
|
||||
return nodefd_db64(file_node, ira_browse=ira, mode=mode)
|
||||
|
||||
elif boo.type == 'realstore':
|
||||
if not ira.store_fname:
|
||||
# On a migrated db, some files may have the wrong storage type
|
||||
# try to fix their directory.
|
||||
if ira.file_size:
|
||||
self._doclog.warning("ir.attachment #%d does not have a filename, trying the name." %ira.id)
|
||||
sfname = ira.name
|
||||
fpath = os.path.join(boo.path,ira.store_fname or ira.name)
|
||||
if (not os.path.exists(fpath)) and mode in ('r','r+'):
|
||||
path, npath = self.__prepare_realpath(cr, file_node, ira, boo.path,
|
||||
do_create = (mode[1] in ('w','a')) )
|
||||
fpath = os.path.join(path, npath[-1])
|
||||
if (not os.path.exists(fpath)) and mode[1] == 'r':
|
||||
raise IOError("File not found: %s" % fpath)
|
||||
elif mode[1] in ('w', 'a') and not ira.store_fname:
|
||||
store_fname = os.path.join(*npath)
|
||||
cr.execute('UPDATE ir_attachment SET store_fname = %s WHERE id = %s',
|
||||
(store_fname, ira.id))
|
||||
return nodefd_file(file_node, path=fpath, mode=mode)
|
||||
|
||||
elif boo.type == 'virtual':
|
||||
@@ -529,21 +559,7 @@ class document_storage(osv.osv):
|
||||
(out, file_node.file_id))
|
||||
elif boo.type == 'realstore':
|
||||
try:
|
||||
file_node.fix_ppath(cr, ira)
|
||||
npath = file_node.full_path() or []
|
||||
# npath may contain empty elements, for root directory etc.
|
||||
for i, n in enumerate(npath):
|
||||
if n == None:
|
||||
del npath[i]
|
||||
for n in npath:
|
||||
for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?', '..'):
|
||||
if ch in n:
|
||||
raise ValueError("Invalid char %s in path %s" %(ch, n))
|
||||
dpath = [boo.path,]
|
||||
dpath += npath[:-1]
|
||||
path = os.path.join(*dpath)
|
||||
if not os.path.isdir(path):
|
||||
os.makedirs(path)
|
||||
path, npath = self.__prepare_realpath(cr, file_node, ira, boo.path, do_create=True)
|
||||
fname = os.path.join(path, npath[-1])
|
||||
fp = file(fname,'wb')
|
||||
fp.write(data)
|
||||
@@ -644,25 +660,23 @@ class document_storage(osv.osv):
|
||||
# nothing to do for a rename, allow to change the db field
|
||||
return { 'name': new_name, 'datas_fname': new_name }
|
||||
elif sbro.type == 'realstore':
|
||||
fname = fil_bo.store_fname
|
||||
ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context)
|
||||
|
||||
path, npath = self.__prepare_realpath(cr, file_node, ira, sbro.path, do_create=False)
|
||||
fname = ira.store_fname
|
||||
|
||||
if not fname:
|
||||
return ValueError("Tried to rename a non-stored file")
|
||||
path = storage_bo.path
|
||||
oldpath = os.path.join(path, fname)
|
||||
|
||||
for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?', '..'):
|
||||
if ch in new_name:
|
||||
raise ValueError("Invalid char %s in name %s" %(ch, new_name))
|
||||
|
||||
file_node.fix_ppath(cr, ira)
|
||||
npath = file_node.full_path() or []
|
||||
dpath = [path,]
|
||||
dpath.extend(npath[:-1])
|
||||
dpath.append(new_name)
|
||||
newpath = os.path.join(*dpath)
|
||||
# print "old, new paths:", oldpath, newpath
|
||||
self._doclog.warning("Trying to rename a non-stored file")
|
||||
if fname != os.path.join(*npath):
|
||||
self._doclog.warning("inconsistency in realstore: %s != %s" , fname, repr(npath))
|
||||
|
||||
oldpath = os.path.join(path, npath[-1])
|
||||
newpath = os.path.join(path, new_name)
|
||||
os.rename(oldpath, newpath)
|
||||
return { 'name': new_name, 'datas_fname': new_name, 'store_fname': new_name }
|
||||
store_path = npath[:-1]
|
||||
store_path.append(new_name)
|
||||
store_fname = os.path.join(*store_path)
|
||||
return { 'name': new_name, 'datas_fname': new_name, 'store_fname': store_fname }
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
|
||||
|
||||
@@ -631,7 +631,9 @@ class node_dir(node_database):
|
||||
if not in_write:
|
||||
# We have to update the data ourselves
|
||||
if ret:
|
||||
dir_obj.write(cr, self.context.uid, [self.dir_id,], ret, self.context.context)
|
||||
ctx = self.context.context.copy()
|
||||
ctx['__from_node'] = True
|
||||
dir_obj.write(cr, self.context.uid, [self.dir_id,], ret, ctx)
|
||||
ret = True
|
||||
|
||||
return ret
|
||||
@@ -1196,7 +1198,9 @@ class node_file(node_class):
|
||||
if not in_write:
|
||||
# We have to update the data ourselves
|
||||
if ret:
|
||||
doc_obj.write(cr, self.context.uid, [self.file_id,], ret, self.context.context)
|
||||
ctx = self.context.context.copy()
|
||||
ctx['__from_node'] = True
|
||||
doc_obj.write(cr, self.context.uid, [self.file_id,], ret, ctx )
|
||||
ret = True
|
||||
|
||||
return ret
|
||||
|
||||
Reference in New Issue
Block a user