def localfiles_data(request): """Serving files for LocalFilesImportStorage""" user = request.user path = request.GET.get('d') if settings.LOCAL_FILES_SERVING_ENABLED is False: return HttpResponseForbidden("Serving local files can be dangerous, so it's disabled by default. " 'You can enable it with LOCAL_FILES_SERVING_ENABLED environment variable, ' 'please check docs: https://labelstud.io/guide/storage.html#Local-storage') local_serving_document_root = settings.LOCAL_FILES_DOCUMENT_ROOT if path and request.user.is_authenticated: path = posixpath.normpath(path).lstrip('/') full_path = Path(safe_join(local_serving_document_root, path)) user_has_permissions = False # Try to find Local File Storage connection based prefix: # storage.path=/home/user, full_path=/home/user/a/b/c/1.jpg => # full_path.startswith(path) => True localfiles_storage = LocalFilesImportStorage.objects \ .annotate(_full_path=Value(os.path.dirname(full_path), output_field=CharField())) \ .filter(_full_path__startswith=F('path')) if localfiles_storage.exists(): user_has_permissions = any(storage.project.has_permission(user) for storage in localfiles_storage) if user_has_permissions and os.path.exists(full_path): content_type, encoding = mimetypes.guess_type(str(full_path)) content_type = content_type or 'application/octet-stream' return RangedFileResponse(request, open(full_path, mode='rb'), content_type) else: return HttpResponseNotFound() return HttpResponseForbidden()
def localfiles_data(request): """Serving files for LocalFilesImportStorage""" path = request.GET.get('d') if settings.LOCAL_FILES_SERVING_ENABLED is False: return HttpResponseForbidden( "Serving local files can be dangerous, so it's disabled by default. " 'You can enable it with LOCAL_FILES_SERVING_ENABLED environment variable' ) local_serving_document_root = get_env('LOCAL_FILES_DOCUMENT_ROOT', default='/') if path and request.user.is_authenticated: path = posixpath.normpath(path).lstrip('/') full_path = Path(safe_join(local_serving_document_root, path)) link = LocalFilesImportStorageLink.objects.filter( key=str(full_path)).first() if link and link.has_permission( request.user) and os.path.exists(full_path): content_type, encoding = mimetypes.guess_type(str(full_path)) content_type = content_type or 'application/octet-stream' return RangedFileResponse(request, open(full_path, mode='rb'), content_type) else: return HttpResponseNotFound() return HttpResponseForbidden()
def stream_audio_url(request, url): file = requests.get(url, allow_redirects=True) response = RangedFileResponse(request, file.content, content_type='audio/wav') response['Content-Disposition'] = 'attachment; filename="evaluation.wav"' return response
def get_uploaded_file(request, filename): file = settings.UPLOAD_DIR + ('/' if not settings.UPLOAD_DIR.endswith('/') else '') + filename logger.debug(f'Fetch uploaded file by user {request.user} => {file}') file_upload = FileUpload.objects.get(file=file) return RangedFileResponse(request, open(file_upload.file.path, mode='rb'))
def stream_audio(request, pk): audio = AudioFile.objects.get(pk=pk).file filepath = str(MEDIA_ROOT + '/' + str(audio)).replace('\\', '/') response = RangedFileResponse(request, open(filepath, "rb"), content_type='audio/mp3') response['Content-Disposition'] = 'attachment; filename="%s"' % filepath return response
def dl_movie_Helper(request, movie): if not movie.user_access(request.user): return "BAD" filename = movie.get_path() mime = MimeTypes().guess_type(filename)[0] fr = RangedFileResponse(request, filename, content_type=mime) fr['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(filename) if fr.status_code == 200: movie.log("Downloaded movie") return fr
def video(request, filename): """ Returns the video file. To be used by VideoPreviewWidget in admin's modelform. Requires permission decorator! """ videopath = os.path.join(settings.MEDIA_ROOT, filename) if not os.path.exists(videopath): return HttpResponseNotFound() return RangedFileResponse(request, open(videopath, 'rb'), content_type='video/mp4')
def get(self, *args, **kwargs): request = self.request filename = kwargs['filename'] file = settings.UPLOAD_DIR + ( '/' if not settings.UPLOAD_DIR.endswith('/') else '') + filename logger.debug(f'Fetch uploaded file by user {request.user} => {file}') file_upload = FileUpload.objects.get(file=file) return RangedFileResponse(request, open(file_upload.file.path, mode='rb'))
def test_more_one_char(self): """ Test requesting 1 bytes to many. """ request = self.factory.get( '/path', HTTP_RANGE='bytes=10-17' ) response = RangedFileResponse( request, io.BytesIO(b'sui2khiau2tsiang5'), content_type='audio/wav' ) self.assertContent(response, b'tsiang5')
def test_failing(self): """ Test requesting non existing bytes. """ request = self.factory.get( '/path', HTTP_RANGE='bytes=17-20' ) response = RangedFileResponse( request, io.BytesIO(b'sui2khiau2tsiang5'), content_type='audio/wav' ) self.assertEqual(response.status_code, 416)
def test_overlapping(self): """ Test requesting to many bytes. """ request = self.factory.get( '/path', HTTP_RANGE='bytes=10-20' ) response = RangedFileResponse( request, io.BytesIO(b'sui2khiau2tsiang5'), content_type='audio/wav' ) self.assertContent(response, b'tsiang5')
def test_begin(self): """ Test requesting the first bytes. """ request = self.factory.get( '/path', HTTP_RANGE='bytes=0-3' ) response = RangedFileResponse( request, io.BytesIO(b'sui2khiau2tsiang5'), content_type='audio/wav' ) self.assertContent(response, b'sui2')
def test_middle(self): """ Test requesting bytes in the middle. """ request = self.factory.get( '/path', HTTP_RANGE='bytes=4-9' ) response = RangedFileResponse( request, io.BytesIO(b'sui2khiau2tsiang5'), content_type='audio/wav' ) self.assertContent(response, b'khiau2')
def retrieve(request, recordid, record, mediaid, media): # check if media exists mediaobj = get_media_for_record(recordid, request.user).filter(id=mediaid) # check download status if not mediaobj or not mediaobj[0].is_downloadable_by(request.user): return HttpResponseForbidden() mediaobj = mediaobj[0] # Allow passing in an argument to prevent setting "attachment" content # disposition, which keeps e.g. the PDF viewer built into Google Chrome # from working inline = request.GET.has_key('inline') name = smart_str(mediaobj.url) if mediaobj.is_local(): # support byte range requests try: content_file = mediaobj.get_absolute_file_path() except IOError: logging.error( "mediaobj.get_absolute_file_path() failed for media.id %s" % mediaid) raise Http404() retval = RangedFileResponse(request, open(content_file, 'r'), content_type=str(mediaobj.mimetype)) else: try: content = mediaobj.load_file() except IOError: logging.error("mediaobj.load_file() failed for media.id %s" % mediaid) raise Http404() if content: retval = HttpResponse(content=content, content_type=str(mediaobj.mimetype)) else: inline = True retval = HttpResponseRedirect(mediaobj.get_absolute_url()) if not inline: retval["Content-Disposition"] = \ 'attachment; filename="%s"' % name Activity.objects.create(event='media-download', request=request, content_object=mediaobj) return retval
def get(self, request, *args, **kwargs): mediafile = MediaFile.objects.filter( idx=request.GET.get('idx')).first() filename = os.path.join(MediaFile.MEDIAS_PATH, mediafile.path, mediafile.name) response = RangedFileResponse(request, open(filename, 'rb'), content_type=mimetypes.guess_type( mediafile.name)[0]) response[ 'Content-Disposition'] = 'attachment; filename="%s"' % filename return response
def get(self, *args, **kwargs): request = self.request filename = kwargs['filename'] file = settings.UPLOAD_DIR + ( '/' if not settings.UPLOAD_DIR.endswith('/') else '') + filename logger.debug(f'Fetch uploaded file by user {request.user} => {file}') file_upload = FileUpload.objects.filter(file=file).last() if not file_upload.has_permission(request.user): return Response(status=status.HTTP_403_FORBIDDEN) if os.path.exists(file_upload.file.path): return RangedFileResponse(request, open(file_upload.file.path, mode='rb')) else: return Response(status=status.HTTP_404_NOT_FOUND)
def get(self, *args, **kwargs): request = self.request filename = kwargs['filename'] file = settings.UPLOAD_DIR + ('/' if not settings.UPLOAD_DIR.endswith('/') else '') + filename logger.debug(f'Fetch uploaded file by user {request.user} => {file}') file_upload = FileUpload.objects.filter(file=file).last() if not file_upload.has_permission(request.user): return Response(status=status.HTTP_403_FORBIDDEN) file = file_upload.file if file.storage.exists(file.name): content_type, encoding = mimetypes.guess_type(str(file.name)) content_type = content_type or 'application/octet-stream' return RangedFileResponse(request, file.open(mode='rb'), content_type=content_type) else: return Response(status=status.HTTP_404_NOT_FOUND)
def serve(request, path, document_root=None, show_indexes=False): """ Serve static files below a given point in the directory structure. To use, put a URL pattern such as:: from django.views.static import serve path('<path:path>', serve, {'document_root': '/path/to/my/files/'}) in your URLconf. You must provide the ``document_root`` param. You may also set ``show_indexes`` to ``True`` if you'd like to serve a basic index of the directory. This index view will use the template hardcoded below, but if you'd like to override it, you can create a template called ``static/directory_index.html``. """ path = posixpath.normpath(path).lstrip('/') fullpath = Path(safe_join(document_root, path)) if fullpath.is_dir(): raise Http404(_("Directory indexes are not allowed here.")) if not fullpath.exists(): raise Http404(_('“%(path)s” does not exist') % {'path': fullpath}) # Respect the If-Modified-Since header. statobj = fullpath.stat() if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'), statobj.st_mtime, statobj.st_size): return HttpResponseNotModified() content_type, encoding = mimetypes.guess_type(str(fullpath)) content_type = content_type or 'application/octet-stream' response = RangedFileResponse(request, fullpath.open('rb'), content_type=content_type) response["Last-Modified"] = http_date(statobj.st_mtime) if encoding: response["Content-Encoding"] = encoding return response
def get(self, request, *args, **kwargs): instance = self.get_object() export_type = request.GET.get('exportType') if instance.status != Export.Status.COMPLETED: return HttpResponse('Export is not completed', status=404) if export_type is None: file_ = instance.file else: file_ = instance.convert_file(export_type) if file_ is None: return HttpResponse("Can't get file", status=404) ext = file_.name.split('.')[-1] response = RangedFileResponse(request, file_, content_type=f'application/{ext}') response[ 'Content-Disposition'] = f'attachment; filename="{file_.name}"' response['filename'] = file_.name return response