]> git.parisson.com Git - telemeta.git/commitdiff
add collection zip get methods, add debug_toolbar to sandbox
authorGuillaume Pellerin <yomguy@parisson.com>
Mon, 20 Jan 2014 12:35:38 +0000 (13:35 +0100)
committerGuillaume Pellerin <yomguy@parisson.com>
Mon, 20 Jan 2014 12:35:38 +0000 (13:35 +0100)
example/sandbox/settings.py
example/sandbox/urls.py
setup.py
telemeta/static/telemeta/css/telemeta.css
telemeta/static/telemeta/images/zip.png [new file with mode: 0644]
telemeta/templates/telemeta/base.html
telemeta/templates/telemeta/collection_detail.html
telemeta/urls.py
telemeta/views/collection.py
telemeta/views/core.py

index ddaf6e0aa3ef69394f145ab0127f6ec8d500f276..38a8743ac72e11b3ffa6f01bd9f7e8553a149189 100644 (file)
@@ -104,6 +104,7 @@ MIDDLEWARE_CLASSES = (
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.locale.LocaleMiddleware',
+    'debug_toolbar.middleware.DebugToolbarMiddleware',
 )
 
 ROOT_URLCONF = 'sandbox.urls'
@@ -130,6 +131,7 @@ INSTALLED_APPS = (
     'south',
     'sorl.thumbnail',
     'notes',
+    'debug_toolbar',
 )
 
 TEMPLATE_CONTEXT_PROCESSORS = (
index 6dd41922dfea4ac3dae3990a76498f7915349c24..fb0665ee7a2b96589e405b95f34b0e0d56defc6f 100644 (file)
@@ -26,4 +26,4 @@ urlpatterns = patterns('',
     # Languages
     (r'^i18n/', include('django.conf.urls.i18n')),    
     (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
-)
+    )
index f61b12550a33c9748228c21bf6cea4d00e79f107..ec2f9c0678ba3b342c889a2c2800d47bdef165f3 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -26,6 +26,8 @@ setup(
         'psutil',
         'pyyaml',
         'python-ebml'
+        'zipstream',
+        'debug_toolbar',
   ],
   platforms=['OS Independent'],
   license='CeCILL v2',
index e5c4d38794309745ab0b653ab3132896d4fc61e6..ba54781c89ad1095b2c4442458b928aefcced76e 100644 (file)
@@ -1207,6 +1207,9 @@ a.image-link {
 .icon_delete{
     background-image: url('../images/delete.png');
 }
+.icon_zip{
+    background-image: url('../images/zip.png');
+}
 .icon_rss,.icon_rss:hover{
     background: url('../images/feed-icon-14x14.png') no-repeat;
     background-position: 0ex .8ex;
diff --git a/telemeta/static/telemeta/images/zip.png b/telemeta/static/telemeta/images/zip.png
new file mode 100644 (file)
index 0000000..7e5d49a
Binary files /dev/null and b/telemeta/static/telemeta/images/zip.png differ
index 32962a2c113bb27ba55d7827f5da74884aa96c35..c4547b3b05a082a978bb6417395c84eacfc41a53 100644 (file)
@@ -25,7 +25,7 @@
 {% block javascript %}
 <script src="{% url django.views.i18n.javascript_catalog %}" type="text/javascript"></script>
 <!--<script src="{{ STATIC_URL }}telemeta/js/jquery-1.6.min.js" type="text/javascript"></script>-->
-<script src="{{ STATIC_URL }}timeside/js/libs/jquery-1.6.min.js" type="text/javascript"></script>
+<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" type="text/javascript"></script>
 <script src="{{ STATIC_URL }}telemeta/js/locale.js" type="text/javascript"></script>
 <script src="{{ STATIC_URL }}telemeta/js/application.js" type="text/javascript"></script>
 {% if user.is_authenticated %}
index 4b4cba10d4c0a094b293e4ee5ad7adc2ee7158c6..78cee3ab0bfd77c228214fc47568e48ed7875fc2 100644 (file)
       <a href="{% url telemeta-collection-additem collection.public_id %}" class="component_icon button icon_add">{% trans "Add item" %}</a>
      {% endif %}
     {% if user.is_authenticated %}
-    <a href=# id ="_add_to_playlist" class="component_icon button icon_add_to_playlist">{% trans "Add to playlist" %}</a>
+     <a href=# id="_add_to_playlist" class="component_icon button icon_add_to_playlist">{% trans "Add to playlist" %}</a>
+    {% if audio_export_enabled or perms.telemeta.can_download_all_items or user.is_superuser %}
+     <a href="{% url telemeta-collection-package collection.public_id %}" id="zip_package" class="component_icon button icon_zip">{% trans "Download" %} ZIP</a>
+    {% endif %}
     {% endif %}
    </div>
 {% endblock %}
index bb85197e1f9029d72ca4e9f7ad2dd65dfa9966c9..f91b992f7782c96395e80779d13fa17a2c7e1be4 100644 (file)
@@ -39,8 +39,8 @@ from django.conf import settings
 from django.views.generic.simple import redirect_to
 from telemeta.models import MediaItem, MediaCollection, MediaItemMarker, MediaCorpus, MediaFonds
 from telemeta.views import HomeView, AdminView, CollectionView, ItemView, \
-                                InstrumentView, InstrumentAliasView, PlaylistView, ProfileView, GeoView, \
-                                LastestRevisionsFeed, ResourceView, UserRevisionsFeed
+                            InstrumentView, InstrumentAliasView, PlaylistView, ProfileView, GeoView, \
+                            LastestRevisionsFeed, ResourceView, UserRevisionsFeed, CollectionPackageView
 from jsonrpc import jsonrpc_site
 import os.path
 import telemeta.config
@@ -170,7 +170,8 @@ urlpatterns = patterns('',
         dict(all_collections_sound, paginate_by=20, template_name="telemeta/collection_list.html"), name="telemeta-collections-sound"),
     # FIXME: need all paths
     url(r'^collections/(?P<path>[A-Za-z0-9._-s/]+)/$', redirect_to, {'url': '/archives/collections/%(path)s/', 'permanent': False}, name="telemeta-collection-redir"),
-
+    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/package/$', CollectionPackageView.as_view(),
+        name="telemeta-collection-package"),
     # RESOURCES
     # Corpus list
     url(r'^archives/corpus/$', 'django.views.generic.list_detail.object_list',
@@ -359,6 +360,10 @@ urlpatterns = patterns('',
             'document_root': settings.TELEMETA_CACHE_DIR,}),
 
     url(r'^', include('jqchat.urls')),
-)
 
+)
 
+if settings.DEBUG:
+    import debug_toolbar
+    urlpatterns += patterns('',
+    url(r'^__debug__/', include(debug_toolbar.urls)),)
\ No newline at end of file
index f2039d47eb45ee5cff2c3610f1555b6165c37999..a0aa61cbdb4ee739e1954865ea3adc906f7383c1 100644 (file)
@@ -160,27 +160,78 @@ class CollectionView(object):
         return render(request, template, {'collection': collection, 'formset': formset,})
 
 
-class CollectionPackageView(DetailView):
+class CollectionPackageView(View):
 
     model = MediaCollection
 
-    def render_to_reponse(self, context):
+    def get_object(self):
+        return MediaCollection.objects.get(public_id=self.kwargs['public_id'])
+
+    def get_stream(self, request, *args, **kwargs):
+        """
+        Stream a ZIP file of collection data
+        without loading the whole file into memory.
+        Based on ZipStream
+        """
+        from telemeta.views import MarkerView
+        from telemeta.backup import CollectionSerializer
+        import json
+        import zipstream
+        
+        z = zipstream.ZipFile()        
+        collection = MediaCollection.objects.get(public_id=public_id)
+        z.write(collection.code)
+        
+        for item in collection.items.all():
+            z.write(item.file.path)
+
+        try:
+            from django.http import StreamingHttpResponse
+            response = StreamingHttpResponse(z, content_type='application/zip')
+        except:
+            response = HttpResponse(z, content_type='application/zip')
+
+        response['Content-Disposition'] = "attachment; filename=%s.%s" % \
+                                             (item.code, 'zip')
+        return response
+    
+    @method_decorator(login_required)
+    def dispatch(self, *args, **kwargs):
+        return super(CollectionPackageView, self).dispatch(*args, **kwargs)
+
+
+
         """
         Create a ZIP file 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.
         """
+
         collection = self.get_object()
-        temp = tempfile.TemporaryFile()
-        archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)
+        tmp_dir = getattr(settings, "FILE_UPLOAD_TEMP_DIR")
+        if not tmp_dir:
+            tmp_dir = '/tmp'
+        temp = tempfile.TemporaryFile(prefix=tmp_dir+os.sep)
+        archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED, allowZip64=True)
+        serializer = CollectionSerializer(collection)
+        archive.writestr('%s/%s%s' % (collection.code, collection.code, '.xml'),
+                         serializer.get_xml().encode("utf-8"))
+
         for item in collection.items.all():
-            ext = item.file.path.splitext()[1]
-            archive.write(item.file, '%s.%s' % (code, ext))
+            if item.file:
+                ext = os.path.splitext(item.file.path)[1]
+                archive.write(item.file.path, '%s/%s%s' % (collection.code, item.code, ext))
+                marker_view = MarkerView()
+                markers = marker_view.get_markers(item.id)
+                if markers:
+                    archive.writestr('%s/%s%s' % (collection.code, item.code, '.json'), json.dumps(markers))
+
         archive.close()
-        wrapper = FileWrapper(temp)
+        wrapper = FixedFileWrapper(temp)
         response = HttpResponse(wrapper, content_type='application/zip')
+
         response['Content-Disposition'] = "attachment; filename=%s.%s" % \
-                                             (item.code, 'zip')
+                                             (collection.code, 'zip')
         response['Content-Length'] = temp.tell()
         temp.seek(0)
         return response
index 5cc102d1592f27709f7b21faabb296a97f6f1793..22d7d03c413fc9be0e0fe70dedfe585003eccf0c 100644 (file)
@@ -55,7 +55,7 @@ from django.http import HttpResponse, HttpResponseRedirect
 from django.http import Http404
 from django.shortcuts import render_to_response, redirect, get_object_or_404
 from django.views.generic import list_detail
-from django.views.generic import DetailView
+from django.views.generic import *
 from django.conf import settings
 from django.contrib import auth
 from django.contrib import messages