cleaned up code

This commit is contained in:
artus40
2018-03-01 19:10:01 +01:00
parent b68980f392
commit 85f388aac2
8 changed files with 142 additions and 164 deletions

View File

@@ -1,10 +1,5 @@
from django.contrib import admin
from django import forms
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from .models import *
from .notes import Observation
@@ -12,6 +7,7 @@ from .notes import Observation
# Basic registration
admin.site.register(Lieu)
# Inlines
class ObservationInline(admin.StackedInline):
model = Observation
@@ -32,7 +28,6 @@ class RencontreAdmin(admin.ModelAdmin):
list_filter = ['lieu']
@admin.register(Maraude)
class MaraudeAdmin(admin.ModelAdmin):

View File

@@ -3,6 +3,3 @@ from django.apps import AppConfig
class Config(AppConfig):
name = 'maraudes'

View File

@@ -1,20 +1,22 @@
from django import forms
from django.utils.translation import gettext
from django.utils import timezone
from django_select2.forms import Select2Widget
# Models
from .models import *
from .notes import *
from notes.forms import UserNoteForm, SimpleNoteForm
from notes.models import Sujet, GENRE_CHOICES
from .models import *
from .notes import *
MONTHS = [
(num, gettext(calendar.month_name[num])) for num in range(1, 13)
]
def current_year_range():
""" Returns a range from year -1 to year + 2 """
year = timezone.now().date().year
return (year - 1, year, year + 1, year + 2)
return year - 1, year, year + 1, year + 2
class MaraudeHiddenDateForm(forms.ModelForm):
@@ -24,8 +26,6 @@ class MaraudeHiddenDateForm(forms.ModelForm):
widgets = {'date': forms.HiddenInput()}
class RencontreForm(forms.ModelForm):
class Meta:
model = Rencontre
@@ -35,36 +35,32 @@ class RencontreForm(forms.ModelForm):
}
ObservationInlineFormSet = forms.inlineformset_factory( Rencontre, Observation,
ObservationInlineFormSet = forms.inlineformset_factory(
Rencontre, Observation,
form=SimpleNoteForm,
extra = 1,
)
extra=1,
)
RencontreInlineFormSet = forms.inlineformset_factory(
Maraude, Rencontre,
form = RencontreForm,
extra = 0,
)
form=RencontreForm,
extra=0,
)
ObservationInlineFormSetNoExtra = forms.inlineformset_factory(
Rencontre, Observation,
form = SimpleNoteForm,
extra = 0
)
form=SimpleNoteForm,
extra=0
)
class MonthSelectForm(forms.Form):
month = forms.ChoiceField(label="Mois",
choices=[
(1, 'Janvier'), (2, 'Février'), (3, 'Mars'), (4, 'Avril'),
(5, 'Mai'), (6, 'Juin'), (7, 'Juillet'), (8, 'Août'),
(9, 'Septembre'),(10, 'Octobre'),(11, 'Novembre'),(12, 'Décembre')
],
choices=MONTHS,
)
year = forms.ChoiceField(label="Année",
choices = [(y, y) for y in current_year_range()]
choices=[(y, y) for y in current_year_range()],
)
def __init__(self, *args, month=None, year=None, **kwargs):
@@ -73,16 +69,13 @@ class MonthSelectForm(forms.Form):
self.fields['year'].initial = year
class AppelForm(UserNoteForm):
class Meta(UserNoteForm.Meta):
model = Appel
fields = ['sujet', 'text', 'entrant', 'created_date', 'created_time']
class SignalementForm(UserNoteForm):
nom = forms.CharField(64, required=False)
prenom = forms.CharField(64, required=False)
age = forms.IntegerField(required=False)

View File

@@ -1,11 +1,9 @@
from django.db.models import Manager
import datetime
from django.utils import timezone
from django.utils.functional import cached_property
from django.db.models import Manager
# TODO: What is really useful in there ??
class MaraudeManager(Manager):
""" Manager for Maraude objects """
@@ -33,7 +31,8 @@ class MaraudeManager(Manager):
def get_future(self, date=None):
""" Retourne la liste des prochaines maraudes """
if not date: date = self.today
if not date:
date = self.today
return self.get_queryset().filter(
date__gte=date
).order_by(
@@ -42,7 +41,8 @@ class MaraudeManager(Manager):
def get_past(self, date=None):
""" Retourne la liste des maraudes passées """
if not date: date = self.today
if not date:
date = self.today
return self.get_queryset().filter(
date__lt=date
).order_by(
@@ -81,15 +81,3 @@ class MaraudeManager(Manager):
return None
except self.model.DoesNotExist:
return None
class ObservationManager(Manager):
def get_for_sujet(self, sujet):
return self.filter(sujet=sujet)
def get_first_for_sujet(self, sujet):
return self.filter(sujet=sujet).order_by('date').first()

View File

@@ -1,22 +1,21 @@
import calendar
import datetime
from collections import OrderedDict
from django.utils import timezone
from django.db import models
from django.db.models import Count
from django.core.urlresolvers import reverse
from django.utils.translation import gettext as _
from utilisateurs.models import Maraudeur
from . import managers
## Fonctions utiles
# Fonctions utiles
def get_referent_maraude():
""" Retourne l'administrateur et référent de la Maraude """
return Maraudeur.objects.get_referent()
def split_by_12h_blocks(iterable):
""" Move object with given 'field' time under 12:00 to the end of stream.
Apart from this, order is untouched.
@@ -31,22 +30,20 @@ def split_by_12h_blocks(iterable):
for note in to_end:
yield note
## Constantes
# Constantes
# Jours de la semaine
WEEKDAYS = [
(0, "Lundi"),
(1, "Mardi"),
(2, "Mercredi"),
(3, "Jeudi"),
(4, "Vendredi"),
(5, "Samedi"),
(6, "Dimanche")
(n, _(calendar.day_name[n])) for n in range(7)
]
MONTHS = {
n: _(calendar.month_name[n]) for n in range(1, 13)
}
# Horaires
HORAIRES_APRESMIDI = datetime.time(16, 0)
HORAIRES_SOIREE = datetime.time(20, 0)
HORAIRES_SOIREE = datetime.time(19, 0)
HORAIRES_CHOICES = (
(HORAIRES_APRESMIDI, 'Après-midi'),
(HORAIRES_SOIREE, 'Soirée')
@@ -60,12 +57,13 @@ DUREE_CHOICES = (
(20, '20 min'),
(30, '30 min'),
(45, '45 min'),
(60, '1 heure'),
(60, '1heure'),
(75, '1h15min'),
(90, '1h30min'),
)
## Modèles
# Modèles
class Lieu(models.Model):
""" Lieu de rencontre """
nom = models.CharField(max_length=128)
@@ -77,7 +75,6 @@ class Lieu(models.Model):
verbose_name = "Lieu de rencontre"
class Maraude(models.Model):
""" Modèle pour une maraude
- date : jour de la maraude
@@ -135,12 +132,12 @@ class Maraude(models.Model):
('view_maraudes', "Accès à l'application 'maraudes'"),
)
MOIS = ["Jan.", "Fév.", "Mars", "Avr.", "Mai", "Juin",
"Juil.", "Août", "Sept.", "Oct.", "Nov.", "Déc."]
def __str__(self):
return '%s %i %s' % (WEEKDAYS[self.date.weekday()][1], # Retrieve text inside tuple
self.date.day,
self.MOIS[self.date.month - 1])
return '%(dayname)s %(day)i %(month)s' % {
'dayname': WEEKDAYS[self.date.weekday()][1], # Retrieve text inside tuple
'day': self.date.day,
'month': MONTHS[self.date.month][:3] + ".",
}
def est_terminee(self):
""" Indique si la maraude est considérée comme terminée """
@@ -161,7 +158,6 @@ class Maraude(models.Model):
return reverse('notes:details-maraude', kwargs={'pk': self.id})
class Rencontre(models.Model):
""" Une Rencontre dans le cadre d'une maraude
"""
@@ -170,7 +166,7 @@ class Rencontre(models.Model):
maraude = models.ForeignKey(
Maraude,
models.CASCADE,
related_name = 'rencontres',
related_name='rencontres',
limit_choices_to={'heure_fin__isnull': False}
)
lieu = models.ForeignKey(
@@ -188,18 +184,19 @@ class Rencontre(models.Model):
ordering = ['maraude', 'heure_debut']
def __str__(self):
return "%s à %s (%imin)" % (
self.lieu,
self.heure_debut.strftime("%Hh%M"),
self.duree
)
return "%(lieu)s à %(heure)s (%(duree)imin)" % {
'lieu': self.lieu,
'heure': self.heure_debut.strftime("%Hh%M"),
'duree': self.duree
}
@property
def date(self):
return self.maraude.date
INDIVIDU = "Individu"
GROUPE = "Groupe"
INDIVIDU = _("Individu")
GROUPE = _("Groupe")
def groupe_ou_individu(self):
""" Retourne le type de rencontre : 'groupe'/'individu' """
nb = self.observations.count()
@@ -254,7 +251,6 @@ class CompteRendu(Maraude):
proxy = True
class FoyerAccueil(Lieu):
""" Foyer d'hébergement partenaire """
@@ -264,7 +260,6 @@ class FoyerAccueil(Lieu):
)
class Planning(models.Model):
""" Plannification des maraudes. Chaque instance représente un jour de la
semaine et un horaire par défaut.
@@ -293,7 +288,6 @@ class Planning(models.Model):
""" Renvoie le jour et l'horaire prévu de maraude, comme un tuple,
pour l'année et le mois donnés.
"""
planning = Planning.get_planning()
for week in calendar.monthcalendar(year, month):
for planned in cls.get_planning():
day_of_maraude = week[planned.week_day]

View File

@@ -1,7 +1,6 @@
from django.db import models
from notes.models import Note
from . import managers
# Extends 'notes' module
@@ -9,7 +8,6 @@ from . import managers
class Observation(Note):
""" Note dans le cadre d'une rencontre """
objects = managers.ObservationManager()
rencontre = models.ForeignKey('maraudes.Rencontre',
models.CASCADE,
related_name="observations")
@@ -25,18 +23,24 @@ class Observation(Note):
def note_bg_colors(self): return "info", "info"
class Appel(Note):
entrant = models.BooleanField( "Appel entrant ?")
entrant = models.BooleanField("Appel entrant ?")
def note_labels(self): return ["Reçu" if self.entrant else "Émis", self.created_by]
def note_bg_colors(self): return "warning", "info"
def note_labels(self):
return ["Reçu" if self.entrant else "Émis", self.created_by]
def note_bg_colors(self):
return "warning", "info"
class Signalement(Note):
source = models.ForeignKey("utilisateurs.Organisme")
def note_labels(self): return [self.source, self.created_by]
def note_bg_colors(self): return 'danger', 'info'
def note_labels(self):
return [self.source, self.created_by]
def note_bg_colors(self):
return 'danger', 'info'

View File

@@ -1,12 +1,11 @@
import datetime
import random
from calendar import monthrange
from django.test import TestCase
from .models import (
Maraude, Maraudeur, Planning,
WEEKDAYS, HORAIRES_SOIREE,
HORAIRES_SOIREE,
)
@@ -14,6 +13,7 @@ MARAUDE_DAYS = [
True, True, False, True, True, False, False
]
def get_maraude_days(start, end):
""" Iterator that returns date of maraude within start-end range """
maraude_days = []
@@ -32,6 +32,7 @@ def get_maraude_days(start, end):
return maraude_days
class PlanningTestCase(TestCase):
def setUp(self):
@@ -50,9 +51,11 @@ class PlanningTestCase(TestCase):
def test_get_maraudes_days_for_month(self):
test_values = [
{'year': 2017, 'month': 2,
'test': [(day, HORAIRES_SOIREE) for day in (2,3,6,7,9,10,13,14,16,17,20,21,23,24,27,28)] },
'test': [(day, HORAIRES_SOIREE) for day in (2, 3, 6, 7, 9, 10, 13, 14, 16,
17, 20, 21, 23, 24, 27, 28)]},
{'year': 2016, 'month': 3,
'test': [(day, HORAIRES_SOIREE) for day in (1,3,4,7,8,10,11,14,15,17,18,21,22,24,25,28,29,31)] },
'test': [(day, HORAIRES_SOIREE) for day in (1, 3, 4, 7, 8, 10, 11, 14, 15,
17, 18, 21, 22, 24, 25, 28, 29, 31)]},
]
for test in test_values:
@@ -61,7 +64,9 @@ class PlanningTestCase(TestCase):
class MaraudeManagerTestCase(TestCase):
maraudeurs = [{"first_name": "Astérix", "last_name": "Le Gaulois"}, {"first_name": "Obélix", "last_name": "et Idéfix"}]
maraudeurs = [
{"first_name": "Astérix", "last_name": "Le Gaulois"},
{"first_name": "Obélix", "last_name": "et Idéfix"}]
def setUp(self):
first = True
@@ -78,14 +83,15 @@ class MaraudeManagerTestCase(TestCase):
self.past_dates = [self.today - datetime.timedelta(d) for d in (1, 3, 5)]
self.future_dates = [self.today + datetime.timedelta(d) for d in (2, 4, 6)]
for date in [self.today,] + self.past_dates + self.future_dates:
for date in [self.today, ] + self.past_dates + self.future_dates:
Maraude.objects.create(
date = date,
referent = self.referent,
binome = self.binome
date=date,
referent=self.referent,
binome=self.binome
)
def retrieve_date(self, maraude):
@staticmethod
def retrieve_date(maraude):
return maraude.date
def test_all_of(self):
@@ -99,12 +105,12 @@ class MaraudeManagerTestCase(TestCase):
def test_future_maraudes_no_args(self):
""" La liste des futures maraudes """
test_set = set(self.future_dates + [self.today,])
test_set = set(self.future_dates + [self.today, ])
check_set = set(map(self.retrieve_date, Maraude.objects.get_future()))
self.assertEqual(test_set, check_set)
def test_future_maraudes_are_sorted_by_date(self):
check_generator = iter(sorted(self.future_dates + [self.today,]))
check_generator = iter(sorted(self.future_dates + [self.today, ]))
for maraude in Maraude.objects.get_future():
self.assertEqual(maraude.date, next(check_generator))
@@ -128,7 +134,6 @@ class MaraudeManagerTestCase(TestCase):
self.assertEqual(self.retrieve_date(Maraude.objects.get_next_of(self.binome)), self.today)
class MaraudeTestCase(TestCase):
def test_est_terminee(self):

View File

@@ -1,22 +1,19 @@
import datetime
import calendar
import logging
from django.conf import settings
from django.utils import timezone
from django.shortcuts import redirect, reverse
from django.views import generic
from django.core.mail import send_mail
from django.forms import modelformset_factory
from django.contrib import messages
from utilisateurs.mixins import MaraudeurMixin
from .models import (Maraude, Maraudeur,
CompteRendu,
Rencontre, Lieu,
Lieu,
Planning,)
from .notes import Signalement
# Forms
from .forms import (RencontreForm,
ObservationInlineFormSet,
MaraudeHiddenDateForm, MonthSelectForm,
@@ -26,6 +23,9 @@ from notes.mixins import NoteFormMixin
logger = logging.getLogger(__name__)
# How many month shall we look back
NUMBER_OF_MONTH_BACKWARDS = 1 # Must be lower than 12 !
def derniers_sujets_rencontres():
""" Renvoie le 'set' des sujets rencontrés dans les deux dernières maraudes """
@@ -38,11 +38,8 @@ def derniers_sujets_rencontres():
def derniers_sujets_signales():
def recent_filter(qs):
NUMBER_OF_MONTH_BACKWARDS = 1 # Must be lower than 12 !
current_date = timezone.localtime(timezone.now()).date()
recent_dates = [(current_date.month, current_date.year)]
for i in range(1, NUMBER_OF_MONTH_BACKWARDS + 1):
prev_month, prev_year = current_date.month - i, current_date.year
if prev_month <= 0:
@@ -56,7 +53,6 @@ def derniers_sujets_signales():
filtered = []
for month, year in recent_dates:
filtered += list(qs.filter(created_date__year=year, created_date__month=month))
return filtered
return recent_filter(Signalement.objects.all())
@@ -66,7 +62,7 @@ class IndexView(NoteFormMixin, MaraudeurMixin, generic.TemplateView):
template_name = "maraudes/index.html"
#NoteFormMixin
# NoteFormMixin
forms = {
'appel': AppelForm,
'signalement': SignalementForm,
@@ -89,18 +85,19 @@ class IndexView(NoteFormMixin, MaraudeurMixin, generic.TemplateView):
if self.request.user.is_superuser:
context['missing_cr'] = CompteRendu.objects.get_queryset().filter(
heure_fin__isnull=True,
date__lt = timezone.localtime(timezone.now()).date()
date__lt=timezone.localtime(timezone.now()).date()
)
return context
## COMPTE-RENDU DE MARAUDE
# COMPTE-RENDU DE MARAUDE
def redirect_to_current_compterendu(request):
maraude_en_cours = Maraude.objects.get_in_progress()
if not maraude_en_cours:
messages.warning(request, "Il n'y a actuellement aucune maraude en cours !")
return redirect("maraudes:index")
kwargs = {'pk': maraude_en_cours.pk}
@@ -128,7 +125,7 @@ class CompteRenduCreateView(MaraudeurMixin, generic.DetailView):
instance=self.form.instance
)
def post(self, request, *args, **kwargs):
def post(self, request, **kwargs):
self.get_forms(request.POST, request.FILES)
if self.form.has_changed():
if not self.form.is_valid() or not self.inline_formset.is_valid():
@@ -145,8 +142,10 @@ class CompteRenduCreateView(MaraudeurMixin, generic.DetailView):
def calculate_end_time(debut, duree):
end_minute = debut.minute + duree
hour = debut.hour + end_minute // 60
if hour >= 24: hour -= 24
elif hour < 0: hour += 24
if hour >= 24:
hour -= 24
elif hour < 0:
hour += 24
minute = end_minute % 60
return datetime.time(
hour,
@@ -179,8 +178,7 @@ class CompteRenduCreateView(MaraudeurMixin, generic.DetailView):
return context
class FinalizeView( MaraudeurMixin,
class FinalizeView(MaraudeurMixin,
generic.detail.SingleObjectMixin,
generic.edit.FormView):
@@ -190,8 +188,7 @@ class FinalizeView( MaraudeurMixin,
success_url = "/maraudes/"
def get(self, *args, **kwargs):
print(self.request.GET)
if bool(self.request.GET.get("no_mail", False)) == True:
if bool(self.request.GET.get("no_mail", False)):
messages.warning(self.request, "Aucun compte-rendu n'a été envoyé !")
return self.finalize()
return super().get(*args, **kwargs)
@@ -232,23 +229,25 @@ class FinalizeView( MaraudeurMixin,
)
if result == 1:
if settings.DEBUG:
messages.warning(self.request, "En mode DEBUG, le compte-rendu n'est pas réellement envoyé !")
else:
messages.success(self.request, "Le compte-rendu a été transmis à %s" % ", ".join(map(str, recipients)))
else:
messages.error(self.request, "Erreur lors de l'envoi du message !")
return self.finalize()
def get_context_data(self, **kwargs):
self.object = self.get_object()
obj = self.get_object()
context = super().get_context_data(**kwargs)
if self.object.est_terminee is True:
context['form'] = None#Useless form
if obj.est_terminee is True:
context['form'] = None # Useless form
return context
# Link there so that "Compte-rendu" menu item is not disabled
context['prochaine_maraude'] = self.object
context['prochaine_maraude'] = obj
return context
class PlanningView(MaraudeurMixin, generic.TemplateView):
""" Vue d'édition du planning des maraudes """
@@ -256,10 +255,14 @@ class PlanningView(MaraudeurMixin, generic.TemplateView):
def _parse_request(self):
self.current_date = datetime.date.today()
try: self.month = int(self.request.GET['month'])
except: self.month = self.current_date.month
try: self.year = int(self.request.GET['year'])
except: self.year = self.current_date.year
try:
self.month = int(self.request.GET['month'])
except ValueError:
self.month = self.current_date.month
try:
self.year = int(self.request.GET['year'])
except ValueError:
self.year = self.current_date.year
def _calculate_initials(self):
self._parse_request()
@@ -267,7 +270,7 @@ class PlanningView(MaraudeurMixin, generic.TemplateView):
for day, time in Planning.get_maraudes_days_for_month(self.year, self.month):
date = datetime.date(self.year, self.month, day)
try:
maraude = Maraude.objects.get(date=date)
Maraude.objects.get(date=date)
except Maraude.DoesNotExist:
self.initials.append({
'date': date,
@@ -284,26 +287,26 @@ class PlanningView(MaraudeurMixin, generic.TemplateView):
self._calculate_initials()
return modelformset_factory(
Maraude,
form = MaraudeHiddenDateForm,
extra = len(self.initials),
form=MaraudeHiddenDateForm,
extra=len(self.initials),
)(
*args,
queryset = self.get_queryset(),
initial = self.initials
queryset=self.get_queryset(),
initial=self.initials
)
def post(self, request):
self.formset = self.get_formset(request.POST, request.FILES)
for form in self.formset.forms:
formset = self.get_formset(request.POST, request.FILES)
for form in formset.forms:
if form.is_valid():
form.save()
else:
logger.info("Form was ignored ! (%s)" % (form.errors.as_data()))
return redirect('maraudes:planning')
def get(self, request):
def get(self, request, *args, **kwargs):
self.formset = self.get_formset()
return super().get(request)
return super().get(request, *args, **kwargs)
def get_weeks(self):
""" List of (day, form) tuples, split by weeks """
@@ -330,8 +333,8 @@ class PlanningView(MaraudeurMixin, generic.TemplateView):
for week in calendar.monthcalendar(self.year, self.month)
]
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['weekdays'] = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"]
context['weeks'] = self.get_weeks()
@@ -341,7 +344,6 @@ class PlanningView(MaraudeurMixin, generic.TemplateView):
return context
class LieuCreateView(generic.edit.CreateView):
""" Vue de création d'un lieu """
@@ -359,6 +361,6 @@ class LieuCreateView(generic.edit.CreateView):
context = super().get_context_data(**kwargs)
try:
context['next'] = self.request.GET['next']
except:
except KeyError:
context['next'] = None
return context