# coding: utf-8 from django.shortcuts import get_object_or_404, render from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, HttpResponseNotFound from django.core.urlresolvers import reverse from django import forms from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis import measure from django.forms.widgets import HiddenInput from monstage.models import * def addslashes(s): d = {'"':'\\"', "'":"\\'", "\0":"\\\0", "\\":"\\\\", '\n':'\\n'} return ''.join(d.get(c, c) for c in s) @login_required def index(request): stages = Stage.objects.filter( profil_user = request.user.profil ) return render(request, 'monstage/index.html', {"stages" : stages}) # # Utilisateurs et profils # def profil(request, profil_id): user = get_object_or_404( User, username = profil_id ) profil = user.profil stages = Stage.objects.filter( profil_user = profil ) return render(request, 'monstage/profil.html', {'profil': profil, 'stages': stages}) @login_required def profil_edit(request): if request.POST: user = request.user user.first_name = request.POST['first_name'] user.last_name = request.POST['last_name'] user.save() return HttpResponseRedirect(reverse('monstage:profil', args=(request.user.username,))) else: (profil, _) = Normalien.objects.get_or_create( user = request.user ) return render(request, 'monstage/profil_edit.html', {'normalien': profil}) # # Stages # def stage(request, stage_id): stage = get_object_or_404( Stage, pk = stage_id) lieux_latlng = [] for lieu in stage.lieux.all(): # GEOS Format : (longitude, latitude) lieux_latlng.append("%f, %f" % (lieu.coord.y, lieu.coord.x)) context = { 'stage': stage, 'modifiable': (stage.profil_user == request.user.profil), 'lieux_latlng': lieux_latlng } return render(request, 'monstage/stage.html', context) class StageForm(forms.ModelForm): class Meta: model = Stage fields = ("type_stage", "start_date", "end_date", "matieres", "sujet", "thematiques", "encadrants") @login_required def stage_add(request): if request.POST: form = StageForm(request.POST) if form.is_valid: new_stage = form.save(commit = False) new_stage.profil_user = request.user.profil new_stage.save() form.save_m2m() return HttpResponseRedirect(reverse('monstage:stage_edit_lieu', args=(new_stage.id,))) else: form = StageForm() return render(request, 'monstage/stage_add.html', { 'form': form }) @login_required def stage_edit_desc(request, stage_id): stage = get_object_or_404( Stage, pk = stage_id) if stage.profil_user != request.user.profil: return HttpResponseForbidden("Ce stage ne vous appartient pas") bullshit = "" if request.POST: form = StageForm(request.POST, instance = stage) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('monstage:stage', args=(stage.id,))) else: form = StageForm(instance = stage) return render(request, 'monstage/stage_edit_desc.html', { 'stage': stage, 'form':form }) class LieuStageForm(forms.Form): lieu_id = forms.IntegerField(widget = HiddenInput()) delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '') def is_to_delete(self): return self.cleaned_data['delete'] class LieuForm(forms.ModelForm): latitude = forms.DecimalField() longitude = forms.DecimalField() delete = forms.BooleanField(help_text=(u'Supprimer ce lieu'), required = False, label = '') def __init__(self, *args, **kwargs): super(LieuForm, self).__init__(*args, **kwargs) self.fields['latitude'].widget = HiddenInput() self.fields['longitude'].widget = HiddenInput() lieu = kwargs.pop('instance', None) if lieu: # GEOS Format : (longitude, latitude) self.fields['longitude'].initial = lieu.coord.x self.fields['latitude'].initial = lieu.coord.y class Meta: model = Lieu fields = ("name", "ville", "pays") def is_to_delete(self): return self.cleaned_data['delete'] def save(self, *args, **kwargs): lieu = super(LieuForm, self).save(commit=False, *args, **kwargs) # GEOS Format : (longitude, latitude) lieu.coord = GEOSGeometry('POINT(%f %f)' % (self.cleaned_data['longitude'], self.cleaned_data['latitude']), srid=4326) return lieu def lieux_candidats(request): if request.GET: lat = float(request.GET.get('lat', False)) lon = float(request.GET.get('lon', False)) if lat and lon: # GEOS Format : (longitude, latitude) coords = GEOSGeometry('POINT(%f %f)' % (lon, lat), srid=4326) distance = {'km': 0.5} lieux = Lieu.objects.filter(coord__distance_lte=(coords, measure.D(**distance))) lieux = lieux.distance(coords).order_by('distance') retour = [ {'name': addslashes(lieu.name), 'id': lieu.id, 'lat':str(lieu.coord.coords[0]), 'lon':str(lieu.coord.coords[1]), 'distance':lieu.distance } for lieu in lieux.distance(coords) ] return render(request, 'monstage/lieux_proches.json', { 'lieux':retour }, content_type='text/plain; charset=utf-8') return HttpResponseNotFound() def stage_edit_lieu(request, stage_id): stage = get_object_or_404( Stage, pk = stage_id) bullshit = '' if stage.profil_user != request.user.profil: return HttpResponseForbidden("Ce stage ne vous appartient pas") if request.POST: valid = True prevLieuxStage = [k for k in stage.lieustage_set.all()] lieuforms = [] deleted = [] for i in range(0, int(request.POST['numplaces'])): toSave = False if request.POST.get('%d-name' % i, False): # Lieu à créer bullshit += str(i) + 'a ' lieuform = LieuForm(request.POST, prefix = str(i)) if not lieuform.is_valid(): valid = False lieuforms.append(lieuform) continue if lieuform.is_to_delete(): pass else: lieu = lieuform.save() lieu.save() lieuform.save_m2m() toSave = True lieuforms.append(LieuStageForm(initial = {'lieu_id': lieu.id}, prefix = str(i))) elif request.POST.get('%d-lieu_id' % i, False): # Lien vers un lieu déjà existant bullshit += str(i) + 'b ' lieuform = LieuStageForm(request.POST, prefix = str(i)) if not lieuform.is_valid(): bullshit += 'invalid ' valid = False lieuforms.append(lieuform) continue if lieuform.is_to_delete(): if len(prevLieuxStage) > 0: deleted.append(prevLieuxStage.pop(0)) else: lieuforms.append(lieuform) lieu = Lieu.objects.get( pk = lieuform.cleaned_data['lieu_id'] ) toSave = True if toSave: # Mise à jour des liens lieu - stage if len(prevLieuxStage) > 0: lieustage = prevLieuxStage.pop(0) lieustage.lieu = lieu lieustage.save() elif len(deleted) > 0: lieustage = deleted.pop(0) lieustage.lieu = lieu lieustage.save() else: LieuStage.objects.create(lieu = lieu, stage = stage) if valid: for lieustage in deleted: lieustage.delete() return HttpResponseRedirect(reverse('monstage:stage_edit_feedback', args=(stage.id,))) else: lieuforms = [(lieu, LieuStageForm(initial={'lieu_id': lieu.id}, prefix=str(counter))) for counter, lieu in enumerate(stage.lieux.all())] emptyform = LieuForm(prefix='{{ID}}') emptylieu = LieuStageForm(prefix='{{ID}}') return render(request, 'monstage/stage_edit_lieu.html', { 'stage': stage, 'debug': bullshit, 'lieuforms': lieuforms, 'emptyform': addslashes(emptyform.as_p()), 'emptylieu': addslashes(emptylieu.as_p()), 'numforms':len(lieuforms) }) class StageFeedbackForm(forms.ModelForm): class Meta: model = Stage fields = ("avis_encadrants", "avis_equipe", "avis_stage", "avis_admin") class LieuStageFeedbackForm(forms.ModelForm): class Meta: model = LieuStage fields = ("avis_global", "avis_lieudevie", "avis_lieustage", "avis_pratique", "avis_visite", "avis_anecdotes") def stage_edit_feedback(request, stage_id): stage = get_object_or_404( Stage, pk = stage_id) if stage.profil_user != request.user.profil: return HttpResponseForbidden("Ce stage ne vous appartient pas") if request.POST: form_gen = StageFeedbackForm(request.POST, instance = stage, prefix = 'gen') forms_lieux = [(LieuStageFeedbackForm(request.POST, instance = lieustage, prefix = lieustage.id), lieustage.lieu) for lieustage in stage.lieustage_set.all()] valid = form_gen.is_valid() for (form, _) in forms_lieux: if not form.is_valid(): valid = False if valid: form_gen.save() for (form, _) in forms_lieux: form.save() return HttpResponseRedirect(reverse('monstage:stage', args=(stage.id,))) else: form_gen = StageFeedbackForm(instance = stage, prefix = 'gen') forms_lieux = [(LieuStageFeedbackForm(instance = lieustage, prefix = lieustage.id), lieustage.lieu) for lieustage in stage.lieustage_set.all()] return render(request, 'monstage/stage_edit_feedback.html', { 'stage': stage, 'form_gen':form_gen, 'forms_lieux':forms_lieux }) def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'monstage/detail.html', {'question': question})