Skip to content
Snippets Groups Projects
Commit a4e97028 authored by ale's avatar ale
Browse files

enable sending invitation emails - last missing part of the invite system

parent 3d8b619c
Branches
No related tags found
No related merge requests found
......@@ -9,6 +9,7 @@ from djrandom import daemonize
from djrandom import utils
from djrandom.database import init_db
from djrandom.frontend import app, svcs
from djrandom.frontend.mailer import Mailer
from djrandom.frontend.search import Searcher
from djrandom.model.external import AlbumImageRetriever
from gevent.wsgi import WSGIServer
......@@ -16,11 +17,13 @@ from gevent.wsgi import WSGIServer
log = logging.getLogger(__name__)
def run_frontend(port, solr_url, db_url, lastfm_api_key, album_art_dir):
def run_frontend(port, solr_url, db_url, lastfm_api_key, album_art_dir,
email_sender):
init_db(db_url)
svcs['searcher'] = Searcher(solr_url)
svcs['album_images'] = AlbumImageRetriever(lastfm_api_key, album_art_dir)
svcs['mailer'] = Mailer(email_sender)
http_server = WSGIServer(('0.0.0.0', port), app)
http_server.serve_forever()
......@@ -32,6 +35,7 @@ def main():
parser.add_option('--port', type='int', default=3003)
parser.add_option('--db_url')
parser.add_option('--lastfm_api_key')
parser.add_option('--email_sender', default='djrandom@localhost')
parser.add_option('--album_art_dir', default='/var/tmp/album-image-cache')
daemonize.add_standard_options(parser)
utils.read_config_defaults(
......@@ -44,7 +48,8 @@ def main():
daemonize.daemonize(opts, run_frontend,
(opts.port, opts.solr_url, opts.db_url,
opts.lastfm_api_key, opts.album_art_dir),
opts.lastfm_api_key, opts.album_art_dir,
opts.email_sender),
support_gevent=True)
......
import smtplib
from email.mime.text import MIMEText
class Mailer(object):
def __init__(self, sender):
self.sender = sender
def send(self, to, subject, message):
msg = MIMEText(message)
msg['Subject'] = '[DJ:Random] %s' % (subject,)
msg['From'] = self.sender
msg['To'] = to
conn = smtplib.SMTP('localhost')
conn.sendmail(self.sender, [to], msg.as_string())
conn.quit()
......@@ -27,6 +27,10 @@ class UserDetailsForm(Form):
raise ValidationError('Passwords are different')
class InviteForm(Form):
email = TextField('Email to invite', [validators.Email()])
class LoginForm(Form):
email = TextField('Email', [validators.Required()])
password = PasswordField('Password', [validators.Required()])
......@@ -89,3 +93,37 @@ def user_revoke_api_key(keyid):
Session.delete(key)
Session.commit()
return redirect('/user/details')
@app.route('/user/invite', methods=['GET', 'POST'])
@require_auth
def user_send_invite():
form = InviteForm()
if form.validate_on_submit():
user = User.query.get(g.userid)
username = user.email.split('@')[0]
email = form.email.data
new_user = User(email, 'x')
svcs['mailer'].send(email, 'Invitation',
new_user.get_activation_email(username))
Session.add(new_user)
Session.commit()
return redirect('/user/details')
return render_template('user_invite.html', form=form)
@app.route('/user/activate/<token>')
def user_activate(token):
email = request.args.get('email')
user = User.query.filter_by(activation_token=token).first()
if not user or user.email != email:
abort(404)
session['userid'] = user.id
user.active = True
Session.add(user)
Session.commit()
log.info('activated user %s' % user.email)
return redirect('/user/details')
......@@ -6,6 +6,22 @@ from datetime import datetime
from djrandom import utils
from djrandom.database import Base
ACTIVATION_TEMPLATE ='''
Hello %(email)s,
%(sent_by)s has invited you to djrandom.incal.net.
Click the following link to activate your account:
%(activation_link)s
--
djrandom invitebot
http://djrandom.incal.net/
'''
def _salt():
return '$6$' + base64.b64encode(os.urandom(12))
......@@ -51,6 +67,14 @@ class User(Base):
def create_api_key(self):
return APIKey(self.id)
def get_activation_email(self, sent_by):
activation_link = 'http://djrandom.incal.net/user/activate/%s?e=%s' % (
self.activation_token, self.email)
return ACTIVATION_TEMPLATE % dict(
email=self.email,
sent_by=sent_by,
activation_link=activation_link)
@classmethod
def find_with_api_key(cls, key):
key_obj = APIKey.query.get(key)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment