# HG changeset patch # User Thierry Florac # Date 1461249467 -7200 # Node ID 792822dde705b63c191477da35f7ba91034af41c # Parent 8eb284fba75aa32c2a2d680049d653fe27afd532 Ue same default view for all files diff -r 8eb284fba75a -r 792822dde705 src/pyams_file/views/file.py --- a/src/pyams_file/views/file.py Thu Oct 08 09:22:40 2015 +0200 +++ b/src/pyams_file/views/file.py Thu Apr 21 16:37:47 2016 +0200 @@ -14,10 +14,10 @@ # import standard library -from http.client import NOT_MODIFIED +from http.client import NOT_MODIFIED, PARTIAL_CONTENT # import interfaces -from pyams_file.interfaces import IFile, IMediaFile +from pyams_file.interfaces import IFile from zope.dublincore.interfaces import IZopeDublinCore # import packages @@ -25,6 +25,9 @@ from pyramid.view import view_config +MAX_RANGE_LENGTH = 1 << 21 # 2 Mb + + @view_config(context=IFile) def FileView(request): """Default file view""" @@ -38,27 +41,27 @@ status=NOT_MODIFIED) response = Response(content_type=context.content_type.decode('utf-8'), - content_disposition='attachment; filename="{0}"'.format(context.filename), last_modified=modified) - response.body_file = context.get_blob(mode='c') - return response - + body_file = context.get_blob(mode='c') -@view_config(context=IMediaFile) -def MediaFileView(request): - """Default media file view""" - context = request.context - - # check for last modification date - modified = IZopeDublinCore(context).modified - if_modified_since = request.if_modified_since - if if_modified_since and (int(modified.timestamp()) <= int(if_modified_since.timestamp())): - return Response(content_type=context.content_type.decode('utf-8'), - status=NOT_MODIFIED) - - response = Response(content_type=context.content_type.decode('utf-8'), - last_modified=modified) if request.params.get('download') is not None: response.content_disposition = 'attachment; filename="{0}"'.format(context.filename) - response.body_file = context.get_blob(mode='c') + + if request.range is not None: + body = body_file.read() + body_length = len(body) + range_start = request.range.start or 0 + if 'Firefox' in request.user_agent: # avoid partial range for Firefox videos + range_end = body_length + else: + range_end = request.range.end or min(body_length, range_start + MAX_RANGE_LENGTH) + ranged_body = body[range_start:range_end] + response.status = PARTIAL_CONTENT + response.headers['Content-Range'] = 'bytes {first}-{last}/{len}'.format(first=range_start, + last=range_start + len(ranged_body) - 1, + len=body_length) + response.body = ranged_body + else: + response.body_file = body_file + return response