Added a view to download zipped fragment books.
authorMarek Stępniowski <marek@stepniowski.com>
Thu, 18 Sep 2008 11:29:18 +0000 (13:29 +0200)
committerMarek Stępniowski <marek@stepniowski.com>
Thu, 18 Sep 2008 11:29:18 +0000 (13:29 +0200)
apps/catalogue/urls.py
apps/catalogue/views.py
wolnelektury/templates/catalogue/tagged_object_list.html

index 154a5aa..11a6378 100644 (file)
@@ -6,13 +6,16 @@ urlpatterns = patterns('catalogue.views',
     url(r'^$', 'main_page', name='main_page'),
     url(r'^polki/$', 'user_shelves', name='user_shelves'),
     url(r'^polki/(?P<slug>[a-zA-Z0-9-]+)/usun/$', 'delete_shelf', name='delete_shelf'),
+    url(r'^polki/(?P<slug>[a-zA-Z0-9-]+)/zip$', 'download_shelf', name='download_shelf'),
     url(r'^lektury/', 'book_list', name='book_list'),
     url(r'^lektura/(?P<slug>[a-zA-Z0-9-]+)/polki/', 'book_sets', name='book_shelves'),
     url(r'^polki/nowa/$', 'new_set', name='new_set'),
-    url(r'^lektura/(?P<slug>[a-zA-Z0-9-]+)\.html$', 'book_text', name='book_text'),
-    url(r'^lektura/(?P<slug>[a-zA-Z0-9-]+)/$', 'book_detail', name='book_detail'),
     url(r'^tags/$', 'tags_starting_with', name='hint'),
     url(r'^szukaj/$', 'search', name='search'),
+    
+    # Public interface. Do not change this URLs.
+    url(r'^lektura/(?P<slug>[a-zA-Z0-9-]+)\.html$', 'book_text', name='book_text'),
+    url(r'^lektura/(?P<slug>[a-zA-Z0-9-]+)/$', 'book_detail', name='book_detail'),
     url(r'^(?P<tags>[a-zA-Z0-9-/]+)/$', 'tagged_object_list', name='tagged_object_list'),
 )
 
index 45dc7a0..de75803 100644 (file)
@@ -1,4 +1,7 @@
 # -*- coding: utf-8 -*-
+import tempfile
+import zipfile
+
 from django.template import RequestContext
 from django.shortcuts import render_to_response, get_object_or_404
 from django.http import HttpResponse, HttpResponseRedirect, Http404
@@ -13,6 +16,7 @@ from django.utils import simplejson
 from django.utils.functional import Promise
 from django.utils.encoding import force_unicode
 from django.views.decorators import cache
+from django.core.servers.basehttp import FileWrapper
 
 from catalogue import models
 from catalogue import forms
@@ -163,7 +167,7 @@ def tags_starting_with(request):
 # = Shelf management =
 # ====================
 @login_required
-@cache.cache_control(must_revalidate=True, max_age=3600, private=True)
+@cache.never_cache
 def user_shelves(request):
     shelves = models.Tag.objects.filter(category='set', user=request.user)
     new_set_form = forms.NewSetForm()
@@ -171,7 +175,7 @@ def user_shelves(request):
             context_instance=RequestContext(request))
 
 
-@cache.cache_control(must_revalidate=True, max_age=3600, private=True)
+@cache.never_cache
 def book_sets(request, slug):
     book = get_object_or_404(models.Book, slug=slug)
     user_sets = models.Tag.objects.filter(category='set', user=request.user)
@@ -197,6 +201,31 @@ def book_sets(request, slug):
         context_instance=RequestContext(request))
 
 
+@cache.cache_control(must_revalidate=True, max_age=1800)
+def download_shelf(request, slug):
+    """"
+    Create a ZIP archive on disk and transmit it in chunks of 8KB,
+    without loading the whole file into memory. A similar approach can
+    be used for large dynamic PDF files.                                        
+    """
+    shelf = get_object_or_404(models.Tag, slug=slug, category='set')
+    
+    # Create a ZIP archive
+    temp = tempfile.TemporaryFile()
+    archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)
+    for book in models.Book.tagged.with_all(shelf):
+        filename = book.html_file.path
+        archive.write(filename, str('%s.html' % book.slug))
+    archive.close()
+    
+    wrapper = FileWrapper(temp)
+    response = HttpResponse(wrapper, content_type='application/zip')
+    response['Content-Disposition'] = 'attachment; filename=%s.zip' % shelf.slug
+    response['Content-Length'] = temp.tell()
+    temp.seek(0)
+    return response
+
+
 @login_required
 @require_POST
 @cache.never_cache
index 769a5cb..7339114 100644 (file)
             </div>
             <div id="toggle-description"><p>Zwiń opis ▲</p></div>
         {% endif %}
-        {% endwith %}
         {% if shelf_is_set %}
-            <a id="download-shelf">
+            <a id="download-shelf" href="{% url download_shelf last_tag.slug %}">
                 Pobierz wszystkie książki z tej półki
             </a>
         {% endif %}
+        {% endwith %}
         <ol>
         {% for book in object_list %}
             <li>{{ book.short_html }}</li>