Skip to content

Commit

Permalink
first commiit
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdelaziz-pixel committed Mar 10, 2020
0 parents commit e0ef461
Show file tree
Hide file tree
Showing 1,665 changed files with 151,710 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .idea/Projet-CarnetDeNotes.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/dataSources.local.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/dataSources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/rSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

151 changes: 151 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
web: gunicorn app:app
init: FLASK_APP=run.py flask init_db
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Application de carnet de notes ou de pensées avec Flask

Il s'agit d'une application développée dans le cadre de mon poste de formateur en développement web. L'objectif est que les apprenants produisent une application à l'aide du framework Python Flask et se familiarisent ainsi avec ses fonctionnalités principales. L'application en question est très simple, il s'agit d'un carnet de notes où ils peuvent écrire ce qu'ils pensent sous forme de post-it.

Au travers de cet exercice, les étudiants apprennent à :
- Démarrer une application Flask
- Organiser une application Flask
- Gérer le routing d'une application
- Importer et utiliser Sqlalchemy en réalisant un CRUD basique
- Gérer un modèle en orienté objet
- Comprendre le protocole HTTP
- Renvoyer un template sous forme de réponse
- Utiliser le moteur de template Jinja2
- Gérer des utilisateurs à l'aide de flask-login

## Consignes

Vous venez d'arriver en tant que stagiaire dans une start-up spécialisée dans la production d'applications open-source python et votre maître de stage vous a assigné une première application à produire. Comme vous êtes jeune stagiaire, on ne vous a pas intégré tout de suite sur un projet client. Afin de vous laisser le temps de prendre vos marques, on vous a assigné un side-project demandé depuis longtemps par le service ressources humaines. Comme vous le savez dans l'entreprise nouvelle le bonheur des salariés est très important, il faut être heureux d'aller au travail et s'y sentir bien afin de pouvoir s'y épanouir et développer l'ensemble de ses potentialités. Le tout bien-sûr dans une démarche RSE et éco-responsable cela va de soi !

Le service ressources humaines vous a donc demandé de produire une application à destination des employés qui leur permettra d'écrire, chacun de manière privée, leurs pensées du jour peu importe leur contenu. Ainsi grâce à cette nouvelle possibilité d'expression, il pourront écrire ce qui leur pèse sur le coeur et seront plus à même de communiquer et donc de travailler avec leurs collègues. Les RH voudraient une applications visuellement moderne, légère où le design ne prend pas le pas sur l'utilisateur mais qui possède quand même une âme marquée, comme ancrée dans l'imaginaire collectif... A lueur de ces explications, comme vous n'êtes pas bon en design vous utiliserez donc Bootstrap 4 pour le front-end de l'application.

Spécifications fonctionnelles:
- La page d'accueil affiche un formulaire de login pour l'utilisateur. On considère que les utilisateurs sont rentrés en base de données manuellement
- L'utilisateur ne peut accéder à son espace d'écriture que si le pseudo indiqué et le mot de passe correspondent à ceux en base de données
- La page d'accueil de l'espace personnel affichent les pensées déjà enregistrées par l'utilisateur et uniquement ses pensées personnelles
- L'utilisateur peut accéder à un espace d'administration d'où il peut supprimer une pensée ou modifier le contenu d'une pensée
- L'utilisateur peut se déconnecter à tout moment de l'application, il est alors renvoyé sur la page de login
- Un utilisateur non connecté ne peut pas accéder à autre chose que la page de login
- L'application est utilisable sur tous types d'appareils (smartphones, tablettes, ordinateurs...)

Spécifications techniques:
- Python3
- Framework Flask 1.0 ou supérieur
- SGBD: Sqlalchemy
- Gestion des formulaires: Wtforms
- Moteur de template : Jinja2
- Gestion des connexions : Flask-login
- Template organisé avec triple héritage
- Framework CSS Bootstrap 4

## Pour aller plus loin

Si vous souhaitez en apprendre plus sur le framework Flask et les librairie qu'on y utilise le plus fréquemment, pourquoi ne pas essayer d'ajouter les fonctionnalités suivantes :
- Permettre aux utilisateurs de se créer eux-même un compte à l'aide d'un formulaire
- Effectuer des vérifications sur les formulaires concernant le niveau de sécurité du mot de passe, la disponibilité du pseudo que l'utilisateur souhaite enregistrer (un pseudo ne peut être utilisé qu'une fois)
- Afficher des messages flash à l'utilisateur selon le succès ou l'échec de ses actions (connexion, création d'une note, enregistrement etc...)
- Essayez de donner une mise en forme sympathique à votre application, vous verrez cela sera utile plus tard
Binary file added __pycache__/config.cpython-36.pyc
Binary file not shown.
Binary file added app.db
Binary file not shown.
32 changes: 32 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import os
from datetime import timedelta

from flask import Flask, session
from flask_login import LoginManager

from .views import app
from . import models

models.db.init_app(app)

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.refresh_view = 'login'
login_manager.refresh_message = (u"Votre session a expiré")
login_manager.refresh_message_category = "warning"


@app.before_request
def before_request():
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=30)


@app.cli.command("init_db")
def init_db():
models.init_db()

@login_manager.user_loader
def load_user(id):
return models.User.query.get(int(id))
Binary file added app/__pycache__/__init__.cpython-36.pyc
Binary file not shown.
Binary file added app/__pycache__/__init__.cpython-37.pyc
Binary file not shown.
Binary file added app/__pycache__/forms.cpython-36.pyc
Binary file not shown.
Binary file added app/__pycache__/forms.cpython-37.pyc
Binary file not shown.
Binary file added app/__pycache__/models.cpython-36.pyc
Binary file not shown.
Binary file added app/__pycache__/models.cpython-37.pyc
Binary file not shown.
Binary file added app/__pycache__/views.cpython-36.pyc
Binary file not shown.
Binary file added app/__pycache__/views.cpython-37.pyc
Binary file not shown.
54 changes: 54 additions & 0 deletions app/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Module to hold the different forms for the application"""
"""Module pour contenir les différents formulaires de candidature"""

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField, TextField
from wtforms.validators import DataRequired, EqualTo, ValidationError, Regexp

from .models import User

# Note that each form corresponds to an entities from the model
# Notez que chaque formulaire correspond à une entité du modèle
# Form fields are defiened by class attributs holding object of the correspnding type field
# Les champs de formulaire sont définis par des attributs de classe contenant un objet du champ de type correspondant

class NewThoughtForm(FlaskForm):
"""Class to generate a form to add a thought to the database"""
"""Classe pour générer un formulaire pour ajouter une pensée à la base de données"""
content = StringField('Citation', validators=[DataRequired()])
submit = SubmitField('Enregistrer')

class LoginForm(FlaskForm):
"""Class to generate a form for the login"""
"""Classe pour générer un formulaire pour la connexion"""
pseudo = StringField('Pseudo', validators=[DataRequired()])
password = PasswordField('Mot de passe', validators=[DataRequired()])
submit = SubmitField('Se connecter')

class RegisterForm(FlaskForm):
"""Class to generate a form for the user to register on the site"""
"""Classe pour générer un formulaire d'inscription de l'utilisateur sur le site"""
last_name = StringField('Nom', validators=[DataRequired()])
first_name = StringField('Prénom', validators=[DataRequired()])
pseudo = StringField('Pseudo', validators=[DataRequired()])
description = TextField('Description personnelle')
password = PasswordField('Mot de passe', validators=[
DataRequired(),
Regexp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,}$", message="Attention le mot de passe doit contenir 6 caractères, une minuscule, une majuscule et un chiffre")
])
password_confirm = PasswordField('Confirmez le mot de passe', validators=[
DataRequired(),
EqualTo('password', "Les deux mot de passes doivent être identiques")
])
submit = SubmitField("S'inscrire")

# NOTE: this a special validation system from wtfform
# REMARQUE: ceci est un système de validation spécial de wtfform
# each method of a form starting with validate_ + the field name is called when submitting the form
# chaque méthode d'un formulaire commençant par validate_ + le nom du champ est appelée lors de la soumission du formulaire
def validate_pseudo(self, pseudo):
"""Function that checks that the pseudo is not already used in database"""
"""Fonction qui vérifie que le pseudo n'est pas déjà utilisé dans la base de données"""
user = User.query.filter_by(pseudo=pseudo.data).first()
if user is not None:
raise ValidationError('Ce pseudo est déjà pris :(')
Loading

0 comments on commit e0ef461

Please sign in to comment.