I have the next view to upload a image but the generated image is corrupted.
class FileUploadView(views.APIView):
parser_classes = (parsers.FileUploadParser,)
def uploadFile(self, up_file):
if not os.path.exists(BUILDING_PHOTOS_FOLDER):
os.mkdir(BUILDING_PHOTOS_FOLDER)
file_name = '{}.jpeg'.format(uuid.uuid4())
destination = open(
'{}/{}'.format(BUILDING_PHOTOS_FOLDER, file_name), 'wb+')
for chunk in up_file.chunks():
destination.write(chunk)
destination.close()
def put(self, request, filename, format=None):
file_obj = request.data['file']
self.uploadFile(file_obj)
return HttpResponse(status=204)
Hi you can try like this
def uploadFile(self, f):
filename = f.name
redington_path = settings.MEDIA_ROOT + '/yourpath/'
if not os.path.exists(redington_path):
os.makedirs(redington_path)
BASE_PATH = settings.MEDIA_ROOT + '/yourpath/'
os.mkdir(os.path.join(BASE_PATH, vendorid))
with open(BASE_PATH + filename, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
you need get files from request.FILES['file']
def put(self, request, filename, format=None):
file_obj = request.FILES['file']
self.uploadFile(file_obj)
return HttpResponse(status=204)
Need to add set format=jpeg and file_name should be up_file.name
class FileUploadView(views.APIView):
parser_classes = (parsers.FileUploadParser,)
def uploadFile(self, up_file):
if not os.path.exists(BUILDING_PHOTOS_FOLDER):
os.mkdir(BUILDING_PHOTOS_FOLDER)
up_file.name
file_name = up_file.name
destination = open('{}/{}'.format(BUILDING_PHOTOS_FOLDER, file_name), 'wb+')
for chunk in up_file.chunks():
destination.write(chunk)
destination.close()
def put(self, request, filename, format='jpeg'):
file_obj = request.data['file']
self.uploadFile(file_obj)
return HttpResponse(status=204)
Finally i solve sending the image as raw binary from frontend.
Related
I have the goal of changing the file object (video uploaded by user) to bytes and then chunking it and then changing these chunks again to images or frames. the following code is a snippet from a django app.
def handle_uploaded_file(f):
with open('./chunks_made.txt', 'wb+') as destination:
for chunk in f.chunks():
print(type(chunk))
print(len(chunk))
destination.write(chunk)
chunk_length = len(chunk)
read_batches(len(chunk))
def read_batches(chunk_size):
with open('./chunks_made.txt', 'rb') as file:
content = file.read(chunk_size)
frame = cv2.imdecode(content, cv2.IMREAD_COLOR)
plt.imshow(frame)
plt.show()
The process view which calls these functions:
def process(request):
video_file = request.FILES['video']
handle_uploaded_file(video_file)
data = 'some_data'
return render(request, 'video/result.html', {'data':video_file})
I don't know how to decode the bytes into the frames as a real image.
I am trying to save a file and do something to it a from in an html file, I am not using django forms but I am using django for backend and I don't need a database since I don't want to keep any of the files. I tried what the django documentation has instructed.
html file
<input type="file" id="face_files" name="face_files" multiple >
view.py
def index(request):
if request.method == "GET":
return render(request, 'index.html')
if request.method == "POST":
form = InputForm(request)
call_form_function(form)
return render(request, 'index.html')
Inputform.py
class InputForm():
def __init__(self, request):
self.face_files = request.FILES.getlist('face_files')
# print('face_files= ', self.face_files)
self.face_name = request.POST.get('face_name')
# print('face_name= ', self.face_name)
def save_files(self):
import os
self.delete_temp()
folder = os.path.dirname(__file__) + '/static/temp/'+self.face_name
try:
os.mkdir(folder)
counter=1
for file in self.face_files:
# print(file)
destination=open(folder +"/face"+str(counter)+".jpg", 'wb+')
for chunk in file.chunks():
destination.write(chunk)
destination.close()
counter+=1
except:
with open(console_html_path, "w+") as f:
f.write(traceback.format_exc())
traceback.print_exc()
return folder
def do_function(self):
folder_path = self.save_files()
function(args, folder_path)
def call_form_function(form):
import threading
t1 = threading.Thread(target=form.do_function)
t1.start()
But I get the error
lib/python3.7/site-packages/django/core/files/uploadedfile.py", line 91, in chunks
self.file.seek(0)
ValueError: I/O operation on closed file.
what am I doing wrong?
You can create a separate function to handle the uploaded file.
def handle_uploaded_files(f):
with open(f'uploaded/folder/path/{f.name}', 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
I am trying to input a file from an input field, save it temporarily to the disk and reply with a response to re-download the same file.
In order to do this, I've read that I need to reply to the browser with a content-type : application/octet-stream and a content-disposition: attachment; "filename=myfile.extension".
I can store and listen to my music file in the /tmp folder so I know that the input part of it works.
This is my code in Pyramid:
#view_config(route_name='process')
def process_file(request):
input_file = request.POST['file'].file
input_file.seek(0)
file_path = os.path.join('/tmp', '%s.mp3' % uuid.uuid4())
with open(file_path, 'wb') as output_file:
shutil.copyfileobj(input_file, output_file)
print(f"Wrote: {file_path}")
filename = file_path.split('/')[-1]
print(filename)
f = open(file_path, 'rb')
return Response(body_file=f, charset='UTF-8', content_type='application/octet-stream', content_disposition=f'attachment; "filename={filename}"')
These are my response headers:
And this is my response body:
However Chrome/Firefox do not start the download of my binary file. What am I doing wrong?
UPDATE
I also tried with FileResponse from Pyramid without success, I still do not get the download popup.
#view_config(route_name='process')
def process_file(request):
input_file = request.POST['file'].file
input_file.seek(0)
file_path = os.path.join('/tmp', '%s.mp3' % uuid.uuid4())
with open(file_path, 'wb') as output_file:
shutil.copyfileobj(input_file, output_file)
print(f"Wrote: {file_path}")
return FileResponse(file_path, request=request)
Apparently I was thinking how to perform this in the wrong way. I need to return a Response('OK') when I upload the file through /process and make another request to return a FileResponse object, building another endpoint /download and returning that fileresponse object fixed this issue.
Example:
#view_config(route_name='process')
def process_file(request):
input_file = request.POST['file'].file
db = request.POST['volume']
input_file.seek(0)
filename = '%s.mp3' % uuid.uuid4()
file_path = os.path.join('/tmp', filename)
with open(file_path, 'wb') as output_file:
shutil.copyfileobj(input_file, output_file)
if boost_track(file_path, filename, db):
return Response(json_body={'filename': filename})
#view_config(route_name='download')
def download_file(request):
filename = request.GET['filename']
file_path = os.path.join('/tmp', filename)
f = open(file_path, 'rb')
return Response(body_file=f, charset='UTF-8', content_type='application/download', content_disposition=f'attachment; filename="{filename}"')
I use this code in DJANGO framework to can some user download images.
this code work fine and download image every time to press download some user.
but this code download absolute images I need to zip this images for any user download.
def download_image(request, id):
product_image=MyModel.objects.get(pk=id)
product_image_url = product_image.upload.url
wrapper = FileWrapper(open(settings.MEDIA_ROOT+ product_image_url[6:], 'rb'))
content_type = mimetypes.guess_type(product_image_url)[0]
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Disposition'] = "attachment; filename=%s" % product_image_url
return response
is easy to change this code to download images in zip file ?
Try the following:
def download_image(request, id):
product_image=MyModel.objects.get(pk=id)
product_image_url = product_image.upload.url
image_path = settings.MEDIA_ROOT+ product_image_url[6:]
image_name = 'whatevername.png'; # Get your file name here.
with ZipFile('export.zip', 'w') as export_zip:
export_zip.write(image_path, image_name)
wrapper = FileWrapper(open('export.zip', 'rb'))
content_type = 'application/zip'
content_disposition = 'attachment; filename=export.zip'
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Disposition'] = content_disposition
return response
I am trying to open a file in a class and close it on exit in this manner.
class PlanetaryImage(object):
#classmethod
def open(cls, filename):
with open(filename, 'rb') as fp:
return cls(fp, filename)
def __init__(self, stream, filename=None, memory_layout='DISK'):
self.filename = filename
self._parse_data(stream)
def _parse_data(self, stream):
data_stream = stream
try:
if self.data_filename is not None:
dirpath = os.path.dirname(self.filename)
data_file = os.path.abspath(
os.path.join(dirpath, self.data_filename))
data_stream = open(data_file, 'rb')
data_stream.seek(self.start_byte)
if self.format in self.BAND_STORAGE_TYPE:
return getattr(self, self.BAND_STORAGE_TYPE[self.format])(data_stream)
raise Exception('Unkown format (%s)' % self.format)
finally:
data_stream.close()
There are certain cases where I am having to use open one more file in _parse_data function. I wanted to use with but the if statements make it difficult. Any suggestions on how to make the try section more pythonic.
There's no reason for _parse_data to try to open a file. It should be the caller's responsibility to either use PlanetaryImage.open with a file name or to provide an open file handle to __init__. _parse_data should do just one thing: parse the data from its stream argument.
class PlanetaryImage(object):
#classmethod
def open(cls, filename):
with open(filename, 'rb') as fp:
return cls(fp, filename)
def __init__(self, stream, memory_layout='DISK'):
self._parse_data(stream)
def _parse_data(self, data_stream):
try:
data_stream.seek(self.start_byte)
if self.format in self.BAND_STORAGE_TYPE:
return getattr(self, self.BAND_STORAGE_TYPE[self.format])(data_stream)
raise Exception('Unkown format (%s)' % self.format)
finally:
data_stream.close()
Now, there are simply two options for using the class:
with open(filename, 'rb') as fp:
x = PlanetaryImage(fp)
...
or
x = PlanetaryImage(filename)
....