first version of send mail with dummy backend and confirm action
This commit is contained in:
62
cntmanage/flightslot/actions/send_email.py
Normal file
62
cntmanage/flightslot/actions/send_email.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.http import HttpRequest
|
||||
from django.db.models.query import QuerySet
|
||||
from django.utils.safestring import SafeText
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from ..models.students import Student
|
||||
|
||||
from smtplib import SMTPException
|
||||
from email.mime.image import MIMEImage
|
||||
|
||||
import os
|
||||
|
||||
def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> None:
|
||||
img: MIMEImage | None = None
|
||||
try:
|
||||
for d in settings.STATICFILES_DIRS:
|
||||
filename = os.path.join(d, "cantorair.png")
|
||||
if not os.path.exists(filename):
|
||||
continue
|
||||
with open(filename, "rb") as f:
|
||||
img = MIMEImage(f.read())
|
||||
img.add_header("Content-ID", "logo_image")
|
||||
img.add_header("Content-Disposition", "inline", filename="cantorair.png")
|
||||
break
|
||||
except:
|
||||
messages.error(request=request, message="Cannot Load CantorAir Logo")
|
||||
return
|
||||
|
||||
for student in queryset:
|
||||
if not student.user or not student.email: # skip student if has not an associated user
|
||||
continue
|
||||
try:
|
||||
username: str = student.user.username
|
||||
password: str = student.default_password()
|
||||
address: str = student.email
|
||||
|
||||
text_message: str = f"Cantor Air Flight Scheduler\nUsername:{username}\nPassword:{password}\n"
|
||||
|
||||
html_message: SafeText = render_to_string(
|
||||
template_name="email/mail.html",
|
||||
context={"username": username, "password": password}
|
||||
)
|
||||
|
||||
mail: EmailMultiAlternatives = EmailMultiAlternatives(
|
||||
subject="CantorAir Flight Scheduler 🛫",
|
||||
from_email="ema.trabattoni@gmail.com",
|
||||
body=text_message,
|
||||
to = [ address ]
|
||||
)
|
||||
mail.attach(filename=img)
|
||||
mail.attach_alternative(content=html_message, mimetype="text/html")
|
||||
mail.send()
|
||||
except SMTPException as e:
|
||||
messages.error(request=request, message=f"Send Mail error: {e.strerror}")
|
||||
except Exception as e:
|
||||
messages.error(request=request, message=f"General Error: {e}")
|
||||
else:
|
||||
messages.success(request=request, message=f"Email sent to {student.surname} {student.name[0].upper()}. -> {mail.to.pop()}")
|
||||
return
|
||||
@@ -10,13 +10,15 @@ from import_export.tmp_storages import CacheStorage
|
||||
from import_export.resources import ModelResource
|
||||
from import_export.forms import ConfirmImportForm, ImportForm
|
||||
|
||||
from django_admin_action_forms import AdminActionFormsMixin, AdminActionForm, action_with_form
|
||||
from django_admin_action_forms import AdminActionFormsMixin, AdminActionForm, ActionForm, action_with_form
|
||||
from admin_confirm import AdminConfirmMixin, confirm_action
|
||||
|
||||
from ..models.aircrafts import AircraftTypes
|
||||
from ..models.courses import Course
|
||||
from ..models.students import Student
|
||||
|
||||
from ..actions.assign_aircraft import assign_aircraft
|
||||
from ..actions.send_email import send_mail_password
|
||||
|
||||
from ..custom.colortag import course_color
|
||||
|
||||
@@ -64,17 +66,19 @@ class ChangeCourseForm(AdminActionForm):
|
||||
class ChangeAircraftForm(AdminActionForm):
|
||||
aircrafts = TypedMultipleChoiceField(choices=AircraftTypes)
|
||||
|
||||
class StudentAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
||||
|
||||
class StudentAdmin(ImportMixin, AdminConfirmMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
||||
model = Student
|
||||
list_display = ("surname", "name", "course", "course_color", "email", "phone", "username", "password", "active", )
|
||||
list_filter = ("course", "active", )
|
||||
search_fields = ("surname", "name", "phone", "email", )
|
||||
actions = ("change_course", "deactivate_students", "change_aircraft", )
|
||||
actions = ("change_course", "deactivate_students", "change_aircraft", "send_mail", )
|
||||
resource_classes = [StudentResource]
|
||||
confirm_form_class = StudentCustomConfirmImportForm
|
||||
tmp_storage_class = CacheStorage
|
||||
skip_admin_log = True
|
||||
|
||||
|
||||
@admin.display(description="Color")
|
||||
def course_color(self, obj: Student) -> SafeText:
|
||||
if not obj.course:
|
||||
@@ -111,6 +115,11 @@ class StudentAdmin(ImportMixin, AdminActionFormsMixin, admin.ModelAdmin):
|
||||
i, ac_types = assign_aircraft(queryset=queryset, data=data)
|
||||
messages.success(request, f"{i} Students updated to {ac_types}")
|
||||
|
||||
@admin.action(description="Send Access Credentials e-mail")
|
||||
@confirm_action
|
||||
def send_mail(self, request: HttpRequest, queryset: QuerySet[Student], data: Any) -> None:
|
||||
send_mail_password(request=request, queryset=queryset)
|
||||
|
||||
# Return the initial form for import confirmations, request course to user
|
||||
def get_confirm_form_initial(self, request: HttpRequest, import_form) -> Dict[str, Any]:
|
||||
initial: Dict[str, Any] = super().get_confirm_form_initial(request, import_form)
|
||||
|
||||
Reference in New Issue
Block a user