|
@@ -0,0 +1,162 @@
|
|
|
+from django.db import models
|
|
|
+from django.forms.widgets import Select, Input
|
|
|
+from django.template import Context, Template
|
|
|
+from django.template.loader import render_to_string
|
|
|
+from django.utils.translation import ugettext_lazy as _
|
|
|
+
|
|
|
+from wagtail.admin.edit_handlers import FieldPanel
|
|
|
+from wagtail.core import hooks
|
|
|
+from wagtail.core.models import Orderable, Page
|
|
|
+from modelcluster.fields import ParentalKey
|
|
|
+
|
|
|
+from coderedcms.api.mailchimp import MailchimpApi
|
|
|
+
|
|
|
+from ast import literal_eval
|
|
|
+import json
|
|
|
+
|
|
|
+
|
|
|
+class MailchimpSubscriberIntegrationWidget(Input):
|
|
|
+ template_name = 'coderedcms/formfields/mailchimp/subscriber_integration_widget.html'
|
|
|
+ js_template_name = 'coderedcms/formfields/mailchimp/subscriber_integration_js.html'
|
|
|
+
|
|
|
+ def get_context(self, name, value, attrs):
|
|
|
+ ctx = super(MailchimpSubscriberIntegrationWidget, self).get_context(name, value, attrs)
|
|
|
+
|
|
|
+ json_value = self.get_json_value(value)
|
|
|
+ list_library = self.build_list_library()
|
|
|
+ ctx['widget']['value'] = json.dumps(json_value)
|
|
|
+ ctx['widget']['extra_js'] = self.render_js(name, list_library, json_value)
|
|
|
+ ctx['widget']['selectable_mailchimp_lists'] = self.get_selectable_mailchimp_lists(list_library)
|
|
|
+ ctx['widget']['stored_mailchimp_list'] = self.get_stored_mailchimp_list(json_value)
|
|
|
+
|
|
|
+ return ctx
|
|
|
+
|
|
|
+ def render_js(self, name, list_library, json_value):
|
|
|
+ ctx = {
|
|
|
+ 'widget_name': name,
|
|
|
+ 'widget_js_name' : name.replace('-', '_'),
|
|
|
+ 'list_library' : list_library,
|
|
|
+ 'stored_mailchimp_list': self.get_stored_mailchimp_list(json_value),
|
|
|
+ 'stored_merge_fields' : self.get_stored_merge_fields(json_value),
|
|
|
+ }
|
|
|
+
|
|
|
+ return render_to_string(self.js_template_name, ctx)
|
|
|
+
|
|
|
+
|
|
|
+ def get_json_value(self, value):
|
|
|
+ if value:
|
|
|
+ json_value = json.loads(value)
|
|
|
+ else:
|
|
|
+ json_value = json.loads('{}')
|
|
|
+ if 'list_id' not in json_value:
|
|
|
+ json_value['list_id'] = ""
|
|
|
+ if 'merge_fields' not in json_value:
|
|
|
+ json_value['merge_fields'] = {}
|
|
|
+ if 'email_field' not in json_value:
|
|
|
+ json_value['email_field'] = ""
|
|
|
+ if 'interest_categories' not in json_value:
|
|
|
+ json_value['interest_categories'] = {}
|
|
|
+ return json_value
|
|
|
+
|
|
|
+ def get_stored_mailchimp_list(self, value):
|
|
|
+ if 'list_id' in value:
|
|
|
+ return str(value['list_id'])
|
|
|
+
|
|
|
+ def get_stored_merge_fields(self, value):
|
|
|
+ if 'merge_fields' in value:
|
|
|
+ return json.dumps(value['merge_fields'])
|
|
|
+ return json.dumps({})
|
|
|
+
|
|
|
+ def get_selectable_mailchimp_lists(self, library):
|
|
|
+ selectable_lists = [('', 'Please select one of your Mailchimp Lists.')]
|
|
|
+ for k, v in library.items():
|
|
|
+ selectable_lists.append((k, v['name']))
|
|
|
+
|
|
|
+ return selectable_lists
|
|
|
+
|
|
|
+ def build_list_library(self):
|
|
|
+ mailchimp = MailchimpApi()
|
|
|
+ list_library = {}
|
|
|
+ if mailchimp.is_active:
|
|
|
+ lists = mailchimp.get_lists()
|
|
|
+ for l in lists['lists']:
|
|
|
+ list_library[l['id']] = {
|
|
|
+ 'name': l['name'],
|
|
|
+ 'merge_fields': {},
|
|
|
+ 'interest_categories': {}
|
|
|
+ }
|
|
|
+
|
|
|
+ list_library[l['id']]['merge_fields'] = mailchimp.get_merge_fields_for_list(l['id'])['merge_fields']
|
|
|
+ list_library[l['id']]['interest_categories'] = mailchimp.get_interest_categories_for_list(l['id'])['categories']
|
|
|
+
|
|
|
+ for category in list_library[l['id']]['interest_categories']:
|
|
|
+ category['interests'] = mailchimp.get_interests_for_interest_category(l['id'], category['id'])['interests']
|
|
|
+
|
|
|
+ return list_library
|
|
|
+
|
|
|
+class MailchimpSubscriberIntegration(models.Model):
|
|
|
+ class Meta:
|
|
|
+ abstract=True
|
|
|
+
|
|
|
+ subscriber_json_data = models.TextField(
|
|
|
+ blank=True,
|
|
|
+ verbose_name=_("List")
|
|
|
+ )
|
|
|
+
|
|
|
+ def integration_operation(self, instance, **kwargs):
|
|
|
+ mailchimp = MailchimpApi()
|
|
|
+ if mailchimp.is_active:
|
|
|
+ rendered_dictionary = self.render_dictionary(self.format_form_submission(kwargs['form_submission']))
|
|
|
+ mailchimp.add_user_to_list(list_id=self.get_list_id(), data=rendered_dictionary)
|
|
|
+
|
|
|
+ def format_form_submission(self, form_submission):
|
|
|
+ formatted_form_data = {}
|
|
|
+ for k, v in literal_eval(form_submission.form_data).items():
|
|
|
+ formatted_form_data[k.replace('-', '_')] = v
|
|
|
+ return formatted_form_data
|
|
|
+
|
|
|
+ def get_data(self):
|
|
|
+ return json.loads(self.subscriber_json_data)
|
|
|
+
|
|
|
+ def get_merge_fields(self):
|
|
|
+ if 'merge_fields' in self.get_data():
|
|
|
+ return self.get_data()['merge_fields']
|
|
|
+ return {}
|
|
|
+
|
|
|
+ def get_list_id(self):
|
|
|
+ if 'list_id' in self.get_data():
|
|
|
+ return self.get_data()['list_id']
|
|
|
+
|
|
|
+ def combine_interest_categories(self):
|
|
|
+ interest_dict = {}
|
|
|
+ for category_id, value in self.get_data()['interest_categories'].items():
|
|
|
+ interest_dict.update(value['interests'])
|
|
|
+
|
|
|
+ return interest_dict
|
|
|
+
|
|
|
+ def render_dictionary(self, form_submission):
|
|
|
+ rendered_dictionary_template = json.dumps({
|
|
|
+ 'members': [
|
|
|
+ {
|
|
|
+ 'email_address': self.get_data()['email_field'],
|
|
|
+ 'merge_fields': self.get_data()['merge_fields'],
|
|
|
+ 'interests': self.combine_interest_categories(),
|
|
|
+ 'status': 'subscribed',
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ rendered_dictionary = Template(rendered_dictionary_template).render(Context(form_submission))
|
|
|
+ return rendered_dictionary
|
|
|
+
|
|
|
+ panels = [
|
|
|
+ FieldPanel('subscriber_json_data', widget=MailchimpSubscriberIntegrationWidget)
|
|
|
+ ]
|
|
|
+
|
|
|
+@hooks.register('form_page_submit')
|
|
|
+def run_mailchimp_subscriber_integrations(instance, **kwargs):
|
|
|
+ if hasattr(instance, 'integration_panels'):
|
|
|
+ for panel in instance.integration_panels:
|
|
|
+ for integration in getattr(instance, panel.relation_name).all():
|
|
|
+ integration.integration_operation(instance, **kwargs)
|