from django.shortcuts import render, get_object_or_404, HttpResponseRedirect from django.contrib import messages from django.contrib.auth.decorators import login_required from django.urls import reverse from django.db.models import Q from courselib.auth import get_person, HttpError from coredata.models import Role from log.models import LogEntry from .models import Reminder, ReminderMessage, MESSAGE_EARLY_CREATION, HISTORY_RETENTION from .forms import ReminderForm import operator from functools import reduce @login_required def index(request): person = get_person(request.user) # PERS, INST reminders for this person personal_reminders = Reminder.objects.filter(reminder_type__in=['PERS','INST'], person=person).select_related('course') # ROLE reminders for this person's current roles user_roles = Role.objects_fresh.filter(person=person) role_query = reduce( operator.or_, (Q(role=r.role) & Q(unit=r.unit) for r in user_roles) ) role_reminders = Reminder.objects.filter(role_query, reminder_type='ROLE').select_related('unit') reminders = set(personal_reminders) | set(role_reminders) context = { 'reminders': reminders, } return render(request, 'reminders/index.html', context) @login_required def create(request): person = get_person(request.user) if request.method == 'POST': form = ReminderForm(data=request.POST, person=person) if form.is_valid(): reminder = form.save(commit=False) reminder.person = person reminder.save() l = LogEntry(userid=request.user.username, description="created reminder %s" % (reminder.slug,), related_object=reminder ) l.save() messages.add_message(request, messages.SUCCESS, 'Reminder created.') return HttpResponseRedirect(reverse('reminders:view', kwargs={'reminder_slug': reminder.slug})) else: form = ReminderForm(person=person) context = { 'form': form, } return render(request, 'reminders/create.html', context) def _get_reminder_or_404(request, reminder_slug): """ Get the reminder *if* the logged-in user is allowed to view/edit it. Else raise 404. """ reminder = get_object_or_404(Reminder, slug=reminder_slug) person = get_person(request.user) if not reminder.can_be_accessed_by(person): get_object_or_404(Reminder, reminder_type='FOO', person=None) # make error same as above raise ValueError() # shouldn't happen, but definitely don't continue error-free from here. return reminder, person @login_required def view(request, reminder_slug): reminder, _ = _get_reminder_or_404(request, reminder_slug) messages = ReminderMessage.objects.filter(reminder=reminder).select_related('person') future_messages = messages.filter(sent=False).order_by('date', 'person') sent_messages = messages.filter(sent=True).order_by('sent_at', 'person') context = { 'reminder': reminder, 'future_messages': future_messages, 'sent_messages': sent_messages, 'future_days': MESSAGE_EARLY_CREATION, 'sent_days': HISTORY_RETENTION, } return render(request, 'reminders/view.html', context) @login_required def edit(request, reminder_slug): reminder, person = _get_reminder_or_404(request, reminder_slug) if request.method == 'POST': form = ReminderForm(instance=reminder, data=request.POST, person=person) if form.is_valid(): reminder = form.save(commit=False) reminder.person = person reminder.save() l = LogEntry(userid=request.user.username, description="edited reminder %s" % (reminder.slug,), related_object=reminder ) l.save() messages.add_message(request, messages.SUCCESS, 'Reminder updated.') return HttpResponseRedirect(reverse('reminders:view', kwargs={'reminder_slug': reminder.slug})) else: form = ReminderForm(instance=reminder, person=person) context = { 'form': form, 'reminder': reminder, } return render(request, 'reminders/edit.html', context) @login_required def delete(request, reminder_slug): if request.method != 'POST': return HttpError(request, status=405, title="Method not allowed", error="This URL accepts only POST requests", errormsg=None) reminder, person = _get_reminder_or_404(request, reminder_slug) reminder.person = person reminder.status = 'D' reminder.save() l = LogEntry(userid=request.user.username, description="deleted reminder %s" % (reminder.slug,), related_object=reminder ) l.save() messages.add_message(request, messages.SUCCESS, 'Reminder deleted.') return HttpResponseRedirect(reverse('reminders:index', kwargs={}))