diff --git a/CHANGELOG.md b/CHANGELOG.md index ba052ce..8ca37ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > **En cours de développement** : les changements à venir sont listés dans la section -> [Unreleased](#unreleased). La dernière version livrée est **2.17.0**. +> [Unreleased](#unreleased). La dernière version livrée est **2.18.0**. --- @@ -14,6 +14,29 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +## [2.18.0] — 2026-09-23 + +### Ajouté + +- **#109 — Support audio & vidéo (lecteurs HTML5 intégrés)** : les fichiers audio + (`.mp3 .m4a .aac .wav .ogg .oga .opus .flac`) et vidéo (`.mp4 .webm .mov .m4v`) + apparaissent désormais dans l'arborescence et l'index (nom/taille/date + uniquement, contenu jamais lu, intégrés à `SUPPORTED_EXTENSIONS` via + `media_types.py`). Nouvel endpoint `GET /api/media/{vault}?path=…` avec support + HTTP `Range` / `206 Partial Content` (`Content-Range`, `Accept-Ranges`, `416` + sur plage invalide, `413` au-delà de `OBSIGATE_MEDIA_MAX_INLINE_MB`, défaut + 500 Mo) — le helper Range de `pdf/stream` a été extrait en + `_stream_file_with_range()` et est partagé. `api_file_view()` expose + `is_audio`/`is_video`/`stream_url`/`media_mime` avant toute lecture texte. + Frontend : lecteur audio dédié (artwork, durée via `loadedmetadata`) et lecteur + vidéo (`playsinline`, scène noire letterboxée), icônes Lucide `audio-lines` / + `video`, pause à la réinitialisation de la vue, repli téléchargement si le codec + n'est pas lisible ou le fichier trop volumineux. Les médias sont exclus du + contexte textuel BooksLM et du cache hors-ligne du service worker. Fiche : + [docs/features/media-viewers-109.md](docs/features/media-viewers-109.md). + +--- + ## [2.17.0] — 2026-09-23 ### Ajouté diff --git a/README.fr.md b/README.fr.md index 19e8b5c..2195fa1 100644 --- a/README.fr.md +++ b/README.fr.md @@ -4,7 +4,7 @@ **Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive. -[![Version](https://img.shields.io/badge/Version-2.17.0-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.18.0-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -83,6 +83,7 @@ Les **guides d'utilisation** pas à pas se trouvent dans [`docs/GUIDES/`](docs/G - **🏷️ Tag cloud** : Filtrage par tags extraits des frontmatters YAML - **🔗 Wikilinks** : Les `[[liens internes]]` Obsidian sont cliquables - **🖼️ Images Obsidian** : Support complet des syntaxes d'images Obsidian avec résolution intelligente +- **🎬 Audio & vidéo** : Lecteurs HTML5 intégrés (`.mp3 .wav .flac .mp4 .webm`…) avec streaming HTTP Range (lecture, déplacement, plein écran), repli téléchargement si le format n'est pas lisible par le navigateur - **🎨 Diagrammes Excalidraw** : Visualiseur/éditeur natif des fichiers `.excalidraw` et `.excalidraw.md` (iframe sandboxée, auto-save, thème clair/sombre, texte des diagrammes indexé pour la recherche) - **🎨 Syntax highlight** : Coloration syntaxique des blocs de code - **🌓 Thème clair/sombre** : Toggle persisté en localStorage @@ -296,6 +297,7 @@ Un compte **admin** connecté voit une icône 🛡️ dans le header : liste, cr | `OBSIGATE_WEBHOOK_ALLOW_HTTP` | Autoriser les webhooks non HTTPS | `false` | | `OBSIGATE_WEBHOOK_ALLOW_PRIVATE` | Autoriser les webhooks vers des adresses privées/boucle | `false` | | `OBSIGATE_PDF_MAX_SIZE_MB` | Taille max des PDF extraits (text indexation) | `50` | +| `OBSIGATE_MEDIA_MAX_INLINE_MB` | Taille max pour la lecture audio/vidéo intégrée (au-delà : téléchargement) | `500` | | `OBSIGATE_PDF_EXTRACT_TIMEOUT` | Timeout extraction PDF (secondes) | `30` | | `OBSIGATE_TAVILY_API_KEY` / `OBSIGATE_BRAVE_API_KEY` / `OBSIGATE_SERPAPI_API_KEY` / `OBSIGATE_EXA_API_KEY` | Fournisseurs de recherche web à clé (essayés avant SearXNG) | — | | `OBSIGATE_WEB_PROVIDERS` | Ordre des fournisseurs de recherche (ex. `brave,searxng`) | — | @@ -964,8 +966,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l ## 📝 Changelog -Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.17.0). +Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.18.0). --- -*Projet : ObsiGate | Version : 2.17.0 | Dernière mise à jour : Septembre 2026* +*Projet : ObsiGate | Version : 2.18.0 | Dernière mise à jour : Septembre 2026* diff --git a/README.md b/README.md index dff25a9..3f267d5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface. -[![Version](https://img.shields.io/badge/Version-2.17.0-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.18.0-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -82,6 +82,7 @@ Step-by-step **user guides** live in [`docs/GUIDES/`](docs/GUIDES/): - **🏷️ Tag Cloud** : Filtering by tags extracted from YAML frontmatters - **🔗 Wikilinks** : `[[internal links]]` from Obsidian are clickable - **🖼️ Obsidian Images** : Full support for all Obsidian image syntaxes with intelligent resolution +- **🎬 Audio & video** : Built-in HTML5 players (`.mp3 .wav .flac .mp4 .webm`…) with HTTP Range streaming (play, seek, fullscreen), falling back to download when the format is not playable in the browser - **🎨 Excalidraw Diagrams** : Native viewer/editor for `.excalidraw` and `.excalidraw.md` files (sandboxed iframe, autosave, dark/light theme, diagram text indexed for search) - **🎨 Syntax Highlight** : Syntax highlighting for code blocks - **🌓 Light/Dark Theme** : Toggle persisted in localStorage @@ -340,6 +341,7 @@ When an **admin** account is logged in, a 🛡️ icon appears in the header. Cl | `OBSIGATE_WEBHOOK_ALLOW_HTTP` | Allow non-HTTPS webhook targets | `false` | | `OBSIGATE_WEBHOOK_ALLOW_PRIVATE` | Allow webhooks to private/loopback addresses | `false` | | `OBSIGATE_PDF_MAX_SIZE_MB` | Max PDF size for text extraction | `50` | +| `OBSIGATE_MEDIA_MAX_INLINE_MB` | Max size for inline audio/video playback (above: download) | `500` | | `OBSIGATE_PDF_EXTRACT_TIMEOUT` | PDF extraction timeout (seconds) | `30` | | `OBSIGATE_TAVILY_API_KEY` / `OBSIGATE_BRAVE_API_KEY` / `OBSIGATE_SERPAPI_API_KEY` / `OBSIGATE_EXA_API_KEY` | Keyed web-search providers (tried before SearXNG) | — | | `OBSIGATE_WEB_PROVIDERS` | Search provider order (e.g. `brave,searxng`) | — | @@ -1140,8 +1142,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) ## 📝 Changelog -See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.17.0). +See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.18.0). --- -*Project: ObsiGate | Version: 2.17.0 | Last updated: September 2026* +*Project: ObsiGate | Version: 2.18.0 | Last updated: September 2026* diff --git a/VERSION b/VERSION index d76bd2b..cf86907 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.17.0 +2.18.0 diff --git a/backend/bookslm.py b/backend/bookslm.py index 0b57126..b0382e7 100644 --- a/backend/bookslm.py +++ b/backend/bookslm.py @@ -15,6 +15,7 @@ import time from pathlib import Path from typing import Any +from backend.media_types import is_media from backend.secret_redactor import redact_file_content logger = logging.getLogger("obsigate.bookslm") @@ -185,6 +186,10 @@ def collect_directory_context(vault_path: Path, directory: str) -> dict[str, Any def _file_entry(target: Path, rel_path: str, remaining: int) -> dict[str, Any] | None: """Read, redact and truncate a single file into a context entry.""" suffix = target.suffix.lower() + # #109-D3 — audio/video (and images) carry no extractable text; never feed + # raw bytes to the model. Images are handled separately via vision data URLs. + if is_media(suffix): + return None try: if suffix == ".pdf": from backend.pdf_reader import extract_pdf_text diff --git a/backend/indexer.py b/backend/indexer.py index 79a4c0e..c023489 100644 --- a/backend/indexer.py +++ b/backend/indexer.py @@ -11,7 +11,7 @@ from typing import Any import frontmatter -from backend.media_types import IMAGE_EXTENSIONS, is_media +from backend.media_types import AUDIO_EXTENSIONS, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, is_media logger = logging.getLogger("obsigate.indexer") @@ -71,7 +71,7 @@ SUPPORTED_EXTENSIONS = { ".dockerfile", ".makefile", ".cmake", ".excalidraw", ".excalidraw.md", -} | set(IMAGE_EXTENSIONS) +} | set(IMAGE_EXTENSIONS) | set(AUDIO_EXTENSIONS) | set(VIDEO_EXTENSIONS) # Ignored directories (configurable via OBSIGATE_IGNORED_DIRS env var) diff --git a/backend/main.py b/backend/main.py index 0053f02..9d4a0bf 100644 --- a/backend/main.py +++ b/backend/main.py @@ -53,7 +53,7 @@ from backend.indexer import ( update_single_file, ) from backend.media_thumbs import generate_thumbnail, is_decodable -from backend.media_types import IMAGE_EXTENSIONS, is_image, media_mime_type +from backend.media_types import IMAGE_EXTENSIONS, is_audio, is_image, is_video, media_mime_type from backend.openapi_docs import ( API_DESCRIPTION, TAGS_METADATA, @@ -205,6 +205,11 @@ class FileContentResponse(BaseModel): size_bytes: int | None = Field(default=None, description="File size in bytes (for unsupported files)") is_pdf: bool | None = Field(default=None, description="True for PDF files") is_image: bool | None = Field(default=None, description="True for image files") + is_audio: bool | None = Field(default=None, description="True for audio files (HTML5