From cc17df7a1c6aa9567ad9379cbe30b2b416088ab8 Mon Sep 17 00:00:00 2001 From: Kalil de Lima Date: Tue, 12 May 2020 10:06:35 -0300 Subject: [PATCH 1/5] build passing tests failing --- credits/models.py | 6 +- drip/admin.py | 6 +- drip/drips.py | 2 +- drip/migrations/0001_initial.py | 128 ------------------ ...__add_field_drip_from_email_name__add_f.py | 119 ---------------- ...0003_auto__add_field_drip_message_class.py | 94 ------------- drip/migrations/__init__.py | 0 drip/models.py | 18 ++- drip/tests.py | 2 +- drip/utils.py | 2 +- requirements.txt | 1 - test_urls.py | 7 +- testsettings.py | 26 +++- 13 files changed, 55 insertions(+), 356 deletions(-) delete mode 100644 drip/migrations/0001_initial.py delete mode 100644 drip/migrations/0002_auto__add_field_drip_from_email__add_field_drip_from_email_name__add_f.py delete mode 100644 drip/migrations/0003_auto__add_field_drip_message_class.py delete mode 100644 drip/migrations/__init__.py diff --git a/credits/models.py b/credits/models.py index dd847f6..bc307a5 100644 --- a/credits/models.py +++ b/credits/models.py @@ -6,7 +6,11 @@ class Profile(models.Model): """ For testing, track the number of "credits". """ - user = models.OneToOneField('auth.User', related_name='profile') + user = models.OneToOneField( + 'auth.User', + related_name='profile', + on_delete=models.CASCADE, + ) credits = models.PositiveIntegerField(default=0) diff --git a/drip/admin.py b/drip/admin.py index 9c1d5a1..387d7af 100644 --- a/drip/admin.py +++ b/drip/admin.py @@ -87,9 +87,9 @@ def change_view(self, request, object_id, extra_context=None): request, object_id, extra_context=self.build_extra_context(extra_context)) def get_urls(self): - from django.conf.urls import patterns, url + from django.conf.urls import url urls = super(DripAdmin, self).get_urls() - my_urls = patterns('', + my_urls = [ url( r'^(?P[\d]+)/timeline/(?P[\d]+)/(?P[\d]+)/$', self.av(self.timeline), @@ -100,7 +100,7 @@ def get_urls(self): self.av(self.view_drip_email), name='view_drip_email' ) - ) + ] return my_urls + urls admin.site.register(Drip, DripAdmin) diff --git a/drip/drips.py b/drip/drips.py index 87b27aa..499caa4 100644 --- a/drip/drips.py +++ b/drip/drips.py @@ -4,7 +4,7 @@ from django.conf import settings from django.db.models import Q from django.template import Context, Template -from django.utils.importlib import import_module +from importlib import import_module from django.core.mail import EmailMultiAlternatives from django.utils.html import strip_tags diff --git a/drip/migrations/0001_initial.py b/drip/migrations/0001_initial.py deleted file mode 100644 index 914041f..0000000 --- a/drip/migrations/0001_initial.py +++ /dev/null @@ -1,128 +0,0 @@ -# -*- 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 model 'Drip' - db.create_table('drip_drip', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('lastchanged', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), - ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)), - ('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)), - ('subject_template', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), - ('body_html_template', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), - )) - db.send_create_signal('drip', ['Drip']) - - # Adding model 'SentDrip' - db.create_table('drip_sentdrip', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('drip', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sent_drips', to=orm['drip.Drip'])), - ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sent_drips', to=orm['auth.User'])), - ('subject', self.gf('django.db.models.fields.TextField')()), - ('body', self.gf('django.db.models.fields.TextField')()), - )) - db.send_create_signal('drip', ['SentDrip']) - - # Adding model 'QuerySetRule' - db.create_table('drip_querysetrule', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('lastchanged', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), - ('drip', self.gf('django.db.models.fields.related.ForeignKey')(related_name='queryset_rules', to=orm['drip.Drip'])), - ('method_type', self.gf('django.db.models.fields.CharField')(default='filter', max_length=12)), - ('field_name', self.gf('django.db.models.fields.CharField')(max_length=128)), - ('lookup_type', self.gf('django.db.models.fields.CharField')(default='exact', max_length=12)), - ('field_value', self.gf('django.db.models.fields.CharField')(max_length=255)), - )) - db.send_create_signal('drip', ['QuerySetRule']) - - - def backwards(self, orm): - # Deleting model 'Drip' - db.delete_table('drip_drip') - - # Deleting model 'SentDrip' - db.delete_table('drip_sentdrip') - - # Deleting model 'QuerySetRule' - db.delete_table('drip_querysetrule') - - - 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'}) - }, - 'drip.drip': { - 'Meta': {'object_name': 'Drip'}, - 'body_html_template': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'subject_template': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'drip.querysetrule': { - 'Meta': {'object_name': 'QuerySetRule'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'drip': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'queryset_rules'", 'to': "orm['drip.Drip']"}), - 'field_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'field_value': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'lookup_type': ('django.db.models.fields.CharField', [], {'default': "'exact'", 'max_length': '12'}), - 'method_type': ('django.db.models.fields.CharField', [], {'default': "'filter'", 'max_length': '12'}) - }, - 'drip.sentdrip': { - 'Meta': {'object_name': 'SentDrip'}, - 'body': ('django.db.models.fields.TextField', [], {}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'drip': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_drips'", 'to': "orm['drip.Drip']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject': ('django.db.models.fields.TextField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_drips'", 'to': "orm['auth.User']"}) - } - } - - complete_apps = ['drip'] diff --git a/drip/migrations/0002_auto__add_field_drip_from_email__add_field_drip_from_email_name__add_f.py b/drip/migrations/0002_auto__add_field_drip_from_email__add_field_drip_from_email_name__add_f.py deleted file mode 100644 index f287ae7..0000000 --- a/drip/migrations/0002_auto__add_field_drip_from_email__add_field_drip_from_email_name__add_f.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- 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 'Drip.from_email' - db.add_column('drip_drip', 'from_email', - self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True), - keep_default=False) - - # Adding field 'Drip.from_email_name' - db.add_column('drip_drip', 'from_email_name', - self.gf('django.db.models.fields.CharField')(max_length=150, null=True, blank=True), - keep_default=False) - - # Adding field 'SentDrip.from_email' - db.add_column('drip_sentdrip', 'from_email', - self.gf('django.db.models.fields.EmailField')(default=None, max_length=75, null=True), - keep_default=False) - - # Adding field 'SentDrip.from_email_name' - db.add_column('drip_sentdrip', 'from_email_name', - self.gf('django.db.models.fields.CharField')(default=None, max_length=150, null=True), - keep_default=False) - - - def backwards(self, orm): - # Deleting field 'Drip.from_email' - db.delete_column('drip_drip', 'from_email') - - # Deleting field 'Drip.from_email_name' - db.delete_column('drip_drip', 'from_email_name') - - # Deleting field 'SentDrip.from_email' - db.delete_column('drip_sentdrip', 'from_email') - - # Deleting field 'SentDrip.from_email_name' - db.delete_column('drip_sentdrip', 'from_email_name') - - - 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'}) - }, - 'drip.drip': { - 'Meta': {'object_name': 'Drip'}, - 'body_html_template': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'from_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'from_email_name': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'subject_template': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'drip.querysetrule': { - 'Meta': {'object_name': 'QuerySetRule'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'drip': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'queryset_rules'", 'to': "orm['drip.Drip']"}), - 'field_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'field_value': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'lookup_type': ('django.db.models.fields.CharField', [], {'default': "'exact'", 'max_length': '12'}), - 'method_type': ('django.db.models.fields.CharField', [], {'default': "'filter'", 'max_length': '12'}) - }, - 'drip.sentdrip': { - 'Meta': {'object_name': 'SentDrip'}, - 'body': ('django.db.models.fields.TextField', [], {}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'drip': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_drips'", 'to': "orm['drip.Drip']"}), - 'from_email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'max_length': '75', 'null': 'True'}), - 'from_email_name': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '150', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject': ('django.db.models.fields.TextField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_drips'", 'to': "orm['auth.User']"}) - } - } - - complete_apps = ['drip'] \ No newline at end of file diff --git a/drip/migrations/0003_auto__add_field_drip_message_class.py b/drip/migrations/0003_auto__add_field_drip_message_class.py deleted file mode 100644 index 5851455..0000000 --- a/drip/migrations/0003_auto__add_field_drip_message_class.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- 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 'Drip.message_class' - db.add_column('drip_drip', 'message_class', - self.gf('django.db.models.fields.CharField')(default='default', max_length=120, blank=True), - keep_default=False) - - def backwards(self, orm): - # Deleting field 'Drip.message_class' - db.delete_column('drip_drip', 'message_class') - - 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'}) - }, - 'drip.drip': { - 'Meta': {'object_name': 'Drip'}, - 'body_html_template': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'from_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'from_email_name': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'message_class': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '120', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'subject_template': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'drip.querysetrule': { - 'Meta': {'object_name': 'QuerySetRule'}, - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'drip': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'queryset_rules'", 'to': "orm['drip.Drip']"}), - 'field_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'field_value': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'lookup_type': ('django.db.models.fields.CharField', [], {'default': "'exact'", 'max_length': '12'}), - 'method_type': ('django.db.models.fields.CharField', [], {'default': "'filter'", 'max_length': '12'}) - }, - 'drip.sentdrip': { - 'Meta': {'object_name': 'SentDrip'}, - 'body': ('django.db.models.fields.TextField', [], {}), - 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'drip': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_drips'", 'to': "orm['drip.Drip']"}), - 'from_email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'max_length': '75', 'null': 'True'}), - 'from_email_name': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '150', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject': ('django.db.models.fields.TextField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_drips'", 'to': "orm['auth.User']"}) - } - } - - complete_apps = ['drip'] \ No newline at end of file diff --git a/drip/migrations/__init__.py b/drip/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/drip/models.py b/drip/models.py index 94fa400..4d8a3b1 100644 --- a/drip/models.py +++ b/drip/models.py @@ -54,8 +54,16 @@ class SentDrip(models.Model): """ date = models.DateTimeField(auto_now_add=True) - drip = models.ForeignKey('drip.Drip', related_name='sent_drips') - user = models.ForeignKey(getattr(settings, 'AUTH_USER_MODEL', 'auth.User'), related_name='sent_drips') + drip = models.ForeignKey( + 'drip.Drip', + related_name='sent_drips', + on_delete=models.CASCADE, + ) + user = models.ForeignKey( + getattr(settings, 'AUTH_USER_MODEL', 'auth.User'), + related_name='sent_drips', + on_delete=models.CASCADE, + ) subject = models.TextField() body = models.TextField() @@ -94,7 +102,11 @@ class QuerySetRule(models.Model): date = models.DateTimeField(auto_now_add=True) lastchanged = models.DateTimeField(auto_now=True) - drip = models.ForeignKey(Drip, related_name='queryset_rules') + drip = models.ForeignKey( + Drip, + related_name='queryset_rules', + on_delete=models.CASCADE, + ) method_type = models.CharField(max_length=12, default='filter', choices=METHOD_TYPES) field_name = models.CharField(max_length=128, verbose_name='Field name of User') diff --git a/drip/tests.py b/drip/tests.py index 948d3a2..e63379d 100644 --- a/drip/tests.py +++ b/drip/tests.py @@ -3,7 +3,7 @@ from django.test import TestCase from django.test.client import RequestFactory from django.core.exceptions import ValidationError -from django.core.urlresolvers import resolve, reverse +from django.urls import resolve, reverse from django.core import mail from django.conf import settings from django.utils import timezone diff --git a/drip/utils.py b/drip/utils.py index 7bb2fe6..b55a471 100644 --- a/drip/utils.py +++ b/drip/utils.py @@ -2,7 +2,7 @@ from django.db import models from django.db.models import ForeignKey, OneToOneField, ManyToManyField -from django.db.models.related import RelatedObject +from django.db.models.fields.related import ForeignObjectRel as RelatedObject # taking a nod from python-requests and skipping six _ver = sys.version_info diff --git a/requirements.txt b/requirements.txt index 932bd37..ede7e65 100755 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,3 @@ django-timedeltafield==0.7.2 # development Sphinx==1.1.3 -South==1.0 diff --git a/test_urls.py b/test_urls.py index 9920823..587bce5 100644 --- a/test_urls.py +++ b/test_urls.py @@ -1,6 +1,7 @@ -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from django.contrib import admin admin.autodiscover() -urlpatterns = patterns("", - url(r'^admin/', include(admin.site.urls))) +urlpatterns = [ + url(r'^admin/', admin.site.urls), +] diff --git a/testsettings.py b/testsettings.py index 0713522..791e6a7 100755 --- a/testsettings.py +++ b/testsettings.py @@ -21,6 +21,7 @@ 'django.contrib.sessions', 'django.contrib.contenttypes', 'django.contrib.staticfiles', + 'django.contrib.messages', 'drip', @@ -28,7 +29,7 @@ 'credits', ) -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -37,6 +38,29 @@ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + # insert your TEMPLATE_DIRS here + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this + # list if you haven't customized them: + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + USE_TZ = True TIME_ZONE = 'UTC' From 94fd3e4b407781f7f5a77cf43139ae910303ee7d Mon Sep 17 00:00:00 2001 From: nsantos16 Date: Mon, 18 May 2020 16:09:35 -0300 Subject: [PATCH 2/5] Changes in django templates for provided compatibility with version 3.0 --- drip/templates/admin/drip/SentDrip/change_form.html | 3 +-- drip/templates/admin/drip/change_form.html | 3 +-- drip/templates/drip/timeline.html | 3 +-- drip/utils.py | 9 +++------ 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drip/templates/admin/drip/SentDrip/change_form.html b/drip/templates/admin/drip/SentDrip/change_form.html index a57983b..346871c 100644 --- a/drip/templates/admin/drip/SentDrip/change_form.html +++ b/drip/templates/admin/drip/SentDrip/change_form.html @@ -1,6 +1,5 @@ {% extends "admin/change_form.html" %} -{% load i18n admin_static admin_list %} -{% load url from future %} +{% load i18n static admin_list %} {% load admin_urls %} {% block object-tools-items %} diff --git a/drip/templates/admin/drip/change_form.html b/drip/templates/admin/drip/change_form.html index 56fe9a6..d8e490f 100644 --- a/drip/templates/admin/drip/change_form.html +++ b/drip/templates/admin/drip/change_form.html @@ -1,6 +1,5 @@ {% extends "admin/change_form.html" %} -{% load i18n admin_static admin_list %} -{% load url from future %} +{% load i18n static admin_list %} {% load admin_urls %} {% block object-tools-items %} diff --git a/drip/templates/drip/timeline.html b/drip/templates/drip/timeline.html index be50bb2..173f4e4 100644 --- a/drip/templates/drip/timeline.html +++ b/drip/templates/drip/timeline.html @@ -1,6 +1,5 @@ {% extends "admin/base_site.html" %} -{% load i18n admin_static admin_modify %} -{% load url from future %} +{% load i18n static admin_modify %} {% load admin_urls %} {% block title %}Viewing Timeline for {{ drip.name }}{% endblock title %} diff --git a/drip/utils.py b/drip/utils.py index b55a471..5d124f3 100644 --- a/drip/utils.py +++ b/drip/utils.py @@ -19,7 +19,7 @@ def get_fields(Model, parent_field="", - model_stack=None, + model_stack=[], stack_limit=2, excludes=['permissions', 'comment', 'content_type']): """ @@ -33,15 +33,12 @@ def get_fields(Model, """ out_fields = [] - if model_stack is None: - model_stack = [] - # github.com/omab/python-social-auth/commit/d8637cec02422374e4102231488481170dc51057 if isinstance(Model, basestring): app_label, model_name = Model.split('.') Model = models.get_model(app_label, model_name) - fields = Model._meta.fields + Model._meta.many_to_many + Model._meta.get_all_related_objects() + fields = Model._meta.fields + Model._meta.many_to_many + Model._meta.get_fields() model_stack.append(Model) # do a variety of checks to ensure recursion isnt being redundant @@ -88,7 +85,7 @@ def get_fields(Model, RelModel = field.model #field_names.extend(get_fields(RelModel, full_field, True)) else: - RelModel = field.related.parent_model + RelModel = field.related_model out_fields.extend(get_fields(RelModel, full_field, list(model_stack))) From 51c3b6951343ec2aa022b929fce91385f882434a Mon Sep 17 00:00:00 2001 From: Kalil de Lima Date: Fri, 29 May 2020 18:47:20 -0300 Subject: [PATCH 3/5] fix all tests --- drip/drips.py | 10 +-- drip/helpers.py | 146 ++++++++++++++++++++++++++++++++ drip/migrations/0001_initial.py | 58 +++++++++++++ drip/migrations/__init__.py | 0 drip/models.py | 11 ++- drip/tests.py | 3 +- 6 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 drip/helpers.py create mode 100644 drip/migrations/0001_initial.py create mode 100644 drip/migrations/__init__.py diff --git a/drip/drips.py b/drip/drips.py index 499caa4..a123564 100644 --- a/drip/drips.py +++ b/drip/drips.py @@ -184,12 +184,10 @@ def apply_queryset_rules(self, qs): ################## def get_queryset(self): - try: - return self._queryset - except AttributeError: - self._queryset = self.apply_queryset_rules(self.queryset())\ - .distinct() - return self._queryset + queryset = getattr(self,'_queryset', None) + if queryset is None: + self._queryset = self.apply_queryset_rules(self.queryset()).distinct() + return self._queryset def run(self): """ diff --git a/drip/helpers.py b/drip/helpers.py new file mode 100644 index 0000000..7edd754 --- /dev/null +++ b/drip/helpers.py @@ -0,0 +1,146 @@ + +import re +import datetime +from decimal import Decimal + +STRFDATETIME = re.compile('([dgGhHis])') +STRFDATETIME_REPL = lambda x: '%%(%s)s' % x.group() + +def parse(string): + """ + Parse a string into a timedelta object. + >>> parse("1 day") + datetime.timedelta(1) + >>> parse("2 days") + datetime.timedelta(2) + >>> parse("1 d") + datetime.timedelta(1) + >>> parse("1 hour") + datetime.timedelta(0, 3600) + >>> parse("1 hours") + datetime.timedelta(0, 3600) + >>> parse("1 hr") + datetime.timedelta(0, 3600) + >>> parse("1 hrs") + datetime.timedelta(0, 3600) + >>> parse("1h") + datetime.timedelta(0, 3600) + >>> parse("1wk") + datetime.timedelta(7) + >>> parse("1 week") + datetime.timedelta(7) + >>> parse("1 weeks") + datetime.timedelta(7) + >>> parse("2 wks") + datetime.timedelta(14) + >>> parse("1 sec") + datetime.timedelta(0, 1) + >>> parse("1 secs") + datetime.timedelta(0, 1) + >>> parse("1 s") + datetime.timedelta(0, 1) + >>> parse("1 second") + datetime.timedelta(0, 1) + >>> parse("1 seconds") + datetime.timedelta(0, 1) + >>> parse("1 minute") + datetime.timedelta(0, 60) + >>> parse("1 min") + datetime.timedelta(0, 60) + >>> parse("1 m") + datetime.timedelta(0, 60) + >>> parse("1 minutes") + datetime.timedelta(0, 60) + >>> parse("1 mins") + datetime.timedelta(0, 60) + >>> parse("2 ws") + Traceback (most recent call last): + ... + TypeError: '2 ws' is not a valid time interval + >>> parse("2 ds") + Traceback (most recent call last): + ... + TypeError: '2 ds' is not a valid time interval + >>> parse("2 hs") + Traceback (most recent call last): + ... + TypeError: '2 hs' is not a valid time interval + >>> parse("2 ms") + Traceback (most recent call last): + ... + TypeError: '2 ms' is not a valid time interval + >>> parse("2 ss") + Traceback (most recent call last): + ... + TypeError: '2 ss' is not a valid time interval + >>> parse("") + Traceback (most recent call last): + ... + TypeError: '' is not a valid time interval + >>> parse("1.5 days") + datetime.timedelta(1, 43200) + >>> parse("3 weeks") + datetime.timedelta(21) + >>> parse("4.2 hours") + datetime.timedelta(0, 15120) + >>> parse(".5 hours") + datetime.timedelta(0, 1800) + >>> parse(" hours") + Traceback (most recent call last): + ... + TypeError: 'hours' is not a valid time interval + >>> parse("1 hour, 5 mins") + datetime.timedelta(0, 3900) + >>> parse("-2 days") + datetime.timedelta(-2) + >>> parse("-1 day 0:00:01") + datetime.timedelta(-1, 1) + >>> parse("-1 day, -1:01:01") + datetime.timedelta(-2, 82739) + >>> parse("-1 weeks, 2 days, -3 hours, 4 minutes, -5 seconds") + datetime.timedelta(-5, 11045) + >>> parse("0 seconds") + datetime.timedelta(0) + >>> parse("0 days") + datetime.timedelta(0) + >>> parse("0 weeks") + datetime.timedelta(0) + >>> zero = datetime.timedelta(0) + >>> parse(nice_repr(zero)) + datetime.timedelta(0) + >>> parse(nice_repr(zero, 'minimal')) + datetime.timedelta(0) + >>> parse(nice_repr(zero, 'short')) + datetime.timedelta(0) + >>> parse(' 50 days 00:00:00 ') + datetime.timedelta(50) + """ + string = string.strip() + + if string == "": + raise TypeError("'%s' is not a valid time interval" % string) + # This is the format we get from sometimes Postgres, sqlite, + # and from serialization + d = re.match(r'^((?P[-+]?\d+) days?,? )?(?P[-+]?)(?P\d+):' + r'(?P\d+)(:(?P\d+(\.\d+)?))?$', + str(string)) + if d: + d = d.groupdict(0) + if d['sign'] == '-': + for k in 'hours', 'minutes', 'seconds': + d[k] = '-' + d[k] + d.pop('sign', None) + else: + # This is the more flexible format + d = re.match( + r'^((?P-?((\d*\.\d+)|\d+))\W*w((ee)?(k(s)?)?)(,)?\W*)?' + r'((?P-?((\d*\.\d+)|\d+))\W*d(ay(s)?)?(,)?\W*)?' + r'((?P-?((\d*\.\d+)|\d+))\W*h(ou)?(r(s)?)?(,)?\W*)?' + r'((?P-?((\d*\.\d+)|\d+))\W*m(in(ute)?(s)?)?(,)?\W*)?' + r'((?P-?((\d*\.\d+)|\d+))\W*s(ec(ond)?(s)?)?)?\W*$', + string) + if not d: + raise TypeError("'%s' is not a valid time interval" % string) + d = d.groupdict(0) + + return datetime.timedelta(**dict(( (k, float(v)) for k,v in d.items()))) diff --git a/drip/migrations/0001_initial.py b/drip/migrations/0001_initial.py new file mode 100644 index 0000000..0c1c8b9 --- /dev/null +++ b/drip/migrations/0001_initial.py @@ -0,0 +1,58 @@ +# Generated by Django 3.0.6 on 2020-05-29 20:38 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Drip', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField(auto_now_add=True)), + ('lastchanged', models.DateTimeField(auto_now=True)), + ('name', models.CharField(help_text='A unique name for this drip.', max_length=255, unique=True, verbose_name='Drip Name')), + ('enabled', models.BooleanField(default=False)), + ('from_email', models.EmailField(blank=True, help_text='Set a custom from email.', max_length=254, null=True)), + ('from_email_name', models.CharField(blank=True, help_text='Set a name for a custom from email.', max_length=150, null=True)), + ('subject_template', models.TextField(blank=True, null=True)), + ('body_html_template', models.TextField(blank=True, help_text='You will have settings and user in the context.', null=True)), + ('message_class', models.CharField(blank=True, default='default', max_length=120)), + ], + ), + migrations.CreateModel( + name='SentDrip', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField(auto_now_add=True)), + ('subject', models.TextField()), + ('body', models.TextField()), + ('from_email', models.EmailField(default=None, max_length=254, null=True)), + ('from_email_name', models.CharField(default=None, max_length=150, null=True)), + ('drip', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_drips', to='drip.Drip')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_drips', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='QuerySetRule', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField(auto_now_add=True)), + ('lastchanged', models.DateTimeField(auto_now=True)), + ('method_type', models.CharField(choices=[('filter', 'Filter'), ('exclude', 'Exclude')], default='filter', max_length=12)), + ('field_name', models.CharField(max_length=128, verbose_name='Field name of User')), + ('lookup_type', models.CharField(choices=[('exact', 'exactly'), ('iexact', 'exactly (case insensitive)'), ('contains', 'contains'), ('icontains', 'contains (case insensitive)'), ('regex', 'regex'), ('iregex', 'contains (case insensitive)'), ('gt', 'greater than'), ('gte', 'greater than or equal to'), ('lt', 'less than'), ('lte', 'less than or equal to'), ('startswith', 'starts with'), ('endswith', 'starts with'), ('istartswith', 'ends with (case insensitive)'), ('iendswith', 'ends with (case insensitive)')], default='exact', max_length=12)), + ('field_value', models.CharField(help_text='Can be anything from a number, to a string. Or, do `now-7 days` or `today+3 days` for fancy timedelta.', max_length=255)), + ('drip', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='queryset_rules', to='drip.Drip')), + ], + ), + ] diff --git a/drip/migrations/__init__.py b/drip/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/drip/models.py b/drip/models.py index 4d8a3b1..9653d92 100644 --- a/drip/models.py +++ b/drip/models.py @@ -8,8 +8,7 @@ # just using this to parse, but totally insane package naming... # https://bitbucket.org/schinckel/django-timedelta-field/ -import timedelta as djangotimedelta - +from drip.helpers import parse class Drip(models.Model): date = models.DateTimeField(auto_now_add=True) @@ -149,16 +148,16 @@ def filter_kwargs(self, qs, now=datetime.now): # set time deltas and dates if self.field_value.startswith('now-'): field_value = self.field_value.replace('now-', '') - field_value = now() - djangotimedelta.parse(field_value) + field_value = now() - parse(field_value) elif self.field_value.startswith('now+'): field_value = self.field_value.replace('now+', '') - field_value = now() + djangotimedelta.parse(field_value) + field_value = now() + parse(field_value) elif self.field_value.startswith('today-'): field_value = self.field_value.replace('today-', '') - field_value = now().date() - djangotimedelta.parse(field_value) + field_value = now().date() - parse(field_value) elif self.field_value.startswith('today+'): field_value = self.field_value.replace('today+', '') - field_value = now().date() + djangotimedelta.parse(field_value) + field_value = now().date() + parse(field_value) # F expressions if self.field_value.startswith('F_'): diff --git a/drip/tests.py b/drip/tests.py index e63379d..661525a 100644 --- a/drip/tests.py +++ b/drip/tests.py @@ -377,8 +377,7 @@ def test_apply_annotations_with_count(self): ) qs = qsr.apply_any_annotation(model_drip.drip.get_queryset()) - - self.assertEqual(list(qs.query.aggregate_select.keys()), ['num_profile_user_groups']) + self.assertEqual(list(qs.query.annotation_select.keys()), ['num_profile_user_groups']) def test_apply_multiple_rules_with_aggregation(self): From 364015c8d9e679b7f85029bb0671311ed64cf45d Mon Sep 17 00:00:00 2001 From: Kalil de Lima Date: Fri, 29 May 2020 18:50:34 -0300 Subject: [PATCH 4/5] remove unnecesary dependency on timedeltafield --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ede7e65..a1f4176 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ # production Django>=1.4 -django-timedeltafield==0.7.2 # development Sphinx==1.1.3 From fc40743f1e0ae0ab004ad553e80fedcfe0bbd4d3 Mon Sep 17 00:00:00 2001 From: Kalil de Lima Date: Fri, 29 May 2020 19:25:53 -0300 Subject: [PATCH 5/5] remove unneccesary empty line --- drip/helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/drip/helpers.py b/drip/helpers.py index 7edd754..d0bfb31 100644 --- a/drip/helpers.py +++ b/drip/helpers.py @@ -1,4 +1,3 @@ - import re import datetime from decimal import Decimal