Add memcached and sorl thumbnail pour thumbnail management. Set default pict on content, project and user.
authorcavaliet
Fri, 30 Dec 2011 18:16:44 +0100
changeset 314 1a8620e5ebb0
parent 313 f47e9d4c8a59
child 315 877f89ec1efa
child 316 dd4a26c7f3d2
Add memcached and sorl thumbnail pour thumbnail management. Set default pict on content, project and user.
.hgignore
src/ldt/ldt/ldt_utils/migrations/0006_auto__add_field_media_image.py
src/ldt/ldt/ldt_utils/migrations/0007_auto__add_field_content_image__del_field_media_image.py
src/ldt/ldt/ldt_utils/migrations/0008_auto__add_field_project_image.py
src/ldt/ldt/ldt_utils/models.py
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/contentslist.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/projectslist.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/publishedprojectslist.html
src/ldt/ldt/settings.py
src/ldt/ldt/templates/ldt/ldt_base.html
src/ldt/ldt/user/forms.py
src/ldt/ldt/user/migrations/0006_auto__add_field_userprofile_image.py
src/ldt/ldt/user/models.py
src/ldt/ldt/user/templates/ldt/user/change_profile.html
src/ldt/ldt/user/urls.py
src/ldt/ldt/user/views.py
virtualenv/res/src/python-memcached-1.48.tar.gz
virtualenv/res/src/sorl-sorl-thumbnail-v10.12.1-65-g2285451.tar.gz
web/ldtplatform/settings.py
web/static/media/thumbnails/contents/content_default_icon.png
web/static/media/thumbnails/groups/group_default_icon.png
web/static/media/thumbnails/projects/project_default_icon.png
web/static/media/thumbnails/users/user_default_icon.png
--- a/.hgignore	Wed Dec 28 11:43:19 2011 +0100
+++ b/.hgignore	Fri Dec 30 18:16:44 2011 +0100
@@ -47,4 +47,6 @@
 syntax: regexp
 ^src/ldt/MANIFEST$
 syntax: regexp
-^\.pydevproject$
\ No newline at end of file
+^\.pydevproject$
+syntax: regexp
+^web/static/media/cache$
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/migrations/0006_auto__add_field_media_image.py	Fri Dec 30 18:16:44 2011 +0100
@@ -0,0 +1,135 @@
+# encoding: 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):
+        
+        # Adding field 'Media.image'
+        db.add_column('ldt_utils_media', 'image', self.gf('sorl.thumbnail.fields.ImageField')(default='thumbnails/contents/drive.jpg', max_length=100), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Media.image'
+        db.delete_column('ldt_utils_media', 'image')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            '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'}),
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        },
+        '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': '512', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lastname': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'})
+        },
+        'ldt_utils.content': {
+            'Meta': {'ordering': "['title']", 'object_name': 'Content'},
+            'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'default': "u'65f86bb5-320d-11e1-a191-c8bcc896c290'", 'unique': 'True', 'max_length': '1024'}),
+            'iriurl': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'media_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ldt_utils.Media']", 'null': 'True', 'blank': 'True'}),
+            'tags': ('tagging.fields.TagField', [], {'max_length': '2048', 'null': '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'})
+        },
+        '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': "orm['auth.User']", '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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/media/drive.jpg'", 'max_length': '100'}),
+            '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', [], {'unique': 'True', 'max_length': '1024'}),
+            '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'})
+        },
+        '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': "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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ldt': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'ldt_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'}),
+            'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        },
+        'ldt_utils.segment': {
+            'Meta': {'unique_together': "(('project_id', 'iri_id', 'ensemble_id', 'cutting_id', 'element_id'),)", 'object_name': 'Segment'},
+            'abstract': ('django.db.models.fields.TextField', [], {'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': "orm['ldt_utils.Content']"}),
+            'cutting_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            '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': '1024'}),
+            'ensemble_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'project_id': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'project_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ldt_utils.Project']", 'null': 'True'}),
+            'start_ts': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
+            'tags': ('tagging.fields.TagField', [], {'max_length': '2048', 'null': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['ldt_utils']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/migrations/0007_auto__add_field_content_image__del_field_media_image.py	Fri Dec 30 18:16:44 2011 +0100
@@ -0,0 +1,141 @@
+# encoding: 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):
+        
+        # Adding field 'Content.image'
+        db.add_column('ldt_utils_content', 'image', self.gf('sorl.thumbnail.fields.ImageField')(default='thumbnails/contents/drive.jpg', max_length=100), keep_default=False)
+
+        # Deleting field 'Media.image'
+        db.delete_column('ldt_utils_media', 'image')
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Content.image'
+        db.delete_column('ldt_utils_content', 'image')
+
+        # Adding field 'Media.image'
+        db.add_column('ldt_utils_media', 'image', self.gf('sorl.thumbnail.fields.ImageField')(default='thumbnails/media/drive.jpg', max_length=100), keep_default=False)
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            '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'}),
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        },
+        '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': '512', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lastname': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'})
+        },
+        'ldt_utils.content': {
+            'Meta': {'ordering': "['title']", 'object_name': 'Content'},
+            'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/contents/drive.jpg'", 'max_length': '100'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'default': "u'4f16ee5c-3221-11e1-90ce-c8bcc896c290'", 'unique': 'True', 'max_length': '1024'}),
+            'iriurl': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'media_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ldt_utils.Media']", 'null': 'True', 'blank': 'True'}),
+            'tags': ('tagging.fields.TagField', [], {'max_length': '2048', 'null': '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'})
+        },
+        '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': "orm['auth.User']", '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'}),
+            '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', [], {'unique': 'True', 'max_length': '1024'}),
+            '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'})
+        },
+        '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': "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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ldt': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'ldt_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'}),
+            'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        },
+        'ldt_utils.segment': {
+            'Meta': {'unique_together': "(('project_id', 'iri_id', 'ensemble_id', 'cutting_id', 'element_id'),)", 'object_name': 'Segment'},
+            'abstract': ('django.db.models.fields.TextField', [], {'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': "orm['ldt_utils.Content']"}),
+            'cutting_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            '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': '1024'}),
+            'ensemble_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'project_id': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'project_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ldt_utils.Project']", 'null': 'True'}),
+            'start_ts': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
+            'tags': ('tagging.fields.TagField', [], {'max_length': '2048', 'null': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['ldt_utils']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/migrations/0008_auto__add_field_project_image.py	Fri Dec 30 18:16:44 2011 +0100
@@ -0,0 +1,136 @@
+# encoding: 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):
+        
+        # Adding field 'Project.image'
+        db.add_column('ldt_utils_project', 'image', self.gf('sorl.thumbnail.fields.ImageField')(default='thumbnails/projects/project_default_icon.png', max_length=100), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Project.image'
+        db.delete_column('ldt_utils_project', 'image')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            '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'}),
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        },
+        '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': '512', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lastname': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'})
+        },
+        'ldt_utils.content': {
+            'Meta': {'ordering': "['title']", 'object_name': 'Content'},
+            'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/contents/content_default_icon.png'", 'max_length': '100'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'default': "u'6298620f-323c-11e1-b412-c8bcc896c290'", 'unique': 'True', 'max_length': '1024'}),
+            'iriurl': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'media_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ldt_utils.Media']", 'null': 'True', 'blank': 'True'}),
+            'tags': ('tagging.fields.TagField', [], {'max_length': '2048', 'null': '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'})
+        },
+        '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': "orm['auth.User']", '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'}),
+            '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', [], {'unique': 'True', 'max_length': '1024'}),
+            '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'})
+        },
+        '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': "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'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/projects/project_default_icon.png'", 'max_length': '100'}),
+            'ldt': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'ldt_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'}),
+            'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
+        },
+        'ldt_utils.segment': {
+            'Meta': {'unique_together': "(('project_id', 'iri_id', 'ensemble_id', 'cutting_id', 'element_id'),)", 'object_name': 'Segment'},
+            'abstract': ('django.db.models.fields.TextField', [], {'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': "orm['ldt_utils.Content']"}),
+            'cutting_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            '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': '1024'}),
+            'ensemble_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'iri_id': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'project_id': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'project_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ldt_utils.Project']", 'null': 'True'}),
+            'start_ts': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
+            'tags': ('tagging.fields.TagField', [], {'max_length': '2048', 'null': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['ldt_utils']
--- a/src/ldt/ldt/ldt_utils/models.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/models.py	Fri Dec 30 18:16:44 2011 +0100
@@ -8,6 +8,7 @@
 import ldt.indexation
 from ldt.security.models import SafeModel
 from ldt.security.manager import SafeManager
+from sorl.thumbnail import ImageField
 from utils import (create_ldt, copy_ldt, create_empty_iri, update_iri, 
     generate_uuid, clean_description)
 import lucene
@@ -126,6 +127,8 @@
     tags = tagging.fields.TagField(max_length=2048, null=True, blank=True)
     media_obj = models.ForeignKey('Media', blank=True, null=True)
     
+    image = ImageField(upload_to=settings.MEDIA_ROOT+"thumbnails/contents/", default="thumbnails/contents/content_default_icon.png")
+    
     class Meta:
         ordering = ["title"]
         permissions = (
@@ -351,6 +354,8 @@
     state = models.IntegerField(choices=STATE_CHOICES, default=1)
     description = models.TextField(null=True, blank=True)
     
+    image = ImageField(upload_to=settings.MEDIA_ROOT+"thumbnails/projects/", default="thumbnails/projects/project_default_icon.png")
+    
     class Meta:
         ordering = ["title"]
         permissions = (
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/contentslist.html	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/contentslist.html	Fri Dec 30 18:16:44 2011 +0100
@@ -1,4 +1,5 @@
 {% load i18n %}
+{% load thumbnail %}
 <div class="projectscontentsheader projectcontentsheadertitle span-12 last" id="contentsheader">
 {% trans "name" %}
 </div>
@@ -7,9 +8,10 @@
 	    <tbody class="projectscontentsbody">
 	{% for content in contents %}
 		<tr class="imageline {% cycle 'projectscontentsoddline' 'projectscontentsevenline'%}">
-		    <td class="cellimg"><div class="cellimgdiv"><img src="{{LDT_MEDIA_PREFIX}}/img/page_add.png" title="{% trans 'create project' %}" alt="{% trans 'create project' %}" href="{% url ldt.ldt_utils.views.create_project content.iri_id %}" class="ldt_link_create_project"/></div></td>
-		    <td class="cellimg"><div class="cellimgdiv"><img  alt="{% trans 'preview media'%}" title="{% trans 'preview media'%}" src="{{LDT_MEDIA_PREFIX}}/img/control_play.png" href="{% url ldt.ldt_utils.views.index content.iri_id %}" class="ldt_link_open_ldt"/></div></td>
-		    <td class="contenttitle"><a {% if content.change %} class="contenttitlelink infostooltip" href="{% url ldt.ldt_utils.views.write_content iri_id=content.iri_id %}" data-title="{{ content.title}}"  data-desc="{{ content.description }}" {% else %} class="contenttitlelink qtiplink" title="{% trans "You can't edit this content" %}" {% endif %}>{{ content.title|default:"_" }}</a></td>
+		  <td class="cellimg"><div class="cellimgdiv"><img src="{{LDT_MEDIA_PREFIX}}/img/page_add.png" title="{% trans 'create project' %}" alt="{% trans 'create project' %}" href="{% url ldt.ldt_utils.views.create_project content.iri_id %}" class="ldt_link_create_project"/></div></td>
+		  <td class="cellimg"><div class="cellimgdiv"><img  alt="{% trans 'preview media'%}" title="{% trans 'preview media'%}" src="{{LDT_MEDIA_PREFIX}}/img/control_play.png" href="{% url ldt.ldt_utils.views.index content.iri_id %}" class="ldt_link_open_ldt"/></div></td>
+		  <td>{% thumbnail content.image "50x50" format="PNG" crop="top" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">{% endthumbnail %}</td>
+		  <td class="contenttitle"><a {% if content.change %} class="contenttitlelink infostooltip" href="{% url ldt.ldt_utils.views.write_content iri_id=content.iri_id %}" data-title="{{ content.title}}"  data-desc="{{ content.description }}" {% else %} class="contenttitlelink qtiplink" title="{% trans "You can't edit this content" %}" {% endif %}>{{ content.title|default:"_" }}</a></td>
 		</tr>
 	{% endfor %}
 		</tbody>
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/projectslist.html	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/projectslist.html	Fri Dec 30 18:16:44 2011 +0100
@@ -1,4 +1,5 @@
 {% load i18n %}
+{% load thumbnail %}
 <div class="projectscontentsheader projectcontentsheadertitle span-12 last" id="projectsheader">
 {% trans "name" %}
 </div>
@@ -37,7 +38,7 @@
         <img src="{{ADMIN_MEDIA_PREFIX}}img/admin/icon-no.gif" {% if project.change %} alt="{% trans 'Project not published, click to publish' %}" title="{% trans 'Project not published, click to publish' %}" class="unpublishedproject qtiplink" {% else %} class="qtiplink" title="{% trans "You are not allowed to change this project" %}"{% endif %}id="project_{{project.ldt_id}}" />
         {% endifequal %}
         </td>
-        
+        <td>{% thumbnail project.image "50x50" crop="center" format="PNG" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />{% empty %}&nbsp;{% endthumbnail %}</td>
         <td class="projecttitle">
         {% if project.state == 2 %}
         <span class="projecttitlelink infostooltip" data-title="{{ project.title }}" data-desc="{{ project.description|linebreaksbr }}" >{% if show_username %}{{ project.owner.username }} : {% endif %}{{ project.title }}</span>
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/publishedprojectslist.html	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/publishedprojectslist.html	Fri Dec 30 18:16:44 2011 +0100
@@ -1,4 +1,5 @@
 {% load i18n %}
+{% load thumbnail %}
 <div class="projectscontentsheader projectcontentsheadertitle span-12 last" id="projectsheader">
 {% trans "name" %}
 </div>
@@ -18,6 +19,7 @@
         <td class="cellimg">
         <img src="{{ADMIN_MEDIA_PREFIX}}img/admin/icon-yes.gif" alt="{% trans 'Project published' %}" id="project_{{project.ldt_id}}" />
         </td>
+        <td>{% thumbnail project.image "50x50" crop="center" format="PNG" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />{% empty %}&nbsp;{% endthumbnail %}</td>
         <td class="projecttitle">
         {% ifequal project.state 2 %}
         <span class="projectinfos" data-title="{{ project.title }}" data-desc="{{ project.description|linebreaksbr }}">{{ project.title }}</span>
--- a/src/ldt/ldt/settings.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/settings.py	Fri Dec 30 18:16:44 2011 +0100
@@ -32,10 +32,13 @@
     'social_auth',
     'south',
     'guardian',
+    'sorl.thumbnail',
 )
 
 MIDDLEWARE_CLASSES = (
+    'django.middleware.cache.UpdateCacheMiddleware',
     'django.middleware.common.CommonMiddleware',
+    'django.middleware.cache.FetchFromCacheMiddleware',
     'ldt.ldt_utils.middleware.swfupload.SWFUploadMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
--- a/src/ldt/ldt/templates/ldt/ldt_base.html	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/templates/ldt/ldt_base.html	Fri Dec 30 18:16:44 2011 +0100
@@ -2,6 +2,7 @@
 {% load i18n %}
 {% load logintag %}
 {% load navigation %}
+{% load thumbnail %}
 
 {% block js_import %}
 	<script type="text/javascript">
@@ -89,7 +90,10 @@
 	        	<a href="{% url admin:index %}" title="{% trans "Link to admin" %}">{% trans "Staff" %}</a>|
 	        {% endif %}
             {% if user.is_authenticated %}
-            <a href="{% url ldt.user.views.profile %}"  title="{% trans "Profile change" %}">{{user.username}}</a>|&nbsp;<a href="{% url ldt.user.views.logout_view %}" title="{% trans "Log out" %}">{% trans "Log out" %}</a>
+            <a href="{% url ldt.user.views.profile %}"  title="{% trans "Profile change" %}">
+              {% thumbnail user.get_profile.image "20x20" crop="center" format="PNG" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />{% empty %}&nbsp;{% endthumbnail %}
+              {{user.username}}</a>
+            |&nbsp;<a href="{% url ldt.user.views.logout_view %}" title="{% trans "Log out" %}">{% trans "Log out" %}</a>
             {% endif %}
         </div>
         {% endblock %}
--- a/src/ldt/ldt/user/forms.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/user/forms.py	Fri Dec 30 18:16:44 2011 +0100
@@ -117,5 +117,24 @@
         profile.language = self.cleaned_data['language']
         profile.save()
         return self.user
+        
+        
+class ProfilePictureForm(forms.Form):
+    image = forms.ImageField(label=_("Profile picture"))
+    
+    def __init__(self, user=None, *args, **kwargs):
+        self.user = user
+        super(ProfilePictureForm, self).__init__(*args, **kwargs)
+        
+    def save(self):
+        profile = self.user.get_profile()
+        # We change the file name and keep the extension.
+        filename = self.cleaned_data['image'].name
+        ext = filename.split(".")[-1]
+        self.cleaned_data['image'].name = self.user.username + "." + ext
+        # We save the picture with the correct name
+        profile.image = self.cleaned_data['image']
+        profile.save()
+        return self.user
     
         
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/user/migrations/0006_auto__add_field_userprofile_image.py	Fri Dec 30 18:16:44 2011 +0100
@@ -0,0 +1,71 @@
+# encoding: 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):
+        
+        # Adding field 'UserProfile.image'
+        db.add_column('user_userprofile', 'image', self.gf('sorl.thumbnail.fields.ImageField')(default='thumbnails/users/user_default_icon.png', max_length=100), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'UserProfile.image'
+        db.delete_column('user_userprofile', 'image')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            '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'}),
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        },
+        'user.ldt': {
+            'Meta': {'object_name': 'Ldt', '_ormbases': ['auth.User']},
+            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        'user.userprofile': {
+            'Meta': {'object_name': 'UserProfile'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('sorl.thumbnail.fields.ImageField', [], {'default': "'thumbnails/users/user_default_icon.png'", 'max_length': '100'}),
+            'language': ('django.db.models.fields.CharField', [], {'default': "'fr'", 'max_length': '2'}),
+            'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
+        }
+    }
+
+    complete_apps = ['user']
--- a/src/ldt/ldt/user/models.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/user/models.py	Fri Dec 30 18:16:44 2011 +0100
@@ -3,6 +3,7 @@
 from django.contrib.auth.models import User, UserManager, Group
 from django.db import models
 from django.db.models.signals import post_save
+from sorl.thumbnail import ImageField
 import datetime
 
         
@@ -34,6 +35,8 @@
 class UserProfile (models.Model): 
     user = models.OneToOneField(User)
     language = models.CharField(max_length=2, default=settings.LANGUAGE_CODE[:2])
+    
+    image = ImageField(upload_to=settings.MEDIA_ROOT+"thumbnails/users/", default="thumbnails/users/user_default_icon.png")
 
     @staticmethod
     def create_user_profile(sender, instance, created, **kwargs):
--- a/src/ldt/ldt/user/templates/ldt/user/change_profile.html	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/user/templates/ldt/user/change_profile.html	Fri Dec 30 18:16:44 2011 +0100
@@ -2,6 +2,8 @@
 {# form of profile change #}
 
 {% load i18n %}
+{% load thumbnail %}
+
 {% block css_import %}
 	{{ block.super }}
     <style type="text/css">
@@ -18,6 +20,26 @@
 	</style>
 {% endblock %}
 
+
+{% block js_import %}
+{{block.super}}
+<script language="javascript">
+$(document).ready(function(){
+	$("#id_image").change(function(){
+		var ext = $('#id_image').val().split('.').pop().toLowerCase();
+		if($.inArray(ext, ['png','jpg','jpeg']) == -1) {
+		    alert('{% trans "Invalid extension ! Your file has to be JPG, JPEG or PNG." %}');
+            $("#id_submit_profile_picture").css('visibility', 'hidden');
+		}
+		else{
+			$("#id_submit_profile_picture").css('visibility', 'visible');
+		}
+	});
+});
+</script>
+{% endblock %}
+
+
 {% block content %}
 {{ block.super }}
 
@@ -132,10 +154,41 @@
         <tr>
         	<td></td>
         	<td><input type="submit" name="submit_password" value="{% trans "Password change" %}" /></td>
-        </tr>         
+        </tr>
     </table>
 </form>
 
+<form enctype="multipart/form-data" method="post" action="{% url ldt.user.views.profile_picture %}">
+{% csrf_token %}
+  <table>
+	<tr>
+	    <td class="leftcolumn">
+	        <strong>{% trans "Current profile picture" %}</strong>
+	    </td>
+	    <td>
+	        {% thumbnail user.get_profile.image "x100" format="PNG" as im %}<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />{% empty %}&nbsp;{% endthumbnail %}
+	    </td>
+	</tr>
+    <tr>
+        <td class="leftcolumn">
+            <label for="id_new_profile_picture">{% trans "Upload your new profile picture" %}<br/> (JPG, PNG, &lt;&nbsp;1&nbsp;Mo)</label>
+        </td>
+        <td>
+            <input type="file" name="image" id="id_image" accept="image/jpeg, image/png" />
+            {% for error in profile_picture_form.image.errors %}
+            <span class="error">
+                {{ error }}                 
+            </span>
+            {% endfor %}
+        </td>
+    </tr>
+    <tr>
+        <td></td>
+        <td><input type="submit" name="submit_profile_picture" id="id_submit_profile_picture" value="{% trans "Profile picture change" %}" style="visibility:hidden" /></td>
+    </tr>
+  </table>
+</form>
+
 </div>
 
 {% endblock%}
--- a/src/ldt/ldt/user/urls.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/user/urls.py	Fri Dec 30 18:16:44 2011 +0100
@@ -4,6 +4,7 @@
     url(r'^loginAjax/$', 'ldt.user.views.login_ajax'),
     url(r'^profile/$', 'ldt.user.views.profile'),
     url(r'^password/$', 'ldt.user.views.password'),
+    url(r'^picture/$', 'ldt.user.views.profile_picture'),
     url(r'^logout/', 'ldt.user.views.logout_view'),
 #    url(r'^space/ldt/$', 'ldt.ldt_utils.views.list_ldt'),
 #    url(r'^space/ldt/indexproject/(?P<id>.*)$', 'ldt.ldt_utils.views.index_project'),
--- a/src/ldt/ldt/user/views.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/src/ldt/ldt/user/views.py	Fri Dec 30 18:16:44 2011 +0100
@@ -6,7 +6,7 @@
 from django.template import RequestContext, loader
 from django.utils import simplejson
 from django.utils.translation import ugettext as _
-from forms import ProfileForm, LanguageChangeForm
+from forms import ProfileForm, LanguageChangeForm, ProfilePictureForm
 from django.views.i18n import set_language
 
     
@@ -16,7 +16,7 @@
     user_language = request.user.get_profile().language
     
     if request.method == "POST":
-        profile_form = ProfileForm(request.user, request.POST, instance=request.user)                 
+        profile_form = ProfileForm(request.user, request.POST, instance=request.user)
         language_form = LanguageChangeForm(request.user, request.POST)
         password_form = PasswordChangeForm(request.user)
 
@@ -36,7 +36,10 @@
         language_form = LanguageChangeForm()
         profile_form = ProfileForm(instance=request.user)
         password_form = PasswordChangeForm(request.user)
-    return render_to_response('ldt/user/change_profile.html', {'profile_form' : profile_form, 'language_form' : language_form, 'password_form' : password_form, 'user_language' : user_language, 'msg' : msg }, context_instance=RequestContext(request))    
+    
+    profile_picture_form = ProfilePictureForm()
+    
+    return render_to_response('ldt/user/change_profile.html', {'profile_form' : profile_form, 'language_form' : language_form, 'password_form' : password_form, 'user_language' : user_language, 'profile_picture_form':profile_picture_form, 'msg' : msg }, context_instance=RequestContext(request))    
 
     
 @login_required   
@@ -56,7 +59,33 @@
         language_form = LanguageChangeForm()
         profile_form = ProfileForm()
         password_form = PasswordChangeForm(request.user)
-    return render_to_response('ldt/user/change_profile.html', {'profile_form' : profile_form, 'language_form' : language_form, 'password_form' : password_form, 'user_language' : user_language, 'msg' : msg }, context_instance=RequestContext(request))
+    
+    profile_picture_form = ProfilePictureForm()
+    
+    return render_to_response('ldt/user/change_profile.html', {'profile_form' : profile_form, 'language_form' : language_form, 'password_form' : password_form, 'user_language' : user_language, 'profile_picture_form':profile_picture_form, 'msg' : msg }, context_instance=RequestContext(request))    
+
+    
+@login_required   
+def profile_picture(request):
+    msg = ''
+    user_language = request.user.get_profile().language
+   
+    if request.method == "POST":
+        profile_form = ProfileForm(instance=request.user)
+        language_form = LanguageChangeForm(request.user, request.POST)
+        password_form = PasswordChangeForm(request.user)
+        profile_picture_form = ProfilePictureForm(request.user, request.POST, request.FILES)
+        if profile_picture_form.is_valid():
+            profile_picture_form.save()
+            msg = _("Your profile picture has been updated.")
+
+    else:
+        language_form = LanguageChangeForm()
+        profile_form = ProfileForm()
+        password_form = PasswordChangeForm(request.user)
+        profile_picture_form = ProfilePictureForm()
+    
+    return render_to_response('ldt/user/change_profile.html', {'profile_form' : profile_form, 'language_form' : language_form, 'password_form' : password_form, 'user_language' : user_language, 'profile_picture_form':profile_picture_form, 'msg' : msg }, context_instance=RequestContext(request))
 
 
 def logout_view(request):
Binary file virtualenv/res/src/python-memcached-1.48.tar.gz has changed
Binary file virtualenv/res/src/sorl-sorl-thumbnail-v10.12.1-65-g2285451.tar.gz has changed
--- a/web/ldtplatform/settings.py	Wed Dec 28 11:43:19 2011 +0100
+++ b/web/ldtplatform/settings.py	Fri Dec 30 18:16:44 2011 +0100
@@ -78,8 +78,10 @@
 )
 
 MIDDLEWARE_CLASSES = (
+    'django.middleware.cache.UpdateCacheMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.cache.FetchFromCacheMiddleware',
     'django.middleware.gzip.GZipMiddleware',
-    'django.middleware.common.CommonMiddleware',
     'ldt.ldt_utils.middleware.swfupload.SWFUploadMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
@@ -140,6 +142,7 @@
     'social_auth',
     'south',
     'guardian',
+    'sorl.thumbnail',
 )
 
 AUTH_PROFILE_MODULE = 'user.UserProfile'
Binary file web/static/media/thumbnails/contents/content_default_icon.png has changed
Binary file web/static/media/thumbnails/groups/group_default_icon.png has changed
Binary file web/static/media/thumbnails/projects/project_default_icon.png has changed
Binary file web/static/media/thumbnails/users/user_default_icon.png has changed