Compare commits

...

1 commit

Author SHA1 Message Date
Martin Pépin
6232bf2de4
Remove unused imports 2019-10-05 00:57:32 +02:00
11 changed files with 97 additions and 104 deletions

View file

@ -2,12 +2,12 @@
from tastypie.resources import ModelResource from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie import fields, utils from tastypie import fields
from django.contrib.gis import geos from django.contrib.gis import geos
from django.urls import reverse from django.urls import reverse
from .models import Lieu, Stage, Normalien, StageMatiere from .models import Lieu, Stage, Normalien
from .utils import approximate_distance from .utils import approximate_distance
class EnScolariteAuthentication(SessionAuthentication): class EnScolariteAuthentication(SessionAuthentication):
@ -20,12 +20,12 @@ class EnScolariteAuthentication(SessionAuthentication):
class LieuResource(ModelResource): class LieuResource(ModelResource):
#stages = fields.ToManyField("avisstage.api.StageResource", #stages = fields.ToManyField("avisstage.api.StageResource",
# "stages", use_in="detail", full=True) # "stages", use_in="detail", full=True)
class Meta: class Meta:
queryset = Lieu.objects.all() queryset = Lieu.objects.all()
resource_name = "lieu" resource_name = "lieu"
fields = ["nom", "ville", "pays", "coord", "type_lieu", "id"] fields = ["nom", "ville", "pays", "coord", "type_lieu", "id"]
#login_required #login_required
authentication = SessionAuthentication() authentication = SessionAuthentication()
@ -46,17 +46,17 @@ class LieuResource(ModelResource):
# Filtrer les lieux qui ont déjà des stages # Filtrer les lieux qui ont déjà des stages
if "has_stage" in filters: if "has_stage" in filters:
orm_filters['stages__public'] = True orm_filters['stages__public'] = True
return orm_filters return orm_filters
# Custom apply filters pour ajouter le "distinct" # Custom apply filters pour ajouter le "distinct"
def apply_filters(self, request, applicable_filters): def apply_filters(self, request, applicable_filters):
return self.get_object_list(request).filter(**applicable_filters).distinct() return self.get_object_list(request).filter(**applicable_filters).distinct()
# Ajout d'informations # Ajout d'informations
def dehydrate(self, bundle): def dehydrate(self, bundle):
bundle = super(LieuResource, self).dehydrate(bundle) bundle = super(LieuResource, self).dehydrate(bundle)
obj = bundle.obj obj = bundle.obj
bundle.data['coord'] = {'lat': float(obj.coord.y), bundle.data['coord'] = {'lat': float(obj.coord.y),
'lng': float(obj.coord.x)} 'lng': float(obj.coord.x)}
@ -65,12 +65,12 @@ class LieuResource(ModelResource):
if "lat" in bundle.request.GET and "lng" in bundle.request.GET: if "lat" in bundle.request.GET and "lng" in bundle.request.GET:
bundle.data['distance'] = approximate_distance( bundle.data['distance'] = approximate_distance(
self.reference_point, bundle.obj.coord) self.reference_point, bundle.obj.coord)
# Autres infos utiles # Autres infos utiles
bundle.data["pays_nom"] = obj.get_pays_display() bundle.data["pays_nom"] = obj.get_pays_display()
bundle.data["type_lieu_nom"] = obj.type_lieu_fancy bundle.data["type_lieu_nom"] = obj.type_lieu_fancy
# TODO use annotate? # TODO use annotate?
bundle.data["num_stages"] = obj.stages.filter(public=True).count() bundle.data["num_stages"] = obj.stages.filter(public=True).count()
return bundle return bundle
@ -94,7 +94,7 @@ class StageResource(ModelResource):
if "lieux" in filters: if "lieux" in filters:
flieux = map(int, filters['lieux'].split(',')) flieux = map(int, filters['lieux'].split(','))
orm_filters['lieux__id__in'] = flieux orm_filters['lieux__id__in'] = flieux
return orm_filters return orm_filters
# Informations à ajouter # Informations à ajouter
@ -106,7 +106,7 @@ class StageResource(ModelResource):
bundle.data['auteur'] = obj.auteur.nom bundle.data['auteur'] = obj.auteur.nom
bundle.data['thematiques'] = list(obj.thematiques.all().values_list("name", flat=True)) bundle.data['thematiques'] = list(obj.thematiques.all().values_list("name", flat=True))
bundle.data['matieres'] = list(obj.matieres.all().values_list("nom", flat=True)) bundle.data['matieres'] = list(obj.matieres.all().values_list("nom", flat=True))
# Adresse de la fiche de stage # Adresse de la fiche de stage
bundle.data['url'] = reverse("avisstage:stage", kwargs={"pk": obj.id}); bundle.data['url'] = reverse("avisstage:stage", kwargs={"pk": obj.id});
return bundle return bundle
@ -115,7 +115,7 @@ class StageResource(ModelResource):
class AuteurResource(ModelResource): class AuteurResource(ModelResource):
stages = fields.ToManyField("avisstage.api.StageResource", stages = fields.ToManyField("avisstage.api.StageResource",
"stages", use_in="detail") "stages", use_in="detail")
class Meta: class Meta:
queryset = Normalien.objects.all() queryset = Normalien.objects.all()
resource_name = "profil" resource_name = "profil"

View file

@ -1,7 +1,7 @@
from django_elasticsearch_dsl import DocType, Index, fields from django_elasticsearch_dsl import DocType, Index, fields
from elasticsearch_dsl import analyzer, token_filter, tokenizer from elasticsearch_dsl import analyzer, token_filter
from .models import Stage, AvisStage, AvisLieu from .models import Stage
from .statics import PAYS_OPTIONS from .statics import PAYS_OPTIONS
PAYS_DICT = dict(PAYS_OPTIONS) PAYS_DICT = dict(PAYS_OPTIONS)
@ -11,7 +11,7 @@ stage.settings(
number_of_shards=1, number_of_shards=1,
number_of_replicas=0 number_of_replicas=0
) )
text_analyzer = analyzer( text_analyzer = analyzer(
'default', 'default',
tokenizer="standard", tokenizer="standard",
@ -32,7 +32,7 @@ class StageDocument(DocType):
}) })
thematiques = fields.StringField() thematiques = fields.StringField()
matieres = fields.StringField() matieres = fields.StringField()
class Meta: class Meta:
model = Stage model = Stage
fields = [ fields = [
@ -65,11 +65,11 @@ class StageDocument(DocType):
def prepare_sujet(self, instance): def prepare_sujet(self, instance):
return instance.sujet.lower() return instance.sujet.lower()
# Hook pour l'affichage des noms de pays # Hook pour l'affichage des noms de pays
def prepare(self, instance): def prepare(self, instance):
data = super(StageDocument, self).prepare(instance) data = super(StageDocument, self).prepare(instance)
for lieu in data['lieux']: for lieu in data['lieux']:
lieu['pays'] = PAYS_DICT[lieu['pays']].lower() lieu['pays'] = PAYS_DICT[lieu['pays']].lower()
return data return data

View file

@ -5,7 +5,7 @@ from django.utils import timezone
import re import re
from .models import Normalien, Stage, Lieu, AvisLieu, AvisStage from .models import Stage, Lieu, AvisLieu, AvisStage
from .widgets import LatLonField from .widgets import LatLonField
# Sur-classe utile # Sur-classe utile
@ -15,12 +15,12 @@ class HTMLTrimmerForm(forms.ModelForm):
leading_white = re.compile(r"^( \t\n)*(<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>( \t\n)*)+?", re.IGNORECASE) leading_white = re.compile(r"^( \t\n)*(<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>( \t\n)*)+?", re.IGNORECASE)
trailing_white = re.compile(r"(( \t\n)*<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>)+?( \t\n)*$", re.IGNORECASE) trailing_white = re.compile(r"(( \t\n)*<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>)+?( \t\n)*$", re.IGNORECASE)
cleaned_data = super(HTMLTrimmerForm, self).clean() cleaned_data = super(HTMLTrimmerForm, self).clean()
for (fname, fval) in cleaned_data.items(): for (fname, fval) in cleaned_data.items():
# Heuristique : les champs commençant par "avis_" sont des champs html # Heuristique : les champs commençant par "avis_" sont des champs html
if fname[:5] == "avis_": if fname[:5] == "avis_":
cleaned_data[fname] = leading_white.sub("", trailing_white.sub("", fval)) cleaned_data[fname] = leading_white.sub("", trailing_white.sub("", fval))
return cleaned_data return cleaned_data
# Infos sur un stage # Infos sur un stage
@ -48,17 +48,17 @@ class StageForm(forms.ModelForm):
if "request" in kwargs: if "request" in kwargs:
self.request = kwargs.pop("request") self.request = kwargs.pop("request")
super(StageForm, self).__init__(*args, **kwargs) super(StageForm, self).__init__(*args, **kwargs)
def save(self, commit=True): def save(self, commit=True):
# Lors de la création : attribution à l'utilisateur connecté # Lors de la création : attribution à l'utilisateur connecté
if self.instance.id is None and hasattr(self, 'request'): if self.instance.id is None and hasattr(self, 'request'):
self.instance.auteur = self.request.user.profil self.instance.auteur = self.request.user.profil
# Date de modification # Date de modification
self.instance.date_maj = timezone.now() self.instance.date_maj = timezone.now()
self.instance.update_stats(False) self.instance.update_stats(False)
stage = super(StageForm, self).save(commit=commit) stage = super(StageForm, self).save(commit=commit)
return stage return stage
@ -97,7 +97,7 @@ class AvisLieuForm(HTMLTrimmerForm):
class LieuForm(forms.ModelForm): class LieuForm(forms.ModelForm):
coord = LatLonField() coord = LatLonField()
id = forms.IntegerField(widget=forms.widgets.HiddenInput(), required=False) id = forms.IntegerField(widget=forms.widgets.HiddenInput(), required=False)
class Meta: class Meta:
model = Lieu model = Lieu
fields = ['id', 'nom', 'type_lieu', 'ville', 'pays', 'coord'] fields = ['id', 'nom', 'type_lieu', 'ville', 'pays', 'coord']
@ -106,4 +106,3 @@ class LieuForm(forms.ModelForm):
class FeedbackForm(forms.Form): class FeedbackForm(forms.Form):
objet = forms.CharField(label="Objet", required=True) objet = forms.CharField(label="Objet", required=True)
message = forms.CharField(label="Message", required=True, widget=forms.widgets.Textarea()) message = forms.CharField(label="Message", required=True, widget=forms.widgets.Textarea())

View file

@ -1,7 +1,7 @@
#coding: utf-8 #coding: utf-8
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Count from django.core.management.base import BaseCommand
from avisstage.models import Stage, Lieu from avisstage.models import Lieu
class Command(BaseCommand): class Command(BaseCommand):
help = 'Nettoie les stages à plusieurs lieux identiques' help = 'Nettoie les stages à plusieurs lieux identiques'
@ -21,7 +21,7 @@ class Command(BaseCommand):
rundb = True rundb = True
else: else:
print(u"Les modifications ne seront pas appliquées") print(u"Les modifications ne seront pas appliquées")
min_lieu = options.get('min_lieu', 0) min_lieu = options.get('min_lieu', 0)
for lieu in Lieu.objects.filter(id__gte=min_lieu).order_by('-id'): for lieu in Lieu.objects.filter(id__gte=min_lieu).order_by('-id'):

View file

@ -1,7 +1,8 @@
#coding: utf-8 #coding: utf-8
from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import BaseCommand
from django.db.models import Count from django.db.models import Count
from avisstage.models import Stage, Lieu from avisstage.models import Stage
class Command(BaseCommand): class Command(BaseCommand):
help = 'Nettoie les stages à plusieurs lieux identiques' help = 'Nettoie les stages à plusieurs lieux identiques'
@ -31,7 +32,7 @@ class Command(BaseCommand):
rundb = True rundb = True
else: else:
print(u"Les modifications ne seront pas appliquées") print(u"Les modifications ne seront pas appliquées")
min_stage = options.get('min_stage', 0) min_stage = options.get('min_stage', 0)
for stage in Stage.objects.annotate(c=Count("lieux"))\ for stage in Stage.objects.annotate(c=Count("lieux"))\

View file

@ -1,7 +1,7 @@
#coding: utf-8 #coding: utf-8
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Count from django.core.management.base import BaseCommand
from avisstage.models import Stage, Lieu from avisstage.models import Lieu
class Command(BaseCommand): class Command(BaseCommand):
help = 'Nettoie les stages à plusieurs lieux identiques' help = 'Nettoie les stages à plusieurs lieux identiques'

View file

@ -9,13 +9,10 @@ from django.db import models
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.gis.db import models as geomodels from django.contrib.gis.db import models as geomodels
from django.template.defaultfilters import slugify
from django.forms.widgets import DateInput
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.html import strip_tags
from taggit_autosuggest.managers import TaggableManager from taggit_autosuggest.managers import TaggableManager
from tinymce.models import HTMLField as RichTextField from tinymce.models import HTMLField as RichTextField
@ -23,8 +20,6 @@ from tinymce.models import HTMLField as RichTextField
from .utils import choices_length from .utils import choices_length
from .statics import DEPARTEMENTS_DEFAUT, PAYS_OPTIONS, TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, TYPE_LIEU_DICT, TYPE_STAGE_DICT, NIVEAU_SCOL_OPTIONS, NIVEAU_SCOL_DICT from .statics import DEPARTEMENTS_DEFAUT, PAYS_OPTIONS, TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS, TYPE_LIEU_DICT, TYPE_STAGE_DICT, NIVEAU_SCOL_OPTIONS, NIVEAU_SCOL_DICT
import ldap
# #
# Profil Normalien (extension du modèle User) # Profil Normalien (extension du modèle User)
# #
@ -93,7 +88,7 @@ def create_user_profile(sender, instance, created, **kwargs):
if "department_code" in edata: if "department_code" in edata:
dep = dict(DEPARTEMENTS_DEFAUT).get( dep = dict(DEPARTEMENTS_DEFAUT).get(
edata["department_code"].lower(), '') edata["department_code"].lower(), '')
profil.promotion = "%s %s" % (dep, edata["entrance_year"]) profil.promotion = "%s %s" % (dep, edata["entrance_year"])
profil.nom = edata.get("name", "") profil.nom = edata.get("name", "")
profil.save() profil.save()
@ -119,7 +114,7 @@ class Lieu(models.Model):
pays = models.CharField(u"Pays", pays = models.CharField(u"Pays",
choices=PAYS_OPTIONS, choices=PAYS_OPTIONS,
max_length=choices_length(PAYS_OPTIONS)) max_length=choices_length(PAYS_OPTIONS))
# Coordonnées # Coordonnées
objects = geomodels.GeoManager() # Requis par GeoDjango objects = geomodels.GeoManager() # Requis par GeoDjango
coord = geomodels.PointField(u"Coordonnées", coord = geomodels.PointField(u"Coordonnées",
@ -137,11 +132,11 @@ class Lieu(models.Model):
def __str__(self): def __str__(self):
return u"%s (%s)" % (self.nom, self.ville) return u"%s (%s)" % (self.nom, self.ville)
class Meta: class Meta:
verbose_name = "Lieu" verbose_name = "Lieu"
verbose_name_plural = "Lieux" verbose_name_plural = "Lieux"
# #
# Matières des stages # Matières des stages
# #
@ -149,7 +144,7 @@ class Lieu(models.Model):
class StageMatiere(models.Model): class StageMatiere(models.Model):
nom = models.CharField(u"Nom", max_length=30) nom = models.CharField(u"Nom", max_length=30)
slug = models.SlugField() slug = models.SlugField()
class Meta: class Meta:
verbose_name = "Matière des stages" verbose_name = "Matière des stages"
verbose_name_plural = "Matières des stages" verbose_name_plural = "Matières des stages"
@ -228,7 +223,7 @@ class Stage(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('avisstage:stage', self) return reverse('avisstage:stage', self)
def __str__(self): def __str__(self):
return u"%s (par %s)" % (self.sujet, self.auteur.user.username) return u"%s (par %s)" % (self.sujet, self.auteur.user.username)
@ -242,16 +237,16 @@ class Stage(models.Model):
length += len(obj.les_plus.split()) length += len(obj.les_plus.split())
length += len(obj.les_moins.split()) length += len(obj.les_moins.split())
return length return length
if self.avis_stage: if self.avis_stage:
self.len_avis_stage = get_len(self.avis_stage) self.len_avis_stage = get_len(self.avis_stage)
self.len_avis_lieux = 0 self.len_avis_lieux = 0
for avis in self.avislieu_set.all(): for avis in self.avislieu_set.all():
self.len_avis_lieux += get_len(avis) self.len_avis_lieux += get_len(avis)
if save: if save:
self.save() self.save()
class Meta: class Meta:
verbose_name = "Stage" verbose_name = "Stage"

View file

@ -4,16 +4,15 @@ from allauth_ens.adapter import deprecate_clippers
from datetime import date from datetime import date
from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from django.conf import settings from django.conf import settings
from .models import User, Normalien, Lieu, Stage, StageMatiere, AvisLieu from .models import User, Lieu, Stage, StageMatiere, AvisLieu
class ExperiENSTestCase(CASTestCase): class ExperiENSTestCase(CASTestCase):
# Dummy database # Dummy database
def setUp(self): def setUp(self):
self.u_conscrit = User.objects.create_user('conscrit', self.u_conscrit = User.objects.create_user('conscrit',
'conscrit@ens.fr', 'conscrit@ens.fr',
@ -28,7 +27,7 @@ class ExperiENSTestCase(CASTestCase):
provider="clipper", provider="clipper",
uid="conscrit") uid="conscrit")
self.sa_conscrit.save() self.sa_conscrit.save()
self.u_archi = User.objects.create_user('archicube', self.u_archi = User.objects.create_user('archicube',
'archicube@ens.fr', 'archicube@ens.fr',
'archicube') 'archicube')
@ -50,7 +49,7 @@ class ExperiENSTestCase(CASTestCase):
self.matiere1.save() self.matiere1.save()
self.matiere2 = StageMatiere(nom="Sortilège", slug="sortilege") self.matiere2 = StageMatiere(nom="Sortilège", slug="sortilege")
self.matiere2.save() self.matiere2.save()
self.cstage1 = Stage(auteur=self.p_conscrit, sujet="Wingardium Leviosa", self.cstage1 = Stage(auteur=self.p_conscrit, sujet="Wingardium Leviosa",
date_debut=date(2000, 5, 10), date_debut=date(2000, 5, 10),
date_fin=date(2000, 8, 26), date_fin=date(2000, 8, 26),
@ -73,7 +72,7 @@ class ExperiENSTestCase(CASTestCase):
chapo="Trop nul") chapo="Trop nul")
alieu2.save() alieu2.save()
self.astage1 = Stage(auteur=self.p_archi, sujet="Alohomora", self.astage1 = Stage(auteur=self.p_archi, sujet="Alohomora",
date_debut=date(1994, 5, 10), date_debut=date(1994, 5, 10),
date_fin=date(1994, 8, 26), date_fin=date(1994, 8, 26),
@ -109,10 +108,10 @@ class PublicViewsTest(ExperiENSTestCase):
def test_stage_visibility_public(self): def test_stage_visibility_public(self):
self.assertRedirectToLogin(reverse('avisstage:stage', self.assertRedirectToLogin(reverse('avisstage:stage',
kwargs={'pk':self.cstage1.id})) kwargs={'pk':self.cstage1.id}))
self.assertRedirectToLogin(reverse('avisstage:stage', self.assertRedirectToLogin(reverse('avisstage:stage',
kwargs={'pk':self.cstage2.id})) kwargs={'pk':self.cstage2.id}))
self.assertRedirectToLogin(reverse('avisstage:stage', self.assertRedirectToLogin(reverse('avisstage:stage',
kwargs={'pk':self.astage1.id})) kwargs={'pk':self.astage1.id}))
@ -127,7 +126,7 @@ class PublicViewsTest(ExperiENSTestCase):
self.assertRedirectToLogin(reverse( self.assertRedirectToLogin(reverse(
'avisstage:profil', kwargs={'username': self.u_archi.username})) 'avisstage:profil', kwargs={'username': self.u_archi.username}))
""" """
Vérifie que la recherche n'est pas accessible hors connexion Vérifie que la recherche n'est pas accessible hors connexion
""" """
@ -151,27 +150,27 @@ class PublicViewsTest(ExperiENSTestCase):
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 401) self.assertEqual(r.status_code, 401)
testurl = reverse('avisstage:api_dispatch_list', testurl = reverse('avisstage:api_dispatch_list',
kwargs={"resource_name": "stage", kwargs={"resource_name": "stage",
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 401) self.assertEqual(r.status_code, 401)
testurl = reverse('avisstage:api_dispatch_list', testurl = reverse('avisstage:api_dispatch_list',
kwargs={"resource_name": "profil", kwargs={"resource_name": "profil",
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 401) self.assertEqual(r.status_code, 401)
""" """
Vérifie que les pages d'édition ne sont pas accessible hors connexion Vérifie que les pages d'édition ne sont pas accessible hors connexion
""" """
def test_edit_visibility_public(self): def test_edit_visibility_public(self):
self.assertRedirectToLogin(reverse( self.assertRedirectToLogin(reverse(
'avisstage:stage_edit', kwargs={'pk':self.cstage1.id})) 'avisstage:stage_edit', kwargs={'pk':self.cstage1.id}))
self.assertRedirectToLogin(reverse( self.assertRedirectToLogin(reverse(
'avisstage:stage_edit', kwargs={'pk':self.astage1.id})) 'avisstage:stage_edit', kwargs={'pk':self.astage1.id}))
@ -208,10 +207,10 @@ class ArchicubeViewsTest(ExperiENSTestCase):
def test_stage_visibility_archi(self): def test_stage_visibility_archi(self):
self.assertPageNotFound(reverse('avisstage:stage', self.assertPageNotFound(reverse('avisstage:stage',
kwargs={'pk':self.cstage1.id})) kwargs={'pk':self.cstage1.id}))
self.assertPageNotFound(reverse('avisstage:stage', self.assertPageNotFound(reverse('avisstage:stage',
kwargs={'pk':self.cstage2.id})) kwargs={'pk':self.cstage2.id}))
testurl = reverse('avisstage:stage', testurl = reverse('avisstage:stage',
kwargs={'pk':self.astage1.id}) kwargs={'pk':self.astage1.id})
r = self.client.get(testurl) r = self.client.get(testurl)
@ -230,13 +229,13 @@ class ArchicubeViewsTest(ExperiENSTestCase):
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
""" """
Vérifie que la recherche n'est pas accessible Vérifie que la recherche n'est pas accessible
""" """
def test_pages_visibility_archi(self): def test_pages_visibility_archi(self):
self.assert403Archicubes(reverse('avisstage:recherche')) self.assert403Archicubes(reverse('avisstage:recherche'))
self.assert403Archicubes(reverse('avisstage:recherche_resultats')) self.assert403Archicubes(reverse('avisstage:recherche_resultats'))
self.assert403Archicubes(reverse('avisstage:stage_items')) self.assert403Archicubes(reverse('avisstage:stage_items'))
@ -260,20 +259,20 @@ class ArchicubeViewsTest(ExperiENSTestCase):
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
testurl = reverse('avisstage:api_dispatch_list', testurl = reverse('avisstage:api_dispatch_list',
kwargs={"resource_name": "stage", kwargs={"resource_name": "stage",
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 401) self.assertEqual(r.status_code, 401)
testurl = reverse('avisstage:api_dispatch_list', testurl = reverse('avisstage:api_dispatch_list',
kwargs={"resource_name": "profil", kwargs={"resource_name": "profil",
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 401) self.assertEqual(r.status_code, 401)
""" """
Vérifie que le seul stage modifiable est le sien Vérifie que le seul stage modifiable est le sien
""" """
@ -296,11 +295,11 @@ class ArchicubeViewsTest(ExperiENSTestCase):
r = self.client.post(testurl, {"publier": True}) r = self.client.post(testurl, {"publier": True})
self.assertRedirects(r, reverse('avisstage:stage', self.assertRedirects(r, reverse('avisstage:stage',
kwargs={"pk": self.astage1.id})) kwargs={"pk": self.astage1.id}))
testurl = reverse('avisstage:stage_ajout') testurl = reverse('avisstage:stage_ajout')
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
testurl = reverse('avisstage:profil_edit') testurl = reverse('avisstage:profil_edit')
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
@ -311,14 +310,14 @@ class ArchicubeViewsTest(ExperiENSTestCase):
class DeprecatedArchicubeViewsTest(ArchicubeViewsTest): class DeprecatedArchicubeViewsTest(ArchicubeViewsTest):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.sa_archi = SocialAccount(user=self.u_archi, self.sa_archi = SocialAccount(user=self.u_archi,
provider="clipper", provider="clipper",
uid="archicube") uid="archicube")
self.sa_archi.save() self.sa_archi.save()
deprecate_clippers() deprecate_clippers()
self.client.login(username='archicube', password='archicube') self.client.login(username='archicube', password='archicube')
@ -330,7 +329,7 @@ ACCÈS EN SCOLARITE
class ScolariteViewsTest(ExperiENSTestCase): class ScolariteViewsTest(ExperiENSTestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.u_vieuxcon = User.objects.create_user('vieuxcon', self.u_vieuxcon = User.objects.create_user('vieuxcon',
'vieuxcon@ens.fr', 'vieuxcon@ens.fr',
'vieuxcon') 'vieuxcon')
@ -344,7 +343,7 @@ class ScolariteViewsTest(ExperiENSTestCase):
provider="clipper", provider="clipper",
uid="vieuxcon") uid="vieuxcon")
self.sa_vieuxcon.save() self.sa_vieuxcon.save()
self.vstage1 = Stage(auteur=self.p_vieuxcon, sujet="Oubliettes", self.vstage1 = Stage(auteur=self.p_vieuxcon, sujet="Oubliettes",
date_debut=date(1998, 5, 10), date_debut=date(1998, 5, 10),
date_fin=date(1998, 8, 26), date_fin=date(1998, 8, 26),
@ -355,7 +354,7 @@ class ScolariteViewsTest(ExperiENSTestCase):
alieu1 = AvisLieu(stage=self.vstage1, lieu=self.lieu2, alieu1 = AvisLieu(stage=self.vstage1, lieu=self.lieu2,
chapo="Pas si mal") chapo="Pas si mal")
alieu1.save() alieu1.save()
self.client.login(username='vieuxcon', password='vieuxcon') self.client.login(username='vieuxcon', password='vieuxcon')
""" """
@ -370,7 +369,7 @@ class ScolariteViewsTest(ExperiENSTestCase):
self.assertPageNotFound(reverse('avisstage:stage', self.assertPageNotFound(reverse('avisstage:stage',
kwargs={'pk':self.cstage2.id})) kwargs={'pk':self.cstage2.id}))
testurl = reverse('avisstage:stage', testurl = reverse('avisstage:stage',
kwargs={'pk':self.vstage1.id}) kwargs={'pk':self.vstage1.id})
r = self.client.get(testurl) r = self.client.get(testurl)
@ -398,7 +397,7 @@ class ScolariteViewsTest(ExperiENSTestCase):
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
""" """
Vérifie que la recherche et les autres pages sont accessible Vérifie que la recherche et les autres pages sont accessible
""" """
@ -442,7 +441,7 @@ class ScolariteViewsTest(ExperiENSTestCase):
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
testurl = reverse('avisstage:api_dispatch_list', testurl = reverse('avisstage:api_dispatch_list',
kwargs={"resource_name": "stage", kwargs={"resource_name": "stage",
"api_name": "v1"}) "api_name": "v1"})
@ -450,14 +449,14 @@ class ScolariteViewsTest(ExperiENSTestCase):
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
self.assertContains(r, "Wingardium Leviosa") # Public self.assertContains(r, "Wingardium Leviosa") # Public
self.assertNotContains(r, "Avada Kedavra") # Brouillon self.assertNotContains(r, "Avada Kedavra") # Brouillon
testurl = reverse('avisstage:api_dispatch_list', testurl = reverse('avisstage:api_dispatch_list',
kwargs={"resource_name": "profil", kwargs={"resource_name": "profil",
"api_name": "v1"}) "api_name": "v1"})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
""" """
Vérifie que le seul stage modifiable est le sien Vérifie que le seul stage modifiable est le sien
""" """
@ -469,7 +468,7 @@ class ScolariteViewsTest(ExperiENSTestCase):
testurl = reverse('avisstage:stage_edit', kwargs={'pk':self.astage1.id}) testurl = reverse('avisstage:stage_edit', kwargs={'pk':self.astage1.id})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 403) self.assertEqual(r.status_code, 403)
testurl = reverse('avisstage:stage_edit', kwargs={'pk':self.vstage1.id}) testurl = reverse('avisstage:stage_edit', kwargs={'pk':self.vstage1.id})
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
@ -484,11 +483,11 @@ class ScolariteViewsTest(ExperiENSTestCase):
r = self.client.post(testurl, {"publier": True}) r = self.client.post(testurl, {"publier": True})
self.assertRedirects(r, reverse('avisstage:stage', self.assertRedirects(r, reverse('avisstage:stage',
kwargs={"pk": self.vstage1.id})) kwargs={"pk": self.vstage1.id}))
testurl = reverse('avisstage:stage_ajout') testurl = reverse('avisstage:stage_ajout')
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
testurl = reverse('avisstage:profil_edit') testurl = reverse('avisstage:profil_edit')
r = self.client.get(testurl) r = self.client.get(testurl)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)

View file

@ -1,6 +1,5 @@
# coding: utf-8 # coding: utf-8
from allauth.socialaccount.models import SocialAccount
from functools import reduce from functools import reduce
from math import cos, radians, sqrt from math import cos, radians, sqrt

View file

@ -2,7 +2,7 @@
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import DetailView, ListView from django.views.generic import DetailView
from django.views.generic.edit import UpdateView, CreateView from django.views.generic.edit import UpdateView, CreateView
from django import forms from django import forms
from django.urls import reverse from django.urls import reverse
@ -58,7 +58,7 @@ class ProfilView(LoginRequiredMixin, DetailView):
# Récupération du profil # Récupération du profil
def get_object(self): def get_object(self):
# Restriction d'accès pour les archicubes # Restriction d'accès pour les archicubes
if (en_scolarite(self.request.user) or if (en_scolarite(self.request.user) or
self.kwargs.get('username') == self.request.user.username): self.kwargs.get('username') == self.request.user.username):
@ -76,7 +76,7 @@ class StageView(LoginRequiredMixin, DetailView):
# Restriction aux stages publics ou personnels # Restriction aux stages publics ou personnels
def get_queryset(self): def get_queryset(self):
filtre = Q(auteur__user_id=self.request.user.id) filtre = Q(auteur__user_id=self.request.user.id)
# Restriction d'accès pour les archicubes # Restriction d'accès pour les archicubes
if en_scolarite(self.request.user): if en_scolarite(self.request.user):
filtre |= Q(public=True) filtre |= Q(public=True)
@ -106,7 +106,7 @@ class ProfilEdit(LoginRequiredMixin, UpdateView):
# Limitation à son propre profil # Limitation à son propre profil
def get_object(self): def get_object(self):
return self.request.user.profil return self.request.user.profil
def get_success_url(self): def get_success_url(self):
return reverse('avisstage:perso') return reverse('avisstage:perso')
@ -179,7 +179,7 @@ def manage_stage(request, pk=None):
@login_required @login_required
def save_lieu(request): def save_lieu(request):
normalien = request.user.profil normalien = request.user.profil
if request.method == "POST": if request.method == "POST":
pk = request.POST.get("id", None) pk = request.POST.get("id", None)
#print(request.POST) #print(request.POST)
@ -198,7 +198,7 @@ def save_lieu(request):
lieu = Lieu() lieu = Lieu()
# Servira à bouger un peu le lieu # Servira à bouger un peu le lieu
jitter = True jitter = True
# Lecture des données # Lecture des données
form = LieuForm(request.POST, instance=lieu) form = LieuForm(request.POST, instance=lieu)
@ -222,7 +222,7 @@ def save_lieu(request):
olieu.ville == lieu.ville and \ olieu.ville == lieu.ville and \
olieu.pays == lieu.pays: olieu.pays == lieu.pays:
return JsonResponse({"success": True, "id": olieu.id}) return JsonResponse({"success": True, "id": olieu.id})
lieu.save() lieu.save()
return JsonResponse({"success": True, "id": lieu.id}) return JsonResponse({"success": True, "id": lieu.id})
else: else:
@ -270,7 +270,7 @@ def publier_stage(request, pk):
stage.public = False stage.public = False
stage.save() stage.save()
return redirect(reverse("avisstage:stage", kwargs={"pk": pk})) return redirect(reverse("avisstage:stage", kwargs={"pk": pk}))
# #

View file

@ -9,7 +9,7 @@ from django.core.cache import cache
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models import Q, Case, When from django.db.models import Q, Case, When
from django.http import JsonResponse, HttpResponseBadRequest from django.http import JsonResponse, HttpResponseBadRequest
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render
import json import json
import logging import logging
@ -32,7 +32,7 @@ class SearchForm(forms.Form):
sujet = forms.CharField(label=u'À propos de', required=False) sujet = forms.CharField(label=u'À propos de', required=False)
contexte = forms.CharField(label=u'Contexte (lieu, encadrant⋅e⋅s, structure)', contexte = forms.CharField(label=u'Contexte (lieu, encadrant⋅e⋅s, structure)',
required=False) required=False)
apres_annee = forms.IntegerField(label=u'Après cette année', required=False) apres_annee = forms.IntegerField(label=u'Après cette année', required=False)
avant_annee = forms.IntegerField(label=u'Avant cette année', required=False) avant_annee = forms.IntegerField(label=u'Avant cette année', required=False)
@ -42,7 +42,7 @@ class SearchForm(forms.Form):
niveau_scol = forms.ChoiceField(label="Année d'étude", choices=([('', u'')] niveau_scol = forms.ChoiceField(label="Année d'étude", choices=([('', u'')]
+ list(NIVEAU_SCOL_OPTIONS)), + list(NIVEAU_SCOL_OPTIONS)),
required=False) required=False)
type_lieu = forms.ChoiceField(label=u"Type de lieu d'accueil", type_lieu = forms.ChoiceField(label=u"Type de lieu d'accueil",
choices=([('', u'')] choices=([('', u'')]
+ list(TYPE_LIEU_OPTIONS)), + list(TYPE_LIEU_OPTIONS)),
@ -105,7 +105,7 @@ def cherche(**kwargs):
| Q(matieres__nom__icontains=generique) | Q(matieres__nom__icontains=generique)
| Q(lieux__nom__icontains=generique)) | Q(lieux__nom__icontains=generique))
# Autres champs -> non fonctionnels # Autres champs -> non fonctionnels
if field_relevant("sujet") or field_relevant("contexte"): if field_relevant("sujet") or field_relevant("contexte"):
raise NotImplementedError( raise NotImplementedError(
"ElasticSearch doit être activé pour ce type de recherche") "ElasticSearch doit être activé pour ce type de recherche")
@ -113,7 +113,7 @@ def cherche(**kwargs):
# #
# Filtres directs db # Filtres directs db
# #
# Dates # Dates
if field_relevant('avant_annee', False): if field_relevant('avant_annee', False):
dte = date(kwargs['avant_annee']+1, 1, 1) dte = date(kwargs['avant_annee']+1, 1, 1)
@ -126,7 +126,7 @@ def cherche(**kwargs):
# Type de stage # Type de stage
if field_relevant('type_stage'): if field_relevant('type_stage'):
filtres &= Q(type_stage=kwargs["type_stage"]) filtres &= Q(type_stage=kwargs["type_stage"])
if field_relevant('niveau_scol'): if field_relevant('niveau_scol'):
filtres &= Q(niveau_scol=kwargs["niveau_scol"]) filtres &= Q(niveau_scol=kwargs["niveau_scol"])
@ -134,7 +134,7 @@ def cherche(**kwargs):
if field_relevant('type_lieu'): if field_relevant('type_lieu'):
filtres &= Q(lieux__type_lieu=kwargs["type_lieu"]) filtres &= Q(lieux__type_lieu=kwargs["type_lieu"])
# Application # Application
if USE_ELASTICSEARCH and use_dsl: if USE_ELASTICSEARCH and use_dsl:
filtres &= Q(id__in=[s.meta.id for s in dsl.scan()]) filtres &= Q(id__in=[s.meta.id for s in dsl.scan()])
@ -145,7 +145,7 @@ def cherche(**kwargs):
if not use_dsl: if not use_dsl:
kwargs['tri'] = '-date_maj' kwargs['tri'] = '-date_maj'
if field_relevant('tri') and kwargs['tri'] in ['-date_maj']: if field_relevant('tri') and kwargs['tri'] in ['-date_maj']:
tri = kwargs['tri'] tri = kwargs['tri']
resultat = resultat.order_by(tri) resultat = resultat.order_by(tri)
@ -223,7 +223,7 @@ def recherche_resultats(request):
if request.GET.get("format") == "json": if request.GET.get("format") == "json":
return JsonResponse({"stages": stages, "page": page, return JsonResponse({"stages": stages, "page": page,
"num_pages": paginator.num_pages}) "num_pages": paginator.num_pages})
template_name = 'avisstage/recherche/resultats.html' template_name = 'avisstage/recherche/resultats.html'
if request.GET.get("format") == "raw": if request.GET.get("format") == "raw":
template_name = 'avisstage/recherche/stage_items.html' template_name = 'avisstage/recherche/stage_items.html'