collection first step
authorcavaliet
Wed, 26 Jun 2013 16:53:45 +0200
changeset 159 b98558f8d2c1
parent 158 8860d922f37c
child 163 39a17b6e0b57
collection first step
src/egonomy/migrations/0003_add_collection_and_items.py
src/egonomy/models.py
src/egonomy/templates/egonomy_all_collections.html
src/egonomy/templates/egonomy_annotate_picture.html
src/egonomy/templates/egonomy_create_fragment.html
src/egonomy/templates/egonomy_newbase.html
src/egonomy/templates/egonomy_view_collection.html
src/egonomy/templates/egonomy_view_fragment.html
src/egonomy/templates/partial/collection_in_list.html
src/egonomy/templates/partial/fragment_in_list.html
src/egonomy/templates/partial/image_in_list.html
src/egonomy/urls.py
src/egonomy/views.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/migrations/0003_add_collection_and_items.py	Wed Jun 26 16:53:45 2013 +0200
@@ -0,0 +1,158 @@
+# -*- 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):
+        # Adding model 'Collection'
+        db.create_table(u'egonomy_collection', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=2048, null=True, blank=True)),
+            ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+            ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+            ('creation', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+            ('modification', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+            ('public', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('publication_type', self.gf('django.db.models.fields.IntegerField')(default=1)),
+        ))
+        db.send_create_signal(u'egonomy', ['Collection'])
+
+        # Adding model 'CollectionItem'
+        db.create_table(u'egonomy_collectionitem', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+            ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+            ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+            ('collection', self.gf('django.db.models.fields.related.ForeignKey')(related_name='items', to=orm['egonomy.Collection'])),
+        ))
+        db.send_create_signal(u'egonomy', ['CollectionItem'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Collection'
+        db.delete_table(u'egonomy_collection')
+
+        # Deleting model 'CollectionItem'
+        db.delete_table(u'egonomy_collectionitem')
+
+
+    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'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': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        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'egonomy.collection': {
+            'Meta': {'object_name': 'Collection'},
+            'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'creation': ('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'}),
+            'modification': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'publication_type': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'})
+        },
+        u'egonomy.collectionitem': {
+            'Meta': {'object_name': 'CollectionItem'},
+            'collection': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'items'", 'to': u"orm['egonomy.Collection']"}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+            'order': ('django.db.models.fields.IntegerField', [], {})
+        },
+        u'egonomy.fragment': {
+            'Meta': {'object_name': 'Fragment'},
+            'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'coordinates': ('django.db.models.fields.TextField', [], {}),
+            'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_saved': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['egonomy.Image']"}),
+            'tags': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'})
+        },
+        u'egonomy.image': {
+            'Meta': {'object_name': 'Image'},
+            'id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'primary_key': 'True'}),
+            'info': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['egonomy.ImageInfo']", 'null': 'True', 'blank': 'True'}),
+            'metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['egonomy.ImageMetadata']"})
+        },
+        u'egonomy.imageinfo': {
+            'Meta': {'object_name': 'ImageInfo'},
+            'exif': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'height': ('django.db.models.fields.IntegerField', [], {}),
+            'id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'primary_key': 'True'}),
+            'image_file': ('django.db.models.fields.files.ImageField', [], {'max_length': '2048'}),
+            'mimetype': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
+            'width': ('django.db.models.fields.IntegerField', [], {})
+        },
+        u'egonomy.imagemetadata': {
+            'Meta': {'object_name': 'ImageMetadata'},
+            'auteur': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'cliche': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'date': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'date_inserted': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_pertimm': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'diametre': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '15', 'blank': 'True'}),
+            'droits': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'hauteur': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '15', 'blank': 'True'}),
+            'id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'primary_key': 'True'}),
+            'inventaire': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'lieu': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'localisation': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'longueur': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '15', 'blank': 'True'}),
+            'mentions': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'mots_cles': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'periode': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'photographe': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'profondeur': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '15', 'blank': 'True'}),
+            'site': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'technique': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'thesaurus_pertimm': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'titre': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'titre_pertimm': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['egonomy']
\ No newline at end of file
--- a/src/egonomy/models.py	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/models.py	Wed Jun 26 16:53:45 2013 +0200
@@ -7,6 +7,8 @@
 
 from django.db import models
 from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
 
 class ImageMetadata(models.Model):
     
@@ -166,14 +168,15 @@
         
         return vb
 
-    
+
+
 class Collection(models.Model):
     
     SLIDESHOW = 1
     MOSAIC = 2
     GEOGRAPHICAL = 3
       
-    STATE_CHOICES = (
+    PUBLICATION_CHOICES = (
     (SLIDESHOW, 'slideshow'),
     (MOSAIC, 'mosaic'),
     (GEOGRAPHICAL, 'geographical')
@@ -185,7 +188,20 @@
     author = models.ForeignKey(User, blank=False, null=False)
     creation = models.DateTimeField(auto_now_add=True)
     modification = models.DateTimeField(auto_now=True)
-    public = models.BooleanField(null=False, default=True) # Collection is published or not, always published by default 
+    public = models.BooleanField(null=False, default=True) # Collection is published or not, always published by default
+    publication_type = models.IntegerField(choices=PUBLICATION_CHOICES, default=1) # slideshow, mosaic ou geographical
+
+
+
+class CollectionItem(models.Model):
+    
+    content_type = models.ForeignKey(ContentType) # can be image ou fragment
+    object_id = models.PositiveIntegerField()
+    content_object = generic.GenericForeignKey('content_type', 'object_id')
+    description = models.TextField(blank=True, null=True)
+    order = models.IntegerField()
+    # An item belongs to only one collection. Collection will have "items" related name.
+    collection = models.ForeignKey(Collection, related_name='items')
     
     
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templates/egonomy_all_collections.html	Wed Jun 26 16:53:45 2013 +0200
@@ -0,0 +1,65 @@
+{% extends "egonomy_newbase.html" %}
+{% load static %}
+{% load i18n %}
+{% load thumbnail %}
+{% load navigation %}
+
+{% block title %}{% trans "All collection" %}{% endblock %}
+
+{% block css_page %}
+<style>
+.bar-tools:first-child {
+    background-position: bottom center;
+}
+</style>
+{% endblock %}
+
+{% block popins %}
+    <div class="popin-wrap">
+        <div id="new-collection" class="popin popin-new-collection box-shadow">
+            <header>
+                <h2>{% trans "New collection" %}</h2>
+                <a href="#" class="close-popin"></a>
+            </header>
+            <section>
+                <form action="{% url 'new_collection' %}" method="POST">
+                    <p>
+                        <label for="collection-title">{% trans "Title" %} :</label>
+                        <input type="text" name="collection-title" id="collection-title">
+                    </p>
+                    <p>
+                        <label class="block" for="collection-description">{% trans "Description" %} :</label>
+                        <textarea name="collection-description" id="collection-description"></textarea>
+                    </p>
+                    <div class="buttons">
+                        <a href="#" class="btn close-popin">{% trans "Cancel" %}</a>
+                        <input class="btn" type="submit" value="{% trans 'Submit' %}">
+                    </div>{% csrf_token %}
+                </form>
+            </section>
+        </div>
+    </div>
+{% endblock %}
+
+{% block content %}
+            <div class="bar-tools clearfix">
+              {% if user_collections %}
+                <h3>{% blocktrans count counter=results|length %}My collection{% plural %}My {{ counter }} collections{% endblocktrans %}</h3>
+              {% else %}
+                <h3>{% trans "All collections" %}</h3>
+              {% endif %}
+                <ul class="clearfix">
+                    <li><a class="open-popin" href="#new-collection">{% trans "New collection" %}</a></li>
+                </ul>
+            </div>
+            {% if nb_pages > 1 %}{% build_pagination nb_pages cur_page_nb url_pagination "clickable" %}{% endif %}
+            <ul class="list-projets-2 clearfix no-border-bot">
+              {% for col in results %}
+                <li>
+                {% include "partial/collection_in_list.html" %}
+                </li>
+              {% endfor %}
+            </ul>
+            {% if nb_pages > 1 %}<p>{% build_pagination nb_pages cur_page_nb url_pagination "clickable" %}</p>{% endif %}
+{% endblock %}
+
--- a/src/egonomy/templates/egonomy_annotate_picture.html	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/templates/egonomy_annotate_picture.html	Wed Jun 26 16:53:45 2013 +0200
@@ -5,38 +5,6 @@
 
 {% block title %}{% trans "Annotate a picture" %}{% endblock %}
 
-{% block popins %}
-    <div class="popin-wrap">
-        <div id="add-to-collection" class="popin popin-new-collection box-shadow">
-            <header>
-                <h2>{% trans "Add to the collection" %}</h2>
-                <a href="#" class="close-popin"></a>
-            </header>
-            <section>
-                <form action="#">
-                    <p>
-                        <label for="collection-name">{% trans "Add to" %} :</label>
-                        <label class="styled-select">
-                            <select>
-                                <option selected="" value="/egonomy/allpictures/">Images</option>
-                                <option value="/egonomy/allfragments/">Fragments</option>
-                            </select>
-                        </label>
-                    </p>
-                    <p>
-                        <label class="block" for="image-description">{% trans "Image comment" %} :</label>
-                        <textarea name="" id="image-description"></textarea>
-                    </p>
-                    <div class="buttons">
-                        <a href="#" class="btn close-popin">{% trans "Cancel" %}</a>
-                        <input class="btn" type="submit" value="{% trans 'Submit' %}">
-                    </div>
-                </form>
-            </section>
-        </div>
-    </div>
-{% endblock %}
-
 {% block content %}
             <div class="title-page">
                 <h2>{{ img.metadata.titre|default:_("No title") }}</h2>
@@ -52,9 +20,9 @@
                     </li>
                     <li>
                       {% if user.is_authenticated %}
-                        <a class="icon plus open-popin" href="#add-to-collection">{% trans "Add to my collection" %}</a>
+                        <a class="icon plus open-popin" href="#add-to-collection">{% trans "Add to a collection" %}</a>
                       {% else %}
-                        <a class="icon plus" href="{% url 'login' %}?next={% url 'annotate_picture' image_id=img.id %}">{% trans "Add to my collection" %}</a>
+                        <a class="icon plus" href="{% url 'login' %}?next={% url 'annotate_picture' image_id=img.id %}">{% trans "Add to a collection" %}</a>
                       {% endif %}
                     </li>
                     <!--li>
--- a/src/egonomy/templates/egonomy_create_fragment.html	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/templates/egonomy_create_fragment.html	Wed Jun 26 16:53:45 2013 +0200
@@ -264,15 +264,6 @@
     <script type="text/javascript" src="{% static 'egonomy/lib/jquery-ui/ui/minified/jquery-ui.min.js' %}"></script>
     <script type="text/javascript" src="{% static 'egonomy/lib/tag-it/js/tag-it.min.js' %}"></script>
     <script type="text/javascript">
-        $(function() {
-            $(".search-type").change(function() {
-                $(".search-form").attr("action", $(this).val());
-                if ($(".search-field").val()) {
-                    $(".search-form").submit();
-                }
-            });
-        });
-        
         // Senseetive api management
         function init_sensitive_click(){
             // Init senseetive api request
--- a/src/egonomy/templates/egonomy_newbase.html	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/templates/egonomy_newbase.html	Wed Jun 26 16:53:45 2013 +0200
@@ -21,6 +21,38 @@
 </head>
 {% endblock %}
 <body>
+    {% if current_user_collection_list %}
+    <div class="popin-wrap">
+        <div id="add-to-collection" class="popin popin-new-collection box-shadow">
+            <header>
+                <h2>{% trans "Add to the collection" %}</h2>
+                <a href="#" class="close-popin"></a>
+            </header>
+            <section>
+                <form action="#">
+                    <p>
+                        <label for="collection-name">{% trans "Add to" %} :</label>
+                        <label class="styled-select">
+                            <select name="collection_pk">
+                              {% for c in current_user_collection_list %}
+                                <option value="{{ c.pk }}">{{ c.title }}</option>
+                              {% endfor %}
+                            </select>
+                        </label>
+                    </p>
+                    <p>
+                        <label class="block" for="image-description">{% trans "Image comment" %} :</label>
+                        <textarea name="" id="image-description"></textarea>
+                    </p>
+                    <div class="buttons">
+                        <a href="#" class="btn close-popin">{% trans "Cancel" %}</a>
+                        <input class="btn" type="submit" value="{% trans 'Submit' %}">
+                    </div>
+                </form>
+            </section>
+        </div>
+    </div>
+    {% endif %}
     {% block popins %}{% endblock %}
     <div class="wrap">
         <header class="clearfix">
@@ -30,7 +62,7 @@
                     <li>
                         <form id="search-form" action="{% if search_fragment %}{% url 'all_fragments' %}{% else %}{% url 'all_pictures' %}{% endif %}" method="GET">
                             <p>
-			                    <input id="search-field" type="text" placeholder="{% trans 'Search' %}" id="id_search" name="search"/>
+			                    <input id="search-field" type="text" placeholder="{% trans 'Search' %}" name="search"/>
 			                    <label class="styled-select">
 				                    <select id="search-type">
 				                        <option value="{% url 'all_pictures' %}"{% if not search_fragment %} selected{% endif %}>Images</option>
@@ -53,7 +85,7 @@
                     <ul class="nav clearfix">
                         <li><a href="{% url 'all_pictures' %}">explorer</a></li>
                         <li><span class="dot-10"></span></li>
-                        <li><a href="#">collectionner</a></li>
+                        <li><a href="{% url 'all_collections' %}">collectionner</a></li>
                         <!--li><span class="dot-10"></span></li>
                         <li><a href="#">créer</a></li>
                         <li><span class="dot-10"></span></li>
@@ -61,7 +93,7 @@
                     </ul>
                   {% if user.is_authenticated %}
                     <ul class="sub-nav clearfix">
-                        <li><a href="#" {% if user_collections %}class="active"{% endif %}>mes collections</a></li>
+                        <li><a href="{% url 'user_collections' username=user %}" {% if user_collections %}class="active"{% endif %}>mes collections</a></li>
                         <li><span class="dot-6"></span></li>
                         <li><a href="{% url 'user_fragments' username=user %}" {% if user_fragments %}class="active"{% endif %}>mes fragments</a></li>
                         <!--li><span class="dot-6"></span></li>
@@ -84,17 +116,17 @@
 	    <script type="text/javascript" src="{% static 'egonomy/js/masonry.min.js' %}"></script>
 	    <script type="text/javascript" src="{% static 'egonomy/js/main.js' %}"></script>
 	    {% endblock %}
+        <script type="text/javascript">
+        $(function() {
+            $("#search-type").change(function() {
+                $("#search-form").attr("action", $(this).val());
+                if ($("#search-field").val()) {
+                    $("#search-form").submit();
+                }
+            });
+        });
+        </script>
 	    {% block js_page %}
-	    <script type="text/javascript">
-		$(function() {
-		    $("#search-type").change(function() {
-		        $("#search-form").attr("action", $(this).val());
-		        if ($("#search-field").val()) {
-		            $("#search-form").submit();
-		        }
-		    });
-		});
-        </script>
 	    {% endblock %}
     </body>
 </html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templates/egonomy_view_collection.html	Wed Jun 26 16:53:45 2013 +0200
@@ -0,0 +1,131 @@
+{% extends "egonomy_newbase.html" %}
+{% load static %}
+{% load i18n %}
+{% load thumbnail %}
+
+{% block title %}{% trans "View a fragment" %}{% endblock %}
+
+{% block popins %}
+    <div class="popin-wrap">
+        <div id="collection-parameters" class="popin big-popin box-shadow">
+            <header>
+                <h2>PARAMÈTRES DE LA COLLECTION</h2>
+                <a href="#" class="close-popin"></a>
+            </header>
+            <section>
+                <form action="#">
+                    <div class="col-left">
+                        <table>
+                            <tbody>
+                                <tr>
+                                    <th>Vignette :</th>
+                                    <td>
+                                        <label class="no-margin styled-select">
+                                            <select class="w-192">
+                                                <option selected value="">Mosaïque</option>
+                                                <option value="/egonomy/allfragments/">Argumentaire</option>
+                                            </select>
+                                        </label>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <th>Visibilité :</th>
+                                    <td>
+                                        <label class="no-margin styled-select">
+                                            <select class="w-192">
+                                                <option selected value="">Visible par moi uniquement</option>
+                                            </select>
+                                        </label>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <th><label for="share-collection">Partager :</label></th>
+                                    <td>
+                                        <input id="share-collection" class="w-194" type="text" placeholder="http://">
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <th colspan="2"><label for="description-collection">Description :</label></th>
+                                </tr>
+                                <tr>
+                                    <td colspan="2">
+                                        <textarea name="" id="description-collection"></textarea>
+                                    </td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                     <ul class="list-projets-2 clearfix">
+                        <li>
+                            <div class="top clearfix">
+                                <img src="img/113x113.png" alt="">
+                                <img src="img/113x113-2.png" alt="">
+                            </div>
+                            <div class="mid">
+                                <h3>Collection n°1</h3>
+                                <p>par Hubert Trucchose</p>
+                            </div>
+                            <div class="bot clearfix">
+                                <img src="img/113x113.png" alt="">
+                                <img src="img/113x113-2.png" alt="">
+                            </div>
+                        </li>
+                    </ul>
+                    <div class="buttons">
+                        <a href="#" class="btn close-popin">Annuler</a>
+                        <input class="btn" type="submit" value="Valider">
+                    </div>
+                </form>
+            </section>
+        </div>
+    </div>
+{% endblock %}
+
+{% block content %}
+            <div class="title-page">
+                <h2>{{ col.title }}</h2>
+                <ul class="sub-nav title-menu clearfix">
+                    <li><a href="#" class="active">argumentaire</a></li>
+                    <li><span class="dot-6"></span></li>
+                    <li><a href="#">mosaïque</a></li>
+                    <li><span class="dot-6"></span></li>
+                    <li><a href="#">géographique</a></li>
+                    <!--li><span class="dot-6"></span></li>
+                    <li><a href="#">envoyer vers collage</a></li-->
+                </ul>
+            </div>
+            <div class="bar-tools clearfix">
+                <ul class="clearfix">
+                    <!--li><a href="#">lire le diaporama</a></li>
+                    <li><a class="icon save" href="#">enregistrer sous</a></li-->
+                    <li><a class="open-popin" href="#collection-parameters">Paramètres de la collection</a></li>
+                </ul>
+            </div>
+            <div class="empty-block">
+                <form class="search-form-big" id="search-form-big" action="{% if search_fragment %}{% url 'all_fragments' %}{% else %}{% url 'all_pictures' %}{% endif %}" method="GET">
+                    <p>
+                        <input id="search-field-big" type="text" placeholder="{% trans 'Search' %}" name="search"/>
+                        <label class="styled-select">
+                            <select id="search-type-big">
+                                <option value="{% url 'all_pictures' %}"{% if not search_fragment %} selected{% endif %}>Images</option>
+                                <option value="{% url 'all_fragments' %}"{% if search_fragment %} selected{% endif %}>Fragments</option>
+                            </select>
+                        </label>
+                        <input type="hidden" value="all" name="field">
+                    </p>
+                </form>
+            </div>
+{% endblock %}
+
+{% block js_page %}
+<script type="text/javascript">
+$(function() {
+    $("#search-type-big").change(function() {
+        $("#search-form-big").attr("action", $(this).val());
+        if ($("#search-field-big").val()) {
+            $("#search-form-big").submit();
+        }
+    });
+});
+</script>
+{% endblock %}
--- a/src/egonomy/templates/egonomy_view_fragment.html	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/templates/egonomy_view_fragment.html	Wed Jun 26 16:53:45 2013 +0200
@@ -5,38 +5,6 @@
 
 {% block title %}{% trans "View a fragment" %}{% endblock %}
 
-{% block popins %}
-    <div class="popin-wrap">
-        <div id="add-to-collection" class="popin popin-new-collection box-shadow">
-            <header>
-                <h2>{% trans "Add to the collection" %}</h2>
-                <a href="#" class="close-popin"></a>
-            </header>
-            <section>
-                <form action="#">
-                    <p>
-                        <label for="collection-name">{% trans "Add to" %} :</label>
-                        <label class="styled-select">
-                            <select>
-                                <option selected="" value="/egonomy/allpictures/">Images</option>
-                                <option value="/egonomy/allfragments/">Fragments</option>
-                            </select>
-                        </label>
-                    </p>
-                    <p>
-                        <label class="block" for="image-description">{% trans "Image comment" %} :</label>
-                        <textarea name="" id="image-description"></textarea>
-                    </p>
-                    <div class="buttons">
-                        <a href="#" class="btn close-popin">{% trans "Cancel" %}</a>
-                        <input class="btn" type="submit" value="{% trans 'Submit' %}">
-                    </div>
-                </form>
-            </section>
-        </div>
-    </div>
-{% endblock %}
-
 {% block content %}
             <div class="title-page">
                 <h2>{{ fragment.title }}</h2>
@@ -63,9 +31,9 @@
                     </li>
                     <li>
                       {% if user.is_authenticated %}
-                        <a class="icon plus open-popin" href="#add-to-collection">{% trans "Add to my collection" %}</a>
+                        <a class="icon plus open-popin" href="#add-to-collection">{% trans "Add to a collection" %}</a>
                       {% else %}
-                        <a class="icon plus" href="{% url 'login' %}?next={% url 'view_fragment' fragment_pk=fragment.pk %}">{% trans "Add to my collection" %}</a>
+                        <a class="icon plus" href="{% url 'login' %}?next={% url 'view_fragment' fragment_pk=fragment.pk %}">{% trans "Add to a collection" %}</a>
                       {% endif %}
                     </li>
                     <!--li>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templates/partial/collection_in_list.html	Wed Jun 26 16:53:45 2013 +0200
@@ -0,0 +1,25 @@
+{% load static %}
+{% load i18n %}
+{% load thumbnail %}
+{# we suppose here that "col" has been defined #}
+<div class="tools toggle">
+    <ul class="clearfix">
+        <li><a title="Partager sur Twitter" class="tool twitter" href="#"></a></li>
+        <li><a title="Partager sur Facebook" class="tool facebook" href="#"></a></li>
+        <!--li><a title="Enregistrer" class="tool save" href="#"></a></li-->
+    </ul>
+</div>
+<a href="{% url 'view_collection' collection_pk=col.pk %}">
+<div class="top clearfix">
+    <img src="{% static 'egonomy/img/empty.gif' %}" width="113" height="113" class="placeholder" />
+    <img src="{% static 'egonomy/img/empty.gif' %}" width="113" height="113" class="placeholder" />
+</div>
+<div class="mid">
+    <h3>{{ col.title|default:_("No title") }}</h3>
+    <p>{% trans "by" %} {{ col.author }}</p>
+</div>
+<div class="bot clearfix">
+    <img src="{% static 'egonomy/img/empty.gif' %}" width="113" height="113" class="placeholder" />
+    <img src="{% static 'egonomy/img/empty.gif' %}" width="113" height="113" class="placeholder" />
+</div>
+</a>
\ No newline at end of file
--- a/src/egonomy/templates/partial/fragment_in_list.html	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/templates/partial/fragment_in_list.html	Wed Jun 26 16:53:45 2013 +0200
@@ -19,7 +19,11 @@
     <ul class="clearfix">
         <li><a class="tool twitter" href="#" title="{% trans 'Share on Twitter'%}"></a></li>
         <li><a class="tool facebook" href="#" title="{% trans 'Share on Facebook'%}"></a></li>
-        <li><a class="tool plus" href="#" title="+"></a></li>
+        {% if user.is_authenticated %}
+        <li><a class="tool plus open-popin" href="#add-to-collection" title="{% trans 'Add to a collection'%}"></a></li>
+        {% else %}
+        <li><a class="tool plus" href="{% url 'login' %}" title="{% trans 'Log in to add to a collection' %}"></a></li>
+        {% endif %}
         <li><a class="tool cut" href="{% url 'create_fragment' image_id=fragment.image.id %}" title="{% trans 'Create a fragment'%}"></a></li>
       {% if user_fragments and username = user.username %}
         <li><a class="tool trash" href="{% url 'delete_fragment' %}?fragment_pk={{ frg.pk }}&next={% url 'user_fragments' user.username %}%3Fpage%3D{{ cur_page_nb }}" onclick="return confirm('{% trans "Do you really want to delete this fragment ? Warning : this action est irreversible." %}')" title="{% trans "Delete this fragment" %}"></a></li>
--- a/src/egonomy/templates/partial/image_in_list.html	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/templates/partial/image_in_list.html	Wed Jun 26 16:53:45 2013 +0200
@@ -33,7 +33,11 @@
     <ul class="clearfix">
         <li><a class="tool twitter" href="#" title="{% trans 'Share on Twitter'%}"></a></li>
         <li><a class="tool facebook" href="#" title="{% trans 'Share on Facebook'%}"></a></li>
-        <li><a class="tool plus" href="#" title="+"></a></li>
+        {% if user.is_authenticated %}
+        <li><a class="tool plus open-popin" href="#add-to-collection" title="{% trans 'Add to a collection'%}"></a></li>
+        {% else %}
+        <li><a class="tool plus" href="{% url 'login' %}" title="{% trans 'Log in to add to a collection' %}"></a></li>
+        {% endif %}
         <li><a class="tool cut" href="{% url 'create_fragment' image_id=img.id %}" title="{% trans 'Create a fragment'%}"></a></li>
     </ul>
 </div>
\ No newline at end of file
--- a/src/egonomy/urls.py	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/urls.py	Wed Jun 26 16:53:45 2013 +0200
@@ -19,6 +19,10 @@
     url(r'^userfragments/(?P<username>.*)/$', 'egonomy.views.user_fragments', name='user_fragments'),
     url(r'^senseetiveapi/$', 'egonomy.views.senseetive_api', name='senseetive_api'),
     url(r'^deletefragment/$', 'egonomy.views.delete_fragment', name='delete_fragment'),
+    url(r'^allcollections/$', 'egonomy.views.all_collections', name='all_collections'),
+    url(r'^usercollections/(?P<username>.*)/$', 'egonomy.views.user_collections', name='user_collections'),
+    url(r'^newcollection/$', 'egonomy.views.new_collection', name='new_collection'),
+    url(r'^viewcollection/(?P<collection_pk>.*)/$', 'egonomy.views.view_collection', name='view_collection'),
 
     # Uncomment the admin/doc line below to enable admin documentation:
     url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
--- a/src/egonomy/views.py	Wed Jun 26 12:02:49 2013 +0200
+++ b/src/egonomy/views.py	Wed Jun 26 16:53:45 2013 +0200
@@ -8,7 +8,7 @@
 from django.shortcuts import get_object_or_404, render_to_response, redirect
 from django.template import RequestContext
 from django.utils.translation import ugettext as _
-from egonomy.models import ImageMetadata, Image, Fragment, ImageInfo
+from egonomy.models import ImageMetadata, Image, Fragment, ImageInfo, Collection
 from egonomy.search_indexes import QueryParser
 from egonomy.search_indexes.paginator import SearchPaginator
 from egonomy.search_indexes.query import ModelRelatedSearchQuerySet
@@ -36,7 +36,7 @@
     frg_list = Fragment.objects.all().order_by('-date_saved').select_related('image', 'image__info', 'image__metadata','author')[:nb_display]
     
     return render_to_response("egonomy_home.html",
-                              {'img_list':img_list, 'fragment_list':frg_list},
+                              {'img_list':img_list, 'fragment_list':frg_list, 'current_user_collection_list':current_user_collection_list(request)},
                               context_instance=RequestContext(request))
 
 
@@ -51,7 +51,8 @@
         last_frg = frg_list[0]
     
     return render_to_response("egonomy_annotate_picture.html",
-                              {'img': img, 'fragment_list': frg_list, 'last_frg':last_frg},
+                              {'img': img, 'fragment_list': frg_list, 'last_frg':last_frg,
+                               'current_user_collection_list':current_user_collection_list(request)},
                               context_instance=RequestContext(request))
 
 
@@ -63,7 +64,8 @@
     fragment_only = {'true': True, 'false': False, "0": False, "1": True}.get((request.GET.get("fragment_only") or "1").lower())
     
     return render_to_response("egonomy_view_fragment.html",
-                              {'fragment': frg, 'fragment_list': frg_list, 'fragment_only':fragment_only},
+                              {'fragment': frg, 'fragment_list': frg_list, 'fragment_only':fragment_only,
+                               'current_user_collection_list':current_user_collection_list(request)},
                               context_instance=RequestContext(request))
 
 @login_required
@@ -153,7 +155,8 @@
         url_pagination = url_pagination + "&search=" + search
 
     return render_to_response("egonomy_all_pictures.html",
-                              {'results':results, 'nb_pages':paginator.num_pages, 'cur_page_nb':cur_page_nb, "search":search, "nb_results":nb_results, "url_pagination":url_pagination},
+                              {'results':results, 'nb_pages':paginator.num_pages, 'cur_page_nb':cur_page_nb, "search":search, "nb_results":nb_results, "url_pagination":url_pagination,
+                               'current_user_collection_list':current_user_collection_list(request)},
                               context_instance=RequestContext(request))
 
 
@@ -193,7 +196,8 @@
         url_pagination = url_pagination + "&search=" + search
 
     return render_to_response("egonomy_all_fragments.html",
-                              {"search_fragment":True, 'results':results, 'nb_pages':paginator.num_pages, 'cur_page_nb':cur_page_nb, "search":search, "nb_results":nb_results, "url_pagination":url_pagination},
+                              {"search_fragment":True, 'results':results, 'nb_pages':paginator.num_pages, 'cur_page_nb':cur_page_nb, "search":search, "nb_results":nb_results, "url_pagination":url_pagination,
+                               'current_user_collection_list':current_user_collection_list(request)},
                               context_instance=RequestContext(request))
 
 
@@ -217,7 +221,8 @@
     url_pagination = reverse("user_fragments", args=[username]) + "?limit=" + str(nb)
 
     return render_to_response("egonomy_all_fragments.html",
-                              {"user_fragments":True, 'username':username, 'results':results, 'nb_pages':paginator.num_pages, "search":None, 'cur_page_nb':cur_page_nb, "url_pagination":url_pagination},
+                              {"user_fragments":True, 'username':username, 'results':results, 'nb_pages':paginator.num_pages, "search":None, 'cur_page_nb':cur_page_nb, "url_pagination":url_pagination,
+                               'current_user_collection_list':current_user_collection_list(request)},
                               context_instance=RequestContext(request))
 
 
@@ -358,3 +363,94 @@
     
     return HttpResponse(json.dumps({"keywords":keywords, "images":images_data}), content_type="application/json")
 
+
+
+def all_collections(request):
+        
+    # Get the cur_page_nb number parameter if possible
+    cur_page_nb = request.GET.get("page") or 1
+    cur_page_nb = int(cur_page_nb)
+    
+    collections = Collection.objects.filter(public=True).order_by('-creation').select_related('items')
+    nb = request.GET.get("limit") or getattr(settings,"IMAGES_PER_PAGE", 32)
+    paginator = Paginator(collections, nb)
+        
+    try:
+        results = paginator.page(cur_page_nb)
+    except (EmptyPage, InvalidPage):
+        results = paginator.page(paginator.num_pages)
+        
+    url_pagination = reverse("all_collections") + "?limit=" + str(nb)
+
+    return render_to_response("egonomy_all_collections.html",
+                              {"user_collections":False, 'results':results, 'nb_pages':paginator.num_pages, 'cur_page_nb':cur_page_nb, "url_pagination":url_pagination},
+                              context_instance=RequestContext(request))
+
+
+
+def user_collections(request, username):
+        
+    # Get the cur_page_nb number parameter if possible
+    cur_page_nb = request.GET.get("page") or 1
+    cur_page_nb = int(cur_page_nb)
+    # get the username
+    user = get_object_or_404(User, username=username)
+    
+    if user==request.user:
+        user_collections = True
+        collections = Collection.objects.filter(author=user).order_by('-creation').select_related('items')
+    else:
+        user_collections = False
+        collections = Collection.objects.filter(author=user).filter(public=True).order_by('-creation').select_related('items')
+        
+    nb = request.GET.get("limit") or getattr(settings,"IMAGES_PER_PAGE", 32)
+    paginator = Paginator(collections, nb)
+        
+    try:
+        results = paginator.page(cur_page_nb)
+    except (EmptyPage, InvalidPage):
+        results = paginator.page(paginator.num_pages)
+        
+    url_pagination = reverse("user_collections", args=[username]) + "?limit=" + str(nb)
+    
+    return render_to_response("egonomy_all_collections.html",
+                              {"user_collections":user_collections, 'username':username, 'results':results, 'nb_pages':paginator.num_pages, 'cur_page_nb':cur_page_nb, "url_pagination":url_pagination},
+                              context_instance=RequestContext(request))
+
+
+
+@login_required
+def new_collection(request):
+        
+    col_title = request.POST["collection-title"]
+    col_desc = request.POST["collection-description"]
+    
+    col = Collection()
+    col.title = col_title
+    col.description = col_desc
+    col.author = request.user
+    col.save()
+    
+    return redirect("view_collection", collection_pk=col.pk)
+
+
+
+
+def view_collection(request, collection_pk):
+    
+    col = get_object_or_404(Collection.objects.select_related('items'), pk=collection_pk)
+    
+    return render_to_response("egonomy_view_collection.html",
+                              {'col':col},
+                              context_instance=RequestContext(request))
+
+
+
+
+def current_user_collection_list(request):
+    
+    if request.user.is_authenticated():
+        return Collection.objects.filter(author=request.user).order_by("title")
+    else:
+        return None
+