create new empty project from content
authorcavaliet
Mon, 03 Jun 2013 18:05:01 +0200
changeset 72 132e14ee5173
parent 71 79974d302930
child 73 cf9ff1447944
create new empty project from content
src/metadatacomposer/static/metadatacomposer/js/common.js
src/metadatacomposer/static/metadatacomposer/js/edition.js
src/metadatacomposer/templates/metadatacomposer_edit.html
src/metadatacomposer/templates/metadatacomposer_home.html
src/metadatacomposer/templates/metadatacomposer_modal_content_library.html
src/metadatacomposer/templates/metadatacomposer_modal_image_library.html
src/metadatacomposer/templates/partial/library_content_list.html
src/metadatacomposer/urls.py
src/metadatacomposer/views.py
--- a/src/metadatacomposer/static/metadatacomposer/js/common.js	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/static/metadatacomposer/js/common.js	Mon Jun 03 18:05:01 2013 +0200
@@ -11,6 +11,7 @@
             typeMedia = $(this).attr('data-type-media'),
             modalTitleInfo = $(this).attr('data-title'),
             hideBibliotheque = $(this).hasAttr('data-hide-bibliotheque') ? true : false,
+            hideAddNew = $(this).hasAttr('data-hide-add-new') ? true : false,
             titleFront;
 
         switch(typeMedia){
@@ -23,12 +24,19 @@
             $("#modal-template").modal("show"); 
             if(hideBibliotheque)
                 $("#modal-template").find(".bibliotheque-link").hide();
+            if(hideAddNew)
+                $("#modal-template").find(".add-new").hide();
         });
 
     });
 
     $('.popup').on('click', '.popup-content a', function(e){
-        e.preventDefault();
+        
+        if($(this).hasClass('no-prevent')){
+            return true;
+        }else{
+            e.preventDefault();
+        }
         if($(this).hasClass('btn-cancel')){
             $(this).parents('.popup').modal('hide');
         }
--- a/src/metadatacomposer/static/metadatacomposer/js/edition.js	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/static/metadatacomposer/js/edition.js	Mon Jun 03 18:05:01 2013 +0200
@@ -79,10 +79,10 @@
             url_transform: function(src) {
                 return [{
                     type: "video/mp4",
-                    src: src.replace(/\.[\d\w]+$/,'.mp4').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
+                    src: src.replace(/\.[\d\w]+$/,'.mp4')
                 }, {
                     type: "video/webm",
-                    src: src.replace(/\.[\d\w]+$/,'.webm').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
+                    src: src.replace(/\.[\d\w]+$/,'.webm')
                 }];
             }
         }
@@ -498,10 +498,10 @@
             var currentTimePlusUnMin = 60 * 1000 + myMedia.currentTime,
                 endAnnotation = (currentTimePlusUnMin<myMedia.duration) ? currentTimePlusUnMin : myMedia.duration;
             var dataAnnotation = {
-                title : 'Nouveau',
+                title : '',
                 begin : myMedia.currentTime,
                 end : endAnnotation,
-                description : 'description',
+                description : '',
                 type : type,
                 keywords : []
             };
@@ -884,9 +884,11 @@
                 left : left,
                 width :width
             });
-
-
-
+        },
+        start : function(){
+            var idSlider = $(this).attr('data-id'),
+                annotationTimeline = $('#annotation-timeline-'+ data.id);
+            annotationTimeline.css('z-index',100);
         },
         stop : function(){
             renderAnnotation()
--- a/src/metadatacomposer/templates/metadatacomposer_edit.html	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_edit.html	Mon Jun 03 18:05:01 2013 +0200
@@ -16,6 +16,7 @@
     <link href="{% static 'metadatacomposer/lib/CLEditor/jquery.cleditor.css' %}" rel="stylesheet">
     <link href="{% static 'metadatacomposer/lib/tag-it/css/jquery.tagit.css' %}" rel="stylesheet">
     <link href="{% static 'metadatacomposer/css/style.css' %}" rel="stylesheet">
+    {% include top_header_css %}
 </head>
 <body>
     <div class="wrap">
--- a/src/metadatacomposer/templates/metadatacomposer_home.html	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_home.html	Mon Jun 03 18:05:01 2013 +0200
@@ -48,7 +48,11 @@
             <article class="container">
                 <div class="row article-title">
                     <h3 class="span8"><i class="icon-file"></i> Derniers projets</h3>
-                    <div class="span4 wrap-btn-add"><a class="btn btn-success" href="#">Ajouter un projet <i class="icon-plus-sign"></i></a></div>
+                    <div class="span4 wrap-btn-add">
+                        <a data-type-media="video" data-title="Ajouter un projet" class="btn btn-success open-modal" 
+                            href="{% url 'composer_modal_content_library' branding=branding %}?mode=create" data-hide-add-new>
+                            Ajouter un projet <i class="icon-plus-sign"></i></a>
+                    </div>
                 </div>
                 <div class="row">
                   {% for p in projects %}
@@ -118,6 +122,42 @@
   {% endblock %}
   {% block js_page %}
     <script src="{% static 'metadatacomposer/js/home.js' %}"></script>
+    <script type="text/javascript">
+    $(document).on('click', 'a.content_pagination', function(e){
+        e.preventDefault();e.stopPropagation();
+        var url = $(this).attr('href');
+        $(this).addClass("loader");
+        $.ajax({
+            url: url,
+            cache: false,
+            type: 'GET',
+            success: function(data, status, request) {
+                $("#content_list_container").html(data);
+            },
+            error: function(jqXHR, textStatus, errorThrown) {
+                resp = $.parseJSON(jqXHR.responseText);
+                alert(resp.message);
+            }
+        });
+    });
+    $(document).on('click', 'a.content_pagination_library', function(e){
+        e.preventDefault();e.stopPropagation();
+        var url = $(this).attr('href');
+        $(this).addClass("loader");
+        $.ajax({
+            url: url,
+            cache: false,
+            type: 'GET',
+            success: function(data, status, request) {
+                $("#content_list_container_library").html(data);
+            },
+            error: function(jqXHR, textStatus, errorThrown) {
+                resp = $.parseJSON(jqXHR.responseText);
+                alert(resp.message);
+            }
+        });
+    });
+    </script>
   {% endblock %}
 {% endblock %}
 {% analytics %}
--- a/src/metadatacomposer/templates/metadatacomposer_modal_content_library.html	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_modal_content_library.html	Mon Jun 03 18:05:01 2013 +0200
@@ -4,7 +4,7 @@
     <div class="span3">
         <ul class="modal-menu">
             <li><a class="btn active" tabindex="-1" href="#"><i class="icon-folder-open"></i> Bibliothèque</a></li>
-            <li><a class="btn open-modal" data-type-media="video" data-title="Ajouter une vidéo" tabindex="-1" href="{% url 'composer_modal_content' branding=branding %}"><i class="icon-plus-sign"></i> Ajouter une vidéo</a></li>
+            <li><a class="add-new btn open-modal" data-type-media="video" data-title="Ajouter une vidéo" tabindex="-1" href="{% url 'composer_modal_content' branding=branding %}"><i class="icon-plus-sign"></i> Ajouter une vidéo</a></li>
         </ul>
     </div>
     <div class="span8 popup-content bibliotheque-video" id="content_list_container_library">
--- a/src/metadatacomposer/templates/metadatacomposer_modal_image_library.html	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_modal_image_library.html	Mon Jun 03 18:05:01 2013 +0200
@@ -4,7 +4,7 @@
     <div class="span3">
         <ul class="modal-menu">
             <li><a class="btn active" tabindex="-1" href="#"><i class="icon-folder-open"></i> Bibliothèque</a></li>
-            <li><a class="btn open-modal" data-type-media="image" data-title="Ajouter une image" tabindex="-1" href="{% url 'composer_modal_image' branding=branding %}"><i class="icon-plus-sign"></i> Ajouter une image</a></li>
+            <li><a class="add-new btn open-modal" data-type-media="image" data-title="Ajouter une image" tabindex="-1" href="{% url 'composer_modal_image' branding=branding %}"><i class="icon-plus-sign"></i> Ajouter une image</a></li>
         </ul>
     </div>
     <div class="span8 popup-content bibliotheque-image" id="image_list_container_library">
--- a/src/metadatacomposer/templates/partial/library_content_list.html	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/templates/partial/library_content_list.html	Mon Jun 03 18:05:01 2013 +0200
@@ -5,9 +5,10 @@
         <div class="row">
           {% for res in content_results %}
             <div class="span2">
-                <a data-url="{{ res.content.url }}"
+                <a {% if mode == "create" %}class="no-prevent" href="{% url 'composer_new_project' branding=branding iri_id=res.content.iri_id %}"
+                   {% else %}href="#" data-url="{{ res.content.url }}"{% endif %}
                    data-title="{{ res.content.title }}"
-                   data-description="{{ res.content.description|default_if_none:"" }}" href="#">
+                   data-description="{{ res.content.description|default_if_none:'' }}" >
                    {% thumbnail res.content.image "140x140" crop="center" format="PNG" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />{% empty %}<img src="{% static 'metadatacomposer/img/140x140.gif' %}" width="140px" height="140px" />{% endthumbnail %}
                 <h5>{{ res.content.title }}</h5></a>
             </div>
@@ -16,7 +17,7 @@
         <div class="pagination">
             <ul>
             {% if content_results.has_previous %}
-                <li><a href="{% url 'composer_content_page' branding=branding %}?page={{ content_results.previous_page_number }}&mode=library" class="content_pagination_library">{% trans "Previous" %}</a></li>
+                <li><a href="{% url 'composer_content_page' branding=branding %}?page={{ content_results.previous_page_number }}&mode={{ mode }}" class="content_pagination_library">{% trans "Previous" %}</a></li>
             {% else %}
                <li class="disabled"><a>{% trans "Previous" %}</a></li>
             {% endif %}
@@ -25,17 +26,17 @@
               {% if i|add:'1' == content_results.number %}
                 <li class="active"><a href="#">{{i|add:'1'}}</a></li>
               {% else %}
-                <li><a href="{% url 'composer_content_page' branding=branding %}?page={{i|add:'1'}}&mode=library" class="content_pagination_library">{{i|add:'1'}}</a></li>
+                <li><a href="{% url 'composer_content_page' branding=branding %}?page={{i|add:'1'}}&mode={{ mode }}" class="content_pagination_library">{{i|add:'1'}}</a></li>
               {% endif %}
              {% endfor %}
             {% endif %}
             {% if content_results.has_next %}
-                <li><a href="{% url 'composer_content_page' branding=branding %}?page={{ content_results.next_page_number }}&mode=library" class="content_pagination_library">{% trans "Next" %}</a></li>
+                <li><a href="{% url 'composer_content_page' branding=branding %}?page={{ content_results.next_page_number }}&mode={{ mode }}" class="content_pagination_library">{% trans "Next" %}</a></li>
             {% else %}
                <li class="disabled"><a>{% trans "Next" %}</a></li>
             {% endif %}
             {% if content_results.paginator.num_pages > 1 %}
-                <li><a href="{% url 'composer_content_page' branding=branding %}?page=x&mode=library" class="content_pagination_library">({% trans "All" %})</a></li>
+                <li><a href="{% url 'composer_content_page' branding=branding %}?page=x&mode={{ mode }}" class="content_pagination_library">({% trans "All" %})</a></li>
             {% endif %}
             </ul>
         </div>
\ No newline at end of file
--- a/src/metadatacomposer/urls.py	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/urls.py	Mon Jun 03 18:05:01 2013 +0200
@@ -6,7 +6,8 @@
     MetadataComposerRemoveImage, MetadataComposerRemoveContent,\
     MetadataComposerRemoveProject, MetadataComposerImage,\
     MetadataComposerModalContentLibrary, MetadataComposerPlayer,\
-    MetadataComposerPreviewPlayer, MetadataComposerEdit
+    MetadataComposerPreviewPlayer, MetadataComposerEdit,\
+    MetadataComposerNewProject
 
 urlpatterns = patterns('',
     url(r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog', name='jsi18n'),
@@ -26,6 +27,7 @@
     url(r'^(?P<branding>.*)/player/(?P<ldt_id>[\w-]+)/$', MetadataComposerPlayer.as_view(), name="composer_player"),
     url(r'^(?P<branding>.*)/previewplayer/(?P<ldt_id>[\w-]+)/$', MetadataComposerPreviewPlayer.as_view(), name="composer_preview_player"),
     url(r'^(?P<branding>.*)/edit/(?P<ldt_id>[\w-]+)/$', MetadataComposerEdit.as_view(), name="composer_edit"),
+    url(r'^(?P<branding>.*)/newproject/(?P<iri_id>[\w-]+)/$', MetadataComposerNewProject.as_view(), name="composer_new_project"),
     url(r'^(?P<branding>.*)/$', MetadataComposerHome.as_view(), name="composer_home"),
     url(r'^$', MetadataComposerHome.as_view(), name="composer_home"),
 )
--- a/src/metadatacomposer/views.py	Mon Jun 03 17:47:15 2013 +0200
+++ b/src/metadatacomposer/views.py	Mon Jun 03 18:05:01 2013 +0200
@@ -1,11 +1,13 @@
 from django.conf import settings
 from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import Group
 from django.core.paginator import Paginator, InvalidPage, EmptyPage
 from django.http import HttpResponse, HttpResponseBadRequest
 from django.shortcuts import redirect, get_object_or_404
 from django.utils.decorators import method_decorator
 from django.views.decorators.cache import never_cache
 from django.views.generic.base import View, TemplateResponseMixin
+from guardian.shortcuts import assign
 from ldt.ldt_utils.models import Project, Content
 from ldt.ldt_utils.views.content import write_content_base, delete_content
 from ldt.ldt_utils.utils import generate_uuid
@@ -14,6 +16,7 @@
 from metadatacomposer.models import Image
 from sorl.thumbnail import get_thumbnail
 import os
+import datetime
 
 
 import logging #@UnresolvedImport
@@ -159,15 +162,19 @@
         page = request.GET.get("page") or 1
         mode = request.GET.get("mode") or "resource"
         select_media = False
+        create_empty_project = False
         if mode=="library":
             self.template_name = "partial/library_content_list.html"
             select_media = True
+        elif mode=="create":
+            self.template_name = "partial/library_content_list.html"
+            create_empty_project = True
         
         # Get current contents page and theirs projects
-        content_results = get_contents_and_projects(page, request.user, select_media)
+        content_results = get_contents_and_projects(page, request.user, select_media, create_empty_project)
         
         context = self.get_context_dict(request)
-        context.update({"content_results":content_results})
+        context.update({"content_results":content_results, "mode":mode})
         return self.render_to_response(context)
 
 
@@ -190,7 +197,7 @@
 
 
 
-def get_contents_and_projects(page, user, select_media=False):
+def get_contents_and_projects(page, user, select_media=False, create_empty_project=False):
     
     # We get the current's page contents
     # prefetch_related("project_set") is unfortunately useless because we have to filter the project queryset later
@@ -213,6 +220,8 @@
         # We filter the content's projects with the user's ones
         if select_media:
             content.url = content.videopath.rstrip('/') + "/" + content.src
+        elif create_empty_project:
+            content.url = "create_project_for_me"
         projects = content.project_set.all().filter(owner=user)
         results_object_list.append({"content":content, "projects":projects})
     
@@ -259,6 +268,32 @@
 
 
 
+class MetadataComposerModalContentLibrary(TemplateResponseMixin, MetadataComposerContextView):
+    
+    def get_template_names(self):
+        return "metadatacomposer_modal_content_library.html"
+    
+    @method_decorator(login_required)
+    @method_decorator(never_cache)
+    def dispatch(self, *args, **kwargs):
+        return super(MetadataComposerModalContentLibrary, self).dispatch(*args, **kwargs)
+    
+    def get(self, request, branding="iri", **kwargs):
+        self.branding = branding
+        mode = request.GET.get("mode") or None
+        
+        select_media = True
+        create_empty_project = False
+        if mode=="create":
+            select_media = False
+            create_empty_project = True
+        
+        context = self.get_context_dict(request)
+        context.update({"content_results":get_contents_and_projects(1, request.user, select_media, create_empty_project), "mode":mode})
+        return self.render_to_response(context)
+
+
+
 class MetadataComposerModalImage(TemplateResponseMixin, MetadataComposerContextView):
     
     def get_template_names(self):
@@ -321,25 +356,6 @@
 
 
 
-class MetadataComposerModalContentLibrary(TemplateResponseMixin, MetadataComposerContextView):
-    
-    def get_template_names(self):
-        return "metadatacomposer_modal_content_library.html"
-    
-    @method_decorator(login_required)
-    @method_decorator(never_cache)
-    def dispatch(self, *args, **kwargs):
-        return super(MetadataComposerModalContentLibrary, self).dispatch(*args, **kwargs)
-    
-    def get(self, request, branding="iri", **kwargs):
-        self.branding = branding
-        
-        context = self.get_context_dict(request)
-        context.update({"content_results":get_contents_and_projects(1, request.user, True)})
-        return self.render_to_response(context)
-
-
-
 class MetadataComposerRemoveImage(View):
     
     @method_decorator(login_required)
@@ -514,3 +530,31 @@
 
 
 
+class MetadataComposerNewProject(View):
+    
+    @method_decorator(login_required)
+    def get(self, request, branding="iri", iri_id=None, **kwargs):
+        self.branding = branding
+        # Get content and creator user
+        content = get_object_or_404(Content.safe_objects, iri_id=iri_id)
+        contents = [ content, ]
+        u = request.user
+        # Create project
+        project = Project.create_project(title="Project on " + content.title + " " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
+                                         user=u, contents=contents, 
+                                         description='', 
+                                         set_icon=False)
+        # Set project state to "published" and save
+        project.state = 2
+        project.save()
+        assign('view_project', u, project)
+        assign('change_project', u, project)
+        # Since the project is published by default, we assign permission for the everyone group
+        everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME)
+        assign('ldt_utils.view_project', everyone, project)
+
+        # Redirect to project edition in composer interface
+        return redirect('composer_edit', branding=branding, ldt_id=project.ldt_id)
+
+
+