Source code for events.views.mkedrm

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.forms.models import inlineformset_factory
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls.base import reverse

from accounts.models import UserPreferences
from emails.generators import EventEmailGenerator
from slack.views import event_edited_notification
from slack.api import slack_post, lookup_user
from events.forms import InternalEventForm, InternalEventForm2019, ServiceInstanceForm
from events.models import BaseEvent, Event2019, ServiceInstance
from helpers.revision import set_revision_comment
from helpers.util import curry_class

import requests, json


[docs]@login_required def eventnew(request, id=None): """ Create or edit an event :param id: Defaults to None (create a new event). Otherwise, this is the primary key value of the event you intend \ to edit """ context = {} # get instance if id is passed in if id: instance = get_object_or_404(BaseEvent, pk=id) context['new'] = False perms = ['events.view_events'] if not (request.user.has_perms(perms) or request.user.has_perms(perms, instance)): raise PermissionDenied is_event2019 = isinstance(instance, Event2019) else: instance = None context['new'] = True is_event2019 = True perms = ['events.add_raw_event'] if not request.user.has_perms(perms): raise PermissionDenied if is_event2019: mk_serviceinstance_formset = inlineformset_factory(BaseEvent, ServiceInstance, extra=3, exclude=[]) mk_serviceinstance_formset.form = curry_class(ServiceInstanceForm, event=instance) context['is_event2019'] = is_event2019 if request.method == 'POST': if instance: # calculate whether an email should be sent based on the event information *before* saving the form. should_send_notification = not instance.test_event if should_send_notification: bcc = [settings.EMAIL_TARGET_VP_DB] if instance.has_projection: bcc.append(settings.EMAIL_TARGET_HP) if is_event2019: if instance: form = InternalEventForm2019(data=request.POST, request_user=request.user, instance=instance) else: form = InternalEventForm2019(data=request.POST, request_user=request.user) else: form = InternalEventForm(data=request.POST, request_user=request.user, instance=instance) if is_event2019: services_formset = mk_serviceinstance_formset(request.POST, request.FILES, instance=instance) if form.is_valid() and (not is_event2019 or services_formset.is_valid()): if instance: set_revision_comment('Edited', form) obj = form.save() # 25Live parsing if is_event2019 and obj.event_id is None: if form.data.get('reference_code') != "": try: url = requests.get(f"https://25live.collegenet.com/25live/data/wpi/run/list/listdata.json?compsubject=event&obj_cache_accl=0&name={form.data.get('reference_code')}") text = url.text jsondata = json.loads(text) obj.event_id = jsondata["rows"][0]["contextId"] obj.save() except requests.JSONDecodeError: pass if is_event2019: services_formset.save() if should_send_notification: # BCC the crew chiefs for ccinstance in obj.ccinstances.all(): methods = clear_to_send(ccinstance.crew_chief, request.user, form.changed_data) if ccinstance.crew_chief.email and 'email' in methods: bcc.append(ccinstance.crew_chief.email) if 'slack' in methods: blocks = event_edited_notification(obj, request.user, form.changed_data) slack_user = lookup_user(ccinstance.crew_chief.email) if slack_user: slack_post(slack_user, text="%s was just edited" % obj.event_name, content=blocks) if obj.reviewed: subject = "Reviewed Event Edited" email_body = "The following event was edited by %s after the event was reviewed for billing." \ % request.user.get_full_name() bcc.append(settings.EMAIL_TARGET_T) elif obj.approved: subject = "Approved Event Edited" email_body = "The following event was edited by %s after the event was approved." % \ request.user.get_full_name() else: subject = "Event Edited" email_body = "The following event was edited by %s." % request.user.get_full_name() # Add list of changed fields to the email if len(form.changed_data) > 0: email_body += "\nFields changed: " for field_name in form.changed_data: email_body += field_name + ", " email_body = email_body[:-2] # add HP to the email if projection was just added to the event if obj.has_projection and settings.EMAIL_TARGET_HP not in bcc: bcc.append(settings.EMAIL_TARGET_HP) to_emails = [] if request.user.email and 'email' in clear_to_send(request.user, request.user, form.changed_data): to_emails.append(request.user.email) email = EventEmailGenerator(event=obj, subject=subject, to_emails=to_emails, body=email_body, bcc=bcc) email.send() else: set_revision_comment('Created event', None) obj = form.save(commit=False) obj.submitted_by = request.user obj.submitted_ip = request.META.get('REMOTE_ADDR') obj.save() form.save_m2m() if is_event2019: mk_serviceinstance_formset.form = curry_class(ServiceInstanceForm, event=obj) services_formset = mk_serviceinstance_formset(request.POST, request.FILES, instance=instance) services_formset.is_valid() services_formset.save() return HttpResponseRedirect(reverse('events:detail', args=(obj.id,))) else: context['e'] = form.errors context['form'] = form if is_event2019 and not services_formset.is_valid(): messages.add_message(request, messages.ERROR, "Whoops! There was an error updating the services " "for this event.") if is_event2019: context['services_formset'] = services_formset else: if is_event2019: context['form'] = InternalEventForm2019(request_user=request.user, instance=instance) context['services_formset'] = mk_serviceinstance_formset(instance=instance) else: context['form'] = InternalEventForm(request_user=request.user, instance=instance) if instance: context['msg'] = "Edit Event" else: context['msg'] = "New Event" return render(request, 'form_crispy_event.html', context)
[docs]def clear_to_send(to, triggered_by, fields_edited): """ Helper function to determine if a user should receive an Event Edited notification :param to: The user the message would be sent to :param triggered_by: The user that edited the event :param fields_edited: A list of edited fields :returns: A list of approved communication methods """ prefs, created = UserPreferences.objects.get_or_create(user=to) if to == triggered_by and prefs.ignore_user_action: return [] subscribed = False for field in fields_edited: if field in prefs.event_edited_field_subscriptions: subscribed = True methods = [] if subscribed and prefs.event_edited_notification_methods in ['email', 'all']: methods.append('email') if subscribed and prefs.event_edited_notification_methods in ['slack', 'all']: methods.append('slack') return methods