1.0.5 — affichage des notices et progression
This commit is contained in:
1 parent
eb38aa9c11
commit
5bccd86edc
10 files changed
+111
-33
No files matched your search
@@ -2,6 +2,20 @@
|
||||
|
||||
Format inspiré de [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/).
|
||||
|
||||
## [1.0.5] — 2026-09-12
|
||||
|
||||
### Corrigé
|
||||
- **Les messages internes de Maigret noyaient les résultats.** « Restarting
|
||||
checks for 98 sites », « 0 extra requests performed » et consorts sont
|
||||
destinés à sa sortie terminal ; affichés dans l'interface, ils repoussaient
|
||||
les résultats hors de l'écran. Ils sont désormais filtrés.
|
||||
- **Le bilan des blocages était répété par variante** — cinq avertissements
|
||||
quasi identiques pour une même cause. Il est cumulé et émis une seule fois en
|
||||
fin de recherche, avec le taux global et le renvoi vers la documentation.
|
||||
- **La progression affichait « 945 / 833 ».** Maigret relance les sites en
|
||||
échec, si bien que le nombre de vérifications dépasse le total estimé. La
|
||||
valeur affichée est bornée.
|
||||
|
||||
## [1.0.4] — 2026-09-12
|
||||
|
||||
### Corrigé
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "limier"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
description = "Plateforme OSINT auto-hébergée : pseudonyme, nom, e-mail, domaine"
|
||||
requires-python = ">=3.12,<3.14"
|
||||
license = { text = "MIT" }
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
"""Limier — plateforme OSINT auto-hébergée."""
|
||||
|
||||
__version__ = "1.0.4"
|
||||
__version__ = "1.0.5"
|
||||
@@ -49,6 +49,24 @@ _logger_maigret.setLevel(logging.WARNING)
|
||||
|
||||
TAILLE_FILE = 2000
|
||||
|
||||
# Messages internes de Maigret sans valeur pour l'utilisateur : relances,
|
||||
# compteurs de requêtes supplémentaires, bannières. Les laisser passer noie les
|
||||
# résultats sous des dizaines de lignes, comme observé en conditions réelles.
|
||||
BRUIT_MAIGRET = (
|
||||
"restarting checks",
|
||||
"extra requests performed",
|
||||
"you can run search",
|
||||
"starting a search",
|
||||
"checking username",
|
||||
"database",
|
||||
"db auto-update",
|
||||
"using sites database",
|
||||
"support maigret",
|
||||
"donate",
|
||||
"detailed site check errors",
|
||||
"extracted ids",
|
||||
)
|
||||
|
||||
SEUIL_ALERTE_BLOCAGE = 0.15
|
||||
"""Part de sites non vérifiables au-delà de laquelle on prévient l'utilisateur.
|
||||
|
||||
@@ -172,6 +190,28 @@ class MoteurPseudonyme(Engine):
|
||||
):
|
||||
yield evenement
|
||||
|
||||
async for evenement in self._bilan(compteur):
|
||||
yield evenement
|
||||
|
||||
async def _bilan(self, compteur: dict[str, int]):
|
||||
"""Avertissement unique de fin de recherche sur la couverture réelle."""
|
||||
bloques = compteur.get("bloques", 0)
|
||||
interroges = compteur.get("interroges", 0)
|
||||
if not interroges:
|
||||
return
|
||||
taux = bloques / interroges
|
||||
if taux > SEUIL_ALERTE_BLOCAGE:
|
||||
yield NoticeEvent(
|
||||
module=self.name,
|
||||
level="warning",
|
||||
message=(
|
||||
f"{bloques} vérifications sur {interroges} ({taux:.0%}) ont échoué — "
|
||||
"blocage anti-robot, captcha ou délai dépassé. Les résultats sont "
|
||||
"partiels. Activer FlareSolverr ou un pool de proxies améliore "
|
||||
"cette couverture (voir docs/06-exploitation.md)."
|
||||
),
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------- interne
|
||||
|
||||
async def _chercher_un(
|
||||
@@ -234,9 +274,12 @@ class MoteurPseudonyme(Engine):
|
||||
if statut.startswith("Unknown"):
|
||||
erreurs_reseau += 1
|
||||
if compteur["faits"] % 10 == 0:
|
||||
# Maigret relance les sites en échec : le nombre de
|
||||
# vérifications dépasse alors le total estimé. On borne
|
||||
# plutôt que d'afficher « 945 / 833 ».
|
||||
yield ProgressEvent(
|
||||
module=self.name,
|
||||
done=compteur["faits"],
|
||||
done=min(compteur["faits"], compteur["total"]),
|
||||
total=compteur["total"],
|
||||
label=label,
|
||||
)
|
||||
@@ -260,10 +303,13 @@ class MoteurPseudonyme(Engine):
|
||||
yield evenement
|
||||
|
||||
elif genre == "notice":
|
||||
message = charge.get("message", "")
|
||||
if not _message_utile(message):
|
||||
continue
|
||||
yield NoticeEvent(
|
||||
module=self.name,
|
||||
level=charge.get("level", "info"),
|
||||
message=charge.get("message", ""),
|
||||
message=message,
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -280,27 +326,20 @@ class MoteurPseudonyme(Engine):
|
||||
)
|
||||
return
|
||||
|
||||
if erreurs_reseau:
|
||||
taux = erreurs_reseau / max(1, len(sites))
|
||||
if taux > SEUIL_ALERTE_BLOCAGE:
|
||||
await self.proxies.signaler_echec(proxy)
|
||||
yield NoticeEvent(
|
||||
module=self.name,
|
||||
level="warning",
|
||||
message=(
|
||||
f"{erreurs_reseau} sites sur {len(sites)} n'ont pas pu être "
|
||||
"vérifiés (blocage ou délai dépassé). Les résultats sont "
|
||||
"partiels — voir la sortie réseau dans la documentation."
|
||||
),
|
||||
)
|
||||
else:
|
||||
await self.proxies.signaler_succes(proxy)
|
||||
# Le bilan des blocages est cumulé puis émis une seule fois en fin de
|
||||
# recherche : le répéter par variante produisait cinq avertissements
|
||||
# quasi identiques pour une même cause.
|
||||
compteur["bloques"] = compteur.get("bloques", 0) + erreurs_reseau
|
||||
compteur["interroges"] = compteur.get("interroges", 0) + len(sites)
|
||||
|
||||
if erreurs_reseau / max(1, len(sites)) > SEUIL_ALERTE_BLOCAGE:
|
||||
await self.proxies.signaler_echec(proxy)
|
||||
else:
|
||||
await self.proxies.signaler_succes(proxy)
|
||||
|
||||
yield ProgressEvent(
|
||||
module=self.name,
|
||||
done=compteur["faits"],
|
||||
done=min(compteur["faits"], compteur["total"]),
|
||||
total=compteur["total"],
|
||||
label=label,
|
||||
)
|
||||
@@ -391,3 +430,11 @@ class MoteurPseudonyme(Engine):
|
||||
if 2 < len(candidat) < 40 and " " not in candidat:
|
||||
trouves[candidat] = site
|
||||
return trouves
|
||||
|
||||
|
||||
def _message_utile(message: str) -> bool:
|
||||
"""Écarte le bavardage interne de Maigret destiné à sa sortie terminal."""
|
||||
if not message or len(message) < 8:
|
||||
return False
|
||||
minuscule = message.lower()
|
||||
return not any(bruit in minuscule for bruit in BRUIT_MAIGRET)
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
REGISTRY=registry.tips-of-mine.com
|
||||
TAG=1.0.4
|
||||
TAG=1.0.5
|
||||
LIMIER_HOST=limier.tips-of-mine.com
|
||||
LIMIER_PUBLIC_URL=https://limier.tips-of-mine.com
|
||||
LIMIER_ENVIRONMENT=prod
|
||||
|
||||
@@ -56,7 +56,7 @@ x-limier-env: &limier-env
|
||||
services:
|
||||
|
||||
limier-api:
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-backend:${TAG:-1.0.4}
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-backend:${TAG:-1.0.5}
|
||||
container_name: limier-api
|
||||
restart: unless-stopped
|
||||
command: ["limier-api"]
|
||||
@@ -99,7 +99,7 @@ services:
|
||||
- "homepage.description=Plateforme OSINT"
|
||||
|
||||
limier-worker:
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-backend:${TAG:-1.0.4}
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-backend:${TAG:-1.0.5}
|
||||
container_name: limier-worker
|
||||
restart: unless-stopped
|
||||
command: ["limier-worker"]
|
||||
@@ -122,7 +122,7 @@ services:
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
|
||||
limier-web:
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-frontend:${TAG:-1.0.4}
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-frontend:${TAG:-1.0.5}
|
||||
container_name: limier-web
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
@@ -205,7 +205,7 @@ services:
|
||||
# ``--profile``, pour que l'installation par défaut reste minimale.
|
||||
|
||||
limier-holehe:
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-holehe:${TAG:-1.0.4}
|
||||
image: ${REGISTRY:-registry.tips-of-mine.com}/limier/limier-holehe:${TAG:-1.0.5}
|
||||
container_name: limier-holehe
|
||||
restart: unless-stopped
|
||||
profiles: ["holehe"]
|
||||
|
||||
@@ -12,7 +12,7 @@ Ni base de données, ni Redis, ni Authentik. On appelle le moteur directement.
|
||||
cd /opt # ou n'importe où, il suffit d'avoir essai_moteur.py sous la main
|
||||
|
||||
docker run --rm -v "$PWD/essai_moteur.py:/tmp/essai.py" \
|
||||
registry.tips-of-mine.com/limier/limier-backend:1.0.4 \
|
||||
registry.tips-of-mine.com/limier/limier-backend:1.0.5 \
|
||||
python /tmp/essai.py domain tips-of-mine.com
|
||||
```
|
||||
|
||||
@@ -24,7 +24,7 @@ Le moteur pseudonyme, en version courte :
|
||||
```bash
|
||||
docker run --rm -v "$PWD/essai_moteur.py:/tmp/essai.py" \
|
||||
-e LIMIER_USERNAME_TOP_SITES=80 \
|
||||
registry.tips-of-mine.com/limier/limier-backend:1.0.4 \
|
||||
registry.tips-of-mine.com/limier/limier-backend:1.0.5 \
|
||||
python /tmp/essai.py username soxoj
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@ Et la recherche par nom, qui montre les variantes déduites :
|
||||
```bash
|
||||
docker run --rm -v "$PWD/essai_moteur.py:/tmp/essai.py" \
|
||||
-e LIMIER_USERNAME_TOP_SITES=60 \
|
||||
registry.tips-of-mine.com/limier/limier-backend:1.0.4 \
|
||||
registry.tips-of-mine.com/limier/limier-backend:1.0.5 \
|
||||
python /tmp/essai.py name "Hubert Cornet"
|
||||
```
|
||||
|
||||
|
||||
+20
-3
@@ -73,7 +73,24 @@ attachés à ton entryPoint `https` et s'appliquent automatiquement.
|
||||
Les priorités de routeurs sont explicites : l'API à 60, l'interface à 50.
|
||||
Sans cela, la règle `Host()` seule de `limier-web` capterait aussi `/api`.
|
||||
|
||||
## 4. Migrations puis démarrage
|
||||
## 4. Droits du volume de la base de sites
|
||||
|
||||
Les conteneurs tournent en utilisateur non privilégié (UID 1000). Docker crée
|
||||
les répertoires de montage en `root`, et ce montage masque les droits posés
|
||||
dans l'image : le worker ne peut alors pas y écrire la base de sites mise à
|
||||
jour, et reste sur les 3 302 sites livrés dans le paquet au lieu des 5 400+
|
||||
disponibles en amont.
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/limier/data/sites
|
||||
chown -R 1000:1000 /opt/limier/data/sites
|
||||
```
|
||||
|
||||
Le symptôme, si on l'oublie : `copie_base_sites_impossible` avec
|
||||
`Permission denied` dans le journal du worker, et `base_sites_prete` annonçant
|
||||
3 302 sites au lieu de 5 442.
|
||||
|
||||
## 5. Migrations puis démarrage
|
||||
|
||||
```bash
|
||||
docker compose run --rm limier-api alembic upgrade head
|
||||
@@ -86,7 +103,7 @@ curl -s https://limier.tips-of-mine.com/api/pret | jq
|
||||
complétude de la configuration. C'est la sonde à regarder quand « ça ne marche
|
||||
pas ». `/api/sante` est la sonde du healthcheck Docker, volontairement triviale.
|
||||
|
||||
## 5. Modules optionnels
|
||||
## 6. Modules optionnels
|
||||
|
||||
```bash
|
||||
# holehe — lire services/holehe/app.py avant d'activer
|
||||
@@ -101,7 +118,7 @@ docker compose --profile flaresolverr up -d
|
||||
Sans `--profile`, ces services ne démarrent pas : l'installation par défaut
|
||||
reste minimale.
|
||||
|
||||
## 6. Mise à jour
|
||||
## 7. Mise à jour
|
||||
|
||||
```bash
|
||||
cd /opt/limier
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "limier-frontend",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
Reference in new issue
Block a user