forked from beba/foerderbarometer
256 lines
7.8 KiB
Python
Executable File
256 lines
7.8 KiB
Python
Executable File
from smtplib import SMTPException
|
|
|
|
from django.shortcuts import render
|
|
from django.http import HttpResponse
|
|
from django.utils.safestring import mark_safe
|
|
from formtools.wizard.views import CookieWizardView
|
|
from django.core.mail import BadHeaderError, EmailMultiAlternatives
|
|
from django.template.loader import get_template
|
|
from django.conf import settings
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.views.generic.edit import FormView
|
|
|
|
from .forms import (
|
|
ExternForm,
|
|
LibraryForm,
|
|
ELiteratureForm,
|
|
SoftwareForm,
|
|
IFGForm,
|
|
LiteratureForm,
|
|
TravelForm,
|
|
EmailForm,
|
|
ListForm,
|
|
BusinessCardForm,
|
|
)
|
|
from .models import TYPE_CHOICES, MODELS, TYPE_BIB, TYPE_ELIT, TYPE_SOFT
|
|
|
|
LIBRARY_FORMS = {
|
|
TYPE_BIB: LibraryForm,
|
|
TYPE_ELIT: ELiteratureForm,
|
|
TYPE_SOFT: SoftwareForm,
|
|
}
|
|
|
|
HELP_TEXTS = {
|
|
'IFG': {
|
|
'notes': (
|
|
'Bitte gib an, wie die gewonnenen Informationen den<br>'
|
|
'Wikimedia-Projekten zugute kommen sollen.'
|
|
)
|
|
},
|
|
'MAIL': {
|
|
'domain': (
|
|
'Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>'
|
|
'möchtest du eine Mailadresse beantragen?'
|
|
)
|
|
},
|
|
'LIT': {
|
|
'notes': 'Bitte gib an, wofür du die Literatur verwenden möchtest.'
|
|
},
|
|
'LIST': {
|
|
'domain': (
|
|
'Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>'
|
|
'möchtest du eine Mailingliste beantragen?'
|
|
)
|
|
},
|
|
}
|
|
|
|
|
|
def auth_deny(choice, pk, auth):
|
|
if choice not in MODELS:
|
|
return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}')
|
|
|
|
MODELS[choice].set_granted(pk, auth)
|
|
|
|
|
|
@login_required
|
|
def export(request):
|
|
'''export the project database to a csv'''
|
|
return HttpResponse('WE WANT CSV!')
|
|
|
|
|
|
@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.'''
|
|
|
|
if ret := auth_deny(choice, pk, True):
|
|
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.'''
|
|
|
|
if ret := auth_deny(choice, pk, False):
|
|
return ret
|
|
else:
|
|
return HttpResponse(f'DENIED! choice: {choice}, pk: {pk}')
|
|
|
|
|
|
def done(request):
|
|
return HttpResponse(
|
|
'Deine Anfrage wurde gesendet. Du erhältst in Kürze eine E-Mail-Benachrichtigung mit deinen Angaben. Für alle Fragen kontaktiere bitte das Team Communitys und Engagement unter community@wikimedia.de.')
|
|
|
|
|
|
def index(request):
|
|
return render(request, 'input/index.html')
|
|
|
|
|
|
class BaseApplicationView(FormView):
|
|
"""
|
|
Base view for all application types.
|
|
|
|
- Each application type (travel, literature, email, etc.) gets its own subclass.
|
|
- Renders the generic form template.
|
|
- Handles saving the submitted form to the database.
|
|
- Adds extra fields from the session or request type if needed.
|
|
- Applies optional help_text overrides for certain fields.
|
|
- Sends confirmation mail to the applicant.
|
|
- Sends notification mail to the internal IF address.
|
|
- Returns the "done" response after successful processing.
|
|
"""
|
|
template_name = 'input/forms/form_generic.html'
|
|
type_code: str = ''
|
|
|
|
def get_context_data(self, **kwargs):
|
|
"""Add the human-readable type string (from TYPE_CHOICES) to the template context."""
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx['typestring'] = TYPE_CHOICES.get(self.type_code, self.type_code)
|
|
return ctx
|
|
|
|
def get_form(self, form_class=None):
|
|
"""Return the form instance and inject custom help_texts if defined for this type."""
|
|
form = super().get_form(form_class)
|
|
|
|
# Apply help_text overrides if defined for this type_code
|
|
if self.type_code in HELP_TEXTS:
|
|
for field, text in HELP_TEXTS[self.type_code].items():
|
|
if field in form.fields:
|
|
form.fields[field].help_text = mark_safe(text)
|
|
|
|
return form
|
|
|
|
def form_valid(self, form):
|
|
"""
|
|
Process a valid form submission:
|
|
- Enrich form data (e.g., set type_code, handle special rules).
|
|
- Save the model instance and related data.
|
|
- Send confirmation and notification mails.
|
|
- Return the "done" response.
|
|
"""
|
|
|
|
# Collect cleaned data and mark the current type
|
|
data = form.cleaned_data.copy()
|
|
data['choice'] = self.type_code
|
|
|
|
# Special rule for literature applications
|
|
if self.type_code == 'LIT' and data.get('selfbuy') == 'TRUE':
|
|
data['selfbuy_give_data'] = 'False'
|
|
|
|
# Save model instance
|
|
modell = form.save(commit=False)
|
|
|
|
# Username from session if present
|
|
if user := self.request.session.get('user'):
|
|
modell.username = user.get('username')
|
|
|
|
# Copy common fields if provided by the form
|
|
if 'realname' in data:
|
|
modell.realname = data['realname']
|
|
if 'email' in data:
|
|
modell.email = data['email']
|
|
|
|
# Set model.type for specific request types
|
|
if self.type_code in ('BIB', 'ELIT', 'SOFT'):
|
|
modell.type = self.type_code
|
|
|
|
# Literature-specific extra field
|
|
if self.type_code == 'LIT' and 'selfbuy_give_data' in data:
|
|
modell.selfbuy_give_data = data['selfbuy_give_data']
|
|
|
|
modell.save()
|
|
if hasattr(form, 'save_m2m'):
|
|
form.save_m2m()
|
|
|
|
# Prepare minimal mail context and send mails
|
|
data['pk'] = modell.pk
|
|
data['url_prefix'] = settings.EMAIL_URL_PREFIX
|
|
data['typestring'] = TYPE_CHOICES.get(self.type_code, self.type_code)
|
|
context = {'data': data}
|
|
|
|
try:
|
|
# Mail to applicant
|
|
txt1 = get_template('input/ifg_volunteer_mail.txt').render(context)
|
|
html1 = get_template('input/ifg_volunteer_mail.html').render(context)
|
|
msg1 = EmailMultiAlternatives(
|
|
'Formular ausgefüllt', txt1, settings.IF_EMAIL, [data['email']]
|
|
)
|
|
msg1.attach_alternative(html1, 'text/html')
|
|
msg1.send()
|
|
|
|
# Mail to IF
|
|
txt2 = get_template('input/if_mail.txt').render(context)
|
|
html2 = get_template('input/if_mail.html').render(context)
|
|
msg2 = EmailMultiAlternatives(
|
|
'Formular ausgefüllt', txt2, settings.IF_EMAIL, [settings.IF_EMAIL]
|
|
)
|
|
msg2.attach_alternative(html2, 'text/html')
|
|
msg2.send()
|
|
|
|
except BadHeaderError:
|
|
modell.delete()
|
|
return HttpResponse('Invalid header found. Data not saved!')
|
|
except SMTPException:
|
|
modell.delete()
|
|
return HttpResponse('Error in sending mails (probably wrong adress?). Data not saved!')
|
|
|
|
return done(self.request)
|
|
|
|
|
|
class TravelApplicationView(BaseApplicationView):
|
|
form_class = TravelForm
|
|
type_code = 'TRAV'
|
|
|
|
|
|
class LibraryApplicationView(BaseApplicationView):
|
|
form_class = LibraryForm
|
|
type_code = 'BIB'
|
|
|
|
|
|
class ELiteratureApplicationView(BaseApplicationView):
|
|
form_class = ELiteratureForm
|
|
type_code = 'ELIT'
|
|
|
|
|
|
class SoftwareApplicationView(BaseApplicationView):
|
|
form_class = SoftwareForm
|
|
type_code = 'SOFT'
|
|
|
|
|
|
class IFGApplicationView(BaseApplicationView):
|
|
form_class = IFGForm
|
|
type_code = 'IFG'
|
|
|
|
|
|
class EmailApplicationView(BaseApplicationView):
|
|
form_class = EmailForm
|
|
type_code = 'MAIL'
|
|
|
|
|
|
class LiteratureApplicationView(BaseApplicationView):
|
|
form_class = LiteratureForm
|
|
type_code = 'LIT'
|
|
|
|
|
|
class ListApplicationView(BaseApplicationView):
|
|
form_class = ListForm
|
|
type_code = 'LIST'
|
|
|
|
|
|
class BusinessCardApplicationView(BaseApplicationView):
|
|
form_class = BusinessCardForm
|
|
type_code = 'VIS'
|