load and modify image. create and modify content.
authorcavaliet
Wed, 22 May 2013 16:19:09 +0200
changeset 27 badc36cf05d2
parent 26 ff669687a0d2
child 29 ec6a5592c617
child 30 ebecbb4597cc
load and modify image. create and modify content.
src/metadatacomposer/static/metadatacomposer/js/common.js
src/metadatacomposer/templates/metadatacomposer_home.html
src/metadatacomposer/templates/metadatacomposer_modal_image.html
src/metadatacomposer/templates/metadatacomposer_modal_video.html
src/metadatacomposer/templates/partial/resource_content_list.html
src/metadatacomposer/templatetags/__init__.py
src/metadatacomposer/templatetags/composer_tags.py
src/metadatacomposer/urls.py
src/metadatacomposer/views.py
--- a/src/metadatacomposer/static/metadatacomposer/js/common.js	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/static/metadatacomposer/js/common.js	Wed May 22 16:19:09 2013 +0200
@@ -6,28 +6,24 @@
 
 //open modal
     $(document).on('click', 'a.open-modal', function(e){
-        console.log("ntm 1");
         e.preventDefault();
-        console.log("ntm 2");
         var modalRemote = $(this).attr('href'),
             typeMedia = $(this).attr('data-type-media'),
             modalTitleInfo = $(this).attr('data-title'),
             hideBibliotheque = $(this).hasAttr('data-hide-bibliotheque') ? true : false,
             titleFront;
-        console.log("ntm 3");
+
         switch(typeMedia){
             case 'video' : titleFront = '<i class="icon-film"></i> Vidéo - '+modalTitleInfo; break;
             case 'image' : titleFront = '<i class="icon-picture"></i> Image - '+modalTitleInfo; break;
         }
         $('#modal-template .modal-header h3').html(titleFront);
 
-        console.log("ntm 4");
         $("#modal-template .modal-body").load(modalRemote, function() { 
             $("#modal-template").modal("show"); 
             if(hideBibliotheque)
                 $("#modal-template").find(".bibliotheque-link").hide();
         });
-        console.log("ntm 5");
 
     });
 
--- a/src/metadatacomposer/templates/metadatacomposer_home.html	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_home.html	Wed May 22 16:19:09 2013 +0200
@@ -79,7 +79,11 @@
             <article class="container">
                 <div class="row article-title">
                     <h3 class="span8"><i class="icon-film"></i> Dernières vidéos</h3>
-                    <div class="span4 wrap-btn-add"><a class="btn btn-success" href="#">Ajouter une vidéo <i class="icon-plus-sign"></i></a></div>
+                    <div class="span4 wrap-btn-add">
+                        <a data-type-media="video" data-title="Ajouter une vidéo" class="btn btn-success open-modal" 
+                         href="{% url composer_modal_video branding=branding %}" data-hide-bibliotheque>
+                         Ajouter une vidéo <i class="icon-plus-sign"></i></a>
+                    </div>
                 </div>
                 <div class="row">
                   {% for c in contents %}
--- a/src/metadatacomposer/templates/metadatacomposer_modal_image.html	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_modal_image.html	Wed May 22 16:19:09 2013 +0200
@@ -43,9 +43,9 @@
             </div>
         </div-->
         <div class="control-group input-image-upload">
-            <label class="control-label" for="media-url-link">Fichier de l'image :</label>
+            <label class="control-label" for="media-url-link">Fichier de l'image :<br/>(jpg, png)</label>
             <div class="controls">
-                <input type="file" name="image_file" id="id_image_file"/>
+                <input type="file" name="image_file" id="id_image_file" accept="image/jpeg, image/png"/>
                 <a href="#" class="btn btn-previsualisation" class="btn"><i class="icon-eye-open"></i> Prévisualiser</a>
                 {% if form.image_file.value %}
                 <p>Image actuelle :</p>
--- a/src/metadatacomposer/templates/metadatacomposer_modal_video.html	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/templates/metadatacomposer_modal_video.html	Wed May 22 16:19:09 2013 +0200
@@ -1,4 +1,6 @@
 {% load static %}
+{% load thumbnail %}
+{% load composer_tags %}
 <div class="row">
     <div class="span3">
         <ul class="modal-menu">
@@ -8,32 +10,40 @@
     </div>
     <div class="span8 offset1 popup-content">
 
-    <form class="row" action="#" method="post">
+    <form class="row" action="{% if content %}{% url composer_modal_video branding=branding iri_id=content.iri_id %}{% else %}{% url composer_modal_video branding=branding %}{% endif %}" enctype="multipart/form-data" method="post">
         <h4 class="span8">Informations sur la vidéo</h4>
         <div class="span4">
-            
-            <label for="title-media-video">Titre :</label>
-            <input type="text" id="title-media-video" name="">
-            <label for="description-title-media">Description :</label>
-            <textarea name="" id="description-title-media"></textarea>
+            {% csrf_token %}
+            <label for="id_content-title">Titre :</label>
+            <input type="text" name="content-title" id="id_content-title" {% if content %}value="{{ content.title }}"{% endif %}/>
+            <label for="id_content-description">Description :</label>
+            <textarea name="content-description" id="id_content-description">{% if content %}{{ content.description }}{% endif %}</textarea>
+            <input type="hidden" name="content-duration" id="id_content-duration" {% if content %}value="{{ content.duration }}"{% endif %}/>
+            <input type="hidden" name="content-media_input_type" id="id_content-media_input_type" value="create" />
+            <input type="hidden" name="content-iri_id" id="id_content-iri_id" value="{{ iri_id }}"/>
+            <input type="checkbox" name="media-media_public" id="id_media-media_public" checked="checked" style="display:none" />
         </div>
         <div class="span4">
             <label for="">Durée de la vidéo :</label>
             <div class="select-duration">
-                <input pattern="[0-9]*" name="" type="text" id="video-hour" class="number-spin span1" value="1">
+                <input pattern="[0-9]*" name="" type="text" id="video-hour" class="number-spin span1" value="{% if content %}{{ content.duration|to_hours }}{% else %}0{% endif %}">
                 <label for="video-hour">H</label>
-                <input pattern="[0-9]*" name="" type="text" id="video-minute" class="number-spin span1" value="1">
+                <input pattern="[0-9]*" name="" type="text" id="video-minute" class="number-spin span1" value="{% if content %}{{ content.duration|to_minutes }}{% else %}10{% endif %}">
                 <label for="video-minute">M</label>
-                <input pattern="[0-9]*" name="" type="text" id="video-seconde" class="number-spin span1" value="1">
+                <input pattern="[0-9]*" name="" type="text" id="video-seconde" class="number-spin span1" value="{% if content %}{{ content.duration|to_seconds }}{% else %}0{% endif %}">
                 <label for="video-seconde">S</label>
             </div>
-            <label for="">Vignette de la vidéo :</label>
-            <input type="file">
+            <label for="">Vignette de la vidéo (jpg, png, 1Mo max) :</label>
+            <input type="file" name="image" id="id_image" accept="image/jpeg, image/png" />
+            {% if content %}
+            <p>Image actuelle :</p>
+            {% thumbnail content.image "x60" crop="center" format="PNG" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />{% empty %}<img src="{% static 'metadatacomposer/img/60x60.gif' %}" width="60px" height="60px" />{% endthumbnail %}
+            {% endif %}
         </div>
         <div class="span8">
             <h4>Source de la vidéo</h4>
             <label for="">URL de la vidéo :</label>
-            <input type="text" class="input-xxlarge" placeholder="http://youtu.be">
+            <input type="text" class="input-xxlarge" placeholder="http://youtu.be" name="media-src" id="id_media-src" {% if content %}value="{{ content.media_obj.src }}"{% endif %}/>
             <div class="control-group">
                 <div class="controls">
                     <a href="#" class="btn-cancel btn btn-inverse"><i class="icon-reply" data-dismiss="modal" aria-hidden="true"></i> Annuler</a>
@@ -50,4 +60,9 @@
     max:60,
     min:0
 });
+// Update time input in milliseconds
+$('.select-duration .number-spin').change(function(){
+    $("#id_content-duration").val( (parseInt($("#video-hour").val()) * 3600000) + (parseInt($("#video-minute").val()) * 60000) + (parseInt($("#video-seconde").val()) * 1000) );
+    console.log($("#id_content-duration").val());
+});
 </script>
\ No newline at end of file
--- a/src/metadatacomposer/templates/partial/resource_content_list.html	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/templates/partial/resource_content_list.html	Wed May 22 16:19:09 2013 +0200
@@ -26,7 +26,7 @@
                                         </td>
                                         <td>{{ res.content.update_date|date:"Y/m/d" }}</td>
                                         <td>
-                                            <a data-type-media="video" data-title="Modifier une vidéo" class="btn open-modal" href="{% url composer_modal_video branding=branding %}"><i class="icon-pencil"></i></a>
+                                            <a data-type-media="video" data-title="Modifier une vidéo" class="btn open-modal" href="{% url composer_modal_video branding=branding iri_id=res.content.iri_id %}"><i class="icon-pencil"></i></a>
                                             <a class="btn btn-delete" data-title="Titre du média" href="#row-list-ressources-video-id1">
                                             <i class="icon-remove"></i>
                                         </a>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/metadatacomposer/templatetags/__init__.py	Wed May 22 16:19:09 2013 +0200
@@ -0,0 +1,1 @@
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/metadatacomposer/templatetags/composer_tags.py	Wed May 22 16:19:09 2013 +0200
@@ -0,0 +1,68 @@
+from django.template import Library, TemplateSyntaxError
+
+register = Library()
+
+@register.filter
+def to_hours(value, arg=None):
+    """Takes an integer value of milliseconds and write the hour duration"""
+    # Error management
+    if value is None :
+        return ""
+    if not isinstance(value, (int,long,float,str,unicode)) :
+        raise TemplateSyntaxError('str_duration value error : value must be integer or long or float or string. type = ' + str(type(value)))
+    if isinstance(value, (str,unicode)) :
+        try:
+            value = int(value)
+        except :
+            raise TemplateSyntaxError('str_duration value error : can not convert value "' + value + '" into integer')
+    # We take off the milliseconds
+    ms = abs(value)
+    sec = ms//1000
+    return (sec//3600)
+to_hours.is_safe = True
+
+
+@register.filter
+def to_minutes(value, arg=None):
+    """Takes an integer value of milliseconds and write the hour duration"""
+    # Error management
+    if value is None :
+        return ""
+    if not isinstance(value, (int,long,float,str,unicode)) :
+        raise TemplateSyntaxError('str_duration value error : value must be integer or long or float or string. type = ' + str(type(value)))
+    if isinstance(value, (str,unicode)) :
+        try:
+            value = int(value)
+        except :
+            raise TemplateSyntaxError('str_duration value error : can not convert value "' + value + '" into integer')
+    # We take off the milliseconds
+    ms = abs(value)
+    sec = ms//1000
+    hours = sec//3600
+    min = (sec - (hours * 3600))//60
+    return min
+to_minutes.is_safe = True
+
+
+@register.filter
+def to_seconds(value, arg=None):
+    """Takes an integer value of milliseconds and write the hour duration"""
+    # Error management
+    if value is None :
+        return ""
+    if not isinstance(value, (int,long,float,str,unicode)) :
+        raise TemplateSyntaxError('str_duration value error : value must be integer or long or float or string. type = ' + str(type(value)))
+    if isinstance(value, (str,unicode)) :
+        try:
+            value = int(value)
+        except :
+            raise TemplateSyntaxError('str_duration value error : can not convert value "' + value + '" into integer')
+    # We take off the milliseconds
+    ms = abs(value)
+    sec = ms//1000
+    hours = sec//3600
+    min = (sec - (hours * 3600))//60
+    sec = (sec - (hours * 3600) - (min*60))
+    return sec
+to_seconds.is_safe = True
+
--- a/src/metadatacomposer/urls.py	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/urls.py	Wed May 22 16:19:09 2013 +0200
@@ -10,6 +10,7 @@
     url(r'^(?P<branding>.*)/resourcelist/$', MetadataComposerResourceList.as_view(), name="composer_resource_list"),
     url(r'^(?P<branding>.*)/imagepage/$', MetadataComposerImagePagination.as_view(), name="composer_image_page"),
     url(r'^(?P<branding>.*)/contentpage/$', MetadataComposerContentPagination.as_view(), name="composer_content_page"),
+    url(r'^(?P<branding>.*)/modalvideo/(?P<iri_id>[\w-]+)$', MetadataComposerModalVideo.as_view(), name="composer_modal_video"),
     url(r'^(?P<branding>.*)/modalvideo/$', MetadataComposerModalVideo.as_view(), name="composer_modal_video"),
     url(r'^(?P<branding>.*)/modalimage/$', MetadataComposerModalImage.as_view(), name="composer_modal_image"),
     url(r'^(?P<branding>.*)/$', MetadataComposerHome.as_view(), name="composer_home"),
--- a/src/metadatacomposer/views.py	Tue May 21 18:01:07 2013 +0200
+++ b/src/metadatacomposer/views.py	Wed May 22 16:19:09 2013 +0200
@@ -3,9 +3,11 @@
 from django.core.paginator import Paginator, InvalidPage, EmptyPage
 from django.shortcuts import redirect
 from django.utils.decorators import method_decorator
+from django.views.decorators.cache import never_cache
 from django.views.generic.base import View, TemplateResponseMixin
-from django.views.generic.edit import FormView
 from ldt.ldt_utils.models import Project, Content
+from ldt.ldt_utils.views.content import write_content_base
+from ldt.ldt_utils.utils import generate_uuid
 from metadatacomposer.forms import ImageUploadModelForm
 from metadatacomposer.models import Image
 
@@ -32,6 +34,7 @@
         return "metadatacomposer_home.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerHome, self).dispatch(*args, **kwargs)
     
@@ -54,6 +57,7 @@
         return "metadatacomposer_project_list.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerProjectList, self).dispatch(*args, **kwargs)
     
@@ -84,6 +88,7 @@
         return "metadatacomposer_resource_list.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerResourceList, self).dispatch(*args, **kwargs)
     
@@ -107,6 +112,7 @@
         return "partial/resource_image_list.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerImagePagination, self).dispatch(*args, **kwargs)
     
@@ -128,6 +134,7 @@
         return "partial/resource_content_list.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerContentPagination, self).dispatch(*args, **kwargs)
     
@@ -193,13 +200,35 @@
         return "metadatacomposer_modal_video.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerModalVideo, self).dispatch(*args, **kwargs)
     
-    def get(self, request, branding="iri", **kwargs):
+    def get(self, request, branding="iri", iri_id=None, **kwargs):
         self.branding = branding
+        
+        # Generate fake id to validate ContentForm
+        if not iri_id:
+            iri_id = generate_uuid()
+            content = None
+        else:
+            content = Content.safe_objects.select_related("media_obj").get(iri_id=iri_id)
+        
         context = self.get_context_dict(request)
+        context.update({"iri_id":iri_id, "content":content})
         return self.render_to_response(context)
+    
+    def post(self, request, branding="iri", iri_id=None, **kwargs):
+        self.branding = branding
+        
+        # We create the media
+        content_form, media_form, picture_form, form_status, _, current_front_project, e, traceback = write_content_base(request, iri_id)
+        # And test creation
+        if (content_form == False and media_form == False and picture_form == False and form_status == False and current_front_project == False):
+            #message=_("An error occurred - Please try again or contact webmaster")
+            #title = _("Error")
+            raise e, None, traceback
+        return redirect(request.META['HTTP_REFERER'])
 
 
 
@@ -209,6 +238,7 @@
         return "metadatacomposer_modal_image.html"
     
     @method_decorator(login_required)
+    @method_decorator(never_cache)
     def dispatch(self, *args, **kwargs):
         return super(MetadataComposerModalImage, self).dispatch(*args, **kwargs)