diff options
author | Aurélien Bompard <aurelien@bompard.org> | 2012-10-02 12:11:40 +0200 |
---|---|---|
committer | Aurélien Bompard <aurelien@bompard.org> | 2012-10-02 12:11:40 +0200 |
commit | bc7ab6eb365c8b78a083f3900fbd7304b5c92436 (patch) | |
tree | b64aa422aa8a2f47451c4eaacad61086ecf29ae3 /hyperkitty | |
parent | c085839fc5bcc61dca6b94bcfe6a65473f9f2975 (diff) | |
download | hyperkitty-bc7ab6eb365c8b78a083f3900fbd7304b5c92436.tar.gz hyperkitty-bc7ab6eb365c8b78a083f3900fbd7304b5c92436.tar.xz hyperkitty-bc7ab6eb365c8b78a083f3900fbd7304b5c92436.zip |
Add a view to download attachments
Diffstat (limited to 'hyperkitty')
-rw-r--r-- | hyperkitty/templates/message.html | 4 | ||||
-rw-r--r-- | hyperkitty/urls.py | 5 | ||||
-rw-r--r-- | hyperkitty/views/message.py | 28 |
3 files changed, 33 insertions, 4 deletions
diff --git a/hyperkitty/templates/message.html b/hyperkitty/templates/message.html index 75770f1..e9f2806 100644 --- a/hyperkitty/templates/message.html +++ b/hyperkitty/templates/message.html @@ -14,7 +14,9 @@ <h2>Attachments</h2> <ul> {% for attachment in attachments %} - <li>{{attachment.name}} ({{attachment.content_type}}, {{attachment.size}} octets)</li> + <li><a href="{% url message_attachment mlist_fqdn=list_address, hashid=hashid, counter=attachment.counter, filename=attachment.name %}">{{attachment.name}}</a> + ({{attachment.content_type}}, {{attachment.size}} octets) + </li> {% endfor %} </ul> {% endif %} diff --git a/hyperkitty/urls.py b/hyperkitty/urls.py index 61779bc..bc52699 100644 --- a/hyperkitty/urls.py +++ b/hyperkitty/urls.py @@ -58,9 +58,12 @@ urlpatterns = patterns('hyperkitty.views', ### MESSAGE LEVEL VIEWS ### # Vote a message - url(r'^message/(?P<mlist_fqdn>.*@.*)/(?P<hashid>.+)/$', + url(r'^message/(?P<mlist_fqdn>.*@.*)/(?P<hashid>\w+)/$', 'message.index', name='message_index'), + url(r'^message/(?P<mlist_fqdn>.*@.*)/(?P<hashid>\w+)/attachment/(?P<counter>\d+)/(?P<filename>.+)$', + 'message.attachment', name='message_attachment'), + url(r'^vote/(?P<mlist_fqdn>.*@.*)/$', 'message.vote', name='message_vote'), ### MESSAGE LEVEL VIEW ENDS ### diff --git a/hyperkitty/views/message.py b/hyperkitty/views/message.py index 0f90ed6..f6c4d91 100644 --- a/hyperkitty/views/message.py +++ b/hyperkitty/views/message.py @@ -19,6 +19,7 @@ import re import os +import urllib import django.utils.simplejson as simplejson from django.http import HttpResponse, HttpResponseRedirect, Http404 @@ -34,7 +35,7 @@ from hyperkitty.lib import get_store from forms import * -def index (request, mlist_fqdn, hashid): +def index(request, mlist_fqdn, hashid): ''' Displays a single message identified by its message_id_hash (derived from message_id) @@ -81,9 +82,32 @@ def index (request, mlist_fqdn, hashid): return HttpResponse(t.render(c)) +def attachment(request, mlist_fqdn, hashid, counter, filename): + """ + Sends the numbered attachment for download. The filename is not used for + lookup, but validated nonetheless for security reasons. + """ + store = get_store(request) + message = store.get_message_by_hash_from_list(mlist_fqdn, hashid) + if message is None: + raise Http404 + attachment = store.get_attachment_by_counter(mlist_fqdn, message.message_id, int(counter)) + if attachment is None or attachment.name != filename: + raise Http404 + # http://djangosnippets.org/snippets/1710/ + response = HttpResponse(attachment.content) + response['Content-Type'] = attachment.content_type + response['Content-Length'] = attachment.size + if attachment.encoding is not None: + response['Content-Encoding'] = attachment.encoding + # Follow RFC2231, browser support is sufficient nowadays (2012-09) + response['Content-Disposition'] = 'attachment; filename*=UTF-8\'\'%s' \ + % urllib.quote(attachment.name.encode('utf-8')) + return response + @login_required -def vote (request, mlist_fqdn): +def vote(request, mlist_fqdn): """ Add a rating to a given message identified by messageid. """ if not request.user.is_authenticated(): return redirect('user_login') |