Commits

Jiangge Zhang committed bd3bafd Merge

Merged feature/async-mail-sender into develop

  • Participants
  • Parent commits fc74fb2, f24a36a

Comments (0)

Files changed (9)

-web: python manage.py runserver
+web: python manage.py runserver --port $PORT
+redis: redis-server --port $PORT
+worker: python manage.py runworker
 postgresql: [ -d $PASSWOOD_DATADIR ] || (mkdir $PASSWOOD_DATADIR && initdb -D $PASSWOOD_DATADIR -E utf-8) && postgres -D $PASSWOOD_DATADIR -k $PASSWOOD_DATADIR
 
 - Python 3.3 (with `virtualenv`_ and `pip`_ installed)
 - Node.js (with `npm`_ installed)
+- Redis Server
 
 And the `bower`_ need to be installed in system-wide::
 
     (passwood-env) $ npm install  # install assets compilers
     (passwood-env) $ bower install  # install assets
 
-Start the devlopment server::
+Start the devlopment server and backend services::
 
     (passwood-env) $ honcho start
 
 import getpass
 
 from flask.ext.script import Manager
+from flask.ext.rq import get_worker
 
 from passwood.app import create_app
-from passwood.ext import db
+from passwood.ext import db, RQ_QUEUES
 from passwood.models.user import User
 
 
     db.session.commit()
 
 
+@manager.command
+def runworker():
+    """Runs worker to execute queues."""
+    worker = get_worker(*RQ_QUEUES)
+    worker.work()
+
+
 if __name__ == "__main__":
     manager.run()
 from flask import Flask
 
-from .ext import db, csrf, mail, login_manager, compressor
+from .ext import db, csrf, mail, login_manager, compressor, rq
 from .views import home, user
 
 
     mail.init_app(app)
     login_manager.init_app(app)
     compressor.init_app(app)
+    rq.init_app(app)
 
     app.register_blueprint(home.bp)
     app.register_blueprint(user.bp)

passwood/dev.cfg.example

 MAIL_USE_TLS = True
 MAIL_USERNAME = "mail-username@example.com"
 MAIL_PASSWORD = "mail-password"
+
+RQ_MAIL_URL = "redis://localhost:5101/1"
 from flask.ext.mail import Mail
 from flask.ext.login import LoginManager
 from flask.ext.compressor import Compressor
+from flask.ext.rq import RQ
 
 from .assets import register_bundles, register_processors
 
 
+RQ_QUEUES = ["mail"]
+
+
 db = SQLAlchemy()
 csrf = CsrfProtect()
 mail = Mail()
 login_manager = LoginManager()
 compressor = Compressor()
+rq = RQ()
 
 register_bundles(compressor)
 register_processors(compressor)

passwood/templates/messages/verify-email.html

 <p>{{ user.name }}, welcome to join us.</p>
 <p>
   Please open
-  <a href="{{ url_for('.verify_email', name=user.name, token_value=token.value, _external=True) }}">this link</a>
+  <a href="{{ url_for('user.verify_email', name=user.name, token_value=token.value, _external=True) }}">this link</a>
   to verify your email address.
 </p>

passwood/views/user.py

 from flask.ext.wtf import Form
 from flask.ext.login import login_user, logout_user
 from flask.ext.mail import Message
+from flask.ext.rq import job
 from wtforms import TextField, PasswordField, SubmitField
 from wtforms import validators
 
         db.session.add(token)
         db.session.commit()
 
-        send_verified_email(user, token)
+        send_verified_email.delay(user.id, token.value)
         flash("Please check your mail to verify the account.")
         return redirect(url_for("home.home"))
 
     return "The token is invalid or expired."
 
 
-def send_verified_email(user, token):
+@job("mail")
+def send_verified_email(user_id, token_value):
+    user = User.query.get(user_id)
+    token = UserToken.query.get(token_value)
+
+    if not user:
+        raise RuntimeError("user not found: %r" % user_id)
+    if not token:
+        raise RuntimeError("token not found: %r" % token_value)
+
     title = "Please verify your email address"
     message = Message(title, recipients=[user.email])
     message.html = render_template("messages/verify-email.html", user=user,
                                    token=token, title=title)
+
     mail.send(message)
 
 
 Flask-Compressor==0.1.0
 Flask-Login==0.2.7
 Flask-Mail==0.9.0
+Flask-RQ==0.2
 Flask-SQLAlchemy==1.0
 Flask-Script==0.6.3
 Flask-WTF==0.9.3
 coverage==3.7.1
 cssmin==0.2.0
 execnet==1.1
+honcho==0.5.0
+ipython==1.1.0
 itsdangerous==0.23
 jsmin==2.0.8
 passlib==1.6.1
 pytest-cache==1.0
 pytest-cov==1.6
 pytest-pep8==1.0.5
+python-dateutil==2.2
+pytz==2013.9
+redis==2.9.0
+rq==0.3.13
+six==1.5.2
 stylus==0.1.0
+times==0.6.2