diff options
| author | P. Christeas <p_christ@hol.gr> | 2010-07-13 13:30:53 +0300 |
|---|---|---|
| committer | P. Christeas <p_christ@hol.gr> | 2010-07-13 13:30:53 +0300 |
| commit | 6eebca04d623827763cd328616d3cb133f151ce9 (patch) | |
| tree | e0c6161aeedefdcec9cc627d3e406010d7ad5cfa /addons/document/nodes.py | |
| parent | 8cd367f9ed6e49bc46c5dcccd2d52c5b9a6c4329 (diff) | |
Document API: node_content.open_data(), for FTP
A crude way to get the data of a content node, using StringIO.
bzr revid: p_christ@hol.gr-20100713103053-hklth9rugddm6ajl
Diffstat (limited to 'addons/document/nodes.py')
| -rw-r--r-- | addons/document/nodes.py | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/addons/document/nodes.py b/addons/document/nodes.py index 58d830a169a..e368c6fc5a0 100644 --- a/addons/document/nodes.py +++ b/addons/document/nodes.py @@ -31,6 +31,8 @@ import errno import os import time +from StringIO import StringIO + # # An object that represent an uri # path: the uri of the object @@ -1221,9 +1223,6 @@ class node_content(node_class): self.dctx.update(dctx) self.act_id = act_id - def open(self, cr, mode=False): - raise DeprecationWarning() - def fill_fields(self, cr, dctx = None): """ Try to read the object and fill missing fields, like mimetype, dates etc. @@ -1250,7 +1249,29 @@ class node_content(node_class): self.content_length = len(data) return data + def open_data(self, cr, mode): + if mode.endswith('b'): + mode = mode[:-1] + if mode in ('r', 'w'): + cperms = mode[:1] + elif mode in ('r+', 'w+'): + cperms = 'rw' + else: + raise IOError(errno.EINVAL, "Cannot open at mode %s" % mode) + + if not self.check_perms(cperms): + raise IOError(errno.EPERM, "Permission denied") + + ctx = self.context.context.copy() + ctx.update(self.dctx) + + return nodefd_content(self, cr, mode, ctx) + def get_data_len(self, cr, fil_obj = None): + # FIXME : here, we actually generate the content twice!! + # we should have cached the generated content, but it is + # not advisable to do keep it in memory, until we have a cache + # expiration logic. if not self.content_length: self.get_data(cr,fil_obj) return self.content_length @@ -1266,3 +1287,53 @@ class node_content(node_class): def _get_ttag(self,cr): return 'cnt-%d%s' % (self.cnt_id,(self.act_id and ('-' + str(self.act_id))) or '') + + +class nodefd_content(StringIO, node_descriptor): + """ A descriptor to content nodes + """ + def __init__(self, parent, cr, mode, ctx): + node_descriptor.__init__(self, parent) + self._context=ctx + + if mode in ('r', 'r+'): + cntobj = parent.context._dirobj.pool.get('document.directory.content') + data = cntobj.process_read(cr, parent.context.uid, parent, ctx) + if data: + parent.content_length = len(data) + StringIO.__init__(self, data) + elif mode in ('w', 'w+'): + StringIO.__init__(self, None) + # at write, we start at 0 (= overwrite), but have the original + # data available, in case of a seek() + elif mode == 'a': + StringIO.__init__(self, None) + else: + logging.getLogger('document.content').error("Incorrect mode %s specified", mode) + raise IOError(errno.EINVAL, "Invalid file mode") + self.mode = mode + + def close(self): + # we now open a *separate* cursor, to update the data. + # FIXME: this may be improved, for concurrency handling + if self.mode == 'r': + StringIO.close(self) + return + + par = self._get_parent() + uid = par.context.uid + cr = pooler.get_db(par.context.dbname).cursor() + try: + if self.mode in ('w', 'w+', 'r+'): + data = self.getvalue() + cntobj = par.context._dirobj.pool.get('document.directory.content') + cntobj.process_write(cr, uid, parent, data, ctx) + elif self.mode == 'a': + raise NotImplementedError + cr.commit() + except Exception, e: + logging.getLogger('document.content').exception('Cannot update db content #%d for close:', par.cnt_id) + raise + finally: + cr.close() + StringIO.close(self) |
