Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Multiple Email Clients #39

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions colossus/apps/campaigns/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
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 _

import html2text

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__)

Expand Down Expand Up @@ -100,18 +100,20 @@ 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
})
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
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions colossus/apps/campaigns/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
25 changes: 14 additions & 11 deletions colossus/apps/campaigns/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()
Expand Down
3 changes: 2 additions & 1 deletion colossus/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions colossus/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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