Browse Source

Ajout du support des avatars. Y'a un peu de nettoyage sur le chemin de stockage

master
Dark-Storm 8 months ago
parent
commit
2089a09753
Signed by: Dark-Storm <l.gatin@neuf.fr> GPG Key ID: F61F10FA138E797C

+ 3
- 2
app/forms/account.py View File

@@ -1,7 +1,8 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SubmitField, FileField
from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SubmitField
from wtforms.fields.html5 import DateField
from wtforms.validators import DataRequired, Optional, Email, EqualTo
from flask_wtf.file import FileField # Cuz' wtforms' FileField is shitty
import app.utils.validators as vd

class RegistrationForm(FlaskForm):
@@ -26,6 +27,6 @@ class UpdateAccountForm(FlaskForm):
submit = SubmitField('Mettre à jour')

class DeleteAccountForm(FlaskForm):
delete = BooleanField('Supprimer le compte', validators=[DataRequired()], description='Attention, cette opération est irréversible !')
delete = BooleanField('Confirmer la suppression', validators=[DataRequired()], description='Attention, cette opération est irréversible !')
old_password = PasswordField('Mot de passe', validators=[DataRequired(), vd.old_password])
submit = SubmitField('Supprimer le compte')

+ 6
- 1
app/models/users.py View File

@@ -1,5 +1,5 @@
from datetime import date, datetime
from app import db
from app import app, db
from flask_login import UserMixin
from app.models.contents import Content
from app.models.privs import SpecialPrivilege, Group, GroupMember, \
@@ -89,6 +89,11 @@ class Member(User, db.Model):
innovation = db.Column(db.Integer)
register_date = db.Column(db.Date, default=date.today)

# Avatars # TODO: rendre ça un peu plus propre
@property
def avatar(self):
return 'avatars/' + str(self.id) + '.png'

# Groups and related privileges
groups = db.relationship('Group', secondary=GroupMember,
back_populates='members')

+ 24
- 27
app/routes/account.py View File

@@ -9,45 +9,42 @@ from app.utils.render import render
@login_required
def account():
form = UpdateAccountForm()
del_form = DeleteAccountForm()
if request.method == "POST":
if form.validate_on_submit():
# Updates to do
updates = {}
# Optional updates (do not update if blank)
if form.email.data:
updates['email'] = form.email.data
if form.password.data:
updates['password'] = form.password.data
# Required updates (update if blank)
updates.update({
"signature": form.signature.data,
"bio": form.biography.data,
"birthday": form.birthday.data,
"newsletter": form.newsletter.data
})
# Do the fucking updates
current_user.update(**updates)
if form.avatar.data:
f = form.avatar.data
f.save("./app/static/"+current_user.avatar)
current_user.update(
email = form.email.data or None,
password = form.password.data or None,
birthday = form.birthday.data,
signature = form.signature.data,
biography = form.biography.data,
newsletter = form.newsletter.data
)
db.session.merge(current_user)
db.session.commit()
flash('Modifications effectuées', 'ok')
else:
flash('Erreur lors de la modification', 'error')

return render('account.html', form=form, del_form=del_form)
return render('account.html', form=form)

@app.route('/account/delete', methods=['GET', 'POST'])
def delete_account():
del_form = DeleteAccountForm()
if del_form.validate_on_submit():
db.session.delete(current_user)
logout_user()
db.session.commit()
flash('Compte supprimé', 'ok')
return redirect(url_for('index'))
else:
flash('Erreur lors de la suppression du compte', 'error')
return render('delete_account.html', del_form=del_form)
if request.method == "POST":
if del_form.validate_on_submit():
db.session.delete(current_user)
logout_user()
db.session.commit()
flash('Compte supprimé', 'ok')
return redirect(url_for('index'))
else:
flash('Erreur lors de la suppression du compte', 'error')
del_form.delete.data = False # Force to check the case to delete the account
return render('delete_account.html', del_form=del_form)


@app.route('/register', methods=['GET', 'POST'])
def register():

BIN
app/static/avatars/3.png View File


+ 4
- 1
app/static/css/container.css View File

@@ -3,7 +3,10 @@
}

section {
margin: 10px 5%;
min-width: 350px;
margin: 20px auto 0; padding: 20px;
background: #ffffff;
border: 1px solid #dddddd; border-radius: 5px;
}

section h1 {

+ 1
- 17
app/static/css/form.css View File

@@ -1,10 +1,3 @@
.form {
min-width: 350px;
margin: 20px auto 0; padding: 20px;
background: #ffffff;
border: 1px solid #dddddd; border-radius: 5px;
}

.form .avatar {
display: inline-block; vertical-align: middle;
border-radius: 100%;
@@ -46,16 +39,7 @@
}

.form input[type="submit"] {
width: 100%;
/*background-color: #149641;
border-color: #1e7408;
color: #ffffff;*/
}
.form input[type="submit"]:hover,
.form input[type="submit"]:focus,
.form input[type="submit"]:active {
/*background-color: #0f7331;
border-color: #073617;*/
/*width: 20%;*/
}

.form form .msgerror {

+ 5
- 10
app/static/css/global.css View File

@@ -66,13 +66,12 @@ textarea {
}

/* Buttons */
.button,
input[type="button"],
input[type="submit"] {
padding: 6px 0;
border-radius: 3px;
font-size: 14px;
font-weight: 400;
border: 1px solid transparent;
padding: 6px 10px;
border: 1px solid transparent; border-radius: 3px;
font-family: 'DejaVu Sans', sans-serif; font-size: 14px; font-weight: 400;
}

/* Checkbox */
@@ -93,25 +92,21 @@ input[type="checkbox"] {
.bg-green,
.bg-green {
background-color: #149641;
border-color: #0e692d;
color: #ffffff;
}
.bg-green:hover,
.bg-green:focus,
.bg-green:active {
background-color: #0f7331;
border-color: #073617;
}

.bg-red,
.bg-red {
background-color: #c0341d;
border-color: #a62d19;
color: #ffffff;
}
.bg-red:hover,
.bg-red:focus,
.bg-red:active {
background-color: #7b2112;
border-color: #073617;
background-color: #aa3421;
}

+ 4
- 21
app/templates/account.html View File

@@ -4,14 +4,14 @@
<section class="form" style="width:80%;">
<h1>Gestion du compte</h1>

<form action="{{ url_for('account') }}" method="post">
<form action="{{ url_for('account') }}" method="post" enctype="multipart/form-data">
{{ form.hidden_tag() }}

<h2>Général</h2>
<div>
{{ form.avatar.label }}
<div>
<img class="avatar" src="{{ url_for('static', filename= 'images/3864.png') }}" />
<img class="avatar" src="{{ url_for('static', filename=current_user.avatar) }}" meta="{{ current_user.avatar }}" />
{{ form.avatar }}
</div>
</div>
@@ -80,24 +80,7 @@
</form>

<h2 style="margin-top:30px;">Supprimer le compte</h2>
<form action="{{ url_for('delete_account') }}" method="post">
{{ del_form.hidden_tag() }}
<div>
{{ del_form.delete.label }}
{{ del_form.delete }}
<div style="font-size:80%;color:rgba(0,0,0,.5)">{{ del_form.delete.description }}</div>
{% for error in del_form.delete.errors %}
<span class="msgerror">{{ error }}</span>
{% endfor %}
</div>
<div>
{{ del_form.old_password.label }}
{{ del_form.old_password(placeholder='************') }}
{% for error in del_form.old_password.errors %}
<span class="msgerror">{{ error }}</span>
{% endfor %}
</div>
<div>{{ del_form.submit(class_="bg-red") }}</div>
</form>
<a href="{{ url_for('delete_account') }}" class="button bg-red">Supprimer le compte</a>

</section>
{% endblock %}

+ 1
- 1
app/templates/base/navbar/account.html View File

@@ -1,7 +1,7 @@
{% if current_user.is_authenticated %}
<div>
<h2>
<img src="{{ url_for('static', filename= 'images/3864.png') }}">
<img src="{{ url_for('static', filename=current_user.avatar) }}">
{{ current_user.name }}
</h2>
<a href="#">

+ 2
- 2
app/templates/delete_account.html View File

@@ -2,12 +2,12 @@

{% block content %}
<section class="form" style="width:80%;">
<h1>Supprimer le compte</h2>
<h1>Suppression du compte</h2>
<form action="{{ url_for('delete_account') }}" method="post">
{{ del_form.hidden_tag() }}
<div>
{{ del_form.delete.label }}
{{ del_form.delete }}
{{ del_form.delete(checked=False) }}
<div style="font-size:80%;color:rgba(0,0,0,.5)">{{ del_form.delete.description }}</div>
{% for error in del_form.delete.errors %}
<span class="msgerror">{{ error }}</span>

+ 1
- 0
config.py View File

@@ -5,6 +5,7 @@ class Config(object):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'postgresql+psycopg2://' + os.environ.get('USER') + ':@/pcv5'
SQLALCHEMY_TRACK_MODIFICATIONS = False
UPLOAD_FOLDER = './app/static/avatars'

class V5Config(object):
# Length allocated to privilege names (slugs)

Loading…
Cancel
Save