Ue same default view for all files
authorThierry Florac <thierry.florac@onf.fr>
Thu, 21 Apr 2016 16:37:47 +0200
changeset 27 792822dde705
parent 26 8eb284fba75a
child 28 8dddc9a466e9
Ue same default view for all files
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