From 72b09f5668b3c578920493c3d4c32c50febca060 Mon Sep 17 00:00:00 2001 From: gotlium Date: Mon, 4 Jan 2016 01:36:27 +0500 Subject: [PATCH 1/5] typo fix --- README.rst | 2 +- TODO.RU | 2 +- docs/api.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index d6c8777..c264406 100644 --- a/README.rst +++ b/README.rst @@ -224,7 +224,7 @@ Push notification API slug='welcome', # recipient can be list, or str separated with comma or simple string - # '+34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8a' or '34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8a, 34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8b' or + # '34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8a' or '34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8a, 34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8b' or # ['34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8a', '34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8b'] or string Mail group slug recipient='34cc3e5f0d2abf2ca0f9af170bd8cd2372a22f8c', diff --git a/TODO.RU b/TODO.RU index a48d451..e11163b 100644 --- a/TODO.RU +++ b/TODO.RU @@ -20,7 +20,7 @@ Version: 2.5 * [-] Поддержка django-rq * [-] Добавить приоритеты на уровне воркеров (воркеры с именами: Low, High, Medium). Далее роутить сообщение в нужный воркер * [-] Поправить документацию с учетом 3 пунктов выше - +* [-] Скрывать поля приоритета и тд, в случае когда выбранные инструменты не поддерживают Приоритет Version: 2.6 ------------ diff --git a/docs/api.rst b/docs/api.rst index 7c6ccd2..e40ab49 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -170,8 +170,8 @@ Node.js example var uri = 'http://127.0.0.1:8000/dbmail/api/'; var data = { api_key: 'ZzriUzE', - 'slug': 'welcome', - 'recipient': 'root@local.host' + slug: 'welcome', + recipient: 'root@local.host' }; request.post({ From 6088343610a55a5f78cf5465507d19c1a409b028 Mon Sep 17 00:00:00 2001 From: gotlium Date: Thu, 7 Jan 2016 13:45:29 +0500 Subject: [PATCH 2/5] update readme --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 71cc114..e093c58 100644 --- a/README.rst +++ b/README.rst @@ -536,5 +536,5 @@ Screenshots Compatibility ------------- -* Python: 2.6, 2.7, pypy, 3.4, 3.5, pypy3 +* Python: 2.7, pypy, 3.4, 3.5, pypy3 * Django: 1.4, 1.5, 1.6, 1.7, 1.8, 1.9 From e7576c8a5f71a225c8be1140d047f1843c6935ba Mon Sep 17 00:00:00 2001 From: ilstreltsov Date: Thu, 10 Mar 2016 17:17:29 +0300 Subject: [PATCH 3/5] unique address changed to db_index and some vars moved to settings --- dbmail/defaults.py | 8 +- dbmail/migrations/0009_auto_20160311_0918.py | 19 ++ dbmail/models.py | 15 +- ...n_address__del_unique_mailsubscription_.py | 261 ++++++++++++++++++ docs/signals.rst | 26 ++ 5 files changed, 317 insertions(+), 12 deletions(-) create mode 100644 dbmail/migrations/0009_auto_20160311_0918.py create mode 100644 dbmail/south_migrations/0040_auto__add_index_mailsubscription_address__del_unique_mailsubscription_.py diff --git a/dbmail/defaults.py b/dbmail/defaults.py index b684b50..f58c1b8 100644 --- a/dbmail/defaults.py +++ b/dbmail/defaults.py @@ -85,7 +85,13 @@ def get_settings(key, default): 'sms': 'dbmail.backends.sms', 'push': 'dbmail.backends.push', }) -_BACKEND = dict([(v, k) for k, v in BACKEND.items()]) +_BACKEND = {v: k for k, v in BACKEND.iteritems()} +BACKENDS_MODEL_CHOICES = get_settings('DB_MAILER_BACKENDS_MODEL_CHOICES', ( + (BACKEND.get('mail'), _('MailBox')), + (BACKEND.get('push'), _('Push')), + (BACKEND.get('sms'), _('SMS')), + (BACKEND.get('tts'), _('TTS')), +)) SMS_PROVIDER = get_settings( 'DB_MAILER_SMS_PROVIDER', 'dbmail.providers.nexmo.sms') diff --git a/dbmail/migrations/0009_auto_20160311_0918.py b/dbmail/migrations/0009_auto_20160311_0918.py new file mode 100644 index 0000000..712cb82 --- /dev/null +++ b/dbmail/migrations/0009_auto_20160311_0918.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dbmail', '0008_auto_20151007_1918'), + ] + + operations = [ + migrations.AlterField( + model_name='mailsubscription', + name='address', + field=models.CharField(help_text='Must be phone number/email/token', max_length=60, verbose_name='Address', db_index=True), + ), + ] diff --git a/dbmail/models.py b/dbmail/models.py index d558973..34efffe 100644 --- a/dbmail/models.py +++ b/dbmail/models.py @@ -18,7 +18,7 @@ from dbmail.defaults import ( PRIORITY_STEPS, UPLOAD_TO, DEFAULT_CATEGORY, AUTH_USER_MODEL, DEFAULT_FROM_EMAIL, DEFAULT_PRIORITY, CACHE_TTL, - BACKEND, _BACKEND, MODEL_HTMLFIELD) + BACKEND, _BACKEND, BACKENDS_MODEL_CHOICES, MODEL_HTMLFIELD) from dbmail import initial_signals, import_by_string from dbmail import python_2_unicode_compatible @@ -27,13 +27,6 @@ HTMLField = import_by_string(MODEL_HTMLFIELD) -BACKENDS = ( - ('dbmail.backends.mail', _('MailBox')), - ('dbmail.backends.push', _('Push')), - ('dbmail.backends.sms', _('SMS')), - ('dbmail.backends.tts', _('TTS')), -) - def _upload_mail_file(instance, filename): if instance is not None: @@ -719,8 +712,8 @@ class MailSubscriptionAbstract(models.Model): user = models.ForeignKey( AUTH_USER_MODEL, verbose_name=_('User'), null=True, blank=True) backend = models.CharField( - _('Backend'), choices=BACKENDS, max_length=50, - default='dbmail.backends.mail') + _('Backend'), choices=BACKENDS_MODEL_CHOICES, max_length=50, + default=BACKEND.get('mail')) start_hour = models.CharField( _('Start hour'), default='00:00', max_length=5) end_hour = models.CharField(_('End hour'), default='23:59', max_length=5) @@ -731,7 +724,7 @@ class MailSubscriptionAbstract(models.Model): defer_at_allowed_hours = models.BooleanField( _('Defer at allowed hours'), default=False) address = models.CharField( - _('Address'), max_length=60, unique=True, + _('Address'), max_length=60, db_index=True, help_text=_('Must be phone number/email/token')) def send_confirmation_link(self, slug='subs-confirmation', **kwargs): diff --git a/dbmail/south_migrations/0040_auto__add_index_mailsubscription_address__del_unique_mailsubscription_.py b/dbmail/south_migrations/0040_auto__add_index_mailsubscription_address__del_unique_mailsubscription_.py new file mode 100644 index 0000000..ea16f77 --- /dev/null +++ b/dbmail/south_migrations/0040_auto__add_index_mailsubscription_address__del_unique_mailsubscription_.py @@ -0,0 +1,261 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Removing unique constraint on 'MailSubscription', fields ['address'] + db.delete_unique('dbmail_mailsubscription', ['address']) + + # Adding index on 'MailSubscription', fields ['address'] + db.create_index('dbmail_mailsubscription', ['address']) + + + def backwards(self, orm): + # Removing index on 'MailSubscription', fields ['address'] + db.delete_index('dbmail_mailsubscription', ['address']) + + # Adding unique constraint on 'MailSubscription', fields ['address'] + db.create_unique('dbmail_mailsubscription', ['address']) + + + 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'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + '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'}) + }, + 'dbmail.apikey': { + 'Meta': {'object_name': 'ApiKey'}, + 'api_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '25'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailbasetemplate': { + 'Meta': {'object_name': 'MailBaseTemplate'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailbcc': { + 'Meta': {'object_name': 'MailBcc'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailcategory': { + 'Meta': {'object_name': 'MailCategory'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailfile': { + 'Meta': {'object_name': 'MailFile'}, + 'filename': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['dbmail.MailTemplate']"}) + }, + 'dbmail.mailfromemail': { + 'Meta': {'object_name': 'MailFromEmail'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'credential': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dbmail.MailFromEmailCredential']", 'null': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailfromemailcredential': { + 'Meta': {'object_name': 'MailFromEmailCredential'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'fail_silently': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'host': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'port': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'use_tls': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}) + }, + 'dbmail.mailgroup': { + 'Meta': {'object_name': 'MailGroup'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailgroupemail': { + 'Meta': {'unique_together': "(('email', 'group'),)", 'object_name': 'MailGroupEmail'}, + 'email': ('django.db.models.fields.CharField', [], {'max_length': '75'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emails'", 'to': "orm['dbmail.MailGroup']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'dbmail.maillog': { + 'Meta': {'object_name': 'MailLog'}, + 'backend': ('django.db.models.fields.CharField', [], {'default': "'mail'", 'max_length': '25', 'db_index': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'error_exception': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailLogException']", 'null': 'True', 'blank': 'True'}), + 'error_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_sent': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'log_id': ('django.db.models.fields.CharField', [], {'max_length': '60', 'db_index': 'True'}), + 'num_of_retries': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'provider': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '250', 'null': 'True', 'db_index': 'True', 'blank': 'True'}), + 'template': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailTemplate']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}) + }, + 'dbmail.maillogemail': { + 'Meta': {'object_name': 'MailLogEmail'}, + 'email': ('django.db.models.fields.CharField', [], {'max_length': '75'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailLog']"}), + 'mail_type': ('django.db.models.fields.CharField', [], {'max_length': '3'}) + }, + 'dbmail.maillogexception': { + 'Meta': {'object_name': 'MailLogException'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '150'}) + }, + 'dbmail.maillogtrack': { + 'Meta': {'object_name': 'MailLogTrack'}, + 'counter': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), + 'ip_area_code': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_country_code': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_country_code3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_country_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_dma_code': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_latitude': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_longitude': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ip_region': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'is_read': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mail_log': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailLog']"}), + 'ua': ('django.db.models.fields.CharField', [], {'max_length': '350', 'null': 'True', 'blank': 'True'}), + 'ua_browser': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'ua_browser_version': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), + 'ua_dist': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), + 'ua_dist_version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'ua_os': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'ua_os_version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.mailsubscription': { + 'Meta': {'object_name': 'MailSubscription'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '60', 'db_index': 'True'}), + 'backend': ('django.db.models.fields.CharField', [], {'default': "'dbmail.backends.mail'", 'max_length': '50'}), + 'defer_at_allowed_hours': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'end_hour': ('django.db.models.fields.CharField', [], {'default': "'23:59'", 'max_length': '5'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_checked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'is_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'start_hour': ('django.db.models.fields.CharField', [], {'default': "'00:00'", 'max_length': '5'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}) + }, + 'dbmail.mailtemplate': { + 'Meta': {'object_name': 'MailTemplate'}, + 'base': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailBaseTemplate']", 'null': 'True', 'blank': 'True'}), + 'bcc_email': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dbmail.MailBcc']", 'symmetrical': 'False', 'blank': 'True'}), + 'category': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dbmail.MailCategory']", 'null': 'True', 'blank': 'True'}), + 'context_note': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'enable_log': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'from_email': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dbmail.MailFromEmail']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interval': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_html': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'db_index': 'True'}), + 'num_of_retries': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'priority': ('django.db.models.fields.SmallIntegerField', [], {'default': '6'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.signal': { + 'Meta': {'object_name': 'Signal'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailGroup']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'interval': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'model': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'receive_once': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'rules': ('django.db.models.fields.TextField', [], {'default': "'{{ instance.email }}'", 'null': 'True', 'blank': 'True'}), + 'signal': ('django.db.models.fields.CharField', [], {'default': "'post_save'", 'max_length': '15'}), + 'template': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.MailTemplate']"}), + 'update_model': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'dbmail.signaldeferreddispatch': { + 'Meta': {'object_name': 'SignalDeferredDispatch'}, + 'args': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'done': ('django.db.models.fields.NullBooleanField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}), + 'eta': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kwargs': ('django.db.models.fields.TextField', [], {}), + 'params': ('django.db.models.fields.TextField', [], {}) + }, + 'dbmail.signallog': { + 'Meta': {'object_name': 'SignalLog'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'model_pk': ('django.db.models.fields.BigIntegerField', [], {}), + 'signal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dbmail.Signal']"}) + } + } + + complete_apps = ['dbmail'] \ No newline at end of file diff --git a/docs/signals.rst b/docs/signals.rst index 5252bf9..c602361 100644 --- a/docs/signals.rst +++ b/docs/signals.rst @@ -66,3 +66,29 @@ When you want transmit some **kwargs to signal, you can use `signals_kwargs`. signals_kwargs={'user': User.objects.get(pk=1)}, use_celery=False ) + +When using MailSubscriptionAbstract model, you may want to check instance for uniqueness before creating it. +In this case you should use either model meta option "unique-together" +or use pre-save signal, that raises IntegrityError in case of duplicates. + +.. code-block:: python + + from django.db import models + + def check_address_is_unique(sender, instance, **kwargs): + if not (instance.is_checked and instance.is_enabled): + return + + query = sender.objects.filter( + is_checked=True, + is_enabled=True, + address=instance.address, + backend=instance.backend + ) + if instance.pk: + query = query.exclude(pk=instance.pk) + if query.exists(): + raise IntegrityError('address must be unique') + + models.signals.pre_save.connect( + check_address_is_unique, sender=MailSubscription) \ No newline at end of file From a091ff6e96d405b2832b6ed92e4ba485ad84eeb5 Mon Sep 17 00:00:00 2001 From: ilstreltsov Date: Wed, 16 Mar 2016 18:23:02 +0300 Subject: [PATCH 4/5] added availability to pass unnamed args to send_confirmation_link func --- dbmail/models.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dbmail/models.py b/dbmail/models.py index 34efffe..b3de83d 100644 --- a/dbmail/models.py +++ b/dbmail/models.py @@ -727,11 +727,13 @@ class MailSubscriptionAbstract(models.Model): _('Address'), max_length=60, db_index=True, help_text=_('Must be phone number/email/token')) - def send_confirmation_link(self, slug='subs-confirmation', **kwargs): + def send_confirmation_link( + self, slug='subs-confirmation', *args, **kwargs): + from dbmail import db_sender kwargs['backend'] = self.backend - db_sender(slug, self.address, **kwargs) + db_sender(slug, self.address, *args, **kwargs) @staticmethod def get_now(): From 1ebcc40a5826ff7f063d36d4dc1c2bfe7acfd6ae Mon Sep 17 00:00:00 2001 From: ilstreltsov Date: Thu, 24 Mar 2016 13:01:21 +0300 Subject: [PATCH 5/5] added availability to pass template context to notify method as named args --- dbmail/models.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dbmail/models.py b/dbmail/models.py index b3de83d..d178bfe 100644 --- a/dbmail/models.py +++ b/dbmail/models.py @@ -768,9 +768,14 @@ def get_notification_list(cls, user_id, **kwargs): @classmethod def notify(cls, slug, user_id=None, sub_filter=None, **kwargs): + from dbmail import db_sender now_hour = cls.get_current_hour() + + context_dict = kwargs.pop('context', {}) + context_instance = kwargs.pop('context_instance', None) + sub_filter = sub_filter if isinstance(sub_filter, dict) else {} for method in cls.get_notification_list(user_id, **sub_filter): @@ -795,7 +800,8 @@ def notify(cls, slug, user_id=None, sub_filter=None, **kwargs): use_slug = extra_slug except MailTemplate.DoesNotExist: pass - db_sender(use_slug, method.address, **kwargs) + db_sender(use_slug, method.address, context_dict, + context_instance, **kwargs) def update_notify_kwargs(self, **kwargs): return kwargs