Email framework
Notifications will be sent when someone submits an application.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from flask import Flask
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from flask.ext.mail import Mail
|
||||
|
||||
# Create app
|
||||
app = Flask(__name__)
|
||||
@@ -8,6 +9,7 @@ app.config.from_object(config.Development)
|
||||
|
||||
# Create database connection object
|
||||
db = SQLAlchemy(app)
|
||||
mail = Mail(app)
|
||||
|
||||
from controllers import main
|
||||
from controllers import admin
|
||||
|
@@ -1,11 +1,12 @@
|
||||
from application import app, db
|
||||
from application.emails import send_email_notification_new_submission
|
||||
from application.models.users import *
|
||||
from application.models.applications import Application, Skill
|
||||
|
||||
from flask import render_template, redirect, url_for, request, flash
|
||||
from flask.ext.security import login_required
|
||||
from flask.ext.security.core import current_user
|
||||
from sqlalchemy.orm.exc import MultipleResultsFound
|
||||
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
|
||||
from flask_wtf import Form
|
||||
from wtforms import TextField, TextAreaField, BooleanField, SelectMultipleField
|
||||
from wtforms.validators import DataRequired
|
||||
@@ -46,9 +47,9 @@ def apply():
|
||||
form = ApplicationForm()
|
||||
form.skills.choices = [(s.id, s.name) for s in Skill.query.all()]
|
||||
if form.validate_on_submit():
|
||||
print 'validating'
|
||||
application = Application(
|
||||
blender_id=current_user.id,
|
||||
network_profile=form.website.data,
|
||||
website=form.website.data,
|
||||
city_country=form.city_country.data,
|
||||
institution_name=form.institution_name.data,
|
||||
@@ -62,6 +63,7 @@ def apply():
|
||||
application.skills.append(s)
|
||||
db.session.add(application)
|
||||
db.session.commit()
|
||||
send_email_notification_new_submission(application)
|
||||
return redirect(url_for('my_application'))
|
||||
# print form.errors
|
||||
return render_template('apply.html',
|
||||
@@ -77,8 +79,8 @@ def my_application():
|
||||
except MultipleResultsFound:
|
||||
flash('You have submitted more than one application. Get in touch with support@blendernetwork.org.')
|
||||
return render_template('index.html')
|
||||
if not application:
|
||||
except NoResultFound:
|
||||
return redirect(url_for('apply'))
|
||||
else:
|
||||
return render_template('my_application.html',
|
||||
application=application)
|
||||
|
||||
return render_template('my_application.html',
|
||||
application=application)
|
||||
|
7
blender-bfct/application/decorators.py
Normal file
7
blender-bfct/application/decorators.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from threading import Thread
|
||||
|
||||
def async(f):
|
||||
def wrapper(*args, **kwargs):
|
||||
thr = Thread(target = f, args = args, kwargs = kwargs)
|
||||
thr.start()
|
||||
return wrapper
|
34
blender-bfct/application/emails.py
Normal file
34
blender-bfct/application/emails.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from flask import render_template
|
||||
from flask.ext.mail import Message
|
||||
from application import mail
|
||||
from application import app
|
||||
from decorators import async
|
||||
|
||||
from application.models.users import user_datastore
|
||||
from application.helpers import get_board_members_emails
|
||||
|
||||
from flask.ext.security import current_user
|
||||
|
||||
|
||||
@async
|
||||
def send_async_email(msg):
|
||||
with app.app_context():
|
||||
mail.send(msg)
|
||||
|
||||
|
||||
def send_email(subject, sender, recipients, text_body, html_body):
|
||||
msg = Message(subject, sender = sender, recipients = recipients)
|
||||
msg.body = text_body
|
||||
msg.html = html_body
|
||||
send_async_email(msg)
|
||||
|
||||
|
||||
def send_email_notification_new_submission(application):
|
||||
board_members = get_board_members_emails()
|
||||
send_email("[BFCT] New BFCT application submitted",
|
||||
'bfct-robot@blender.org',
|
||||
board_members,
|
||||
render_template("email/new_submission.txt",
|
||||
application=application),
|
||||
render_template("email/new_submission.html",
|
||||
application=application))
|
@@ -1,3 +1,5 @@
|
||||
from application.models.users import User, Role
|
||||
|
||||
def pretty_date(time=False):
|
||||
"""
|
||||
Get a datetime object or a int() Epoch timestamp and return a
|
||||
@@ -40,3 +42,9 @@ def pretty_date(time=False):
|
||||
if day_diff <= 365:
|
||||
return str(day_diff/30) + " months ago"
|
||||
return str(day_diff/365) + " years ago"
|
||||
|
||||
|
||||
def get_board_members_emails():
|
||||
board_members = User.query.join(Role, User.roles).filter(Role.name == 'bfct_board').all()
|
||||
board_members_emails = [member.email for member in board_members]
|
||||
return board_members_emails
|
||||
|
@@ -31,7 +31,7 @@ class Role(db.Model, RoleMixin):
|
||||
# Define models
|
||||
roles_users = db.Table('roles_users',
|
||||
db.Column('user_id', db.Integer(), db.ForeignKey(User.id)),
|
||||
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')),
|
||||
db.Column('role_id', db.Integer(), db.ForeignKey(Role.id)),
|
||||
info={'bind_key': 'users'})
|
||||
|
||||
# Setup Flask-Security
|
||||
|
@@ -108,8 +108,9 @@
|
||||
<hr/>
|
||||
|
||||
<div class="input-group input-group-lg width-full">
|
||||
{{ form.bio_message(class='form-control', id='editor1', placeholder='Tell us a bit about yourself and why you want to be a BFCT') }}
|
||||
<label class="control-label">Biography or Personal Message</label>
|
||||
{{ form.bio_message(class='form-control', id='editor1', placeholder='Tell us a bit about yourself and why you want to be a BFCT') }}
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
@@ -0,0 +1,4 @@
|
||||
<p>Hello!</p>
|
||||
<p>A new BFCT application awaits your review! Check it out at the <a href="http://www.blender.org/certification{{url_for('applications.view', id=application.id)}}">BFCT portal</a>.</p>
|
||||
|
||||
<p>The BFCT robot</p>
|
@@ -0,0 +1,4 @@
|
||||
Hello!
|
||||
A new BFCT application awaits your review! Check it out at http://www.blender.org/certification{{url_for('applications.view', id=application.id)}}.
|
||||
|
||||
The BFCT robot
|
Reference in New Issue
Block a user