From e05ac2ffa149403159f1784fce8c22061d463191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Fri, 10 Apr 2015 21:42:07 -0300 Subject: [PATCH 1/6] Saving name and description about a popit api instance --- global_test_case.py | 11 + .../0063_auto__add_aboutpopitapiinstance.py | 287 ++++++++++++++++++ nuntium/popit_api_instance.py | 29 ++ nuntium/tests/fixtures/popit_about_404.yaml | 29 ++ .../fixtures/uk_parliament_popit_about.yaml | 30 ++ nuntium/tests/popit_api_instance_tests.py | 53 +++- requirements.txt | 1 + 7 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py create mode 100644 nuntium/tests/fixtures/popit_about_404.yaml create mode 100644 nuntium/tests/fixtures/uk_parliament_popit_about.yaml diff --git a/global_test_case.py b/global_test_case.py index 951299f4..6d814c3b 100644 --- a/global_test_case.py +++ b/global_test_case.py @@ -14,6 +14,7 @@ from django.test import RequestFactory from django.test.client import Client import logging +import vcr _LOCALS = threading.local() @@ -167,6 +168,14 @@ class WriteItClient(WriteItRequestFactory, Client): pass +def popit_about_url_matcher(r1, r2): + url_contains_popit = 'popit' in r1.url + ends_in_about = (r1.url.endswith('/about/') or r1.url.endswith('/about')) + if url_contains_popit and ends_in_about: + return True + return False + + class WriteItTestCaseMixin(object): client_class = WriteItClient fixtures = ['example_data.yaml'] @@ -174,6 +183,8 @@ class WriteItTestCaseMixin(object): def setUp(self): self.site = Site.objects.get_current() self.factory = WriteItRequestFactory() + self.vcr = vcr.VCR() + self.vcr.register_matcher('popit_url', popit_about_url_matcher) def assertRedirects(self, response, expected_url, status_code=302, target_status_code=200, host=None, msg_prefix=''): self.assertEquals(response.status_code, status_code) diff --git a/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py b/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py new file mode 100644 index 00000000..7ad5dac5 --- /dev/null +++ b/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py @@ -0,0 +1,287 @@ +# -*- 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): + # Adding model 'AboutPopitApiInstance' + db.create_table(u'nuntium_aboutpopitapiinstance', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('popit_api_instance', self.gf('django.db.models.fields.related.OneToOneField')(related_name='about', unique=True, to=orm['popit.ApiInstance'])), + ('name', self.gf('django.db.models.fields.CharField')(max_length=512)), + ('description', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal(u'nuntium', ['AboutPopitApiInstance']) + + + def backwards(self, orm): + # Deleting model 'AboutPopitApiInstance' + db.delete_table(u'nuntium_aboutpopitapiinstance') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contactos.contact': { + 'Meta': {'object_name': 'Contact'}, + 'contact_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.ContactType']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_bounced': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'null': 'True', 'to': u"orm['auth.User']"}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'popit_identifier': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'null': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'contactos.contacttype': { + 'Meta': {'object_name': 'ContactType'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'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'}), + u'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'}) + }, + u'djangoplugins.plugin': { + 'Meta': {'ordering': "(u'_order',)", 'unique_together': "(('point', 'name'),)", 'object_name': 'Plugin'}, + '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'point': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangoplugins.PluginPoint']"}), + 'pythonpath': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}) + }, + u'djangoplugins.pluginpoint': { + 'Meta': {'object_name': 'PluginPoint'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pythonpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'nuntium.aboutpopitapiinstance': { + 'Meta': {'object_name': 'AboutPopitApiInstance'}, + 'description': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'popit_api_instance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'about'", 'unique': 'True', 'to': u"orm['popit.ApiInstance']"}) + }, + u'nuntium.answer': { + 'Meta': {'object_name': 'Answer'}, + 'content': ('django.db.models.fields.TextField', [], {}), + 'content_html': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': u"orm['nuntium.Message']"}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}) + }, + u'nuntium.answerattachment': { + 'Meta': {'object_name': 'AnswerAttachment'}, + 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['nuntium.Answer']"}), + 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '512'}) + }, + u'nuntium.answerwebhook': { + 'Meta': {'object_name': 'AnswerWebHook'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answer_webhooks'", 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.confirmation': { + 'Meta': {'object_name': 'Confirmation'}, + 'confirmated_at': ('django.db.models.fields.DateField', [], {'default': 'None', 'null': 'True'}), + 'created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.Message']", 'unique': 'True'}) + }, + u'nuntium.confirmationtemplate': { + 'Meta': {'object_name': 'ConfirmationTemplate'}, + 'content_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'content_text': ('django.db.models.fields.TextField', [], {'default': "u'Hello {author_name}\\n\\n\\nYou just submitted a message via {writeit_name}. Please visit the following link to confirm you want to send this message\\n\\n{confirmation_url}\\n\\n(If you can\\u2019t click the link, try copying and pasting it into your browser\\u2019s address bar)\\n\\n**IMPORTANT** Once confirmed and sent, the message will also be published on {writeit_name}, where your name, your message, and any replies, will be public and online for anyone to read, and will also appear in search engine results.\\n\\nIf this message didn\\u2019t come from you (or you\\u2019ve changed your mind and don\\u2019t want to send it after all) please just ignore this email.\\n\\nThanks for using {writeit_name}, and here is a copy of your message for your records:\\n\\n\\nTo: {recipients}\\nSubject: {subject}\\n\\n{content}\\n'"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'default': "u'Please confirm your WriteIt message to {recipients}\\n'", 'max_length': '512'}), + 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.WriteItInstance']", 'unique': 'True'}) + }, + u'nuntium.membership': { + 'Meta': {'object_name': 'Membership'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.message': { + 'Meta': {'ordering': "['-created']", 'object_name': 'Message'}, + 'author_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'confirmated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'moderated': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.messagerecord': { + 'Meta': {'object_name': 'MessageRecord'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + 'datetime': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'nuntium.moderation': { + 'Meta': {'object_name': 'Moderation'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'message': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'moderation'", 'unique': 'True', 'to': u"orm['nuntium.Message']"}) + }, + u'nuntium.newanswernotificationtemplate': { + 'Meta': {'object_name': 'NewAnswerNotificationTemplate'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject_template': ('django.db.models.fields.CharField', [], {'default': "u'{person} has replied to your message {subject}\\n'", 'max_length': '255'}), + 'template_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'template_text': ('django.db.models.fields.TextField', [], {'default': 'u\'Dear {author_name}\\n\\n{person} has replied to your {writeit_name}\\nmessage with subject\\n\\n"{subject}"\\n\\n\\nYou can see their response at\\n\\n{message_url}\\n\\n\\n{person} said:\\n\\n{content}\\n\\n-- \\n\\nThanks for using {writeit_name}\\n\''}), + 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'new_answer_notification_template'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.nocontactom': { + 'Meta': {'object_name': 'NoContactOM'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) + }, + u'nuntium.outboundmessage': { + 'Meta': {'object_name': 'OutboundMessage'}, + 'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.Contact']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) + }, + u'nuntium.outboundmessageidentifier': { + 'Meta': {'object_name': 'OutboundMessageIdentifier'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'outbound_message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.OutboundMessage']", 'unique': 'True'}) + }, + u'nuntium.outboundmessagepluginrecord': { + 'Meta': {'object_name': 'OutboundMessagePluginRecord'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'number_of_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'outbound_message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.OutboundMessage']"}), + 'plugin': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangoplugins.Plugin']"}), + 'sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'try_again': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'nuntium.ratelimiter': { + 'Meta': {'object_name': 'RateLimiter'}, + 'count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'day': ('django.db.models.fields.DateField', [], {}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.subscriber': { + 'Meta': {'object_name': 'Subscriber'}, + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subscribers'", 'to': u"orm['nuntium.Message']"}) + }, + u'nuntium.writeitinstance': { + 'Meta': {'object_name': 'WriteItInstance'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'writeitinstances'", 'to': u"orm['auth.User']"}), + 'persons': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'writeit_instances'", 'symmetrical': 'False', 'through': u"orm['nuntium.Membership']", 'to': u"orm['popit.Person']"}), + 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}) + }, + u'nuntium.writeitinstanceconfig': { + 'Meta': {'object_name': 'WriteItInstanceConfig'}, + 'allow_messages_using_form': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'autoconfirm_api_messages': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'can_create_answer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'custom_from_domain': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_host': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_host_password': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_host_user': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_port': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'email_use_ssl': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'email_use_tls': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'maximum_recipients': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'moderation_needed_in_all_messages': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'notify_owner_when_new_answer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'rate_limiter': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'testing_mode': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'writeitinstance': ('annoying.fields.AutoOneToOneField', [], {'related_name': "'config'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.writeitinstancepopitinstancerecord': { + 'Meta': {'object_name': 'WriteitInstancePopitInstanceRecord'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'periodicity': ('django.db.models.fields.CharField', [], {'default': "'1W'", 'max_length': "'2'"}), + 'popitapiinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.ApiInstance']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'nothing'", 'max_length': "'20'"}), + 'status_explanation': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'popit.apiinstance': { + 'Meta': {'object_name': 'ApiInstance'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'url': ('popit.fields.ApiInstanceURLField', [], {'unique': 'True', 'max_length': '200'}) + }, + u'popit.person': { + 'Meta': {'object_name': 'Person'}, + 'api_instance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.ApiInstance']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'popit_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'popit_url': ('popit.fields.PopItURLField', [], {'default': "''", 'max_length': '200', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['nuntium'] \ No newline at end of file diff --git a/nuntium/popit_api_instance.py b/nuntium/popit_api_instance.py index f89982b9..d99a5661 100644 --- a/nuntium/popit_api_instance.py +++ b/nuntium/popit_api_instance.py @@ -2,6 +2,8 @@ from contactos.models import Contact from mailit import MailChannel from datetime import datetime +from django.db import models +import slumber def get_date_or_none(membership_doc, key, format="%Y-%m-%d"): @@ -83,6 +85,12 @@ def create_contact(cls, obj, doc, writeitinstance): contact.save() +class AboutPopitApiInstance(models.Model): + popit_api_instance = models.OneToOneField('PopitApiInstance', related_name='about') + name = models.CharField(max_length=512) + description = models.TextField() + + class PopitApiInstance(ApiInstance): class Meta: proxy = True @@ -95,3 +103,24 @@ def fetch_all_from_api(self, writeitinstance): models = [PopitPerson] for model in models: model.fetch_all_from_api(instance=self, writeitinstance=writeitinstance) + + def get_about(self, about_class=AboutPopitApiInstance): + api = slumber.API(self.url) + ''' + Right here I depend a bit on popit and how it is going to behave in the future + so here it is the thing for example for https://yournextmp.popit.mysociety.org/api/v0.1 + there is no /about because the /about is in the root of the api in other words + https://yournextmp.popit.mysociety.org/api/about, so is ```about``` going to be part of /v0.1? + if the answer to that is No then we should strip the version of the api from the URL + which I'm not doing right now. + ''' + about = about_class(popit_api_instance=self) + try: + result = api.about().get() + for key in result['result'].keys(): + if hasattr(about, key): + setattr(about, key, result['result'][key]) + except slumber.exceptions.HttpClientError: + pass + about.save() + return about diff --git a/nuntium/tests/fixtures/popit_about_404.yaml b/nuntium/tests/fixtures/popit_about_404.yaml new file mode 100644 index 00000000..ba13b5e5 --- /dev/null +++ b/nuntium/tests/fixtures/popit_about_404.yaml @@ -0,0 +1,29 @@ +interactions: +- request: + body: null + headers: + Connection: [close] + Host: [yournextmp.popit.mysociety.org] + User-Agent: [Python-urllib/2.7] + method: GET + uri: https://yournextmp.popit.mysociety.org/api/v0.1/about + response: + body: {string: !!python/unicode "{\n \"errors\": [\n \"collection 'about' + not found\"\n ]\n}"} + headers: + accept-ranges: [bytes] + access-control-allow-origin: ['*'] + age: ['0'] + connection: [close] + content-length: ['56'] + content-type: [application/json; charset=utf-8] + date: ['Sat, 11 Apr 2015 00:44:13 GMT'] + etag: [W/"38-8b9a338f"] + server: [nginx] + set-cookie: [connect.sess=s%3Aj%3A%7B%22passport%22%3A%7B%7D%7D.UywPBji0dFbUMZW5r1RdSpofbQAIv7kGfQeO1FGtXmc; + Domain=.popit.mysociety.org; Path=/; HttpOnly; Secure] + vary: ['X-HTTP-Method-Override,Origin'] + x-content-type-options: [nosniff] + x-url: [/api/v0.1/about] + status: {code: 404, message: Not Found} +version: 1 diff --git a/nuntium/tests/fixtures/uk_parliament_popit_about.yaml b/nuntium/tests/fixtures/uk_parliament_popit_about.yaml new file mode 100644 index 00000000..e692b279 --- /dev/null +++ b/nuntium/tests/fixtures/uk_parliament_popit_about.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Connection: [close] + Host: [parliament.popit.mysociety.org] + User-Agent: [Python-urllib/2.7] + method: GET + uri: http://parliament.popit.mysociety.org/api/about/ + response: + body: {string: !!python/unicode "{\n \"result\": {\n \"name\": \"UK Parliament\",\n + \ \"description\": \"A list of everybody in both houses of the UK Parliament, + based on the Members' Data Platform.\",\n \"language\": \"en\",\n \"license\": + \"The **{{name}}** PopIt instance is made available under the [Open Database + License](http://opendatacommons.org/licenses/odbl/1.0/). Any rights in individual + contents of the database are licensed under the [Database Contents License](http://opendatacommons.org/licenses/dbcl/1.0/).\",\n + \ \"person_count\": 4138,\n \"organization_count\": 333\n }\n}"} + headers: + accept-ranges: [bytes] + age: ['0'] + connection: [close] + content-length: ['543'] + content-type: [application/json; charset=utf-8] + date: ['Fri, 10 Apr 2015 15:27:58 GMT'] + etag: [W/"21f-818edeb2"] + vary: [X-HTTP-Method-Override] + x-content-type-options: [nosniff] + x-url: [/api/about] + status: {code: 200, message: OK} +version: 1 diff --git a/nuntium/tests/popit_api_instance_tests.py b/nuntium/tests/popit_api_instance_tests.py index 32a4c843..953f7abe 100644 --- a/nuntium/tests/popit_api_instance_tests.py +++ b/nuntium/tests/popit_api_instance_tests.py @@ -8,7 +8,58 @@ from django.utils.unittest import skipUnless from django.conf import settings from django.contrib.auth.models import User -from nuntium.popit_api_instance import is_current_membership +from nuntium.popit_api_instance import is_current_membership, PopitApiInstance, AboutPopitApiInstance + + +class PopitApiInstanceAboutTestsCase(TestCase): + ''' + Ok so what I thought was: + PopitApiInstance is a proxy Model (https://docs.djangoproject.com/en/1.6/topics/db/models/#proxy-models) + which means that it doesn't have a database representation of its own + and I could make it proxy = True but then I would have to create a datamigration and + call me a chicken but I really really don't want to go that way, cause it looks scary =(. + So what I thought was that I could create a statellite class called AboutPopitApiInstance which would have some other information + about the PopitApiInstance like name and description in this TestCase I'm testing its creation as well as when I go and do instance.get_about() + it should go to popit get the about and store it. + ''' + def setUp(self): + super(PopitApiInstanceAboutTestsCase, self).setUp() + + def test_a_popit_instance_can_have_about(self): + '''A PopitApiInstance can have a about info''' + + popit_api_instance = PopitApiInstance.objects.get(id=1) + AboutPopitApiInstance.objects.create( + popit_api_instance=popit_api_instance, + name="UK Parliament", + description="A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.") + self.assertEquals(popit_api_instance.about.name, "UK Parliament") + self.assertEquals(popit_api_instance.about.description, "A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.") + + def test_importing_name_and_description_from_popit(self): + '''Getting it and retrieving the data''' + with self.vcr.use_cassette('nuntium/tests/fixtures/uk_parliament_popit_about.yaml', match_on=['popit_url']): + popit_api_instance = PopitApiInstance.objects.get(id=1) + about = popit_api_instance.get_about() + self.assertEquals(about.name, + "UK Parliament") + self.assertEquals(about.description, + "A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.") + + def test_cope_with_404_or_other_errors(self): + ''' + Even if there is an error with the url it creates an AboutPopitApiInstance object + ''' + with self.vcr.use_cassette('nuntium/tests/fixtures/popit_about_404.yaml', match_on=['popit_url']): + popit_api_instance = PopitApiInstance.objects.get(id=1) + about = popit_api_instance.get_about() + ''' + So the AboutPopitApiInstance is not None but the content in name and description are empty + ''' + self.assertTrue(about) + self.assertFalse(about.name) + self.assertFalse(about.description) + self.assertTrue(about.id) @skipUnless(settings.LOCAL_POPIT, "No local popit running") diff --git a/requirements.txt b/requirements.txt index 6628c151..3b6a1b3a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,3 +44,4 @@ celery-haystack==0.8 django-celery-transactions<0.2.0 django-downloadview==1.6 django-subdomains==2.0.4 +vcrpy==1.4.0 \ No newline at end of file From 6f19ddc65afa0c4271a0e0a2059a1065c64ec1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Sat, 11 Apr 2015 00:03:46 -0300 Subject: [PATCH 2/6] Changing the order of imports in INSTALLED_APPS (which is obvious) and using a class level attribute to refer to the about_class --- nuntium/popit_api_instance.py | 7 +++++-- writeit/settings.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/nuntium/popit_api_instance.py b/nuntium/popit_api_instance.py index d99a5661..52bbc696 100644 --- a/nuntium/popit_api_instance.py +++ b/nuntium/popit_api_instance.py @@ -92,6 +92,9 @@ class AboutPopitApiInstance(models.Model): class PopitApiInstance(ApiInstance): + about_class = AboutPopitApiInstance + + class Meta: proxy = True @@ -104,7 +107,7 @@ def fetch_all_from_api(self, writeitinstance): for model in models: model.fetch_all_from_api(instance=self, writeitinstance=writeitinstance) - def get_about(self, about_class=AboutPopitApiInstance): + def get_about(self): api = slumber.API(self.url) ''' Right here I depend a bit on popit and how it is going to behave in the future @@ -114,7 +117,7 @@ def get_about(self, about_class=AboutPopitApiInstance): if the answer to that is No then we should strip the version of the api from the URL which I'm not doing right now. ''' - about = about_class(popit_api_instance=self) + about = self.about_class(popit_api_instance=self) try: result = api.about().get() for key in result['result'].keys(): diff --git a/writeit/settings.py b/writeit/settings.py index bf06e463..8487a80c 100644 --- a/writeit/settings.py +++ b/writeit/settings.py @@ -198,10 +198,10 @@ 'annoying', 'celery_haystack', - 'nuntium', 'djangoplugins', 'pagination', 'popit', + 'nuntium', 'south', 'contactos', 'mailit', From 65d634bc78a2dad70840a95675c2d013ac972fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Fri, 10 Apr 2015 21:42:07 -0300 Subject: [PATCH 3/6] Saving name and description about a popit api instance --- global_test_case.py | 11 + .../0063_auto__add_aboutpopitapiinstance.py | 287 ++++++++++++++++++ nuntium/popit_api_instance.py | 28 ++ nuntium/tests/fixtures/popit_about_404.yaml | 29 ++ .../fixtures/uk_parliament_popit_about.yaml | 30 ++ nuntium/tests/popit_api_instance_tests.py | 53 +++- requirements.txt | 1 + 7 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py create mode 100644 nuntium/tests/fixtures/popit_about_404.yaml create mode 100644 nuntium/tests/fixtures/uk_parliament_popit_about.yaml diff --git a/global_test_case.py b/global_test_case.py index 951299f4..6d814c3b 100644 --- a/global_test_case.py +++ b/global_test_case.py @@ -14,6 +14,7 @@ from django.test import RequestFactory from django.test.client import Client import logging +import vcr _LOCALS = threading.local() @@ -167,6 +168,14 @@ class WriteItClient(WriteItRequestFactory, Client): pass +def popit_about_url_matcher(r1, r2): + url_contains_popit = 'popit' in r1.url + ends_in_about = (r1.url.endswith('/about/') or r1.url.endswith('/about')) + if url_contains_popit and ends_in_about: + return True + return False + + class WriteItTestCaseMixin(object): client_class = WriteItClient fixtures = ['example_data.yaml'] @@ -174,6 +183,8 @@ class WriteItTestCaseMixin(object): def setUp(self): self.site = Site.objects.get_current() self.factory = WriteItRequestFactory() + self.vcr = vcr.VCR() + self.vcr.register_matcher('popit_url', popit_about_url_matcher) def assertRedirects(self, response, expected_url, status_code=302, target_status_code=200, host=None, msg_prefix=''): self.assertEquals(response.status_code, status_code) diff --git a/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py b/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py new file mode 100644 index 00000000..7ad5dac5 --- /dev/null +++ b/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py @@ -0,0 +1,287 @@ +# -*- 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): + # Adding model 'AboutPopitApiInstance' + db.create_table(u'nuntium_aboutpopitapiinstance', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('popit_api_instance', self.gf('django.db.models.fields.related.OneToOneField')(related_name='about', unique=True, to=orm['popit.ApiInstance'])), + ('name', self.gf('django.db.models.fields.CharField')(max_length=512)), + ('description', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal(u'nuntium', ['AboutPopitApiInstance']) + + + def backwards(self, orm): + # Deleting model 'AboutPopitApiInstance' + db.delete_table(u'nuntium_aboutpopitapiinstance') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contactos.contact': { + 'Meta': {'object_name': 'Contact'}, + 'contact_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.ContactType']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_bounced': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'null': 'True', 'to': u"orm['auth.User']"}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'popit_identifier': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'null': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'contactos.contacttype': { + 'Meta': {'object_name': 'ContactType'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'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'}), + u'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'}) + }, + u'djangoplugins.plugin': { + 'Meta': {'ordering': "(u'_order',)", 'unique_together': "(('point', 'name'),)", 'object_name': 'Plugin'}, + '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'point': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangoplugins.PluginPoint']"}), + 'pythonpath': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}) + }, + u'djangoplugins.pluginpoint': { + 'Meta': {'object_name': 'PluginPoint'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'pythonpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'nuntium.aboutpopitapiinstance': { + 'Meta': {'object_name': 'AboutPopitApiInstance'}, + 'description': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'popit_api_instance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'about'", 'unique': 'True', 'to': u"orm['popit.ApiInstance']"}) + }, + u'nuntium.answer': { + 'Meta': {'object_name': 'Answer'}, + 'content': ('django.db.models.fields.TextField', [], {}), + 'content_html': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': u"orm['nuntium.Message']"}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}) + }, + u'nuntium.answerattachment': { + 'Meta': {'object_name': 'AnswerAttachment'}, + 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['nuntium.Answer']"}), + 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '512'}) + }, + u'nuntium.answerwebhook': { + 'Meta': {'object_name': 'AnswerWebHook'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answer_webhooks'", 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.confirmation': { + 'Meta': {'object_name': 'Confirmation'}, + 'confirmated_at': ('django.db.models.fields.DateField', [], {'default': 'None', 'null': 'True'}), + 'created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.Message']", 'unique': 'True'}) + }, + u'nuntium.confirmationtemplate': { + 'Meta': {'object_name': 'ConfirmationTemplate'}, + 'content_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'content_text': ('django.db.models.fields.TextField', [], {'default': "u'Hello {author_name}\\n\\n\\nYou just submitted a message via {writeit_name}. Please visit the following link to confirm you want to send this message\\n\\n{confirmation_url}\\n\\n(If you can\\u2019t click the link, try copying and pasting it into your browser\\u2019s address bar)\\n\\n**IMPORTANT** Once confirmed and sent, the message will also be published on {writeit_name}, where your name, your message, and any replies, will be public and online for anyone to read, and will also appear in search engine results.\\n\\nIf this message didn\\u2019t come from you (or you\\u2019ve changed your mind and don\\u2019t want to send it after all) please just ignore this email.\\n\\nThanks for using {writeit_name}, and here is a copy of your message for your records:\\n\\n\\nTo: {recipients}\\nSubject: {subject}\\n\\n{content}\\n'"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'default': "u'Please confirm your WriteIt message to {recipients}\\n'", 'max_length': '512'}), + 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.WriteItInstance']", 'unique': 'True'}) + }, + u'nuntium.membership': { + 'Meta': {'object_name': 'Membership'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.message': { + 'Meta': {'ordering': "['-created']", 'object_name': 'Message'}, + 'author_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'confirmated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'moderated': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.messagerecord': { + 'Meta': {'object_name': 'MessageRecord'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + 'datetime': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'nuntium.moderation': { + 'Meta': {'object_name': 'Moderation'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'message': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'moderation'", 'unique': 'True', 'to': u"orm['nuntium.Message']"}) + }, + u'nuntium.newanswernotificationtemplate': { + 'Meta': {'object_name': 'NewAnswerNotificationTemplate'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subject_template': ('django.db.models.fields.CharField', [], {'default': "u'{person} has replied to your message {subject}\\n'", 'max_length': '255'}), + 'template_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'template_text': ('django.db.models.fields.TextField', [], {'default': 'u\'Dear {author_name}\\n\\n{person} has replied to your {writeit_name}\\nmessage with subject\\n\\n"{subject}"\\n\\n\\nYou can see their response at\\n\\n{message_url}\\n\\n\\n{person} said:\\n\\n{content}\\n\\n-- \\n\\nThanks for using {writeit_name}\\n\''}), + 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'new_answer_notification_template'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.nocontactom': { + 'Meta': {'object_name': 'NoContactOM'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) + }, + u'nuntium.outboundmessage': { + 'Meta': {'object_name': 'OutboundMessage'}, + 'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.Contact']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) + }, + u'nuntium.outboundmessageidentifier': { + 'Meta': {'object_name': 'OutboundMessageIdentifier'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'outbound_message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.OutboundMessage']", 'unique': 'True'}) + }, + u'nuntium.outboundmessagepluginrecord': { + 'Meta': {'object_name': 'OutboundMessagePluginRecord'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'number_of_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'outbound_message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.OutboundMessage']"}), + 'plugin': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangoplugins.Plugin']"}), + 'sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'try_again': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'nuntium.ratelimiter': { + 'Meta': {'object_name': 'RateLimiter'}, + 'count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'day': ('django.db.models.fields.DateField', [], {}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.subscriber': { + 'Meta': {'object_name': 'Subscriber'}, + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subscribers'", 'to': u"orm['nuntium.Message']"}) + }, + u'nuntium.writeitinstance': { + 'Meta': {'object_name': 'WriteItInstance'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'writeitinstances'", 'to': u"orm['auth.User']"}), + 'persons': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'writeit_instances'", 'symmetrical': 'False', 'through': u"orm['nuntium.Membership']", 'to': u"orm['popit.Person']"}), + 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}) + }, + u'nuntium.writeitinstanceconfig': { + 'Meta': {'object_name': 'WriteItInstanceConfig'}, + 'allow_messages_using_form': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'autoconfirm_api_messages': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'can_create_answer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'custom_from_domain': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_host': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_host_password': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_host_user': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'email_port': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'email_use_ssl': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'email_use_tls': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'maximum_recipients': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'moderation_needed_in_all_messages': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'notify_owner_when_new_answer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'rate_limiter': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'testing_mode': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'writeitinstance': ('annoying.fields.AutoOneToOneField', [], {'related_name': "'config'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'nuntium.writeitinstancepopitinstancerecord': { + 'Meta': {'object_name': 'WriteitInstancePopitInstanceRecord'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'periodicity': ('django.db.models.fields.CharField', [], {'default': "'1W'", 'max_length': "'2'"}), + 'popitapiinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.ApiInstance']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'nothing'", 'max_length': "'20'"}), + 'status_explanation': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) + }, + u'popit.apiinstance': { + 'Meta': {'object_name': 'ApiInstance'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'url': ('popit.fields.ApiInstanceURLField', [], {'unique': 'True', 'max_length': '200'}) + }, + u'popit.person': { + 'Meta': {'object_name': 'Person'}, + 'api_instance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.ApiInstance']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'popit_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), + 'popit_url': ('popit.fields.PopItURLField', [], {'default': "''", 'max_length': '200', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['nuntium'] \ No newline at end of file diff --git a/nuntium/popit_api_instance.py b/nuntium/popit_api_instance.py index 351f1642..cbfd90a1 100644 --- a/nuntium/popit_api_instance.py +++ b/nuntium/popit_api_instance.py @@ -2,6 +2,7 @@ from contactos.models import Contact from mailit import MailChannel from datetime import datetime +from django.db import models import slumber @@ -93,6 +94,12 @@ def create_contact(cls, obj, doc, writeitinstance): contact.save() +class AboutPopitApiInstance(models.Model): + popit_api_instance = models.OneToOneField('PopitApiInstance', related_name='about') + name = models.CharField(max_length=512) + description = models.TextField() + + class PopitApiInstance(ApiInstance): class Meta: proxy = True @@ -105,3 +112,24 @@ def fetch_all_from_api(self, writeitinstance): models = [PopitPerson] for model in models: model.fetch_all_from_api(instance=self, writeitinstance=writeitinstance) + + def get_about(self, about_class=AboutPopitApiInstance): + api = slumber.API(self.url) + ''' + Right here I depend a bit on popit and how it is going to behave in the future + so here it is the thing for example for https://yournextmp.popit.mysociety.org/api/v0.1 + there is no /about because the /about is in the root of the api in other words + https://yournextmp.popit.mysociety.org/api/about, so is ```about``` going to be part of /v0.1? + if the answer to that is No then we should strip the version of the api from the URL + which I'm not doing right now. + ''' + about = about_class(popit_api_instance=self) + try: + result = api.about().get() + for key in result['result'].keys(): + if hasattr(about, key): + setattr(about, key, result['result'][key]) + except slumber.exceptions.HttpClientError: + pass + about.save() + return about diff --git a/nuntium/tests/fixtures/popit_about_404.yaml b/nuntium/tests/fixtures/popit_about_404.yaml new file mode 100644 index 00000000..ba13b5e5 --- /dev/null +++ b/nuntium/tests/fixtures/popit_about_404.yaml @@ -0,0 +1,29 @@ +interactions: +- request: + body: null + headers: + Connection: [close] + Host: [yournextmp.popit.mysociety.org] + User-Agent: [Python-urllib/2.7] + method: GET + uri: https://yournextmp.popit.mysociety.org/api/v0.1/about + response: + body: {string: !!python/unicode "{\n \"errors\": [\n \"collection 'about' + not found\"\n ]\n}"} + headers: + accept-ranges: [bytes] + access-control-allow-origin: ['*'] + age: ['0'] + connection: [close] + content-length: ['56'] + content-type: [application/json; charset=utf-8] + date: ['Sat, 11 Apr 2015 00:44:13 GMT'] + etag: [W/"38-8b9a338f"] + server: [nginx] + set-cookie: [connect.sess=s%3Aj%3A%7B%22passport%22%3A%7B%7D%7D.UywPBji0dFbUMZW5r1RdSpofbQAIv7kGfQeO1FGtXmc; + Domain=.popit.mysociety.org; Path=/; HttpOnly; Secure] + vary: ['X-HTTP-Method-Override,Origin'] + x-content-type-options: [nosniff] + x-url: [/api/v0.1/about] + status: {code: 404, message: Not Found} +version: 1 diff --git a/nuntium/tests/fixtures/uk_parliament_popit_about.yaml b/nuntium/tests/fixtures/uk_parliament_popit_about.yaml new file mode 100644 index 00000000..e692b279 --- /dev/null +++ b/nuntium/tests/fixtures/uk_parliament_popit_about.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Connection: [close] + Host: [parliament.popit.mysociety.org] + User-Agent: [Python-urllib/2.7] + method: GET + uri: http://parliament.popit.mysociety.org/api/about/ + response: + body: {string: !!python/unicode "{\n \"result\": {\n \"name\": \"UK Parliament\",\n + \ \"description\": \"A list of everybody in both houses of the UK Parliament, + based on the Members' Data Platform.\",\n \"language\": \"en\",\n \"license\": + \"The **{{name}}** PopIt instance is made available under the [Open Database + License](http://opendatacommons.org/licenses/odbl/1.0/). Any rights in individual + contents of the database are licensed under the [Database Contents License](http://opendatacommons.org/licenses/dbcl/1.0/).\",\n + \ \"person_count\": 4138,\n \"organization_count\": 333\n }\n}"} + headers: + accept-ranges: [bytes] + age: ['0'] + connection: [close] + content-length: ['543'] + content-type: [application/json; charset=utf-8] + date: ['Fri, 10 Apr 2015 15:27:58 GMT'] + etag: [W/"21f-818edeb2"] + vary: [X-HTTP-Method-Override] + x-content-type-options: [nosniff] + x-url: [/api/about] + status: {code: 200, message: OK} +version: 1 diff --git a/nuntium/tests/popit_api_instance_tests.py b/nuntium/tests/popit_api_instance_tests.py index 32a4c843..953f7abe 100644 --- a/nuntium/tests/popit_api_instance_tests.py +++ b/nuntium/tests/popit_api_instance_tests.py @@ -8,7 +8,58 @@ from django.utils.unittest import skipUnless from django.conf import settings from django.contrib.auth.models import User -from nuntium.popit_api_instance import is_current_membership +from nuntium.popit_api_instance import is_current_membership, PopitApiInstance, AboutPopitApiInstance + + +class PopitApiInstanceAboutTestsCase(TestCase): + ''' + Ok so what I thought was: + PopitApiInstance is a proxy Model (https://docs.djangoproject.com/en/1.6/topics/db/models/#proxy-models) + which means that it doesn't have a database representation of its own + and I could make it proxy = True but then I would have to create a datamigration and + call me a chicken but I really really don't want to go that way, cause it looks scary =(. + So what I thought was that I could create a statellite class called AboutPopitApiInstance which would have some other information + about the PopitApiInstance like name and description in this TestCase I'm testing its creation as well as when I go and do instance.get_about() + it should go to popit get the about and store it. + ''' + def setUp(self): + super(PopitApiInstanceAboutTestsCase, self).setUp() + + def test_a_popit_instance_can_have_about(self): + '''A PopitApiInstance can have a about info''' + + popit_api_instance = PopitApiInstance.objects.get(id=1) + AboutPopitApiInstance.objects.create( + popit_api_instance=popit_api_instance, + name="UK Parliament", + description="A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.") + self.assertEquals(popit_api_instance.about.name, "UK Parliament") + self.assertEquals(popit_api_instance.about.description, "A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.") + + def test_importing_name_and_description_from_popit(self): + '''Getting it and retrieving the data''' + with self.vcr.use_cassette('nuntium/tests/fixtures/uk_parliament_popit_about.yaml', match_on=['popit_url']): + popit_api_instance = PopitApiInstance.objects.get(id=1) + about = popit_api_instance.get_about() + self.assertEquals(about.name, + "UK Parliament") + self.assertEquals(about.description, + "A list of everybody in both houses of the UK Parliament, based on the Members' Data Platform.") + + def test_cope_with_404_or_other_errors(self): + ''' + Even if there is an error with the url it creates an AboutPopitApiInstance object + ''' + with self.vcr.use_cassette('nuntium/tests/fixtures/popit_about_404.yaml', match_on=['popit_url']): + popit_api_instance = PopitApiInstance.objects.get(id=1) + about = popit_api_instance.get_about() + ''' + So the AboutPopitApiInstance is not None but the content in name and description are empty + ''' + self.assertTrue(about) + self.assertFalse(about.name) + self.assertFalse(about.description) + self.assertTrue(about.id) @skipUnless(settings.LOCAL_POPIT, "No local popit running") diff --git a/requirements.txt b/requirements.txt index 6628c151..3b6a1b3a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,3 +44,4 @@ celery-haystack==0.8 django-celery-transactions<0.2.0 django-downloadview==1.6 django-subdomains==2.0.4 +vcrpy==1.4.0 \ No newline at end of file From a5d0f7f4b142e031ff412d350ce3bd1eb2346f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Sat, 11 Apr 2015 00:03:46 -0300 Subject: [PATCH 4/6] Changing the order of imports in INSTALLED_APPS (which is obvious) and using a class level attribute to refer to the about_class --- nuntium/popit_api_instance.py | 7 +++++-- writeit/settings.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/nuntium/popit_api_instance.py b/nuntium/popit_api_instance.py index cbfd90a1..f70827e4 100644 --- a/nuntium/popit_api_instance.py +++ b/nuntium/popit_api_instance.py @@ -101,6 +101,9 @@ class AboutPopitApiInstance(models.Model): class PopitApiInstance(ApiInstance): + about_class = AboutPopitApiInstance + + class Meta: proxy = True @@ -113,7 +116,7 @@ def fetch_all_from_api(self, writeitinstance): for model in models: model.fetch_all_from_api(instance=self, writeitinstance=writeitinstance) - def get_about(self, about_class=AboutPopitApiInstance): + def get_about(self): api = slumber.API(self.url) ''' Right here I depend a bit on popit and how it is going to behave in the future @@ -123,7 +126,7 @@ def get_about(self, about_class=AboutPopitApiInstance): if the answer to that is No then we should strip the version of the api from the URL which I'm not doing right now. ''' - about = about_class(popit_api_instance=self) + about = self.about_class(popit_api_instance=self) try: result = api.about().get() for key in result['result'].keys(): diff --git a/writeit/settings.py b/writeit/settings.py index 0d968596..e9841fd4 100644 --- a/writeit/settings.py +++ b/writeit/settings.py @@ -199,10 +199,10 @@ 'annoying', 'celery_haystack', - 'nuntium', 'djangoplugins', 'pagination', 'popit', + 'nuntium', 'south', 'contactos', 'mailit', From b0d18dce3749bed18057ba6beb3775d59d18cecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Mon, 20 Apr 2015 15:30:43 -0300 Subject: [PATCH 5/6] Updating migration 0063 that adds the model AboutPopitApiInstance --- ...> 0065_auto__add_aboutpopitapiinstance.py} | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) rename nuntium/migrations/{0063_auto__add_aboutpopitapiinstance.py => 0065_auto__add_aboutpopitapiinstance.py} (93%) diff --git a/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py b/nuntium/migrations/0065_auto__add_aboutpopitapiinstance.py similarity index 93% rename from nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py rename to nuntium/migrations/0065_auto__add_aboutpopitapiinstance.py index 7ad5dac5..cedc05c4 100644 --- a/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py +++ b/nuntium/migrations/0065_auto__add_aboutpopitapiinstance.py @@ -128,7 +128,7 @@ def backwards(self, orm): u'nuntium.confirmation': { 'Meta': {'object_name': 'Confirmation'}, 'confirmated_at': ('django.db.models.fields.DateField', [], {'default': 'None', 'null': 'True'}), - 'created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), + 'created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 20, 0, 0)'}), u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), 'message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.Message']", 'unique': 'True'}) @@ -136,9 +136,9 @@ def backwards(self, orm): u'nuntium.confirmationtemplate': { 'Meta': {'object_name': 'ConfirmationTemplate'}, 'content_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'content_text': ('django.db.models.fields.TextField', [], {'default': "u'Hello {author_name}\\n\\n\\nYou just submitted a message via {writeit_name}. Please visit the following link to confirm you want to send this message\\n\\n{confirmation_url}\\n\\n(If you can\\u2019t click the link, try copying and pasting it into your browser\\u2019s address bar)\\n\\n**IMPORTANT** Once confirmed and sent, the message will also be published on {writeit_name}, where your name, your message, and any replies, will be public and online for anyone to read, and will also appear in search engine results.\\n\\nIf this message didn\\u2019t come from you (or you\\u2019ve changed your mind and don\\u2019t want to send it after all) please just ignore this email.\\n\\nThanks for using {writeit_name}, and here is a copy of your message for your records:\\n\\n\\nTo: {recipients}\\nSubject: {subject}\\n\\n{content}\\n'"}), + 'content_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject': ('django.db.models.fields.CharField', [], {'default': "u'Please confirm your WriteIt message to {recipients}\\n'", 'max_length': '512'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.WriteItInstance']", 'unique': 'True'}) }, u'nuntium.membership': { @@ -165,7 +165,7 @@ def backwards(self, orm): u'nuntium.messagerecord': { 'Meta': {'object_name': 'MessageRecord'}, 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), - 'datetime': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), + 'datetime': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 20, 0, 0)'}), u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), 'status': ('django.db.models.fields.CharField', [], {'max_length': '255'}) @@ -179,9 +179,9 @@ def backwards(self, orm): u'nuntium.newanswernotificationtemplate': { 'Meta': {'object_name': 'NewAnswerNotificationTemplate'}, u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject_template': ('django.db.models.fields.CharField', [], {'default': "u'{person} has replied to your message {subject}\\n'", 'max_length': '255'}), + 'subject_template': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), 'template_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'template_text': ('django.db.models.fields.TextField', [], {'default': 'u\'Dear {author_name}\\n\\n{person} has replied to your {writeit_name}\\nmessage with subject\\n\\n"{subject}"\\n\\n\\nYou can see their response at\\n\\n{message_url}\\n\\n\\n{person} said:\\n\\n{content}\\n\\n-- \\n\\nThanks for using {writeit_name}\\n\''}), + 'template_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'new_answer_notification_template'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) }, u'nuntium.nocontactom': { @@ -189,6 +189,7 @@ def backwards(self, orm): u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}), 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) }, u'nuntium.outboundmessage': { @@ -196,6 +197,7 @@ def backwards(self, orm): 'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.Contact']"}), u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}), 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) }, u'nuntium.outboundmessageidentifier': { @@ -281,6 +283,12 @@ def backwards(self, orm): 'popit_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), 'popit_url': ('popit.fields.PopItURLField', [], {'default': "''", 'max_length': '200', 'unique': 'True', 'null': 'True', 'blank': 'True'}), 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + u'sites.site': { + 'Meta': {'ordering': "(u'domain',)", 'object_name': 'Site', 'db_table': "u'django_site'"}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) } } From 3d97456db1f9476dcc1c0dc1b82af8db37082c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Mon, 20 Apr 2015 18:00:38 -0300 Subject: [PATCH 6/6] Removing migration nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py that was still there for some reason --- .../0063_auto__add_aboutpopitapiinstance.py | 287 ------------------ 1 file changed, 287 deletions(-) delete mode 100644 nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py diff --git a/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py b/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py deleted file mode 100644 index 7ad5dac5..00000000 --- a/nuntium/migrations/0063_auto__add_aboutpopitapiinstance.py +++ /dev/null @@ -1,287 +0,0 @@ -# -*- 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): - # Adding model 'AboutPopitApiInstance' - db.create_table(u'nuntium_aboutpopitapiinstance', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('popit_api_instance', self.gf('django.db.models.fields.related.OneToOneField')(related_name='about', unique=True, to=orm['popit.ApiInstance'])), - ('name', self.gf('django.db.models.fields.CharField')(max_length=512)), - ('description', self.gf('django.db.models.fields.TextField')()), - )) - db.send_create_signal(u'nuntium', ['AboutPopitApiInstance']) - - - def backwards(self, orm): - # Deleting model 'AboutPopitApiInstance' - db.delete_table(u'nuntium_aboutpopitapiinstance') - - - models = { - u'auth.group': { - 'Meta': {'object_name': 'Group'}, - u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - u'auth.permission': { - 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), - u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - u'contactos.contact': { - 'Meta': {'object_name': 'Contact'}, - 'contact_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.ContactType']"}), - 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_bounced': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'null': 'True', 'to': u"orm['auth.User']"}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), - 'popit_identifier': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True'}), - 'value': ('django.db.models.fields.CharField', [], {'max_length': '512'}), - 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'contacts'", 'null': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'contactos.contacttype': { - 'Meta': {'object_name': 'ContactType'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'label_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - u'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'}), - u'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'}) - }, - u'djangoplugins.plugin': { - 'Meta': {'ordering': "(u'_order',)", 'unique_together': "(('point', 'name'),)", 'object_name': 'Plugin'}, - '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'point': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangoplugins.PluginPoint']"}), - 'pythonpath': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}) - }, - u'djangoplugins.pluginpoint': { - 'Meta': {'object_name': 'PluginPoint'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'pythonpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - u'nuntium.aboutpopitapiinstance': { - 'Meta': {'object_name': 'AboutPopitApiInstance'}, - 'description': ('django.db.models.fields.TextField', [], {}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), - 'popit_api_instance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'about'", 'unique': 'True', 'to': u"orm['popit.ApiInstance']"}) - }, - u'nuntium.answer': { - 'Meta': {'object_name': 'Answer'}, - 'content': ('django.db.models.fields.TextField', [], {}), - 'content_html': ('django.db.models.fields.TextField', [], {}), - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': u"orm['nuntium.Message']"}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}) - }, - u'nuntium.answerattachment': { - 'Meta': {'object_name': 'AnswerAttachment'}, - 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['nuntium.Answer']"}), - 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '512'}) - }, - u'nuntium.answerwebhook': { - 'Meta': {'object_name': 'AnswerWebHook'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), - 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answer_webhooks'", 'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'nuntium.confirmation': { - 'Meta': {'object_name': 'Confirmation'}, - 'confirmated_at': ('django.db.models.fields.DateField', [], {'default': 'None', 'null': 'True'}), - 'created': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), - 'message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.Message']", 'unique': 'True'}) - }, - u'nuntium.confirmationtemplate': { - 'Meta': {'object_name': 'ConfirmationTemplate'}, - 'content_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'content_text': ('django.db.models.fields.TextField', [], {'default': "u'Hello {author_name}\\n\\n\\nYou just submitted a message via {writeit_name}. Please visit the following link to confirm you want to send this message\\n\\n{confirmation_url}\\n\\n(If you can\\u2019t click the link, try copying and pasting it into your browser\\u2019s address bar)\\n\\n**IMPORTANT** Once confirmed and sent, the message will also be published on {writeit_name}, where your name, your message, and any replies, will be public and online for anyone to read, and will also appear in search engine results.\\n\\nIf this message didn\\u2019t come from you (or you\\u2019ve changed your mind and don\\u2019t want to send it after all) please just ignore this email.\\n\\nThanks for using {writeit_name}, and here is a copy of your message for your records:\\n\\n\\nTo: {recipients}\\nSubject: {subject}\\n\\n{content}\\n'"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject': ('django.db.models.fields.CharField', [], {'default': "u'Please confirm your WriteIt message to {recipients}\\n'", 'max_length': '512'}), - 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.WriteItInstance']", 'unique': 'True'}) - }, - u'nuntium.membership': { - 'Meta': {'object_name': 'Membership'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), - 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'nuntium.message': { - 'Meta': {'ordering': "['-created']", 'object_name': 'Message'}, - 'author_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), - 'confirmated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'moderated': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), - 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'nuntium.messagerecord': { - 'Meta': {'object_name': 'MessageRecord'}, - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), - 'datetime': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2015, 4, 10, 0, 0)'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'status': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - u'nuntium.moderation': { - 'Meta': {'object_name': 'Moderation'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '256'}), - 'message': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'moderation'", 'unique': 'True', 'to': u"orm['nuntium.Message']"}) - }, - u'nuntium.newanswernotificationtemplate': { - 'Meta': {'object_name': 'NewAnswerNotificationTemplate'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'subject_template': ('django.db.models.fields.CharField', [], {'default': "u'{person} has replied to your message {subject}\\n'", 'max_length': '255'}), - 'template_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'template_text': ('django.db.models.fields.TextField', [], {'default': 'u\'Dear {author_name}\\n\\n{person} has replied to your {writeit_name}\\nmessage with subject\\n\\n"{subject}"\\n\\n\\nYou can see their response at\\n\\n{message_url}\\n\\n\\n{person} said:\\n\\n{content}\\n\\n-- \\n\\nThanks for using {writeit_name}\\n\''}), - 'writeitinstance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'new_answer_notification_template'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'nuntium.nocontactom': { - 'Meta': {'object_name': 'NoContactOM'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), - 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.Person']"}), - 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) - }, - u'nuntium.outboundmessage': { - 'Meta': {'object_name': 'OutboundMessage'}, - 'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contactos.Contact']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.Message']"}), - 'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': "'10'"}) - }, - u'nuntium.outboundmessageidentifier': { - 'Meta': {'object_name': 'OutboundMessageIdentifier'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'outbound_message': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['nuntium.OutboundMessage']", 'unique': 'True'}) - }, - u'nuntium.outboundmessagepluginrecord': { - 'Meta': {'object_name': 'OutboundMessagePluginRecord'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'number_of_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), - 'outbound_message': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.OutboundMessage']"}), - 'plugin': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangoplugins.Plugin']"}), - 'sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'try_again': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) - }, - u'nuntium.ratelimiter': { - 'Meta': {'object_name': 'RateLimiter'}, - 'count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), - 'day': ('django.db.models.fields.DateField', [], {}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'nuntium.subscriber': { - 'Meta': {'object_name': 'Subscriber'}, - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subscribers'", 'to': u"orm['nuntium.Message']"}) - }, - u'nuntium.writeitinstance': { - 'Meta': {'object_name': 'WriteItInstance'}, - 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'writeitinstances'", 'to': u"orm['auth.User']"}), - 'persons': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'writeit_instances'", 'symmetrical': 'False', 'through': u"orm['nuntium.Membership']", 'to': u"orm['popit.Person']"}), - 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}) - }, - u'nuntium.writeitinstanceconfig': { - 'Meta': {'object_name': 'WriteItInstanceConfig'}, - 'allow_messages_using_form': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'autoconfirm_api_messages': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'can_create_answer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'custom_from_domain': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), - 'email_host': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), - 'email_host_password': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), - 'email_host_user': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), - 'email_port': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'email_use_ssl': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - 'email_use_tls': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'maximum_recipients': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), - 'moderation_needed_in_all_messages': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'notify_owner_when_new_answer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'rate_limiter': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'testing_mode': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'writeitinstance': ('annoying.fields.AutoOneToOneField', [], {'related_name': "'config'", 'unique': 'True', 'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'nuntium.writeitinstancepopitinstancerecord': { - 'Meta': {'object_name': 'WriteitInstancePopitInstanceRecord'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'periodicity': ('django.db.models.fields.CharField', [], {'default': "'1W'", 'max_length': "'2'"}), - 'popitapiinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.ApiInstance']"}), - 'status': ('django.db.models.fields.CharField', [], {'default': "'nothing'", 'max_length': "'20'"}), - 'status_explanation': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'writeitinstance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['nuntium.WriteItInstance']"}) - }, - u'popit.apiinstance': { - 'Meta': {'object_name': 'ApiInstance'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'url': ('popit.fields.ApiInstanceURLField', [], {'unique': 'True', 'max_length': '200'}) - }, - u'popit.person': { - 'Meta': {'object_name': 'Person'}, - 'api_instance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['popit.ApiInstance']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'popit_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'popit_url': ('popit.fields.PopItURLField', [], {'default': "''", 'max_length': '200', 'unique': 'True', 'null': 'True', 'blank': 'True'}), - 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}) - } - } - - complete_apps = ['nuntium'] \ No newline at end of file