From d2386f2b1ddef9c005737397d7db4992f9bf09d4 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 19 Nov 2021 19:07:20 +0100 Subject: [PATCH] Change documentation type --- .gitignore | 4 +- README.md | 7 +- doc/GesMag/db.html | 275 +++++++++++++++++++++++++++ doc/GesMag/index.html | 70 +++++++ doc/GesMag/main.html | 430 ++++++++++++++++++++++++++++++++++++++++++ doc/GesMag/users.html | 357 +++++++++++++++++++++++++++++++++++ doc/README.md | 342 --------------------------------- doc/README.pdf | Bin 66499 -> 0 bytes 8 files changed, 1137 insertions(+), 348 deletions(-) create mode 100644 doc/GesMag/db.html create mode 100644 doc/GesMag/index.html create mode 100644 doc/GesMag/main.html create mode 100644 doc/GesMag/users.html delete mode 100644 doc/README.md delete mode 100644 doc/README.pdf diff --git a/.gitignore b/.gitignore index fe392f0..59c84bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -*.pdf __pycache__/ + +*.pdf *.sqlite3 -!doc/* diff --git a/README.md b/README.md index 0792557..d268425 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,8 @@ A savoir : - [x] Lisibilité du code - [x] Toutes les fonctions sont nommés et typés (j'utilises `Python 3.9.7`) -### Crédit -Pour générer la documentation présente [ici](doc/README.md) vous aurez besoin de [pdoc](https://pdoc3.github.io/pdoc/). +### Crédit pour la documentation +Pour générer la documentation présente [ici](doc/) vous aurez besoin de [pdoc](https://pdoc3.github.io/pdoc/), ainsi pour la générer, vous devez lancez cette commande : ``` -python3 -m pdoc --pdf . 1> doc/README.md +python3 -m pdoc --html --output-dir doc . ``` -J'utilises Chromium pour convertir le fichier Markdown vers un [fichier pdf disponible ici](doc/README.pdf). diff --git a/doc/GesMag/db.html b/doc/GesMag/db.html new file mode 100644 index 0000000..be599be --- /dev/null +++ b/doc/GesMag/db.html @@ -0,0 +1,275 @@ + + + + + + +GesMag.db API documentation + + + + + + + + + + + +
+
+
+

Module GesMag.db

+
+
+
+ +Expand source code + +
import sqlite3
+from sqlite3.dbapi2 import Cursor
+
+class BaseDeDonnees:
+    """Gère la base de donnée."""
+    def __init__(self, urlBaseDeDonnee: str):
+        self.connexion = self.creerConnexion(urlBaseDeDonnee)
+
+    def creerConnexion(self, path: str):
+        """Connexion à une base de donnée SQLite."""
+        if not self.fichierExiste(path): # si l base de donnée n'existe pas
+            open(path, "x") # on la créer
+        try:
+            connnexion = sqlite3.connect(path)
+        except sqlite3.Error as e:
+            print(e) # on affiche l'erreur
+            connnexion = None # et renvoie None
+        return connnexion
+
+    def fichierExiste(self, path: str) -> bool:
+        """Vérifie qu'un fichier existe."""
+        try: # on essaie d'ouvrir le fichier
+            open(path, "r")
+        except FileNotFoundError: # si le fichier n'existe pas
+            return False
+        else: # si le fichier existe
+            return True
+
+    def requete(self, requete: str, valeurs = None):
+        """Envois une requête vers la base de données."""
+        try:
+            curseur = self.connexion.cursor()
+            if valeurs: # s'il y a des valeurs alors on lance la commande `execute` avec ses dernières
+                if type(valeurs) not in [list, tuple]: # si la valeur c'est juste une chaîne de charactère (par exemple), alors la converti en liste
+                    valeurs = [valeurs]
+                curseur.execute(requete, valeurs)
+            else: # sinon on lance juste la requête
+                curseur.execute(requete)
+            self.connexion.commit() # applique les changements à la base de donnée
+            return (curseur, curseur.lastrowid) # renvoie le curseur et l'ID de l'élément modifié
+        except sqlite3.Error as e: # s'il y a eu une erreur SQLite
+            print(e)
+
+    def affichageResultat(self, curseur: Cursor) -> list:
+        """Affiche le résultat d'une requête."""
+        tableau = []
+        if curseur == None: # si le curseur est vide il n'y a rien a affiché (tableau vide)
+            return tableau
+        lignes = curseur[0].fetchall() # sinon on récupère les éléments
+        for ligne in lignes:
+            tableau.append(ligne) # on les ajoute au tableau
+        return tableau # on le renvoie
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class BaseDeDonnees +(urlBaseDeDonnee: str) +
+
+

Gère la base de donnée.

+
+ +Expand source code + +
class BaseDeDonnees:
+    """Gère la base de donnée."""
+    def __init__(self, urlBaseDeDonnee: str):
+        self.connexion = self.creerConnexion(urlBaseDeDonnee)
+
+    def creerConnexion(self, path: str):
+        """Connexion à une base de donnée SQLite."""
+        if not self.fichierExiste(path): # si l base de donnée n'existe pas
+            open(path, "x") # on la créer
+        try:
+            connnexion = sqlite3.connect(path)
+        except sqlite3.Error as e:
+            print(e) # on affiche l'erreur
+            connnexion = None # et renvoie None
+        return connnexion
+
+    def fichierExiste(self, path: str) -> bool:
+        """Vérifie qu'un fichier existe."""
+        try: # on essaie d'ouvrir le fichier
+            open(path, "r")
+        except FileNotFoundError: # si le fichier n'existe pas
+            return False
+        else: # si le fichier existe
+            return True
+
+    def requete(self, requete: str, valeurs = None):
+        """Envois une requête vers la base de données."""
+        try:
+            curseur = self.connexion.cursor()
+            if valeurs: # s'il y a des valeurs alors on lance la commande `execute` avec ses dernières
+                if type(valeurs) not in [list, tuple]: # si la valeur c'est juste une chaîne de charactère (par exemple), alors la converti en liste
+                    valeurs = [valeurs]
+                curseur.execute(requete, valeurs)
+            else: # sinon on lance juste la requête
+                curseur.execute(requete)
+            self.connexion.commit() # applique les changements à la base de donnée
+            return (curseur, curseur.lastrowid) # renvoie le curseur et l'ID de l'élément modifié
+        except sqlite3.Error as e: # s'il y a eu une erreur SQLite
+            print(e)
+
+    def affichageResultat(self, curseur: Cursor) -> list:
+        """Affiche le résultat d'une requête."""
+        tableau = []
+        if curseur == None: # si le curseur est vide il n'y a rien a affiché (tableau vide)
+            return tableau
+        lignes = curseur[0].fetchall() # sinon on récupère les éléments
+        for ligne in lignes:
+            tableau.append(ligne) # on les ajoute au tableau
+        return tableau # on le renvoie
+
+

Methods

+
+
+def affichageResultat(self, curseur: sqlite3.Cursor) ‑> list +
+
+

Affiche le résultat d'une requête.

+
+ +Expand source code + +
def affichageResultat(self, curseur: Cursor) -> list:
+    """Affiche le résultat d'une requête."""
+    tableau = []
+    if curseur == None: # si le curseur est vide il n'y a rien a affiché (tableau vide)
+        return tableau
+    lignes = curseur[0].fetchall() # sinon on récupère les éléments
+    for ligne in lignes:
+        tableau.append(ligne) # on les ajoute au tableau
+    return tableau # on le renvoie
+
+
+
+def creerConnexion(self, path: str) +
+
+

Connexion à une base de donnée SQLite.

+
+ +Expand source code + +
def creerConnexion(self, path: str):
+    """Connexion à une base de donnée SQLite."""
+    if not self.fichierExiste(path): # si l base de donnée n'existe pas
+        open(path, "x") # on la créer
+    try:
+        connnexion = sqlite3.connect(path)
+    except sqlite3.Error as e:
+        print(e) # on affiche l'erreur
+        connnexion = None # et renvoie None
+    return connnexion
+
+
+
+def fichierExiste(self, path: str) ‑> bool +
+
+

Vérifie qu'un fichier existe.

+
+ +Expand source code + +
def fichierExiste(self, path: str) -> bool:
+    """Vérifie qu'un fichier existe."""
+    try: # on essaie d'ouvrir le fichier
+        open(path, "r")
+    except FileNotFoundError: # si le fichier n'existe pas
+        return False
+    else: # si le fichier existe
+        return True
+
+
+
+def requete(self, requete: str, valeurs=None) +
+
+

Envois une requête vers la base de données.

+
+ +Expand source code + +
def requete(self, requete: str, valeurs = None):
+    """Envois une requête vers la base de données."""
+    try:
+        curseur = self.connexion.cursor()
+        if valeurs: # s'il y a des valeurs alors on lance la commande `execute` avec ses dernières
+            if type(valeurs) not in [list, tuple]: # si la valeur c'est juste une chaîne de charactère (par exemple), alors la converti en liste
+                valeurs = [valeurs]
+            curseur.execute(requete, valeurs)
+        else: # sinon on lance juste la requête
+            curseur.execute(requete)
+        self.connexion.commit() # applique les changements à la base de donnée
+        return (curseur, curseur.lastrowid) # renvoie le curseur et l'ID de l'élément modifié
+    except sqlite3.Error as e: # s'il y a eu une erreur SQLite
+        print(e)
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/doc/GesMag/index.html b/doc/GesMag/index.html new file mode 100644 index 0000000..f9207c0 --- /dev/null +++ b/doc/GesMag/index.html @@ -0,0 +1,70 @@ + + + + + + +GesMag API documentation + + + + + + + + + + + +
+ + +
+ + + \ No newline at end of file diff --git a/doc/GesMag/main.html b/doc/GesMag/main.html new file mode 100644 index 0000000..c17eb3d --- /dev/null +++ b/doc/GesMag/main.html @@ -0,0 +1,430 @@ + + + + + + +GesMag.main API documentation + + + + + + + + + + + +
+
+
+

Module GesMag.main

+
+
+
+ +Expand source code + +
import tkinter.messagebox as messagebox
+
+from tkinter import *
+from re import sub
+
+from users import Utilisateurs # import de mon fichier pour gérer la base de donnée
+
+def dimensionsFenetre(fenetre, taille: tuple):
+    """Permet de définir une fenetre centrer sur l'écran"""
+    largeur = fenetre.winfo_screenwidth()
+    hauteur = fenetre.winfo_screenheight()
+
+    x = (largeur // 2) - (taille[0] // 2)
+    y = (hauteur // 2) - (taille[1] // 2)
+
+    fenetre.geometry(f"{taille[0]}x{taille[1]}+{x}+{y}")
+
+class GesMag:
+    """Programme de Gestion d'une caise de magasin."""
+    def demarrer(self) -> None:
+        """Lance le programme GesMag."""
+        print("Lancement de l'interface de gestion d'une caisse d'un magasin...")
+        self.font = ("Comfortaa", 14) # police par défaut
+        Utilisateurs().creationTable() # on créer la base de donnée si elle n'existe pas déjà
+        self.parent = Tk() # on créer notre fenêtre principale
+
+        self._interfaceConnexion() # on créer la variable `self.f` qui est la frame a affiché
+        self.f.grid() # on affiche la frame
+
+        self.parent.mainloop() # on affiche la fenêtre
+
+    def motDePasseCorrect(self, motDPasse: str) -> tuple:
+        """Détermine si un mot de passe suit la politique du programme ou non."""
+        if len(motDPasse) == 0: # si le champs est vide
+            return (False, "Mot de passe incorrect.")
+        if len(motDPasse) < 8: # si le mot de passe est plus petit que 8 caractères
+            return (False, "Un mot de passe doit faire 8 caractères minimum.")
+        """
+        Pour le regex, je réfléchie comme dans la fonction `self.connexion`.
+        J'utilises pas `match` parce que je suis plus à l'aise avec `sub`.
+        """
+        if not sub(r"[A-Z]", '', motDPasse) != motDPasse:
+            return (False, "Un mot de passe doit au moins contenir une lettre majuscule.")
+        if not sub(r"[a-z]", '', motDPasse) != motDPasse:
+            return (False, "Un mot de passe doit au moins contenir une lettre minuscule.")
+        if not sub(r" *?[^\w\s]+", '', motDPasse) != motDPasse:
+            return (False, "Un mot de passe doit au moins contenir un caractère spécial.")
+
+        return (True,) # si aucun des tests précédents n'est valide, alors le mot de passe est valide
+
+    def connexion(self, utilisateur: str, motDePasse: str):
+        """Gère la connexion aux différentes interfaces de l'application."""
+        """
+        Vérification nom d'utilisateur / mot de passe correctement entré
+        -> Pour le nom d'utilisateur on vérifie si le champs n'est pas vide
+           et si il y a bien que des lettres et des chiffres (le regex élimine tout
+           ce qui n'est pas ça, alors si la fonction `sub` renvoie pas exactement
+           la même chaîne de charactère alors c'est qu'il y avait un charactère
+           interdit dans le nom d'utilisateur).
+        -> Pour le mot de passe on demande à la fonction `motDePasseCorrect` pour
+           éviter de faire tout les tests ici.
+        """
+        if len(utilisateur) == 0 or sub(r" *?[^\w\s]+", '', utilisateur) != utilisateur:
+            messagebox.showerror("Erreur", "Utilisateur incorrect.")
+            return
+        mdpOk = self.motDePasseCorrect(motDePasse)
+        if not mdpOk[0]:
+            messagebox.showerror("Erreur", mdpOk[1])
+            return
+
+        # Redirection vers la bonne interface
+        if Utilisateurs().verificationIdentifiants(utilisateur, motDePasse):
+            print("Bienvenue mon pote")
+        else:
+            print(f"Bah nan frérot c'est pas bon, ça c'est la liste des utilisateurs : {Utilisateurs().listUtilisateurs()}")
+
+    def _interfaceConnexion(self):
+        """Affiche la fenêtre de connexion."""
+        # Paramètres de la fenêtre
+        dimensionsFenetre(self.parent, (400, 600))
+        self.parent.title("Fenêtre de connexion")
+
+        # Instanciation de la Frame, on va donc ajouter tout nos widgets à cet Frame
+        self.f = Frame(self.parent)
+
+        # Affichage des labels et boutons
+        tentativeDeConnexion = lambda _ = None: self.connexion(utilisateur.get(), motDpasse.get()) # lambda pour envoyer les informations entrés dans le formulaire
+        ecart = 80 # écart pour avoir un affichage centré
+        Label(self.f).grid(row=0, pady=50) # utilisé pour du padding (meilleur affichage)
+
+        Label(self.f, text="Utilisateur", font=self.font).grid(column=0, row=1, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
+        utilisateur = Entry(self.f, font=self.font, width=18)
+        utilisateur.grid(column=1, row=2, columnspan=2, padx=ecart)
+
+        Label(self.f, text="Mot de passe", font=self.font).grid(column=0, row=3, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
+        motDpasse = Entry(self.f, font=self.font, show='⁎', width=18)
+        motDpasse.grid(column=1, row=4, columnspan=2, padx=ecart)
+        motDpasse.bind("<Return>", tentativeDeConnexion)
+
+        def __afficherMDP(self):
+            """Permet de gérer l'affichage du mot de passe dans le champs sur la page de connexion."""
+            if self.mdpVisible == False: # si mot de passe caché, alors on l'affiche
+                self.mdpVisible = True
+                motDpasse.config(show='')
+                bouttonAffichageMDP.config(font=("Arial", 10, "overstrike"))
+
+            else: # inversement
+                self.mdpVisible = False
+                motDpasse.config(show='⁎')
+                bouttonAffichageMDP.config(font=("Arial", 10))
+
+        bouttonAffichageMDP = Button(self.f, text='👁', command=lambda: __afficherMDP(self))
+        bouttonAffichageMDP.grid(column=2, row=4, columnspan=2)
+        self.mdpVisible = False
+
+        bouton = Button(self.f, text="Se connecter", font=self.font, command=tentativeDeConnexion)
+        bouton.grid(column=0, row=5, columnspan=3, padx=ecart, pady=20)
+        bouton.bind("<Return>", tentativeDeConnexion)
+
+        Button(self.f, text="Quitter", font=self.font, command=quit).grid(column=0, row=6, columnspan=4, pady=20)
+
+if __name__ == "__main__":
+    """"Application "GesMag" pour le module de Programmation d'interfaces (2021-2022)"""
+    print("--  Compte par défaut --\nNom d'utilisateur: admin\nMot de passe: P@ssword\n")
+    GesMag().demarrer()
+
+
+
+
+
+
+
+

Functions

+
+
+def dimensionsFenetre(fenetre, taille: tuple) +
+
+

Permet de définir une fenetre centrer sur l'écran

+
+ +Expand source code + +
def dimensionsFenetre(fenetre, taille: tuple):
+    """Permet de définir une fenetre centrer sur l'écran"""
+    largeur = fenetre.winfo_screenwidth()
+    hauteur = fenetre.winfo_screenheight()
+
+    x = (largeur // 2) - (taille[0] // 2)
+    y = (hauteur // 2) - (taille[1] // 2)
+
+    fenetre.geometry(f"{taille[0]}x{taille[1]}+{x}+{y}")
+
+
+
+
+
+

Classes

+
+
+class GesMag +
+
+

Programme de Gestion d'une caise de magasin.

+
+ +Expand source code + +
class GesMag:
+    """Programme de Gestion d'une caise de magasin."""
+    def demarrer(self) -> None:
+        """Lance le programme GesMag."""
+        print("Lancement de l'interface de gestion d'une caisse d'un magasin...")
+        self.font = ("Comfortaa", 14) # police par défaut
+        Utilisateurs().creationTable() # on créer la base de donnée si elle n'existe pas déjà
+        self.parent = Tk() # on créer notre fenêtre principale
+
+        self._interfaceConnexion() # on créer la variable `self.f` qui est la frame a affiché
+        self.f.grid() # on affiche la frame
+
+        self.parent.mainloop() # on affiche la fenêtre
+
+    def motDePasseCorrect(self, motDPasse: str) -> tuple:
+        """Détermine si un mot de passe suit la politique du programme ou non."""
+        if len(motDPasse) == 0: # si le champs est vide
+            return (False, "Mot de passe incorrect.")
+        if len(motDPasse) < 8: # si le mot de passe est plus petit que 8 caractères
+            return (False, "Un mot de passe doit faire 8 caractères minimum.")
+        """
+        Pour le regex, je réfléchie comme dans la fonction `self.connexion`.
+        J'utilises pas `match` parce que je suis plus à l'aise avec `sub`.
+        """
+        if not sub(r"[A-Z]", '', motDPasse) != motDPasse:
+            return (False, "Un mot de passe doit au moins contenir une lettre majuscule.")
+        if not sub(r"[a-z]", '', motDPasse) != motDPasse:
+            return (False, "Un mot de passe doit au moins contenir une lettre minuscule.")
+        if not sub(r" *?[^\w\s]+", '', motDPasse) != motDPasse:
+            return (False, "Un mot de passe doit au moins contenir un caractère spécial.")
+
+        return (True,) # si aucun des tests précédents n'est valide, alors le mot de passe est valide
+
+    def connexion(self, utilisateur: str, motDePasse: str):
+        """Gère la connexion aux différentes interfaces de l'application."""
+        """
+        Vérification nom d'utilisateur / mot de passe correctement entré
+        -> Pour le nom d'utilisateur on vérifie si le champs n'est pas vide
+           et si il y a bien que des lettres et des chiffres (le regex élimine tout
+           ce qui n'est pas ça, alors si la fonction `sub` renvoie pas exactement
+           la même chaîne de charactère alors c'est qu'il y avait un charactère
+           interdit dans le nom d'utilisateur).
+        -> Pour le mot de passe on demande à la fonction `motDePasseCorrect` pour
+           éviter de faire tout les tests ici.
+        """
+        if len(utilisateur) == 0 or sub(r" *?[^\w\s]+", '', utilisateur) != utilisateur:
+            messagebox.showerror("Erreur", "Utilisateur incorrect.")
+            return
+        mdpOk = self.motDePasseCorrect(motDePasse)
+        if not mdpOk[0]:
+            messagebox.showerror("Erreur", mdpOk[1])
+            return
+
+        # Redirection vers la bonne interface
+        if Utilisateurs().verificationIdentifiants(utilisateur, motDePasse):
+            print("Bienvenue mon pote")
+        else:
+            print(f"Bah nan frérot c'est pas bon, ça c'est la liste des utilisateurs : {Utilisateurs().listUtilisateurs()}")
+
+    def _interfaceConnexion(self):
+        """Affiche la fenêtre de connexion."""
+        # Paramètres de la fenêtre
+        dimensionsFenetre(self.parent, (400, 600))
+        self.parent.title("Fenêtre de connexion")
+
+        # Instanciation de la Frame, on va donc ajouter tout nos widgets à cet Frame
+        self.f = Frame(self.parent)
+
+        # Affichage des labels et boutons
+        tentativeDeConnexion = lambda _ = None: self.connexion(utilisateur.get(), motDpasse.get()) # lambda pour envoyer les informations entrés dans le formulaire
+        ecart = 80 # écart pour avoir un affichage centré
+        Label(self.f).grid(row=0, pady=50) # utilisé pour du padding (meilleur affichage)
+
+        Label(self.f, text="Utilisateur", font=self.font).grid(column=0, row=1, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
+        utilisateur = Entry(self.f, font=self.font, width=18)
+        utilisateur.grid(column=1, row=2, columnspan=2, padx=ecart)
+
+        Label(self.f, text="Mot de passe", font=self.font).grid(column=0, row=3, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
+        motDpasse = Entry(self.f, font=self.font, show='⁎', width=18)
+        motDpasse.grid(column=1, row=4, columnspan=2, padx=ecart)
+        motDpasse.bind("<Return>", tentativeDeConnexion)
+
+        def __afficherMDP(self):
+            """Permet de gérer l'affichage du mot de passe dans le champs sur la page de connexion."""
+            if self.mdpVisible == False: # si mot de passe caché, alors on l'affiche
+                self.mdpVisible = True
+                motDpasse.config(show='')
+                bouttonAffichageMDP.config(font=("Arial", 10, "overstrike"))
+
+            else: # inversement
+                self.mdpVisible = False
+                motDpasse.config(show='⁎')
+                bouttonAffichageMDP.config(font=("Arial", 10))
+
+        bouttonAffichageMDP = Button(self.f, text='👁', command=lambda: __afficherMDP(self))
+        bouttonAffichageMDP.grid(column=2, row=4, columnspan=2)
+        self.mdpVisible = False
+
+        bouton = Button(self.f, text="Se connecter", font=self.font, command=tentativeDeConnexion)
+        bouton.grid(column=0, row=5, columnspan=3, padx=ecart, pady=20)
+        bouton.bind("<Return>", tentativeDeConnexion)
+
+        Button(self.f, text="Quitter", font=self.font, command=quit).grid(column=0, row=6, columnspan=4, pady=20)
+
+

Methods

+
+
+def connexion(self, utilisateur: str, motDePasse: str) +
+
+

Gère la connexion aux différentes interfaces de l'application.

+
+ +Expand source code + +
def connexion(self, utilisateur: str, motDePasse: str):
+    """Gère la connexion aux différentes interfaces de l'application."""
+    """
+    Vérification nom d'utilisateur / mot de passe correctement entré
+    -> Pour le nom d'utilisateur on vérifie si le champs n'est pas vide
+       et si il y a bien que des lettres et des chiffres (le regex élimine tout
+       ce qui n'est pas ça, alors si la fonction `sub` renvoie pas exactement
+       la même chaîne de charactère alors c'est qu'il y avait un charactère
+       interdit dans le nom d'utilisateur).
+    -> Pour le mot de passe on demande à la fonction `motDePasseCorrect` pour
+       éviter de faire tout les tests ici.
+    """
+    if len(utilisateur) == 0 or sub(r" *?[^\w\s]+", '', utilisateur) != utilisateur:
+        messagebox.showerror("Erreur", "Utilisateur incorrect.")
+        return
+    mdpOk = self.motDePasseCorrect(motDePasse)
+    if not mdpOk[0]:
+        messagebox.showerror("Erreur", mdpOk[1])
+        return
+
+    # Redirection vers la bonne interface
+    if Utilisateurs().verificationIdentifiants(utilisateur, motDePasse):
+        print("Bienvenue mon pote")
+    else:
+        print(f"Bah nan frérot c'est pas bon, ça c'est la liste des utilisateurs : {Utilisateurs().listUtilisateurs()}")
+
+
+
+def demarrer(self) ‑> None +
+
+

Lance le programme GesMag.

+
+ +Expand source code + +
def demarrer(self) -> None:
+    """Lance le programme GesMag."""
+    print("Lancement de l'interface de gestion d'une caisse d'un magasin...")
+    self.font = ("Comfortaa", 14) # police par défaut
+    Utilisateurs().creationTable() # on créer la base de donnée si elle n'existe pas déjà
+    self.parent = Tk() # on créer notre fenêtre principale
+
+    self._interfaceConnexion() # on créer la variable `self.f` qui est la frame a affiché
+    self.f.grid() # on affiche la frame
+
+    self.parent.mainloop() # on affiche la fenêtre
+
+
+
+def motDePasseCorrect(self, motDPasse: str) ‑> tuple +
+
+

Détermine si un mot de passe suit la politique du programme ou non.

+
+ +Expand source code + +
def motDePasseCorrect(self, motDPasse: str) -> tuple:
+    """Détermine si un mot de passe suit la politique du programme ou non."""
+    if len(motDPasse) == 0: # si le champs est vide
+        return (False, "Mot de passe incorrect.")
+    if len(motDPasse) < 8: # si le mot de passe est plus petit que 8 caractères
+        return (False, "Un mot de passe doit faire 8 caractères minimum.")
+    """
+    Pour le regex, je réfléchie comme dans la fonction `self.connexion`.
+    J'utilises pas `match` parce que je suis plus à l'aise avec `sub`.
+    """
+    if not sub(r"[A-Z]", '', motDPasse) != motDPasse:
+        return (False, "Un mot de passe doit au moins contenir une lettre majuscule.")
+    if not sub(r"[a-z]", '', motDPasse) != motDPasse:
+        return (False, "Un mot de passe doit au moins contenir une lettre minuscule.")
+    if not sub(r" *?[^\w\s]+", '', motDPasse) != motDPasse:
+        return (False, "Un mot de passe doit au moins contenir un caractère spécial.")
+
+    return (True,) # si aucun des tests précédents n'est valide, alors le mot de passe est valide
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/doc/GesMag/users.html b/doc/GesMag/users.html new file mode 100644 index 0000000..bd6cb66 --- /dev/null +++ b/doc/GesMag/users.html @@ -0,0 +1,357 @@ + + + + + + +GesMag.users API documentation + + + + + + + + + + + +
+
+
+

Module GesMag.users

+
+
+
+ +Expand source code + +
from db import BaseDeDonnees
+
+class Utilisateurs(BaseDeDonnees):
+    """Gère une table "utilisateurs" pour une base de donnée donné."""
+    def __init__(self):
+        super().__init__(r"utilisateurs.sqlite3")
+
+    def creationTable(self) -> None:
+        """Créer la table qui stocker les utilisateurs."""
+        requete = """
+                  CREATE TABLE IF NOT EXISTS utilisateurs (
+                      id INTEGER PRIMARY KEY,
+                      pseudo TEXT,
+                      passe TEXT,
+                      metier INTEGER,
+                      nom TEXT,
+                      prenom TEXT,
+                      naissance TEXT,
+                      adresse TEXT,
+                      postal INTEGER
+                  );
+                  """
+        self.requete(requete)
+        # Ajout d'un utilisateur par défaut si aucun utilisateur n'existe dans la base de donnée
+        if len(self.listUtilisateurs()) == 0:
+            self.ajoutUtilisateurs(
+                pseudo="admin",
+                passe="P@ssword",
+                metier=0,
+                nom="Admin",
+                prenom="Admin",
+                naissance="2000/10/09",
+                adresse="12 Rue de Montmartre",
+                postal=46800
+            )
+
+    def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) -> list:
+        """Ajoute un utilisateur et retourne l'ID de ce dernier."""
+        requete = """
+                  INSERT INTO utilisateurs (
+                      pseudo, passe, metier, nom, prenom, naissance, adresse, postal
+                  ) VALUES (
+                      ?, ?, ?, ?, ?, ?, ?, ?
+                  );
+                  """
+        self.requete(requete, [pseudo, passe, metier, nom, prenom, naissance, adresse, postal])
+        return self.affichageResultat(self.requete("SELECT last_insert_rowid();"))
+
+    def suppressionUtilisateurs(self, pseudo: str) -> None:
+        """Supprime un utilisateur."""
+        requete = """
+                  DELETE FROM utilisateurs
+                  WHERE pseudo = ?
+                  """
+        self.requete(requete, pseudo)
+
+    def verificationIdentifiants(self, pseudo: str, motDePasse: str) -> bool:
+        """Renvoie vrai ou faux si les identifiants données sont bons."""
+        requete = """
+                  SELECT EXISTS (
+                      SELECT 1 FROM utilisateurs
+                      WHERE pseudo = ? AND passe = ?
+                  )
+                  """
+        # Vrai si le premier élément que renvoie la requête au dessus est 1
+        return True if self.affichageResultat(self.requete(requete, [pseudo, motDePasse]))[0][0] == 1 else False
+
+    def listUtilisateurs(self) -> list:
+        """Retourne la liste des nom d'utilisateurs."""
+        requete = """
+                  SELECT pseudo FROM utilisateurs
+                  """
+        # i[0] parce que sinon ça renvoie des Tuple qui ressemble à ça : `(Utilisateur,)`
+        return [i[0] for i in self.affichageResultat(self.requete(requete))]
+
+
+
+
+
+
+
+
+
+

Classes

+
+
+class Utilisateurs +
+
+

Gère une table "utilisateurs" pour une base de donnée donné.

+
+ +Expand source code + +
class Utilisateurs(BaseDeDonnees):
+    """Gère une table "utilisateurs" pour une base de donnée donné."""
+    def __init__(self):
+        super().__init__(r"utilisateurs.sqlite3")
+
+    def creationTable(self) -> None:
+        """Créer la table qui stocker les utilisateurs."""
+        requete = """
+                  CREATE TABLE IF NOT EXISTS utilisateurs (
+                      id INTEGER PRIMARY KEY,
+                      pseudo TEXT,
+                      passe TEXT,
+                      metier INTEGER,
+                      nom TEXT,
+                      prenom TEXT,
+                      naissance TEXT,
+                      adresse TEXT,
+                      postal INTEGER
+                  );
+                  """
+        self.requete(requete)
+        # Ajout d'un utilisateur par défaut si aucun utilisateur n'existe dans la base de donnée
+        if len(self.listUtilisateurs()) == 0:
+            self.ajoutUtilisateurs(
+                pseudo="admin",
+                passe="P@ssword",
+                metier=0,
+                nom="Admin",
+                prenom="Admin",
+                naissance="2000/10/09",
+                adresse="12 Rue de Montmartre",
+                postal=46800
+            )
+
+    def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) -> list:
+        """Ajoute un utilisateur et retourne l'ID de ce dernier."""
+        requete = """
+                  INSERT INTO utilisateurs (
+                      pseudo, passe, metier, nom, prenom, naissance, adresse, postal
+                  ) VALUES (
+                      ?, ?, ?, ?, ?, ?, ?, ?
+                  );
+                  """
+        self.requete(requete, [pseudo, passe, metier, nom, prenom, naissance, adresse, postal])
+        return self.affichageResultat(self.requete("SELECT last_insert_rowid();"))
+
+    def suppressionUtilisateurs(self, pseudo: str) -> None:
+        """Supprime un utilisateur."""
+        requete = """
+                  DELETE FROM utilisateurs
+                  WHERE pseudo = ?
+                  """
+        self.requete(requete, pseudo)
+
+    def verificationIdentifiants(self, pseudo: str, motDePasse: str) -> bool:
+        """Renvoie vrai ou faux si les identifiants données sont bons."""
+        requete = """
+                  SELECT EXISTS (
+                      SELECT 1 FROM utilisateurs
+                      WHERE pseudo = ? AND passe = ?
+                  )
+                  """
+        # Vrai si le premier élément que renvoie la requête au dessus est 1
+        return True if self.affichageResultat(self.requete(requete, [pseudo, motDePasse]))[0][0] == 1 else False
+
+    def listUtilisateurs(self) -> list:
+        """Retourne la liste des nom d'utilisateurs."""
+        requete = """
+                  SELECT pseudo FROM utilisateurs
+                  """
+        # i[0] parce que sinon ça renvoie des Tuple qui ressemble à ça : `(Utilisateur,)`
+        return [i[0] for i in self.affichageResultat(self.requete(requete))]
+
+

Ancestors

+
    +
  • db.BaseDeDonnees
  • +
+

Methods

+
+
+def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) ‑> list +
+
+

Ajoute un utilisateur et retourne l'ID de ce dernier.

+
+ +Expand source code + +
def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) -> list:
+    """Ajoute un utilisateur et retourne l'ID de ce dernier."""
+    requete = """
+              INSERT INTO utilisateurs (
+                  pseudo, passe, metier, nom, prenom, naissance, adresse, postal
+              ) VALUES (
+                  ?, ?, ?, ?, ?, ?, ?, ?
+              );
+              """
+    self.requete(requete, [pseudo, passe, metier, nom, prenom, naissance, adresse, postal])
+    return self.affichageResultat(self.requete("SELECT last_insert_rowid();"))
+
+
+
+def creationTable(self) ‑> None +
+
+

Créer la table qui stocker les utilisateurs.

+
+ +Expand source code + +
def creationTable(self) -> None:
+    """Créer la table qui stocker les utilisateurs."""
+    requete = """
+              CREATE TABLE IF NOT EXISTS utilisateurs (
+                  id INTEGER PRIMARY KEY,
+                  pseudo TEXT,
+                  passe TEXT,
+                  metier INTEGER,
+                  nom TEXT,
+                  prenom TEXT,
+                  naissance TEXT,
+                  adresse TEXT,
+                  postal INTEGER
+              );
+              """
+    self.requete(requete)
+    # Ajout d'un utilisateur par défaut si aucun utilisateur n'existe dans la base de donnée
+    if len(self.listUtilisateurs()) == 0:
+        self.ajoutUtilisateurs(
+            pseudo="admin",
+            passe="P@ssword",
+            metier=0,
+            nom="Admin",
+            prenom="Admin",
+            naissance="2000/10/09",
+            adresse="12 Rue de Montmartre",
+            postal=46800
+        )
+
+
+
+def listUtilisateurs(self) ‑> list +
+
+

Retourne la liste des nom d'utilisateurs.

+
+ +Expand source code + +
def listUtilisateurs(self) -> list:
+    """Retourne la liste des nom d'utilisateurs."""
+    requete = """
+              SELECT pseudo FROM utilisateurs
+              """
+    # i[0] parce que sinon ça renvoie des Tuple qui ressemble à ça : `(Utilisateur,)`
+    return [i[0] for i in self.affichageResultat(self.requete(requete))]
+
+
+
+def suppressionUtilisateurs(self, pseudo: str) ‑> None +
+
+

Supprime un utilisateur.

+
+ +Expand source code + +
def suppressionUtilisateurs(self, pseudo: str) -> None:
+    """Supprime un utilisateur."""
+    requete = """
+              DELETE FROM utilisateurs
+              WHERE pseudo = ?
+              """
+    self.requete(requete, pseudo)
+
+
+
+def verificationIdentifiants(self, pseudo: str, motDePasse: str) ‑> bool +
+
+

Renvoie vrai ou faux si les identifiants données sont bons.

+
+ +Expand source code + +
def verificationIdentifiants(self, pseudo: str, motDePasse: str) -> bool:
+    """Renvoie vrai ou faux si les identifiants données sont bons."""
+    requete = """
+              SELECT EXISTS (
+                  SELECT 1 FROM utilisateurs
+                  WHERE pseudo = ? AND passe = ?
+              )
+              """
+    # Vrai si le premier élément que renvoie la requête au dessus est 1
+    return True if self.affichageResultat(self.requete(requete, [pseudo, motDePasse]))[0][0] == 1 else False
+
+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index e6a2f4b..0000000 --- a/doc/README.md +++ /dev/null @@ -1,342 +0,0 @@ ---- -description: | - API documentation for modules: GesMag, GesMag.db, GesMag.main, GesMag.users. - -lang: en - -classoption: oneside -geometry: margin=1in -papersize: a4 - -linkcolor: blue -links-as-notes: true -... - - - -# Namespace `GesMag` {#id} - - - - - -## Sub-modules - -* [GesMag.db](#GesMag.db) -* [GesMag.main](#GesMag.main) -* [GesMag.users](#GesMag.users) - - - - - - - -# Module `GesMag.db` {#id} - - - - - - - - -## Classes - - - -### Class `BaseDeDonnees` {#id} - - - - -> class BaseDeDonnees( -> urlBaseDeDonnee: str -> ) - - -Gère la base de donnée. - - - - - - - - -#### Methods - - - -##### Method `affichageResultat` {#id} - - - - -> def affichageResultat( -> self, -> curseur: sqlite3.Cursor -> ) ‑> list - - -Affiche le résultat d'une requête. - - -##### Method `creerConnexion` {#id} - - - - -> def creerConnexion( -> self, -> path: str -> ) - - -Connexion à une base de donnée SQLite. - - -##### Method `fichierExiste` {#id} - - - - -> def fichierExiste( -> self, -> path: str -> ) ‑> bool - - -Vérifie qu'un fichier existe. - - -##### Method `requete` {#id} - - - - -> def requete( -> self, -> requete: str, -> valeurs=None -> ) - - -Envois une requête vers la base de données. - - - - -# Module `GesMag.main` {#id} - - - - - - - -## Functions - - - -### Function `dimensionsFenetre` {#id} - - - - -> def dimensionsFenetre( -> fenetre, -> taille: tuple -> ) - - -Permet de définir une fenetre centrer sur l'écran - - - -## Classes - - - -### Class `GesMag` {#id} - - - - -> class GesMag - - -Programme de Gestion d'une caise de magasin. - - - - - - - - -#### Methods - - - -##### Method `connexion` {#id} - - - - -> def connexion( -> self, -> utilisateur: str, -> motDePasse: str -> ) - - -Gère la connexion aux différentes interfaces de l'application. - - -##### Method `demarrer` {#id} - - - - -> def demarrer( -> self -> ) ‑> None - - -Lance le programme GesMag. - - -##### Method `motDePasseCorrect` {#id} - - - - -> def motDePasseCorrect( -> self, -> motDPasse: str -> ) ‑> tuple - - -Détermine si un mot de passe suit la politique du programme ou non. - - - - -# Module `GesMag.users` {#id} - - - - - - - - -## Classes - - - -### Class `Utilisateurs` {#id} - - - - -> class Utilisateurs - - -Gère une table "utilisateurs" pour une base de donnée donné. - - - -#### Ancestors (in MRO) - -* [db.BaseDeDonnees](#db.BaseDeDonnees) - - - - - - - -#### Methods - - - -##### Method `ajoutUtilisateurs` {#id} - - - - -> def ajoutUtilisateurs( -> self, -> pseudo: str, -> passe: str, -> metier: int, -> nom: str, -> prenom: str, -> naissance: str, -> adresse: str, -> postal: str -> ) ‑> list - - -Ajoute un utilisateur et retourne l'ID de ce dernier. - - -##### Method `creationTable` {#id} - - - - -> def creationTable( -> self -> ) ‑> None - - -Créer la table qui stocker les utilisateurs. - - -##### Method `listUtilisateurs` {#id} - - - - -> def listUtilisateurs( -> self -> ) ‑> list - - -Retourne la liste des nom d'utilisateurs. - - -##### Method `suppressionUtilisateurs` {#id} - - - - -> def suppressionUtilisateurs( -> self, -> pseudo: str -> ) ‑> None - - -Supprime un utilisateur. - - -##### Method `verificationIdentifiants` {#id} - - - - -> def verificationIdentifiants( -> self, -> pseudo: str, -> motDePasse: str -> ) ‑> bool - - -Renvoie vrai ou faux si les identifiants données sont bons. - - ------ -Generated by *pdoc* 0.10.0 (). diff --git a/doc/README.pdf b/doc/README.pdf deleted file mode 100644 index 709758a678790d0a79a6e4f1983fddacf738cb26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66499 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