Projet

Général

Profil

0001-misc-accept-non-local-storage-as-attachments-in-evol.patch

Thomas Noël, 15 octobre 2020 12:39

Télécharger (7,39 ko)

Voir les différences:

Subject: [PATCH] misc: accept non-local storage as attachments in evolution
 (#47704)

 wcs/qommon/upload_storage.py |  2 +-
 wcs/wf/attachment.py         |  5 +--
 wcs/workflows.py             | 63 ++++++++++++++++++++++++------------
 3 files changed, 47 insertions(+), 23 deletions(-)
wcs/qommon/upload_storage.py
41 41
    def get_file_pointer(self):
42 42
        if 'fp' in self.__dict__ and self.__dict__.get('fp') is not None:
43 43
            return self.__dict__.get('fp')
44
        elif hasattr(self, 'qfilename'):
44
        elif getattr(self, 'qfilename', None):
45 45
            basedir = os.path.join(get_publisher().app_dir, 'uploads')
46 46
            self.fp = open(os.path.join(basedir, self.qfilename), 'rb')
47 47
            return self.fp
wcs/wf/attachment.py
63 63
                if not isinstance(p, AttachmentEvolutionPart):
64 64
                    continue
65 65
                if os.path.basename(p.filename) == fn:
66
                    return redirect( '%sfiles/attachment-%s/%s' % (
67
                            self.filled.get_url(), fn, urllib.quote(p.base_filename)))
66
                    is_in_backoffice = bool(get_request() and get_request().is_in_backoffice())
67
                    return redirect('%sfiles/attachment-%s/%s' % (
68
                            self.filled.get_url(backoffice=is_in_backoffice), fn, urllib.quote(p.base_filename)))
68 69

  
69 70
    raise TraversalError()
70 71

  
wcs/workflows.py
39 39
from quixote.html import htmltext
40 40
from .qommon import errors
41 41
from .qommon.template import Template, TemplateError
42
from .qommon.upload_storage import PicklableUpload, get_storage_object
42 43

  
43 44
from .conditions import Condition
44 45
from .roles import Role, logged_users_role, get_user_roles
......
117 118

  
118 119
    @property
119 120
    def content(self):
120
        return self.attachment_evolution_part.get_file_pointer().read()
121
        fp = self.attachment_evolution_part.get_file_pointer()
122
        if fp:
123
            return fp.read()
124
        return b''
121 125

  
122 126
    @property
123 127
    def b64_content(self):
......
168 172
    content_type = None
169 173
    charset = None
170 174
    varname = None
175
    storage = None
176
    storage_attrs = None
171 177

  
172 178
    def __init__(self, base_filename, fp, orig_filename=None, content_type=None,
173
            charset=None, varname=None):
179
            charset=None, varname=None, storage=None, storage_attrs=None):
174 180
        self.base_filename = base_filename
175 181
        self.orig_filename = orig_filename or base_filename
176 182
        self.content_type = content_type
177 183
        self.charset = charset
178 184
        self.fp = fp
179 185
        self.varname = varname
186
        self.storage = storage
187
        self.storage_attrs = storage_attrs
180 188

  
181 189
    @classmethod
182 190
    def from_upload(cls, upload, varname=None):
183 191
        return AttachmentEvolutionPart(
184 192
                upload.base_filename,
185
                upload.fp,
193
                getattr(upload, 'fp', None),
186 194
                upload.orig_filename,
187 195
                upload.content_type,
188 196
                upload.charset,
189
                varname=varname)
197
                varname=varname,
198
                storage=getattr(upload, 'storage', None),
199
                storage_attrs=getattr(upload, 'storage_attrs', None))
190 200

  
191 201
    def get_file_pointer(self):
192 202
        return open(self.filename, 'rb')
193 203

  
194 204
    def __getstate__(self):
195 205
        odict = self.__dict__.copy()
196
        if not 'fp' in odict:
206
        if not odict.get('fp'):
207
            if 'filename' not in odict:
208
                # we need a filename as an identifier: create one from nothing
209
                # instead of file_digest(self.fp) (see below)
210
                odict['filename'] = str(uuid.uuid4())
211
                self.filename = odict['filename']
197 212
            return odict
198 213

  
199 214
        del odict['fp']
......
213 228
        return odict
214 229

  
215 230
    def view(self):
216
        return htmltext('<p class="wf-attachment"><a href="attachment?f=%s">%s</a>' % (
217
                    os.path.basename(self.filename), self.orig_filename))
231
        show_link = True
232
        if self.has_redirect_url():
233
            is_in_backoffice = bool(get_request() and get_request().is_in_backoffice())
234
            show_link = bool(self.get_redirect_url(backoffice=is_in_backoffice))
235
        if show_link:
236
            return htmltext('<p class="wf-attachment"><a href="attachment?f=%s">%s</a></p>' % (
237
                        os.path.basename(self.filename), self.orig_filename))
238
        else:
239
            return htmltext('<p class="wf-attachment">%s</p>' % self.orig_filename)
218 240

  
219 241
    @classmethod
220 242
    def get_substitution_variables(cls, formdata):
......
224 246
    # mimic PicklableUpload methods:
225 247

  
226 248
    def can_thumbnail(self):
227
        return True
249
        return get_storage_object(getattr(self, 'storage', None)).can_thumbnail(self)
228 250

  
229 251
    def has_redirect_url(self):
230
        return False
252
        return get_storage_object(getattr(self, 'storage', None)).has_redirect_url(self)
231 253

  
232
    def get_redirect_url(self, upload, backoffice=False):
233
        # should never be called, has_redirect_url is False
234
        raise AssertionError('no get_redirect_url on AttachmentEvolutionPart object')
254
    def get_redirect_url(self, backoffice=False):
255
        return get_storage_object(getattr(self, 'storage', None)).get_redirect_url(self,
256
                backoffice=backoffice)
235 257

  
236 258

  
237 259
class DuplicateGlobalActionNameError(Exception):
......
2179 2201
                if not picklableupload:
2180 2202
                    continue
2181 2203

  
2182
                try:
2183
                    # convert any value to a PicklableUpload; it will ususally
2184
                    # be a dict like one provided by qommon/evalutils:attachment()
2185
                    picklableupload = FileField.convert_value_from_anything(picklableupload)
2186
                except ValueError:
2187
                    get_publisher().notify_of_exception(sys.exc_info(),
2188
                                                        context='[workflow/attachments]')
2189
                    continue
2204
                if not isinstance(picklableupload, PicklableUpload):
2205
                    try:
2206
                        # convert any value to a PicklableUpload; it will ususally
2207
                        # be a dict like one provided by qommon/evalutils:attachment()
2208
                        picklableupload = FileField.convert_value_from_anything(picklableupload)
2209
                    except ValueError:
2210
                        get_publisher().notify_of_exception(sys.exc_info(),
2211
                                                            context='[workflow/attachments]')
2212
                        continue
2190 2213

  
2191 2214
                uploads.append(picklableupload)
2192 2215

  
2193
-