feat: add hidden files configuration with per-vault settings for includeHidden and hiddenWhitelist, supporting environment variables and UI controls for selective indexing of dot-prefixed files and folders
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Set
|
||||
import threading
|
||||
|
||||
from backend.indexer import _should_include_path
|
||||
|
||||
logger = logging.getLogger("obsigate.attachment_indexer")
|
||||
|
||||
@@ -34,7 +36,7 @@ def clear_resolution_cache(vault_name: Optional[str] = None) -> None:
|
||||
del _resolution_cache[key]
|
||||
|
||||
|
||||
def _scan_vault_attachments(vault_name: str, vault_path: str) -> Dict[str, List[Path]]:
|
||||
def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict = None) -> Dict[str, List[Path]]:
|
||||
"""Synchronously scan a vault directory for image attachments.
|
||||
|
||||
Walks the vault tree and builds a filename -> absolute path mapping
|
||||
@@ -43,6 +45,7 @@ def _scan_vault_attachments(vault_name: str, vault_path: str) -> Dict[str, List[
|
||||
Args:
|
||||
vault_name: Display name of the vault.
|
||||
vault_path: Absolute filesystem path to the vault root.
|
||||
vault_cfg: Optional vault configuration dict with hidden files settings.
|
||||
|
||||
Returns:
|
||||
Dict mapping lowercase filenames to lists of absolute paths.
|
||||
@@ -50,6 +53,10 @@ def _scan_vault_attachments(vault_name: str, vault_path: str) -> Dict[str, List[
|
||||
vault_root = Path(vault_path)
|
||||
index: Dict[str, List[Path]] = {}
|
||||
|
||||
# Default config if not provided
|
||||
if vault_cfg is None:
|
||||
vault_cfg = {"includeHidden": False, "hiddenWhitelist": []}
|
||||
|
||||
if not vault_root.exists():
|
||||
logger.warning(f"Vault path does not exist for attachment scan: {vault_path}")
|
||||
return index
|
||||
@@ -58,9 +65,9 @@ def _scan_vault_attachments(vault_name: str, vault_path: str) -> Dict[str, List[
|
||||
|
||||
try:
|
||||
for fpath in vault_root.rglob("*"):
|
||||
# Skip hidden files and directories
|
||||
# Check if path should be included based on hidden files configuration
|
||||
rel_parts = fpath.relative_to(vault_root).parts
|
||||
if any(part.startswith(".") for part in rel_parts):
|
||||
if not _should_include_path(rel_parts, vault_cfg):
|
||||
continue
|
||||
|
||||
# Only process files
|
||||
@@ -121,7 +128,7 @@ async def build_attachment_index(vault_config: Dict[str, Dict[str, any]]) -> Non
|
||||
new_index[name] = {}
|
||||
continue
|
||||
|
||||
tasks.append((name, loop.run_in_executor(None, _scan_vault_attachments, name, vault_path)))
|
||||
tasks.append((name, loop.run_in_executor(None, _scan_vault_attachments, name, vault_path, config)))
|
||||
|
||||
for name, task in tasks:
|
||||
new_index[name] = await task
|
||||
@@ -136,18 +143,19 @@ async def build_attachment_index(vault_config: Dict[str, Dict[str, any]]) -> Non
|
||||
logger.info(f"Attachment index built: {len(attachment_index)} vaults, {total_attachments} total attachments")
|
||||
|
||||
|
||||
async def rescan_vault_attachments(vault_name: str, vault_path: str) -> int:
|
||||
async def rescan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict = None) -> int:
|
||||
"""Rescan attachments for a single vault.
|
||||
|
||||
Args:
|
||||
vault_name: Name of the vault to rescan.
|
||||
vault_path: Absolute path to the vault root.
|
||||
vault_cfg: Optional vault configuration dict with hidden files settings.
|
||||
|
||||
Returns:
|
||||
Number of attachments indexed.
|
||||
"""
|
||||
loop = asyncio.get_event_loop()
|
||||
new_vault_index = await loop.run_in_executor(None, _scan_vault_attachments, vault_name, vault_path)
|
||||
new_vault_index = await loop.run_in_executor(None, _scan_vault_attachments, vault_name, vault_path, vault_cfg)
|
||||
|
||||
with _attachment_lock:
|
||||
attachment_index[vault_name] = new_vault_index
|
||||
|
||||
Reference in New Issue
Block a user