downloading archives response corrupts files - python

wrapper = FileWrapper(file("C:/pics.zip"))
content_type = mimetypes.guess_type(result.files)[0]
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Length'] = os.path.getsize("C:/pics.zip")
response['Content-Disposition'] = "attachment; filename=pics.zip"
return response
pics.zip is a valid file with 3 pictures inside.
server response the download, but when I am going to open the zip, winrar says This archive is either in unknown format or damaged!
If I change the file path and the file name to a valid image C:/pic.jpg is downloaded damaged too.
What Im missing in this download view?

The problem is that you're not reading it as a binary file :)
This should work:
wrapper = FileWrapper(file("C:/pics.zip", 'rb'))

Related

Firefox does not save file with extension

I have a view in my Django application which creates a XLSX file and returns it to the user for download:
# Creates the response
response = HttpResponse(output.read(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
response['Content-Disposition'] = 'attachment; filename="{}".xlsx'.format(tournament.name)
When I try to download the file in Chrome, it works perfectly: the file is downloaded with filename "blabla.xlsx".
However with Firefox, it is downloaded with filename "blabla" (no extension).
Did you ever encounter this problem?

DJango Python File Upload how to preserve orginal file

I am trying to upload a file using Rest to a DJango Python API. But I noticed the file gets modified. Specifically a content-disposition is added to it. I haven't found a good way to remove this. The problem is I am trying to upload a tar that needs to be unzipped, but the modified content prevents unzipping the file.
I’m using this file parser on a rest page:
from rest_framework.parsers import FileUploadParser
The following code seems to get the file for me in the post method of an APIView
file_obj = request.FILES['file']
scanfile.file.save(file_obj.name, file_obj)
Where scanfile is a model with a file field.
The file gets saved with contents like this:
--b3c91a6c13e34fd5a1e253b1a72d63b3
Content-Disposition: form-data; name="file"; filename="sometar.tgz"
My tar file contents here.....
--b3c91a6c13e34fd5a1e253b1a72d63b3
My client looks like this:
filename = "sometar.tgz"
exclusion = "../../exclusionlist.txt"
headers = {'Content-Type': 'multipart/form-data;’,
'Authorization': 'JWT %s' % token,
}
url = "http://localhost:%s/api/scan/Project/%s/" % (port, filename)
#files = {'file': open(filename, 'rb'), 'exclusion_file': open(exclusion, 'rb')} # also tried this way but it just put the info in the same file and I see the headers in the file
files = [('file', open(filename, 'rb')), ('file', open(exclusion, 'rb'))]
x = requests.post(url, files=files, headers=headers)
So my question is how do I remove that content-disposition info from the saved file so I can properly unzip the file?
request.FILES['file'] is an UploadedFile object. You can get its name with request.FILES['file'].name and get just the content with request.FILES['file'].read().
You should be careful with read() and big files:
Read the entire uploaded data from the file. Be careful with this
method: if the uploaded file is huge it can overwhelm your system if
you try to read it into memory. You’ll probably want to use chunks()
instead; see below.
https://docs.djangoproject.com/en/1.11/ref/request-response/#django.http.HttpRequest.FILES
https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile

Django Serve .XLSX File and force download

I'm currently using openPYXL in order to open a template file within Django
module_dir = os.path.dirname(__file__) # get current directory
file_path = os.path.join(module_dir, fileName)
username = request.user.username
workbook = load_workbook(file_path)
worksheet = workbook.active
The file is then edited, and saved under a different name(This works fine, I can open the created file and it contains the information desired), however what I'm struggling with is serving this file to the user, I've tried various techniques such as shown below
workbook.save('EvalofSelf1.xlsx')
response = HttpResponse()
file_path = os.path.join(os.path.dirname(os.path.realpath(__name__)), 'EvalofSelf1.xlsx')
response['X-Sendfile'] = file_path
response['Content-Type'] = 'mimetype/submimetype'
response['Content-Disposition'] = 'attachment; filename=%s.xlsx' % 'DownloadedEval'
All of which serve a file as requested, but the file contains no actual data, is 0kb in size and unopenable, how can I serve up the created file from my Django project directory, retaining all information stored within it?
You're not ever putting the file contents into the response, so naturally it is 0 bytes. X-Sendfile is for a completely different purpose - when you're redirecting to a static server - and needs a URL, not a file path, anyway.
file_path = os.path.join(os.path.dirname(os.path.realpath(__name__)), 'EvalofSelf1.xlsx')
response = HttpResponse(open(file_path, 'rb').read())
response['Content-Type'] = 'mimetype/submimetype'
response['Content-Disposition'] = 'attachment; filename=DownloadedEval.xlsx'

Django Serving a Download File

I'm trying to serve a txt file generated with some content and i am having some issues. I'vecreated the temp files and written the content using NamedTemporaryFile and just set delete to false to debug however the downloaded file does not contain anything.
My guess is the response values are not pointed to the correct file, hense nothing is being downloaded, heres my code:
f = NamedTemporaryFile()
f.write(p.body)
response = HttpResponse(FileWrapper(f), mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=test-%s.txt' % p.uuid
response['X-Sendfile'] = f.name
Have you considered just sending p.body through the response like this:
response = HttpResponse(mimetype='text/plain')
response['Content-Disposition'] = 'attachment; filename="%s.txt"' % p.uuid
response.write(p.body)
XSend requires the path to the file in
response['X-Sendfile']
So, you can do
response['X-Sendfile'] = smart_str(path_to_file)
Here, path_to_file is the full path to the file (not just the name of the file)
Checkout this django-snippet
There can be several problems with your approach:
file content does not have to be flushed, add f.flush() as mentioned in comment above
NamedTemporaryFile is deleted on closing, what might happen just as you exit your function, so the webserver has no chance to pick it up
temporary file name might be out of paths which web server is configured to send using X-Sendfile
Maybe it would be better to use StreamingHttpResponse instead of creating temporary files and X-Sendfile...
import urllib2;
url ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=s&chld=H|0";
opener = urllib2.urlopen(url);
mimetype = "application/octet-stream"
response = HttpResponse(opener.read(), mimetype=mimetype)
response["Content-Disposition"]= "attachment; filename=aktel.png"
return response

How to download a file uploaded using django-filebrowser?

I am trying to create a download of a file object. the file was added using django-filebrowser which means it is turn in to a string path to the the file. I have tried the following:
f = Obj.objects.get(id=obj_id)
myfile = FileObject(os.path.join(MEDIA_ROOT, f.Audio.path))
...
response = HttpResponse(myfile, content_type="audio/mpeg")
response['Content-Disposition'] = 'attachment; filename=myfile.mp3'
return response
The file that is downloaded contains the string of the path to the file location and not the file. Could anyone be of assistance on how to access the file object?
f = Obj.objects.get(id=obj_id)
myfile = open(os.path.join(MEDIA_ROOT, f.Audio.path)).read()
...
response = HttpResponse(myfile, content_type="audio/mpeg")
response['Content-Disposition'] = 'attachment; filename=myfile.mp3'
return response
NOTE! This is not memory friendly! Since the whole file is put into memory. You're better of using a webserver for file serving or if you want to use Django for file serving you could use xsendfile or have a look at this thread
You need to open the file and send it's binary contents back in the response. So something like:
fileObject = FileObject(os.path.join(MEDIA_ROOT, f.Audio.path))
myfile = open(fileObject.path)
response = HttpResponse(myfile.read(), mimetype="audio/mpeg")
response['Content-Disposition'] = 'attachment; filename=myfile.mp3'
return response
Hope that gets what you're looking for.

Categories