#!/usr/bin/env python

"""Please be aware this code is a stopgap measure that should go away when
more complete support for file uploading is added to newforms.

This demonstrates one way to do HTTP file upload using Django's groovy
new "newforms" approach.  There isn't a FileField-type class for newforms
yet (as of March 9th, 2007), so you must do some additional work to fetch
the uploaded content."""


try:
    import cStringIO as StringIO
except ImportError:
    import StringIO
import zipfile

from django import http
from django import newforms as forms
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required

# You will probably want to work with one or more of your model classes.
#from mysite.pix.models import Picture


class ZipUploadForm(forms.Form):
    """A django.newforms class that uses a FileInput widget to accept
    uploaded .ZIP files."""

    zip_file = forms.Field(widget=forms.FileInput())
    owner = forms.CharField(max_length=80)

    def clean_zipfile(self):
        if 'zip_file' in self.clean_data:
            zip_file = self.clean_data['zip_file']
            if zip_file.get('content-type') != 'application/zip':
                msg = 'Only .ZIP archive files are allowed.'
                raise forms.ValidationError(msg)
            else:
                # Verify that it's a valid zipfile
                zip = zipfile.ZipFile(StringIO(zip_file['content']))
                bad_file = zip.testzip()
                zip.close()
                del zip
                if bad_file:
                    msg = '"%s" in the .ZIP archive is corrupt.' % (bad_file,)
                    raise forms.ValidationError(msg)
            return zip_file

    def save(self):
        owner = self.clean_data['owner']
        zipdata = self.clean_data['zip_file']['content']
        zip = zipfile.ZipFile(StringIO.StringIO(zipdata))
        for filename in zip.namelist():
            # Do something here with each file in the .ZIP archive.
            #
            # For example, if you expect the archive to contain image
            # files, you could process each one with PIL, then create
            # and populate your models.Picture object and save it.
            #data = zip.read(filename)
            #pic = Picture(owner, filename, data)
            #pic.save()
            pass
        zip.close()


@login_required
def zip_upload(request, template='zipupload.html'):

    form = None

    # Typically, we'd do a permissions check here.
    #if not request.user.has_perm('pix.add_picture'):
    #    return http.HttpResponseForbidden('You cannot add pictures.')

    if request.POST:
        post_data = request.POST.copy()
        post_data.update(request.FILES)
        form = ZipUploadForm(post_data)
        if form.is_valid():
            success = form.save()
            return http.HttpResponseRedirect('/pix/upload_success/')
    else:
        form = ZipUploadForm()
    return render_to_response(template, {'form':form})



# Example template for "zipupload.html"
{% extends "base.html" %}

{% block content %}
  <div class="content">
    <h1>Upload a .Zip file</h1>
    <div class="body">
      <p>
        <form action="/zip_upload/" method="post"
              enctype="multipart/form-data">
          <table>
            {{ form }}
          </table>
          <input type="submit" value="Upload ZIP" />
        </form>
      </p><br />
      <p>Some helpful text really should go here.</p>
    </div>
  </div>
{% endblock %}