views:

199

answers:

1

I'm creating an web app in Pylons, and am working on an image upload action. This is currently running using egg:paste#http on my windows machine, in the basic development configuration described in the pylons documentation quickstart.

When I POST an image to my application, then move the image to the web root directory, then pull the uploaded image up in the browser, the image appears distorted. This is what I got when i uploaded a GIF of the Yahoo! logo, but most files don't show up in the browser at all, presumably because of corruption:

distorted yahoo logo

This is the basic code I'm working with (straight out of the pylons documentation):

os_path = os.path.join(config.images_dir, request.POST['image'].filename)
save_file = open(os_path, 'w')
shutil.copyfileobj(request.POST['image'].file, save_file)
request.POST['image'].file.close()
save_file.close()

request.POST['image'] is a cgi.FieldStorage object. I thought this may be an issue with Windows line endings somehow, but I'm not sure how to check that or correct for it. What is causing my uploaded images to be distorted / corrupt?

+2  A: 

You are probably just missing the 'b' (binary) flag for effectively writing the file as binary:

save_file = open(os_path, 'wb')

But I don't see why you need the shutil.copyfileobj call in there, why not do something like this:

file_save_path = os.path.join(config.images_dir, request.POST['image'].filename)
file_contents = request.POST['image'].file.read()

# insert sanity checks here...

save_file = open(file_save_path, 'wb')
save_file.write(file_contents)
save_file.close()

Or make the last three lines a bit more pythonic (making sure the file handle gets closed even if the write fails):

with open(file_save_path, 'wb') as save_file:
    save_file.write(file_contents)

It's possible you need a

from __future__ import with_statements

at the top of your file if you're below Python 2.6.

ChristopheD
Thank you, that works perfectly.
Travis