update grabber (sql+req)
This commit is contained in:
parent
532358e2fc
commit
fc3f179250
84
app.py
84
app.py
@ -3,50 +3,76 @@ from fastapi.responses import HTMLResponse
|
|||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
import json
|
import json
|
||||||
from grabber import Grabber
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
app = FastAPI()
|
from grabber import Grabber, flotte, create_db_and_tables
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
create_db_and_tables()
|
||||||
|
yield
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
ordi1 = Grabber()
|
|
||||||
|
|
||||||
@app.post("/endpoint")
|
@app.post("/endpoint")
|
||||||
async def receive_info(request: Request):
|
async def receive_info(request: Request):
|
||||||
# Lire le body brut
|
|
||||||
body = await request.body()
|
body = await request.body()
|
||||||
print(body)
|
|
||||||
|
|
||||||
# Parser le JSON
|
|
||||||
try:
|
try:
|
||||||
data = json.loads(body)
|
data = json.loads(body)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
raise HTTPException(status_code=400, detail="Invalid JSON")
|
raise HTTPException(status_code=400, detail="Invalid JSON")
|
||||||
|
|
||||||
hw = data["HARDWARE"]
|
sw = data.get("SOFTWARE", {})
|
||||||
sw = data["SOFTWARE"]
|
# On récupère l'adresse MAC, c'est notre nouvel identifiant unique
|
||||||
|
mac = sw.get("mac_address")
|
||||||
|
hostname = sw.get("hostname", "Inconnu")
|
||||||
|
|
||||||
ordi1.motherboard = hw["motherboard"]
|
if not mac:
|
||||||
ordi1.cpu_model = hw["cpu_model"]
|
raise HTTPException(status_code=400, detail="Adresse MAC manquante dans le JSON")
|
||||||
ordi1.cpu_id = hw["cpu_id"]
|
|
||||||
ordi1.cpu_cores = hw["cpu_cores"]
|
|
||||||
ordi1.cpu_threads = hw["cpu_threads"]
|
|
||||||
ordi1.cpu_frequency_min = hw["cpu_frequency_min"]
|
|
||||||
ordi1.cpu_frequency_cur = hw["cpu_frequency_cur"]
|
|
||||||
ordi1.cpu_frequency_max = hw["cpu_frequency_max"]
|
|
||||||
|
|
||||||
ordi1.hostname = sw["hostname"]
|
# Si la machine n'est pas encore connue par son adresse MAC
|
||||||
ordi1.os = sw["os"]
|
if mac not in flotte:
|
||||||
ordi1.arch = sw["arch"]
|
print(f"Nouvelle machine détectée : {hostname} ({mac})")
|
||||||
ordi1.desktop_env = sw["desktop_env"]
|
flotte[mac] = Grabber(mac, hostname)
|
||||||
ordi1.window_manager = sw["window_manager"]
|
|
||||||
ordi1.kernel = sw["kernel"]
|
|
||||||
|
|
||||||
print(f"Hostname is {ordi1.hostname}")
|
ordi_actuel = flotte[mac]
|
||||||
print(f"Motherboard serial is {ordi1.motherboard}")
|
ordi_actuel.update(data)
|
||||||
|
ordi_actuel.save()
|
||||||
|
|
||||||
return {"status": "ok"}
|
return {"status": "ok", "mac": mac}
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
async def list_ordis(request: Request):
|
||||||
|
"""Affiche la liste des ordis, identifiés par MAC mais affichés par Hostname."""
|
||||||
|
# On crée des liens qui pointent vers /ordi/ADRESSE_MAC
|
||||||
|
# Mais pour l'humain, on affiche "Hostname (Mac)"
|
||||||
|
list_items = []
|
||||||
|
for mac, grabber_obj in flotte.items():
|
||||||
|
nom_affiche = f"{grabber_obj.hostname} <small>({mac})</small>"
|
||||||
|
list_items.append(f'<li><a href="/ordi/{mac}">{nom_affiche}</a></li>')
|
||||||
|
|
||||||
@app.get("/ordi1")
|
liens_html = "".join(list_items)
|
||||||
async def show_info(request: Request):
|
|
||||||
return templates.TemplateResponse("item.html", {"request": request, "ordi": ordi1})
|
return HTMLResponse(f"""
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dashboard Grabber</title>
|
||||||
|
<style>body{{font-family:sans-serif; padding:20px;}} li{{margin:5px 0;}}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Tableau de bord Grabber</h1>
|
||||||
|
<h2>Machines connectées</h2>
|
||||||
|
<ul>{liens_html or "En attente de données..."}</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""")
|
||||||
|
|
||||||
|
# L'URL attend maintenant une adresse MAC (ex: /ordi/00:11:22:33:44:55)
|
||||||
|
@app.get("/ordi/{mac_address}")
|
||||||
|
async def show_info(request: Request, mac_address: str):
|
||||||
|
if mac_address in flotte:
|
||||||
|
return templates.TemplateResponse("item.html", {"request": request, "ordi": flotte[mac_address]})
|
||||||
|
else:
|
||||||
|
return HTMLResponse("<h1>Machine introuvable</h1>", status_code=404)
|
||||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
125
grabber.py
125
grabber.py
@ -1,36 +1,95 @@
|
|||||||
#!/usr/bin/python3
|
from typing import Optional
|
||||||
import configparser
|
from datetime import datetime
|
||||||
import requests
|
from sqlmodel import Field, Session, SQLModel, create_engine
|
||||||
|
|
||||||
class Grabber():
|
# --- CONFIGURATION BASE DE DONNÉES ---
|
||||||
motherboard = " "
|
DB_FILE = "grabberman.db"
|
||||||
cpu_model = " "
|
sqlite_url = f"sqlite:///{DB_FILE}"
|
||||||
cpu_id = " "
|
engine = create_engine(sqlite_url, echo=False)
|
||||||
cpu_cores = " "
|
|
||||||
cpu_threads = " "
|
|
||||||
cpu_frequency_min = " "
|
|
||||||
cpu_frequency_cur = " "
|
|
||||||
cpu_frequency_max = " "
|
|
||||||
ram_size = " "
|
|
||||||
ram_slots = " "
|
|
||||||
ram_number = " "
|
|
||||||
|
|
||||||
hostname = " "
|
# --- MODÈLE DE DONNÉES (TABLE SQL) ---
|
||||||
os = " "
|
class SystemLog(SQLModel, table=True):
|
||||||
arch = " "
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
desktop_env = " "
|
date_scan: datetime = Field(default_factory=datetime.now)
|
||||||
window_manager = " "
|
|
||||||
kernel = " "
|
|
||||||
|
|
||||||
def fetch_summary(self):
|
# NOUVEAU : mac_address devient un champ indexé important
|
||||||
return
|
mac_address: str = Field(index=True)
|
||||||
def shutdown():
|
hostname: str
|
||||||
return
|
|
||||||
def status(self):
|
# Champs Hardware
|
||||||
return
|
motherboard: Optional[str] = None
|
||||||
def link_to_user(self,user):
|
cpu_model: Optional[str] = None
|
||||||
return
|
cpu_id: Optional[str] = None
|
||||||
def remove_user_access(self):
|
cpu_cores: Optional[str] = None
|
||||||
return
|
cpu_threads: Optional[str] = None
|
||||||
def show_users(self):
|
cpu_frequency_min: Optional[str] = None
|
||||||
return
|
cpu_frequency_cur: Optional[str] = None
|
||||||
|
cpu_frequency_max: Optional[str] = None
|
||||||
|
gpu_model: Optional[str] = None
|
||||||
|
ram_slots: Optional[str] = None
|
||||||
|
|
||||||
|
# Champs Software
|
||||||
|
os: Optional[str] = None
|
||||||
|
arch: Optional[str] = None
|
||||||
|
desktop_env: Optional[str] = None
|
||||||
|
window_manager: Optional[str] = None
|
||||||
|
kernel: Optional[str] = None
|
||||||
|
|
||||||
|
def create_db_and_tables():
|
||||||
|
SQLModel.metadata.create_all(engine)
|
||||||
|
|
||||||
|
# --- GESTION DE LA FLOTTE EN MÉMOIRE ---
|
||||||
|
# Le dictionnaire stockera maintenant : {"AA:BB:CC:DD:EE:FF": GrabberObject}
|
||||||
|
flotte = {}
|
||||||
|
|
||||||
|
class Grabber:
|
||||||
|
def __init__(self, mac_address, hostname="Inconnu"):
|
||||||
|
self.mac_address = mac_address
|
||||||
|
self.hostname = hostname
|
||||||
|
self.data_cache = {}
|
||||||
|
|
||||||
|
def update(self, json_data):
|
||||||
|
"""Met à jour les données et prépare l'objet SQLModel."""
|
||||||
|
hw = json_data.get("HARDWARE", {})
|
||||||
|
sw = json_data.get("SOFTWARE", {})
|
||||||
|
|
||||||
|
# Mise à jour du hostname s'il a changé, mais on garde la MAC comme ancre
|
||||||
|
if "hostname" in sw:
|
||||||
|
self.hostname = sw["hostname"]
|
||||||
|
|
||||||
|
# On prépare les données pour la DB
|
||||||
|
self.data_cache = {
|
||||||
|
"mac_address": self.mac_address, # On n'oublie pas la MAC
|
||||||
|
"hostname": self.hostname,
|
||||||
|
"motherboard": hw.get("motherboard", "N/A"),
|
||||||
|
"cpu_model": hw.get("cpu_model", "N/A"),
|
||||||
|
"cpu_id": hw.get("cpu_id", "N/A"),
|
||||||
|
"cpu_cores": hw.get("cpu_cores", "N/A"),
|
||||||
|
"cpu_threads": hw.get("cpu_threads", "N/A"),
|
||||||
|
"cpu_frequency_min": hw.get("cpu_frequency_min", "N/A"),
|
||||||
|
"cpu_frequency_cur": hw.get("cpu_frequency_cur", "N/A"),
|
||||||
|
"cpu_frequency_max": hw.get("cpu_frequency_max", "N/A"),
|
||||||
|
"gpu_model": hw.get("gpu_model", "N/A"),
|
||||||
|
"ram_slots": hw.get("ram_slots", "N/A"),
|
||||||
|
"os": sw.get("os", "N/A"),
|
||||||
|
"arch": sw.get("arch", "N/A"),
|
||||||
|
"desktop_env": sw.get("desktop_env", "N/A"),
|
||||||
|
"window_manager": sw.get("window_manager", "N/A"),
|
||||||
|
"kernel": sw.get("kernel", "N/A")
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
"""Enregistre les données via SQLModel."""
|
||||||
|
try:
|
||||||
|
log_entry = SystemLog(**self.data_cache)
|
||||||
|
with Session(engine) as session:
|
||||||
|
session.add(log_entry)
|
||||||
|
session.commit()
|
||||||
|
session.refresh(log_entry)
|
||||||
|
print(f"Sauvegarde réussie pour {self.hostname} ({self.mac_address})")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Erreur SQLModel : {e}")
|
||||||
|
|
||||||
|
# Permet d'accéder aux propriétés comme ordi.cpu_model dans le template
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return self.data_cache.get(name, "N/A")
|
||||||
61
grabber.sh
61
grabber.sh
@ -40,7 +40,7 @@ echo ""
|
|||||||
|
|
||||||
#----- Verify dependecies available -----
|
#----- Verify dependecies available -----
|
||||||
REQUIRED_CMDS_SIMPLE=(inxi dmidecode lscpu lsblk nproc numfmt)
|
REQUIRED_CMDS_SIMPLE=(inxi dmidecode lscpu lsblk nproc numfmt)
|
||||||
REQUIRED_CMDS_FULL=(inxi dmidecode lscpu lsblk nproc numfmt python3 jq)
|
REQUIRED_CMDS_FULL=(inxi dmidecode lscpu lsblk nproc numfmt python3 jq sqlite3)
|
||||||
|
|
||||||
requirements_simple() {
|
requirements_simple() {
|
||||||
echo -n "Checking dependencies... "
|
echo -n "Checking dependencies... "
|
||||||
@ -184,48 +184,6 @@ done
|
|||||||
TOTAL_STORAGE=$(numfmt --to iec $TOTAL_STORAGE)
|
TOTAL_STORAGE=$(numfmt --to iec $TOTAL_STORAGE)
|
||||||
#---------------------------------
|
#---------------------------------
|
||||||
|
|
||||||
# Compile Hardware informations
|
|
||||||
hardware() {
|
|
||||||
echo "[HARDWARE]" >> $SUM_FILE
|
|
||||||
echo "MB_SERIAL = $MB_SERIAL" >> $SUM_FILE
|
|
||||||
echo "" >> $SUM_FILE
|
|
||||||
|
|
||||||
echo "--- CPU DATA ---" >> $SUM_FILE
|
|
||||||
echo "CPU_MODEL = $CPU_MODEL" >> $SUM_FILE
|
|
||||||
echo "CPU_ID = $CPU_ID" >> $SUM_FILE
|
|
||||||
echo "CPU_CORES=$CPU_CORES" >> $SUM_FILE
|
|
||||||
echo "CPU_THREADS=$CPU_THREADS" >> $SUM_FILE
|
|
||||||
echo "CPU_FREQUENCY_MIN=$CPU_FREQUENCY_MIN" >> $SUM_FILE
|
|
||||||
echo "CPU_FREQUENCY_CUR=$CPU_FREQUENCY_CUR" >> $SUM_FILE
|
|
||||||
echo "CPU_FREQUENCY_MAX=$CPU_FREQUENCY_MAX" >> $SUM_FILE
|
|
||||||
echo "" >> $SUM_FILE
|
|
||||||
|
|
||||||
echo "--- GPU DATA ---" >> $SUM_FILE
|
|
||||||
echo "GPU_MODEL=$GPU_MODEL" >> $SUM_FILE
|
|
||||||
echo "" >> $SUM_FILE
|
|
||||||
|
|
||||||
echo "--- RAM DATA ---" >> $SUM_FILE
|
|
||||||
echo "RAM_SIZE = $RAM_SIZE" >> $SUM_FILE
|
|
||||||
echo "RAM_SLOTS=$RAM_SLOTS" >> $SUM_FILE
|
|
||||||
echo "RAM_NUMBER=$RAM_NUMBER" >> $SUM_FILE
|
|
||||||
|
|
||||||
for i in $(seq 1 $RAM_SLOTS_NUMBER); do
|
|
||||||
R_SIZE=$(sudo dmidecode --type=memory | grep "Size:" | grep -v "Volatile" | grep -v "Cache" | grep -v "Logical" | cut -d: -f2 | sed -n "${i}p" | sed 's/\ //')
|
|
||||||
R_SLOT=$i
|
|
||||||
R_FREQ=$(sudo dmidecode --type=memory | grep Speed | grep -v "Memory" | cut -d: -f2 | sed -n "${i}p" | sed 's/\ //')
|
|
||||||
|
|
||||||
echo "RAM_${i}_SIZE=$R_SIZE" >> $SUM_FILE
|
|
||||||
echo "RAM_${i}_SLOT=$R_SLOT" >> $SUM_FILE
|
|
||||||
echo "RAM_${i}_FREQ=$R_FREQ" >> $SUM_FILE
|
|
||||||
done
|
|
||||||
echo "" >> $SUM_FILE
|
|
||||||
|
|
||||||
echo "--- STORAGE DATA ---" >> $SUM_FILE
|
|
||||||
disks_partitions
|
|
||||||
echo "STORAGE = $TOTAL_STORAGE" >> $SUM_FILE
|
|
||||||
echo "" >> $SUM_FILE
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
|
|
||||||
######## SOFTWARE PART #########################
|
######## SOFTWARE PART #########################
|
||||||
@ -233,17 +191,7 @@ OS=$(lsb_release -a | grep Description | cut -f2)
|
|||||||
ARCH=$(uname -a | cut -d' ' -f10)
|
ARCH=$(uname -a | cut -d' ' -f10)
|
||||||
KERNEL=$(uname -r)
|
KERNEL=$(uname -r)
|
||||||
HOSTNAME=$(hostname)
|
HOSTNAME=$(hostname)
|
||||||
|
MAC_ADDRESS=$(cat /sys/class/net/$(ls /sys/class/net | grep -vE '^(lo|docker|veth|br)' | head -n 1)/address)
|
||||||
# Compile Software informations
|
|
||||||
software() {
|
|
||||||
echo "[SOFTWARE]"
|
|
||||||
echo "OS = $OS"
|
|
||||||
echo "HOSTNAME = $HOSTNAME"
|
|
||||||
echo "ARCHITECTURE = $ARCH"
|
|
||||||
echo "KERNEL = $KERNEL"
|
|
||||||
echo "DESKTOP_ENV = $XDG_CURRENT_DESKTOP"
|
|
||||||
echo "WINDOW_MANAGER = $XDG_SESSION_TYPE"
|
|
||||||
} >> $SUM_FILE
|
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
|
|
||||||
@ -261,6 +209,7 @@ json_file() {
|
|||||||
--arg gpu_model "$GPU_MODEL" \
|
--arg gpu_model "$GPU_MODEL" \
|
||||||
--arg ram_slots "$RAM_SLOTS" \
|
--arg ram_slots "$RAM_SLOTS" \
|
||||||
--arg hostname "$HOSTNAME" \
|
--arg hostname "$HOSTNAME" \
|
||||||
|
--arg mac_address "$MAC_ADDRESS" \
|
||||||
--arg os "$OS" \
|
--arg os "$OS" \
|
||||||
--arg arch "$ARCH" \
|
--arg arch "$ARCH" \
|
||||||
--arg desktop_env "$XDG_CURRENT_DESKTOP" \
|
--arg desktop_env "$XDG_CURRENT_DESKTOP" \
|
||||||
@ -281,6 +230,7 @@ json_file() {
|
|||||||
},
|
},
|
||||||
SOFTWARE: {
|
SOFTWARE: {
|
||||||
hostname: $hostname,
|
hostname: $hostname,
|
||||||
|
mac_address:$mac_address,
|
||||||
os: $os,
|
os: $os,
|
||||||
arch: $arch,
|
arch: $arch,
|
||||||
desktop_env: $desktop_env,
|
desktop_env: $desktop_env,
|
||||||
@ -311,10 +261,7 @@ python_venv() {
|
|||||||
echo "It's grabbin time!"
|
echo "It's grabbin time!"
|
||||||
hello
|
hello
|
||||||
echo "Fetching hardware data..."
|
echo "Fetching hardware data..."
|
||||||
hardware
|
|
||||||
echo "Fetching software data..."
|
echo "Fetching software data..."
|
||||||
software
|
|
||||||
echo "Writing everything in summary.txt"
|
|
||||||
if [ "$choice" = "1" ]; then
|
if [ "$choice" = "1" ]; then
|
||||||
echo "Grabber has complete his mission! Find every logs saved in your home repository inside the /grabber folder."
|
echo "Grabber has complete his mission! Find every logs saved in your home repository inside the /grabber folder."
|
||||||
echo "See you space cowboy..."
|
echo "See you space cowboy..."
|
||||||
|
|||||||
BIN
grabberman.db
BIN
grabberman.db
Binary file not shown.
@ -1,4 +1,4 @@
|
|||||||

|

|
||||||
|
|
||||||
# Grabber - Fetch all your PC
|
# Grabber - Fetch all your PC
|
||||||
|
|
||||||
|
|||||||
@ -40,3 +40,4 @@ typing-inspection==0.4.2
|
|||||||
typing_extensions==4.15.0
|
typing_extensions==4.15.0
|
||||||
urllib3==2.6.3
|
urllib3==2.6.3
|
||||||
uvicorn==0.40.0
|
uvicorn==0.40.0
|
||||||
|
sqlmodel==0.0.32
|
||||||
@ -5,31 +5,62 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Informations Système</title>
|
<title>Informations Système</title>
|
||||||
<style>
|
<style>
|
||||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
body { font-family: Arial, sans-serif; margin: 20px; background-color: #f9f9f9; }
|
||||||
h1 { color: #333; }
|
h1 { color: #333; text-align: center; }
|
||||||
|
|
||||||
|
/* Style pour le conteneur d'un seul PC */
|
||||||
|
.computer-container {
|
||||||
|
background-color: white;
|
||||||
|
border: 2px solid #333;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 40px; /* Espace entre chaque ordi */
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.computer-header {
|
||||||
|
background-color: #333;
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.section { margin-bottom: 20px; border: 1px solid #ccc; padding: 10px; }
|
.section { margin-bottom: 20px; border: 1px solid #ccc; padding: 10px; }
|
||||||
.section h2 { margin-top: 0; }
|
.section h2 { margin-top: 0; color: #555; border-bottom: 2px solid #ddd; padding-bottom: 5px;}
|
||||||
table { width: 100%; border-collapse: collapse; }
|
|
||||||
|
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
||||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||||
th { background-color: #f2f2f2; }
|
th { background-color: #f2f2f2; width: 30%; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Informations de l'Ordinateur</h1>
|
<h1>Parc Informatique ({{ ordinateurs|length }} machines)</h1>
|
||||||
|
|
||||||
|
{% for ordi in ordinateurs %}
|
||||||
|
|
||||||
|
<div class="computer-container">
|
||||||
|
<div class="computer-header">
|
||||||
|
<h2>🖥️ {{ ordi.hostname }} <small>(MAC: {{ ordi.mac_address }})</small></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>[HARDWARE]</h2>
|
<h2>[HARDWARE]</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Propriété</th><th>Valeur</th></tr>
|
<tr><th>Propriété</th><th>Valeur</th></tr>
|
||||||
<tr><td>Hostname</td><td>{{ ordi.hostname }}</td></tr>
|
<tr><td>Série Carte Mère</td><td>{{ ordi.mb_serial }}</td></tr>
|
||||||
<tr><td>CPU</td><td>{{ ordi.cpu_model }}</td></tr>
|
<tr><td>Série Châssis</td><td>{{ ordi.chassis_serial }}</td></tr>
|
||||||
<tr><td>ID CPU</td><td>{{ ordi.cpu_id }}</td></tr>
|
<tr><td>CPU</td><td>{{ ordi.cpu }}</td></tr>
|
||||||
<tr><td>Nombre de Cœurs CPU</td><td>{{ ordi.cpu_cores }}</td></tr>
|
<tr><td>CPU ID</td><td>{{ ordi.cpu_id }}</td></tr>
|
||||||
<tr><td>Nombre de Threads CPU</td><td>{{ ordi.cpu_threads }}</td></tr>
|
<tr><td>Nombre de Cœurs CPU</td><td>{{ ordi.cpu_cores_number }}</td></tr>
|
||||||
|
<tr><td>Nombre de Threads CPU</td><td>{{ ordi.cpu_threads_number }}</td></tr>
|
||||||
<tr><td>Fréquence Min CPU</td><td>{{ ordi.cpu_frequency_min }}</td></tr>
|
<tr><td>Fréquence Min CPU</td><td>{{ ordi.cpu_frequency_min }}</td></tr>
|
||||||
<tr><td>Fréquence Courante CPU</td><td>{{ ordi.cpu_frequency_cur }}</td></tr>
|
<tr><td>Fréquence Courante CPU</td><td>{{ ordi.cpu_frequency_cur }}</td></tr>
|
||||||
<tr><td>Fréquence Max CPU</td><td>{{ ordi.cpu_frequency_max }}</td></tr>
|
<tr><td>Fréquence Max CPU</td><td>{{ ordi.cpu_frequency_max }}</td></tr>
|
||||||
<tr><td>Nombre de slots de RAM</td><td>{{ ordi.ram_slots }}</td></tr>
|
<tr><td>Modèle GPU</td><td>{{ ordi.gpu_model }}</td></tr>
|
||||||
|
<tr><td>Stockage Total</td><td>{{ ordi.stockage_total }}</td></tr>
|
||||||
|
<tr><td>Nombre de slots de RAM</td><td>{{ ordi.ram_slots_number }}</td></tr>
|
||||||
|
<tr><td>Génération RAM</td><td>{{ ordi.ram_gen }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -40,10 +71,17 @@
|
|||||||
<tr><td>Hostname</td><td>{{ ordi.hostname }}</td></tr>
|
<tr><td>Hostname</td><td>{{ ordi.hostname }}</td></tr>
|
||||||
<tr><td>OS</td><td>{{ ordi.os }}</td></tr>
|
<tr><td>OS</td><td>{{ ordi.os }}</td></tr>
|
||||||
<tr><td>Architecture</td><td>{{ ordi.arch }}</td></tr>
|
<tr><td>Architecture</td><td>{{ ordi.arch }}</td></tr>
|
||||||
<tr><td>Desktop</td><td>{{ ordi.desktop_env }}</td></tr>
|
<tr><td>Desktop</td><td>{{ ordi.desktop }}</td></tr>
|
||||||
<tr><td>Window Manager</td><td>{{ ordi.window_manager }}</td></tr>
|
<tr><td>Window Manager</td><td>{{ ordi.wm }}</td></tr>
|
||||||
<tr><td>Kernel</td><td>{{ ordi.kernel }}</td></tr>
|
<tr><td>Kernel</td><td>{{ ordi.kernel }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% if not ordinateurs %}
|
||||||
|
<p style="text-align:center; color: red;">Aucun ordinateur enregistré dans la base de données.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user