integration_models.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from django.db import models
  2. from django.forms.widgets import Input
  3. from django.template import Context, Template
  4. from django.template.loader import render_to_string
  5. from django.utils.translation import gettext_lazy as _
  6. from wagtail.admin.panels import FieldPanel
  7. from wagtail import hooks
  8. from wagtailcrx.api.mailchimp import MailchimpApi
  9. import json
  10. class MailchimpSubscriberIntegrationWidget(Input):
  11. template_name = 'wagtailcrx/formfields/mailchimp/subscriber_integration_widget.html'
  12. js_template_name = 'wagtailcrx/formfields/mailchimp/subscriber_integration_js.html'
  13. def get_context(self, name, value, attrs):
  14. ctx = super(MailchimpSubscriberIntegrationWidget, self).get_context(name, value, attrs)
  15. json_value = self.get_json_value(value)
  16. list_library = self.build_list_library()
  17. ctx['widget']['value'] = json.dumps(json_value)
  18. ctx['widget']['extra_js'] = self.render_js(name, list_library, json_value)
  19. ctx['widget']['selectable_mailchimp_lists'] = self.get_selectable_mailchimp_lists(
  20. list_library)
  21. ctx['widget']['stored_mailchimp_list'] = self.get_stored_mailchimp_list(json_value)
  22. return ctx
  23. def render_js(self, name, list_library, json_value):
  24. ctx = {
  25. 'widget_name': name,
  26. 'widget_js_name': name.replace('-', '_'),
  27. 'list_library': list_library,
  28. 'stored_mailchimp_list': self.get_stored_mailchimp_list(json_value),
  29. 'stored_merge_fields': self.get_stored_merge_fields(json_value),
  30. }
  31. return render_to_string(self.js_template_name, ctx)
  32. def get_json_value(self, value):
  33. if value:
  34. json_value = json.loads(value)
  35. else:
  36. json_value = json.loads('{}')
  37. if 'list_id' not in json_value:
  38. json_value['list_id'] = ""
  39. if 'merge_fields' not in json_value:
  40. json_value['merge_fields'] = {}
  41. if 'email_field' not in json_value:
  42. json_value['email_field'] = ""
  43. if 'interest_categories' not in json_value:
  44. json_value['interest_categories'] = {}
  45. return json_value
  46. def get_stored_mailchimp_list(self, value):
  47. if 'list_id' in value:
  48. return str(value['list_id'])
  49. def get_stored_merge_fields(self, value):
  50. if 'merge_fields' in value:
  51. return json.dumps(value['merge_fields'])
  52. return json.dumps({})
  53. def get_selectable_mailchimp_lists(self, library):
  54. selectable_lists = [('', '--- Select a Mailchimp List ---')]
  55. for k, v in library.items():
  56. selectable_lists.append((k, v['name']))
  57. return selectable_lists
  58. def build_list_library(self):
  59. mailchimp = MailchimpApi()
  60. list_library = {}
  61. if mailchimp.is_active:
  62. lists = mailchimp.get_lists()
  63. for mlist in lists['lists']:
  64. list_library[mlist['id']] = {
  65. 'name': mlist['name'],
  66. 'merge_fields': {},
  67. 'interest_categories': {}
  68. }
  69. list_library[mlist['id']]['merge_fields'] = \
  70. mailchimp.get_merge_fields_for_list(mlist['id'])['merge_fields']
  71. list_library[mlist['id']]['interest_categories'] = \
  72. mailchimp.get_interest_categories_for_list(mlist['id'])['categories']
  73. for category in list_library[mlist['id']]['interest_categories']:
  74. category['interests'] = mailchimp.get_interests_for_interest_category(
  75. mlist['id'],
  76. category['id']
  77. )['interests']
  78. return list_library
  79. class MailchimpSubscriberIntegration(models.Model):
  80. class Meta:
  81. abstract = True
  82. subscriber_json_data = models.TextField(
  83. blank=True,
  84. verbose_name=_("List")
  85. )
  86. def integration_operation(self, instance, **kwargs):
  87. mailchimp = MailchimpApi()
  88. if mailchimp.is_active:
  89. submission_dict = kwargs['form_submission'].get_data()
  90. rendered_dictionary = self.render_dictionary(submission_dict)
  91. mailchimp.add_user_to_list(list_id=self.get_list_id(), data=rendered_dictionary)
  92. def get_data(self):
  93. return json.loads(self.subscriber_json_data)
  94. def get_merge_fields(self):
  95. if 'merge_fields' in self.get_data():
  96. return self.get_data()['merge_fields']
  97. return {}
  98. def get_list_id(self):
  99. if 'list_id' in self.get_data():
  100. return self.get_data()['list_id']
  101. def combine_interest_categories(self):
  102. interest_dict = {}
  103. for category_id, value in self.get_data()['interest_categories'].items():
  104. interest_dict.update(value['interests'])
  105. return interest_dict
  106. def render_dictionary(self, form_submission):
  107. rendered_dictionary_template = json.dumps({
  108. 'members': [
  109. {
  110. 'email_address': self.get_data()['email_field'],
  111. 'merge_fields': self.get_data()['merge_fields'],
  112. 'interests': self.combine_interest_categories(),
  113. 'status': 'subscribed',
  114. }
  115. ],
  116. 'update_existing': True
  117. })
  118. rendered_dictionary = Template(
  119. rendered_dictionary_template).render(Context(form_submission))
  120. return rendered_dictionary
  121. panels = [
  122. FieldPanel('subscriber_json_data', widget=MailchimpSubscriberIntegrationWidget)
  123. ]
  124. @hooks.register('form_page_submit')
  125. def run_mailchimp_subscriber_integrations(instance, **kwargs):
  126. if hasattr(instance, 'integration_panels'):
  127. for panel in instance.integration_panels:
  128. for integration in getattr(instance, panel.relation_name).all():
  129. integration.integration_operation(instance, **kwargs)