mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
Captures : légères, plafonnées, et supprimées avec leur discussion
Trois causes d'encombrement traitées : - JPEG au lieu de PNG (Playwright déduit le format de l'extension). Sur une vraie page web — photos, dégradés — le JPEG pèse 3 à 10 fois moins ; le PNG ne gagnait que sur les aplats, cas minoritaire ici. - Pleine page DÉSACTIVÉE par défaut : un article long capturé en entier fait plusieurs milliers de pixels de haut, donc plusieurs Mo, alors que « montre cette page » veut presque toujours dire le premier écran. Le modèle peut toujours demander full_page. - Ménage automatique : au plus 20 captures et 40 Mo par discussion, les plus anciennes partant en premier. La capture qui vient d'être prise n'est JAMAIS supprimée — une capture plus lourde que le plafond se serait effacée elle-même, et le modèle aurait renvoyé un lien mort. Les captures sont désormais rangées PAR DISCUSSION (captures/<id>/…) : supprimer une discussion, ou la vider, emporte ses images. Sans ce rangement, des fichiers que plus aucun message n'affiche restaient sur le disque. Tests : ménage (nombre et octets), survie de la capture courante, et suppression qui n'emporte que les captures de la discussion visée.
This commit is contained in:
4 files changed
+194
-8
No files matched your search
@@ -0,0 +1,95 @@
|
||||
package loki
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Le dossier de captures ne doit pas croître sans fin — mais la capture qui
|
||||
// vient d'être prise doit survivre au ménage, même seule et plus lourde que le
|
||||
// plafond : sinon le modèle renvoie à l'utilisateur un lien vers un fichier que
|
||||
// pruneCaptures a effacé dans la foulée.
|
||||
func TestPruneCapturesGardeLaDerniere(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
// 25 captures d'âges croissants, au-delà du plafond en NOMBRE.
|
||||
var last string
|
||||
for i := 0; i < 25; i++ {
|
||||
p := filepath.Join(dir, fmt.Sprintf("shot-%02d.jpg", i))
|
||||
if err := os.WriteFile(p, []byte("x"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// mtime croissant : shot-00 est la plus ancienne.
|
||||
mt := time.Now().Add(time.Duration(i-25) * time.Minute)
|
||||
if err := os.Chtimes(p, mt, mt); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
last = p
|
||||
}
|
||||
pruneCaptures(dir, last)
|
||||
|
||||
ents, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(ents) != maxCaptureFiles {
|
||||
t.Fatalf("%d fichiers restants, attendu %d", len(ents), maxCaptureFiles)
|
||||
}
|
||||
if _, err := os.Stat(last); err != nil {
|
||||
t.Fatalf("la capture la plus récente a été supprimée : %v", err)
|
||||
}
|
||||
// Les plus anciennes doivent être parties, pas les récentes.
|
||||
if _, err := os.Stat(filepath.Join(dir, "shot-00.jpg")); err == nil {
|
||||
t.Fatal("la capture la plus ancienne aurait dû être supprimée")
|
||||
}
|
||||
}
|
||||
|
||||
// Supprimer une discussion doit emporter ses captures : sans ça, des images que
|
||||
// plus aucun message n'affiche restent sur le disque pour toujours. Et elle ne
|
||||
// doit emporter QUE les siennes.
|
||||
func TestConvDeleteSupprimeLesCaptures(t *testing.T) {
|
||||
t.Setenv("LOKI_HOME", t.TempDir())
|
||||
|
||||
a := convEnsureActive()
|
||||
b := convNew() // b devient active, a reste
|
||||
|
||||
shot := func(id string) string {
|
||||
dir, _ := captureDirFor(id)
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p := filepath.Join(dir, "vue.jpg")
|
||||
if err := os.WriteFile(p, []byte("jpeg"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return p
|
||||
}
|
||||
shotA, shotB := shot(a), shot(b)
|
||||
|
||||
if err := convDelete(a); err != nil {
|
||||
t.Fatalf("suppression de la discussion : %v", err)
|
||||
}
|
||||
if _, err := os.Stat(shotA); err == nil {
|
||||
t.Fatal("la capture de la discussion supprimée est toujours là")
|
||||
}
|
||||
if _, err := os.Stat(shotB); err != nil {
|
||||
t.Fatalf("la capture d'une AUTRE discussion a été supprimée : %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Une capture unique plus lourde que le plafond en OCTETS ne doit pas s'effacer
|
||||
// elle-même : il ne resterait alors rien à montrer.
|
||||
func TestPruneCapturesNEffacePasUneCaptureUniqueTropLourde(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
p := filepath.Join(dir, "enorme.jpg")
|
||||
if err := os.WriteFile(p, make([]byte, maxCaptureBytes+1), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pruneCaptures(dir, p)
|
||||
if _, err := os.Stat(p); err != nil {
|
||||
t.Fatalf("la capture courante a été supprimée : %v", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user