from datetime import timedelta from django.contrib.auth import update_session_auth_hash from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.views import PasswordChangeView from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse_lazy from web.models import Event, Availability @login_required() def index(request): parsed_events = [] for active_event in Event.objects.filter(active=True).order_by('start_date'): data = { 'id': active_event.id, 'name': active_event.name, 'start_date': active_event.start_date.date(), 'end_date': active_event.end_date.date(), 'responses': ', '.join([x.user.username for x in active_event.availability_set.all()]) } parsed_events.append(data) context = { 'events': parsed_events } return render(request, "index.html", context) def change_password(request): if request.method == 'POST': form = PasswordChangeForm(request.user, request.POST) if form.is_valid(): user = form.save() update_session_auth_hash(request, user) return redirect('password_change_done') else: form = PasswordChangeForm(request.user) return render(request, 'change-password/change_password.html', {'form': form}) def password_change_done(request): return render(request, 'change-password/password_change_done.html') @login_required() def event(request, event_id): event = get_object_or_404(Event, pk=event_id) if request.method == 'POST': handle_availability_update(event, request) return redirect('event', event_id=event_id) elif request.method == 'GET': day_count = (event.end_date - event.start_date).days + 1 morning = {} noon = {} night = {} all_availabilities = {} requesting_user_submitted = False context = { 'event': event, 'morning': morning, 'noon': noon, 'night': night, 'user_availability': None, 'active_dates': None, 'user_responses': 0, 'best_days': {}, 'no_overlap_message': '' } user_availability = Availability.objects.filter(event_id=event) if user_availability: for user_avail in user_availability: context['user_responses'] += 1 for time in user_avail.time_table.get('active', []): if time not in all_availabilities: all_availabilities[time] = [] all_availabilities[time].append(user_avail.user.username) if request.user == user_avail.user: requesting_user_submitted = True context['active_dates'] = user_avail.time_table['active'] context['all_availabilities'] = all_availabilities for i in range(day_count): date = event.start_date + timedelta(days=i) human_readable_date = date.strftime('%m/%d/%Y %A') for idx, time_period_array in enumerate([morning, noon, night]): date_id = date.strftime(f'%m/%d/%Y %A-{idx}') users = ', '.join(all_availabilities.get(date_id, [])) if not requesting_user_submitted: users = '' time_period_array[human_readable_date] = (date_id, users) if all_availabilities: most_avail = None for day in sorted(all_availabilities, key=lambda k: len(all_availabilities[k]), reverse=True): if not most_avail: most_avail = len(all_availabilities[day]) if len(all_availabilities[day]) >= most_avail - 1 and len(all_availabilities[day]) != 1: day_arr = day.split('-') if day_arr[-1] == '0': hday = day_arr[0] + ' Morning' if day_arr[-1] == '1': hday = day_arr[0] + ' Noon' if day_arr[-1] == '2': hday = day_arr[0] + ' Night' context['best_days'][hday] = ', '.join(all_availabilities[day]) if not requesting_user_submitted: all_availabilities = {} if context['best_days'] == {}: context['no_overlap_message'] = 'There are currently no overlapping times or dates!' return render(request, "event.html", context) def handle_availability_update(event, request): availability_data = { 'active': [] } for date, value in request.POST.items(): if date != 'csrfmiddlewaretoken': availability_data['active'].append(date) user_availability = Availability.objects.filter(event_id=event).filter(user=request.user) if not user_availability: a = Availability( event_id=event, user=request.user, time_table=availability_data ) a.save() else: avail = user_availability[0] avail.time_table = availability_data avail.save()