This commit is contained in:
2025-12-20 03:47:10 +01:00
parent 8428bf9c82
commit dcba044cd6
179 changed files with 10345 additions and 786 deletions

View File

@@ -9,11 +9,24 @@ from datetime import datetime
from app.db.session import get_db
from app.core.security import verify_token
from app.schemas.benchmark import BenchmarkPayload, BenchmarkResponse, BenchmarkDetail, BenchmarkSummary
from app.schemas.benchmark import (
BenchmarkPayload,
BenchmarkResponse,
BenchmarkDetail,
BenchmarkSummary,
BenchmarkUpdate,
)
from app.models.device import Device
from app.models.hardware_snapshot import HardwareSnapshot
from app.models.benchmark import Benchmark
from app.utils.scoring import calculate_global_score
from app.utils.scoring import (
calculate_global_score,
calculate_cpu_score,
calculate_memory_score,
calculate_disk_score,
calculate_network_score,
calculate_gpu_score
)
router = APIRouter()
@@ -91,7 +104,7 @@ async def submit_benchmark(
snapshot.ram_slots_total = hw.ram.slots_total if hw.ram else None
snapshot.ram_slots_used = hw.ram.slots_used if hw.ram else None
snapshot.ram_ecc = hw.ram.ecc if hw.ram else None
snapshot.ram_layout_json = json.dumps([slot.dict() for slot in hw.ram.layout]) if hw.ram and hw.ram.layout else None
snapshot.ram_layout_json = json.dumps([slot.model_dump() for slot in hw.ram.layout]) if hw.ram and hw.ram.layout else None
# GPU
snapshot.gpu_summary = f"{hw.gpu.vendor} {hw.gpu.model}" if hw.gpu and hw.gpu.model else None
@@ -104,11 +117,12 @@ async def submit_benchmark(
# Storage
snapshot.storage_summary = f"{len(hw.storage.devices)} device(s)" if hw.storage and hw.storage.devices else None
snapshot.storage_devices_json = json.dumps([d.dict() for d in hw.storage.devices]) if hw.storage and hw.storage.devices else None
snapshot.partitions_json = json.dumps([p.dict() for p in hw.storage.partitions]) if hw.storage and hw.storage.partitions else None
snapshot.storage_devices_json = json.dumps([d.model_dump() for d in hw.storage.devices]) if hw.storage and hw.storage.devices else None
snapshot.partitions_json = json.dumps([p.model_dump() for p in hw.storage.partitions]) if hw.storage and hw.storage.partitions else None
# Network
snapshot.network_interfaces_json = json.dumps([i.dict() for i in hw.network.interfaces]) if hw.network and hw.network.interfaces else None
snapshot.network_interfaces_json = json.dumps([i.model_dump() for i in hw.network.interfaces]) if hw.network and hw.network.interfaces else None
snapshot.network_shares_json = json.dumps([share.model_dump() for share in hw.network_shares]) if hw.network_shares else None
# OS / Motherboard
snapshot.os_name = hw.os.name if hw.os else None
@@ -116,15 +130,29 @@ async def submit_benchmark(
snapshot.kernel_version = hw.os.kernel_version if hw.os else None
snapshot.architecture = hw.os.architecture if hw.os else None
snapshot.virtualization_type = hw.os.virtualization_type if hw.os else None
snapshot.screen_resolution = hw.os.screen_resolution if hw.os else None
snapshot.display_server = hw.os.display_server if hw.os else None
snapshot.session_type = hw.os.session_type if hw.os else None
snapshot.last_boot_time = hw.os.last_boot_time if hw.os else None
snapshot.uptime_seconds = hw.os.uptime_seconds if hw.os else None
snapshot.battery_percentage = hw.os.battery_percentage if hw.os else None
snapshot.battery_status = hw.os.battery_status if hw.os else None
snapshot.battery_health = hw.os.battery_health if hw.os else None
snapshot.hostname = hw.os.hostname if hw.os else None
snapshot.desktop_environment = hw.os.desktop_environment if hw.os else None
snapshot.motherboard_vendor = hw.motherboard.vendor if hw.motherboard else None
snapshot.motherboard_model = hw.motherboard.model if hw.motherboard else None
snapshot.bios_vendor = hw.motherboard.bios_vendor if hw.motherboard and hasattr(hw.motherboard, 'bios_vendor') else None
snapshot.bios_version = hw.motherboard.bios_version if hw.motherboard else None
snapshot.bios_date = hw.motherboard.bios_date if hw.motherboard else None
# PCI and USB Devices
snapshot.pci_devices_json = json.dumps([d.model_dump(by_alias=True) for d in hw.pci_devices]) if hw.pci_devices else None
snapshot.usb_devices_json = json.dumps([d.model_dump() for d in hw.usb_devices]) if hw.usb_devices else None
# Misc
snapshot.sensors_json = json.dumps(hw.sensors.dict()) if hw.sensors else None
snapshot.raw_info_json = json.dumps(hw.raw_info.dict()) if hw.raw_info else None
snapshot.sensors_json = json.dumps(hw.sensors.model_dump()) if hw.sensors else None
snapshot.raw_info_json = json.dumps(hw.raw_info.model_dump()) if hw.raw_info else None
# Add to session only if it's a new snapshot
if not existing_snapshot:
@@ -135,18 +163,61 @@ async def submit_benchmark(
# 3. Create benchmark
results = payload.results
# Calculate global score if not provided or recalculate
global_score = calculate_global_score(
cpu_score=results.cpu.score if results.cpu else None,
memory_score=results.memory.score if results.memory else None,
disk_score=results.disk.score if results.disk else None,
network_score=results.network.score if results.network else None,
gpu_score=results.gpu.score if results.gpu else None
)
# Recalculate scores from raw metrics using new formulas
cpu_score = None
cpu_score_single = None
cpu_score_multi = None
# Use provided global_score if available and valid
if results.global_score is not None:
global_score = results.global_score
if results.cpu:
# Use scores from script if available (preferred), otherwise calculate
if results.cpu.score_single is not None:
cpu_score_single = results.cpu.score_single
elif results.cpu.events_per_sec_single:
cpu_score_single = calculate_cpu_score(results.cpu.events_per_sec_single)
if results.cpu.score_multi is not None:
cpu_score_multi = results.cpu.score_multi
elif results.cpu.events_per_sec_multi:
cpu_score_multi = calculate_cpu_score(results.cpu.events_per_sec_multi)
# Use score from script if available, otherwise calculate
if results.cpu.score is not None:
cpu_score = results.cpu.score
elif results.cpu.events_per_sec_multi:
cpu_score = cpu_score_multi
elif results.cpu.events_per_sec:
cpu_score = calculate_cpu_score(results.cpu.events_per_sec)
memory_score = None
if results.memory and results.memory.throughput_mib_s:
memory_score = calculate_memory_score(results.memory.throughput_mib_s)
disk_score = None
if results.disk:
disk_score = calculate_disk_score(
read_mb_s=results.disk.read_mb_s,
write_mb_s=results.disk.write_mb_s
)
network_score = None
if results.network:
network_score = calculate_network_score(
upload_mbps=results.network.upload_mbps,
download_mbps=results.network.download_mbps
)
gpu_score = None
if results.gpu and results.gpu.glmark2_score:
gpu_score = calculate_gpu_score(results.gpu.glmark2_score)
# Calculate global score from recalculated component scores
global_score = calculate_global_score(
cpu_score=cpu_score,
memory_score=memory_score,
disk_score=disk_score,
network_score=network_score,
gpu_score=gpu_score
)
# Extract network results for easier frontend access
network_results = None
@@ -155,7 +226,7 @@ async def submit_benchmark(
"upload_mbps": results.network.upload_mbps if hasattr(results.network, 'upload_mbps') else None,
"download_mbps": results.network.download_mbps if hasattr(results.network, 'download_mbps') else None,
"ping_ms": results.network.ping_ms if hasattr(results.network, 'ping_ms') else None,
"score": results.network.score
"score": network_score
}
benchmark = Benchmark(
@@ -165,11 +236,13 @@ async def submit_benchmark(
bench_script_version=payload.bench_script_version,
global_score=global_score,
cpu_score=results.cpu.score if results.cpu else None,
memory_score=results.memory.score if results.memory else None,
disk_score=results.disk.score if results.disk else None,
network_score=results.network.score if results.network else None,
gpu_score=results.gpu.score if results.gpu else None,
cpu_score=cpu_score,
cpu_score_single=cpu_score_single,
cpu_score_multi=cpu_score_multi,
memory_score=memory_score,
disk_score=disk_score,
network_score=network_score,
gpu_score=gpu_score,
details_json=json.dumps(results.dict()),
network_results_json=json.dumps(network_results) if network_results else None
@@ -210,9 +283,54 @@ async def get_benchmark(
bench_script_version=benchmark.bench_script_version,
global_score=benchmark.global_score,
cpu_score=benchmark.cpu_score,
cpu_score_single=benchmark.cpu_score_single,
cpu_score_multi=benchmark.cpu_score_multi,
memory_score=benchmark.memory_score,
disk_score=benchmark.disk_score,
network_score=benchmark.network_score,
gpu_score=benchmark.gpu_score,
details=json.loads(benchmark.details_json)
details=json.loads(benchmark.details_json),
notes=benchmark.notes
)
@router.patch("/benchmarks/{benchmark_id}", response_model=BenchmarkSummary)
async def update_benchmark_entry(
benchmark_id: int,
payload: BenchmarkUpdate,
db: Session = Depends(get_db)
):
"""
Update editable benchmark fields (currently only notes).
"""
benchmark = db.query(Benchmark).filter(Benchmark.id == benchmark_id).first()
if not benchmark:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Benchmark {benchmark_id} not found"
)
update_data = payload.model_dump(exclude_unset=True)
if "notes" in update_data:
benchmark.notes = update_data["notes"]
db.add(benchmark)
db.commit()
db.refresh(benchmark)
return BenchmarkSummary(
id=benchmark.id,
run_at=benchmark.run_at.isoformat(),
global_score=benchmark.global_score,
cpu_score=benchmark.cpu_score,
cpu_score_single=benchmark.cpu_score_single,
cpu_score_multi=benchmark.cpu_score_multi,
memory_score=benchmark.memory_score,
disk_score=benchmark.disk_score,
network_score=benchmark.network_score,
gpu_score=benchmark.gpu_score,
bench_script_version=benchmark.bench_script_version,
notes=benchmark.notes
)