Fixed static and template email files for container
This commit is contained in:
@@ -154,4 +154,4 @@ EMAIL_PORT = 587
|
|||||||
EMAIL_USE_TLS = True
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
|
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
|
||||||
EMAIL_FILE_PATH = "/tmp/app-messages" # change this to a proper location
|
EMAIL_FILE_PATH = "/mnt/d/Test/flightslot-mail" # change this to a proper location
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ ROOT_URLCONF = 'cntmanage.urls'
|
|||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': ['/var/www/templates'],
|
'DIRS': ['/var/www/templates', '/app/templates'],
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
@@ -139,6 +139,9 @@ USE_TZ = True
|
|||||||
# https://docs.djangoproject.com/en/5.1/howto/static-files/
|
# https://docs.djangoproject.com/en/5.1/howto/static-files/
|
||||||
STATIC_URL = "static/"
|
STATIC_URL = "static/"
|
||||||
STATIC_ROOT = "/var/www/static/"
|
STATIC_ROOT = "/var/www/static/"
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
"/app/static/"
|
||||||
|
]
|
||||||
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
@@ -155,4 +158,4 @@ EMAIL_PORT = 587
|
|||||||
EMAIL_USE_TLS = True
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
# Use dummy backed for testing
|
# Use dummy backed for testing
|
||||||
EMAIL_BACKEND = "django.core.mail.backends..dummy.EmailBackend"
|
EMAIL_BACKEND = "django.core.mail.backends.dummy.EmailBackend"
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ FROM python:3.12-slim AS deploy
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
# Copy application custom static files
|
# Copy application custom static files
|
||||||
RUN mkdir -p static
|
RUN mkdir -p static
|
||||||
COPY ./static/cantorair.jpg ./static
|
COPY ./static/* ./static
|
||||||
COPY ./static/cantorair_blue.jpg ./static
|
|
||||||
# Copy application custom templates for admin page
|
# Copy application custom templates for admin page
|
||||||
RUN mkdir -p /templates/admin
|
RUN mkdir -p /templates/admin
|
||||||
|
RUN mkdir -p /templates/email
|
||||||
COPY ./templates/admin/* ./templates/admin/
|
COPY ./templates/admin/* ./templates/admin/
|
||||||
|
COPY ./templates/email/* ./templates/email/
|
||||||
# Copy and install application wheel package
|
# Copy and install application wheel package
|
||||||
COPY --from=builder /build/dist/*.whl ./
|
COPY --from=builder /build/dist/*.whl ./
|
||||||
RUN pip install --no-cache-dir *.whl
|
RUN pip install --no-cache-dir *.whl
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from django.conf import settings
|
from django.contrib.staticfiles import finders
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeText
|
||||||
@@ -11,24 +11,27 @@ from ..models.students import Student
|
|||||||
from smtplib import SMTPException
|
from smtplib import SMTPException
|
||||||
from email.mime.image import MIMEImage
|
from email.mime.image import MIMEImage
|
||||||
|
|
||||||
import os
|
from typing import List
|
||||||
|
|
||||||
def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> None:
|
def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> None:
|
||||||
img: MIMEImage | None = None
|
img: MIMEImage | None = None
|
||||||
try:
|
filename: str
|
||||||
for d in settings.STATICFILES_DIRS:
|
candidates = finders.find("cantorair.png")
|
||||||
filename = os.path.join(d, "cantorair.png")
|
if not candidates:
|
||||||
if not os.path.exists(filename):
|
messages.error(request=request, message="Cannot Load CantorAir Logo")
|
||||||
continue
|
return
|
||||||
|
elif isinstance(candidates, list):
|
||||||
|
filename = candidates.pop()
|
||||||
|
else:
|
||||||
|
filename = candidates
|
||||||
|
|
||||||
with open(filename, "rb") as f:
|
with open(filename, "rb") as f:
|
||||||
img = MIMEImage(f.read())
|
img = MIMEImage(f.read())
|
||||||
img.add_header("Content-ID", "logo_image")
|
img.add_header("Content-ID", "logo_image")
|
||||||
img.add_header("Content-Disposition", "inline", filename="cantorair.png")
|
img.add_header("Content-Disposition", "inline", filename="cantorair.png")
|
||||||
break
|
|
||||||
except:
|
|
||||||
messages.error(request=request, message="Cannot Load CantorAir Logo")
|
|
||||||
return
|
|
||||||
|
|
||||||
|
# build mail list filling template
|
||||||
|
mails: List[EmailMultiAlternatives] = []
|
||||||
for student in queryset:
|
for student in queryset:
|
||||||
if not student.user or not student.email: # skip student if has not an associated user
|
if not student.user or not student.email: # skip student if has not an associated user
|
||||||
continue
|
continue
|
||||||
@@ -52,11 +55,19 @@ def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> Non
|
|||||||
)
|
)
|
||||||
mail.attach(filename=img)
|
mail.attach(filename=img)
|
||||||
mail.attach_alternative(content=html_message, mimetype="text/html")
|
mail.attach_alternative(content=html_message, mimetype="text/html")
|
||||||
mail.send()
|
mails.append(mail)
|
||||||
except SMTPException as e:
|
|
||||||
messages.error(request=request, message=f"Send Mail error: {e.strerror}")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messages.error(request=request, message=f"General Error: {e}")
|
messages.error(request=request, message=f"General Error: {e}")
|
||||||
|
|
||||||
|
# Open only one conenction and send mass email
|
||||||
|
try:
|
||||||
|
with get_connection() as conn:
|
||||||
|
conn.send_messages(mails)
|
||||||
|
except SMTPException as e:
|
||||||
|
messages.error(request=request, message=f"Send Mail SMTP error: {e.strerror}")
|
||||||
|
except Exception as e:
|
||||||
|
messages.error(request=request, message=f"Send Mail General error: {e}")
|
||||||
else:
|
else:
|
||||||
messages.success(request=request, message=f"Email Sent To: {student.surname} {student.name[0].upper()}. -> {mail.to.pop()}")
|
messages.success(request=request, message=f"Successfully sent {len(mails)} messages")
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -115,9 +115,9 @@ class StudentAdmin(ImportMixin, AdminConfirmMixin, AdminActionFormsMixin, admin.
|
|||||||
i, ac_types = assign_aircraft(queryset=queryset, data=data)
|
i, ac_types = assign_aircraft(queryset=queryset, data=data)
|
||||||
messages.success(request, f"{i} Students updated to {ac_types}")
|
messages.success(request, f"{i} Students updated to {ac_types}")
|
||||||
|
|
||||||
@admin.action(description="Send Access Credentials e-mail")
|
|
||||||
@confirm_action
|
@confirm_action
|
||||||
def send_mail(self, request: HttpRequest, queryset: QuerySet[Student], data: Any) -> None:
|
@admin.action(description="Send Access Credentials e-mail")
|
||||||
|
def send_mail(self, request: HttpRequest, queryset: QuerySet[Student], *args: Any) -> None:
|
||||||
send_mail_password(request=request, queryset=queryset)
|
send_mail_password(request=request, queryset=queryset)
|
||||||
|
|
||||||
# Return the initial form for import confirmations, request course to user
|
# Return the initial form for import confirmations, request course to user
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
admin: CantorAir2k25
|
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
<h1 id="site-name">
|
<h1 id="site-name">
|
||||||
<a href="{% url 'admin:index' %}" style="color: #0b1728;">
|
<a href="{% url 'admin:index' %}" style="color: #0b1728;">
|
||||||
<img src="{% static 'cantorair_blue.jpg' %}"
|
<img src="{% static 'cantorair.png' %}"
|
||||||
height="60px"
|
height="70px"
|
||||||
style="margin-right: 20px;"/>
|
style="margin-right: 20px;"/>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
3
note.txt
3
note.txt
@@ -3,3 +3,6 @@ OK aereo assegnato allo studente di fianco al numero della missione per PPL, inv
|
|||||||
OK le missioni ripetute su piu' giorni hanno una cella per giorno (non unite)
|
OK le missioni ripetute su piu' giorni hanno una cella per giorno (non unite)
|
||||||
OK lo studente vede solo le missioni della sua fase PPL->PPL ATPL-> tutto
|
OK lo studente vede solo le missioni della sua fase PPL->PPL ATPL-> tutto
|
||||||
OK ogni richiesta ha un colore diverso che cicla con delle tinte pastello
|
OK ogni richiesta ha un colore diverso che cicla con delle tinte pastello
|
||||||
|
|
||||||
|
|
||||||
|
password: CantorAir2k25
|
||||||
|
|||||||
Reference in New Issue
Block a user