diff options
| author | Harry (Open ERP) <hmo@tinyerp.com> | 2009-12-08 19:00:41 +0530 |
|---|---|---|
| committer | Harry (Open ERP) <hmo@tinyerp.com> | 2009-12-08 19:00:41 +0530 |
| commit | 307898c2a8152de4dabdce9a90a37f1412d74d80 (patch) | |
| tree | 7c5d0878c745d40914016502316b063ef35c6b3e /addons/document | |
| parent | 84898328030e9172ce759067fe28a91d7210a49f (diff) | |
[FIX] document: fixed problem on mkdir, remove, create file, rename
bzr revid: hmo@tinyerp.com-20091208133041-ikpo3by8r8xbrthb
Diffstat (limited to 'addons/document')
| -rw-r--r-- | addons/document/directory_content.py | 20 | ||||
| -rw-r--r-- | addons/document/document_directory.py | 6 | ||||
| -rw-r--r-- | addons/document/document_storage.py | 11 | ||||
| -rw-r--r-- | addons/document/ftpserver/abstracted_fs.py | 286 | ||||
| -rw-r--r-- | addons/document/nodes.py | 19 |
5 files changed, 195 insertions, 147 deletions
diff --git a/addons/document/directory_content.py b/addons/document/directory_content.py index dbd801d6be0..a43b5730627 100644 --- a/addons/document/directory_content.py +++ b/addons/document/directory_content.py @@ -24,8 +24,10 @@ from osv import osv, fields from osv.orm import except_orm import urlparse +import netsvc import os import nodes +import StringIO class document_directory_content_type(osv.osv): _name = 'document.directory.content.type' @@ -71,17 +73,16 @@ class document_directory_content(osv.osv): """ # TODO: respect the context! - if content.include_name and not node.object2: + model = node.res_model + if content.include_name and not model: return False res2 = [] tname = '' if content.include_name: - content_name = node.object2.name - obj = pool.get(node.object.ressource_type_id.model) - name_for = obj._name.split('.')[-1] - if content_name and content_name.find(name_for) == 0 : - content_name = content_name.replace(name_for,'') + content_name = node.displayname or '' + obj = node.context._dirobj.pool.get(model) + if content_name: tname = (content.prefix or '') + content_name + (content.suffix or '') + (content.extension or '') else: tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '') @@ -101,12 +102,13 @@ class document_directory_content(osv.osv): if node.extension != '.pdf': raise Exception("Invalid content: %s" % node.extension) return True + def process_read(self, cr, uid, node): if node.extension != '.pdf': raise Exception("Invalid content: %s" % node.extension) - report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.content.report_id.id) - srv = netsvc.LocalService('report.'+report.report_name) - pdf,pdftype = srv.create(cr, uid, [node.object.id], {}, {}) + report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.report_id) + srv = netsvc.Service._services['report.'+report.report_name] + pdf,pdftype = srv.create(cr, uid, [node.context.context['res_id']], {}, {}) s = StringIO.StringIO(pdf) s.name = node return s diff --git a/addons/document/document_directory.py b/addons/document/document_directory.py index 95e4d438b76..1f95fd6a61a 100644 --- a/addons/document/document_directory.py +++ b/addons/document/document_directory.py @@ -176,9 +176,9 @@ class document_directory(osv.osv): did = root_id duri = uri path = [] - context = ncontext.context - while len(duri): - nid = self.search(cr,uid,[('parent_id','=',did),('name','=',duri[0]),('type','=','directory')], context=context) + context = ncontext.context + while len(duri): + nid = self.search(cr,uid,[('parent_id','=',did),('name','=',duri[0]),('type','=','directory')], context=context) if not nid: break if len(nid)>1: diff --git a/addons/document/document_storage.py b/addons/document/document_storage.py index 488a5ee7e6c..54e4ad3f9cf 100644 --- a/addons/document/document_storage.py +++ b/addons/document/document_storage.py @@ -190,11 +190,12 @@ class document_storage(osv.osv): path = boo.path try: flag = None - # This can be improved - 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 + # 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) diff --git a/addons/document/ftpserver/abstracted_fs.py b/addons/document/ftpserver/abstracted_fs.py index d795110d4ea..11fd56f976e 100644 --- a/addons/document/ftpserver/abstracted_fs.py +++ b/addons/document/ftpserver/abstracted_fs.py @@ -13,6 +13,7 @@ import netsvc import os from service import security from osv import osv +from document.nodes import node_res_dir, node_res_obj import stat def log(message): @@ -202,18 +203,13 @@ class abstracted_fs: # Ok def fs2ftp(self, node): - res = '/' + res='/' if node: - path = node.path - print '**********', path - if isinstance(path,list): - path = '/'.join(path) - res = os.path.normpath(path) + res=os.path.normpath(''.join(node.full_path())) res = res.replace("\\", "/") while res[:2] == '//': res = res[1:] - if len(node.path): - res = '/' + node.path[0] + '/' + _to_decode(res) + res='/' + node.context.dbname + '/' + _to_decode(res) #res = node and ('/' + node.cr.dbname + '/' + _to_decode(self.ftpnorm(node.path))) or '/' return res @@ -235,16 +231,16 @@ class abstracted_fs: # Ok def create(self, node, objname, mode): - objname=_to_unicode(objname) - cr = node.cr - uid = node.uid - pool = pooler.get_pool(cr.dbname) - child = node.child(objname) + objname = _to_unicode(objname) + uid = node.context.uid + pool = pooler.get_pool(node.context.dbname) + cr = pooler.get_db(node.context.dbname).cursor() + child = node.child(cr, objname) if child: if child.type in ('collection','database'): raise OSError(1, 'Operation not permited.') - if child.type=='content': - s = content_wrapper(cr.dbname, uid, pool, child) + if child.type == 'content': + s = content_wrapper(node.context.dbname, uid, pool, child) return s try: fobj = pool.get('ir.attachment') @@ -252,29 +248,34 @@ class abstracted_fs: # TODO: test if already exist and modify in this case if node.type=file ### checked already exits - object2=node and node.object2 or False - object=node and node.object or False - cid=False - - where=[('name','=',objname)] + object2 = False + if isinstance(node, node_res_obj): + object2 = node and pool.get(node.context.context['res_model']).browse(cr, uid, node.context.context['res_id']) or False + + cid = False + object = node.context._dirobj.browse(cr, uid, node.dir_id) + where = [('name','=',objname)] if object and (object.type in ('directory')) or object2: where.append(('parent_id','=',object.id)) else: where.append(('parent_id','=',False)) if object2: - where +=[('res_id','=',object2.id),('res_model','=',object2._name)] + where += [('res_id','=',object2.id),('res_model','=',object2._name)] cids = fobj.search(cr, uid,where) if len(cids): - cid=cids[0] + cid = cids[0] if not cid: val = { 'name': objname, 'datas_fname': objname, + 'parent_id' : node.dir_id, 'datas': '', 'file_size': 0L, 'file_type': ext, + 'store_method' : (object.storage_id.type == 'filestore' and 'fs')\ + or (object.storage_id.type == 'db' and 'db') } if object and (object.type in ('directory')) or not object2: val['parent_id']= object and object.id or False @@ -292,9 +293,9 @@ class abstracted_fs: cid = fobj.create(cr, uid, val, context={}) cr.commit() - s = file_wrapper('', cid, cr.dbname, uid, ) + s = file_wrapper('', cid, node.context.dbname, uid, ) return s - except Exception,e: + except Exception,e: log(e) raise OSError(1, 'Operation not permited.') @@ -304,16 +305,23 @@ class abstracted_fs: raise OSError(1, 'Operation not permited.') # Reading operation if node.type=='file': + cr = pooler.get_db(node.context.dbname).cursor() + uid = node.context.uid if not self.isfile(node): raise OSError(1, 'Operation not permited.') - s = StringIO.StringIO(base64.decodestring(node.object.datas or '')) + fobj = node.context._dirobj.pool.get('ir.attachment').browse(cr, uid, node.file_id, context=node.context.context) + if fobj.store_method and fobj.store_method== 'fs' : + s = StringIO.StringIO(node.get_data(cr, fobj)) + else: + s = StringIO.StringIO(base64.decodestring(fobj.db_datas or '')) s.name = node return s elif node.type=='content': - cr = node.cr - uid = node.uid - pool = pooler.get_pool(cr.dbname) - return getattr(pool.get('document.directory.content'), 'process_read_'+node.content.extension[1:])(cr, uid, node) +# cr = node.cr + uid = node.context.uid + cr = pooler.get_db(node.context.dbname).cursor() + pool = pooler.get_pool(node.context.dbname) + return getattr(pool.get('document.directory.content'), 'process_read')(cr, uid, node) else: raise OSError(1, 'Operation not permited.') @@ -344,7 +352,7 @@ class abstracted_fs: if dir: cr = dir.cr uid = dir.uid - pool = pooler.get_pool(cr.dbname) + pool = pooler.get_pool(node.context.dbname) object=dir and dir.object or False object2=dir and dir.object2 or False res=pool.get('ir.attachment').search(cr,uid,[('name','like',prefix),('parent_id','=',object and object.type in ('directory','ressource') and object.id or False),('res_id','=',object2 and object2.id or False),('res_model','=',object2 and object2._name or False)]) @@ -359,8 +367,8 @@ class abstracted_fs: # Ok def chdir(self, path): if not path: - self.cwd='/' - return None + self.cwd = '/' + return None if path.type in ('collection','database'): self.cwd = self.fs2ftp(path) else: @@ -369,31 +377,36 @@ class abstracted_fs: # Ok def mkdir(self, node, basename): """Create the specified directory.""" + cr = False if not node: raise OSError(1, 'Operation not permited.') try: - basename=_to_unicode(basename) - object2=node and node.object2 or False - object=node and node.object or False - cr = node.cr - uid = node.uid - pool = pooler.get_pool(cr.dbname) - if node.object and (node.object.type=='ressource') and not node.object2: + basename =_to_unicode(basename) + cr = pooler.get_db(node.context.dbname).cursor() + uid = node.context.uid + pool = pooler.get_pool(node.context.dbname) + object2 = False + if isinstance(node, node_res_obj): + object2 = node and pool.get(node.context.context['res_model']).browse(cr, uid, node.context.context['res_id']) or False + obj = node.context._dirobj.browse(cr, uid, node.dir_id) + if obj and (obj.type == 'ressource') and not object2: raise OSError(1, 'Operation not permited.') val = { 'name': basename, - 'ressource_parent_type_id': object and object.ressource_type_id.id or False, + 'ressource_parent_type_id': obj and obj.ressource_type_id.id or False, 'ressource_id': object2 and object2.id or False } - if (object and (object.type in ('directory'))) or not object2: - val['parent_id'] = object and object.id or False + #if (obj and (obj.type in ('directory'))) or not object2: + # val['parent_id'] = obj and obj.id or False + val['parent_id'] = node.dir_id # Check if it alreayd exists ! pool.get('document.directory').create(cr, uid, val) - cr.commit() + cr.commit() except Exception,e: log(e) raise OSError(1, 'Operation not permited.') - + finally: + if cr: cr.close() # Ok def close_cr(self, data): @@ -421,8 +434,9 @@ class abstracted_fs: # Ok def listdir(self, path): """List the content of a directory.""" - class false_node: - object = None + class false_node(object): + write_date = None + create_date = None type = 'database' def __init__(self, db): self.path = '/'+db @@ -434,55 +448,83 @@ class abstracted_fs: uid = security.login(db, self.username, self.password) if uid: result.append(false_node(db)) - except osv.except_osv: + except osv.except_osv: pass return result - return path.children() + cr = pooler.get_db(path.context.dbname).cursor() + return path.children(cr) # Ok def rmdir(self, node): """Remove the specified directory.""" - cr = node.cr - uid = node.uid - pool = pooler.get_pool(cr.dbname) - object2=node and node.object2 or False - object=node and node.object or False - if object._table_name=='document.directory': - if node.children(): + assert node + cr = pooler.get_db(node.context.dbname).cursor() + uid = node.context.uid + pool = pooler.get_pool(node.context.dbname) + object = node.context._dirobj.browse(cr, uid, node.dir_id) + if not object: + raise OSError(2, 'Not such file or directory.') + if object._table_name == 'document.directory': + if node.children(cr): raise OSError(39, 'Directory not empty.') res = pool.get('document.directory').unlink(cr, uid, [object.id]) else: - raise OSError(39, 'Directory not empty.') + raise OSError(1, 'Operation not permited.') cr.commit() + cr.close() # Ok def remove(self, node): + assert node + if node.type == 'collection': + return self.rmdir(node) + elif node.type == 'file': + return self.rmfile(node) + raise OSError(1, 'Operation not permited.') + + def rmfile(self, node): """Remove the specified file.""" - cr = node.cr - uid = node.uid - pool = pooler.get_pool(cr.dbname) - object2=node and node.object2 or False - object=node and node.object or False + assert node + if node.type == 'collection': + return self.rmdir(node) + uid = node.context.uid + pool = pooler.get_pool(node.context.dbname) + cr = pooler.get_db(node.context.dbname).cursor() + object = pool.get('ir.attachment').browse(cr, uid, node.file_id) if not object: raise OSError(2, 'Not such file or directory.') - if object._table_name=='ir.attachment': + if object._table_name == 'ir.attachment': res = pool.get('ir.attachment').unlink(cr, uid, [object.id]) else: raise OSError(1, 'Operation not permited.') cr.commit() + cr.close() # Ok - def rename(self, src, dst_basedir,dst_basename): + def rename(self, src, dst_basedir, dst_basename): """ Renaming operation, the effect depends on the src: * A file: read, create and remove * A directory: change the parent and reassign childs to ressource """ + cr = False try: - dst_basename=_to_unicode(dst_basename) - if src.type=='collection': - if src.object._table_name <> 'document.directory': + dst_basename = _to_unicode(dst_basename) + cr = pooler.get_db(src.context.dbname).cursor() + uid = src.context.uid + + if src.type == 'collection': + obj2 = False + dst_obj2 = False + pool = pooler.get_pool(src.context.dbname) + if isinstance(src, node_res_obj): + obj2 = src and pool.get(src.context.context['res_model']).browse(cr, uid, src.context.context['res_id']) or False + obj = src.context._dirobj.browse(cr, uid, src.dir_id) + if isinstance(dst_basedir, node_res_obj): + dst_obj2 = dst_basedir and pool.get(dst_basedir.context.context['res_model']).browse(cr, uid, dst_basedir.context.context['res_id']) or False + dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id) + if obj._table_name <> 'document.directory': raise OSError(1, 'Operation not permited.') result = { 'directory': [], @@ -491,44 +533,41 @@ class abstracted_fs: # Compute all childs to set the new ressource ID child_ids = [src] while len(child_ids): - node = child_ids.pop(0) - child_ids += node.children() - if node.type =='collection': - result['directory'].append(node.object.id) - if (not node.object.ressource_id) and node.object2: + node = child_ids.pop(0) + child_ids += node.children(cr) + object2 = node and hasattr(node, "res_model") and node.res_model or False + object = node.context._dirobj.browse(cr, uid, node.dir_id) + if node.type == 'collection': + result['directory'].append(object.id) + if (not object.ressource_id) and object2: raise OSError(1, 'Operation not permited.') - elif node.type =='file': - result['attachment'].append(node.object.id) - - cr = src.cr - uid = src.uid - pool = pooler.get_pool(cr.dbname) - object2=src and src.object2 or False - object=src and src.object or False - if object2 and not object.ressource_id: + elif node.type == 'file': + result['attachment'].append(object.id) + + + if obj2 and not obj.ressource_id: raise OSError(1, 'Operation not permited.') val = { 'name':dst_basename, } - if (dst_basedir.object and (dst_basedir.object.type in ('directory'))) or not dst_basedir.object2: - val['parent_id'] = dst_basedir.object and dst_basedir.object.id or False + if (dst_obj and (dst_obj.type in ('directory'))) or not dst_obj2: + val['parent_id'] = dst_obj and dst_obj.id or False else: val['parent_id'] = False - res = pool.get('document.directory').write(cr, uid, [object.id],val) - - if dst_basedir.object2: - ressource_type_id = pool.get('ir.model').search(cr,uid,[('model','=',dst_basedir.object2._name)])[0] - ressource_id = dst_basedir.object2.id - title = dst_basedir.object2.name - ressource_model = dst_basedir.object2._name - if dst_basedir.object2._name=='res.partner': - partner_id=dst_basedir.object2.id - else: - obj2=pool.get(dst_basedir.object2._name) - partner_id= obj2.fields_get(cr,uid,['partner_id']) and dst_basedir.object2.partner_id.id or False + res = pool.get('document.directory').write(cr, uid, [obj.id], val) + + if dst_obj2: + ressource_type_id = pool.get('ir.model').search(cr, uid, [('model','=',dst_obj2._name)])[0] + ressource_id = dst_obj2.id + title = dst_obj2.name + ressource_model = dst_obj2._name + if dst_obj2._name == 'res.partner': + partner_id = dst_obj2.id + else: + partner_id= pool.get(dst_obj2._name).fields_get(cr, uid, ['partner_id']) and dst_obj2.partner_id.id or False else: ressource_type_id = False - ressource_id=False + ressource_id = False ressource_model = False partner_id = False title = False @@ -545,11 +584,17 @@ class abstracted_fs: } pool.get('ir.attachment').write(cr, uid, result['attachment'], val) if (not val['res_id']) and result['attachment']: - dst_basedir.cr.execute('update ir_attachment set res_id=NULL where id in ('+','.join(map(str,result['attachment']))+')') + cr.execute('update ir_attachment set res_id=NULL where id in ('+','.join(map(str,result['attachment']))+')') cr.commit() - elif src.type=='file': - pool = pooler.get_pool(src.cr.dbname) + elif src.type == 'file': + pool = pooler.get_pool(src.context.dbname) + obj = pool.get('ir.attachment').browse(cr, uid, src.file_id) + dst_obj2 = False + if isinstance(dst_basedir, node_res_dir): + dst_obj2 = dst_basedir and dst_basedir.res_model or False + dst_obj = dst_basedir.context._dirobj.browse(cr, uid, dst_basedir.dir_id) + val = { 'partner_id':False, #'res_id': False, @@ -559,40 +604,40 @@ class abstracted_fs: 'title': dst_basename, } - if (dst_basedir.object and (dst_basedir.object.type in ('directory','ressource'))) or not dst_basedir.object2: - val['parent_id'] = dst_basedir.object and dst_basedir.object.id or False + if (dst_obj and (dst_obj.type in ('directory','ressource'))) or not dst_obj2: + val['parent_id'] = dst_obj and dst_obj.id or False else: val['parent_id'] = False - if dst_basedir.object2: - val['res_model'] = dst_basedir.object2._name - val['res_id'] = dst_basedir.object2.id - val['title'] = dst_basedir.object2.name - if dst_basedir.object2._name=='res.partner': - val['partner_id']=dst_basedir.object2.id - else: - obj2=pool.get(dst_basedir.object2._name) - val['partner_id']= obj2.fields_get(src.cr, src.uid,['partner_id']) and dst_basedir.object2.partner_id.id or False - elif src.object.res_id: + if dst_obj2: + val['res_model'] = dst_obj2._name + val['res_id'] = dst_obj2.id + val['title'] = dst_obj2.name + if dst_obj2._name == 'res.partner': + val['partner_id'] = dst_obj2.id + else: + val['partner_id'] = pool.get(dst_obj2._name).fields_get(src.cr, src.uid, ['partner_id']) and dst_obj2.partner_id.id or False + elif obj.res_id: # I had to do that because writing False to an integer writes 0 instead of NULL # change if one day we decide to improve osv/fields.py - dst_basedir.cr.execute('update ir_attachment set res_id=NULL where id=%s', (src.object.id,)) + cr.execute('update ir_attachment set res_id=NULL where id=%s', (obj.id,)) - pool.get('ir.attachment').write(src.cr, src.uid, [src.object.id], val) - src.cr.commit() + pool.get('ir.attachment').write(cr, uid, [obj.id], val) + cr.commit() elif src.type=='content': - src_file=self.open(src,'r') - dst_file=self.create(dst_basedir,dst_basename,'w') + src_file = self.open(src,'r') + dst_file = self.create(dst_basedir, dst_basename, 'w') dst_file.write(src_file.getvalue()) dst_file.close() src_file.close() - src.cr.commit() + cr.commit() else: raise OSError(1, 'Operation not permited.') except Exception,err: log(err) raise OSError(1,'Operation not permited.') - + finally: + if cr: cr.close() @@ -635,15 +680,16 @@ class abstracted_fs: """Return the size of the specified file in bytes.""" result = 0L if node.type=='file': - result = node.object.file_size or 0L + result = node.content_length or 0L return result # Ok def getmtime(self, node): """Return the last modified time as a number of seconds since the epoch.""" - if node.object and node.type<>'content': - dt = (node.object.write_date or node.object.create_date)[:19] + + if node.write_date or node.create_date: + dt = (node.write_date or node.create_date)[:19] result = time.mktime(time.strptime(dt, '%Y-%m-%d %H:%M:%S')) else: result = time.mktime(time.localtime()) diff --git a/addons/document/nodes.py b/addons/document/nodes.py index 845ba4e3ace..42a0e21f2f7 100644 --- a/addons/document/nodes.py +++ b/addons/document/nodes.py @@ -51,7 +51,7 @@ class node_context(object): def __init__(self, cr, uid, context=None): # we don't cache the cr! - #self.cr = cr + self.dbname = cr.dbname self.uid = uid self.context = context self._dirobj = pooler.get_pool(cr.dbname).get('document.directory') @@ -114,7 +114,7 @@ class node_class(object): s+=self.path else: s.append(self.path) - return s + return map(lambda x: '/' +x, s) def children(self, cr): print "node_class.children()" @@ -318,6 +318,7 @@ class node_res_dir(node_class): self.namefield = dirr.resource_field or 'name' self.displayname = dirr.name # Important: the domain is evaluated using the *parent* dctx! + self.dctx.update({'active_id': self.context.context['dir_id']}) self.domain = safe_eval(dirr.domain,self.dctx) # and then, we add our own vars in the dctx: if dctx: @@ -353,14 +354,13 @@ class node_res_dir(node_class): ctx.update(self.dctx) where = [] if self.domain: - where.append(self.domain) + where += self.domain if self.resm_id: where.append(('id','=',self.resm_id)) if name: where.append((self.namefield,'=',name)) - # print "Where clause for %s" % self.res_model, where - + # print "Where clause for %s" % self.res_model, where resids = obj.search(cr,uid, where, context=ctx) res = [] for bo in obj.browse(cr,uid,resids,context=ctx): @@ -396,8 +396,7 @@ class node_res_obj(node_class): self.content_length = 0 self.res_model = res_model self.domain = parent.domain - self.displayname = path - + self.displayname = path if res_bo: self.res_id = res_bo.id dc2 = self.context.context @@ -415,10 +414,10 @@ class node_res_obj(node_class): else: self.res_id = res_id - def children(self,cr): + def children(self,cr): return self._child_get(cr) + self._file_get(cr) - def child(self,cr, name): + def child(self,cr, name): res = self._child_get(cr,name) if res: return res[0] @@ -481,7 +480,7 @@ class node_res_obj(node_class): ctx.update(self.dctx) where = [('parent_id','=',self.dir_id) ] if name: - where.append(('name','=',name)) + where.append(('name','=',name)) ids = dirobj.search(cr, uid, where,context=ctx) res = [] if ids: |
