import os
import sqlite3
import hashlib
import uuid
import socket
from datetime import datetime, timedelta
import tkinter as tk
from tkinter import messagebox, ttk
# =====================================================
# 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 DONNÉES
# =====================================================
def connect_db():
conn = [Link](DB_PATH)
return conn, [Link]()
def init_db():
conn, cursor = connect_db()
# Table licence
[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
)
""")
# Table PC autorisés
[Link]("""
CREATE TABLE IF NOT EXISTS licence_pc (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pc_id TEXT UNIQUE
)
""")
# Table utilisateurs
[Link]("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE,
password TEXT,
role TEXT
)
""")
# 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")
)
# Table classes
[Link]("""
CREATE TABLE IF NOT EXISTS classes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT UNIQUE
)
""")
# Table élèves
[Link]("""
CREATE TABLE IF NOT EXISTS eleves (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT,
prenom TEXT,
matricule TEXT UNIQUE,
classe_id INTEGER,
FOREIGN KEY (classe_id) REFERENCES classes(id)
)
""")
# Table enseignants
[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)
)
""")
# Ajouter les classes si elles n’existent pas
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,))
[Link]()
[Link]()
# =====================================================
# ID UNIQUE DU PC
# =====================================================
def get_pc_id():
raw = f"{[Link]()}-{[Link]()}"
return hashlib.sha256([Link]()).hexdigest()
# =====================================================
# GÉNÉRATION DE CLÉ (ADMIN)
# =====================================================
def generer_licence():
data = f"{PC_MAX}|{LICENCE_JOURS}|{SECRET}"
return hashlib.sha256([Link]()).hexdigest().upper()
# =====================================================
# VÉRIFICATION DE LA LICENCE
# =====================================================
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
# =====================================================
# LICENCE - ACTIVATION
# =====================================================
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 avec succès.\nMaximum 3 PC autorisés.")
[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]()
# =====================================================
# FONCTIONS UTILITAIRES ÉLÈVES
# =====================================================
def rechercher_classes():
conn, cursor = connect_db()
[Link]("SELECT nom FROM classes ORDER BY id")
result = [Link]()
[Link]()
return [r[0] for r in result]
def ajouter_eleve(nom, prenom, matricule, classe_nom):
conn, cursor = connect_db()
[Link]("SELECT id FROM classes WHERE nom=?", (classe_nom,))
classe = [Link]()
if not classe:
[Link]()
return False
classe_id = classe[0]
try:
[Link](
"INSERT INTO eleves (nom, prenom, matricule, classe_id) VALUES (?,?,?,?)",
(nom, prenom, matricule, classe_id)
)
[Link]()
[Link]()
return True
except:
[Link]()
return False
def rechercher_eleve(mot_cle):
conn, cursor = connect_db()
[Link]("""
SELECT [Link], [Link], [Link], [Link]
FROM eleves e
JOIN classes c ON e.classe_id=[Link]
WHERE [Link] LIKE ? OR [Link] LIKE ?
""", (f"%{mot_cle}%", f"%{mot_cle}%"))
result = [Link]()
[Link]()
return result
# =====================================================
# FONCTIONS UTILITAIRES ENSEIGNANTS
# =====================================================
def ajouter_enseignant(nom, prenom, classe_nom):
conn, cursor = connect_db()
[Link]("SELECT id FROM classes WHERE nom=?", (classe_nom,))
classe = [Link]()
if not classe:
[Link]()
return False
classe_id = classe[0]
try:
[Link](
"INSERT INTO enseignants (nom, prenom, classe_id) VALUES (?,?,?)",
(nom, prenom, classe_id)
)
[Link]()
[Link]()
return True
except:
[Link]()
return False
def rechercher_enseignant(mot_cle):
conn, cursor = connect_db()
[Link]("""
SELECT [Link], [Link], [Link]
FROM enseignants e
JOIN classes c ON e.classe_id=[Link]
WHERE [Link] LIKE ? OR [Link] LIKE ?
""", (f"%{mot_cle}%", f"%{mot_cle}%"))
result = [Link]()
[Link]()
return result
# =====================================================
# INTERFACE GÉRER ÉLÈVES
# =====================================================
def gerer_eleves():
# ... ton code déjà existant
pass
# =====================================================
# INTERFACE GÉRER ENSEIGNANTS
# =====================================================
def gerer_enseignants():
win = [Link]()
[Link]("Gestion des enseignants")
[Link]("600x400")
tab_control = [Link](win)
tab1 = [Link](tab_control)
tab2 = [Link](tab_control)
tab_control.add(tab1, text="Ajouter enseignant")
tab_control.add(tab2, text="Rechercher enseignant")
tab_control.pack(expand=1, fill="both")
# Ajouter
[Link](tab1, text="Nom").grid(row=0, column=0, padx=5, pady=5)
nom_entry = [Link](tab1)
nom_entry.grid(row=0, column=1, padx=5, pady=5)
[Link](tab1, text="Prénom").grid(row=1, column=0, padx=5, pady=5)
prenom_entry = [Link](tab1)
prenom_entry.grid(row=1, column=1, padx=5, pady=5)
[Link](tab1, text="Classe").grid(row=2, column=0, padx=5, pady=5)
classes_list = rechercher_classes()
classe_combo = [Link](tab1, values=classes_list, state="readonly")
classe_combo.grid(row=2, column=1, padx=5, pady=5)
def ajouter_action():
nom = nom_entry.get().strip()
prenom = prenom_entry.get().strip()
classe = classe_combo.get()
if ajouter_enseignant(nom, prenom, classe):
[Link]("Succès", "Enseignant ajouté ✔")
else:
[Link]("Erreur", "Impossible d'ajouter l'enseignant (doublon ?)")
[Link](tab1, text="Ajouter", command=ajouter_action).grid(row=3, column=0, columnspan=2,
pady=10)
# Rechercher
[Link](tab2, text="Nom ou prénom").grid(row=0, column=0, padx=5, pady=5)
search_entry = [Link](tab2)
search_entry.grid(row=0, column=1, padx=5, pady=5)
tree = [Link](tab2, columns=("Nom","Prénom","Classe"), show="headings")
[Link]("Nom", text="Nom")
[Link]("Prénom", text="Prénom")
[Link]("Classe", text="Classe")
[Link](row=1, column=0, columnspan=2, pady=10)
def rechercher_action():
for row in tree.get_children():
[Link](row)
results = rechercher_enseignant(search_entry.get().strip())
for r in results:
[Link]("", "end", values=r)
[Link](tab2, text="Rechercher", command=rechercher_action).grid(row=2, column=0,
columnspan=2, pady=5)
# =====================================================
# ÉCRAN LOGIN
# =====================================================
def ecran_login():
# ... ton code déjà existant
pass
# =====================================================
# DASHBOARD
# =====================================================
def lancer_dashboard():
app = [Link]()
[Link](APP_NAME)
[Link]("700x450")
style = [Link](app)
style.theme_use("clam")
[Link]("TFrame", background="#1e1e1e")
[Link]("TLabel", background="#1e1e1e", foreground="white", font=("Segoe UI", 10))
[Link]("TButton", font=("Segoe UI", 10), padding=6)
frame = [Link](app)
[Link](fill="both", expand=True)
[Link](frame, text="GESTION SCOLAIRE", font=("Segoe UI", 18, "bold")).pack(pady=30)
[Link](frame, text="Licence valide ✔ (3 PC maximum)", foreground="#4CAF50", font=("Segoe UI",
11)).pack(pady=10)
# --- Boutons ---
[Link](frame, text="Gérer les élèves", command=gerer_eleves, width=25).pack(pady=10)
[Link](frame, text="Gérer les enseignants", command=gerer_enseignants, width=25).pack(pady=10)
[Link](frame, text="Quitter", command=[Link], width=20).pack(pady=40)
[Link]()
# =====================================================
# PROGRAMME PRINCIPAL
# =====================================================
if __name__ == "__main__":
init_db()
if licence_valide():
ecran_login()
else:
activation_licence()