def sendpath(storage_type, key, path, mimetype): storage_obj = storage(storage_type) filesize = storage_obj.get_size(key, path) full_path = storage_obj.get_path(key, path) if full_path: return send_file(full_path) fileobj = storage_obj.get_file(key, path) if fileobj is None: raise Http404 response = StreamingHttpResponse(read_file_in_chunks(fileobj), content_type=mimetype) if mimetype[0:4] != 'text' and mimetype[0:5] != 'image': response['Content-Disposition'] = 'attachment; filename={0}'.format(os.path.basename(path)) response['Content-Length'] = filesize return response
def sendpath(storage_type, key, path, mimetype): storage_obj = storage(storage_type) filesize = storage_obj.get_size(key, path) full_path = storage_obj.get_path(key, path) if full_path: return send_file(full_path) fileobj = storage_obj.get_file(key, path) if fileobj is None: raise Http404 response = StreamingHttpResponse(read_file_in_chunks(fileobj), content_type=mimetype) if mimetype[0:4] != 'text' and mimetype[0:5] != 'image': response['Content-Disposition'] = 'attachment; filename={0}'.format( os.path.basename(path)) response['Content-Length'] = filesize return response
def get_file(request: HttpRequest, eid: int, compression: str = None, path: str = '', element: Element = None, name: str = None): """ Send file to the client as a HttpResponse Multiple combinations: * case 1) if path != '' => send a file inside a compressed archive * case 2) elif compression is not None => required uncompressed archive to compress it to the new format * case 3) else => require original file :param request: :param eid: :param compression: :param path: :param element: avoid an extra DB query to fetch :param name: :return: """ # noinspection PyUnusedLocal name = name if element is None: element = get_object_or_404( Element.reader_queryset(request).select_related(), id=eid) arc_storage, arc_key, arc_path = None, None, None mimetype = 'application/octet-stream' if element.uncompressed_key and path: # case 1 path = os.path.normpath(path) if path.startswith('../'): raise Http404 elif element.uncompressed_key and compression is not None: # case 2 arc_storage, arc_key, arc_path = storage( settings.STORAGE_UNCOMPRESSED), element.uncompressed_key, path elif element.archive_key: # case 2 or 3 if compression is not None: # case 2 arc_storage, arc_key, arc_path = storage( settings.STORAGE_ARCHIVE), element.archive_key, '' else: raise Http404 if arc_storage is not None: temp_file = tempfile.TemporaryFile(mode='w+b', dir=settings.TEMP_ROOT) comp_file = None ext = '' if compression == 'zip': mimetype = 'application/zip' ext = '.zip' comp_file = zipfile.ZipFile(temp_file, 'w', zipfile.ZIP_DEFLATED) elif compression == 'tgz': mimetype = 'application/x-tar' ext = '.tgz' comp_file = tarfile.open(None, 'w:gz', fileobj=temp_file) comp_file.write = comp_file.addfile elif compression == 'tbz': mimetype = 'application/x-tar' ext = '.tbz' comp_file = tarfile.open(None, 'w:bz2', fileobj=temp_file) comp_file.write = comp_file.addfile reldir = None for root, dirs, files in arc_storage.walk(arc_key, arc_path): if reldir is None: reldir = root for name in files: fullname = os.path.join(root, name) fileobj = arc_storage.get_file(arc_key, fullname) arcname = os.path.relpath(fullname, reldir) tarinfo = tarfile.TarInfo(arcname) tarinfo.size = arc_storage.get_size(arc_key, fullname) comp_file.write(tarinfo, fileobj) comp_file.close() temp_file.seek(0) fileobj = temp_file filename = os.path.basename(element.filename) + ext elif path: mimetype = mimetypes.guess_type(path)[0] if mimetype is None: mimetype = 'application/octet-stream' return sendpath(settings.STORAGE_UNCOMPRESSED, element.uncompressed_key, path, mimetype) else: return sendpath(settings.STORAGE_ARCHIVE, element.archive_key, '', element.mimetype) response = StreamingHttpResponse(read_file_in_chunks(fileobj), content_type=mimetype) if mimetype[0:4] != 'text' and mimetype[0:5] != 'image': response['Content-Disposition'] = 'attachment; filename={0}'.format( filename) return response
def get_file(request: HttpRequest, eid: int, compression: str=None, path: str='', element: Element=None, name: str=None): """ Send file to the client as a HttpResponse Multiple combinations: * case 1) if path != '' => send a file inside a compressed archive * case 2) elif compression is not None => required uncompressed archive to compress it to the new format * case 3) else => require original file :param request: :param eid: :param compression: :param path: :param element: avoid an extra DB query to fetch :param name: :return: """ # noinspection PyUnusedLocal name = name if element is None: element = get_object_or_404(Element.reader_queryset(request).select_related(), id=eid) arc_storage, arc_key, arc_path = None, None, None mimetype = 'application/octet-stream' if element.uncompressed_key and path: # case 1 path = os.path.normpath(path) if path.startswith('../'): raise Http404 elif element.uncompressed_key and compression is not None: # case 2 arc_storage, arc_key, arc_path = storage(settings.STORAGE_UNCOMPRESSED), element.uncompressed_key, path elif element.archive_key: # case 2 or 3 if compression is not None: # case 2 arc_storage, arc_key, arc_path = storage(settings.STORAGE_ARCHIVE), element.archive_key, '' else: raise Http404 if arc_storage is not None: temp_file = tempfile.TemporaryFile(mode='w+b', dir=settings.TEMP_ROOT) comp_file = None ext = '' if compression == 'zip': mimetype = 'application/zip' ext = '.zip' comp_file = zipfile.ZipFile(temp_file, 'w', zipfile.ZIP_DEFLATED) elif compression == 'tgz': mimetype = 'application/x-tar' ext = '.tgz' comp_file = tarfile.open(None, 'w:gz', fileobj=temp_file) comp_file.write = comp_file.addfile elif compression == 'tbz': mimetype = 'application/x-tar' ext = '.tbz' comp_file = tarfile.open(None, 'w:bz2', fileobj=temp_file) comp_file.write = comp_file.addfile reldir = None for root, dirs, files in arc_storage.walk(arc_key, arc_path): if reldir is None: reldir = root for name in files: fullname = os.path.join(root, name) fileobj = arc_storage.get_file(arc_key, fullname) arcname = os.path.relpath(fullname, reldir) tarinfo = tarfile.TarInfo(arcname) tarinfo.size = arc_storage.get_size(arc_key, fullname) comp_file.write(tarinfo, fileobj) comp_file.close() temp_file.seek(0) fileobj = temp_file filename = os.path.basename(element.filename) + ext elif path: mimetype = mimetypes.guess_type(path)[0] if mimetype is None: mimetype = 'application/octet-stream' return sendpath(settings.STORAGE_UNCOMPRESSED, element.uncompressed_key, path, mimetype) else: return sendpath(settings.STORAGE_ARCHIVE, element.archive_key, '', element.mimetype) response = StreamingHttpResponse(read_file_in_chunks(fileobj), content_type=mimetype) if mimetype[0:4] != 'text' and mimetype[0:5] != 'image': response['Content-Disposition'] = 'attachment; filename={0}'.format(filename) return response