from datetime import date from smtplib import SMTPException from django.shortcuts import render from django.forms import modelformset_factory from django.http import HttpResponse from formtools.wizard.views import CookieWizardView from django.core.mail import send_mail, BadHeaderError from django.conf import settings from django.template.loader import get_template from django.template import Context from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.html import format_html from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\ HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ ListForm, BusinessCardForm, INTERN_CHOICES from .models import Project, TYPE_CHOICES, Library, Literature from .settings import IF_EMAIL def auth_deny(choice,pk,auth): if choice in ('BIB', 'ELIT', 'SOFT'): Library.set_granted(pk,auth) if choice == 'LIT': Literature.set_granted(pk,auth) if choice == 'IFG': IFG.set_granted(pk,auth) else: return HttpResponse(f'ERROR! UNKNWON CHOICE TYPE! {choice}') return False @login_required def authorize(request, choice, pk): '''If IF grant a support they click a link in a mail which leads here. We write the granted field in the database here and set a timestamp.''' ret = auth_deny(choice, pk, True) if ret: return ret else: return HttpResponse(f"AUTHORIZED! choice: {choice}, pk: {pk}") @login_required def deny(request, choice, pk): '''If IF denies a support they click a link in a mail which leads here We write the granted field in the database here.''' ret = auth_deny(choice, pk, False) if ret: return ret else: return HttpResponse(f"DENIED! choice: {choice}, pk: {pk}") def done(request): return HttpResponse("Your data is save now.") class InternView(LoginRequiredMixin, CookieWizardView): '''This View is for WMDE-employees only''' template_name = 'input/extern.html' form_list = [InternForm, ProjectForm] def get_form(self, step=None, data=None, files=None): '''this function determines which part of the multipart form is displayed next''' if step is None: step = self.steps.current print ("get_form() step " + step) if step == '1': prev_data = self.get_cleaned_data_for_step('0') choice = prev_data.get('choice') print(f'choice detection: {INTERN_CHOICES[choice]}') if choice == 'HON': form = HonoraryCertificateForm(data) elif choice == 'PRO': form = ProjectForm(data) elif choice == 'TRAV': form = TravelForm(data) else: raise RuntimeError(f'ERROR! UNKNOWN FORMTYPE {choice} in InternView') else: form = super().get_form(step, data, files) return form def done(self, form_list, **kwargs): print('InternView.done() reached') # gather data from all forms data = {} for form in form_list: data = {**data, **form.cleaned_data} print(data) # write data to database form = form.save(commit=False) # we have to copy the data from the first form here # this is ugly code. how can we copy this without explicit writing? # i found no way to access the ModelForm.Meta.exclude-tupel form.realname = data['realname'] # form.username = data['username'] form.email = data['email'] form.granted = True form.granted_date = date.today() form.save() return done(self.request) # these where used as labels in the second form TYPE_CHOICES is used for the first form and the # text above the second form. only used for BIB, SOFT, ELIT in the moment LABEL_CHOICES = {'BIB': format_html('Bibliothek'), 'ELIT': format_html('Datenbank/Online-Ressource'), 'MAIL': format_html('E-Mail-Adresse'), 'IFG': format_html('Kostenübernahme IFG-Anfrage'), 'LIT': format_html('Literaturstipendium'), 'LIST': format_html('Mailingliste'), 'SOFT': format_html('Software'), 'VIS': format_html('Visitenkarten'), } class ExternView(CookieWizardView): '''This View is for Volunteers''' template_name = "input/extern.html" form_list = [ExternForm, LibraryForm] def get_form(self, step=None, data=None, files=None): '''this function determines which part of the multipart form is displayed next''' if step is None: step = self.steps.current print ("get_form() step " + step) if step == '1': prev_data = self.get_cleaned_data_for_step('0') choice = prev_data.get('choice') print(f'choice detection in ExternView: {TYPE_CHOICES[choice]}') if choice == 'IFG': form = IFGForm(data) elif choice in ('BIB', 'SOFT', 'ELIT'): form = LibraryForm(data) form.fields['library'].label = LABEL_CHOICES[choice] elif choice == 'MAIL': form = EmailForm(data) elif choice == 'LIT': form = LiteratureForm(data) elif choice == 'VIS': form = BusinessCardForm(data) elif choice == 'LIST': form = ListForm(data) else: raise RuntimeError(f'ERROR! UNKNOWN FORMTYPE {choice} in ExternView') self.choice = choice else: form = super().get_form(step, data, files) return form def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) if hasattr(self, 'choice'): context["choice"] = TYPE_CHOICES[self.choice] return context def done(self, form_list, **kwargs): print('ExternView.done() reached') # gather data from all forms data = {} for form in form_list: data = {**data, **form.cleaned_data} print(data) # write data to database modell = form.save(commit=False) # we have to copy the data from the first form here # this is a bit ugly code. can we copy this without explicit writing? modell.realname = data['realname'] # form.username = data['username'] modell.email = data['email'] # write type of form in some cases if data['choice'] in ('BIB', 'ELIT', 'SOFT'): modell.type = data['choice'] form.save() # add some data to context for mail templates data['pk'] = modell.pk data['urlprefix'] = settings.URLPREFIX data['grant'] = ('LIT', 'SOFT', 'ELIT', 'BIB', 'IFG') data['DOMAIN'] = ('MAIL', 'LIST') data['typestring'] = TYPE_CHOICES[data['choice']] # we need to send the following mails here: context = { 'data': data } try: # - mail with entered data to the Volunteer mail_template = get_template('input/ifg_volunteer_mail.txt') send_mail( 'Formular ausgefüllt', mail_template.render(context), IF_EMAIL, [data['email']], fail_silently=False) # - mail to IF with link to accept/decline mail_template = get_template('input/if_mail.txt') send_mail( 'Formular ausgefüllt', mail_template.render(context), IF_EMAIL, [IF_EMAIL], fail_silently=False) # raise SMTPException("testing pupose only") except BadHeaderError: modell.delete() return HttpResponse('Invalid header found. Data not saved!') except SMTPException: modell.delete() return HttpResponse('Error in sending mails (propably wrong adress?). Data not saved!') return done(self.request)