Recherche textuelle dans l'agenda
authorEric Mc Sween <eric.mcsween@gmail.com>
Thu, 28 Oct 2010 16:49:44 +0000 (12:49 -0400)
committerEric Mc Sween <eric.mcsween@gmail.com>
Thu, 28 Oct 2010 16:49:44 +0000 (12:49 -0400)
auf_savoirs_en_partage/savoirs/forms.py
auf_savoirs_en_partage/savoirs/lib/recherche.py
auf_savoirs_en_partage/savoirs/models.py
auf_savoirs_en_partage/savoirs/views.py
auf_savoirs_en_partage/templates/savoirs/evenement.html
auf_savoirs_en_partage/templates/savoirs/evenement_index.html
auf_savoirs_en_partage/templates/savoirs/evenement_resultat.html [new file with mode: 0644]
auf_savoirs_en_partage/templates/savoirs/index.html

index 2b54358..b126abd 100644 (file)
@@ -83,6 +83,28 @@ class ActualiteSearchForm(forms.Form):
            chercher les mot-clés recherchés dans un texte."""
         if self.is_valid():
             return build_search_regexp(self.cleaned_data['q'])
            chercher les mot-clés recherchés dans un texte."""
         if self.is_valid():
             return build_search_regexp(self.cleaned_data['q'])
+
+class EvenementSearchForm(forms.Form):
+    """Formulaire de recherche pour les événements."""
+
+    q = forms.CharField(required=False, label="Mots-clés")
+    
+    def get_query_set(self):
+        """Retourne l'ensemble des événements qui correspondent aux valeurs
+           entrées dans le formulaire."""
+        evenements = Evenement.objects.filter(approuve=True)
+        if self.is_valid():
+            query = self.cleaned_data['q']
+            if query:
+                evenements = evenements.search(query)
+        return evenements
+
+    def get_search_regexp(self):
+        """Retourne une expression régulière compilée qui peut servir à
+           chercher les mot-clés recherchés dans un texte."""
+        if self.is_valid():
+            return build_search_regexp(self.cleaned_data['q'])
+
 ###
 
 class EvenementForm(forms.ModelForm):
 ###
 
 class EvenementForm(forms.ModelForm):
index 7755450..90bc67c 100644 (file)
@@ -171,6 +171,7 @@ def build_search_regexp(query):
         part = part.replace(u'é', u'[éÉ]')
         part = part.replace(u'ê', u'[êÊ]')
         part = part.replace(u'î', u'[îÎ]')
         part = part.replace(u'é', u'[éÉ]')
         part = part.replace(u'ê', u'[êÊ]')
         part = part.replace(u'î', u'[îÎ]')
+        part = part.replace(u'ç', u'[çÇ]')
 
         # Faire ceci après avoir traité les caractères accentués...
         part = part.replace('a', u'[aàâÀÂ]')
 
         # Faire ceci après avoir traité les caractères accentués...
         part = part.replace('a', u'[aàâÀÂ]')
@@ -178,6 +179,7 @@ def build_search_regexp(query):
         part = part.replace('i', u'[iïîÎ]')
         part = part.replace('o', u'[oô]')
         part = part.replace('u', u'[uûüù]')
         part = part.replace('i', u'[iïîÎ]')
         part = part.replace('o', u'[oô]')
         part = part.replace('u', u'[uûüù]')
+        part = part.replace('c', u'[cç]')
 
         parts.append(part)
     return re.compile('|'.join(parts), re.I) 
 
         parts.append(part)
     return re.compile('|'.join(parts), re.I) 
index b1dbd0a..4e4c7cb 100644 (file)
@@ -62,6 +62,30 @@ class Actualite(models.Model):
         db_table = u'actualite'
         ordering = ["-date",]
 
         db_table = u'actualite'
         ordering = ["-date",]
 
+class EvenementManager(models.Manager):
+
+    def get_query_set(self):
+        return EvenementQuerySet(self.model)
+
+    def search(self, text):
+        return self.get_query_set().search(text)
+
+class EvenementQuerySet(models.query.QuerySet):
+
+    def search(self, text):
+        qs = self
+        words = text.split()
+        for word in words:
+            qs = qs.filter(Q(titre__icontains=word) | 
+                           Q(mots_cles__icontains=word) |
+                           Q(discipline__nom__icontains=word) | 
+                           Q(discipline_secondaire__nom__icontains=word) |
+                           Q(type__icontains=word) |
+                           Q(lieu__icontains=word) |
+                           Q(description__icontains=word) |
+                           Q(contact__icontains=word))
+        return qs
+
 class Evenement(models.Model):
     uid = models.CharField(max_length = 255, default = str(uuid.uuid1()))
     approuve = models.BooleanField(default = False)
 class Evenement(models.Model):
     uid = models.CharField(max_length = 255, default = str(uuid.uuid1()))
     approuve = models.BooleanField(default = False)
@@ -90,6 +114,11 @@ class Evenement(models.Model):
     contact = models.TextField(blank = True, null = True)
     url = models.CharField(max_length=255, blank = True, null = True)
 
     contact = models.TextField(blank = True, null = True)
     url = models.CharField(max_length=255, blank = True, null = True)
 
+    objects = EvenementManager()
+
+    class Meta:
+        ordering = ['-debut']
+
     def __unicode__(self,):
         return "[%s] %s" % (self.uid, self.titre)
 
     def __unicode__(self,):
         return "[%s] %s" % (self.uid, self.titre)
 
index a711cd5..2673edc 100644 (file)
@@ -1,7 +1,7 @@
 # -*- encoding: utf-8 -*-
 import datetime, simplejson, copy, vobject
 
 # -*- encoding: utf-8 -*-
 import datetime, simplejson, copy, vobject
 
-from django.shortcuts import render_to_response
+from django.shortcuts import render_to_response, get_object_or_404
 from django.template import Context, RequestContext
 from django.http import HttpResponse, HttpResponseRedirect
 from django.contrib.auth.decorators import login_required
 from django.template import Context, RequestContext
 from django.http import HttpResponse, HttpResponseRedirect
 from django.contrib.auth.decorators import login_required
@@ -25,27 +25,18 @@ def index (request):
     oldest = datetime.date.today () - delta
     actualites = Actualite.objects.filter (visible = '1', date__gt = oldest)
     actualites = actualites[0:configuration['accueil_actualite']]
     oldest = datetime.date.today () - delta
     actualites = Actualite.objects.filter (visible = '1', date__gt = oldest)
     actualites = actualites[0:configuration['accueil_actualite']]
-    try:
-        erreur_caldav = False
-        events = evenements()[0:configuration['accueil_evenement']]
-    except:
-        erreur_caldav = u"Problème de connexion à l'agenda"
-        events = []
-    
-    
+    evenements = Evenement.objects.filter(approuve=True)[0:configuration['accueil_evenement']]
     ressources = Record.objects.all().order_by('?')[:configuration['accueil_ressource']]
     chercheurs = Chercheur.objects.all().order_by('?')[:configuration['accueil_chercheur']]
     sites = Site.objects.all().order_by('?')[:configuration['accueil_sites']]
     ressources = Record.objects.all().order_by('?')[:configuration['accueil_ressource']]
     chercheurs = Chercheur.objects.all().order_by('?')[:configuration['accueil_chercheur']]
     sites = Site.objects.all().order_by('?')[:configuration['accueil_sites']]
-    return render_to_response ("savoirs/index.html", \
-            Context ({"actualites": actualites,
-                      "events": events,
-                      "erreur_caldav": erreur_caldav,
-                      "caldav_url": configuration['calendrier_publique'],
-                      "ressources":ressources,
-                      "chercheurs":chercheurs,
-                      "sites":sites,
-                      }), \
-            context_instance = RequestContext(request))
+    return render_to_response("savoirs/index.html",
+                               dict(actualites=actualites,
+                                    evenements=evenements,
+                                    caldav_url=configuration['calendrier_publique'],
+                                    ressources=ressources,
+                                    chercheurs=chercheurs,
+                                    sites=sites),
+                              context_instance = RequestContext(request))
 
 # sous-menu droite
 def a_propos (request):
 
 # sous-menu droite
 def a_propos (request):
@@ -159,21 +150,21 @@ def actualite_index(request):
 
 # agenda
 def evenement_index(request):
 
 # agenda
 def evenement_index(request):
-    try:
-        erreur_caldav = False
-        events = evenements()
-    except:
-        erreur_caldav = u"Problème de connexion à l'agenda"
-        events = []
-    return render_to_response ("savoirs/evenement_index.html", \
-            Context ({'evenements':events}), \
-            context_instance = RequestContext(request))
+    search_form = EvenementSearchForm(request.GET)
+    evenements = search_form.get_query_set()
+    search_regexp = search_form.get_search_regexp()
+    return render_to_response("savoirs/evenement_index.html",
+                              dict(evenements=evenements,
+                                   search_form=search_form,
+                                   search_regexp=search_regexp,
+                                   nb_resultats=len(evenements)),
+                              context_instance=RequestContext(request))
 
 def evenement(request, id):
 
 def evenement(request, id):
-    event = evenement_info(id)
-    return render_to_response ("savoirs/evenement.html", \
-            Context ({'event': event.instance.vevent}), \
-            context_instance = RequestContext(request))
+    evenement = get_object_or_404(Evenement, pk=id)
+    return render_to_response("savoirs/evenement.html",
+                              dict(evenement=evenement),
+                              context_instance=RequestContext(request))
 
 def evenement_ajout(request):
     template = "savoirs/evenement_ajout.html"
 
 def evenement_ajout(request):
     template = "savoirs/evenement_ajout.html"
index 3efc953..b37ddc5 100644 (file)
@@ -1,35 +1,46 @@
 {% extends "container_base.html" %}
 
 {% block contenu %}
 {% extends "container_base.html" %}
 
 {% block contenu %}
-<h4>{{ event.summary.value }}</h4>
+<h4>{{ evenement.titre }}</h4>
 
 <div class="zone-texte">
   <table width="100%">
     <tr>
       <th width="120px">Début</th>
 
 <div class="zone-texte">
   <table width="100%">
     <tr>
       <th width="120px">Début</th>
-      <td>{{ event.dtstart.value|date:"Y-m-d H:i" }} (UTC)</td>
+      <td>{{ evenement.debut|date:"Y-m-d H:i" }} (UTC)</td>
     </tr>
     <tr>
       <th>Fin</th>
     </tr>
     <tr>
       <th>Fin</th>
-      <td>{{ event.dtend.value|date:"Y-m-d H:i" }} (UTC)</td>
+      <td>{{ evenement.fin|date:"Y-m-d H:i" }} (UTC)</td>
     </tr>
     <tr>
       <th>Description</th>
     </tr>
     <tr>
       <th>Description</th>
-      <td>{{ event.description.value|linebreaksbr }}</td>
+      <td>{{ evenement.description|linebreaksbr }}</td>
     </tr>
     </tr>
+    {% if evenement.mots_cles %}
+    <tr>
+      <th>Mots-clés</th>
+      <td>{{ evenement.mots_cles }}</td>
+    </tr>
+    {% endif %}
+    {% if evenement.contact %}
     <tr>
       <th>Contact</th>
     <tr>
       <th>Contact</th>
-      <td>{{ event.contact.value|linebreaksbr }}</td>
+      <td>{{ evenement.contact|linebreaksbr }}</td>
     </tr>
     </tr>
+    {% endif %}
+    {% if evenement.lieu %}
     <tr>
       <th>Emplacement</th>
     <tr>
       <th>Emplacement</th>
-      <td>{{ event.location.value|linebreaksbr }}</td>
+      <td>{{ evenement.lieu|linebreaksbr }}</td>
     </tr>
     </tr>
+    {% endif %}
+    {% if evenement.url %}
     <tr>
       <th>URL</th>
     <tr>
       <th>URL</th>
-      <td><a href="{{ event.url.value }}">{{ event.url.value }}</a></td>
+      <td><a href="{{ evenement.url }}">{{ evenement.url }}</a></td>
     </tr>
     </tr>
+    {% endif %}
   </table>
 </div>
   </table>
 </div>
-
 {% endblock %}
 {% endblock %}
index d4b7ad8..a4b0e60 100644 (file)
@@ -1,7 +1,8 @@
 {% extends "container_base.html" %}
 {% extends "container_base.html" %}
-
+{% load pagination_tags %}
 
 {% block contenu %}
 
 {% block contenu %}
+{% autopaginate evenements 10 %}
 <h4>Agenda</h4>
 <ul class="actions">
   {% include "savoirs/evenement_actions.html" %}
 <h4>Agenda</h4>
 <ul class="actions">
   {% include "savoirs/evenement_actions.html" %}
 </ul>
 
 <div class="contenu-wrapper">
 </ul>
 
 <div class="contenu-wrapper">
-<table id="repertoire">
-    <tr>
-        <th>Nom</th>
-    </tr>
-{% for e in evenements %}
-    <tr class="{% cycle 'odd' 'notodd' %}">
-        <td><a href="{% url savoirs.views.evenement e.uid.value %}" class="le-titre">{{ e.summary.value|truncatewords:20 }}</a></td>
-    </tr>
-{% endfor %}
-</table>
+  <form action="" method="get">
+    <table>
+      {{ search_form.as_table }}
+      <tr><th></th><td><input type="submit" value="Rechercher" /></td></tr>
+    </table>
+  </form>
+  <p><strong>{{ nb_resultats }} événements correspondant à votre recherche :</strong></p>
+  <div class="centre">{% paginate %}</div>
+  {% for evenement in evenements %}
+  {% include "savoirs/evenement_resultat.html" %}
+  {% endfor %}
+  <div class="centre">{% paginate %}</div>
 </div>
 </div>
-
 {% endblock %}
 {% endblock %}
diff --git a/auf_savoirs_en_partage/templates/savoirs/evenement_resultat.html b/auf_savoirs_en_partage/templates/savoirs/evenement_resultat.html
new file mode 100644 (file)
index 0000000..320c8e4
--- /dev/null
@@ -0,0 +1,7 @@
+{% load search %}
+
+<div class="resultatRecherche">
+  <div class="la-date">{{ evenement.debut|date:"d F Y H:i" }}</div>
+  <div><a href="{% url savoirs.views.evenement evenement.pk %}" class="le-titre">{{ evenement.titre|highlight:search_regexp }}</a></div>
+  <div class="le-resume">{{ evenement.description|excerpt:search_regexp|highlight:search_regexp }}</div>
+</div>
index b19ce49..ca1cc64 100644 (file)
 <div class="demi-droite clearfix">
     <div id="agenda" class="box">
         <h4><a href="{% url savoirs.views.evenement_index %}">Agenda</a></h4>
 <div class="demi-droite clearfix">
     <div id="agenda" class="box">
         <h4><a href="{% url savoirs.views.evenement_index %}">Agenda</a></h4>
-        {% if not erreur_caldav %}
-            <a id="rss-agenda" href="/rss/agenda"><img src="/media/img/feed.png" /></a>
-            
-            <ul class="sous-menu">
-                <li><a href="{% url savoirs.views.evenement_index %}">Tous les événements</a></li>
-                {% include "savoirs/evenement_actions.html" %}
-            </ul>
-            
-            <ul class="liste-de-l-accueil">
-            {% for event in events %}
-                <li>
-                <span class="la-date">{{ event.dtstart.value|date:"d F Y" }} {{ event.dtstart.value|date:"H:i" }}</span>
-                <a href="{% url savoirs.views.evenement event.uid.value %}" class="le-titre">{{ event.summary.value|truncatewords:20 }}</a>
-                <span class="le-resume">{{ event.description.value|truncatewords:20 }}</span>
-                </li>
-            {% endfor %}
-            </ul>
-        {% else %}
-            <ul><li>{{ erreur_caldav }}</li></ul>
-        {% endif %}
+        <a id="rss-agenda" href="/rss/agenda"><img src="/media/img/feed.png" /></a>
+
+        <ul class="sous-menu">
+          <li><a href="{% url savoirs.views.evenement_index %}">Tous les événements</a></li>
+          {% include "savoirs/evenement_actions.html" %}
+        </ul>
+
+        <ul class="liste-de-l-accueil">
+          {% for evenement in evenements %}
+          <li>
+          <span class="la-date">{{ evenement.debut|date:"d F Y H:i" }}</span>
+          <a href="{% url savoirs.views.evenement evenement.id %}" class="le-titre">{{ evenement.titre|truncatewords:20 }}</a>
+          <span class="le-resume">{{ evenement.description|truncatewords:20 }}</span>
+          </li>
+          {% endfor %}
+        </ul>
     </div>
     <div  id="ressources" class="box">
         <h4><a href="{% url savoirs.views.ressource_index %}">Ressources</a></h4>
     </div>
     <div  id="ressources" class="box">
         <h4><a href="{% url savoirs.views.ressource_index %}">Ressources</a></h4>