diff --git a/insalan/mailer.py b/insalan/mailer.py index 52152a96..f9541df2 100644 --- a/insalan/mailer.py +++ b/insalan/mailer.py @@ -30,13 +30,13 @@ class UserMailer: """ Send emails. """ - def __init__(self, MAIL_HOST:str, MAIL_PORT:str, MAIL_FROM: str, MAIL_PASS: str, MAIL_SSL:bool, TEST: bool = False): - self.MAIL_HOST = MAIL_HOST - self.MAIL_PORT = MAIL_PORT - self.MAIL_SSL = MAIL_SSL - self.MAIL_FROM = MAIL_FROM - self.MAIL_PASS = MAIL_PASS - self.TEST = TEST + def __init__(self, mail_host:str, mail_port:str, mail_from: str, mail_pass: str, mail_ssl:bool, test: bool = False): + self.mail_host = mail_host + self.mail_port = mail_port + self.mail_ssl = mail_ssl + self.mail_from = mail_from + self.mail_pass = mail_pass + self.test = test self.queue = [] def send_email_confirmation(self, user_object: User): @@ -51,22 +51,22 @@ def send_email_confirmation(self, user_object: User): user = user_object.username connection = get_connection( - host=self.MAIL_HOST, - port=self.MAIL_PORT, - password=self.MAIL_PASS, + host=self.mail_host, + port=self.mail_port, + password=self.mail_pass, fail_silently=False, - use_ssl=self.MAIL_SSL, - username=self.MAIL_FROM, + use_ssl=self.mail_ssl, + username=self.mail_from, ) email = EmailMessage( insalan.settings.EMAIL_SUBJECT_PREFIX + _("Confirmez votre courriel"), _("Confirmez votre adresse de courriel en cliquant sur ") + f"{insalan.settings.PROTOCOL}://{insalan.settings.WEBSITE_HOST}/verification/{user}/{token}", - self.MAIL_FROM, + self.mail_from, [user_object.email], connection=connection, ) - if self.TEST: + if self.test: email.send() else: self.queue.append(email) @@ -80,11 +80,11 @@ def send_password_reset(self, user_object: User): connection = get_connection( fail_silently=False, - username=self.MAIL_FROM, - password=self.MAIL_PASS, - host=self.MAIL_HOST, - port=self.MAIL_PORT, - use_ssl=self.MAIL_SSL, + username=self.mail_from, + password=self.mail_pass, + host=self.mail_host, + port=self.mail_port, + use_ssl=self.mail_ssl, ) email = EmailMessage( insalan.settings.EMAIL_SUBJECT_PREFIX + _("Demande de ré-initialisation de mot de passe"), @@ -94,11 +94,11 @@ def send_password_reset(self, user_object: User): "vous pouvez cliquer sur le lien suivant: " ) + f"{insalan.settings.PROTOCOL}://{insalan.settings.WEBSITE_HOST}/reset-password/{user}/{token}", - self.MAIL_FROM, + self.mail_from, [user_object.email], connection=connection, ) - if self.TEST: + if self.test: email.send() else: self.queue.append(email) @@ -109,43 +109,43 @@ def send_kick_mail(self, user_object: User, team_name: str): """ connection = get_connection( fail_silently=False, - username=self.MAIL_FROM, - password=self.MAIL_PASS, - host=self.MAIL_HOST, - port=self.MAIL_PORT, - use_ssl=self.MAIL_SSL, + username=self.mail_from, + password=self.mail_pass, + host=self.mail_host, + port=self.mail_port, + use_ssl=self.mail_ssl, ) email = EmailMessage( insalan.settings.EMAIL_SUBJECT_PREFIX + _("Vous avez été exclu.e de votre équipe"), _("Vous avez été exclu.e de l'équipe %s.") % team_name, - self.MAIL_FROM, + self.mail_from, [user_object.email], connection=connection, ) - if self.TEST: + if self.test: email.send() else: self.queue.append(email) def send_ticket_mail(self, user_object: User, ticket: str): """ - Send a mail to a user that has been kicked. + Send a mail with the ticket in attachment. """ ticket_pdf = TicketManager.generate_ticket_pdf(ticket) connection = get_connection( fail_silently=False, - username=self.MAIL_FROM, - password=self.MAIL_PASS, - host=self.MAIL_HOST, - port=self.MAIL_PORT, - use_ssl=self.MAIL_SSL, + username=self.mail_from, + password=self.mail_pass, + host=self.mail_host, + port=self.mail_port, + use_ssl=self.mail_ssl, ) email = EmailMessage( insalan.settings.EMAIL_SUBJECT_PREFIX + _("Votre billet pour l'InsaLan"), _("Votre inscription pour l'Insalan a été payée. Votre billet est disponible en pièce jointe. Vous pouvez retrouver davantages d'informations sur l'évènement sur le site internet de l'InsaLan."), - self.MAIL_FROM, + self.mail_from, [user_object.email], connection=connection, ) @@ -155,7 +155,7 @@ def send_ticket_mail(self, user_object: User, ticket: str): "application/pdf" ) - if self.TEST: + if self.test: email.send() else: self.queue.append(email) @@ -166,23 +166,23 @@ def send_tournament_mail(self, user_object: User, title: str, content: str, atta """ connection = get_connection( fail_silently=False, - username=self.MAIL_FROM, - password=self.MAIL_PASS, - host=self.MAIL_HOST, - port=self.MAIL_PORT, - use_ssl=self.MAIL_SSL, + username=self.mail_from, + password=self.mail_pass, + host=self.mail_host, + port=self.mail_port, + use_ssl=self.mail_ssl, ) email = EmailMessage( insalan.settings.EMAIL_SUBJECT_PREFIX + title, content, - self.MAIL_FROM, + self.mail_from, [user_object.email], connection=connection, ) if attachment: email.attach(attachment.name, attachment.read()) - if self.TEST: + if self.test: email.send() else: self.queue.append(email) @@ -203,13 +203,13 @@ class MailManager: mailers = {} @staticmethod - def get_mailer(MAIL_FROM: str) -> UserMailer: + def get_mailer(mail_from: str) -> UserMailer: """ Get a mailer for a specific email address. """ - if MAIL_FROM not in MailManager.mailers: + if mail_from not in MailManager.mailers: return None - return MailManager.mailers[MAIL_FROM] + return MailManager.mailers[mail_from] @staticmethod def get_default_mailer() -> UserMailer: @@ -221,11 +221,11 @@ def get_default_mailer() -> UserMailer: return list(MailManager.mailers.values())[0] @staticmethod - def add_mailer(MAIL_HOST:str, MAIL_PORT: str, MAIL_FROM: str, MAIL_PASS: str, MAIL_SSL:bool, TEST: bool = False): + def add_mailer(mail_host:str, mail_port: str, mail_from: str, mail_pass: str, mail_ssl:bool, test: bool = False): """ Add a mailer for a specific email address. """ - MailManager.mailers[MAIL_FROM] = UserMailer(MAIL_HOST, MAIL_PORT, MAIL_FROM, MAIL_PASS, MAIL_SSL, TEST=TEST) + MailManager.mailers[mail_from] = UserMailer(mail_host, mail_port, mail_from, mail_pass, mail_ssl, test=test) @staticmethod def send_queued_mail(): @@ -240,16 +240,16 @@ def start_scheduler(): logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING) # Check if we are in test mode - TEST = 'test' in sys.argv - print(TEST, file=sys.stderr) + test = 'test' in sys.argv + print(test, file=sys.stderr) # Add mailers for auth in insalan.settings.EMAIL_AUTH: mailer = insalan.settings.EMAIL_AUTH[auth] - MailManager.add_mailer(mailer["host"], mailer["port"], mailer["from"], mailer["pass"], mailer["ssl"], TEST=TEST) + MailManager.add_mailer(mailer["host"], mailer["port"], mailer["from"], mailer["pass"], mailer["ssl"], test=test) # Start scheduler - if not TEST: + if not test: scheduler = BackgroundScheduler() scheduler.add_job(MailManager.send_queued_mail, 'interval', seconds=30) scheduler.start() diff --git a/insalan/settings.py b/insalan/settings.py index 2997574f..fbc0847a 100644 --- a/insalan/settings.py +++ b/insalan/settings.py @@ -222,13 +222,9 @@ ] CSRF_COOKIE_DOMAIN = '.' + getenv("WEBSITE_HOST", "localhost") -# MAILER SETTINGS +# MAILER SETTINGS - Mail are not sent with test mode EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" - EMAIL_AUTH = json.loads(getenv("MAIL_AUTH", '{"contact": {"from":"noreply@insalan.fr", "pass":"password", "host":"localhost", "port":587, "ssl":true}, "tournament": {"from":"noreply@insalan.fr", "pass":"password", "host":"localhost", "port":587, "ssl":true}}')) - -EMAIL_PORT = int(getenv("MAIL_PORT", "465")) -EMAIL_USE_SSL = getenv("MAIL_SSL", "true").lower() in ["true", "1", "t", "y", "yes"] EMAIL_SUBJECT_PREFIX = "[InsaLan] " # Payment variables diff --git a/insalan/tickets/admin.py b/insalan/tickets/admin.py index 07c97f11..464010bf 100644 --- a/insalan/tickets/admin.py +++ b/insalan/tickets/admin.py @@ -24,7 +24,7 @@ def send_tickets_to_mail(self, request, queryset): Action to send tickets to mail """ for ticket in queryset: - MailManager.get_mailer(EMAIL_AUTH["contact"]["from"]).send_ticket_mail(ticket.user, ticket) + MailManager.get_mailer(EMAIL_AUTH["tournament"]["from"]).send_ticket_mail(ticket.user, ticket) messages.info(request, _("Les tickets sélectionnés sont en cours d'envoi.")) admin.site.register(Ticket, TicketAdmin) diff --git a/insalan/tournament/models.py b/insalan/tournament/models.py index 861e9bfa..624d2e9a 100644 --- a/insalan/tournament/models.py +++ b/insalan/tournament/models.py @@ -862,6 +862,18 @@ class Caster(models.Model): class TournamentMailer(models.Model): + """ + The TournamentMailer model is used to send emails to players of a tournament with filters. + + The filters are: + - tournament: the tournament of the players + - team_validated: if the players are in validated teams + - captains: if the players are captains + + The save method is overriden to send the mail to every players matching the filters and not + actually save the object. The database table should be empty at all time. + + """ class Meta: verbose_name_plural = 'mailers' # The name displayed in the admin sidebar diff --git a/insalan/tournament/views.py b/insalan/tournament/views.py index f97b9532..b15dea4f 100644 --- a/insalan/tournament/views.py +++ b/insalan/tournament/views.py @@ -408,7 +408,7 @@ def patch(self, request, *args, **kwargs): player = Player.objects.get(id=uid) # if player hasn't paid, remove him from the team if player.as_user().id != user.id and player.payment_status == PaymentStatus.NOT_PAID: - MailManager.get_mailer(EMAIL_AUTH["contact"]["from"]).send_kick_mail(player.as_user(), team.name) + MailManager.get_mailer(EMAIL_AUTH["tournament"]["from"]).send_kick_mail(player.as_user(), team.name) player.delete() # manager edit @@ -420,7 +420,7 @@ def patch(self, request, *args, **kwargs): manager = Manager.objects.get(id=uid) # if manager hasn't paid, remove him from the team if manager.as_user().id != user.id and manager.payment_status == PaymentStatus.NOT_PAID: - MailManager.get_mailer(EMAIL_AUTH["contact"]["from"]).send_kick_mail(manager.as_user(), team.name) + MailManager.get_mailer(EMAIL_AUTH["tournament"]["from"]).send_kick_mail(manager.as_user(), team.name) manager.delete() # substitute edit @@ -432,7 +432,7 @@ def patch(self, request, *args, **kwargs): substitute = Substitute.objects.get(id=uid) # if substitute hasn't paid, remove him from the team if substitute.as_user().id != user.id and substitute.payment_status == PaymentStatus.NOT_PAID: - MailManager.get_mailer(EMAIL_AUTH["contact"]["from"]).send_kick_mail(substitute.as_user(), team.name) + MailManager.get_mailer(EMAIL_AUTH["tournament"]["from"]).send_kick_mail(substitute.as_user(), team.name) substitute.delete() team.save()