def submit_dispatch(campaign_id): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) form = DispatcherConfirmForm(request.form) form.send_at.data = datetime.strptime(form.send_at.data, '%Y-%m-%d %H:%M:%S') if form.send_at.data else None if form.validate_on_submit(): params = { 'campaign_id': campaign.id, 'account_id': current_user.account_id, 'user_id': current_user.id, 'list_id': campaign.list_id, 'import_data': campaign.list_.import_data } if form.submit_send_at.data: params['send_at'] = form.send_at.data params['state'] = 15 scheduled = 1 else: params['send_at'] = None scheduled = 0 d = Dispatcher.create(**params) if d and d.id: if not d.send_at: d.send() # fire emails => celery return redirect(url_for('campaign.success', campaign_id=campaign_id, scheduled=scheduled)) else: flash('There was an error beginning the send, none have been sent.', 'warning') else: flash_errors(form) return redirect(url_for('campaign.edit', campaign_id=campaign_id))
def update(campaign_id=None): form = CampaignForm(request.form) list_id = request.form.get('list_id', None) form = setup_campaign_select_choices(form, list_id) campaign = Campaign.find_by_id(campaign_id) if form.validate_on_submit(): params = { 'name': form.name.data, 'from_email_dd': form.from_email_dd.data, 'from_name_dd': form.from_name_dd.data, 'reply_to_dd': form.reply_to_dd.data, 'to_email_dd': form.to_email_dd.data, 'to_name_dd': form.to_name_dd.data, 'from_email_ov': form.from_email_ov.data, 'from_name_ov': form.from_name_ov.data, 'reply_to_ov': form.reply_to_ov.data, 'to_email_ov': form.to_email_ov.data, 'to_name_ov': form.to_name_ov.data, 'selector_col_name': form.selector_col_name.data } if campaign.selector_col_name and campaign.selector_col_name != params['selector_col_name']: flash("Selector column changed, all emails have had selector values removed.", 'warning') for email in campaign.emails: email.update(selector_col_val=None) campaign.update(**params) flash('Campaign Updated') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) flash_errors(form) list_form = CampaignListForm() list_form.list_id.choices = [('','')] + [(str(h.id), h.name) for h in List.find_all()] return render_template('campaign/edit.html', form=form, campaign=campaign, list_form=list_form)
def test_campaign_determiner_duplicates_true(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) e = Email.find_by_id_anon(stack['email_id']) e.update(selector_col_val='["dog"]') e2 = Email.create(account_id=c.account_id, name="EmailTwo", campaign_id=c.id) e2.update(selector_col_val='["dog"]') self.assertEqual(c.determiner_duplicates(),(True,'dog'))
def test_campaign_email_determiner_none(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) c.update(selector_col_name='dog') e = Email.find_by_id_anon(stack['email_id']) e.update(selector_col_val='["woof"]') e2 = Email.create(account_id=c.account_id, name="EmailTwo", campaign_id=c.id) e2.update(selector_col_val='["heina"]') self.assertEqual(c.email_determiner({'dog': 'cat'}), None)
def delete(campaign_id): campaign = Campaign.find_by_id(campaign_id) if campaign: if campaign.emails or campaign.dispatcher: flash('This campaign has emails or a dispatch attached to it, and cannot be deleted', 'warning') else: try: campaign.delete() flash('Campaign deleted') except Exception, e: flash('Exception: %s'%e)
def list_update(campaign_id=None): campaign = Campaign.find_by_id(campaign_id) list_id = request.form.get('list_id') l = List.find_by_id(list_id) if list_id else None acct_id = current_user.account_id if campaign and acct_id == campaign.account_id and l and acct_id == l.account_id: campaign.update(list_id=list_id) return jsonify({'success': 'true'}) else: return jsonify({'success': 'false'})
def test_campaign_get_selector_import_data(self): stack = helpers.create_stack() l = List.find_by_id_anon(stack['list_id']) l.import_data = [{"dog": "cat"}, {"dog": "bird"}] l.save() c = Campaign.find_by_id_anon(stack['campaign_id']) c.selector_col_name = 'dog' c.save() e = Email.find_by_id_anon(stack['email_id']) e.selector_col_val = '["cat"]' e.save() self.assertEqual(c.get_selector_import_data(), [{'dog': 'cat'}])
def test_dispatcher_send_email_from_data_no_email(self): stack = helpers.create_stack() d = Dispatcher.find_by_id_anon(stack['dispatcher_id']) c = Campaign.find_by_id_anon(stack['campaign_id']) e = Email.find_by_id_anon(stack['email_id']) c.update(selector_col_name='dog') e.update(selector_col_val='["false"]') send_cnt = Send.query.count() sk_cnt = int(d.get_skipped()) d.send_email_from_data({'dog': 'cat'}) self.assertEqual(send_cnt, Send.query.count()) self.assertEqual(str(sk_cnt + 1), d.get_skipped())
def create(campaign_id=None): form = NewCampaignForm(request.form) if form.validate_on_submit(): params = { 'name': form.name.data, 'account_id': current_user.account_id } c = Campaign.create(**params) if c: flash('Campaign Created') return redirect(url_for('campaign.edit', campaign_id=c.id)) flash_errors(form) return redirect(url_for('campaign.index'))
def edit(campaign_id=None): if campaign_id: campaign = Campaign.find_by_id(campaign_id) if campaign: form = CampaignForm(obj=campaign) form = setup_campaign_select_choices(form, campaign.list_id) if campaign.list_id else form if not form.from_email_ov.data: form.from_email_ov.data = current_user.account.default_from_email else: flash('Campaign not found') return redirect('/campaigns/') list_form = CampaignListForm() list_form.list_id.choices = [('','')] + [(str(h.id), h.name) for h in List.find_all()] return render_template('campaign/edit.html', form=form, campaign=campaign, list_form=list_form, emails=campaign.emails)
def image_upload(file_size_ok, campaign_id=None, email_id=None): email = Email.find_by_id(email_id) campaign = Campaign.find_by_id(campaign_id) if campaign and email and current_user.account_id == campaign.account_id and current_user.account_id == email.account_id: file = request.files['image_file'] if not file_size_ok: return jsonify({'error': 'File is too large.'}) if file and allowed_image_file(secure_filename(file.filename.lower())): filename = secure_filename(file.filename) url = upload_email_image(current_user.account_id, campaign_id, email_id, filename, file) return jsonify({'link': url}) else: return jsonify({'error': 'Invalid image type.'}) return jsonify({'error': 'Could not upload image.'})
def update(campaign_id=None, email_id=None): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) email = Email.find_by_id(email_id) if not email: return abort(404) form = EditEmailForm(request.form) if campaign.list_id: keys = campaign.list_.get_import_data_keys() form.selector_col_val.choices = campaign.list_.get_unique_col_values( campaign.selector_col_name, True) else: keys = [] if form.validate_on_submit(): params = { 'name': form.name.data, 'subject': form.subject.data, 'preheader': form.preheader.data, 'html': form.html.data, 'text': form.text.data, 'selector_col_val': json.dumps(filter(None, form.selector_col_val.data)) } email.update(**params) flash('Email Updated') return redirect( url_for('email.edit', email_id=email.id, campaign_id=campaign.id)) flash_errors(form) return render_template('email/new.html', form=form, campaign=campaign, email=email, keys=keys)
def new(campaign_id=None): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) email = None form = NewEmailForm() templates = Template.get_all_choices() keys = [] if campaign.list_id: keys = campaign.list_.get_import_data_keys() form.selector_col_val.choices = campaign.list_.get_unique_col_values( campaign.selector_col_name, True) if email and email.selector_col_val: form.selector_col_val.data = email.selector_col_val return render_template('email/new.html', form=form, campaign=campaign, email=email, keys=keys, templates=templates)
def create(campaign_id=None): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) form = NewEmailForm(request.form) if campaign.list_id: keys = campaign.list_.get_import_data_keys() form.selector_col_val.choices = campaign.list_.get_unique_col_values( campaign.selector_col_name, True) else: keys = [] templates = Template.get_all_choices() if form.validate_on_submit(): params = { 'name': form.name.data, 'subject': form.subject.data, 'preheader': form.preheader.data, 'selector_col_val': form.selector_col_val.data } if form.template.data: params['html'] = Template.get_html(form.template.data) params['account_id'] = current_user.account_id params['campaign_id'] = campaign.id email = Email.create(**params) if email: flash('Email Created') return redirect( url_for('email.edit', email_id=email.id, campaign_id=campaign.id)) flash_errors(form) return render_template('email/new.html', form=form, campaign=campaign, keys=keys, templates=templates)
def preview(campaign_id=None, email_id=None): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) email = Email.find_by_id(email_id) if not email: return abort(404) list_id = email.campaign.list_id if email.campaign.list_id else request.args.get( 'list_id', None) l = List.find_by_id(list_id) if l: s_data = campaign.get_selector_import_data() rando_set = range(len(s_data)) if rando_set: rando = random.sample(rando_set, 1)[0] rando = s_data[rando] html = email.render_html_attr(rando, 'preview') # fake hash id if not email.text: email.text = 'No content.' text = email.render_text_attr(rando, 'preview') return render_template('email/preview.html', email=email, html=html, text=text, email_id=email_id, campaign_id=campaign_id) else: flash( "No valid data available for preview. You may need to set a selector value." ) return redirect( url_for('email.edit', email_id=email_id, campaign_id=campaign.id)) else: flash("Preview is not available until a list is selected.") return redirect( url_for('email.edit', email_id=email_id, campaign_id=campaign.id))
def confirm_dispatch(campaign_id): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) form = DispatcherForm(request.form) display_time = form.send_at.data.strftime('%m-%d-%Y %I:%M %p') form.send_at.data = form.send_at.data + timedelta(hours=7) # localize utc if not form.validate_on_submit(): flash_errors(form) return redirect(url_for('campaign.dispatcher', campaign_id=campaign.id)) current_form=DispatcherConfirmForm() if form.data.get('submit_now'): current_form.send_at.data = display_time = None else: current_form.send_at.data = form.send_at.data return render_template('campaign/confirm_dispatch.html', campaign=campaign, form=current_form, display_time=display_time )
def edit(campaign_id=None, email_id=None): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) email = Email.find_by_id(email_id) if not email: flash('Email not found') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) form = EditEmailForm(obj=email) keys = [] if campaign.list_id: keys = campaign.list_.get_import_data_keys() form.selector_col_val.choices = campaign.list_.get_unique_col_values( campaign.selector_col_name, True) if email and email.selector_col_val: form.selector_col_val.data = email.selector_col_val return render_template('email/edit.html', form=form, campaign=campaign, email=email, keys=keys, auto_text=current_user.account.auto_text)
def test_campaign_check_email_keys_good(self): stack = helpers.create_stack() e = Email.find_by_id_anon(stack['email_id']) e.update(html="{{bad_test}}") c = Campaign.find_by_id_anon(stack['campaign_id']) self.assertEqual(c.check_email_keys(),(False,"bad_test"))
def index(): page = int(request.args.get('page', 1)) pagination = Campaign.find_all_desc().paginate(page=page, per_page=20) form = NewCampaignForm() return render_template('campaign/index.html', user=current_user, pagination=pagination, form=form)
def test_campaign_selector_send_count(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) redis.delete('selector_send_count_%s' % c.id) self.assertEqual(c.selector_send_count(),1)
def test_campaign_render_attr(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) c.update(from_email_dd="Email Address") data = {'Email Address':'*****@*****.**'} self.assertEqual(c.render_attr('from_email_dd', data), "*****@*****.**")
def test_campaign_selector_missing_false(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) self.assertEqual(c.selector_missing(),False)
def test_campaign_selector_missing_true(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) e2 = Email.create(account_id=c.account_id, name="EmailTwo", campaign_id=c.id) self.assertEqual(c.selector_missing(),True)
def test_campaign_email_determiner_no_specification(self): stack = helpers.create_stack() c = Campaign.find_by_id_anon(stack['campaign_id']) e = Email.find_by_id_anon(stack['email_id']) e2 = Email.create(account_id=c.account_id, name="EmailTwo", campaign_id=c.id) self.assertEqual(c.email_determiner({}), e)
def dispatcher(campaign_id): campaign = Campaign.find_by_id(campaign_id) if campaign_id else None if not campaign: return abort(404) if not current_user.accepted_terms: flash("You must accept the terms of this site before you can send emails.", 'warning') return redirect(url_for('user.terms')) if not current_user.account.active: flash("Your account is inactive, please contact support.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) if not current_user.account.api_key: flash("Your account does not have an api key, please contact support.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) # Must have list and emails if not campaign.list_id or not campaign.emails: flash("A campaign must have an associated list and at least one email.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) # List must have data if not campaign.list_.total_send_count() > 0: flash("List contains no data, cannot begin send process.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) # Must have footer if not current_user.account.footer_html: flash("This account does not have a footer, please add one before you initiate a send.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) # Don't allow dup sends if Dispatcher.check_for_recent(campaign.id): flash("To safeguard from duplication, a campaign may not be sent more than once in a 2 minute span.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) if campaign.selector_missing(): flash("There is more than one email, but no selector. Please choose a selector or have only one email.", 'warning') return redirect(url_for('campaign.edit', campaign_id=campaign.id)) valid_keys, bad_key = campaign.check_email_keys() selector_dups,bad_selector = campaign.determiner_duplicates() form = DispatcherForm() email_list = print_list(campaign.emails, 'name') d = datetime.utcnow() - timedelta(hours=7) # localize utc d_value = d.strftime(DT_FORMAT) d_min = d_value d_max = (d + timedelta(days=7)).strftime(DT_FORMAT) return render_template('campaign/dispatcher.html', form=form, campaign=campaign, valid_keys=valid_keys, bad_key=bad_key, selector_dups=selector_dups, bad_selector=bad_selector, email_list=email_list, d_min=d_min, d_max=d_max, d_value=d_value )
def test_campaign_check_email_keys_bad(self): stack = helpers.create_stack() e = Email.find_by_id_anon(stack['email_id']) e.update(html="{{test}}") c = Campaign.find_by_id_anon(stack['campaign_id']) self.assertEqual(c.check_email_keys(),(True,None))