From: Olivier Larchevêque Date: Tue, 13 Mar 2012 16:30:28 +0000 (-0400) Subject: api recherche X-Git-Url: http://git.auf.org/?p=auf_savoirs_en_partage_django.git;a=commitdiff_plain;h=f41337c8c963966cc084e1e33c7631642b6dfcc2;ds=sidebyside api recherche --- diff --git a/auf_savoirs_en_partage/chercheurs/api.py b/auf_savoirs_en_partage/chercheurs/api.py index 7d01e33..1b68b4c 100644 --- a/auf_savoirs_en_partage/chercheurs/api.py +++ b/auf_savoirs_en_partage/chercheurs/api.py @@ -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) diff --git a/auf_savoirs_en_partage/chercheurs/models.py b/auf_savoirs_en_partage/chercheurs/models.py index 0ee9dab..6fd1649 100644 --- a/auf_savoirs_en_partage/chercheurs/models.py +++ b/auf_savoirs_en_partage/chercheurs/models.py @@ -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): diff --git a/auf_savoirs_en_partage/urls.py b/auf_savoirs_en_partage/urls.py index ec14293..37b784a 100644 --- a/auf_savoirs_en_partage/urls.py +++ b/auf_savoirs_en_partage/urls.py @@ -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\d+)/$', 'chercheurs.api.api'), (r'^api/chercheurs/pays/(?P.*)/$', 'chercheurs.api.api'), (r'^api/chercheurs/region/(?P.*)/$', 'chercheurs.api.api'), - (r'^api/chercheurs/rss$', APIFilChercheurs(), {}, ), + (r'^api/chercheurs/recherche', 'chercheurs.api.recherche' ), # groupes