diff --git a/README.md b/README.md index cee7f2c..1b8781d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # Planète Casio v5 +## Code de conduite + +Don't be an asshole. + ## Style de code -* L'indentation se fait avec des tabulations -* Merci d'essayer de respecter les 80 colonnes max +* On respecte la PEP8. Je sais c'est relou d'indenter avec des espaces, mais au moins le reste est consistant. +* La seule exception concerne la longueur des lignes. Merci d'essayer de respecter les 79 colonnes, mais dans certains cas c'est plus crade de revenir à la ligne, donc blc. +* Je conseille d'utiliser Flake8 qui permet de vérifier les erreurs de syntaxe, de style, etc. en live. diff --git a/app/forms/account.py b/app/forms/account.py index d4abf6b..5abe4ae 100644 --- a/app/forms/account.py +++ b/app/forms/account.py @@ -2,9 +2,10 @@ from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SubmitField, DecimalField 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 +from flask_wtf.file import FileField # Cuz' wtforms' FileField is shitty import app.utils.validators as vd + class RegistrationForm(FlaskForm): username = StringField('Pseudonyme', validators=[DataRequired(), vd.name_valid, vd.name_available]) email = StringField('Adresse Email', validators=[DataRequired(), Email(), vd.email]) @@ -14,6 +15,7 @@ class RegistrationForm(FlaskForm): newsletter = BooleanField('Inscription à la newsletter', description='Un mail par trimestre environ, pour être prévenu des concours, évènements et nouveautés.') submit = SubmitField('S\'enregistrer') + class UpdateAccountForm(FlaskForm): avatar = FileField('Avatar', validators=[Optional(), vd.avatar]) email = StringField('Adresse email', validators=[Optional(), Email(), vd.email, vd.old_password]) @@ -26,6 +28,7 @@ class UpdateAccountForm(FlaskForm): newsletter = BooleanField('Inscription à la newsletter', description='Un mail par trimestre environ, pour être prévenu des concours, évènements et nouveautés.') submit = SubmitField('Mettre à jour') + class DeleteAccountForm(FlaskForm): 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]) @@ -55,6 +58,7 @@ class AdminUpdateAccountForm(FlaskForm): newsletter = BooleanField('Inscription à la newsletter', description='Un mail par trimestre environ, pour être prévenu des concours, évènements et nouveautés.') submit = SubmitField('Mettre à jour') + class AdminDeleteAccountForm(FlaskForm): delete = BooleanField('Confirmer la suppression', validators=[DataRequired()], description='Attention, cette opération est irréversible !') submit = SubmitField('Supprimer le compte') diff --git a/app/forms/login.py b/app/forms/login.py index d8dad8e..7879b32 100644 --- a/app/forms/login.py +++ b/app/forms/login.py @@ -2,6 +2,7 @@ from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, BooleanField, SubmitField from wtforms.validators import DataRequired + class LoginForm(FlaskForm): username = StringField('Identifiant', validators=[DataRequired()]) password = PasswordField('Mot de passe', validators=[DataRequired()]) diff --git a/app/forms/search.py b/app/forms/search.py index 808b387..1eedbf8 100644 --- a/app/forms/search.py +++ b/app/forms/search.py @@ -3,12 +3,13 @@ from wtforms import StringField, SubmitField from wtforms.fields.html5 import DateField from wtforms.validators import DataRequired, Optional + # TODO: compléter le formulaire de recherche avancée class AdvancedSearchForm(FlaskForm): q = StringField('Rechercher :', validators=[DataRequired()]) date = DateField('Date', validators=[Optional()]) submit = SubmitField('Affiner la recherche') + class SearchForm(FlaskForm): q = StringField('Rechercher', validators=[DataRequired()]) - \ No newline at end of file diff --git a/app/models/contents.py b/app/models/contents.py index 83ea859..d5a11f7 100644 --- a/app/models/contents.py +++ b/app/models/contents.py @@ -2,12 +2,13 @@ from datetime import datetime from app import db from app.models.users import * + class Content(db.Model): __tablename__ = 'content' id = db.Column(db.Integer, primary_key=True) type = db.Column(db.String(20)) __mapper_args__ = { - 'polymorphic_identity':__tablename__, + 'polymorphic_identity': __tablename__, 'polymorphic_on': type } # Standalone properties @@ -16,4 +17,4 @@ class Content(db.Model): date_modified = db.Column(db.DateTime, default=datetime.now) # Relationships author_id = db.Column(db.ForeignKey('user.id')) - author = db.relationship("User", back_populates="contents") \ No newline at end of file + author = db.relationship("User", back_populates="contents") diff --git a/app/models/privs.py b/app/models/privs.py index 63a489d..bf2113e 100644 --- a/app/models/privs.py +++ b/app/models/privs.py @@ -10,6 +10,7 @@ from config import V5Config # the "grant-special-privileges" privilege) can grant privileges on a per-user # basis. + # SpecialPrivilege: Privilege manually granted to a user class SpecialPrivilege(db.Model): __tablename__ = 'special_privilege' @@ -25,7 +26,8 @@ class SpecialPrivilege(db.Model): self.priv = priv def __repr__(self): - return f'' + return f'' + # Group: User group, corresponds to a community role and a set of privileges class Group(db.Model): @@ -41,7 +43,7 @@ class Group(db.Model): # Textual description description = db.Column(db.UnicodeText) # List of members (lambda delays evaluation) - members = db.relationship('Member', secondary=lambda:GroupMember, + members = db.relationship('Member', secondary=lambda: GroupMember, back_populates='groups') def __init__(self, name, css, descr): @@ -70,11 +72,13 @@ class Group(db.Model): def __repr__(self): return f'' + # Many-to-many relation for users belonging to groups GroupMember = db.Table('group_member', db.Model.metadata, db.Column('gid', db.Integer, db.ForeignKey('group.id')), db.Column('uid', db.Integer, db.ForeignKey('member.id'))) + # Meny-to-many relationship for privileges granted to groups class GroupPrivilege(db.Model): __tablename__ = 'group_privilege' diff --git a/app/models/users.py b/app/models/users.py index 745518f..eb91af5 100644 --- a/app/models/users.py +++ b/app/models/users.py @@ -1,5 +1,5 @@ -from datetime import date, datetime -from app import app, db +from datetime import date +from app import db from flask_login import UserMixin from app.models.contents import Content from app.models.privs import SpecialPrivilege, Group, GroupMember, \ @@ -7,9 +7,9 @@ from app.models.privs import SpecialPrivilege, Group, GroupMember, \ from config import V5Config import werkzeug.security -import app import re import math +import app # User: Website user that performs actions on the content class User(UserMixin, db.Model): @@ -67,10 +67,11 @@ class User(UserMixin, db.Model): return True + # Guest: Unregistered user with minimal privileges class Guest(User, db.Model): __tablename__ = 'guest' - __mapper_args__ = { 'polymorphic_identity': __tablename__ } + __mapper_args__ = {'polymorphic_identity': __tablename__} # ID of the [User] entry id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) @@ -83,20 +84,21 @@ class Guest(User, db.Model): def __repr__(self): return f'' + # Member: Registered user with full access to the website's services class Member(User, db.Model): __tablename__ = 'member' - __mapper_args__ = { 'polymorphic_identity': __tablename__ } + __mapper_args__ = {'polymorphic_identity': __tablename__} # Id of the [User] entry id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) # Primary attributes (needed for the system to work) - name = db.Column(db.Unicode(32), index=True, unique=True) - email = db.Column(db.Unicode(120), index=True, unique=True) + name = db.Column(db.Unicode(32), index=True, unique=True) + email = db.Column(db.Unicode(120), index=True, unique=True) password_hash = db.Column(db.String(255)) - xp = db.Column(db.Integer) - innovation = db.Column(db.Integer) + xp = db.Column(db.Integer) + innovation = db.Column(db.Integer) register_date = db.Column(db.Date, default=date.today) # Avatars # TODO: rendre ça un peu plus propre @@ -115,9 +117,9 @@ class Member(User, db.Model): back_populates='members') # Personal information, all optional - bio = db.Column(db.UnicodeText) + bio = db.Column(db.UnicodeText) signature = db.Column(db.UnicodeText) - birthday = db.Column(db.Date) + birthday = db.Column(db.Date) # Settings newsletter = db.Column(db.Boolean, default=False) @@ -187,7 +189,7 @@ class Member(User, db.Model): turn out dangerous! """ - data = { key: data[key] for key in data if data[key] is not None } + data = {key: data[key] for key in data if data[key] is not None} if "name" in data: if not User.valid_name(data["name"]): @@ -232,7 +234,7 @@ class Member(User, db.Model): """ self.xp_points = max(self.xp_points + amount, 0) - def add_innovation(self, n): + def add_innovation(self, amount): """ Reward innovation points to a member. If [amount] is negative, the innovation points total will decrease, down to zero. @@ -255,6 +257,7 @@ class Member(User, db.Model): def __repr__(self): return f'' + @app.login.user_loader def load_user(id): return User.query.get(int(id))