v1.53 : tagging to taggit migration V01.53
authorcavaliet
Thu, 10 Apr 2014 15:55:47 +0200
changeset 1296 1a24fb79eb11
parent 1295 75b5e67ec752
child 1297 eb12e89fdbb1
v1.53 : tagging to taggit migration
.settings/org.eclipse.core.resources.prefs
src/ldt/ldt/__init__.py
src/ldt/ldt/api/ldt/resources/segment.py
src/ldt/ldt/api/ldt/resources/tag.py
src/ldt/ldt/indexation/search_indexes.py
src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/annotation_text.txt
src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/content_text.txt
src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/segment_text.txt
src/ldt/ldt/ldt_utils/contentindexer.py
src/ldt/ldt/ldt_utils/forms.py
src/ldt/ldt/ldt_utils/migrations/0029_tagging_to_taggit.py
src/ldt/ldt/ldt_utils/models.py
src/ldt/ldt/ldt_utils/segmentserializer.py
src/ldt/ldt/ldt_utils/templates/front/front_all_contents.html
src/ldt/ldt/ldt_utils/templates/front/front_home.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/contentslist.html
src/ldt/ldt/ldt_utils/views/content.py
src/ldt/ldt/ldt_utils/views/front.py
src/ldt/ldt/ldt_utils/views/workspace.py
src/ldt/ldt/settings.py
src/ldt/ldt/templatetags/taggit_extras_ldt.py
src/ldt/ldt/text/migrations/0003_auto__del_field_annotation_tags_field.py
src/ldt/ldt/text/models.py
--- a/.settings/org.eclipse.core.resources.prefs	Thu Apr 03 15:58:25 2014 +0200
+++ b/.settings/org.eclipse.core.resources.prefs	Thu Apr 10 15:55:47 2014 +0200
@@ -1,4 +1,3 @@
-#Thu Sep 19 17:16:28 CEST 2013
 eclipse.preferences.version=1
 encoding//src/ldt/ldt/core/migrations/0001_initial.py=utf-8
 encoding//src/ldt/ldt/core/migrations/0002_auto__del_owner.py=utf-8
@@ -38,6 +37,7 @@
 encoding//src/ldt/ldt/ldt_utils/migrations/0026_set_relative_ldtproject.py=utf-8
 encoding//src/ldt/ldt/ldt_utils/migrations/0027_auto__chg_field_project_owner__chg_field_media_creator.py=utf-8
 encoding//src/ldt/ldt/ldt_utils/migrations/0028_all_users_in_everyone.py=utf-8
+encoding//src/ldt/ldt/ldt_utils/migrations/0029_tagging_to_taggit.py=utf-8
 encoding//src/ldt/ldt/ldt_utils/views/json.py=utf-8
 encoding//src/ldt/ldt/management/commands/synciri.py=utf-8
 encoding//src/ldt/ldt/management/commands/updateiriurlinprojects.py=utf-8
@@ -45,6 +45,7 @@
 encoding//src/ldt/ldt/test/test_runner.py=utf-8
 encoding//src/ldt/ldt/text/migrations/0001_initial.py=utf-8
 encoding//src/ldt/ldt/text/migrations/0002_auto__chg_field_annotation_external_id.py=utf-8
+encoding//src/ldt/ldt/text/migrations/0003_auto__del_field_annotation_tags_field.py=utf-8
 encoding//src/ldt/ldt/user/migrations/0001_initial.py=utf-8
 encoding//src/ldt/ldt/user/migrations/0005_add_permission_owner_group.py=utf-8
 encoding//src/ldt/ldt/user/migrations/0008_auto__chg_field_groupprofile_image__chg_field_groupprofile_group__chg_.py=utf-8
--- a/src/ldt/ldt/__init__.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/__init__.py	Thu Apr 10 15:55:47 2014 +0200
@@ -1,6 +1,6 @@
 __all__ = ["VERSION", "get_version", "__version__"]
 
-VERSION = (1, 52, 7, "final", 0)
+VERSION = (1, 53, 0, "final", 0)
 
 
 def get_version():
--- a/src/ldt/ldt/api/ldt/resources/segment.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/api/ldt/resources/segment.py	Thu Apr 10 15:55:47 2014 +0200
@@ -101,7 +101,7 @@
                     Q(start_ts__gte=begin, start_ts__lte=end) |                            # segment starts between begin and end
                     Q(start_ts__gte=begin-F('duration'), start_ts__lte=end-F('duration')) |# segment ends between begin and end
                     Q(start_ts__lte=begin, start_ts__gte=end-F('duration'))                # period [begin:end] is included in the segment
-                    ).select_related("project_obj")
+                    ).select_related("project_obj").prefetch_related("tags")
         
         a = SegmentSerializer(content, segments)
         return self.create_response(request, a.serialize_to_cinelab())
--- a/src/ldt/ldt/api/ldt/resources/tag.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/api/ldt/resources/tag.py	Thu Apr 10 15:55:47 2014 +0200
@@ -1,9 +1,9 @@
 from django.conf import settings
 from django.conf.urls import url
 from django.core.paginator import Paginator, InvalidPage
-from haystack.query import SearchQuerySet
 from ldt.ldt_utils.models import Segment
-from tagging.models import Tag
+from ldt.templatetags.taggit_extras_ldt import get_queryset
+from taggit.models import Tag
 from tastypie.http import HttpNotFound
 from tastypie.resources import ModelResource, ALL
 from tastypie.utils import trailing_slash
@@ -38,14 +38,17 @@
             weight_steps = 10
         tags_cloud = None
         if content_ids=="all" or segment_ids=="all":
-            tags_cloud = Tag.objects.cloud_for_model(Segment, steps=weight_steps)
+            #tags_cloud = Tag.objects.cloud_for_model(Segment, steps=weight_steps)
+            tags_cloud = get_queryset('ldt_utils.Segment')
         elif content_ids != "":
             # We get all the segments for these contents
             content_ids = content_ids.split(',')
-            tags_cloud = Tag.objects.cloud_for_model(Segment, filters={"iri_id__in":content_ids}, steps=weight_steps)
+            #tags_cloud = Tag.objects.cloud_for_model(Segment, filters={"iri_id__in":content_ids}, steps=weight_steps)
+            tags_cloud = get_queryset(Segment.objects.filter(iri_id__in=content_ids))
         elif not all_segments and segment_ids != "":
             segment_ids = segment_ids.split(',')
-            tags_cloud = Tag.objects.cloud_for_model(Segment, filters={"element_id__in":segment_ids}, steps=weight_steps)
+            #tags_cloud = Tag.objects.cloud_for_model(Segment, filters={"element_id__in":segment_ids}, steps=weight_steps)
+            tags_cloud = get_queryset(Segment.objects.filter(element_id__in=segment_ids))
         
         limit = request.GET.get('limit', getattr(settings, 'API_LIMIT_PER_PAGE', 20))
         if limit == "0":
@@ -75,4 +78,6 @@
         # This function enable to add the weight of a tag in the bundle's datas, which is not in the tag model
         if bundle.obj and hasattr(bundle.obj,'font_size'):
             bundle.data['weight'] = bundle.obj.font_size
+        if bundle.obj and hasattr(bundle.obj,'num_times'):
+            bundle.data['weight'] = bundle.obj.num_times
         return bundle
\ No newline at end of file
--- a/src/ldt/ldt/indexation/search_indexes.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/indexation/search_indexes.py	Thu Apr 10 15:55:47 2014 +0200
@@ -29,6 +29,9 @@
     def get_model(self):
         return Segment
     
+    def prepare_tags(self, obj):
+        return ",".join([tag.name for tag in obj.tags.all()])
+    
 class AnnotationIndex(indexes.SearchIndex, indexes.Indexable):
     text = indexes.CharField(document=True, use_template=True)
     tags = indexes.CharField(model_attr='tags', indexed=True, stored=False)
@@ -39,6 +42,9 @@
 
     def get_model(self):
         return Annotation
+    
+    def prepare_tags(self, obj):
+        return ",".join([tag.name for tag in obj.tags.all()])
 
 
 class ContentIndex(indexes.SearchIndex, indexes.Indexable):
@@ -48,4 +54,7 @@
     abstract = indexes.CharField(model_attr='description', indexed=True, stored=False, null=True)
     
     def get_model(self):
-        return Content
\ No newline at end of file
+        return Content
+    
+    def prepare_tags(self, obj):
+        return ",".join([tag.name for tag in obj.tags.all()])
\ No newline at end of file
--- a/src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/annotation_text.txt	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/annotation_text.txt	Thu Apr 10 15:55:47 2014 +0200
@@ -1,4 +1,4 @@
-{{object.tags}}
+{% for tag in object.tags.all %} {{ tag.name }} {% endfor %}
 {{object.title}}
 {{object.description}}
 {{object.text}}
\ No newline at end of file
--- a/src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/content_text.txt	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/content_text.txt	Thu Apr 10 15:55:47 2014 +0200
@@ -1,3 +1,3 @@
-{{object.tags}}
+{% for tag in object.tags.all %} {{ tag.name }} {% endfor %}
 {{object.title}}
 {{object.description}}
\ No newline at end of file
--- a/src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/segment_text.txt	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/indexation/templates/search/indexes/ldt_utils/segment_text.txt	Thu Apr 10 15:55:47 2014 +0200
@@ -1,3 +1,3 @@
-{{object.tags}}
+{% for tag in object.tags.all %} {{ tag.name }} {% endfor %}
 {{object.title}}
 {{object.abstract}}
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/contentindexer.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/contentindexer.py	Thu Apr 10 15:55:47 2014 +0200
@@ -7,10 +7,9 @@
 from ldt.ldt_utils.stat import update_stat_project, add_annotation_to_stat
 from ldt.ldt_utils.utils import reduce_text_node
 from ldt.utils.url import request_with_auth
-from tagging import settings as tagging_settings
 import logging
 import lxml.etree #@UnresolvedImport
-import tagging.utils
+from taggit.utils import parse_tags
 
 logger = logging.getLogger(__name__)
 
@@ -92,11 +91,6 @@
                 if tags is None:
                     tags = u""
                 
-                tags_list = [tag[:tagging_settings.MAX_TAG_LENGTH] for tag in tagging.utils.parse_tag_input(tags)]
-                tags = u",".join(tags_list)
-                if u"," not in tags:
-                    tags = u"," + tags
-                
 
                 title = reduce_text_node(elementNode, "title/text()")                
                 abstract = reduce_text_node(elementNode, "abstract/text()")
@@ -122,7 +116,6 @@
                               ensemble_id=ensembleId,
                               cutting_id=decoupId,
                               element_id=elementId,
-                              tags=tags,
                               title=title,
                               abstract=abstract,
                               duration=duration,
@@ -133,14 +126,20 @@
                               project_id=ldt_id,
                               audio_src=audio_src,
                               audio_href=audio_href)
+                # Because of taggit managing (we HAVE to have primary key to ad tags), we save segment and then tags
                 seg.polemics = seg.get_polemic(polemics)
-                if settings.LDT_INDEXATION_INSERT_BATCH_SIZE < 2:
-                    seg.save()
-                else:
-                    self.__segment_cache.append(seg)
-                    if not (len(self.__segment_cache)%settings.LDT_INDEXATION_INSERT_BATCH_SIZE):
-                        object_insert(Segment, self.__segment_cache)
-                        self.__segment_cache = []
+                seg.save()
+                for t in parse_tags(tags):
+                    seg.tags.add(t)
+                seg.save()
+                
+#                 if settings.LDT_INDEXATION_INSERT_BATCH_SIZE < 2:
+#                     seg.save()
+#                 else:
+#                     self.__segment_cache.append(seg)
+#                     if not (len(self.__segment_cache)%settings.LDT_INDEXATION_INSERT_BATCH_SIZE):
+#                         object_insert(Segment, self.__segment_cache)
+#                         self.__segment_cache = []
 
 
 class ContentIndexer(LdtIndexer):
@@ -221,7 +220,6 @@
               ensemble_id=ensemble_id,
               cutting_id=cutting_id,
               element_id=element_id,
-              tags=tags_str,
               title=title,
               abstract=abstract,
               duration=duration,
@@ -234,6 +232,9 @@
               audio_href=audio_href)
     seg.polemics = seg.get_polemic(polemics)
     seg.save()
+    for t in parse_tags(tags_str):
+        seg.tags.add(t)
+    seg.save()
     add_annotation_to_stat(seg.content, seg.start_ts, seg.start_ts+seg.duration)
 
 
--- a/src/ldt/ldt/ldt_utils/forms.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/forms.py	Thu Apr 10 15:55:47 2014 +0200
@@ -5,6 +5,7 @@
 from ldt.security.forms import ShareForm
 from models import Project, Content, Media
 from utils import generate_uuid
+from taggit.forms import TagField
 
 class LdtImportForm(forms.Form):
     importFile = forms.FileField()
@@ -55,6 +56,7 @@
     is_public = forms.BooleanField(required=False)
     front_project = forms.ModelChoiceField(queryset=Project.objects.none(), required=False, label=_("content.front_project"))
     duration = ldt_fields.LdtDurationField(required=True, label=_("content.duration")+" (Ms, M:S, H:M:S, HhM, Ss, Ssec)", formats=["%M:%S", "%H:%M:%S", "%Hh%M", "%Ss", "%Ssec"])
+    tags = TagField(required=False)
         
     def clean_iri_id(self):
         data = self.cleaned_data.get('iri_id')
@@ -70,9 +72,6 @@
         if not iriurl_data:
             iriurl_data = "%s/%s.iri" % (iri_id_data, iri_id_data)    
         cleaned_data['iriurl'] = iriurl_data
-        # if needed, we add a comma to the tag list, to force comma separated list and enable tags with spaces.
-        if ',' not in cleaned_data['tags'] and cleaned_data['tags']!="" :
-            cleaned_data['tags'] = cleaned_data['tags'] + ','
         return cleaned_data
     
     class Meta:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/migrations/0029_tagging_to_taggit.py	Thu Apr 10 15:55:47 2014 +0200
@@ -0,0 +1,204 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from django.template.defaultfilters import slugify
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        # Deleting field 'Content.tags'
+        db.delete_column(u'ldt_utils_content', 'tags')
+        # Deleting field 'Segment.tags_field'
+        db.delete_column(u'ldt_utils_segment', 'tags')
+        # Dirty version, but version who enables migration in one step : change table and column names 
+        # instead of copying data from orm["tagging.*"] to orm["taggit.*"]
+        # Change columns name
+        db.rename_table('tagging_taggeditem', 'taggit_taggeditem')
+        db.rename_table('tagging_tag', 'taggit_tag')
+        db.add_column('taggit_tag', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255, null=True), keep_default=True)
+        """
+        ALTER TABLE `tagging_tag` ADD COLUMN `slug` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ''  AFTER `name`;
+        ALTER TABLE `tagging_tag` CHANGE COLUMN `name` `name` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ''  COMMENT ''  AFTER `id`;
+        ALTER TABLE `tagging_taggeditem` CHANGE COLUMN `object_id` `object_id` INT(11) UNSIGNED NOT NULL DEFAULT 0  COMMENT ''  AFTER `content_type_id`;
+        ALTER TABLE `tagging_taggeditem` CHANGE COLUMN `object_id` `object_id` INT(11) UNSIGNED NOT NULL DEFAULT 0  COMMENT ''  AFTER `tag_id`;
+        """
+        tags = orm['taggit.tag'].objects.all()
+        slugs = {}
+        for t in tags:
+            slug = slugify(t.name)
+            if slug in slugs:
+                slugs[slug] += 1
+                s = slug + "-" + str(slugs[slug])
+            else:
+                slugs[slug] = 1
+                s = slug
+            t.slug = s
+            t.save()
+            print str(t.pk) + " : " + t.name + " : " + t.slug
+        
+
+    def backwards(self, orm):
+        "Write your backwards methods here."
+        db.delete_column('taggit_tag', 'slug')
+        db.rename_table('taggit_tag', 'tagging_tag')
+        db.rename_table('taggit_taggeditem', 'tagging_taggeditem')
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'ldt_utils.author': {
+            'Meta': {'object_name': 'Author'},
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+            'firstname': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}),
+            'handle': ('django.db.models.fields.CharField', [], {'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lastname': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'})
+        },
+        u'ldt_utils.content': {
+            'Meta': {'ordering': "['title']", 'object_name': 'Content'},
+            'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['ldt_utils.Author']", 'symmetrical': 'False', 'blank': 'True'}),
+            'content_creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'front_project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ldt_utils.Project']", 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/contents/content_default_icon.png'", 'max_length': '200'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'default': "u'9a8e899c-bb15-11e3-ba1e-c8bcc896c290'", 'unique': 'True', 'max_length': '255'}),
+            'iriurl': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'media_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ldt_utils.Media']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'update_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+        },
+        u'ldt_utils.contentstat': {
+            'Meta': {'object_name': 'ContentStat'},
+            'annotation_volume_str': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'content': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'stat_annotation'", 'unique': 'True', 'to': u"orm['ldt_utils.Content']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_annotated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}),
+            'nb_annotations': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}),
+            'polemics_volume_str': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'})
+        },
+        u'ldt_utils.media': {
+            'Meta': {'object_name': 'Media'},
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['user.LdtUser']", 'null': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'external_id': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'external_permalink': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'external_publication_url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'external_src_url': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'media_creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'mimetype_field': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}),
+            'src': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'src_hash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'update_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'videopath': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'})
+        },
+        u'ldt_utils.project': {
+            'Meta': {'ordering': "['title']", 'object_name': 'Project'},
+            'changed_by': ('django.db.models.fields.CharField', [], {'max_length': '70'}),
+            'contents': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['ldt_utils.Content']", 'symmetrical': 'False'}),
+            'created_by': ('django.db.models.fields.CharField', [], {'max_length': '70'}),
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/projects/project_default_icon.png'", 'max_length': '200'}),
+            'ldt': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'ldt_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['user.LdtUser']", 'null': 'True', 'blank': 'True'}),
+            'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        },
+        u'ldt_utils.segment': {
+            'Meta': {'object_name': 'Segment'},
+            'abstract': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'audio_href': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}),
+            'audio_src': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'author': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'content': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ldt_utils.Content']"}),
+            'cutting_id': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}),
+            'date': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
+            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
+            'element_id': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}),
+            'ensemble_id': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'id_hash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'polemics': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'blank': 'True'}),
+            'project_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'project_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['ldt_utils.Project']", 'null': 'True'}),
+            'start_ts': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'})
+        },
+        u'tagging.tag': {
+            'Meta': {'ordering': "('name',)", 'object_name': 'Tag'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
+        },
+        u'tagging.taggeditem': {
+            'Meta': {'unique_together': "(('tag', 'content_type', 'object_id'),)", 'object_name': 'TaggedItem'},
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'items'", 'to': u"orm['tagging.Tag']"})
+        },
+        u'taggit.tag': {
+            'Meta': {'object_name': 'Tag'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
+        },
+        u'taggit.taggeditem': {
+            'Meta': {'object_name': 'TaggedItem'},
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
+        },
+        u'user.ldtuser': {
+            'Meta': {'object_name': 'LdtUser'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/users/user_default_icon.png'", 'max_length': '200'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'language': ('django.db.models.fields.CharField', [], {'default': "'fr'", 'max_length': '2'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        }
+    }
+
+    complete_apps = ['tagging', 'ldt_utils']
+    symmetrical = True
--- a/src/ldt/ldt/ldt_utils/models.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/models.py	Thu Apr 10 15:55:47 2014 +0200
@@ -1,9 +1,7 @@
 import datetime
-import mimetypes
+import lxml.etree #@UnresolvedImport
 import os.path
 import re
-from shutil import move
-import uuid
 
 from django.conf import settings
 from django.contrib.auth import get_user_model
@@ -12,20 +10,21 @@
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 from guardian.shortcuts import assign, remove_perm, get_perms
-import lxml.etree #@UnresolvedImport
 from sorl.thumbnail import ImageField
-import tagging.fields
-from tagging.models import Tag
+from taggit.managers import TaggableManager
 
 from ldt.core.models import Document
-from ldt.security import (get_current_user_or_admin, set_current_user, 
-    get_current_user)
+from ldt.security import get_current_user_or_admin, set_current_user, \
+    get_current_user
 from ldt.security.manager import SafeManager
 from ldt.security.models import SafeModel
 from ldt.utils import generate_hash, url as url_utils
 from ldt.utils.web_url_management import get_web_url
-from utils import (create_ldt, copy_ldt, create_empty_iri, update_iri, 
-    generate_uuid)
+import mimetypes
+from shutil import move
+from utils import create_ldt, copy_ldt, create_empty_iri, update_iri, \
+    generate_uuid
+import uuid
 
 from .events import post_project_save
 
@@ -176,7 +175,7 @@
     authors = models.ManyToManyField(Author, blank=True, verbose_name=_('content.authors'))
     duration = models.IntegerField(null=True, blank=True, verbose_name=_('content.duration'))
     content_creation_date = models.DateTimeField(null=True, blank=True, verbose_name=_('content.content_creation_date'))
-    tags = tagging.fields.TagField(max_length=2048, null=True, blank=True)
+    tags = TaggableManager()
     media_obj = models.ForeignKey('Media', blank=True, null=True)
     image = ImageField(upload_to="thumbnails/contents/", default=settings.DEFAULT_CONTENT_ICON, max_length=200)
     front_project = models.ForeignKey('Project', null=True, blank=True)
@@ -801,7 +800,7 @@
     ensemble_id = models.CharField(max_length=512, unique=False, db_index=True)
     cutting_id = models.CharField(max_length=512, unique=False, db_index=True)    
     element_id = models.CharField(max_length=512, unique=False, db_index=True)
-    tags = tagging.fields.TagField(max_length=2048, null=True, blank=True, unique=False)
+    tags = TaggableManager()
     title = models.CharField(max_length=2048, unique=False, null=True, blank=True)
     duration = models.IntegerField(null=True)
     start_ts = models.IntegerField(null=True)
--- a/src/ldt/ldt/ldt_utils/segmentserializer.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/segmentserializer.py	Thu Apr 10 15:55:47 2014 +0200
@@ -1,7 +1,6 @@
 from django.conf import settings
 from ldt.ldt_utils.stat import get_string_from_buckets
 from ldt.security.utils import use_forbidden_url
-from tagging.utils import parse_tag_input
 import logging
 import lxml.etree
 import uuid
@@ -139,7 +138,7 @@
         for seg in self.segments:
             
             segment_tags = []
-            for tag in parse_tag_input(seg.tags):
+            for tag in [t.name for t in seg.tags.all()]:
                 if not self.tags.has_key(tag):
                     new_tag = {
                         "meta": {
--- a/src/ldt/ldt/ldt_utils/templates/front/front_all_contents.html	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_all_contents.html	Thu Apr 10 15:55:47 2014 +0200
@@ -3,6 +3,7 @@
 {% load thumbnail %}
 {% load front_tags %}
 {% load static %}
+{% load taggit_extras_ldt %}
 
 {% block title %}
 {% if tag_label %}
@@ -57,8 +58,9 @@
       </ul>
     </li>
     <li class="li_h2" id="home_tag_cloud">
+    {% get_tagcloud as tag_cloud for 'ldt_utils.Content' %}
     {% if tag_cloud|length > 0 %}<p class="left tag_link">{% trans 'All categories of medias' %} : {% for t in tag_cloud %}<a href="{% url 'ldt.ldt_utils.views.front.all_contents' %}?tag={{t.name}}">
-      <span style="font-size:{{t.font_size|add:"12"}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
+      <span style="font-size:{{t.weight|floatformat:0|add:'11'}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
     {% endif %}
     </li>
       <!-- Pagination -->
@@ -114,8 +116,7 @@
     {% endfor %}
 </ul>
 {% if tag_cloud|length > 0 %}<p class="left tag_link">{% trans 'All categories of medias' %} : {% for t in tag_cloud %}<a href="{% url 'ldt.ldt_utils.views.front.all_contents' %}?tag={{t.name}}">
-  <span style="font-size:{{t.font_size|add:"12"}}px;">{{t.name}}</span>
-  </a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
+  <span style="font-size:{{t.weight|floatformat:0|add:'11'}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
 {% endif %}
 {% endblock %}
 
--- a/src/ldt/ldt/ldt_utils/templates/front/front_home.html	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_home.html	Thu Apr 10 15:55:47 2014 +0200
@@ -3,6 +3,7 @@
 {% load thumbnail %}
 {% load front_tags %}
 {% load static %}
+{% load taggit_extras_ldt %}
 
 {% block title %}{% trans "front.home" %}{% endblock %}
 
@@ -47,8 +48,9 @@
       </ul>
     </li>
     <li class="li_h2" id="home_tag_cloud">
+    {% get_tagcloud as tag_cloud for 'ldt_utils.Content' %}
     {% if tag_cloud|length > 0 %}<p class="left tag_link">{% trans 'All categories of medias' %} : {% for t in tag_cloud %}<a href="{% url 'ldt.ldt_utils.views.front.all_contents' %}?tag={{t.name}}">
-	  <span style="font-size:{{t.font_size|add:"12"}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
+	  <span style="font-size:{{t.weight|floatformat:0|add:'11'}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
 	{% endif %}
     </li>
     {% for content in last_contents %}
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/contentslist.html	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/contentslist.html	Thu Apr 10 15:55:47 2014 +0200
@@ -2,6 +2,7 @@
 {% load thumbnail %}
 {% load front_tags %}
 {% load static %}
+{% load taggit_extras_ldt %}
 
 <ul class="prev_next_cont_proj" >
     <li id="content_tags_li"><span id="content_tags" class="clickable">{% if tag_cloud|length > 0 %}{% trans 'All categories' %}{% endif %}</span>{% if current_content_tag %}{% if current_content_tag != "" %} &gt; {{current_content_tag}} <span id="no_content_tag" class="clickable">[x]</span>{% endif %}{% endif %}</li>
@@ -10,10 +11,10 @@
 	<input type="hidden" value="{{current_content_page}}" name="current_content_page" id="current_content_page">
 {% endif %}
 </ul>
-<div id="content_tags_cloud">{% if tag_cloud|length > 0 %}
+<div id="content_tags_cloud">{% get_tagcloud as tag_cloud for 'ldt_utils.Content' %}{% if tag_cloud|length > 0 %}
   <p>
   {% for t in tag_cloud %}
-    <a class="contents_tag clickable" alt="{{t.name}}"><span style="font-size:{{t.font_size|add:"10"}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}
+    <a class="contents_tag clickable" alt="{{t.name}}"><span style="font-size:{{t.weight|floatformat:0|add:'9'}}px;">{{t.name}}</span></a>{% if not forloop.last %}, {% endif %}
   {% endfor %}
   </p>{% endif %}
   <input type="hidden" value="{{current_content_tag}}" name="current_content_tag" id="current_content_tag">
--- a/src/ldt/ldt/ldt_utils/views/content.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/views/content.py	Thu Apr 10 15:55:47 2014 +0200
@@ -17,7 +17,6 @@
 from ldt.security.utils import (assign_perm_to_obj, add_change_attr, get_userlist, 
     get_userlist_model)
 from ldt.user.forms import PictureForm
-from tagging.models import Tag, TaggedItem
 import datetime
 import ldt.utils.path as ldt_utils_path
 import logging
@@ -33,6 +32,7 @@
 import urllib2
 import urlparse
 #from django.core.files.temp import NamedTemporaryFile
+logger = logging.getLogger(__name__)
 
 def media_management(request, media_input_type, cleaned_data, content_form, media_form, form_status):
     if media_input_type == "none":
@@ -251,16 +251,31 @@
                                    
                     for key in ["media_input_type", "groups", "is_public", "read_list", "write_list", "share" ]:
                         del content_defaults[key]
-                        
+                    
+                    #taggit management : save tags and add them after get_or_create
+                    logger.debug("YEAH 1")
+                    saved_tags = content_defaults.get('tags') or []
+                    logger.debug("YEAH 2")
+                    logger.debug(saved_tags)
+                    content_defaults.pop('tags')
+                    logger.debug("YEAH 3")
+                    logger.debug(content_defaults)
                     content, created = Content.safe_objects.get_or_create(iri_id=content_form.cleaned_data['iri_id'], defaults=content_defaults) #@UndefinedVariable
-                                      
+                    logger.debug("YEAH 3-2")
+                    content.tags.clear()
+                    for t in saved_tags:
+                        logger.debug("YEAH 3-3 " + t)
+                        content.tags.add(t)
+                    logger.debug("YEAH 4")
+                    logger.debug(content.tags.names())
+                    
                     if not created and not request.user.has_perm('ldt_utils.change_content', content):
                         raise AttributeError("%s is not allowed to change content %s" % (request.user, content))
-                    
+                    logger.debug("YEAH 5")
                     cached_assign('change_content', request.user, content)
                     cached_assign('view_content', request.user, content)
                     everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME)
-                    
+                    logger.debug("YEAH 6")
                     if media_form.cleaned_data['media_public']:
                         cached_assign('view_content', everyone, content)
                         if media:
@@ -274,14 +289,14 @@
                             cached_assign('view_content', everyone, content)
                         else:
                             remove_perm('ldt_utils.view_content', everyone, content)
-                    
+                    logger.debug("YEAH 7")
                     if not created:
-                        for attribute in ('iriurl', 'title', 'description', 'duration', 'content_creation_date', 'tags', 'media_obj'):
+                        for attribute in ('iriurl', 'title', 'description', 'duration', 'content_creation_date', 'media_obj'):
                             setattr(content, attribute, content_defaults[attribute])
                             
                         if request.user.is_staff and content_defaults.has_key('front_project'):
                             content.front_project = content_defaults['front_project']
-                    
+                    logger.debug("YEAH 9")
                     content.save()
                     picture_form.model = content
                     picture_form.save()  
@@ -289,9 +304,12 @@
                     media_form = MediaForm(instance=media, prefix="media")
                     content_form = ContentForm(instance=content, prefix="content")
                     picture_form = PictureForm()
+                    logger.debug("YEAH 10")
             else:
+                logger.debug("YEAH 11")
                 form_status = 'error'
         except Exception, e:
+            logger.debug("YEAH 12")
             transaction.rollback()
             __, value, traceback = sys.exc_info()
             return False, False, False, False, False, False, e, traceback
@@ -376,7 +394,7 @@
     elif submit_action=="close":
         return redirect("root-view")
     else:
-        content_form, media_form, picture_form, form_status, content_temp, current_front_project, e, traceback = write_content_base(request, iri_id)        
+        content_form, media_form, picture_form, form_status, content_temp, current_front_project, e, traceback = write_content_base(request, iri_id)
         if iri_id: 
             #content_temp = Content.objects.select_related('media_obj').get(iri_id=iri_id)
             media_temp = content_temp.media_obj
@@ -542,25 +560,22 @@
         nb_ct_pages = int(math.ceil(content_nb / settings.LDT_MAX_CONTENTS_PER_PAGE)) + 1
         content_list = Content.safe_objects.filter(title__icontains=filter_c)[(num_page*settings.LDT_MAX_CONTENTS_PER_PAGE):((num_page+1)*settings.LDT_MAX_CONTENTS_PER_PAGE)] #@UndefinedVariable
     elif filter_c and tag_filter :
-        #TaggedItem.objects.get_by_model(Content.objects.all(), '"'+tag_filter+'"')
-        content_nb = TaggedItem.objects.get_by_model(Content.safe_objects.filter(title__icontains=filter_c), '"'+tag_filter+'"').count()
+        content_nb = Content.objects.filter(title__icontains=filter_c, tags__name__in=tag_filter).distinct().count()
         nb_ct_pages = int(math.ceil(content_nb / settings.LDT_MAX_CONTENTS_PER_PAGE)) + 1
-        content_list = TaggedItem.objects.get_by_model(Content.safe_objects.filter(title__icontains=filter_c), '"'+tag_filter+'"')[(num_page*settings.LDT_MAX_CONTENTS_PER_PAGE):((num_page+1)*settings.LDT_MAX_CONTENTS_PER_PAGE)] #@UndefinedVariable
+        content_nb = Content.objects.filter(title__icontains=filter_c, tags__name__in=tag_filter).distinct()[(num_page*settings.LDT_MAX_CONTENTS_PER_PAGE):((num_page+1)*settings.LDT_MAX_CONTENTS_PER_PAGE)]
     elif tag_filter and not filter_c:
-        content_nb = TaggedItem.objects.get_by_model(Content.safe_objects.all(), '"'+tag_filter+'"').count()
-        nb_ct_pages = int(math.ceil(content_nb / settings.LDT_MAX_CONTENTS_PER_PAGE)) +1
-        content_list = TaggedItem.objects.get_by_model(Content.safe_objects.all(), '"'+tag_filter+'"')[(num_page*settings.LDT_MAX_CONTENTS_PER_PAGE):((num_page+1)*settings.LDT_MAX_CONTENTS_PER_PAGE)] #@UndefinedVariable
+        content_nb = Content.safe_objects.select_related('stat_annotation').filter(tags__name__in=[tag_filter]).distinct().count()
+        nb_ct_pages = int(math.ceil(content_nb / settings.LDT_MAX_CONTENTS_PER_PAGE)) + 1
+        content_list = Content.safe_objects.select_related('stat_annotation').filter(tags__name__in=[tag_filter]).distinct()[(num_page*settings.LDT_MAX_CONTENTS_PER_PAGE):((num_page+1)*settings.LDT_MAX_CONTENTS_PER_PAGE)] #@UndefinedVariable
     else:
         content_nb, nb_ct_pages, content_list = get_contents_page(num_page, request.user)
     #Change attributes with object permissions
     content_list = add_change_attr(request.user, content_list)
-    # Get the all tags list
-    tag_cloud = get_content_tags()
     
     is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
     return render_to_response("ldt/ldt_utils/partial/contentslist.html",
                               {'contents': content_list, 'nb_ct_pages': nb_ct_pages, 'content_nb': content_nb, 'current_content_page':float(num_page),
-                               'tag_cloud': tag_cloud, 'current_content_tag':tag_filter, 'is_gecko': is_gecko
+                               'current_content_tag':tag_filter, 'is_gecko': is_gecko
                                },
                               context_instance=RequestContext(request))
     
@@ -572,9 +587,10 @@
     return content_nb, nb_ct_pages, content_list
 
 
-def get_content_tags(limit=None, steps=10):
-    if limit is None:
-        return Tag.objects.cloud_for_model(Content, steps=steps)
-    else :
-        return Tag.objects.cloud_for_model(Content, steps=steps)[:limit]
+# def get_content_tags(limit=None, steps=10):
+#     return None
+#     if limit is None:
+#         return Tag.objects.cloud_for_model(Content, steps=steps)
+#     else :
+#         return Tag.objects.cloud_for_model(Content, steps=steps)[:limit]
         
--- a/src/ldt/ldt/ldt_utils/views/front.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/views/front.py	Thu Apr 10 15:55:47 2014 +0200
@@ -9,11 +9,9 @@
 from django.template import RequestContext
 from ldt.ldt_utils.forms import SearchForm
 from ldt.ldt_utils.models import Content, Project
-from ldt.ldt_utils.views.content import get_content_tags
 from ldt.ldt_utils.views.group import get_group_projects
 from ldt.ldt_utils.views.workspace import get_search_results
 from ldt.utils.url import static
-from tagging.models import TaggedItem
 import logging
 from guardian.shortcuts import get_objects_for_group
 from ldt.indexation import get_results_with_context
@@ -31,14 +29,11 @@
     active_groups = Group.objects.select_related("profile").annotate(nb_users=Count("ldtuser")).exclude(name=settings.PUBLIC_GROUP_NAME)[:5]
     # Get the main tag list
     front_tags = settings.FRONT_TAG_LIST
-    # Get the all tags list
-    tag_cloud = get_content_tags()
     
     is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1)
     
     return render_to_response("front/front_home.html",
-                              {'last_contents': last_contents, 'most_contents':most_contents, 'active_groups':active_groups, 'front_tags':front_tags,
-                               'tag_cloud': tag_cloud, 'is_gecko': is_gecko},
+                              {'last_contents': last_contents, 'most_contents':most_contents, 'active_groups':active_groups, 'front_tags':front_tags, 'is_gecko': is_gecko},
                               context_instance=RequestContext(request))
 
 
@@ -119,7 +114,8 @@
         if tag_label is None :
             content_list = Content.safe_objects.all().select_related('stat_annotation')
         else :
-            content_list = TaggedItem.objects.get_by_model(Content.safe_objects.all().select_related('stat_annotation'), '"'+tag_label+'"')
+            #content_list = TaggedItem.objects.get_by_model(Content.safe_objects.all().select_related('stat_annotation'), '"'+tag_label+'"')
+            content_list = Content.safe_objects.select_related('stat_annotation').filter(tags__name__in=[tag_label])
     else :
         #content_list = Content.safe_objects.filter(title__icontains=media_title).select_related('stat_annotation')
         content_searched = get_results_with_context(Content, "all", media_title)
@@ -137,14 +133,11 @@
     
     # Get the main tag list
     front_tags = settings.FRONT_TAG_LIST
-    # Get the all tags list
-    tag_cloud = get_content_tags()
     
     is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1)
 
     return render_to_response("front/front_all_contents.html",
-                              {'results':results, 'tag_label':tag_label, 'media_title':media_title, 'front_tags':front_tags, 'tag_cloud':tag_cloud,
-                               'is_gecko': is_gecko},
+                              {'results':results, 'tag_label':tag_label, 'media_title':media_title, 'front_tags':front_tags, 'is_gecko': is_gecko},
                               context_instance=RequestContext(request))
 
 
@@ -265,8 +258,18 @@
         content_tag = sform.cleaned_data["content_tag"]
         content_list = None
         if content_tag is not None and content_tag != "" :
-            content_list = TaggedItem.objects.get_by_model(Content.objects.all(), '"'+content_tag+'"')
+            #content_list = TaggedItem.objects.get_by_model(Content.objects.all(), '"'+content_tag+'"')
+            content_list = Content.safe_objects.filter(tags__name__in=[content_tag])
         results, nb, nb_segment = get_search_results(request, search, field, page, content_list)
+        
+        # If there was no answer, we check if a search with content's title works
+        if nb==0:
+            nb = Content.safe_objects.filter(title__icontains=search).count()
+            nb_segment = 0
+            content_results = Content.safe_objects.filter(title__icontains=search).select_related('stat_annotation')[:settings.LDT_MEDIA_IN_RESULTS_PAGE]
+    else:
+        results, nb, nb_segment = None, 0, 0
+        
 
     return render_to_response('front/front_search_results.html', {
                                 'results': results, 'nb_results' : nb, 'nb_segment':nb_segment, 'search' : search, 
--- a/src/ldt/ldt/ldt_utils/views/workspace.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/ldt_utils/views/workspace.py	Thu Apr 10 15:55:47 2014 +0200
@@ -25,7 +25,7 @@
 from ldt.ldt_utils.models import Content, Project, Segment
 from ldt.ldt_utils.projectserializer import ProjectJsonSerializer
 from ldt.ldt_utils.utils import boolean_convert
-from ldt.ldt_utils.views.content import get_contents_page, get_content_tags
+from ldt.ldt_utils.views.content import get_contents_page
 from ldt.ldt_utils.views.project import (get_projects_page, 
     get_published_projects_page)
 from ldt.security.utils import add_change_attr, get_userlist
@@ -41,8 +41,6 @@
     content_nb, nb_ct_pages, content_list = get_contents_page(num_page, request.user)
     # get list of projects owned by the current user
     project_nb, nb_pj_pages, project_list = get_projects_page(num_page, request.user)
-    # Get the all tags list
-    tag_cloud = get_content_tags()
 
     is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
     
@@ -50,8 +48,7 @@
     return render_to_response("ldt/ldt_utils/workspace.html",
                               {'contents': content_list, 'nb_ct_pages': nb_ct_pages, 'content_nb': content_nb, 'current_content_page':float(num_page),
                                'projects': project_list, 'nb_pj_pages': nb_pj_pages, 'project_nb': project_nb, 'current_project_page':float(num_page),
-                               'tag_cloud': tag_cloud, 'is_gecko': is_gecko, #'project_api_url':"match.url_name",
-                               #'project_api_view':match.url_name,'project_api_args':"project_api_args",'project_api_kwargs':"project_api_kwargs"
+                               'is_gecko': is_gecko
                                },
                               context_instance=RequestContext(request))
 
--- a/src/ldt/ldt/settings.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/settings.py	Thu Apr 10 15:55:47 2014 +0200
@@ -19,7 +19,7 @@
     'django.contrib.messages',
     'django.contrib.admin',
     'registration',
-    'tagging',
+    'taggit',
     'haystack',
     'ldt',
     'ldt.core',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/templatetags/taggit_extras_ldt.py	Thu Apr 10 15:55:47 2014 +0200
@@ -0,0 +1,107 @@
+"""
+from taggit-templatetags. This app is very useful but does not
+"""
+
+from django import template
+from django.db import models
+from django.db.models import Count
+from django.core.exceptions import FieldError
+
+from templatetag_sugar.register import tag
+from templatetag_sugar.parser import Name, Variable, Constant, Optional, Model
+
+from taggit import VERSION as TAGGIT_VERSION
+from taggit.managers import TaggableManager
+from taggit.models import TaggedItem, Tag
+from taggit_templatetags import settings
+from django.utils.safestring import SafeText
+from django.contrib.contenttypes.models import ContentType
+
+T_MAX = getattr(settings, 'TAGCLOUD_MAX', 6.0)
+T_MIN = getattr(settings, 'TAGCLOUD_MIN', 1.0)
+
+register = template.Library()
+
+import logging
+logger = logging.getLogger(__name__)
+
+def get_queryset(forvar=None):
+    if None == forvar:
+        # get all tags
+        queryset = Tag.objects.all()
+    else:
+        if isinstance(forvar, str) or isinstance(forvar, SafeText):
+            # extract app label and model name
+            beginning, applabel, model = None, None, None
+            try:
+                beginning, applabel, model = forvar.rsplit('.', 2)
+            except ValueError:
+                try:
+                    applabel, model = forvar.rsplit('.', 1)
+                except ValueError:
+                    applabel = forvar
+            
+            # filter tagged items
+            if applabel:
+                queryset = TaggedItem.objects.filter(content_type__app_label=applabel.lower())
+            if model:
+                queryset = queryset.filter(content_type__model=model.lower())
+        else:
+            # forvar is a query set
+            content_type = ContentType.objects.get_for_model(forvar[0])
+            queryset = TaggedItem.objects.filter(content_type=content_type, object_id__in=[o.pk for o in forvar])
+            
+        # get tags
+        tag_ids = queryset.values_list('tag_id', flat=True)
+        queryset = Tag.objects.filter(id__in=tag_ids)
+            
+
+    # Retain compatibility with older versions of Django taggit
+    # a version check (for example taggit.VERSION <= (0,8,0)) does NOT
+    # work because of the version (0,8,0) of the current dev version of django-taggit
+    try:
+        return queryset.annotate(num_times=Count('taggeditem_items'))
+    except FieldError:
+        return queryset.annotate(num_times=Count('taggit_taggeditem_items'))
+
+def get_weight_fun(t_min, t_max, f_min, f_max):
+    def weight_fun(f_i, t_min=t_min, t_max=t_max, f_min=f_min, f_max=f_max):
+        # Prevent a division by zero here, found to occur under some
+        # pathological but nevertheless actually occurring circumstances.
+        if f_max == f_min:
+            mult_fac = 1.0
+        else:
+            mult_fac = float(t_max-t_min)/float(f_max-f_min)
+            
+        return t_max - (f_max-f_i)*mult_fac
+    return weight_fun
+
+@tag(register, [Constant('as'), Name(), Optional([Constant('for'), Variable()])])
+def get_taglist(context, asvar, forvar=None):
+    queryset = get_queryset(forvar)         
+    queryset = queryset.order_by('-num_times')        
+    context[asvar] = queryset
+    return ''
+
+@tag(register, [Constant('as'), Name(), Optional([Constant('for'), Variable()])])
+def get_tagcloud(context, asvar, forvar=None):
+    queryset = get_queryset(forvar)
+    num_times = queryset.values_list('num_times', flat=True)
+    if(len(num_times) == 0):
+        context[asvar] = queryset
+        return ''
+    weight_fun = get_weight_fun(T_MIN, T_MAX, min(num_times), max(num_times))
+    queryset = queryset.order_by('name')
+    for tag in queryset:
+        tag.weight = weight_fun(tag.num_times)
+    context[asvar] = queryset
+    return ''
+    
+def include_tagcloud(forvar=None):
+    return {'forvar': forvar}
+
+def include_taglist(forvar=None):
+    return {'forvar': forvar}
+  
+register.inclusion_tag('taggit_templatetags/taglist_include.html')(include_taglist)
+register.inclusion_tag('taggit_templatetags/tagcloud_include.html')(include_tagcloud)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/text/migrations/0003_auto__del_field_annotation_tags_field.py	Thu Apr 10 15:55:47 2014 +0200
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Deleting field 'Annotation.tags_field'
+        db.delete_column(u'text_annotation', 'tags_field')
+
+
+    def backwards(self, orm):
+        # Adding field 'Annotation.tags_field'
+        db.add_column(u'text_annotation', 'tags_field',
+                      self.gf('tagging.fields.TagField')(max_length=2048, null=True),
+                      keep_default=False)
+
+
+    models = {
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'taggit.tag': {
+            'Meta': {'object_name': 'Tag'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
+        },
+        u'taggit.taggeditem': {
+            'Meta': {'object_name': 'TaggedItem'},
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
+        },
+        u'text.annotation': {
+            'Meta': {'object_name': 'Annotation'},
+            'color': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'contributor': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'creator': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'external_id': ('django.db.models.fields.CharField', [], {'default': "u'9ecffd11-be56-11e3-8877-c8bcc896c290'", 'unique': 'True', 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'update_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'uri': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        }
+    }
+
+    complete_apps = ['text']
\ No newline at end of file
--- a/src/ldt/ldt/text/models.py	Thu Apr 03 15:58:25 2014 +0200
+++ b/src/ldt/ldt/text/models.py	Thu Apr 10 15:55:47 2014 +0200
@@ -1,9 +1,8 @@
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
-from tagging.models import Tag
+from taggit.managers import TaggableManager
 from utils import generate_uuid
 import lxml.etree
-import tagging.fields
 #from django.core.management.validation import max_length
 
 def Property(func):
@@ -13,7 +12,7 @@
 class Annotation(models.Model):
     external_id = models.CharField(max_length=255, null=False, unique=True, default=generate_uuid, verbose_name=_('annotation.external_id'))
     uri = models.CharField(max_length=1024, verbose_name=_('annotation.uri'))
-    tags_field = tagging.fields.TagField(max_length=2048, null=True, blank=True, verbose_name=_('annotation.tags'))
+    tags_field = TaggableManager()
     title = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('annotation.title'))
     description = models.TextField(null=True, blank=True, verbose_name=_('annotation.description'))
     text = models.TextField(null=True, blank=True, verbose_name=_('annotation.text'))
@@ -46,19 +45,14 @@
     @Property
     def tag_list(): #@NoSelf
         def fget(self):
-            return [t.name for t in Tag.objects.get_for_object(self)]
+            #return [t.name for t in Tag.objects.get_for_object(self)]
+            return self.tags.names()
         
         return locals()
         
     
-    def get_tag_list(self):
-        tags = []
-        if self.tags:
-            tags_list = unicode(self.tags)
-            for t in tags_list.split(","):
-                tags.append(t.strip()) 
-        return tags
-        #return self.tags
+    def get_tag_list(self): 
+        return self.tags.names()
 
 
     def __unicode__(self):