Files
Noxely/server/noxely_server/config.py
T
tuxgyver 51b60cda70 Appairage du téléphone, en-têtes de licence (2.1.0)
Recopier un jeton de trente-trois caractères sur un clavier tactile n'était pas
un réglage, c'était une corvée. On ouvre désormais une fenêtre depuis le
serveur, on appuie sur Appairer côté téléphone, et c'est fait.

Le jeton n'est pas pour autant distribué : ouvrir la fenêtre l'exige déjà,
elle dure deux minutes, se referme dès qu'un appareil s'est servi, et ne
répond qu'à une adresse privée. Le champ de saisie reste là pour qui préfère
le coller.

Les cinquante fichiers de code portent en outre leur notice de licence, comme
la GPL le recommande. Elle est en français, comme le reste ; le texte qui fait
foi demeure celui de LICENSE, non traduit.
2026-09-13 20:15:14 +02:00

78 lines
2.7 KiB
Python

# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
# Copyright © 2026 Johnny (tuxgyver)
#
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
# telle que publiée par la Free Software Foundation.
#
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
"""Configuration du serveur Noxely, lue de l'environnement.
Aucune valeur sensible n'est écrite dans le dépôt : le jeton et les chemins viennent d'un
fichier .env local, à l'image des autres services de la maison.
"""
from __future__ import annotations
import os
import secrets
from dataclasses import dataclass
from pathlib import Path
def _persisted_token(data_dir: Path) -> str:
"""Jeton auto-généré, conservé entre deux démarrages.
Un jeton tiré à chaque lancement obligerait à reconfigurer le téléphone après le moindre
redémarrage : il est donc écrit une fois, en lecture seule pour son propriétaire.
"""
path = data_dir / "token"
if path.exists():
existing = path.read_text().strip()
if existing:
return existing
token = secrets.token_urlsafe(24)
data_dir.mkdir(parents=True, exist_ok=True)
path.write_text(token + "\n")
path.chmod(0o600)
print(f"[noxely] jeton généré et conservé dans {path}")
return token
@dataclass(frozen=True)
class Config:
data_dir: Path
token: str
host: str
port: int
#: Nombre de stations balayées à chaque passage du guet.
watch_stations: int
#: Pause entre deux balayages, en secondes. Le balayage est continu : cette pause n'est
#: qu'un garde-fou pour ne pas marteler l'annuaire si un tour échoue instantanément.
watch_interval: int
#: Stations sondées en parallèle. Plus il est haut, plus un tour complet est bref.
watch_concurrency: int
@property
def media_dir(self) -> Path:
return self.data_dir / "media"
@property
def db_path(self) -> Path:
return self.data_dir / "noxely.sqlite3"
def load() -> Config:
data_dir = Path(os.environ.get("NOXELY_DATA", "./data")).expanduser().resolve()
token = os.environ.get("NOXELY_TOKEN", "").strip() or _persisted_token(data_dir)
return Config(
data_dir=data_dir,
token=token,
host=os.environ.get("NOXELY_HOST", "0.0.0.0"),
port=int(os.environ.get("NOXELY_PORT", "8710")),
watch_stations=int(os.environ.get("NOXELY_WATCH_STATIONS", "40")),
watch_interval=int(os.environ.get("NOXELY_WATCH_INTERVAL", "5")),
watch_concurrency=int(os.environ.get("NOXELY_WATCH_CONCURRENCY", "8")),
)