def send_notification(user): message = Message(_(u'Zresetowano hasło'), sender='*****@*****.**', recipients=[user.email]) message.html = render_template( 'emails/password_reset_confirmation.html', username=user.username) mail.send(message)
def signup(): if current_user.is_authenticated(): return redirect(url_for('tickets')) form = SignupForm(request.form, next=request.args.get('next')) if form.validate_on_submit(): user = User(form.badgeid.data, form.name.data) user.set_password(form.password.data) db.session.add(user) try: db.session.commit() except IntegrityError, e: app.logger.warn("Exception %r adding user for %s, assuming duplicate badge", e, form.badgeid.data) flash("This badge is already registered. Please log in, or reset your password if you've forgotten it.") return redirect(url_for('login')) login_user(user) if user.email: # send a welcome email. msg = Message("Welcome to Electromagnetic Field", sender=app.config['SCHEDULE_EMAIL'], recipients=[user.email]) msg.body = render_template('welcome-email.txt', user=user) mail.send(msg) return redirect(form.next.data or url_for('tickets'))
def send_notification(user): message = Message(subject=_(u'Rozpoczęto reset hasła'), sender='*****@*****.**', recipients=[user.email]) message.html = render_template('emails/request_password_reset.html', hash=user.password_reset_hash) mail.send(message)
def forgot_username(): result = "" try: email = request.get_json()['email'] user = Users.query.filter_by(email=email).first() if not user: result = { 'success': False, 'error': "No user associated with that email" } else: msg = Message("ISEEU Username") msg.recipients = [user.email] msg.body = "Your ISEEU username is: \n\n" msg.body += user.username msg.body += "\n\n\nThanks,\nThe ISEEU Team" mail.send(msg) result = {'success': True, 'error': ""} except Exception as e: print(e) result = {'error': str(e), 'success': False} return jsonify(result)
def sendFlaskMail(email, subject, message): return sender = "%s <%s>" % (settings.AccountName, settings.Sender) receivers = [email] msg = Message(subject, sender=sender, recipients=receivers) msg.html = message mail.send(msg)
def admin_txn_reconcile(txn_id, payment_id): txn = BankTransaction.query.get_or_404(txn_id) payment = BankPayment.query.get_or_404(payment_id) form = ManualReconcilePaymentForm() if form.validate_on_submit(): if form.reconcile.data: app.logger.info("%s manually reconciling against payment %s (%s) by %s", current_user.name, payment.id, payment.bankref, payment.user.email) if txn.payment: app.logger.error("Transaction already reconciled") flash("Transaction %s already reconciled" % txn.id) return redirect(url_for('admin_txns')) if payment.state == 'paid': app.logger.error("Payment has already been paid") flash("Payment %s already paid" % payment.id) return redirect(url_for('admin_txns')) txn.payment = payment payment.paid() db.session.commit() msg = Message("Electromagnetic Field ticket purchase update", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) msg.body = render_template("tickets-paid-email-banktransfer.txt", user=payment.user, payment=payment) mail.send(msg) flash("Payment ID %s marked as paid" % payment.id) return redirect(url_for('admin_txns')) return render_template('admin/txn-reconcile.html', txn=txn, payment=payment, form=form)
def run(self): print "warning about expired Tickets" seen = {} expired = Ticket.query.filter(Ticket.expires <= datetime.utcnow(), Ticket.paid == False).all() for t in expired: # test that the ticket has a payment... not all do. if t.payment: if t.payment.id not in seen: seen[t.payment.id] = True for p in seen: p = Payment.query.get(p) print "emailing %s <%s> about payment %d" % (p.user.name, p.user.email, p.id) # race condition, not all ticket may of expired, but if any of # them have we will warn about all of them. # not really a problem tho. msg = Message("Electromagnetic Field ticket purchase update", sender=app.config['TICKETS_EMAIL'], recipients=[p.user.email]) msg.body = render_template("tickets-expired-warning.txt", payment=p) mail.send(msg)
def stripe_payment_paid(payment): if payment.state == 'paid': logger.info('Payment is already paid, ignoring') return if payment.state != 'charged': logger.error('Current payment state is %s (should be charged)', payment.state) raise StripeUpdateConflict() logger.info('Setting payment %s to paid', payment.id) payment.paid() db.session.commit() msg = Message('Your EMF ticket payment has been confirmed', sender=app.config.get('TICKETS_EMAIL'), recipients=[payment.user.email]) msg.body = render_template('tickets-paid-email-stripe.txt', user=payment.user, payment=payment) if app.config.get('RECEIPTS'): page = render_receipt(payment.tickets, pdf=True) pdf = render_pdf(page) msg.attach('Receipt.pdf', 'application/pdf', pdf.read()) mail.send(msg)
def run(self): all_tickets = Ticket.query.filter_by(paid=True, emailed=False) users = all_tickets.join(User).group_by(User).with_entities( User).order_by(User.id) for user in users: tickets = all_tickets.filter_by(user_id=user.id) page = render_receipt(tickets, pdf=True) pdf = render_pdf(page, url_root=app.config.get('BASE_URL')) plural = (tickets.count() != 1 and 's' or '') msg = Message("Your Electromagnetic Field Ticket%s" % plural, sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) msg.body = render_template("receipt.txt", user=user) msg.attach('Receipt.pdf', 'application/pdf', pdf.read()) app.logger.info('Emailing %s receipt for %s tickets', user.email, tickets.count()) mail.send(msg) for ticket in tickets: ticket.emailed = True db.session.commit()
def stripe_payment_refunded(payment): if payment.state == 'refunded': logger.info('Payment is already refunded, ignoring') return logger.info('Setting payment %s to refunded', payment.id) now = datetime.utcnow() for ticket in payment.tickets: ticket.paid = False if ticket.expires is None or ticket.expires > now: ticket.expires = now payment.state = 'refunded' db.session.commit() if not app.config.get('TICKETS_NOTICE_EMAIL'): app.logger.warning('No tickets notice email configured, not sending') return msg = Message('An EMF ticket payment has been refunded', sender=app.config.get('TICKETS_EMAIL'), recipients=[app.config.get('TICKETS_NOTICE_EMAIL')[1]]) msg.body = render_template('emails/tickets-refunded-email-stripe.txt', user=payment.user, payment=payment) mail.send(msg)
def send_reminder(payment_id): payment = BankPayment.query.get_or_404(payment_id) form = SendReminderForm() if form.validate_on_submit(): if form.remind.data: app.logger.info("%s sending reminder email to %s <%s> for payment %s", current_user.name, payment.user.name, payment.user.email, payment.id) if payment.reminder_sent: app.logger.error('Reminder for payment %s already sent', payment.id) flash("Cannot send duplicate reminder email for payment %s" % payment.id) return redirect(url_for('admin.expiring')) msg = Message("Electromagnetic Field ticket purchase update", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) msg.body = render_template("emails/tickets-reminder.txt", payment=payment) mail.send(msg) payment.reminder_sent = True db.session.commit() flash("Reminder email for payment %s sent" % payment.id) return redirect(url_for('admin.expiring')) return render_template('admin/payment-send-reminder.html', payment=payment, form=form)
def run(self): paid_items = Ticket.query.filter_by(paid=True).join(TicketType).filter(or_( TicketType.admits.in_(['full', 'kid', 'car', 'campervan']), TicketType.fixed_id.in_(range(14, 24)))) users = (paid_items.filter(Ticket.emailed == False).join(User) # noqa .group_by(User).with_entities(User).order_by(User.id)) for user in users: user_tickets = Ticket.query.filter_by(paid=True).join(TicketType, User).filter( TicketType.admits.in_(['full', 'kid', 'car', 'campervan']), User.id == user.id) plural = (user_tickets.count() != 1 and 's' or '') msg = Message("Your Electromagnetic Field Ticket%s" % plural, sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) msg.body = render_template("emails/receipt.txt", user=user) attach_tickets(msg, user) app.logger.info('Emailing %s receipt for %s tickets', user.email, user_tickets.count()) mail.send(msg) db.session.commit()
def stripe_payment_paid(payment): if payment.state == 'paid': logger.info('Payment is already paid, ignoring') return if payment.state == 'partrefunded': logger.info('Payment is already partially refunded, ignoring') return if payment.state != 'charged': logger.error('Current payment state is %s (should be charged)', payment.state) raise StripeUpdateConflict() logger.info('Setting payment %s to paid', payment.id) payment.paid() db.session.commit() msg = Message('Your EMF payment has been confirmed', sender=app.config.get('TICKETS_EMAIL'), recipients=[payment.user.email]) msg.body = render_template('emails/tickets-paid-email-stripe.txt', user=payment.user, payment=payment) if feature_enabled('ISSUE_TICKETS'): attach_tickets(msg, payment.user) mail.send(msg) db.session.commit()
def stripe_payment_paid(payment): if payment.state == 'paid': logger.info('Payment is already paid, ignoring') return if payment.state == 'partrefunded': logger.info('Payment is already partially refunded, ignoring') return if payment.state != 'charged': logger.error('Current payment state is %s (should be charged)', payment.state) raise StripeUpdateConflict() logger.info('Setting payment %s to paid', payment.id) payment.paid() db.session.commit() msg = Message('Your EMF ticket payment has been confirmed', sender=app.config.get('TICKETS_EMAIL'), recipients=[payment.user.email]) msg.body = render_template('emails/tickets-paid-email-stripe.txt', user=payment.user, payment=payment) if feature_enabled('ISSUE_TICKETS'): attach_tickets(msg, payment.user) mail.send(msg) db.session.commit()
def stripe_payment_refunded(payment): if payment.state == 'refunded': logger.info('Payment is already refunded, ignoring') return logger.info('Setting payment %s to refunded', payment.id) # Payment is already locked by the caller of stripe_update_payment with db.session.no_autoflush: for purchase in payment.purchases: purchase.refund_purchase() payment.state = 'refunded' db.session.commit() if not app.config.get('TICKETS_NOTICE_EMAIL'): app.logger.warning('No tickets notice email configured, not sending') return msg = Message('An EMF payment has been refunded', sender=app.config.get('TICKETS_EMAIL'), recipients=[app.config.get('TICKETS_NOTICE_EMAIL')[1]]) msg.body = render_template('emails/notice-payment-refunded.txt', payment=payment) mail.send(msg)
def charge_stripe(payment): logger.info("Charging Stripe payment %s, token %s", payment.id, payment.token) # If we fail to go from charging to charged, we won't have the charge ID, # so can't process the webhook. The payment will need to be manually resolved. # Test this with 4000000000000341. payment.state = 'charging' db.session.commit() try: charge = stripe.Charge.create( amount=payment.amount_int, currency=payment.currency.lower(), card=payment.token, description=payment.description, statement_description='Tickets 2016', # max 15 chars, appended to company name ) except stripe.CardError as e: error = e.json_body['error'] logger.warn('Card payment failed with exception "%s"', e) # Don't save the charge_id - they can try again flash('Unfortunately your card payment failed with the error: %s' % (error['message'])) return redirect(url_for('.stripe_tryagain', payment_id=payment.id)) except Exception as e: logger.warn("Exception %r confirming payment", e) flash('An error occurred with your payment, please try again') return redirect(url_for('.stripe_tryagain', payment_id=payment.id)) finally: # Allow trying again payment.state = 'captured' db.session.commit() payment.chargeid = charge.id if charge.paid: payment.paid() else: payment.state = 'charged' for t in payment.tickets: t.expires = datetime.utcnow() + timedelta(days=app.config['EXPIRY_DAYS_STRIPE']) logger.info("Set expiry for ticket %s", t.id) db.session.commit() logger.info('Payment %s completed OK (state %s)', payment.id, payment.state) msg = Message("Your EMF ticket purchase", sender=app.config.get('TICKETS_EMAIL'), recipients=[payment.user.email]) msg.body = render_template("emails/tickets-purchased-email-stripe.txt", user=payment.user, payment=payment) if feature_enabled('ISSUE_TICKETS') and charge.paid: attach_tickets(msg, payment.user) mail.send(msg) db.session.commit() return redirect(url_for('.stripe_waiting', payment_id=payment.id))
def email_tickets(): """ Email tickets to those who haven't received them """ users_purchase_counts = (Purchase.query.filter_by( is_paid_for=True, state="paid").join(PriceTier, Product, ProductGroup).filter( ProductGroup.type.in_(RECEIPT_TYPES)).join( Purchase.owner).with_entities(User, func.count( Purchase.id)).group_by(User).order_by(User.id)) for user, purchase_count in users_purchase_counts: plural = purchase_count != 1 and "s" or "" msg = Message( "Your Electromagnetic Field Ticket%s" % plural, sender=app.config["TICKETS_EMAIL"], recipients=[user.email], ) already_emailed = set_tickets_emailed(user) msg.body = render_template("emails/receipt.txt", user=user, already_emailed=already_emailed) attach_tickets(msg, user) app.logger.info("Emailing %s receipt for %s tickets", user.email, purchase_count) mail.send(msg) db.session.commit()
def transfer(ticket_id): try: ticket = current_user.tickets.filter_by(id=ticket_id).one() except NoResultFound: return redirect(url_for('tickets.main')) if not ticket or not ticket.paid or not ticket.type.is_transferable: return redirect(url_for('tickets.main')) form = TicketTransferForm() if form.validate_on_submit(): assert ticket.user_id == current_user.id email = form.email.data if not User.does_user_exist(email): new_user = True # Create a new user to transfer the ticket to to_user = User(email, form.name.data) db.session.add(to_user) db.session.commit() else: new_user = False to_user = User.query.filter_by(email=email).one() ticket.transfer(from_user=current_user, to_user=to_user) app.logger.info('Ticket %s transferred from %s to %s', ticket, current_user, to_user) # Alert the users via email code = to_user.login_code(app.config['SECRET_KEY']) msg = Message("You've been sent a ticket to EMF 2016!", sender=app.config.get('TICKETS_EMAIL'), recipients=[to_user.email]) msg.body = render_template('emails/ticket-transfer-new-owner.txt', to_user=to_user, from_user=current_user, new_user=new_user, code=code) if feature_enabled('ISSUE_TICKETS'): attach_tickets(msg, to_user) mail.send(msg) db.session.commit() msg = Message("You sent someone an EMF 2016 ticket", sender=app.config.get('TICKETS_EMAIL'), recipients=[current_user.email]) msg.body = render_template('emails/ticket-transfer-original-owner.txt', to_user=to_user, from_user=current_user) mail.send(msg) flash("Your ticket was transferred.") return redirect(url_for('tickets.main')) return render_template('ticket-transfer.html', ticket=ticket, form=form)
def forgot_password(): result = "" try: username = request.get_json()['username'] user = Users.query.filter_by(username=username).first() if not user: result = {'success': False, 'error': "Incorrect username"} else: password = password_generator(10) msg = Message("ISEEU Forgot Password") msg.recipients = [user.email] msg.body = "This is your new password. Please login and change it immediately.\n\n\n" msg.body += password msg.body += "\n\n\nThanks,\nThe ISEEU Team" mail.send(msg) user.set_password(password) result = user.register_user() except Exception as e: print(e) result = {'error': str(e), 'success': False} return jsonify(result)
def message_batch(): proposals, filtered = filter_proposal_request() form = SendMessageForm() if form.validate_on_submit(): if form.send.data: for proposal in proposals: msg = CFPMessage() msg.is_to_admin = False msg.from_user_id = current_user.id msg.proposal_id = proposal.id msg.message = form.message.data db.session.add(msg) db.session.commit() app.logger.info('Sending message from %s to %s', current_user.id, proposal.user_id) msg_url = external_url('cfp.proposal_messages', proposal_id=proposal.id) msg = Message('New message about your EMF proposal', sender=app.config['CONTENT_EMAIL'], recipients=[proposal.user.email]) msg.body = render_template('cfp_review/email/new_message.txt', url=msg_url, to_user=proposal.user, from_user=current_user, proposal=proposal) mail.send(msg) flash('Messaged %s proposals' % len(proposals), 'info') return redirect(url_for('.proposals', **request.args)) return render_template('cfp_review/message_batch.html', form=form, proposals=proposals)
def transfer_start(): if get_user_currency( ) == 'EUR' and not app.config.get('BANK_TRANSFER_EURO'): return redirect(url_for('pay_choose')) payment = add_payment_and_tickets(BankPayment) if not payment: logging.warn('Unable to add payment and tickets to database') flash( 'Your session information has been lost. Please try ordering again.' ) return redirect(url_for('tickets')) logger.info("Created bank payment %s (%s)", payment.id, payment.bankref) payment.state = "inprogress" db.session.commit() msg = Message("Your EMF ticket purchase", sender=app.config['TICKETS_EMAIL'], recipients=[current_user.email]) msg.body = render_template("tickets-purchased-email-banktransfer.txt", user=current_user, payment=payment) mail.send(msg) return redirect(url_for('transfer_waiting', payment_id=payment.id))
def stripe_payment_paid(payment: StripePayment): if payment.state == "paid": logger.info("Payment is already paid, ignoring") return if payment.state == "partrefunded": logger.info("Payment is already partially refunded, ignoring") return logger.info("Setting payment %s to paid", payment.id) payment.paid() db.session.commit() msg = Message( "Your EMF payment has been confirmed", sender=app.config.get("TICKETS_EMAIL"), recipients=[payment.user.email], ) already_emailed = set_tickets_emailed(payment.user) msg.body = render_template( "emails/tickets-paid-email-stripe.txt", user=payment.user, payment=payment, already_emailed=already_emailed, ) if feature_enabled("ISSUE_TICKETS"): attach_tickets(msg, payment.user) mail.send(msg) db.session.commit()
def transfer_start(payment): if not feature_enabled('BANK_TRANSFER'): return redirect(url_for('tickets.pay')) if get_user_currency() == 'EUR' and not feature_enabled('BANK_TRANSFER_EURO'): return redirect(url_for('tickets.pay')) logger.info("Created bank payment %s (%s)", payment.id, payment.bankref) # No extra preparation required for bank transfer. We can go straight to inprogress. if payment.currency == 'GBP': days = app.config.get('EXPIRY_DAYS_TRANSFER') elif payment.currency == 'EUR': days = app.config.get('EXPIRY_DAYS_TRANSFER_EURO') payment.expires = datetime.utcnow() + timedelta(days=days) payment.state = "inprogress" for purchase in payment.purchases: purchase.set_state('payment-pending') db.session.commit() msg = Message("Your EMF ticket purchase", sender=app.config['TICKETS_EMAIL'], recipients=[current_user.email]) msg.body = render_template("emails/tickets-purchased-email-banktransfer.txt", user=current_user, payment=payment) mail.send(msg) return redirect(url_for('payments.transfer_waiting', payment_id=payment.id))
def gocardless_payment_failed(payment): if payment.state == 'failed': logger.info('Payment is already failed, skipping') return if payment.state in {'inprogress', 'paid'}: logger.info("Setting payment %s to failed", payment.id) payment.state = 'failed' else: logger.error("Current payment state is %s (should be inprogress or paid), ignoring", payment.state) return payment.expires = datetime.utcnow() + timedelta(days=app.config['EXPIRY_DAYS_GOCARDLESS']) for purchase in payment.purchases: purchase.set_state('payment-pending') msg = Message("Your EMF payment has failed", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) msg.body = render_template("emails/payment-failed.txt", payment=payment) mail.send(msg) db.session.commit() if not app.config.get('TICKETS_NOTICE_EMAIL'): app.logger.warning('No tickets notice email configured, not sending') return msg = Message('An EMF payment has failed', sender=app.config.get('TICKETS_EMAIL'), recipients=[app.config.get('TICKETS_NOTICE_EMAIL')[1]]) msg.body = render_template('emails/notice-payment-failed.txt', payment=payment) mail.send(msg)
def gocardless_payment_paid(payment): if payment.state == 'paid': logger.info('Payment is already paid, ignoring') return if payment.state == 'partrefunded': logger.info('Payment is already partially refunded, ignoring') return if payment.state != 'inprogress': logger.error("Current payment state is %s (should be inprogress), ignoring", payment.state) return logger.info("Setting payment %s to paid", payment.id) payment.paid() msg = Message("Your EMF ticket payment has been confirmed", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) already_emailed = set_tickets_emailed(payment.user) msg.body = render_template('emails/tickets-paid-email-gocardless.txt', user=payment.user, payment=payment, already_emailed=already_emailed) if feature_enabled('ISSUE_TICKETS'): attach_tickets(msg, payment.user) db.session.commit() mail.send(msg)
def signup(): if current_user.is_authenticated(): return redirect(url_for('tickets')) form = SignupForm(request.form, next=request.args.get('next')) if request.method == 'POST' and form.validate(): user = User(form.email.data, form.name.data) user.set_password(form.password.data) db.session.add(user) try: db.session.commit() except IntegrityError, e: app.logger.warn('Adding user raised %r, assuming duplicate email', e) flash("This email address %s is already in use. Please log in, or reset your password if you've forgotten it." % (form.email.data)) return redirect(url_for('login')) login_user(user) # send a welcome email. msg = Message("Welcome to Electromagnetic Field", sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) msg.body = render_template("welcome-email.txt", user=user) mail.send(msg) return redirect(form.next.data or url_for('tickets'))
def run(self): # We set state to receipt-emailed in attach_tickets users_purchase_counts = Purchase.query.filter_by(is_paid_for=True, state='paid') \ .join(PriceTier, Product, ProductGroup) \ .filter(ProductGroup.type.in_(RECEIPT_TYPES)) \ .join(Purchase.owner) \ .with_entities(User, func.count(Purchase.id)) \ .group_by(User) \ .order_by(User.id) for user, purchase_count in users_purchase_counts: plural = (purchase_count != 1 and 's' or '') msg = Message("Your Electromagnetic Field Ticket%s" % plural, sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) already_emailed = set_tickets_emailed(user) msg.body = render_template("emails/receipt.txt", user=user, already_emailed=already_emailed) attach_tickets(msg, user) app.logger.info('Emailing %s receipt for %s tickets', user.email, purchase_count) mail.send(msg) db.session.commit()
def run(self): # We set state to receipt-emailed in attach_tickets users_purchase_counts = Purchase.query.filter_by(is_paid_for=True, state='paid') \ .join(PriceTier, Product, ProductGroup) \ .filter(ProductGroup.type.in_(RECEIPT_TYPES)) \ .join(Purchase.owner) \ .with_entities(User, func.count(Purchase.id)) \ .group_by(User) \ .order_by(User.id) for user, purchase_count in users_purchase_counts: plural = (purchase_count != 1 and 's' or '') msg = Message("Your Electromagnetic Field Ticket%s" % plural, sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) msg.body = render_template("emails/receipt.txt", user=user) attach_tickets(msg, user) app.logger.info('Emailing %s receipt for %s tickets', user.email, purchase_count) mail.send(msg) db.session.commit()
def stripe_refund_start(payment_id): payment = get_user_payment_or_abort( payment_id, 'stripe', valid_states=['paid'], ) form = StripeRefundForm() if form.validate_on_submit(): app.logger.info('Creating refund request for Stripe payment %s', payment.id) req = RefundRequest(payment=payment, note=form.note.data) db.session.add(req) payment.state = 'refund-requested' if not app.config.get('TICKETS_NOTICE_EMAIL'): app.logger.warning('No tickets notice email configured, not sending') else: msg = Message("An EMF refund request has been received", sender=app.config.get('TICKETS_EMAIL'), recipients=[app.config.get('TICKETS_NOTICE_EMAIL')[1]]) msg.body = render_template('emails/notice-refund-request.txt', payment=payment) mail.send(msg) db.session.commit() flash("Your refund request has been sent") return redirect(url_for('users.purchases')) return render_template('payments/stripe-refund.html', payment=payment, form=form)
def signup(): if current_user.is_authenticated(): return redirect(url_for('tickets')) form = SignupForm(request.form, next=request.args.get('next')) if request.method == 'POST' and form.validate(): user = User(form.email.data, form.name.data) user.set_password(form.password.data) db.session.add(user) try: db.session.commit() except IntegrityError, e: app.logger.warn('Adding user raised %r, assuming duplicate email', e) flash( "This email address %s is already in use. Please log in, or reset your password if you've forgotten it." % (form.email.data)) return redirect(url_for('login')) login_user(user) # send a welcome email. msg = Message("Welcome to Electromagnetic Field", sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) msg.body = render_template("welcome-email.txt", user=user) mail.send(msg) return redirect(form.next.data or url_for('tickets'))
def stripe_payment_refunded(payment: StripePayment): # Email user msg = Message( "You have received a refund from EMF", sender=app.config.get("TICKETS_EMAIL"), recipients=[payment.user.email], ) msg.body = render_template("emails/stripe-refund-sent.txt", user=payment.user, payment=payment) mail.send(msg) if payment.state == "refunded": logger.info("Payment is already refunded, ignoring") return logger.info("Setting payment %s to refunded", payment.id) # Payment is already locked by the caller of stripe_update_payment with db.session.no_autoflush: for purchase in payment.purchases: purchase.refund_purchase() payment.state = "refunded" db.session.commit() ticket_admin_email( "Unexpected Stripe refund received", "emails/notice-payment-refunded.txt", payment=payment, )
def delete_calendar(): result = "" try: req = request.get_json() entry = Calendar.query.filter_by(id=req['id']).first() if entry.requestId is not None: try: beamReq = requests.query.filter_by(id=entry.requestId).first() beamReq.status = "Approved" beamReq.scheduled_start = None msg = Message("Beam Time Request Date Rescinded") msg.recipients = [beamReq.email] msg.body = "Your beam time request " + beamReq.title msg.body += " has had it's scheduled date rescinded.\n\n" msg.body += "ISEEU Team" mail.send(msg) except: pass Calendar.query.filter_by(id=req['id']).delete() db.session.commit() result = {'error': "", 'success': True} except Exception as e: result = {'error': str(e), 'success': False} return result
def users(): form = NewUserForm() if form.validate_on_submit(): email, name = form.email.data, form.name.data user = User(email, name) db.session.add(user) db.session.commit() app.logger.info( '%s manually created new user with email %s and id: %s', current_user.id, email, user.id) code = user.login_code(app.config['SECRET_KEY']) msg = Message('Welcome to the EMF website', sender=app.config['CONTACT_EMAIL'], recipients=[email]) msg.body = render_template('emails/manually-added-user.txt', user=user, code=code) mail.send(msg) flash('Created account for: %s' % name) return redirect(url_for('.users')) users = User.query.order_by(User.id).options(joinedload( User.permissions)).all() return render_template('admin/users/users.html', users=users, form=form)
def gocardless_payment_paid(payment): if payment.state == 'paid': logger.info('Payment is already paid, ignoring') return if payment.state == 'partrefunded': logger.info('Payment is already partially refunded, ignoring') return if payment.state != 'inprogress': logger.error( "Current payment state is %s (should be inprogress), ignoring", payment.state) return logger.info("Setting payment %s to paid", payment.id) payment.paid() msg = Message("Your EMF ticket payment has been confirmed", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) already_emailed = set_tickets_emailed(payment.user) msg.body = render_template('emails/tickets-paid-email-gocardless.txt', user=payment.user, payment=payment, already_emailed=already_emailed) if feature_enabled('ISSUE_TICKETS'): attach_tickets(msg, payment.user) db.session.commit() mail.send(msg)
def login(): if current_user.is_authenticated: return redirect(request.args.get('next', url_for('.account'))) if request.args.get('code'): user = User.get_by_code(app.config['SECRET_KEY'], request.args.get('code')) if user is not None: login_user(user) session.permanent = True return redirect(request.args.get('next', url_for('.account'))) else: flash("Your login link was invalid. Please note that they expire after 6 hours.") form = LoginForm(request.form, next=request.args.get('next')) if form.validate_on_submit(): code = form._user.login_code(app.config['SECRET_KEY']) msg = Message('Electromagnetic Field: Login details', sender=app.config['TICKETS_EMAIL'], recipients=[form._user.email]) msg.body = render_template('emails/login-code.txt', user=form._user, code=code, next_url=request.args.get('next')) mail.send(msg) flash("We've sent you an email with your login link") if request.args.get('email'): form.email.data = request.args.get('email') return render_template("account/login.html", form=form, next=request.args.get('next'))
def users(): form = NewUserForm() if form.validate_on_submit(): email, name = form.email.data, form.name.data user = User(email, name) db.session.add(user) db.session.commit() app.logger.info('%s manually created new user with email %s and id: %s', current_user.id, email, user.id) code = user.login_code(app.config['SECRET_KEY']) msg = Message('Welcome to the EMF website', sender=app.config['CONTACT_EMAIL'], recipients=[email]) msg.body = render_template('emails/manually-added-user.txt', user=user, code=code) mail.send(msg) flash('Created account for: %s' % name) return redirect(url_for('.users')) users = User.query.order_by(User.id).options(joinedload(User.permissions)).all() return render_template('admin/users/users.html', users=users, form=form)
def stripe_refund_start(payment_id): payment = get_user_payment_or_abort( payment_id, 'stripe', valid_states=['paid'], ) form = StripeRefundForm() if form.validate_on_submit(): app.logger.info('Setting Stripe payment %s to refund-requested', payment.id) payment.state = 'refund-requested' if not app.config.get('TICKETS_NOTICE_EMAIL'): app.logger.warning( 'No tickets notice email configured, not sending') else: msg = Message( "An EMF refund request has been received", sender=app.config.get('TICKETS_EMAIL'), recipients=[app.config.get('TICKETS_NOTICE_EMAIL')[1]]) msg.body = render_template('emails/notice-refund-request.txt', payment=payment) mail.send(msg) db.session.commit() flash("Your refund request has been sent") return redirect(url_for('users.purchases')) return render_template('payments/stripe-refund.html', payment=payment, form=form)
def reconcile(self, ref, amount, t): if t.type.lower() == 'other' or t.type.upper() == "DIRECTDEP": if str(ref).startswith("GOCARDLESS LTD "): # ignore gocardless payments return try: payment = self.find_payment(ref) except Exception, e: if not self.quiet: print "Exception matching ref %s paid %.2f: %s" % (repr(ref), amount, e) self.badrefs.append([repr(ref), amount]) else: user = payment.user # # so now we have the ref and an amount # if payment.state == "paid" and (Decimal(payment.amount_pence) / 100) == amount: # all paid up, great lets ignore this one. self.alreadypaid += 1 return unpaid = payment.tickets.all() total = Decimal(0) for t in unpaid: if t.paid == False: total += Decimal(str(t.type.cost)) elif not self.quiet: if payment.id not in self.overpays: print "attempt to pay for paid ticket: %d, user: %s, payment id: %d, paid: %.2f, ref %s" % (t.id, payment.user.name, payment.id, amount, ref) if total == 0: # nothing owed, so an old payment... return if total != amount and payment.id not in self.overpays: print "tried to reconcile payment %s for %s, but amount paid (%.2f) didn't match amount owed (%.2f)" % (ref, user.name, amount, total) else: # all paid up. if not self.quiet: print "user %s paid for %d (%.2f) tickets with ref: %s" % (user.name, len(unpaid), amount, ref) self.paid += 1 self.tickets_paid += len(unpaid) if self.doit: for t in unpaid: t.paid = True payment.state = "paid" db.session.commit() # send email # tickets-paid-email-banktransfer.txt msg = Message("Electromagnetic Field ticket purchase update", \ sender=app.config.get('TICKETS_EMAIL'), \ recipients=[payment.user.email] ) msg.body = render_template("tickets-paid-email-banktransfer.txt", \ user = payment.user, payment=payment ) mail.send(msg)
def send_reset_email(user): token = user.create_reset_token() msg = Message('Password Change', sender='*****@*****.**', recipients=[user.email]) msg.body = f'''To reset your password, follow this link: {url_for('users.reset_password', token=token, _external=True)} Ignore if you did not initiate the request.''' mail.send(msg)
def send_email(to, subject, template, **kw): msg = Message( mail_config.FlASKY_MAIL_SUBJECT_PREFIX + subject, sender = mail_config.FLASKY_MAIL_SENDER, recipients=[to] ) msg.body = render_template(template + '.txt', **kw) msg.html = render_template(template + '.html', **kw) mail.send(msg)
def transaction_reconcile(txn_id, payment_id): txn = BankTransaction.query.get_or_404(txn_id) payment = BankPayment.query.get_or_404(payment_id) form = ManualReconcilePaymentForm() if form.validate_on_submit(): if form.reconcile.data: app.logger.info( "%s manually reconciling against payment %s (%s) by %s", current_user.name, payment.id, payment.bankref, payment.user.email, ) if txn.payment: app.logger.error("Transaction already reconciled") flash("Transaction %s already reconciled" % txn.id) return redirect(url_for("admin.transactions")) payment.lock() if payment.state == "paid": app.logger.error("Payment has already been paid") flash("Payment %s already paid" % payment.id) return redirect(url_for("admin.transactions")) txn.payment = payment payment.paid() db.session.commit() msg = Message( "Electromagnetic Field ticket purchase update", sender=app.config["TICKETS_EMAIL"], recipients=[payment.user.email], ) already_emailed = set_tickets_emailed(payment.user) msg.body = render_template( "emails/tickets-paid-email-banktransfer.txt", user=payment.user, payment=payment, already_emailed=already_emailed, ) if feature_enabled("ISSUE_TICKETS"): attach_tickets(msg, payment.user) mail.send(msg) flash("Payment ID %s marked as paid" % payment.id) return redirect(url_for("admin.transactions")) return render_template("admin/accounts/txn-reconcile.html", txn=txn, payment=payment, form=form)
def send_async_email(msg): """ 异步发送邮件 :param msg: :return: """ from main import app with app.app_context(): mail.send(msg)
def tickets_reserve(email): user = User.get_by_email(email) if user is None: form = ReserveTicketsNewUserForm() new_user = True else: form = ReserveTicketsForm() new_user = False pts = PriceTier.query.join(Product, ProductGroup) \ .order_by(ProductGroup.name, Product.display_name, Product.id).all() form.add_price_tiers(pts) if form.validate_on_submit(): if not user: name = form.name.data app.logger.info('Creating new user with email %s and name %s', email, name) user = User(email, name) flash('Created account for %s' % name) db.session.add(user) basket = form.create_basket(user) app.logger.info('Admin basket for %s %s', user.email, basket) try: basket.create_purchases() basket.ensure_purchase_capacity() db.session.commit() except CapacityException as e: db.session.rollback() app.logger.warn('Limit exceeded creating admin tickets: %s', e) return redirect(url_for('.tickets_reserve', email=email)) code = user.login_code(app.config['SECRET_KEY']) msg = Message('Your reserved tickets to EMF', sender=app.config['TICKETS_EMAIL'], recipients=[user.email]) msg.body = render_template('emails/tickets-reserved.txt', user=user, code=code, tickets=basket.purchases, new_user=new_user, currency=form.currency.data) mail.send(msg) db.session.commit() flash('Reserved tickets and emailed {}'.format(user.email)) return redirect(url_for('.tickets_issue')) return render_template('admin/tickets/tickets-reserve.html', form=form, pts=pts, user=user)
def create_gc_payment(payment): try: logger.info("Creating GC payment for %s (%s)", payment.id, payment.mandate) gc_payment = gocardless_client.payments.create(params={ "amount": payment.amount_int, "currency": payment.currency, "links": { "mandate": payment.mandate, }, "metadata": { "payment_id": str(payment.id), }, }, headers={'Idempotency-Key': str(payment.id)}) payment.gcid = gc_payment.id payment.state = 'inprogress' except gocardless_pro.errors.ValidationFailedError as exc: currency_errors = [e for e in exc.errors if e['field'] == 'currency'] if currency_errors: # e['message'] will be one of: # 'must be GBP for a bacs mandate' # 'must be EUR for a sepa_core mandate' logger.error("Currency exception %r confirming payment", exc) flash("Your account cannot be used for {} payments".format(payment.currency)) else: logger.error("Exception %r confirming payment", exc) flash("An error occurred with your payment, please contact {}".format(app.config['TICKETS_EMAIL'][1])) return redirect(url_for('users.purchases')) except Exception as e: logger.error("Exception %r confirming payment", e) flash("An error occurred with your payment, please contact {}".format(app.config['TICKETS_EMAIL'][1])) return redirect(url_for('users.purchases')) # We need to make sure of a 5 working days grace # for gocardless payments, so push the payment expiry forwards payment.expires = datetime.utcnow() + timedelta(days=app.config['EXPIRY_DAYS_GOCARDLESS']) for purchase in payment.purchases: purchase.set_state('payment-pending') db.session.commit() logger.info("Reset expiry for payment %s", payment.id) # FIXME: determine whether these are tickets or generic products msg = Message("Your EMF ticket purchase", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) msg.body = render_template("emails/tickets-purchased-email-gocardless.txt", user=payment.user, payment=payment) mail.send(msg) return redirect(url_for('.gocardless_waiting', payment_id=payment.id))
def send_confirmation(payment): msg = Message("Electromagnetic Field ticket purchase update", sender=app.config['TICKETS_EMAIL'], recipients=[payment.user.email]) msg.body = render_template("emails/tickets-paid-email-banktransfer.txt", user=payment.user, payment=payment) if feature_enabled('ISSUE_TICKETS'): attach_tickets(msg, payment.user) mail.send(msg) db.session.commit()
def run(self): query = text("""select distinct "user".id from "user", ticket where ticket.user_id = "user".id and ticket.paid = true""") for row in db.engine.execute(query): user = User.query.filter_by(id=row[0]).one() msg = Message("Your Electromagnetic Field Ticket", sender=app.config['TICKETS_EMAIL'], recipients=[user.email] ) user.create_receipt() msg.body = render_template("ticket.txt", user=user) print "Sending to", user.email, "..." mail.send(msg)
def post(self): if request.form["repassword"] != request.form["password"]: flash(u"两次输入密码不一致!") return redirect('/regist') elif request.form["verify_code"] != session["verify_code"]: flash(u"验证码错误!") return redirect('/regist') mail_html = open(os.path.join(app.root_path, 'static/mail/email_regist.html')).read() url = auth_token.Auth_token.generate_auth_token(request.form) msg = Message(u'明天工作室', recipients=[request.form["email"]]) msg.html = mail_html.replace('{}', url) mail.send(msg) flash(u"已发送验证链接到您的邮箱,请登录您的邮箱完成注册!") return redirect('/regist')
def notify_email(volunteer, subject, message): template = 'notification/email/volunteer_request.txt' while True: msg = Message(subject, sender=app.config['VOLUNTEER_EMAIL'], recipients=[volunteer.volunteer_email]) msg.body = render_template(template, message=message, volunteer=volunteer) try: mail.send(msg) return True except AttributeError as e: app.logger.error('Failed to email volunteer %s, ABORTING: %s', volunteer.volunteer_email, e) return False
def forgot_password(): form = ForgotPasswordForm(request.form) if request.method == 'POST' and form.validate(): if form._user: reset = PasswordReset(form.email.data) reset.new_token() db.session.add(reset) db.session.commit() msg = Message("EMF password reset", sender=app.config.get('TICKETS_EMAIL'), recipients=[form.email.data]) msg.body = render_template("reset-password-email.txt", user=form._user, reset=reset) mail.send(msg) return redirect(url_for('reset_password', email=form.email.data)) return render_template("forgot-password.html", form=form)
def run(self): proposals = Proposal.query.filter(Proposal.scheduled_duration.isnot(None)).\ filter(Proposal.state.in_(['accepted'])).\ filter(Proposal.type.in_(['talk', 'workshop'])).all() for proposal in proposals: user = proposal.user msg = Message("We really need information about your EMF %s '%s'!" % (proposal.type, proposal.title), sender=app.config['SPEAKERS_EMAIL'], recipients=[user.email]) msg.body = render_template("emails/cfp-please-finalise.txt", user=user, proposal=proposal) app.logger.info('Emailing %s about proposal %s', user.email, proposal.title) mail.send(msg) db.session.commit()
def transfer_start(): payment = add_payment_and_tickets(BankPayment) if not payment: flash("Your session information has been lost. Please try ordering again.") return redirect(url_for("tickets")) app.logger.info("User %s created bank payment %s (%s)", current_user.id, payment.id, payment.bankref) payment.state = "inprogress" db.session.add(payment) db.session.commit() msg = Message("Your EMF ticket purchase", sender=app.config.get("TICKETS_EMAIL"), recipients=[current_user.email]) msg.body = render_template("tickets-purchased-email-banktransfer.txt", user=current_user, payment=payment) mail.send(msg) return redirect(url_for("transfer_waiting", payment=payment.id))
def signup(): if not request.args.get('code'): abort(404) uid = verify_signup_code(app.config['SECRET_KEY'], time.time(), request.args.get('code')) if uid is None: flash("Your signup link was invalid. Please note that they expire after 6 hours.") abort(404) user = User.query.get_or_404(uid) if not user.has_permission('admin'): app.logger.warn("Signup link resolves to non-admin user %s", user) abort(404) form = SignupForm() if current_user.is_authenticated: return redirect(url_for('.account')) if form.validate_on_submit(): email, name = form.email.data, form.name.data user = User(email, name) if form.allow_promo.data: user.promo_opt_in = True db.session.add(user) db.session.commit() app.logger.info('Signed up new user with email %s and id %s', email, user.id) msg = Message('Welcome to the EMF website', sender=app.config['CONTACT_EMAIL'], recipients=[email]) msg.body = render_template('emails/signup-user.txt', user=user) mail.send(msg) login_user(user) return redirect(url_for('.account')) if request.args.get('email'): form.email.data = request.args.get('email') return render_template("account/signup.html", form=form)
def post(self): if request.form["verify_code"] != session["verify_code"]: flash(u"验证码错误!") return redirect('/password/forget') cur = db.connection.cursor() cur.execute("""select email from user_info where email="{}";""".format(request.form['email'])) email = cur.fetchone() if email: mail_html = open(os.path.join(app.root_path, 'static/mail/email_password.html')).read() msg = Message(u'明天工作室', recipients=[request.form["email"]]) url = auth_token.Auth_token.generate_auth_token({"email": email[0]}) msg.html = mail_html.replace('{}', url) mail.send(msg) flash(u"请登录您的邮箱获取重置链接!") return redirect('/password/forget') else: flash(u"用户不存在!") return redirect('/password/forget')