initial message processing

This commit is contained in:
Tom Irgang 2023-05-03 08:26:24 +02:00
parent 82d752c677
commit 61e543b1b0
4 changed files with 110 additions and 7 deletions

View file

@ -0,0 +1,96 @@
import os
import re
import logging
from imap_tools import MailBox, AND, MailMessage
from django.core.mail import send_mail
from .models import Guest, Message, Question, Organisator
logger = logging.getLogger(__name__)
def send_message_notification(message: Message, guest: Guest):
"""
Send new message notification.
"""
organizers = []
for organizer in Organisator.objects.all():
organizers.append(organizer.mail)
subject = f'Neue Nachricht von Gast {guest.name} ({guest.mail})'
text = f'Hallo,\n'
f'der Gast {guest.name} ({guest.mail}) hat folgende Nachricht gesendet:\n\n'
f'{message.message}'
# TODO: add attachments
# TODO: add link to message
send_mail(
subject=subject,
message=text,
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
recipient_list=organizers,
fail_silently=True
)
def process_message(message: MailMessage, guest: Guest):
"""
Process a valid message from a guest.
"""
content = message.text
if message.html:
content = message.html
result = re.search('Q#([0-9]+):', message.subject)
if result:
question_pk = result.group(1)
question = Question.objects.filter(pk=question_pk).first()
if question:
if question.device.guest.mail == message.from_:
question.answer = content
question.save()
# TODO: save attachments and add to message
logger.info(
f'Valid answer for Question {question_pk} from {message.from_} received.')
# TODO: send notifications
else:
logger.warning(
f'Answer for Question {question_pk} from {message.from_} received,'
' but the question was not for this guest. Message was ignored.')
# TODO: send reply that mail address was wrong
else:
logger.warning(
f'Answer for Question {question_pk} from {message.from_} received,'
' but there is no such question. Message was ignored.')
else:
db_message = Message(
message=content,
guest=guest,
)
db_message.save()
send_message_notification(message, guest)
def process_mails():
"""
Check for new messages and handle valid messages.
"""
host = os.getenv("DJANGO_EMAIL_HOST", "")
user = os.getenv("DJANGO_EMAIL_HOST_USER", None)
password = os.getenv("DJANGO_EMAIL_HOST_PASSWORD", None)
mailbox = MailBox(host).login(user, password)
messages = mailbox.fetch(criteria=AND(seen=False),
mark_seen=True, bulk=True)
message_count = 0
for message in messages:
message_count += 1
sender = message.from_
guest = Guest.objects.filter(mail=sender).first()
if guest:
process_message(message, guest)
else:
logger.warning(
'Mail form unknown sender %s with subject %s ignored.'
% (sender, message.subject))
return message_count

View file

@ -14,15 +14,15 @@ from django.contrib import messages
from django.views import generic
from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.http import HttpResponseRedirect, HttpResponse
from django.core.exceptions import PermissionDenied
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login
from django.utils.timezone import now
from repapp.models import CustomUser, Organisator, Reparateur
from .models import Cafe, Device, Guest, OneTimeLogin
from .forms import RegisterDevice, RegisterGuest
from .models import (Cafe, Device, Guest, OneTimeLogin,
CustomUser, Organisator, Reparateur)
from . import mail_interface
def send_one_time_login_mail(secret, mail, request):
@ -216,11 +216,15 @@ class RegisterDeviceFormView(generic.edit.FormView):
device.save()
guest = Guest.objects.filter(mail=mail).first()
user = CustomUser.objects.filter(email=mail).first()
if guest:
if guest and user:
device.guest = guest
device.save()
guest.user = user
guest.save()
send_confirmation_mails(device, guest, cafe, self.request)
resp = HttpResponseRedirect(
@ -407,14 +411,15 @@ def cron(request):
"""
View to trigger automated regular tasks.
"""
pass
return HttpResponse('done.')
def process_mails(request):
"""
View to trigger processing of email in inbox.
"""
pass
count = mail_interface.process_mails()
return HttpResponse(f'Done. Processed {count} messages.')
def one_time_login(request, secret: str):

View file

@ -11,3 +11,4 @@ mozilla-django-oidc==3.0.0
djlint==1.23.3
django-import-export==3.2.0
selenium==4.9.0
imap-tools==1.0.0

View file

@ -5,3 +5,4 @@ crispy-bootstrap4==2022.1
crispy-bootstrap5==0.7
mozilla-django-oidc==3.0.0
django-import-export==3.2.0
imap-tools==1.0.0