From 24297aae0aec752014ef931a9141f484e7dbec2d Mon Sep 17 00:00:00 2001 From: Bojan Mihelac Date: Mon, 20 May 2013 13:43:10 +0200 Subject: [PATCH] Added support for sending with SMTP_SSL See: http://docs.python.org/2/library/smtplib.html#smtplib.SMTP_SSL --- docs/HISTORY.txt | 5 + emencia/django/newsletter/admin/smtpserver.py | 8 +- .../0004_auto__add_field_smtpserver_ssl.py | 129 ++++++++++++++++++ emencia/django/newsletter/models.py | 8 +- 4 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 emencia/django/newsletter/migrations/0004_auto__add_field_smtpserver_ssl.py diff --git a/docs/HISTORY.txt b/docs/HISTORY.txt index dd15bd9..7036829 100644 --- a/docs/HISTORY.txt +++ b/docs/HISTORY.txt @@ -1,6 +1,11 @@ Changelog ========= +0.4 (unreleased) +---------------- + +- Added support for sending with SMTP_SSL + 0.3 --- diff --git a/emencia/django/newsletter/admin/smtpserver.py b/emencia/django/newsletter/admin/smtpserver.py index a69687c..5c0db32 100644 --- a/emencia/django/newsletter/admin/smtpserver.py +++ b/emencia/django/newsletter/admin/smtpserver.py @@ -27,12 +27,14 @@ class Meta: class SMTPServerAdmin(admin.ModelAdmin): form = SMTPServerAdminForm - list_display = ('name', 'host', 'port', 'user', 'tls', 'mails_hour',) - list_filter = ('tls',) + list_display = ('name', 'host', 'port', 'user', 'tls', 'ssl', + 'mails_hour',) + list_filter = ('tls', 'ssl') search_fields = ('name', 'host', 'user') fieldsets = ((None, {'fields': ('name', )}), (_('Configuration'), {'fields': ('host', 'port', - 'user', 'password', 'tls')}), + 'user', 'password', 'tls', + 'ssl')}), (_('Miscellaneous'), {'fields': ('mails_hour', 'headers'), 'classes': ('collapse', )}), ) diff --git a/emencia/django/newsletter/migrations/0004_auto__add_field_smtpserver_ssl.py b/emencia/django/newsletter/migrations/0004_auto__add_field_smtpserver_ssl.py new file mode 100644 index 0000000..00313f0 --- /dev/null +++ b/emencia/django/newsletter/migrations/0004_auto__add_field_smtpserver_ssl.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'SMTPServer.ssl' + db.add_column('newsletter_smtpserver', 'ssl', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + def backwards(self, orm): + # Deleting field 'SMTPServer.ssl' + db.delete_column('newsletter_smtpserver', 'ssl') + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'newsletter.attachment': { + 'Meta': {'object_name': 'Attachment'}, + 'file_attachment': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'newsletter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['newsletter.Newsletter']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'newsletter.contact': { + 'Meta': {'ordering': "('creation_date',)", 'object_name': 'Contact'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'subscriber': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'tags': ('tagging.fields.TagField', [], {}), + 'tester': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'newsletter.contactmailingstatus': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'ContactMailingStatus'}, + 'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['newsletter.Contact']"}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'link': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['newsletter.Link']", 'null': 'True', 'blank': 'True'}), + 'newsletter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['newsletter.Newsletter']"}), + 'status': ('django.db.models.fields.IntegerField', [], {}) + }, + 'newsletter.link': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'Link'}, + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'newsletter.mailinglist': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'MailingList'}, + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'mailinglist_subscriber'", 'symmetrical': 'False', 'to': "orm['newsletter.Contact']"}), + 'unsubscribers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'mailinglist_unsubscriber'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['newsletter.Contact']"}) + }, + 'newsletter.newsletter': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'Newsletter'}, + 'content': ('django.db.models.fields.TextField', [], {'default': "u'\\n\\n'"}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'header_reply': ('django.db.models.fields.CharField', [], {'default': "'info@status.si'", 'max_length': '255'}), + 'header_sender': ('django.db.models.fields.CharField', [], {'default': "'info@status.si'", 'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailing_list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['newsletter.MailingList']"}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'sending_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'server': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['newsletter.SMTPServer']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'test_contacts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['newsletter.Contact']", 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'newsletter.smtpserver': { + 'Meta': {'object_name': 'SMTPServer'}, + 'headers': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'host': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mails_hour': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'port': ('django.db.models.fields.IntegerField', [], {'default': '25'}), + 'ssl': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'tls': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}) + }, + 'newsletter.workgroup': { + 'Meta': {'object_name': 'WorkGroup'}, + 'contacts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['newsletter.Contact']", 'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailinglists': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['newsletter.MailingList']", 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'newsletters': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['newsletter.Newsletter']", 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['newsletter'] diff --git a/emencia/django/newsletter/models.py b/emencia/django/newsletter/models.py index bbdddef..ba128d5 100644 --- a/emencia/django/newsletter/models.py +++ b/emencia/django/newsletter/models.py @@ -1,5 +1,5 @@ """Models for emencia.django.newsletter""" -from smtplib import SMTP +from smtplib import SMTP, SMTP_SSL from smtplib import SMTPHeloError from datetime import datetime from datetime import timedelta @@ -44,6 +44,7 @@ class SMTPServer(models.Model): help_text=_('Leave it empty if the host is public.')) port = models.IntegerField(_('server port'), default=25) tls = models.BooleanField(_('server use TLS')) + ssl = models.BooleanField(_('server use SSL'), default=False) headers = models.TextField(_('custom headers'), blank=True, help_text=_('key1: value1 key2: value2, splitted by return line.\n'\ @@ -52,7 +53,10 @@ class SMTPServer(models.Model): def connect(self): """Connect the SMTP Server""" - smtp = SMTP(smart_str(self.host), int(self.port)) + if self.ssl: + smtp = SMTP_SSL(smart_str(self.host), int(self.port)) + else: + smtp = SMTP(smart_str(self.host), int(self.port)) smtp.ehlo_or_helo_if_needed() if self.tls: smtp.starttls()