]> git.parisson.com Git - telemeta.git/commitdiff
fix item and collection code validation with ValidationError
authoryomguy <yomguy@parisson.com>
Wed, 4 May 2011 12:25:47 +0000 (14:25 +0200)
committeryomguy <yomguy@parisson.com>
Wed, 4 May 2011 12:25:47 +0000 (14:25 +0200)
telemeta/__init__.py
telemeta/htdocs/css/telemeta.css
telemeta/models/__init__.py
telemeta/models/media.py
telemeta/templates/telemeta_default/base.html
telemeta/templates/telemeta_default/collection_add.html
telemeta/templates/telemeta_default/collection_edit.html
telemeta/templates/telemeta_default/mediaitem_add.html
telemeta/templates/telemeta_default/mediaitem_copy.html
telemeta/templates/telemeta_default/mediaitem_edit.html
telemeta/web/base.py

index 12c89576e2c4ee5927aa9ca581e631de20c50419..d83fcaca50e712a8363a5112522b87d59ad5b524 100644 (file)
@@ -12,7 +12,7 @@ U{http://telemeta.org}
 """
 
 __docformat__ = 'epytext en'
-__version__ = '0.7.2'
+__version__ = '0.8'
 __url__ = 'http://telemeta.org'
 __copyright__ = '(C) 2007-2011 Parisson'
 __license__ = 'CeCILL-2'
index 8562ae99b06a49a3c7e1ffa6f8978f0da39c99a1..9d91a01871f7c681535ca883bfca374215f8cd9a 100644 (file)
@@ -792,6 +792,12 @@ table td.error {
     font-weight: bold;
 }
 
+.infos li.error{
+    color: red; 
+    font-weight: bold;
+    font-size: 110%;
+}
+
 .gmap {
     border: solid 1px #888;
     margin-top: 0.8em;
index 5dd06929e4edbe0a8a8254aa4cafd21723ad024b..72aa524c4b4a53dcd0dd6cc8722e4bc4b75f9edd 100644 (file)
@@ -38,3 +38,4 @@ from telemeta.models.instrument import *
 from telemeta.models.enum import *
 from telemeta.models.system import *
 
+
index f59e5a1be194c4c3daf65358caeb2d6319b969b4..07dd5a15fbb61bdf5e4551850244f4db9ceda2fd 100644 (file)
 
 from django.contrib.auth.models import User
 from django.utils.translation import ugettext_lazy as _
+from django.core.exceptions import ValidationError
 from telemeta.models.core import *
 from telemeta.models.enum import ContextKeyword
 from telemeta.util.unaccent import unaccent_icmp
 import re
 from telemeta.models.location import LocationRelation, Location
 from telemeta.models.system import Revision
-from telemeta.models import query
+from telemeta.models.query import *
 from django.forms import ModelForm
 
+
 class MediaResource(ModelCore):
     "Base class of all media objects"
 
@@ -66,16 +68,24 @@ class MediaResource(ModelCore):
     class Meta:
         abstract = True
 
+
+collection_published_code_regex   = '[A-Za-z0-9._-]*'
+collection_unpublished_code_regex = '[A-Za-z0-9._-]*'
+collection_code_regex             = '(?:%s|%s)' % (collection_published_code_regex, 
+                                                    collection_unpublished_code_regex)
+                                                        
 class MediaCollection(MediaResource):
     "Describe a collection of items"
     element_type = 'collection'
     PUBLIC_ACCESS_CHOICES = (('none', 'none'), ('metadata', 'metadata'), ('full', 'full'))
 
-    published_code_regex   = '[A-Za-z0-9._-]*'
-    unpublished_code_regex = '[A-Za-z0-9._-]*'
-    code_regex             = '(?:%s|%s)' % (published_code_regex, unpublished_code_regex)
+    def is_valid_collection_code(value):
+        "Check if the collection code is well formed"
+        regex = '^' + collection_code_regex + '$'
+        if not re.match(regex, value):
+            raise ValidationError(u'%s is not a valid collection code' % value)
     
-    code                  = CharField(_('code'), unique=True, required=True)
+    code                  = CharField(_('code'), unique=True, required=True, validators=[is_valid_collection_code])
     old_code              = CharField(_('old code'), unique=True, null=True)
     reference             = CharField(_('reference'), unique=True, null=True)
     title                 = CharField(_('title'), required=True)
@@ -125,7 +135,7 @@ class MediaCollection(MediaResource):
     public_access         = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES, 
                                       max_length=16, default="metadata")
 
-    objects               = query.MediaCollectionManager()
+    objects               = MediaCollectionManager()
 
     def __unicode__(self):
         if self.title:
@@ -179,29 +189,13 @@ class MediaCollection(MediaResource):
         duration = Duration()
         for item in self.items.all():
             duration += item.computed_duration()
-
         return duration
+        
     computed_duration.verbose_name = _('computed duration')        
-
-    def is_valid_code(self, code):
-        "Check if the collection code is well formed"
-        if self.is_published:
-            regex = '^' + self.published_code_regex + '$'
-        else:
-            regex = '^' + self.unpublished_code_regex + '$'
-           
-        if re.match(regex, code):
-            return True
-
-        return False
-
-    def save(self, force_insert=False, force_update=False, user=None):
-        if not self.code:
-            raise RequiredFieldError(self, self._meta.get_field('code'))
-        if not self.is_valid_code(self.code):
-            raise MediaInvalidCodeError("%s is not a valid code for this collection" % self.code)
+            
+    def save(self, force_insert=False, force_update=False, user=None, code=None):
         super(MediaCollection, self).save(force_insert, force_update)
-
+        
     class Meta(MetaCore):
         db_table = 'media_collections'
     
@@ -209,15 +203,16 @@ class MediaCollectionForm(ModelForm):
     class Meta:
         model = MediaCollection
 
+
+item_published_code_regex    = '[A-Za-z0-9._-]*'
+item_unpublished_code_regex  = '[A-Za-z0-9._-]*'
+item_code_regex              = '(?:%s|%s)' % (item_published_code_regex, item_unpublished_code_regex)
+
 class MediaItem(MediaResource):
     "Describe an item"
     element_type = 'item'
     PUBLIC_ACCESS_CHOICES = (('none', 'none'), ('metadata', 'metadata'), ('full', 'full'))
 
-    published_code_regex    = '[A-Za-z0-9._-]*'
-    unpublished_code_regex  = '[A-Za-z0-9._-]*'
-    code_regex              = '(?:%s|%s)' % (published_code_regex, unpublished_code_regex)
-
     collection            = ForeignKey('MediaCollection', related_name="items", 
                                        verbose_name=_('collection'))
     title                 = CharField(_('title'))
@@ -250,7 +245,7 @@ class MediaItem(MediaResource):
     file                  = FileField(_('file'), upload_to='items/%Y/%m/%d', db_column="filename")
     public_access         = CharField(_('public access'), choices=PUBLIC_ACCESS_CHOICES, max_length=16, default="metadata")
 
-    objects               = query.MediaItemManager()
+    objects               = MediaItemManager()
 
     def keywords(self):
         return ContextKeyword.objects.filter(item_relations__item = self)
@@ -269,21 +264,20 @@ class MediaItem(MediaResource):
         "Check if the item code is well formed"
         if not re.match('^' + self.collection.code, self.code):
             return False
-
         if self.collection.is_published:
-            regex = '^' + self.published_code_regex + '$'
+            regex = '^' + item_published_code_regex + '$'
         else:
-            regex = '^' + self.unpublished_code_regex + '$'
-
+            regex = '^' + item_unpublished_code_regex + '$'
         if re.match(regex, code):
             return True
-
         return False
 
-    def save(self, force_insert=False, force_update=False):
+    def clean(self):
         if self.code and not self.is_valid_code(self.code):
-            raise MediaInvalidCodeError("%s is not a valid item code for collection %s" 
+            raise ValidationError("%s is not a valid item code for collection %s" 
                                         % (self.code, self.collection.code))
+                                        
+    def save(self, force_insert=False, force_update=False):
         super(MediaItem, self).save(force_insert, force_update)
 
     def computed_duration(self):
@@ -373,9 +367,7 @@ class PlaylistResource(ModelCore):
 
     class Meta(MetaCore):
         db_table = 'playlist_resources'
-
-class MediaInvalidCodeError(Exception):
-    pass
+        
 
 class MediaItemMarker(MediaResource):
     "2D marker object : text value vs. time"
index c3b918bc019ec7ea8d325a0321d429712dd21c9e..12a28249e83f00f1657e5fb654e59a65fb8d23ef 100644 (file)
@@ -24,7 +24,7 @@
 
 {% block extra_javascript %}{% endblock %}
 
-{% if user.is_authenticated and perms.telemeta.change_mediaitem %}
+{% if user.is_authenticated %}
     <script type='text/javascript'>var CURRENT_USER_NAME="{{ user.username }}";</script>
 {% else %}
     <script type='text/javascript'>var CURRENT_USER_NAME=undefined;</script>
index 800d748d6b0ea7678f2d81b140391dca85c166f4..d83fcb84ec61ff04860250c586d4fb20d16c6a62 100644 (file)
@@ -11,6 +11,7 @@
 {% block infos %}
         <div class="infos">
         <form method="POST" id ="_addCollectionForm" action="">{% csrf_token %}
+        <ul>{% for error in form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}</ul>
         <table>
         {% for field in form %}
             {% if not field.html_name == "copied_from_item" %}
index 18ec62dbc51a65a4dfe4655409d7185bfcb8756d..7c585d3dbf068ceef8a58f2f7d664b867a6679d2 100644 (file)
@@ -10,8 +10,9 @@
 {% endblock %}
 
 {% block infos %}
-        <div class="infos">
-        <form method="POST" id="_editCollectionForm" action="">{% csrf_token %}
+     <div class="infos">
+      <form method="POST" id="_editCollectionForm" action="">{% csrf_token %}
+      <ul>{% for error in form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}</ul>
        <table>
        {% for field in form %}
         {% if not field.html_name == "copied_from_item" %}
@@ -27,6 +28,6 @@
          <a href="#" class="component_icon button icon_save"
    onclick="document.getElementById('_editCollectionForm').submit(); return false;">{% trans "Save" %}</a>
         </div>
-        </form>
-        </div>
+      </form>
+     </div>
 {% endblock infos%}
index e2bdec6c90ff5e5d6521e5421e6a5417d7bb33cd..632ed5440b8414c0c3273e754c0b757ea8d2e975 100644 (file)
@@ -20,6 +20,7 @@
     {% block infos %}
     <div class="infos">
      <form method="POST" id="_addItemForm" action="" enctype="multipart/form-data">{% csrf_token %}
+       <ul>{% for error in form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}</ul>
        <table>
        {% for field in form %}
         {% if not field.html_name == "copied_from_item" %}
index b503d3b13905c9360fb3330b3d483e9b96a84754..23767a05fdd1c0a0d6e7b5dde536274406f8c27a 100644 (file)
@@ -20,6 +20,7 @@
   {% block infos %}    
     <div class="infos">
      <form enctype="multipart/form-data" id="_mediaItemCopyForm" method="POST" action="">{% csrf_token %}
+     <ul>{% for error in form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}</ul>
       <table>
        {% for field in form %}
         {% if not field.html_name == "copied_from_item" %}
index 7aabeed3939aabf1fcc2f5662859ec587260d6b6..542e4fc323bb7f9463e34a6ed05c5764c79d4255 100644 (file)
@@ -12,6 +12,7 @@
   {% block infos %}    
     <div class="infos">
      <form enctype="multipart/form-data" id="_editItemForm" method="POST" action="">{% csrf_token %}
+     <ul>{% for error in form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}</ul>
       <table>
        {% for field in form %}
         {% if not field.html_name == "copied_from_item" %}
index d7100fc9af7e1ce9441d7c161633a849e0c512df..18f39a7fbf3b72b8a319ffb573549ffc49233f2b 100644 (file)
@@ -366,7 +366,7 @@ class WebView(object):
         else:
             form = MediaItemForm(instance=item)
         
-        return render(request, template, {'item': item, "form": form})
+        return render(request, template, {'item': item, 'form': form})
     
     @method_decorator(permission_required('telemeta.add_mediaitem'))
     def item_copy(self, request, public_id, template='telemeta/mediaitem_copy.html'):