2020-11-16 14:53:43 +00:00
from smtplib import SMTPException
2020-10-26 11:34:09 +00:00
2020-09-21 12:27:16 +00:00
from django . shortcuts import render
2020-09-29 09:08:16 +00:00
from django . http import HttpResponse
2025-08-19 14:08:48 +00:00
from django . utils . safestring import mark_safe
2020-10-05 11:35:28 +00:00
from formtools . wizard . views import CookieWizardView
2025-08-19 14:08:48 +00:00
from django . core . mail import BadHeaderError , EmailMultiAlternatives
2020-10-07 13:07:02 +00:00
from django . template . loader import get_template
2025-08-19 07:45:14 +00:00
from django . conf import settings
2020-10-28 14:49:18 +00:00
from django . contrib . auth . decorators import login_required
2025-08-31 21:41:11 +00:00
from django . views . generic . edit import FormView
2020-09-22 10:21:05 +00:00
2025-08-20 10:06:43 +00:00
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 ,
}
2025-08-31 21:41:11 +00:00
HELP_TEXTS = {
2025-09-01 11:24:59 +00:00
' IFG ' : {
' notes ' : (
' Bitte gib an, wie die gewonnenen Informationen den<br> '
' Wikimedia-Projekten zugute kommen sollen. '
2025-08-31 21:41:11 +00:00
)
} ,
2025-09-01 11:24:59 +00:00
' MAIL ' : {
' domain ' : (
' Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br> '
' möchtest du eine Mailadresse beantragen? '
2025-08-31 21:41:11 +00:00
)
} ,
2025-09-01 11:24:59 +00:00
' LIT ' : {
' notes ' : ' Bitte gib an, wofür du die Literatur verwenden möchtest. '
2025-08-31 21:41:11 +00:00
} ,
2025-09-01 11:24:59 +00:00
' LIST ' : {
' domain ' : (
' Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br> '
' möchtest du eine Mailingliste beantragen? '
2025-08-31 21:41:11 +00:00
)
} ,
}
2025-08-20 10:06:43 +00:00
def auth_deny ( choice , pk , auth ) :
if choice not in MODELS :
2021-01-04 10:24:20 +00:00
return HttpResponse ( f ' ERROR! UNKNOWN CHOICE TYPE! { choice } ' )
2025-08-20 10:06:43 +00:00
MODELS [ choice ] . set_granted ( pk , auth )
2025-08-21 08:08:38 +00:00
2020-11-19 14:55:10 +00:00
@login_required
def export ( request ) :
''' export the project database to a csv '''
return HttpResponse ( ' WE WANT CSV! ' )
2021-01-04 09:44:03 +00:00
2025-08-21 08:08:38 +00:00
2020-10-28 14:49:18 +00:00
@login_required
2020-10-20 06:39:00 +00:00
def authorize ( request , choice , pk ) :
2020-10-21 07:54:12 +00:00
''' 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 . '''
2025-08-21 08:42:55 +00:00
if ret := auth_deny ( choice , pk , True ) :
2020-10-27 12:47:46 +00:00
return ret
2020-10-20 07:35:04 +00:00
else :
2025-09-01 11:24:59 +00:00
return HttpResponse ( f ' AUTHORIZED! choice: { choice } , pk: { pk } ' )
2020-10-20 07:35:04 +00:00
2025-08-21 08:08:38 +00:00
2020-10-28 14:49:18 +00:00
@login_required
2020-10-20 06:39:00 +00:00
def deny ( request , choice , pk ) :
2020-10-21 07:54:12 +00:00
''' If IF denies a support they click a link in a mail which leads here
We write the granted field in the database here . '''
2020-10-21 07:22:53 +00:00
2025-08-21 08:42:55 +00:00
if ret := auth_deny ( choice , pk , False ) :
2020-10-27 12:47:46 +00:00
return ret
2020-10-20 07:35:04 +00:00
else :
2025-09-01 11:24:59 +00:00
return HttpResponse ( f ' DENIED! choice: { choice } , pk: { pk } ' )
2020-10-20 07:35:04 +00:00
2020-10-20 06:06:36 +00:00
2020-09-29 09:08:16 +00:00
def done ( request ) :
2025-08-31 21:41:11 +00:00
return HttpResponse (
2025-09-01 11:24:59 +00:00
' 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. ' )
2020-09-30 12:26:08 +00:00
2025-08-21 08:02:19 +00:00
2024-01-07 14:13:21 +00:00
def index ( request ) :
return render ( request , ' input/index.html ' )
2020-10-28 14:49:18 +00:00
2020-11-18 15:03:27 +00:00
2025-08-31 21:41:11 +00:00
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 .
"""
2025-09-01 11:24:59 +00:00
template_name = ' input/forms/form_generic.html '
type_code : str = ' '
2020-10-05 13:10:23 +00:00
2020-11-18 11:05:18 +00:00
def get_context_data ( self , * * kwargs ) :
2025-08-31 21:41:11 +00:00
""" Add the human-readable type string (from TYPE_CHOICES) to the template context. """
ctx = super ( ) . get_context_data ( * * kwargs )
2025-09-01 11:24:59 +00:00
ctx [ ' typestring ' ] = TYPE_CHOICES . get ( self . type_code , self . type_code )
2025-08-31 21:41:11 +00:00
return ctx
2025-08-18 14:32:31 +00:00
2025-08-31 21:41:11 +00:00
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 )
2023-02-27 17:09:29 +00:00
2025-08-31 21:41:11 +00:00
# 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 )
2025-08-18 14:33:04 +00:00
2025-08-31 21:41:11 +00:00
return form
2023-02-27 17:09:29 +00:00
2025-08-31 21:41:11 +00:00
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 .
"""
2020-10-05 11:35:28 +00:00
2025-08-31 21:41:11 +00:00
# Collect cleaned data and mark the current type
data = form . cleaned_data . copy ( )
2025-09-01 11:24:59 +00:00
data [ ' choice ' ] = self . type_code
2020-10-20 06:06:36 +00:00
2025-08-31 21:41:11 +00:00
# Special rule for literature applications
2025-09-01 11:24:59 +00:00
if self . type_code == ' LIT ' and data . get ( ' selfbuy ' ) == ' TRUE ' :
data [ ' selfbuy_give_data ' ] = ' False '
2025-08-31 21:41:11 +00:00
# Save model instance
modell = form . save ( commit = False )
2025-08-18 14:32:31 +00:00
2025-08-31 21:41:11 +00:00
# Username from session if present
2025-09-01 11:24:59 +00:00
user = self . request . session . get ( ' user ' )
2025-08-31 21:41:11 +00:00
if user :
2025-09-01 11:24:59 +00:00
modell . username = user . get ( ' username ' )
2025-08-18 14:32:31 +00:00
2025-08-31 21:41:11 +00:00
# Copy common fields if provided by the form
2025-09-01 11:24:59 +00:00
if ' realname ' in data :
modell . realname = data [ ' realname ' ]
if ' email ' in data :
modell . email = data [ ' email ' ]
2025-08-31 21:41:11 +00:00
# Set model.type for specific request types
2025-09-01 11:24:59 +00:00
if self . type_code in ( ' BIB ' , ' ELIT ' , ' SOFT ' ) :
2025-08-31 21:41:11 +00:00
modell . type = self . type_code
# Literature-specific extra field
2025-09-01 11:24:59 +00:00
if self . type_code == ' LIT ' and ' selfbuy_give_data ' in data :
modell . selfbuy_give_data = data [ ' selfbuy_give_data ' ]
2025-08-31 21:41:11 +00:00
modell . save ( )
2025-09-01 11:24:59 +00:00
if hasattr ( form , ' save_m2m ' ) :
2025-08-31 21:41:11 +00:00
form . save_m2m ( )
# Prepare minimal mail context and send mails
2025-09-01 11:24:59 +00:00
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 }
2025-08-31 21:41:11 +00:00
try :
# Mail to applicant
2025-09-01 11:24:59 +00:00
txt1 = get_template ( ' input/ifg_volunteer_mail.txt ' ) . render ( context )
html1 = get_template ( ' input/ifg_volunteer_mail.html ' ) . render ( context )
2025-08-31 21:41:11 +00:00
msg1 = EmailMultiAlternatives (
2025-09-01 11:24:59 +00:00
' Formular ausgefüllt ' , txt1 , settings . IF_EMAIL , [ data [ ' email ' ] ]
2025-08-31 21:41:11 +00:00
)
2025-09-01 11:24:59 +00:00
msg1 . attach_alternative ( html1 , ' text/html ' )
2023-02-27 17:09:29 +00:00
msg1 . send ( )
2025-08-31 21:41:11 +00:00
# Mail to IF
2025-09-01 11:24:59 +00:00
txt2 = get_template ( ' input/if_mail.txt ' ) . render ( context )
html2 = get_template ( ' input/if_mail.html ' ) . render ( context )
2025-08-31 21:41:11 +00:00
msg2 = EmailMultiAlternatives (
2025-09-01 11:24:59 +00:00
' Formular ausgefüllt ' , txt2 , settings . IF_EMAIL , [ settings . IF_EMAIL ]
2025-08-31 21:41:11 +00:00
)
2025-09-01 11:24:59 +00:00
msg2 . attach_alternative ( html2 , ' text/html ' )
2023-02-27 17:09:29 +00:00
msg2 . send ( )
2025-08-18 14:32:31 +00:00
2020-10-08 10:38:49 +00:00
except BadHeaderError :
2020-11-16 15:10:31 +00:00
modell . delete ( )
2025-09-01 11:24:59 +00:00
return HttpResponse ( ' Invalid header found. Data not saved! ' )
2020-11-16 14:53:43 +00:00
except SMTPException :
2020-11-16 15:10:31 +00:00
modell . delete ( )
2025-09-01 11:24:59 +00:00
return HttpResponse ( ' Error in sending mails (probably wrong adress?). Data not saved! ' )
2020-10-07 11:15:00 +00:00
2020-10-01 12:45:04 +00:00
return done ( self . request )
2025-08-31 21:41:11 +00:00
class TravelApplicationView ( BaseApplicationView ) :
form_class = TravelForm
2025-09-01 11:24:59 +00:00
type_code = ' TRAV '
2025-08-31 21:41:11 +00:00
class LibraryApplicationView ( BaseApplicationView ) :
form_class = LibraryForm
2025-09-01 11:24:59 +00:00
type_code = ' BIB '
2025-08-31 21:41:11 +00:00
class ELiteratureApplicationView ( BaseApplicationView ) :
form_class = ELiteratureForm
2025-09-01 11:24:59 +00:00
type_code = ' ELIT '
2025-08-31 21:41:11 +00:00
class SoftwareApplicationView ( BaseApplicationView ) :
form_class = SoftwareForm
2025-09-01 11:24:59 +00:00
type_code = ' SOFT '
2025-08-31 21:41:11 +00:00
class IFGApplicationView ( BaseApplicationView ) :
form_class = IFGForm
2025-09-01 11:24:59 +00:00
type_code = ' IFG '
2025-08-31 21:41:11 +00:00
class EmailApplicationView ( BaseApplicationView ) :
form_class = EmailForm
2025-09-01 11:24:59 +00:00
type_code = ' MAIL '
2025-08-31 21:41:11 +00:00
class LiteratureApplicationView ( BaseApplicationView ) :
form_class = LiteratureForm
2025-09-01 11:24:59 +00:00
type_code = ' LIT '
2025-08-31 21:41:11 +00:00
class ListApplicationView ( BaseApplicationView ) :
form_class = ListForm
2025-09-01 11:24:59 +00:00
type_code = ' LIST '
2025-08-31 21:41:11 +00:00
class BusinessCardApplicationView ( BaseApplicationView ) :
form_class = BusinessCardForm
2025-09-01 11:24:59 +00:00
type_code = ' VIS '