This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
biomon/src/biomon/views.py

295 lines
10 KiB
Python

# -*- coding: utf-8 -*-
'''
biomon - Signs monitoring and patient management application
Copyright (C) 2015 Entr'ouvert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import requests
from datetime import datetime
from django.views.generic import (TemplateView, FormView, View, ListView,
CreateView, UpdateView, DeleteView)
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth import forms as auth_forms
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse_lazy
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from . import cbv
from . import models
from . import forms
from . import whisper_backend
from . import time_utils
from medibot import models as medibot_models
LAST_PATIENT_COOKIE = 'last-patient'
class HomepageView(TemplateView):
template_name="biomon/homepage.html"
class LoginView(FormView):
form_class = auth_forms.AuthenticationForm
template_name = 'biomon/login.html'
def form_valid(self, form):
username = self.request.POST.get('username')
password = self.request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(self.request, user)
return super(LoginView, self).form_valid(form)
def get_success_url(self):
next_url = self.request.POST.get('next', None)
if next_url:
return "%s" % (next_url)
return reverse_lazy('patient_list')
class LogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
return HttpResponseRedirect(reverse_lazy('login'))
class PatientList(ListView):
model = models.Patient
def get_queryset(self):
return models.Patient.objects.order_by('display_name')
def get_context_data(self, **kwargs):
context = super(PatientList, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class PatientCreate(CreateView):
model = models.Patient
fields = ['firstname', 'lastname', 'sex', 'birthdate', 'monitoring_place',
'room', 'emergency_contact', 'regular_doctor', 'medical_comment',
'enabled']
def form_valid(self, form):
messages.add_message(self.request, messages.INFO, u'Patient créé.')
return super(PatientCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(PatientCreate, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class PatientUpdate(UpdateView):
model = models.Patient
fields = ['firstname', 'lastname', 'sex', 'birthdate', 'monitoring_place',
'room', 'emergency_contact', 'regular_doctor', 'medical_comment']
class PatientDetail(cbv.MultiUpdateView):
model = models.Patient
forms_classes = {
'main': forms.MainForm,
'simple_alert_profile' : forms.SimpleAlertProfileForm,
't_check' : forms.TemperatureCheckForm,
'hr_check' : forms.HeartrateCheckForm,
}
template_name = "biomon/patient_detail.html"
success_url = '.'
def dispatch(self, *args, **kwargs):
result = super(PatientDetail, self).dispatch(*args, **kwargs)
result.set_cookie(LAST_PATIENT_COOKIE, str(self.object.pk),
max_age=3600*24*365, httponly=True)
return result
def form_valid(self, form):
if 't_check' in form and form.get('t_check').is_valid():
form.get('t_check').cleaned_data['patient'] = self.get_object()
tc = models.TemperatureCheck(**form.get('t_check').cleaned_data)
tc.save()
if 'hr_check' in form and form.get('hr_check').is_valid():
form.get('hr_check').cleaned_data['patient'] = self.get_object()
hrc = models.HeartrateCheck(**form.get('hr_check').cleaned_data)
hrc.save()
messages.add_message(self.request, messages.INFO,
_(u'Patient record updated.'))
return super(PatientDetail, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(PatientDetail, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
def process(subject, metric, values, lookup_range=600):
backend = whisper_backend.WhisperBackend(subject, metric)
l = []
for value in values:
timestamp = time_utils.unix_time(datetime.combine(value.date, value.time))
l.append((value, backend.get_closest(timestamp=timestamp, lookup_range=lookup_range)))
return l
subject = str(self.get_object().id)
metric = settings.WHISPER_HEARTRATE_METRIC
values = models.HeartrateCheck.objects.filter(patient=self.get_object()).order_by('-date').order_by('-time')
context['hr_checks'] = process(subject, metric, values)
metric = settings.WHISPER_TEMPERATURE_METRIC
values = models.TemperatureCheck.objects.filter(patient=self.get_object()).order_by('-date').order_by('-time')
context['t_checks'] = process(subject, metric, values)
context['display_alert_profile'] = settings.DISPLAY_ALERT_PROFILE
context['default_episode_duration'] = settings.DEFAULT_EPISODE_DURATION
return context
class PatientDelete(DeleteView):
model = models.Patient
success_url = reverse_lazy('patient_list')
class PatientUpdateEnabledField(cbv.AjaxableResponseMixin, UpdateView):
model = models.Patient
fields = ['enabled']
class AlertCheckView(cbv.AjaxableResponseMixin, UpdateView):
model = medibot_models.Episode
fields = ['checked']
success_url = '.'
def form_valid(self, form):
form.instance.checker = self.request.user
return super(AlertCheckView, self).form_valid(form)
class AllAlertCheckPatientView(View):
def post(self, request, *args, **kwargs):
patient = None
#XXX list exceptions or don't catch, it is better to crash
try:
patient = models.Patient.objects.get(id=self.kwargs.get('pk', None))
except:
return JsonResponse({'message': 'patient not found',})
medibot_models.Episode.objects.filter(patient=patient).update(checked=True, checker=request.user)
return JsonResponse({'message': 'ok',})
class AllAlertsView(TemplateView):
template_name="biomon/alerts.html"
def get_context_data(self, **kwargs):
context = super(AllAlertsView, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class AllAlertsCheckView(View):
def post(self, request, *args, **kwargs):
medibot_models.Episode.objects.all().update(checked=True, checker=request.user)
return JsonResponse({'message': 'ok',})
class RoomList(ListView):
model = models.Room
def get_context_data(self, **kwargs):
context = super(RoomList, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class RoomCreate(CreateView):
model = models.Room
success_url = reverse_lazy('room_list')
fields = ['number']
def get_context_data(self, **kwargs):
context = super(RoomCreate, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class RoomUpdate(UpdateView):
model = models.Room
success_url = reverse_lazy('room_list')
fields = ['number']
def get_context_data(self, **kwargs):
context = super(RoomUpdate, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class RoomDelete(DeleteView):
model = models.Room
success_url = reverse_lazy('room_list')
def get_context_data(self, **kwargs):
context = super(RoomDelete, self).get_context_data(**kwargs)
try:
context['lastpatient'] = models.Patient.objects.get(
pk=int(self.request.COOKIES.get(LAST_PATIENT_COOKIE)))
except:
pass
return context
class RoomNumberToPid(View):
def get(self, request, *args, **kwargs):
room = get_object_or_404(models.Room,
number=kwargs.get('number', None))
infos = {'pid' : ''}
try:
infos = {'pid' : room.patient.id}
except models.Patient.DoesNotExist:
pass
return JsonResponse(infos)