class WriteItInstance(models.Model):
    """WriteItInstance: Entity that groups messages and people
    for usability purposes. E.g. 'Candidates running for president'"""
    name = models.CharField(max_length=255)
    description = models.CharField(max_length=512, blank=True)
    slug = AutoSlugField(populate_from='name', unique=True)
    persons = models.ManyToManyField(Person,
        related_name='writeit_instances',
        through='Membership')
    owner = models.ForeignKey(User, related_name="writeitinstances")

    def add_person(self, person):
        Membership.objects.get_or_create(writeitinstance=self, person=person)

    @property
    def persons_with_contacts(self):
        return self.persons.filter(contact__writeitinstance=self, contact__isnull=False).distinct()

    def relate_with_persons_from_popit_api_instance(self, popit_api_instance):
        try:
            popit_api_instance.fetch_all_from_api(writeitinstance=self)
        except ConnectionError, e:
            self.do_something_with_a_vanished_popit_api_instance(popit_api_instance)
            e.message = _('We could not connect with the URL')
            return (False, e)
        except Exception, e:
            self.do_something_with_a_vanished_popit_api_instance(popit_api_instance)
            return (False, e)
        persons = Person.objects.filter(api_instance=popit_api_instance)
        for person in persons:
            # There could be several memberships created.
            memberships = Membership.objects.filter(writeitinstance=self, person=person)
            if memberships.count() == 0:
                Membership.objects.create(writeitinstance=self, person=person)
            if memberships.count() > 1:
                membership = memberships[0]
                memberships.exclude(id=membership.id).delete()

        return (True, None)

    def do_something_with_a_vanished_popit_api_instance(self, popit_api_instance):
        pass

    def _load_persons_from_a_popit_api(self, popit_api_instance):
        success_relating_people, error = self.relate_with_persons_from_popit_api_instance(popit_api_instance)
        record = WriteitInstancePopitInstanceRecord.objects.get(
            writeitinstance=self,
            popitapiinstance=popit_api_instance
            )
        if success_relating_people:
            record.set_status('success')
        else:
            if isinstance(error, ConnectionError):
                record.set_status('error', _('We could not connect with the URL'))
            else:
                record.set_status('error', error.message)
        return (success_relating_people, error)

    def load_persons_from_a_popit_api(self, popit_url):
        '''This is an async wrapper for getting people from the api'''
        popit_api_instance, created = PopitApiInstance.objects.get_or_create(url=popit_url)
        record, created = WriteitInstancePopitInstanceRecord.objects.get_or_create(
            writeitinstance=self,
            popitapiinstance=popit_api_instance
            )
        if not created:
            record.updated = datetime.datetime.today()
            record.save()
        record.set_status('inprogress')
        from nuntium.tasks import pull_from_popit
        return pull_from_popit.delay(self, popit_api_instance)

    def get_absolute_url(self):
        return reverse('instance_detail', subdomain=self.slug)

    @property
    def pulling_from_popit_status(self):
        records = WriteitInstancePopitInstanceRecord.objects.filter(writeitinstance=self)
        result = {'nothing': 0, 'inprogress': 0, 'success': 0, 'error': 0}
        for record in records:
            result[record.status] += 1
        return result

    @property
    def can_create_messages(self):
        if self.config.allow_messages_using_form and \
                self.contacts.exists():
            return True

        return False

    def __unicode__(self):
        return self.name class WriteItInstanceConfig(models.Model):
    writeitinstance = AutoOneToOneField(WriteItInstance, related_name='config')
    testing_mode = models.BooleanField(default=True)
    moderation_needed_in_all_messages = models.BooleanField(
        help_text=_("Every message is going to \
        have a moderation mail"), default=False)
    allow_messages_using_form = models.BooleanField(
        help_text=_("Allow the creation of new messages \
        using the web"), default=True)
    rate_limiter = models.IntegerField(default=0)
    notify_owner_when_new_answer = models.BooleanField(
        help_text=_("The owner of this instance \
        should be notified \
        when a new answer comes in"), default=False)
    autoconfirm_api_messages = models.BooleanField(
        help_text=_("Messages pushed to the api should \
            be confirmed automatically"), default=True)

    custom_from_domain = models.CharField(max_length=512, null=True, blank=True)
    email_host = models.CharField(max_length=512, null=True, blank=True)
    email_host_password = models.CharField(max_length=512, null=True, blank=True)
    email_host_user = models.CharField(max_length=512, null=True, blank=True)
    email_port = models.IntegerField(null=True, blank=True)
    email_use_tls = models.NullBooleanField()
    email_use_ssl = models.NullBooleanField()
    can_create_answer = models.BooleanField(default=False, help_text="Can create an answer using the WebUI")
    maximum_recipients = models.PositiveIntegerField(default=5)
    default_language = models.CharField(max_length=10, choices=settings.LANGUAGES)

    def get_mail_connection(self):
        connection = mail.get_connection()
        if self.custom_from_domain:
            connection.host = self.email_host
            connection.password = self.email_host_password
            connection.username = self.email_host_user
            connection.port = self.email_port
            connection.use_tls = self.email_use_tls
        return connection class WriteitInstancePopitInstanceRecord(models.Model):
    STATUS_CHOICES = (
        ("nothing", _("Not doing anything now")),
        ("error", _("Error")),
        ("success", _("Success")),
        ("waiting", _("Waiting")),
        ("inprogress", _("In Progress")),
        )
    writeitinstance = models.ForeignKey(WriteItInstance)
    popitapiinstance = models.ForeignKey(ApiInstance)
    periodicity = models.CharField(
        max_length="2",
        choices=PERIODICITY,
        default='1W',
        )
    status = models.CharField(
        max_length="20",
        choices=STATUS_CHOICES,
        default="nothing",
        )
    status_explanation = models.TextField(default='')
    updated = models.DateTimeField(auto_now_add=True)
    created = models.DateTimeField(auto_now_add=True, editable=False)

    def __unicode__(self):
        return "The people from {url} were loaded into {instance}".format(
            url=self.popitapiinstance.url,
            instance=self.writeitinstance.__unicode__(),
            )

    def set_status(self, status, explanation=''):
        self.status = status
        self.status_explanation = explanation
        self.save() class Message(models.Model):
    """Message: Class that contain the info for a model, \
    despite of the input and the output channels. Subject \
    and content are mandatory fields"""
    author_name = models.CharField(max_length=512)
    author_email = models.EmailField()
    subject = models.CharField(max_length=255)
    content = models.TextField()
    writeitinstance = models.ForeignKey(WriteItInstance)
    confirmated = models.BooleanField(default=False)
    slug = models.SlugField(max_length=255, unique=True)
    public = models.BooleanField(default=True)
    moderated = models.NullBooleanField()
    created = models.DateTimeField(auto_now_add=True, null=True)
    updated = models.DateTimeField(auto_now=True, null=True)

    objects = MessagesManager()
    public_objects = PublicMessagesManager()
    moderation_required_objects = NonModeratedMessagesManager()

    class Meta:
        ordering = ["-created"]

    def __init__(self, *args, **kwargs):
        self.persons = None
        if 'persons' in kwargs:
            self.persons = kwargs.pop('persons')

        super(Message, self).__init__(*args, **kwargs)

    def clean(self):
        try:
            rate_limiter = RateLimiter.objects.get(
                writeitinstance=self.writeitinstance,
                email=self.author_email,
                day=datetime.date.today()
                )
            if self.writeitinstance.config.rate_limiter > 0 and \
                    rate_limiter.count >= self.writeitinstance.config.rate_limiter:
                raise ValidationError(_('You have reached '
                    + 'your limit for today please try again tomorrow'))
        except ObjectDoesNotExist:
            pass
        super(Message, self).clean()

    #TODO: only new outbound_messages
    def recently_confirmated(self):
        status = 'ready'
        if not self.public or \
                self.writeitinstance.config.moderation_needed_in_all_messages:
            moderation, created = Moderation.objects.get_or_create(message=self)
            self.send_moderation_mail()
            status = 'needmodera'
        for outbound_message in self.outbound_messages:
            outbound_message.status = status
            outbound_message.save()

        if self.author_email:
            Subscriber.objects.create(email=self.author_email, message=self)
        self.confirmated = True
        self.save()

    @property
    def people(self):
        people = Person.objects.filter(
            Q(contact__outboundmessage__message=self) |
            Q(nocontactom__message=self)
            ).distinct()

        return people

    @property
    def outbound_messages(self):
        no_contact_oms = NoContactOM.objects.filter(message=self)
        outbound_messages = OutboundMessage.objects.filter(message=self)

        return list(chain(no_contact_oms, outbound_messages))

    def get_absolute_url(self):
        return reverse(
            'thread_read',
            subdomain=self.writeitinstance.slug,
            kwargs={
                'slug': self.slug,
                },
            )

    def slugifyme(self):
        if not slugify(unidecode(unicode(self.subject))):
            self.subject = '-'

        self.slug = slugify(unidecode(unicode(self.subject)))
        #Previously created messages with the same slug

        regex = "^" + self.slug + "(-[0-9]*){0,1}$"
        previously = Message.objects.filter(slug__regex=regex)
        count = 1
        for message in previously:
            new_regex = "^" + self.slug + "-(\d+){0,1}$"
            if re.match(new_regex, message.slug) is not None:
                groups = re.match(new_regex, message.slug).groups()
                if len(groups) > 0:
                    if int(groups[0]) > count:
                        count = int(groups[0])

        previously = previously.count()
        if previously > 0:
            self.slug = self.slug + '-' + str(count + 1)

    def veryfy_people(self):
        if not self.persons:
            raise TypeError(_('A message needs persons to be sent'))

    def create_moderation(self):
        Moderation.objects.create(message=self)

    def create_outbound_messages(self):
        if not self.persons:
            return
        for person in self.persons:
            self.create_outbound_messages_to_person(person)

    def create_outbound_messages_to_person(self, person):
        if not person.contact_set.all():
            NoContactOM.objects.get_or_create(message=self, person=person, site=Site.objects.get_current())
            return
        for contact in person.contact_set.filter(writeitinstance=self.writeitinstance):
            if not contact.is_bounced:
                OutboundMessage.objects.get_or_create(
                    contact=contact, message=self, site=Site.objects.get_current())

    def save(self, *args, **kwargs):
        created = self.id is None
        if created and self.writeitinstance.config.moderation_needed_in_all_messages:
            self.moderated = False
        super(Message, self).save(*args, **kwargs)
        if created and not self.public:
            self.create_moderation()
        self.create_outbound_messages()

    def set_to_ready(self):
        for outbound_message in self.outbound_messages:
            outbound_message.status = 'ready'
            outbound_message.save()

    def send_moderation_mail(self):
        url_reject = reverse('moderation_rejected',
            subdomain=self.writeitinstance.slug,
            kwargs={
                'slug': self.moderation.key
            })

        url_accept = reverse('moderation_accept',
            subdomain=self.writeitinstance.slug,
            kwargs={
                'slug': self.moderation.key
            })

        context = {
            'owner_name': self.writeitinstance.owner.username,
            'author_name': self.author_name,
            'author_email': self.author_email,
            'recipients': u', '.join([x.name for x in self.people]),
            'subject': self.subject,
            'content': self.content,
            'site_name': self.writeitinstance.name,
            'url_reject': url_reject,
            'url_accept': url_accept,
            }

        if settings.SEND_ALL_EMAILS_FROM_DEFAULT_FROM_EMAIL:
            from_email = settings.DEFAULT_FROM_EMAIL
        else:
            from_domain = self.writeitinstance.config.custom_from_domain\
                or settings.DEFAULT_FROM_DOMAIN
            from_email = self.writeitinstance.slug + "@" + from_domain

        connection = self.writeitinstance.config.get_mail_connection()
        msg = EmailMultiAlternatives(
            moderation_subject.format(**context),
            template_with_wrap(moderation_content_txt, context),
            from_email,
            [self.writeitinstance.owner.email],
            connection=connection,
            )
        msg.send()

    def moderate(self):
        if not self.confirmated:
            raise ValidationError(_('The message needs '
                + 'to be confirmated first'))
        self.set_to_ready()
        self.moderation.success()

    def __unicode__(self):
        return _('%(subject)s at %(instance)s') % {
            'subject': self.subject,
            'instance': self.writeitinstance.name,
            } class NewAnswerNotificationTemplate(models.Model):
    writeitinstance = models.OneToOneField(
        WriteItInstance,
        related_name='new_answer_notification_template',
        )
    template_html = models.TextField(
        blank=True,
        help_text=_('You can use {author_name}, {person}, {subject}, {content}, {message_url}, and {site_name}'),
        )
    template_text = models.TextField(
        blank=True,
        help_text=_('You can use {author_name}, {person}, {subject}, {content}, {message_url}, and {site_name}'),
        )
    subject_template = models.CharField(
        max_length=255,
        blank=True,
        help_text=_('You can use {author_name}, {person}, {subject}, {content}, {message_url}, and {site_name}'),
        )

    def __unicode__(self):
        return _("Notification template for %s") % self.writeitinstance.name

    def get_content_template(self):
        return self.template_text or default_new_answer_content_template

    def get_subject_template(self):
        return self.subject_template or default_new_answer_subject_template class ConfirmationTemplate(models.Model):
    writeitinstance = models.OneToOneField(WriteItInstance)
    content_html = models.TextField(
        blank=True,
        help_text=_('You can use {author_name}, {site_name}, {subject}, {content}, {recipients}, {confirmation_url}, and {message_url}'),
        )
    content_text = models.TextField(
        blank=True,
        help_text=_('You can use {author_name}, {site_name}, {subject}, {content}, {recipients}, {confirmation_url}, and {message_url}'),
        )
    subject = models.CharField(
        max_length=512,
        blank=True,
        help_text=_('You can use {author_name}, {site_name}, {subject}, {content}, {recipients}, {confirmation_url}, and {message_url}'),
        )

    def get_content_template(self):
        return self.content_text or default_confirmation_template_content_text

    def get_subject_template(self):
        return self.subject or default_confirmation_template_subject class Answer(models.Model):
    content = models.TextField()
    content_html = models.TextField()
    person = models.ForeignKey(Person)
    message = models.ForeignKey(Message, related_name='answers')
    created = models.DateTimeField(auto_now=True, null=True)

    def save(self, *args, **kwargs):
        memberships = self.message.writeitinstance.membership_set.filter(person=self.person)
        if memberships.count() == 0:
            raise AttributeError(_("This guy does not belong here"))
        super(Answer, self).save(*args, **kwargs)

    def __unicode__(self):
        return _("%(person)s said \"%(content)s\""
                 + " to the message %(message)s") % {
            'person': self.person.name,
            'content': self.content,
            'message': self.message.subject,
            } class Moderation(models.Model):
    message = models.OneToOneField(Message, related_name='moderation')
    key = models.CharField(max_length=256)

    def save(self, *args, **kwargs):
        created = self.id is None
        if created:
            self.key = str(uuid.uuid1().hex)
        super(Moderation, self).save(*args, **kwargs)

    def success(self):
        self.message.moderated = True
        self.message.save()

    def get_success_url(self):
        return reverse('moderation_accept',
            subdomain=self.message.writeitinstance.slug,
            kwargs={
                'slug': self.key
            })

    def get_reject_url(self):
        return reverse('moderation_rejected',
            subdomain=self.message.writeitinstance.slug,
            kwargs={
                'slug': self.key
            }) class AnswerWebHook(models.Model):
    url = models.URLField(max_length=255)
    writeitinstance = models.ForeignKey(
        WriteItInstance,
        related_name='answer_webhooks',
        )

    def __unicode__(self):
        return '%(url)s at %(instance)s' % {
            'url': self.url,
            'instance': self.writeitinstance.name
        } class WriteItInstanceBasicForm(ModelForm):
    language = ChoiceField(choices=settings.LANGUAGES, widget=Select(attrs={'class':'form-control'}))

    def __init__(self, *args, **kwargs):
        try:
            kwargs['initial']['language'] = kwargs['instance'].config.default_language
        except KeyError:
            pass
        super(WriteItInstanceBasicForm, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        ret = super(WriteItInstanceBasicForm, self).save(*args, **kwargs)
        ret.config.default_language = self.cleaned_data['language']
        ret.config.save()
        return ret

    class Meta:
        model = WriteItInstance
        fields = ['name', 'description']

        widgets = {
            'name': TextInput(attrs={'class': 'form-control'}),
            'description': TextInput(
                attrs={
                    'class': 'form-control',
                    'placeholder': _('Write to the people who represent you.'),
                    }),
            } class NewAnswerNotificationTemplateForm(ModelForm):
    def __init__(self, *args, **kwargs):
        self.writeitinstance = kwargs.pop('writeitinstance')
        super(NewAnswerNotificationTemplateForm, self).__init__(*args, **kwargs)
        self.initial['template_text'] = self.initial['template_text'] or default_new_answer_content_template
        self.initial['subject_template'] = self.initial['subject_template'] or default_new_answer_subject_template

    def save(self, commit=True):
        template = super(NewAnswerNotificationTemplateForm, self).save(commit=False)
        if self.cleaned_data['template_text'] == default_new_answer_content_template:
            self.cleaned_data['template_text'] = None
        if self.cleaned_data['subject_template'] == default_new_answer_subject_template:
            self.cleaned_data['subject_template'] = None

        template.writeitinstance = self.writeitinstance
        if commit:
            template.save()
        return template

    class Meta:
        model = NewAnswerNotificationTemplate
        fields = ['subject_template', 'template_text']

        widgets = {
            'subject_template': TextInput(attrs={'class': 'form-control'}),
            'template_text': Textarea(attrs={'class': 'form-control'}),
        } class ConfirmationTemplateForm(ModelForm):
    class Meta:
        model = ConfirmationTemplate
        fields = ['subject', 'content_text']
        widgets = {
            'subject': TextInput(attrs={'class': 'form-control'}),
            'content_text': Textarea(attrs={'class': 'form-control'}),
        }

    def __init__(self, *args, **kwargs):
        if "writeitinstance" not in kwargs:
            raise ValidationError(_("WriteIt Instance not present"))
        self.writeitinstance = kwargs.pop("writeitinstance")
        super(ConfirmationTemplateForm, self).__init__(*args, **kwargs)
        self.initial['subject'] = self.initial['subject'] or default_confirmation_template_subject
        self.initial['content_text'] = self.initial['content_text'] or default_confirmation_template_content_text

    def save(self, commit=True):
        template = super(ConfirmationTemplateForm, self).save(commit=commit)
        if template.subject == default_confirmation_template_subject:
            template.subject = u''
        if template.content_text == default_confirmation_template_content_text:
            template.content_text = u''
        if commit:
            template.save()
        return template class WriteItInstanceAnswerNotificationForm(ModelForm):
    class Meta:
        model = WriteItInstanceConfig
        fields = ['notify_owner_when_new_answer']
        widgets = {
            'notify_owner_when_new_answer': CheckboxInput(attrs={'class': 'form-control'}),
        } class WriteItInstanceApiAutoconfirmForm(ModelForm):
    class Meta:
        model = WriteItInstanceConfig
        fields = ['autoconfirm_api_messages']
        widgets = {
            'autoconfirm_api_messages': CheckboxInput(attrs={'class': 'form-control'}),
        } class WriteItInstanceCreateForm(WriteItInstanceCreateFormPopitUrl):
    slug = CharField(
        label=_("The subdomain your site will run at"),
        help_text=_("Choose wisely; this can't be changed."),
        required=True,
        min_length=4,
        )

    class Meta:
        model = WriteItInstance
        fields = ('popit_url', 'slug')

    def __init__(self, *args, **kwargs):
        if 'owner' in kwargs:
            self.owner = kwargs.pop('owner')
        super(WriteItInstanceCreateForm, self).__init__(*args, **kwargs)
        self.fields['popit_url'].widget.attrs['class'] = 'form-control'
        self.fields['popit_url'].widget.attrs['required'] = True
        self.fields['slug'].widget.attrs['class'] = 'form-control'

    def clean_slug(self):
        slug = self.cleaned_data['slug']
        if not slug:
            return slug
        url_validator = validators.URLValidator(message="Enter a valid subdomain")
        url = 'http://%s.example.com' % slug
        url_validator(url)
        slug_exists = WriteItInstance.objects.filter(slug__iexact=slug).exists()
        if slug_exists:
            raise ValidationError(_("This subdomain has already been taken."))
        return slug

    def save(self, commit=True):
        instance = super(WriteItInstanceCreateForm, self).save(commit=False)
        slug = self.cleaned_data['slug']
        instance.slug = slug
        instance.name = slug
        instance.owner = self.owner
        instance.save()
        instance.config.default_language = settings.LANGUAGE_CODE
        instance.config.save()
        self.relate_with_people()
        return instance class WriteItInstanceModerationForm(ModelForm):
    class Meta:
        model = WriteItInstanceConfig
        fields = ['moderation_needed_in_all_messages']
        widgets = {
            'moderation_needed_in_all_messages': CheckboxInput(attrs={'class': 'form-control'}),
        } class WriteItInstanceMaxRecipientsForm(ModelForm):
    class Meta:
        model = WriteItInstanceConfig
        fields = ['maximum_recipients']
        widgets = {
            'maximum_recipients': NumberInput(attrs={'class': 'form-control'}),
        }

    def __init__(self, *args, **kwargs):
        super(WriteItInstanceMaxRecipientsForm, self).__init__(*args, **kwargs)
        self.fields['maximum_recipients'].validators.append(validators.MinValueValidator(1))
        self.fields['maximum_recipients'].validators.append(validators.MaxValueValidator(settings.OVERALL_MAX_RECIPIENTS)) class WriteItInstanceRateLimiterForm(ModelForm):
    class Meta:
        model = WriteItInstanceConfig
        fields = ['rate_limiter']
        widgets = {'rate_limiter': NumberInput(attrs={'class': 'form-control', 'min': 0})}

    def __init__(self, *args, **kwargs):
        super(WriteItInstanceRateLimiterForm, self).__init__(*args, **kwargs)
        self.fields['rate_limiter'].validators.append(validators.MinValueValidator(0)) class WriteItInstanceWebBasedForm(ModelForm):
    class Meta:
        model = WriteItInstanceConfig
        fields = ['allow_messages_using_form']
        widgets = {
            'allow_messages_using_form': CheckboxInput(attrs={'class': 'form-control'}),
        } class AnswerForm(ModelForm):
    person = ModelChoiceField(queryset=Person.objects.none())

    class Meta:
        model = Answer
        fields = ('person', 'content')
        widgets = {
            'content': TextInput(attrs={'class': 'form-control'})
        }

    def __init__(self, *args, **kwargs):
        self.message = kwargs.pop('message')
        super(AnswerForm, self).__init__(*args, **kwargs)
        self.fields['person'].queryset = self.message.people
        self.fields['person'].widget.attrs['class'] = 'form-control'

    def save(self, commit=True):
        answer = super(AnswerForm, self).save(commit=False)
        answer.message = self.message
        answer.save()
        return answer class RelatePopitInstanceWithWriteItInstance(Form, PopitParsingFormMixin):
    popit_url = URLField(
        label=_('Popolo URL'),
        help_text=_("Example: https://cdn.rawgit.com/everypolitician/everypolitician-data/1460373/data/Abkhazia/Assembly/ep-popolo-v1.0.json"),
        )

    def __init__(self, *args, **kwargs):
        self.writeitinstance = kwargs.pop('writeitinstance')
        super(RelatePopitInstanceWithWriteItInstance, self).__init__(*args, **kwargs)

    def relate(self):
        result = self.writeitinstance.load_persons_from_a_popit_api(
            self.cleaned_data['popit_url']
            )
        return result

    def clean(self, *args, **kwargs):
        cleaned_data = super(RelatePopitInstanceWithWriteItInstance, self).clean(*args, **kwargs)
        if self.writeitinstance.writeitinstancepopitinstancerecord_set.filter(popitapiinstance__url=cleaned_data.get('popit_url')):
            self.relate()
            raise ValidationError(_("You have already added this source. But we will fetch the data from it again now."))
        return cleaned_data class WebhookCreateForm(ModelForm):
    class Meta:
        model = AnswerWebHook
        fields = ['url']

    def __init__(self, *args, **kwargs):
        self.writeitinstance = kwargs.pop('writeitinstance')
        super(WebhookCreateForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        webhook = super(WebhookCreateForm, self).save(commit=False)
        webhook.writeitinstance = self.writeitinstance
        webhook.save()
        return webhook class PopitApiInstance(ApiInstance):
    class Meta:
        proxy = True

    def fetch_all_from_api(self, writeitinstance):
        """
        Update all the local data from the API. This method actually delegates
        to the other models.
        """
        models = [PopitPerson]
        for model in models:
            model.fetch_all_from_api(instance=self, writeitinstance=writeitinstance) @task()
def pull_from_popit(writeitinstance, popit_api_instance):
    result = writeitinstance._load_persons_from_a_popit_api(popit_api_instance)
    logger.info(u'Resyncing ' + writeitinstance.__unicode__() + u' with ' + popit_api_instance.__unicode__())
    return result class WriteItPopitUpdateForm(ModelForm):
    class Meta:
        model = WriteitInstancePopitInstanceRecord
        fields = ['periodicity']
import requests
import json
from django.contrib.auth.decorators import login_required
from subdomains.utils import reverse
from django.http import HttpResponse, Http404
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView, CreateView, DetailView, View, ListView, RedirectView
from django.views.generic.edit import UpdateView, DeleteView, FormView
from mailit.forms import MailitTemplateForm
from instance.models import WriteItInstance, WriteItInstanceConfig, WriteitInstancePopitInstanceRecord
from ..models import Message,\
    NewAnswerNotificationTemplate, ConfirmationTemplate, \
    Answer, Moderation, \
    AnswerWebHook
from .forms import WriteItInstanceBasicForm, \
    NewAnswerNotificationTemplateForm, ConfirmationTemplateForm, \
    WriteItInstanceAnswerNotificationForm, \
    WriteItInstanceApiAutoconfirmForm, \
    WriteItInstanceCreateForm, \
    WriteItInstanceModerationForm, \
    WriteItInstanceMaxRecipientsForm, \
    WriteItInstanceRateLimiterForm, \
    WriteItInstanceWebBasedForm, \
    AnswerForm, RelatePopitInstanceWithWriteItInstance, \
    WebhookCreateForm
from django.contrib import messages as view_messages
from django.utils.translation import ugettext as _
from nuntium.popit_api_instance import PopitApiInstance
from nuntium.tasks import pull_from_popit
from nuntium.user_section.forms import WriteItPopitUpdateForm
from django.contrib.sites.models import Site
            writeitinstancepopitinstancerecord__writeitinstance=writeitinstance)

        popit_api_instance = get_object_or_404(popits_previously_related, pk=kwargs['popit_api_pk'])
        pull_from_popit.delay(writeitinstance, popit_api_instance)
        return HttpResponse()


class WriteItPopitUpdateView(UpdateView):
    form_class = WriteItPopitUpdateForm
    model = WriteitInstancePopitInstanceRecord

    def get_writeitinstance(self):
        self.writeitinstance = get_object_or_404(WriteItInstance, slug=self.request.subdomain, owner=self.request.user)

    def dispatch(self, *args, **kwargs):
        self.get_writeitinstance()
        if self.request.method != 'POST':
            return self.http_method_not_allowed(*args, **kwargs)
        return super(WriteItPopitUpdateView, self).dispatch(*args, **kwargs)

    def form_valid(self, form):
        form.save()
        return HttpResponse(
            json.dumps({
                'id': form.instance.id,
                'periodicity': form.instance.periodicity
                }),
            content_type='application/json'
        )

    def form_invalid(self, form):
        super(WriteItPopitUpdateView, self).form_invalid(form)
        return HttpResponse(
            json.dumps({
                'errors': form.errors
                }),
            content_type='application/json'
        )


class WriteItDeleteView(DeleteView):
    model = WriteItInstance

    # @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        self.kwargs['slug'] = request.subdomain
        return super(WriteItDeleteView, self).dispatch(request, *args, **kwargs)

    def get_object(self, queryset=None):
        obj = super(WriteItDeleteView, self).get_object(queryset=queryset)
        if not obj.owner == self.request.user:
            raise Http404
        return obj

    def get_success_url(self):
        url = reverse('your-instances')
        return url


class MessageTogglePublic(RedirectView):
    permanent = False

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(MessageTogglePublic, self).dispatch(*args, **kwargs)

    def get_redirect_url(self, *args, **kwargs):
        message = get_object_or_404(Message,
            pk=kwargs['pk'],
            writeitinstance__slug=self.request.subdomain,
            writeitinstance__owner=self.request.user,
            )
        message.public = not message.public
        message.save()
        if message.public:
            view_messages.info(self.request, _("This message has been marked as public"))
        else:
            view_messages.info(self.request, _("This message has been marked as private"))
        return reverse('messages_per_writeitinstance', subdomain=self.request.subdomain)


class ContactUsView(TemplateView):
    template_name = 'nuntium/profiles/contact.html'


class WelcomeView(DetailView):
    model = WriteItInstance
    template_name = 'nuntium/profiles/welcome.html'

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        self.kwargs['slug'] = request.subdomain
        return super(WelcomeView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(WelcomeView, self).get_context_data(**kwargs)
        # passing URLs in for easy insertion into the translation tags
        # because we're using an overridden version of the url tag that
        # doesn't allow the use of "as" to pass the url as a variable
        # that can be quoted within a translation block. *sigh*
        context['url_template_update'] = reverse('writeitinstance_template_update', subdomain=self.request.subdomain)
        context['url_basic_update'] = reverse('writeitinstance_basic_update', subdomain=self.request.subdomain)
        context['url_maxrecipients_update'] = reverse('writeitinstance_maxrecipients_update', subdomain=self.request.subdomain)
        context['url_answernotification_update'] = reverse('writeitinstance_answernotification_update', subdomain=self.request.subdomain)
        context['url_recipients'] = reverse('contacts-per-writeitinstance', subdomain=self.request.subdomain)
        context['url_data_sources'] = reverse('relate-writeit-popit', subdomain=self.request.subdomain)
        return context


class WriteItInstanceWebHooksView(WriteItInstanceDetailBaseView):
    template_name = 'nuntium/profiles/webhooks.html'

    def get_context_data(self, *args, **kwargs):
        context = super(WriteItInstanceWebHooksView, self).get_context_data(*args, **kwargs)
        context['form'] = WebhookCreateForm(writeitinstance=self.object)
        return context


class WriteItInstanceCreateWebHooksView(CreateView):
    model = AnswerWebHook

    form_class = WebhookCreateForm