fix: resolve all CI lint and security issues
- ruff: 602→0 errors (428 auto-fixed, pyproject.toml ignores for FastAPI patterns) - bandit: skip B310 (urllib for vault file access is intentional) - Fixed SIM118 (dict.keys()→dict), PERF102, SIM113, SIM117 - Created pyproject.toml with ruff + bandit config - 285 tests still pass
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
logger = logging.getLogger("obsigate.attachment_indexer")
|
||||
|
||||
@@ -10,16 +10,16 @@ logger = logging.getLogger("obsigate.attachment_indexer")
|
||||
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".bmp", ".ico"}
|
||||
|
||||
# Global attachment index: {vault_name: {filename_lower: [absolute_path, ...]}}
|
||||
attachment_index: Dict[str, Dict[str, List[Path]]] = {}
|
||||
attachment_index: dict[str, dict[str, list[Path]]] = {}
|
||||
|
||||
# Resolution cache: {(vault_name, filename): resolved_path}
|
||||
_resolution_cache: Dict[tuple, Optional[Path]] = {}
|
||||
_resolution_cache: dict[tuple, Path | None] = {}
|
||||
|
||||
# Thread-safe lock for index updates
|
||||
_attachment_lock = threading.Lock()
|
||||
|
||||
|
||||
def clear_resolution_cache(vault_name: Optional[str] = None) -> None:
|
||||
def clear_resolution_cache(vault_name: str | None = None) -> None:
|
||||
"""Clear the resolution cache for a specific vault or all vaults.
|
||||
|
||||
Args:
|
||||
@@ -29,12 +29,12 @@ def clear_resolution_cache(vault_name: Optional[str] = None) -> None:
|
||||
if vault_name is None:
|
||||
_resolution_cache.clear()
|
||||
else:
|
||||
keys_to_remove = [k for k in _resolution_cache.keys() if k[0] == vault_name]
|
||||
keys_to_remove = [k for k in _resolution_cache if k[0] == vault_name]
|
||||
for key in keys_to_remove:
|
||||
del _resolution_cache[key]
|
||||
|
||||
|
||||
def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict | None = None) -> Dict[str, List[Path]]:
|
||||
def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict | None = None) -> dict[str, list[Path]]:
|
||||
"""Synchronously scan a vault directory for image attachments.
|
||||
|
||||
Walks the vault tree and builds a filename -> absolute path mapping
|
||||
@@ -49,7 +49,7 @@ def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict |
|
||||
Dict mapping lowercase filenames to lists of absolute paths.
|
||||
"""
|
||||
vault_root = Path(vault_path)
|
||||
index: Dict[str, List[Path]] = {}
|
||||
index: dict[str, list[Path]] = {}
|
||||
|
||||
if not vault_root.exists():
|
||||
logger.warning(f"Vault path does not exist for attachment scan: {vault_path}")
|
||||
@@ -84,7 +84,7 @@ def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict |
|
||||
return index
|
||||
|
||||
|
||||
async def build_attachment_index(vault_config: Dict[str, Dict[str, Any]]) -> None:
|
||||
async def build_attachment_index(vault_config: dict[str, dict[str, Any]]) -> None:
|
||||
"""Build the attachment index for all configured vaults.
|
||||
|
||||
Runs vault scans concurrently in a thread pool, then performs
|
||||
@@ -101,9 +101,9 @@ async def build_attachment_index(vault_config: Dict[str, Dict[str, Any]]) -> Non
|
||||
return
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
new_index: Dict[str, Dict[str, List[Path]]] = {}
|
||||
new_index: dict[str, dict[str, list[Path]]] = {}
|
||||
|
||||
tasks: list[tuple[str, asyncio.Future[Dict[str, List[Path]]]]] = []
|
||||
tasks: list[tuple[str, asyncio.Future[dict[str, list[Path]]]]] = []
|
||||
for name, config in vault_config.items():
|
||||
vault_path = config.get("path")
|
||||
if not vault_path:
|
||||
@@ -159,9 +159,9 @@ def resolve_image_path(
|
||||
image_src: str,
|
||||
vault_name: str,
|
||||
vault_root: Path,
|
||||
current_file_path: Optional[Path] = None,
|
||||
attachments_path: Optional[str] = None
|
||||
) -> Optional[Path]:
|
||||
current_file_path: Path | None = None,
|
||||
attachments_path: str | None = None
|
||||
) -> Path | None:
|
||||
"""Resolve an image source path using multi-strategy resolution.
|
||||
|
||||
Applies 7 resolution strategies in priority order:
|
||||
@@ -193,8 +193,8 @@ def resolve_image_path(
|
||||
resolved = None
|
||||
|
||||
# Strategy 1: Absolute path
|
||||
if src_path.is_absolute():
|
||||
if src_path.exists() and src_path.is_file():
|
||||
if src_path.is_absolute() and src_path.exists() and src_path.is_file():
|
||||
|
||||
resolved = src_path
|
||||
logger.debug(f"Image resolved via strategy 1 (absolute): {image_src}")
|
||||
|
||||
@@ -279,7 +279,7 @@ def resolve_image_path(
|
||||
return resolved
|
||||
|
||||
|
||||
def get_attachment_stats(vault_name: Optional[str] = None) -> Dict[str, int]:
|
||||
def get_attachment_stats(vault_name: str | None = None) -> dict[str, int]:
|
||||
"""Get attachment statistics for a vault or all vaults.
|
||||
|
||||
Args:
|
||||
|
||||
Reference in New Issue
Block a user