diff options
| author | P. Christeas <p_christ@hol.gr> | 2010-07-13 23:53:24 +0300 |
|---|---|---|
| committer | P. Christeas <p_christ@hol.gr> | 2010-07-13 23:53:24 +0300 |
| commit | 31d45716ca29df2809d98d6aed3e9a5eb64d20d9 (patch) | |
| tree | 9c81908318a2a2fe28ae5bb8f1d605f6bddb0659 /addons/document/document_storage.py | |
| parent | bbbf42c6ba0f5aa05a53c5b31f909432cbd5f708 (diff) | |
Document storage: fix opening/closing filestore descriptors
At open, if a file is created, a new store_fname has to be generated.
At close, the size of the file has to be updated at all write modes.
bzr revid: p_christ@hol.gr-20100713205324-q6g2tvem2qem6ftg
Diffstat (limited to 'addons/document/document_storage.py')
| -rw-r--r-- | addons/document/document_storage.py | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py index 4d7c7d10eda..d3e6921324f 100644 --- a/addons/document/document_storage.py +++ b/addons/document/document_storage.py @@ -98,10 +98,9 @@ class nodefd_file(nodes.node_descriptor): def __init__(self, parent, path, mode): nodes.node_descriptor.__init__(self, parent) self.__file = open(path, mode) - if mode in ('w', 'w+', 'r+'): - self._need_index = True - else: - self._need_index = False + if mode.endswith('b'): + mode = mode[:-1] + self.mode = mode for attr in ('closed', 'read', 'write', 'seek', 'tell'): setattr(self,attr, getattr(self.__file, attr)) @@ -110,8 +109,8 @@ class nodefd_file(nodes.node_descriptor): # TODO: locking in init, close() fname = self.__file.name self.__file.close() - - if self._need_index: + + if self.mode in ('w', 'w+', 'r+'): par = self._get_parent() cr = pooler.get_db(par.context.dbname).cursor() icont = '' @@ -133,14 +132,34 @@ class nodefd_file(nodes.node_descriptor): icont_u = '' try: - cr.execute('UPDATE ir_attachment SET index_content = %s, file_type = %s WHERE id = %s', - (icont_u, mime, par.file_id)) - par.content_length = filesize + fsize = os.stat(fname).st_size + cr.execute("UPDATE ir_attachment " \ + " SET index_content = %s, file_type = %s, " \ + " file_size = %s " \ + " WHERE id = %s", + (icont_u, mime, fsize, par.file_id)) + par.content_length = fsize par.content_type = mime cr.commit() cr.close() except Exception: - logging.getLogger('document.storage').debug('Cannot save file indexed content:', exc_info=True) + logging.getLogger('document.storage').warning('Cannot save file indexed content:', exc_info=True) + + elif self.mode in ('a', 'a+' ): + try: + par = self._get_parent() + cr = pooler.get_db(par.context.dbname).cursor() + fsize = os.stat(fname).st_size + cr.execute("UPDATE ir_attachment SET file_size = %s " \ + " WHERE id = %s", + (fsize, par.file_id)) + par.content_length = fsize + par.content_type = mime + cr.commit() + cr.close() + except Exception: + logging.getLogger('document.storage').warning('Cannot save file appended content:', exc_info=True) + class nodefd_db(StringIO, nodes.node_descriptor): @@ -336,6 +355,18 @@ class document_storage(osv.osv): ('path_uniq', 'UNIQUE(type,path)', "The storage path must be unique!") ] + def __get_random_fname(self, path): + flag = None + # This can be improved + if os.path.isdir(path): + for dirs in os.listdir(path): + if os.path.isdir(os.path.join(path, dirs)) and len(os.listdir(os.path.join(path, dirs))) < 4000: + flag = dirs + break + flag = flag or create_directory(path) + filename = random_name() + return os.path.join(flag, filename) + 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 @@ -364,10 +395,17 @@ class document_storage(osv.osv): 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, but is at filestore, fix it!" % ira.id) - raise IOError(errno.ENOENT, 'No file can be located') - fpath = os.path.join(boo.path, ira.store_fname) + if mode in ('r','r+'): + if ira.file_size: + self._doclog.warning( "ir.attachment #%d does not have a filename, but is at filestore, fix it!" % ira.id) + raise IOError(errno.ENOENT, 'No file can be located') + else: + store_fname = self.__get_random_fname(boo.path) + cr.execute('UPDATE ir_attachment SET store_fname = %s WHERE id = %s', + (store_fname, ira.id)) + fpath = os.path.join(boo.path, store_fname) + else: + fpath = os.path.join(boo.path, ira.store_fname) return nodefd_file(file_node, path=fpath, mode=mode) elif boo.type == 'db': @@ -385,7 +423,7 @@ class document_storage(osv.osv): 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): + if (not os.path.exists(fpath)) and mode in ('r','r+'): raise IOError("File not found: %s" % fpath) return nodefd_file(file_node, path=fpath, mode=mode) @@ -464,23 +502,14 @@ class document_storage(osv.osv): if boo.type == 'filestore': path = boo.path try: - flag = None - # This can be improved - if os.path.isdir(path): - for dirs in os.listdir(path): - if os.path.isdir(os.path.join(path, dirs)) and len(os.listdir(os.path.join(path, dirs))) < 4000: - flag = dirs - break - flag = flag or create_directory(path) - filename = random_name() - fname = os.path.join(path, flag, filename) + store_fname = self.__get_random_fname(path) + fname = os.path.join(path, store_fname) fp = file(fname, 'wb') fp.write(data) fp.close() self._doclog.debug( "Saved data to %s" % fname) filesize = len(data) # os.stat(fname).st_size - store_fname = os.path.join(flag, filename) - + # TODO Here, an old file would be left hanging. except Exception, e: |
