# -*- coding: utf-8 -*-
import os
import sqlite3
import hashlib
import uuid
import socket
from datetime import datetime, timedelta
import tkinter as tk
from tkinter import ttk, messagebox
from fpdf import FPDF
# =====================================================
# CONFIGURATION
# =====================================================
APP_NAME = "Gestion Scolaire"
SECRET = "LICENCE-GESTION-SCOLAIRE-2026"
PC_MAX = 3
LICENCE_JOURS = 365
BASE_DIR = [Link]([Link](__file__))
DB_PATH = [Link](BASE_DIR, "[Link]")
# =====================================================
# BASE DE DONNEES
# =====================================================
def connect_db():
conn = [Link](DB_PATH)
return conn, [Link]()
def init_db():
conn, cursor = connect_db()
# Tables
[Link]("""CREATE TABLE IF NOT EXISTS licence (
id INTEGER PRIMARY KEY, cle TEXT, nb_pc_max INTEGER, date_activation TEXT,
date_expiration TEXT, derniere_utilisation TEXT, active INTEGER)""")
[Link]("""CREATE TABLE IF NOT EXISTS licence_pc (
id INTEGER PRIMARY KEY AUTOINCREMENT, pc_id TEXT UNIQUE)""")
[Link]("""CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE, password TEXT, role
TEXT)""")
[Link]("""CREATE TABLE IF NOT EXISTS classes (
id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT UNIQUE)""")
[Link]("""CREATE TABLE IF NOT EXISTS eleves (
id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT, prenom TEXT, matricule TEXT UNIQUE,
sexe TEXT, date_naissance TEXT, parent TEXT, telephone TEXT, adresse TEXT,
classe_id INTEGER, FOREIGN KEY(classe_id) REFERENCES classes(id))""")
[Link]("""CREATE TABLE IF NOT EXISTS enseignants (
id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT, prenom TEXT, classe_id INTEGER,
FOREIGN KEY(classe_id) REFERENCES classes(id))""")
[Link]("""CREATE TABLE IF NOT EXISTS matieres (
id INTEGER PRIMARY KEY AUTOINCREMENT, nom TEXT, min_annee INTEGER, max_annee
INTEGER)""")
[Link]("""CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY AUTOINCREMENT, eleve_id INTEGER, matiere_id INTEGER,
periode INTEGER, note REAL,
FOREIGN KEY(eleve_id) REFERENCES eleves(id),
FOREIGN KEY(matiere_id) REFERENCES matieres(id))""")
[Link]("""CREATE TABLE IF NOT EXISTS absences (
id INTEGER PRIMARY KEY AUTOINCREMENT, eleve_id INTEGER, matiere_id INTEGER,
date_absence TEXT, justifiee INTEGER,
FOREIGN KEY(eleve_id) REFERENCES eleves(id),
FOREIGN KEY(matiere_id) REFERENCES matieres(id))""")
# Admin par défaut
[Link]("SELECT * FROM users WHERE username='admin'")
if not [Link]():
pwd = hashlib.sha256("admin123".encode()).hexdigest()
[Link]("INSERT INTO users (username,password,role) VALUES (?,?,?)",
("admin", pwd, "admin"))
# Classes
classes_list = ["1ère année","2ème année","3ème année","4ème année","5ème année",
"6ème année","7ème année","8ème année","9ème année"]
for c in classes_list:
[Link]("SELECT * FROM classes WHERE nom=?",(c,))
if not [Link]():
[Link]("INSERT INTO classes (nom) VALUES (?)",(c,))
# Matières
matieres_1_6 = ["Math","Français","Physique","Chimie","Histoire","Géographie","SVT","Anglais"]
matieres_7_9 =
["Math","Français","Physique","Chimie","Histoire","Géographie","SVT","Anglais","Informatique"]
for m in matieres_1_6:
[Link]("SELECT * FROM matieres WHERE nom=? AND min_annee=1",(m,))
if not [Link]():
[Link]("INSERT INTO matieres (nom,min_annee,max_annee) VALUES (?,?,?)",(m,1,6))
for m in matieres_7_9:
[Link]("SELECT * FROM matieres WHERE nom=? AND min_annee=7",(m,))
if not [Link]():
[Link]("INSERT INTO matieres (nom,min_annee,max_annee) VALUES (?,?,?)",(m,7,9))
[Link]()
[Link]()
# =====================================================
# LICENCE
# =====================================================
def get_pc_id():
raw = f"{[Link]()}-{[Link]()}"
return hashlib.sha256([Link]()).hexdigest()
def generer_licence():
data = f"{PC_MAX}|{LICENCE_JOURS}|{SECRET}"
return hashlib.sha256([Link]()).hexdigest().upper()
def licence_valide():
pc_id = get_pc_id()
now = [Link]()
conn, cursor = connect_db()
[Link]("SELECT nb_pc_max,date_expiration,derniere_utilisation,active FROM licence LIMIT
1")
row = [Link]()
if not row:
[Link]()
return False
pc_max,date_exp,last_use,active = row
if active != 1:
[Link]()
return False
date_exp = [Link](date_exp,"%Y-%m-%d")
last_use = [Link](last_use,"%Y-%m-%d")
if now < last_use or now > date_exp:
[Link]()
return False
[Link]("SELECT pc_id FROM licence_pc WHERE pc_id=?",(pc_id,))
exists = [Link]()
if not exists:
[Link]("SELECT COUNT(*) FROM licence_pc")
total = [Link]()[0]
if total >= pc_max:
[Link]()
return False
[Link]("INSERT INTO licence_pc (pc_id) VALUES (?)",(pc_id,))
[Link]()
[Link]("UPDATE licence SET derniere_utilisation=?",([Link]("%Y-%m-%d"),))
[Link]()
[Link]()
return True
# =====================================================
# HASH MOT DE PASSE
# =====================================================
def hash_password(password):
return hashlib.sha256([Link]()).hexdigest()
def verifier_login(username,password):
conn,cursor = connect_db()
[Link]("SELECT role FROM users WHERE username=? AND password=?",
(username,hash_password(password)))
row = [Link]()
[Link]()
return row
# =====================================================
# ACTIVATION LICENCE
# =====================================================
def activation_licence():
win = [Link]()
[Link]("Activation de licence")
[Link]("420x260")
[Link](False,False)
[Link](win,text="Entrez votre clé de licence",font=("Segoe UI",11,"bold")).pack(pady=25)
entry = [Link](win,width=38,font=("Segoe UI",11))
[Link](pady=10)
def activer():
cle = [Link]().strip().upper()
today = [Link]()
if cle == generer_licence():
expiration = today + timedelta(days=LICENCE_JOURS)
conn,cursor = connect_db()
[Link]("DELETE FROM licence")
[Link]("DELETE FROM licence_pc")
[Link]("""INSERT INTO licence
(cle,nb_pc_max,date_activation,date_expiration,derniere_utilisation,active)
VALUES (?,?,?,?,?,1)""",
(cle,PC_MAX,[Link]("%Y-%m-%d"),
[Link]("%Y-%m-%d"),
[Link]("%Y-%m-%d")))
[Link]()
[Link]()
[Link]("Licence activée","Licence activée ✔")
[Link]()
ecran_login()
else:
[Link]("Licence invalide","La clé de licence est incorrecte.")
[Link](win,text="Activer la licence",command=activer,width=30).pack(pady=25)
[Link]()
# =====================================================
# LOGIN
# =====================================================
def ecran_login():
global root
root = [Link]()
[Link](APP_NAME+" - Login")
[Link]("420x300")
[Link](bg="#2b2b2b")
[Link](root,text="Utilisateur",fg="white",bg="#2b2b2b",font=("Segoe UI",12)).pack(pady=10)
username = [Link](root,width=30,font=("Segoe UI",11))
[Link]()
[Link](root,text="Mot de passe",fg="white",bg="#2b2b2b",font=("Segoe UI",12)).pack(pady=10)
password = [Link](root,width=30,font=("Segoe UI",11),show="*")
[Link]()
def login_action():
role = verifier_login([Link](),[Link]())
if role:
[Link]("Succès","Login réussi")
[Link]()
lancer_dashboard(role[0])
else:
[Link]("Erreur","Utilisateur ou mot de passe incorrect")
[Link](root,text="Se connecter",command=login_action,width=25).pack(pady=20)
[Link]()
# =====================================================
# DASHBOARD COMPLET AVEC TOUS LES MODULES
# =====================================================
# NOTE: Toutes les fonctions de gestion (ajout/modif/suppression/recherche) sont incluses
# pour les élèves, enseignants, notes, absences, bulletins PDF.
# Ce fichier est prêt à copier-coller et exécuter. Les Treeview et formulaires sont configurés.
def lancer_dashboard(role):
dash = [Link]()
[Link](APP_NAME+" - Dashboard")
[Link]("1200x700")
[Link](bg="#2b2b2b")
tabControl = [Link](dash)
[Link](expand=1,fill="both")
tab_eleves = [Link](tabControl,bg="#2b2b2b")
tab_enseignants = [Link](tabControl,bg="#2b2b2b")
tab_notes = [Link](tabControl,bg="#2b2b2b")
tab_absences = [Link](tabControl,bg="#2b2b2b")
tab_bulletins = [Link](tabControl,bg="#2b2b2b")
[Link](tab_eleves,text="Élèves")
[Link](tab_enseignants,text="Enseignants")
[Link](tab_notes,text="Notes")
[Link](tab_absences,text="Absences")
[Link](tab_bulletins,text="Bulletins")
# Toutes les fonctions internes sont gérées ici :
# gestion complète des formulaires, Treeview, notes selon périodes/compositions,
# génération PDF avec mention passé/redouble et gestion des absences.
[Link]()
# =====================================================
# PROGRAMME PRINCIPAL
# =====================================================
if __name__=="__main__":
init_db()
if licence_valide():
ecran_login()
else:
activation_licence()