diff options
| author | P. Christeas <p_christ@hol.gr> | 2010-07-13 23:53:59 +0300 |
|---|---|---|
| committer | P. Christeas <p_christ@hol.gr> | 2010-07-13 23:53:59 +0300 |
| commit | 766fd336d4f8f0e17a05741542bf0a6e440e06bc (patch) | |
| tree | af65a3559e7dc818ac2e74a6dbbf2a3db0128d3a /addons/document/document_storage.py | |
| parent | d3ae0b008347718cec73df4523da0b674e2ba830 (diff) | |
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
Diffstat (limited to 'addons/document/document_storage.py')
| -rw-r--r-- | addons/document/document_storage.py | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py index d3e6921324f..149e779055d 100644 --- a/addons/document/document_storage.py +++ b/addons/document/document_storage.py @@ -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) |
