def unsubscribe(self, **kwargs): """ Wraps the listUnsubscribe API call for this user and list. See http://apidocs.mailchimp.com/api/1.3/listunsubscribe.func.php for a list of keyword arguments. The following arguments will be passed to listUnsubscribe() automatically and should not be provided by the caller. id email_address Returns True if the user was unsubscribed, False if the user was not unsubscribed, or raises a MailChimpError if the API returned an error. """ kwargs['email_address'] = self.user.email kwargs['id'] = get_list_id() response = self.get_mailsnake_instance().listUnsubscribe(**kwargs) raise_if_error(response) if response: if 'delete_member' in kwargs and kwargs['delete_member']: self.status = self.NOT_SUBSCRIBED else: self.status = self.UNSUBSCRIBED self.save() return response
def update(self, **kwargs): """ Wraps the listUpdateMember API call for this user and list. See http://apidocs.mailchimp.com/api/1.3/listupdatemember.func.php for a list of keyword arguments. The following arguments will be passed to listUnsubscribe() automatically and should not be provided by the caller. id email_address FNAME (in merge_vars) LNAME (in merge_vars) Returns True if the user was udpated, False if the user was not unsubscribed, or raises a MailChimpError if the API returned an error. """ kwargs['email_address'] = self.user.email kwargs['id'] = get_list_id() if not 'merge_vars' in kwargs: kwargs['merge_vars'] = {} kwargs['merge_vars']['FNAME'] = self.user.first_name kwargs['merge_vars']['LNAME'] = self.user.last_name response = self.get_mailsnake_instance().listUpdateMember(**kwargs) raise_if_error(response) return response
def test_pending_user_subscription(self): ms = MailSnake(settings.MAILCHIMP_API_KEY) user = get_admin_user() subscription = UserSubscription.objects.get(user=user) delete_member(user) ms.listInterestGroupingAdd(id=get_list_id(), name="Test Interest Group", type="checkboxes", groups=["Option 1", "Option 2"]) # when a user signs up... pending, c = PendingUserSubscription.objects.get_or_create(user=user) optin_ip = getattr(settings, 'MAILCHIMP_TEST_IP', '184.106.168.48') optin_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') pending.merge_vars = { 'OPTIN_IP': optin_ip, 'OPTIN_TIME': optin_time, } pending.save() # when the user is activated, confirmed, etc. pending.subscribe(double_optin=False) subscription.sync() self.assertEqual(optin_ip, subscription.optin_ip) self.assertEqual(optin_time, subscription.optin_time) self.assertTrue(subscription.is_subscribed()) pending.delete()
def sync(self, save=True): """ Populate the model fields from the values returned from the MailChimp listMemberInfo API call for this user and list. If 'save' is True, the save() method will be called on this UserSubscription instance. Returns the 'data' portion of the API response on success. Raises MailChimpError if the API returned an error. See: http://apidocs.mailchimp.com/api/1.3/listmemberinfo.func.php """ kwargs = {'email_address': self.user.email, 'id': get_list_id()} response = self.get_mailsnake_instance().listMemberInfo(**kwargs) if not response['success']: self.status = self.NOT_SUBSCRIBED self.optin_time = None self.optin_ip = None data = None else: data = response['data'][0] if data['status'] == 'unsubscribed': self.status = self.UNSUBSCRIBED elif data['status'] == 'pending': self.status = self.PENDING elif data['status'] == 'cleaned': self.status = self.CLEANED elif data['status'] == 'subscribed': self.status = self.SUBSCRIBED else: self.status = self.UNKNOWN if data['ip_opt']: self.optin_ip = data['ip_opt'] if data['timestamp']: self.optin_time = data['timestamp'] if save: self.save() return data
def subscribe(self, **kwargs): """ Wraps the listSubscribe API call for this user and list. See http://apidocs.mailchimp.com/api/1.3/listsubscribe.func.php for a list of keyword arguments. The following arguments will be passed to listSubscribe() automatically and should not be provided by the caller: id email_address FNAME (in merge_vars) LNAME (in merge_vars) Returns True if the user was subscribed, False if the user was not subscribed, or raises a MailChimpError if the API returned an error. """ kwargs['email_address'] = self.user.email kwargs['id'] = get_list_id() if not 'merge_vars' in kwargs: kwargs['merge_vars'] = {} kwargs['merge_vars']['FNAME'] = self.user.first_name kwargs['merge_vars']['LNAME'] = self.user.last_name response = self.get_mailsnake_instance().listSubscribe(**kwargs) raise_if_error(response) if response: if 'merge_vars' in kwargs: merge_vars = kwargs['merge_vars'] if 'OPTIN_IP' in merge_vars: self.optin_ip = merge_vars['OPTIN_IP'] if 'OPTIN_TIME' in merge_vars: self.optin_time = merge_vars['OPTIN_TIME'] if 'double_optin' in kwargs and not kwargs['double_optin']: self.status = self.SUBSCRIBED else: self.status = self.PENDING self.save() return response
def setUpClass(cls): # create test groups cls.ms = MailSnake(settings.MAILCHIMP_API_KEY) cls.list_id = get_list_id() cls.checkboxes_name = "Test Checkboxes" r = cls.ms.listInterestGroupingAdd(id=cls.list_id, name=cls.checkboxes_name, type="checkboxes", groups=["Option 1", "Option 2"]) cls.checkboxes_id = r cls.radio_name = "Test Radio" r = cls.ms.listInterestGroupingAdd(id=cls.list_id, name=cls.radio_name, type="radio", groups=["Option 1", "Option 2"]) cls.radio_id = r cls.select_name = "Test Select" r = cls.ms.listInterestGroupingAdd(id=cls.list_id, name=cls.select_name, type="dropdown", groups=["Option 1", "Option 2"]) cls.select_id = r
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