def pre_save_user(sender, instance, **kwargs): try: original = User.objects.get(pk=instance.pk) except User.DoesNotExist: pass else: # Sync with MailChimp whenever a user becomes active if not original.is_active == instance.is_active and instance.is_active: user = instance profile = user.get_profile() mailsnake = MailSnake(settings.MAILCHIMP_API_KEY) if profile.newsletter: email = user.email.encode('utf-8') logger.debug('Subscribing ' + email + ' to MailChimp list...') try: mailsnake.listSubscribe(id=settings.MAILCHIMP_LIST_ID, email_address=email, double_optin=False, update_existing=True, send_welcome=True) except: logger.exception('Failed to subscribe ' + email + ' to MailChimp list') else: email = user.email.encode('utf-8') # If the user is already subscribed on MailChimp, go ahead and update our local state to match logger.debug('Retrieving subscription state for ' + email + ' on MailChimp list...') try: info = mailsnake.listMemberInfo( id=settings.MAILCHIMP_LIST_ID, email_address=(email, )) except: logger.exception( 'Failed to retrieve subscription state for ' + email) else: if info['success'] == 1 and info['data'][0][ 'status'] == 'subscribed': profile.newsletter = True profile.save(dispatch_signal=False)
def groups_form_factory(email=None, grouping_name=None, list_id=None): """ Form factory for selecting the interest groups. email An email address of a list member from which to set the initial values for the form. grouping_name The grouping name as defined in MailChimp. If not provided then the first grouping will be used. list_id The MailChimp list ID. If not provided, the value defined in the config settings will be used. """ if not hasattr(settings, 'MAILCHIMP_API_KEY'): raise ImproperlyConfigured(_("You need to specify MAILCHIMP_API_KEY" \ "in your Django settings file.")) ms = MailSnake(settings.MAILCHIMP_API_KEY) if not list_id: list_id = get_list_id() # get all groupings for the list grouping = None response = ms.listInterestGroupings(id=list_id) raise_if_error(response) # get the correct grouping if not grouping_name: grouping = response[0] grouping_name = grouping['name'] else: for try_grouping in response: if try_grouping['name'] == grouping_name: grouping = try_grouping if not grouping: errmsg = _("Grouping not found: '%s'") % grouping_name raise MailChimpGroupingNotFound(errmsg) if email: # get the user's group subscription to set initial field values response = ms.listMemberInfo(id=list_id, email_address=[email]) if not response['success']: raise MailChimpEmailNotFound user_groupings = response['data'][0]['merges']['GROUPINGS'] for try_grouping in user_groupings: if try_grouping['name'] == grouping_name: user_grouping = try_grouping # create the appropriate type of fields if grouping['form_field'] == 'checkboxes': fields = SortedDict() for i, group in enumerate(grouping['groups']): key = 'mailchimp_group_'+group['bit'] if email: initial=bool(user_grouping['groups'].find(group['name'])+1) else: initial=False fields.insert(i, key, forms.BooleanField(label=group['name'], required=False, initial=initial)) else: # radio or select fields = {} CHOICES = tuple((group['bit'], group['name']) for group in grouping['groups']) for group in grouping['groups']: initial=None if email: if bool(user_grouping['groups'].find(group['name'])+1): initial = group['bit'] else: initial = None if grouping['form_field'] == 'radio': widget = RadioSelect else: widget = Select fields['mailchimp_group'] = forms.ChoiceField(choices=CHOICES, label=grouping['name'], widget=widget, initial=initial) form = type('GroupsForm', (_GroupsForm,), {'base_fields': fields}) form._grouping = grouping return form
def mailchimp_webhook(request): ''' This view is called via a MailChimp webhook. ''' response = {} try: if request.GET['secret'] == 'WZnI3VUbvQxe4hjcRj8i5tEXpTyk7XMHgdRiu12SUVE': webhook_type = request.POST['type'] if webhook_type == 'subscribe': email = request.POST['data[email]'] # Update the user's preference if the user exists try: user = User.objects.get(email=email) except User.DoesNotExist: pass else: profile = user.get_profile() if profile: profile.newsletter = True profile.save(dispatch_signal=False) elif webhook_type == 'unsubscribe' or webhook_type == 'cleaned': email = request.POST['data[email]'] # Update the user's preference if the user exists try: user = User.objects.get(email=email) except User.DoesNotExist: pass else: profile = user.get_profile() if profile: profile.newsletter = False profile.save(dispatch_signal=False) elif webhook_type == 'upemail': old_email = request.POST['data[old_email]'] new_email = request.POST['data[new_email]'] mailsnake = MailSnake(settings.MAILCHIMP_API_KEY) # Update the user's preference if the user exists try: user = User.objects.get(email=old_email) except User.DoesNotExist: pass else: profile = user.get_profile() if profile: try: info = mailsnake.listMemberInfo(id=settings.MAILCHIMP_LIST_ID, email_address=(old_email,)) except: logger.exception('Failed to retrieve subscription info for ' + old_email + ' from MailChimp') else: if info['success'] == 1 and info['data'][0]['status'] == 'subscribed': profile.newsletter = True else: profile.newsletter = False profile.save(dispatch_signal=False) # Update the user's preference if the user exists try: user = User.objects.get(email=new_email) except User.DoesNotExist: pass else: profile = user.get_profile() if profile: try: info = mailsnake.listMemberInfo(id=settings.MAILCHIMP_LIST_ID, email_address=(new_email,)) except: logger.exception('Failed to retrieve subscription info for ' + new_email + ' from MailChimp') else: if info['success'] == 1 and info['data'][0]['status'] == 'subscribed': profile.newsletter = True else: profile.newsletter = False profile.save(dispatch_signal=False) response['success'] = 1 else: response['success'] = 0 except: response['success'] = 0 return HttpResponse(simplejson.dumps(response), mimetype='application/json')