aboutsummaryrefslogtreecommitdiff
path: root/pyaggr3g470r
diff options
context:
space:
mode:
Diffstat (limited to 'pyaggr3g470r')
-rw-r--r--pyaggr3g470r/__init__.py4
-rw-r--r--pyaggr3g470r/forms.py17
-rw-r--r--pyaggr3g470r/templates/login.html4
-rw-r--r--pyaggr3g470r/templates/signup.html28
-rw-r--r--pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mobin9296 -> 9531 bytes
-rw-r--r--pyaggr3g470r/translations/fr/LC_MESSAGES/messages.po165
-rw-r--r--pyaggr3g470r/views.py29
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
index 788fca40..b1ecc508 100644
--- a/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo
+++ b/pyaggr3g470r/translations/fr/LC_MESSAGES/messages.mo
Binary files differ
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():
bgstack15