diff --git a/colossus/apps/campaigns/api.py b/colossus/apps/campaigns/api.py index c0028498..e223c4c8 100644 --- a/colossus/apps/campaigns/api.py +++ b/colossus/apps/campaigns/api.py @@ -3,7 +3,7 @@ from smtplib import SMTPException from django.contrib.sites.shortcuts import get_current_site -from django.core.mail import EmailMultiAlternatives, get_connection +from django.core.mail import EmailMultiAlternatives from django.utils import timezone from django.utils.translation import gettext as _ @@ -11,7 +11,7 @@ from colossus.apps.campaigns.constants import CampaignStatus from colossus.apps.subscribers.constants import ActivityTypes -from colossus.utils import get_absolute_url +from colossus.utils import get_absolute_url, get_campaign_connection logger = logging.getLogger(__name__) @@ -100,7 +100,7 @@ def send_campaign_email_subscriber(email, subscriber, site, connection=None): return send_campaign_email(email, context, subscriber.get_email(), connection) -def send_campaign_email_test(email, recipient_list): +def send_campaign_email_test(email, recipient_list, connection=None): if email.campaign.mailing_list is not None: unsubscribe_absolute_url = get_absolute_url('subscribers:unsubscribe_manual', kwargs={ 'mailing_list_uuid': email.campaign.mailing_list.uuid @@ -108,10 +108,12 @@ def send_campaign_email_test(email, recipient_list): else: unsubscribe_absolute_url = '#' context = get_test_email_context(unsub=unsubscribe_absolute_url) - return send_campaign_email(email, context, recipient_list, is_test=True) + return send_campaign_email(email, context, recipient_list, is_test=True, connection=connection) def send_campaign(campaign): + connection = get_campaign_connection(campaign=campaign) + campaign.status = CampaignStatus.DELIVERING campaign.save(update_fields=['status']) site = get_current_site(request=None) # get site based on SITE_ID @@ -122,7 +124,7 @@ def send_campaign(campaign): if campaign.track_opens: campaign.email.enable_open_tracking() - with get_connection() as connection: + with connection: for subscriber in campaign.get_recipients(): if not subscriber.activities.filter(activity_type=ActivityTypes.SENT, email=campaign.email).exists(): sent = send_campaign_email_subscriber(campaign.email, subscriber, site, connection) diff --git a/colossus/apps/campaigns/forms.py b/colossus/apps/campaigns/forms.py index 3ec76663..2d3ea353 100644 --- a/colossus/apps/campaigns/forms.py +++ b/colossus/apps/campaigns/forms.py @@ -115,9 +115,9 @@ class CampaignTestEmailForm(forms.Form): class Meta: fields = ('email',) - def send(self, email): + def send(self, email, connection=None): recipient_email = self.cleaned_data.get('email') - send_campaign_email_test(email, recipient_email) + send_campaign_email_test(email, recipient_email, connection=connection) class EmailEditorForm(forms.Form): diff --git a/colossus/apps/campaigns/views.py b/colossus/apps/campaigns/views.py index a35923cc..31ee894f 100644 --- a/colossus/apps/campaigns/views.py +++ b/colossus/apps/campaigns/views.py @@ -21,6 +21,7 @@ from colossus.apps.subscribers.constants import ActivityTypes from colossus.apps.subscribers.models import Activity +from ...utils import get_campaign_connection from .api import get_test_email_context from .constants import CampaignStatus, CampaignTypes from .forms import ( @@ -172,17 +173,17 @@ def get_context_data(self, **kwargs): .filter(campaign_id=self.kwargs.get('pk'), activity_type=ActivityTypes.UNSUBSCRIBED) \ .count() - subscriber_open_activities = Activity.objects \ - .filter(email__campaign_id=self.kwargs.get('pk'), activity_type=ActivityTypes.OPENED) \ - .values('subscriber__id', 'subscriber__email') \ - .annotate(total_opens=Count('id')) \ - .order_by('-total_opens')[:10] + subscriber_open_activities = Activity.objects.filter(email__campaign_id=self.kwargs.get('pk'), + activity_type=ActivityTypes.OPENED) \ + .values('subscriber__id', 'subscriber__email') \ + .annotate(total_opens=Count('id')) \ + .order_by('-total_opens')[:10] - location_open_activities = Activity.objects \ - .filter(email__campaign_id=self.kwargs.get('pk'), activity_type=ActivityTypes.OPENED) \ - .values('location__country__code', 'location__country__name') \ - .annotate(total_opens=Count('id')) \ - .order_by('-total_opens')[:10] + location_open_activities = Activity.objects.filter(email__campaign_id=self.kwargs.get('pk'), + activity_type=ActivityTypes.OPENED) \ + .values('location__country__code', 'location__country__name') \ + .annotate(total_opens=Count('id')) \ + .order_by('-total_opens')[:10] kwargs.update({ 'links': links, @@ -416,10 +417,12 @@ def campaign_edit_content(request, pk): @login_required def campaign_test_email(request, pk): campaign = get_object_or_404(Campaign, pk=pk) + connection = get_campaign_connection(campaign=campaign) + if request.method == 'POST': form = CampaignTestEmailForm(request.POST) if form.is_valid(): - form.send(campaign.email) + form.send(campaign.email, connection=connection) return redirect(campaign.get_absolute_url()) else: form = CampaignTestEmailForm() diff --git a/colossus/urls.py b/colossus/urls.py index e49b97d8..89146a2b 100644 --- a/colossus/urls.py +++ b/colossus/urls.py @@ -20,9 +20,10 @@ if settings.DEBUG: - import debug_toolbar from django.conf.urls.static import static + import debug_toolbar + urlpatterns = [ path('__debug__/', include(debug_toolbar.urls)), ] + urlpatterns diff --git a/colossus/utils.py b/colossus/utils.py index 71a22baf..01371826 100644 --- a/colossus/utils.py +++ b/colossus/utils.py @@ -3,8 +3,13 @@ from typing import Optional from django.conf import settings +from django.conf.global_settings import ( + EMAIL_HOST, EMAIL_HOST_PASSWORD, EMAIL_HOST_USER, EMAIL_PORT, + EMAIL_USE_TLS, +) from django.contrib.gis.geoip2 import GeoIP2 from django.contrib.sites.shortcuts import get_current_site +from django.core.mail import get_connection from django.http import HttpRequest from django.urls import reverse @@ -102,3 +107,32 @@ def get_absolute_url(urlname: str, kwargs: dict = None) -> str: path = reverse(urlname, kwargs=kwargs) absolute_url = '%s://%s%s' % (protocol, site.domain, path) return absolute_url + + +def get_campaign_connection(campaign=None, *args, **kwargs): + if not campaign: + return get_connection() + smtp_username = campaign.mailing_list.smtp_username or EMAIL_HOST_USER + smtp_password = campaign.mailing_list.smtp_password or EMAIL_HOST_PASSWORD + smtp_host = campaign.mailing_list.smtp_host or EMAIL_HOST + smtp_port = campaign.mailing_list.smtp_port or EMAIL_PORT + use_tls = campaign.mailing_list.smtp_use_tls or EMAIL_USE_TLS + use_ssl = campaign.mailing_list.smtp_use_ssl + timeout = campaign.mailing_list.smtp_timeout + smtp_ssl_keyfile = campaign.mailing_list.smtp_ssl_keyfile + smtp_ssl_certfile = campaign.mailing_list.smtp_ssl_certfile + connection = get_connection(host=smtp_host, + port=smtp_port, + username=smtp_username, + password=smtp_password + ) + if use_tls: + connection.use_tls = use_tls + if timeout: + connection.timeout = timeout + if use_ssl and smtp_ssl_certfile and smtp_ssl_keyfile: + connection.use_ssl = use_ssl + connection.ssl_keyfile = smtp_ssl_keyfile + connection.ssl_certfile = smtp_ssl_certfile + + return connection