api recherche
authorOlivier Larchevêque <olivier.larcheveque@auf.org>
Tue, 13 Mar 2012 16:30:28 +0000 (12:30 -0400)
committerOlivier Larchevêque <olivier.larcheveque@auf.org>
Tue, 13 Mar 2012 16:30:28 +0000 (12:30 -0400)
auf_savoirs_en_partage/chercheurs/api.py
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/urls.py

index 7d01e33..1b68b4c 100644 (file)
@@ -1,13 +1,14 @@
 # -*- encoding: utf-8 -*
+
 from django.http import HttpResponse
-from django.core import serializers
 from django.shortcuts import get_object_or_404
 
 from django.utils import simplejson
 
-from savoirs.models import Region
 from savoirs.rss import FilChercheurs
-from chercheurs.models import Chercheur, Personne
+from auf.django.references import models as ref
+from chercheurs.models import Chercheur
+from chercheurs.forms import ChercheurSearchForm
 
 STATUS_OK = 200
 STATUS_ERROR = 400
@@ -15,12 +16,70 @@ STATUS_ERROR_PERMISSIONS = 403
 STATUS_ERROR_NOT_FOUND = 404
 STATUS_ERROR_BADMETHOD = 405
 
-class APIFilChercheurs(FilChercheurs):
-    description = "Pour services tiers"
+def recherche(request):
+    """
+    API spéciale de recherche pour retourner une structure de données complète
+    par rapport au RSS.
+    """
+    search_form = ChercheurSearchForm(request.GET)
+    search = search_form.save(commit=False)
+    data = []
+
+    # S'assure qu'un filtre existe au moins
+    no_criterion = True
+    for criterion, val in request.GET.items():
+        if val not in (None, u'', ''):
+            no_criterion = False
+            break
+    if no_criterion:
+        return api_return(STATUS_ERROR, 'no criterion', True)
+
+    # run() de ChercheurSearchForm()
+    results = Chercheur.objects
+    if search.q:
+        results = results.search(search.q)
+    if search.nom_chercheur:
+        results = results.add_to_query('@(nom,prenom) ' + search.nom_chercheur)
+    if search.equipe_recherche:
+        results = results.add_to_query('@equipe_recherche ' + search.equipe_recherche)
+    if search.discipline:
+        results = results.filter_discipline(search.discipline)
+    if search.region:
+        results = results.filter_region(search.region)
+    if search.statut:
+        if search.statut == "expert":
+            results = results.filter_expert()
+        else:
+            results = results.filter_statut(search.statut)
+    if search.domaine:
+        results = results.filter_groupe(search.domaine)
+    if search.pays:
+        results = results.filter_pays(search.pays)
+    if search.nord_sud:
+        results = results.filter_nord_sud(search.nord_sud)
+    if search.genre:
+        results = results.filter_genre(search.genre)
+    if search.activites_francophonie == 'instance_auf':
+        results = results.filter(membre_instance_auf=True)
+    elif search.activites_francophonie == 'expert_oif':
+        results = results.filter(expert_oif=True)
+    elif search.activites_francophonie == 'association_francophone':
+        results = results.filter(membre_association_francophone=True)
+    elif search.activites_francophonie == 'reseau_institutionnel':
+        results = results.filter(membre_reseau_institutionnel=True)
+
+    # sous-ensemble de pays
+    limitation_pays = request.GET.get('limitation_pays', None)
+    
+    if limitation_pays is not None:
+        pays = [ref.Pays.objects.get(code=pays_code) for pays_code in limitation_pays.split(',')]
+        results = results.filter_pays(pays)
+
+    for chercheur in results.all():
+        data.append(chercheur_2_dict(chercheur))
+    
+    return api_return(STATUS_OK, dict_2_json(data), True)
 
-    def items(self, search):
-        """Pas de limite temporelle"""
-        return search.run().order_by('-date_modification')
 
 def api(request, pays=None, region=None, chercheur_id=None):
     api = API(request)
@@ -60,104 +119,104 @@ def dict_2_json(data):
     return simplejson.dumps(data, indent=4)
 
 
+def chercheur_2_dict(chercheur):
+    """
+    Structure flat d'un chercheur pour JSON
+    """
+    # Domaines de recherche du chercheur
+    domaines_recherche = []
+    for dr in chercheur.domaines_recherche:
+        domaines_recherche.append(dr.nom)
+
+    # Groupes chercheur
+    groupes_chercheur = []
+    for gc in chercheur.groupes_chercheur:
+        groupes_chercheur.append(gc.nom)
+
+    # Expertises
+    expertises = []
+    for exp in chercheur.expertises.all():
+        expertises.append(
+        {'nom': '%s' % exp.nom,
+            'date': '%s' % exp.date,
+            'organisme_demandeur': '%s' % exp.organisme_demandeur,
+            'organisme_demandeur_visible': exp.organisme_demandeur_visible})
+
+    # Publications
+    publications = []
+    for pub in chercheur.publications.all():
+        publications.append(
+        {'auteurs': '%s' % pub.auteurs,
+            'titre': '%s' % pub.titre,
+            'revue': '%s' % pub.revue,
+            'annee': '%s' % pub.annee,
+            'editeur': '%s' % pub.editeur,
+            'lieu_edition': '%s' % pub.lieu_edition,
+            'nb_pages': '%s' % pub.nb_pages,
+            'url': '%s' % pub.url,
+            'publication_affichage': '%s' %  pub.publication_affichage})
+
+    chercheur_details = {'id': '%s' % chercheur.id, 
+            'civilite': '%s' % chercheur.civilite, 
+            'prenom': '%s' % chercheur.prenom, 
+            'nom': '%s' % chercheur.nom,
+            'pays': '%s' % chercheur.pays,
+            'pays_code': '%s' % chercheur.pays.code,
+            'etablissement': '%s' % chercheur.etablissement_display,
+            'afficher_courriel': '%s' % chercheur.afficher_courriel,
+            'courriel': '%s' % chercheur.courriel_display(), 
+            'region': '%s' % chercheur.region.nom, 
+            'statut': '%s' % chercheur.get_statut_display(), 
+            'diplome': '%s' % chercheur.diplome, 
+            'domaines_recherche': domaines_recherche,
+            'discipline': '%s' % chercheur.discipline,
+            'theme_recherche': '%s' % chercheur.theme_recherche, 
+            'equipe_recherche': '%s' % chercheur.equipe_recherche, 
+            'mots_cles': '%s' % chercheur.mots_cles, 
+            'url_site_web': '%s' % chercheur.url_site_web, 
+            'url_blog': '%s' % chercheur.url_blog, 
+            'url_reseau_social': '%s' % chercheur.url_reseau_social, 
+            'membre_instance_auf': chercheur.membre_instance_auf, 
+            'expert_oif': chercheur.expert_oif, 
+            'membre_association_francophone': chercheur.membre_association_francophone, 
+            'membre_reseau_institutionnel': chercheur.membre_reseau_institutionnel, 
+            'membre_instance_auf_nom': '%s' % chercheur.get_membre_instance_auf_nom_display(), 
+            'membre_instance_auf_fonction': '%s' % chercheur.membre_instance_auf_fonction, 
+            'membre_instance_auf_dates': '%s' % chercheur.membre_instance_auf_dates, 
+            'expert_oif_details': '%s' % chercheur.expert_oif_details, 
+            'expert_oif_dates': '%s' % chercheur.expert_oif_dates, 
+            'membre_association_francophone_details': '%s' % chercheur.membre_association_francophone_details, 
+            'membre_reseau_institutionnel_nom': '%s' %
+            chercheur.get_membre_reseau_institutionnel_nom_display(), 
+            "membre_reseau_institutionnel_fonction": "%s" % chercheur.membre_reseau_institutionnel_fonction, 
+            "membre_reseau_institionnel_dates": "%s" % chercheur.membre_reseau_institutionnel_dates, 
+            "expertises": expertises, 
+            "expertises_auf": chercheur.expertises_auf,
+            "publications": publications}
+
+    # devrait faire le lookup 
+    try:
+        if chercheur.these:
+            chercheur_details['these'] = {"these" : "%s" % chercheur.these,
+                "these_url": "%s" % chercheur.these.url, 
+                "these_titre": "%s" % chercheur.these.titre, 
+                "these_etablissement": "%s" % chercheur.these.etablissement, 
+                "these_annee": "%s" % chercheur.these.annee, 
+                "these_nb_pages": "%s" % chercheur.these.nb_pages, 
+                "these_directeur": "%s" % chercheur.these.directeur, 
+                }
+    except:
+        pass
+    return chercheur_details
+
+
 class API:
     def __init__(self, request):
         self.request = request
 
     def api_chercheur(self, chercheur_id):
         chercheur = get_object_or_404(Chercheur, id=chercheur_id)
-        # Domaines de recherche du chercheur
-        data = serializers.serialize('json', [chercheur,])
-        #return api_return(STATUS_OK, data, True)     
-
-
-        domaines_recherche = []
-        for dr in chercheur.domaines_recherche:
-            domaines_recherche.append(dr.nom)
-
-        # Groupes chercheur
-        groupes_chercheur = []
-        for gc in chercheur.groupes_chercheur:
-            groupes_chercheur.append(gc.nom)
-
-        # Expertises
-        expertises = []
-        for exp in chercheur.expertises.all():
-            expertises.append(
-            {'nom': '%s' % exp.nom,
-                'date': '%s' % exp.date,
-                'organisme_demandeur': '%s' % exp.organisme_demandeur,
-                'organisme_demandeur_visible': exp.organisme_demandeur_visible})
-
-        # Publications
-        publications = []
-        for pub in chercheur.publications.all():
-            publications.append(
-            {'auteurs': '%s' % pub.auteurs,
-                'titre': '%s' % pub.titre,
-                'revue': '%s' % pub.revue,
-                'annee': '%s' % pub.annee,
-                'editeur': '%s' % pub.editeur,
-                'lieu_edition': '%s' % pub.lieu_edition,
-                'nb_pages': '%s' % pub.nb_pages,
-                'url': '%s' % pub.url,
-                'publication_affichage': '%s' %  pub.publication_affichage})
-
-        chercheur_details = [{'id': '%s' % chercheur.id, 
-                'civilite': '%s' % chercheur.civilite, 
-                'prenom': '%s' % chercheur.prenom, 
-                'nom': '%s' % chercheur.nom,
-                'pays': '%s' % chercheur.pays,
-                'pays_code': '%s' % chercheur.pays.code,
-                'etablissement': '%s' % chercheur.etablissement_display,
-                'afficher_courriel': '%s' % chercheur.afficher_courriel,
-                'courriel': '%s' % chercheur.courriel_display(), 
-                'region': '%s' % chercheur.region.nom, 
-                'statut': '%s' % chercheur.get_statut_display(), 
-                'diplome': '%s' % chercheur.diplome, 
-                'domaines_recherche': domaines_recherche,
-                'discipline': '%s' % chercheur.discipline,
-                'theme_recherche': '%s' % chercheur.theme_recherche, 
-                'equipe_recherche': '%s' % chercheur.equipe_recherche, 
-                'mots_cles': '%s' % chercheur.mots_cles, 
-                'url_site_web': '%s' % chercheur.url_site_web, 
-                'url_blog': '%s' % chercheur.url_blog, 
-                'url_reseau_social': '%s' % chercheur.url_reseau_social, 
-                'membre_instance_auf': chercheur.membre_instance_auf, 
-                'expert_oif': chercheur.expert_oif, 
-                'membre_association_francophone': chercheur.membre_association_francophone, 
-                'membre_reseau_institutionnel': chercheur.membre_reseau_institutionnel, 
-                'membre_instance_auf_nom': '%s' % chercheur.get_membre_instance_auf_nom_display(), 
-                'membre_instance_auf_fonction': '%s' % chercheur.membre_instance_auf_fonction, 
-                'membre_instance_auf_dates': '%s' % chercheur.membre_instance_auf_dates, 
-                'expert_oif_details': '%s' % chercheur.expert_oif_details, 
-                'expert_oif_dates': '%s' % chercheur.expert_oif_dates, 
-                'membre_association_francophone_details': '%s' % chercheur.membre_association_francophone_details, 
-                'membre_reseau_institutionnel_nom': '%s' %
-                chercheur.get_membre_reseau_institutionnel_nom_display(), 
-                "membre_reseau_institutionnel_fonction": "%s" % chercheur.membre_reseau_institutionnel_fonction, 
-                "membre_reseau_institionnel_dates": "%s" % chercheur.membre_reseau_institutionnel_dates, 
-                "expertises": expertises, 
-                "expertises_auf": chercheur.expertises_auf,
-                "publications": publications}]
-
-        # devrait faire le lookup 
-        try:
-            if chercheur.these:
-                details_pop = chercheur_details.pop(0)
-                details_pop.update(
-                    {"these" : "%s" % chercheur.these,
-                    "these_url": "%s" % chercheur.these.url, 
-                    "these_titre": "%s" % chercheur.these.titre, 
-                    "these_etablissement": "%s" % chercheur.these.etablissement, 
-                    "these_annee": "%s" % chercheur.these.annee, 
-                    "these_nb_pages": "%s" % chercheur.these.nb_pages, 
-                    "these_directeur": "%s" % chercheur.these.directeur, 
-                    })
-            chercheur_details.append(details_pop)
-        except:
-            pass
-
+        chercheur_details = chercheur_2_dict(chercheur)
         return api_return(STATUS_OK, dict_2_json(chercheur_details), True)     
         
 
index 0ee9dab..6fd1649 100644 (file)
@@ -94,7 +94,15 @@ class ChercheurQuerySet(SEPQuerySet):
         return self.filter(groupes=groupe)
 
     def filter_pays(self, pays):
-        return self.filter(Q(etablissement__pays=pays) | Q(etablissement_autre_pays=pays))
+        """
+        Filtre sur un ou plusieurs pays.
+        """
+        if hasattr(pays, "__getitem__") or hasattr(pays, "__iter__"):
+            pays_ids = [p.id for p in pays]
+            return self.filter(Q(etablissement__pays__id__in=pays_ids) |
+                    Q(etablissement_autre_pays__id__in=pays_ids))
+        else:
+            return self.filter(Q(etablissement__pays=pays) | Q(etablissement_autre_pays=pays))
 
     def filter_region(self, region):
         return self.filter(Q(etablissement__pays__region=region) | Q(etablissement_autre_pays__region=region))
@@ -143,7 +151,13 @@ class ChercheurSphinxQuerySet(SEPSphinxQuerySet):
         return self.filter(groupe_ids=groupe.id)
 
     def filter_pays(self, pays):
-        return self.filter(pays_id=pays.id)
+        """
+        Filtre sur un ou plusieurs pays.
+        """
+        if hasattr(pays, "__getitem__") or hasattr(pays, "__iter__"):
+            return self.filter(pays_id__in=[p.id for p in pays])
+        else:
+            return self.filter(pays_id=pays.id)
 
     NORD_SUD_CODES = {'Nord': 1, 'Sud': 2}
     def filter_nord_sud(self, nord_sud):
index ec14293..37b784a 100644 (file)
@@ -4,7 +4,6 @@ from django.conf.urls.defaults import patterns, include, handler500, handler404,
 from django.conf import settings
 from django.contrib import admin
 from savoirs.rss import FilChercheurs, FilRessources, FilActualites, FilAppels, FilEvenements, FilSites, FilMessages
-from chercheurs.api import APIFilChercheurs
 admin.autodiscover()
 
 handler500 = "views.page_500"
@@ -107,7 +106,7 @@ urlpatterns = sep_patterns + patterns(
     (r'^api/chercheurs/(?P<chercheur_id>\d+)/$', 'chercheurs.api.api'),
     (r'^api/chercheurs/pays/(?P<pays>.*)/$', 'chercheurs.api.api'),
     (r'^api/chercheurs/region/(?P<region>.*)/$', 'chercheurs.api.api'),
-    (r'^api/chercheurs/rss$', APIFilChercheurs(), {}, ),
+    (r'^api/chercheurs/recherche', 'chercheurs.api.recherche' ),
 
 
     # groupes