import os, posixpath, stat, urllib
import mimetypes, rfc822
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, Http404, HttpResponseNotModified, HttpResponseServerError
from django.views.static import was_modified_since
from django.template import RequestContext, loader

def serve_file(request, dir=None, filename=None, user_filename=None, mimetype=None):
    """
    This is a hacked django.views.static.serve
    with added headers

    example urls.py usage:
    (r'^download-novella/(?P<filename>.+)$', 'rldjango.common.views.serve_file',
        { 'dir':/home/reportlab/staticfiles/novellas',
          'user_filename':'mynovella.pdf' }),
    """
    assert type(filename) is str  # we don't want any clever '.' or '/' encoding hacks
    if not filename or not dir:
        raise PermissionDenied
    if filename.endswith('/'):
        filename = filename[:-1]
    if '..' in filename or '/' in filename:
        raise PermissionDenied
    dir = posixpath.normpath(urllib.unquote(dir))
    fullpath = os.path.join(dir, filename)
    if os.path.isdir(fullpath):
        raise Http404, "Directory indexes are not allowed here."
    if not os.path.exists(fullpath):
        raise Http404, '"%s" does not exist' % fullpath
    # Respect the If-Modified-Since header.
    statobj = os.stat(fullpath)
    if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
                              statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]):
        return HttpResponseNotModified()
    if not mimetype:
        mimetype = mimetypes.guess_type(fullpath)[0]
    contents = open(fullpath, 'rb').read()
    response = HttpResponse(contents, mimetype=mimetype)
    response["Last-Modified"] = rfc822.formatdate(statobj[stat.ST_MTIME])
    if user_filename:
        print "adding fn: %s" % user_filename
        response['Content-Disposition'] = 'attachment; filename=%s' % user_filename
        response['Content-Length'] = '%d' % len(contents)
    return response

def server_error(request, template_name='500.html'):
    # like django.views.defaults.server_error, but uses RequestContext
    t = loader.get_template(template_name)
    return HttpResponseServerError(t.render(RequestContext(request, {})))

def specialEdit(request, app_label, model_name, object_id):
    """Forwards urls to admin edit for special processing"""
    from django.contrib.admin.views.main import change_stage
    result = change_stage(request, app_label, model_name, object_id)
    if not request.POST or 'class="errorlist"' in str(result):
        return result
    return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "", "");</script>')