diff options
Diffstat (limited to 'pyaggr3g470r')
-rw-r--r-- | pyaggr3g470r/__init__.py | 4 | ||||
-rw-r--r-- | pyaggr3g470r/forms.py | 17 | ||||
-rw-r--r-- | pyaggr3g470r/templates/login.html | 4 | ||||
-rw-r--r-- | pyaggr3g470r/templates/signup.html | 28 | ||||
-rw-r--r-- | pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo | bin | 9296 -> 9531 bytes | |||
-rw-r--r-- | pyaggr3g470r/translations/fr/LC_MESSAGES/messages.po | 165 | ||||
-rw-r--r-- | pyaggr3g470r/views.py | 29 |
7 files changed, 167 insertions, 80 deletions
diff --git a/pyaggr3g470r/__init__.py b/pyaggr3g470r/__init__.py index e4023f37..fd08ffc6 100644 --- a/pyaggr3g470r/__init__.py +++ b/pyaggr3g470r/__init__.py @@ -19,6 +19,10 @@ app.config['SECRET_KEY'] = os.urandom(12) app.config['SQLALCHEMY_DATABASE_URI'] = conf.SQLALCHEMY_DATABASE_URI db = SQLAlchemy(app) +app.config['RECAPTCHA_USE_SSL'] = True +app.config['RECAPTCHA_PUBLIC_KEY'] = conf.RECAPTCHA_PUBLIC_KEY +app.config['RECAPTCHA_PRIVATE_KEY'] = conf.RECAPTCHA_PRIVATE_KEY + ALLOWED_EXTENSIONS = set(['xml', 'opml']) def allowed_file(filename): diff --git a/pyaggr3g470r/forms.py b/pyaggr3g470r/forms.py index 7f9ab88b..6a11362c 100644 --- a/pyaggr3g470r/forms.py +++ b/pyaggr3g470r/forms.py @@ -30,9 +30,26 @@ from flask import flash from flask.ext.wtf import Form from flask.ext.babel import lazy_gettext from wtforms import TextField, TextAreaField, PasswordField, BooleanField, SubmitField, validators +from flask_wtf import RecaptchaField from pyaggr3g470r.models import User +class SignupForm(Form): + firstname = TextField(lazy_gettext("First name"), [validators.Required(lazy_gettext("Please enter your first name."))]) + lastname = TextField(lazy_gettext("Last name"), [validators.Required(lazy_gettext("Please enter your last name."))]) + email = TextField(lazy_gettext("Email"), [validators.Required(lazy_gettext("Please enter your email."))]) + password = PasswordField(lazy_gettext("Password")) + recaptcha = RecaptchaField() + submit = SubmitField(lazy_gettext("Sign up")) + + def __init__(self, *args, **kwargs): + Form.__init__(self, *args, **kwargs) + + def validate(self): + if not Form.validate(self): + return False + return True + class SigninForm(Form): """ Sign in form. diff --git a/pyaggr3g470r/templates/login.html b/pyaggr3g470r/templates/login.html index 689b259f..0a3bec2e 100644 --- a/pyaggr3g470r/templates/login.html +++ b/pyaggr3g470r/templates/login.html @@ -26,8 +26,6 @@ {{ form.submit(class_="btn") }} </form> </div> - {% if email != '' %} - <p><a href="mailto:{{ email }}?subject=[pyAggr3g470r] {{ _('Account creation') }}">{{ _('Request an account.') }}</a></p> - {% endif %} + <a href="/signup/" class="btn btn-default">{{ _('Sign up') }}</a> </div><!-- /.container --> {% endblock %}
\ No newline at end of file diff --git a/pyaggr3g470r/templates/signup.html b/pyaggr3g470r/templates/signup.html new file mode 100644 index 00000000..9c2ad32c --- /dev/null +++ b/pyaggr3g470r/templates/signup.html @@ -0,0 +1,28 @@ +{% extends "layout.html" %} +{% block content %} +<div class="container"> + <div class="jumbotron"> + <form action="" method="post" name="save"> + {{ form.hidden_tag() }} + + {{ form.firstname.label }} + {{ form.firstname(class_="form-control") }} {% for error in form.firstname.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %} + + {{ form.lastname.label }} + {{ form.lastname(class_="form-control") }} {% for error in form.lastname.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %} + + {{ form.email.label }} + {{ form.email(class_="form-control") }} {% for error in form.email.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %} + + {{ form.password.label }} + {{ form.password(class_="form-control") }} {% for error in form.password.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %} + + {{ form.recaptcha.label }} + {{ form.recaptcha }} {% for error in form.recaptcha.errors %} <span style="color: red;">{{ error }}<br /></span> {% endfor %} + + <br /> + {{ form.submit(class_="btn") }} + </form> + </div> +</div><!-- /.container --> +{% endblock %} diff --git a/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo b/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo Binary files differindex 788fca40..b1ecc508 100644 --- a/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo +++ b/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo diff --git a/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.po b/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.po index 51e12053..ff548119 100644 --- a/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.po +++ b/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2014-05-05 08:36+0200\n" -"PO-Revision-Date: 2014-05-05 08:37+0100\n" +"POT-Creation-Date: 2014-05-05 12:19+0200\n" +"PO-Revision-Date: 2014-05-05 12:20+0100\n" "Last-Translator: Cédric Bonhomme <cedric@cedricbonhomme.org>\n" "Language-Team: fr <LL@li.org>\n" "Language: fr\n" @@ -19,208 +19,221 @@ msgstr "" "Generated-By: Babel 1.3\n" "X-Generator: Poedit 1.5.4\n" -#: pyaggr3g470r/forms.py:40 -msgid "Please enter your email address." -msgstr "S'il vous plaît, entrez votre adresse email." +#: pyaggr3g470r/forms.py:38 pyaggr3g470r/forms.py:93 +msgid "First name" +msgstr "Prénom" + +#: pyaggr3g470r/forms.py:38 pyaggr3g470r/forms.py:93 +msgid "Please enter your first name." +msgstr "S'il vous plaît, entrez votre prénom." + +#: pyaggr3g470r/forms.py:39 pyaggr3g470r/forms.py:94 +msgid "Last name" +msgstr "Nom de famille" + +#: pyaggr3g470r/forms.py:39 pyaggr3g470r/forms.py:94 +msgid "Please enter your last name." +msgstr "S'il vous plaît, entrez votre nom de famille." + +#: pyaggr3g470r/forms.py:40 pyaggr3g470r/forms.py:95 +#: pyaggr3g470r/templates/admin/dashboard.html:14 +msgid "Email" +msgstr "Email" + +#: pyaggr3g470r/forms.py:40 pyaggr3g470r/forms.py:95 +msgid "Please enter your email." +msgstr "S'il vous plaît, entrez votre email." -#: pyaggr3g470r/forms.py:41 pyaggr3g470r/forms.py:79 +#: pyaggr3g470r/forms.py:41 pyaggr3g470r/forms.py:58 pyaggr3g470r/forms.py:96 msgid "Password" msgstr "Mot de passe" -#: pyaggr3g470r/forms.py:41 +#: pyaggr3g470r/forms.py:43 +msgid "Sign up" +msgstr "S'inscrire" + +#: pyaggr3g470r/forms.py:57 +msgid "Please enter your email address." +msgstr "S'il vous plaît, entrez votre adresse email." + +#: pyaggr3g470r/forms.py:58 msgid "Please enter a password." msgstr "S'il vous plaît entrer un mot de passe." -#: pyaggr3g470r/forms.py:42 pyaggr3g470r/templates/login.html:5 +#: pyaggr3g470r/forms.py:59 pyaggr3g470r/templates/login.html:5 msgid "Log In" msgstr "Connexion" -#: pyaggr3g470r/forms.py:55 +#: pyaggr3g470r/forms.py:72 msgid "Invalid email or password" msgstr "E-mail ou mot de passe invalide" -#: pyaggr3g470r/forms.py:60 pyaggr3g470r/templates/feeds.html:11 +#: pyaggr3g470r/forms.py:77 pyaggr3g470r/templates/feeds.html:11 msgid "Title" msgstr "Titre" -#: pyaggr3g470r/forms.py:60 +#: pyaggr3g470r/forms.py:77 msgid "Please enter a title." msgstr "S'il vous plaît, entrez un titre." -#: pyaggr3g470r/forms.py:61 pyaggr3g470r/templates/admin/user.html:30 +#: pyaggr3g470r/forms.py:78 pyaggr3g470r/templates/admin/user.html:30 msgid "Feed link" msgstr "Lien du flux" -#: pyaggr3g470r/forms.py:61 +#: pyaggr3g470r/forms.py:78 msgid "Please enter a link for the feed." msgstr "S'il vous plaît, entrez un lien pour le flux." -#: pyaggr3g470r/forms.py:62 pyaggr3g470r/templates/admin/user.html:31 +#: pyaggr3g470r/forms.py:79 pyaggr3g470r/templates/admin/user.html:31 msgid "Site link" msgstr "Lien du site" -#: pyaggr3g470r/forms.py:63 +#: pyaggr3g470r/forms.py:80 msgid "Email notification" msgstr "Notification par email" -#: pyaggr3g470r/forms.py:64 +#: pyaggr3g470r/forms.py:81 msgid "Check for updates" msgstr "Vérifier les mises à jour" -#: pyaggr3g470r/forms.py:65 pyaggr3g470r/forms.py:80 +#: pyaggr3g470r/forms.py:82 pyaggr3g470r/forms.py:97 msgid "Save" msgstr "Sauver" -#: pyaggr3g470r/forms.py:76 -msgid "First name" -msgstr "Prénom" - -#: pyaggr3g470r/forms.py:76 -msgid "Please enter your first name." -msgstr "S'il vous plaît, entrez votre prénom." - -#: pyaggr3g470r/forms.py:77 -msgid "Last name" -msgstr "Nom de famille" - -#: pyaggr3g470r/forms.py:77 -msgid "Please enter your last name." -msgstr "S'il vous plaît, entrez votre nom de famille." - -#: pyaggr3g470r/forms.py:78 pyaggr3g470r/templates/admin/dashboard.html:14 -msgid "Email" -msgstr "Email" - -#: pyaggr3g470r/forms.py:78 -msgid "Please enter your email." -msgstr "S'il vous plaît, entrez votre email." - -#: pyaggr3g470r/views.py:93 +#: pyaggr3g470r/views.py:94 msgid "Authentication required." msgstr "Authentification requise." -#: pyaggr3g470r/views.py:98 +#: pyaggr3g470r/views.py:99 msgid "Forbidden." msgstr "Interdit." -#: pyaggr3g470r/views.py:143 +#: pyaggr3g470r/views.py:144 msgid "Logged in successfully." msgstr "Connecté avec succès." -#: pyaggr3g470r/views.py:163 +#: pyaggr3g470r/views.py:164 msgid "Logged out successfully." msgstr "Déconnecté avec succès." -#: pyaggr3g470r/views.py:195 +#: pyaggr3g470r/views.py:185 +msgid "Email already used." +msgstr "Email déjà utilisé." + +#: pyaggr3g470r/views.py:188 +msgid "Your account has been created. You can now sign." +msgstr "Votre compte a été créé. Vous pouvez maintenant vous connecter." + +#: pyaggr3g470r/views.py:222 msgid "Downloading articles..." msgstr "Téléchargement des articles." -#: pyaggr3g470r/views.py:283 +#: pyaggr3g470r/views.py:310 msgid "Articles marked as read." msgstr "Articles marqués comme lus." -#: pyaggr3g470r/views.py:286 +#: pyaggr3g470r/views.py:313 msgid "All articles marked as read" msgstr "Tous les articles marqués comme lus." -#: pyaggr3g470r/views.py:317 +#: pyaggr3g470r/views.py:344 msgid "Article" msgstr "Article" -#: pyaggr3g470r/views.py:317 +#: pyaggr3g470r/views.py:344 msgid "deleted." msgstr "supprimé." -#: pyaggr3g470r/views.py:320 +#: pyaggr3g470r/views.py:347 msgid "This article do not exist." msgstr "Cet article n'existe pas." -#: pyaggr3g470r/views.py:413 +#: pyaggr3g470r/views.py:440 msgid "Database indexed." msgstr "Base de données indexée." -#: pyaggr3g470r/views.py:415 pyaggr3g470r/views.py:484 +#: pyaggr3g470r/views.py:442 pyaggr3g470r/views.py:511 msgid "An error occured" msgstr "Une erreur est survenue." -#: pyaggr3g470r/views.py:418 +#: pyaggr3g470r/views.py:445 msgid "Option not available on Heroku." msgstr "Option non disponible sur Heroku." -#: pyaggr3g470r/views.py:433 pyaggr3g470r/views.py:443 +#: pyaggr3g470r/views.py:460 pyaggr3g470r/views.py:470 msgid "Error when exporting articles." msgstr "Erreur lors de l'export des articles." -#: pyaggr3g470r/views.py:449 +#: pyaggr3g470r/views.py:476 msgid "Export format not supported." msgstr "Ce format d'export n'est pas supporté." -#: pyaggr3g470r/views.py:472 +#: pyaggr3g470r/views.py:499 msgid "Full text search is not yet implemented for Heroku." msgstr "La recherche rapide n'est pas supporté sur Heroku." -#: pyaggr3g470r/views.py:510 +#: pyaggr3g470r/views.py:537 msgid "File not allowed." msgstr "Fichier non autorisé." -#: pyaggr3g470r/views.py:516 +#: pyaggr3g470r/views.py:543 msgid "feeds imported." msgstr "flux importés." -#: pyaggr3g470r/views.py:518 +#: pyaggr3g470r/views.py:545 msgid "Impossible to import the new feeds." msgstr "Impossible d'importer les nouveaux flux." -#: pyaggr3g470r/views.py:554 pyaggr3g470r/views.py:566 -#: pyaggr3g470r/views.py:569 pyaggr3g470r/views.py:592 +#: pyaggr3g470r/views.py:581 pyaggr3g470r/views.py:593 +#: pyaggr3g470r/views.py:596 pyaggr3g470r/views.py:619 #: pyaggr3g470r/templates/admin/user.html:45 msgid "Feed" msgstr "Flux" -#: pyaggr3g470r/views.py:554 pyaggr3g470r/views.py:610 -#: pyaggr3g470r/views.py:668 +#: pyaggr3g470r/views.py:581 pyaggr3g470r/views.py:637 +#: pyaggr3g470r/views.py:695 msgid "successfully updated." msgstr "mis à jour avec succès." -#: pyaggr3g470r/views.py:566 pyaggr3g470r/views.py:679 +#: pyaggr3g470r/views.py:593 pyaggr3g470r/views.py:706 msgid "successfully created." msgstr "créé avec succès." -#: pyaggr3g470r/views.py:569 +#: pyaggr3g470r/views.py:596 msgid "already in the database." msgstr "déjà dans la base de données." -#: pyaggr3g470r/views.py:575 +#: pyaggr3g470r/views.py:602 msgid "Edit the feed" msgstr "Éditez ce flux" -#: pyaggr3g470r/views.py:579 pyaggr3g470r/templates/layout.html:48 +#: pyaggr3g470r/views.py:606 pyaggr3g470r/templates/layout.html:48 msgid "Add a feed" msgstr "Ajouter un flux" -#: pyaggr3g470r/views.py:592 pyaggr3g470r/views.py:719 +#: pyaggr3g470r/views.py:619 pyaggr3g470r/views.py:746 msgid "successfully deleted." msgstr "supprimé avec succès." -#: pyaggr3g470r/views.py:610 pyaggr3g470r/views.py:668 -#: pyaggr3g470r/views.py:679 pyaggr3g470r/views.py:719 +#: pyaggr3g470r/views.py:637 pyaggr3g470r/views.py:695 +#: pyaggr3g470r/views.py:706 pyaggr3g470r/views.py:746 msgid "User" msgstr "Utilisateur" -#: pyaggr3g470r/views.py:629 +#: pyaggr3g470r/views.py:656 msgid "Your account has been deleted." msgstr "Votre compte a été supprimé." -#: pyaggr3g470r/views.py:631 pyaggr3g470r/views.py:705 -#: pyaggr3g470r/views.py:721 +#: pyaggr3g470r/views.py:658 pyaggr3g470r/views.py:732 +#: pyaggr3g470r/views.py:748 msgid "This user does not exist." msgstr "Cet utilisateur n'existe pas." -#: pyaggr3g470r/views.py:688 +#: pyaggr3g470r/views.py:715 msgid "Edit the user" msgstr "Éditer cet utilisateur" -#: pyaggr3g470r/views.py:691 pyaggr3g470r/templates/admin/dashboard.html:35 +#: pyaggr3g470r/views.py:718 pyaggr3g470r/templates/admin/dashboard.html:35 msgid "Add a new user" msgstr "Ajouter un nouvel utilisateur" diff --git a/pyaggr3g470r/views.py b/pyaggr3g470r/views.py index ac89f0b8..dbbaf5d0 100644 --- a/pyaggr3g470r/views.py +++ b/pyaggr3g470r/views.py @@ -34,6 +34,7 @@ from flask.ext.login import LoginManager, login_user, logout_user, login_require from flask.ext.principal import Principal, Identity, AnonymousIdentity, identity_changed, identity_loaded, Permission, RoleNeed, UserNeed from flask.ext.babel import gettext from sqlalchemy import desc +from sqlalchemy.exc import IntegrityError from werkzeug import generate_password_hash import conf @@ -41,7 +42,7 @@ import utils import export if not conf.ON_HEROKU: import search as fastsearch -from forms import SigninForm, AddFeedForm, ProfileForm +from forms import SignupForm, SigninForm, AddFeedForm, ProfileForm from pyaggr3g470r import app, db, allowed_file, babel from pyaggr3g470r.models import User, Feed, Article, Role from pyaggr3g470r.decorators import feed_access_required @@ -163,6 +164,32 @@ def logout(): flash(gettext("Logged out successfully."), 'success') return redirect(url_for('login')) +@app.route('/signup/', methods=['GET', 'POST']) +def signup(): + """ + Signup page. + """ + form = SignupForm() + + if form.validate_on_submit(): + role_user = Role.query.filter(Role.name == "user").first() + user = User(firstname=form.firstname.data, + lastname=form.lastname.data, + email=form.email.data, + pwdhash=generate_password_hash(form.password.data)) + user.roles.extend([role_user]) + db.session.add(user) + try: + db.session.commit() + except IntegrityError: + flash(gettext('Email already used.'), 'warning') + return render_template('signup.html', form=form) + + flash(gettext('Your account has been created. You can now sign.'), 'success') + return redirect(url_for('home')) + + return render_template('signup.html', form=form) + @app.route('/') @login_required def home(): |