use logger

This commit is contained in:
Gamosoft 2026-06-30 16:32:41 +02:00
parent 0ca2211f69
commit e341ef423e
5 changed files with 39 additions and 26 deletions

View File

@ -8,6 +8,7 @@ replaced with placeholder HTML since they would make exports too large.
""" """
import base64 import base64
import logging
import re import re
from pathlib import Path from pathlib import Path
from typing import Optional, Tuple from typing import Optional, Tuple
@ -16,6 +17,8 @@ import mimetypes
# Import shared media type definitions and scanner from utils to avoid duplication # Import shared media type definitions and scanner from utils to avoid duplication
from backend.utils import MEDIA_EXTENSIONS, get_media_type, scan_notes_fast_walk from backend.utils import MEDIA_EXTENSIONS, get_media_type, scan_notes_fast_walk
logger = logging.getLogger("uvicorn.error")
def get_media_as_base64(media_path: Path) -> Optional[Tuple[str, str]]: def get_media_as_base64(media_path: Path) -> Optional[Tuple[str, str]]:
""" """
@ -41,7 +44,7 @@ def get_media_as_base64(media_path: Path) -> Optional[Tuple[str, str]]:
base64_data = base64.b64encode(media_data).decode('utf-8') base64_data = base64.b64encode(media_data).decode('utf-8')
return (f"data:{mime_type};base64,{base64_data}", media_type) return (f"data:{mime_type};base64,{base64_data}", media_type)
except Exception as e: except Exception as e:
print(f"Failed to read media {media_path}: {e}") logger.error("Failed to read media %s: %s", media_path, e)
return None return None

View File

@ -11,6 +11,7 @@ facades at the bottom of this file.
from __future__ import annotations from __future__ import annotations
import logging
import os import os
import re import re
import threading import threading
@ -21,6 +22,8 @@ from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Iterable, List, Optional, Set, Tuple from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
logger = logging.getLogger("uvicorn.error")
# Below this many markdown files, parallel tag extraction adds more overhead # Below this many markdown files, parallel tag extraction adds more overhead
# than it saves. # than it saves.
@ -899,7 +902,7 @@ def on_note_saved(notes_dir: str, full_path: Path, content: str) -> None:
) )
_index.update_note(record, extract_links_from_content(content), content=content) _index.update_note(record, extract_links_from_content(content), content=content)
except Exception as e: except Exception as e:
print(f"note_index: on_note_saved failed for {full_path}: {e}") logger.error("note_index: on_note_saved failed for %s: %s", full_path, e)
def on_note_deleted(notes_dir: str, full_path: Path) -> None: def on_note_deleted(notes_dir: str, full_path: Path) -> None:
@ -907,7 +910,7 @@ def on_note_deleted(notes_dir: str, full_path: Path) -> None:
rel_path = full_path.relative_to(Path(notes_dir)).as_posix() rel_path = full_path.relative_to(Path(notes_dir)).as_posix()
_index.remove_note(rel_path) _index.remove_note(rel_path)
except Exception as e: except Exception as e:
print(f"note_index: on_note_deleted failed for {full_path}: {e}") logger.error("note_index: on_note_deleted failed for %s: %s", full_path, e)
def on_note_renamed(notes_dir: str, old_full_path: Path, new_full_path: Path) -> None: def on_note_renamed(notes_dir: str, old_full_path: Path, new_full_path: Path) -> None:
@ -918,7 +921,7 @@ def on_note_renamed(notes_dir: str, old_full_path: Path, new_full_path: Path) ->
new_full_path.relative_to(base).as_posix(), new_full_path.relative_to(base).as_posix(),
) )
except Exception as e: except Exception as e:
print(f"note_index: on_note_renamed failed: {e}") logger.error("note_index: on_note_renamed failed: %s", e)
def on_folder_renamed(notes_dir: str, old_full_path: Path, new_full_path: Path) -> None: def on_folder_renamed(notes_dir: str, old_full_path: Path, new_full_path: Path) -> None:
@ -930,7 +933,7 @@ def on_folder_renamed(notes_dir: str, old_full_path: Path, new_full_path: Path)
new_full_path.relative_to(base).as_posix(), new_full_path.relative_to(base).as_posix(),
) )
except Exception as e: except Exception as e:
print(f"note_index: on_folder_renamed failed: {e}") logger.error("note_index: on_folder_renamed failed: %s", e)
_index.invalidate() _index.invalidate()
@ -939,7 +942,7 @@ def on_folder_deleted(notes_dir: str, full_path: Path) -> None:
rel_prefix = full_path.relative_to(Path(notes_dir)).as_posix() rel_prefix = full_path.relative_to(Path(notes_dir)).as_posix()
_index.remove_folder_prefix(rel_prefix) _index.remove_folder_prefix(rel_prefix)
except Exception as e: except Exception as e:
print(f"note_index: on_folder_deleted failed: {e}") logger.error("note_index: on_folder_deleted failed: %s", e)
_index.invalidate() _index.invalidate()
@ -952,7 +955,7 @@ def populate_from_scan(
try: try:
_index.bulk_set(notes_meta, folders, sources_raw) _index.bulk_set(notes_meta, folders, sources_raw)
except Exception as e: except Exception as e:
print(f"note_index: populate_from_scan failed: {e}") logger.error("note_index: populate_from_scan failed: %s", e)
def ensure_search_index(notes_dir: str) -> bool: def ensure_search_index(notes_dir: str) -> bool:

View File

@ -4,6 +4,7 @@ Handles creating, storing, and revoking share tokens for public note access.
""" """
import json import json
import logging
import secrets import secrets
import string import string
from pathlib import Path from pathlib import Path
@ -13,6 +14,8 @@ import threading
from .utils import validate_path_security from .utils import validate_path_security
logger = logging.getLogger("uvicorn.error")
# Thread lock for safe concurrent access # Thread lock for safe concurrent access
_lock = threading.Lock() _lock = threading.Lock()
@ -99,7 +102,7 @@ def save_tokens(data_dir: str, tokens: Dict[str, Dict[str, Any]]) -> bool:
json.dump(tokens, f, indent=2, ensure_ascii=False) json.dump(tokens, f, indent=2, ensure_ascii=False)
return True return True
except IOError as e: except IOError as e:
print(f"Failed to save share tokens: {e}") logger.error("Failed to save share tokens: %s", e)
return False return False

View File

@ -2,10 +2,13 @@
Theme management for NoteDiscovery Theme management for NoteDiscovery
""" """
import logging
from pathlib import Path from pathlib import Path
from typing import List, Dict from typing import List, Dict
import re import re
logger = logging.getLogger("uvicorn.error")
def parse_theme_metadata(theme_path: Path) -> Dict[str, str]: def parse_theme_metadata(theme_path: Path) -> Dict[str, str]:
"""Parse theme metadata from CSS file comments""" """Parse theme metadata from CSS file comments"""
@ -28,7 +31,7 @@ def parse_theme_metadata(theme_path: Path) -> Dict[str, str]:
metadata["type"] = match.group(1) metadata["type"] = match.group(1)
break break
except Exception as e: except Exception as e:
print(f"Error parsing theme metadata from {theme_path}: {e}") logger.error("Error parsing theme metadata from %s: %s", theme_path, e)
return metadata return metadata

View File

@ -5,6 +5,7 @@ Heavy work (backlinks, graph, full-text search, tag aggregation) is delegated
to the in-memory index in note_index.py. to the in-memory index in note_index.py.
""" """
import logging
import os import os
import re import re
import shutil import shutil
@ -21,6 +22,8 @@ from datetime import datetime, timezone
from . import note_index from . import note_index
from .note_index import NoteRecord, extract_links_from_content from .note_index import NoteRecord, extract_links_from_content
logger = logging.getLogger("uvicorn.error")
# ============================================================================ # ============================================================================
# Pagination Support # Pagination Support
@ -443,13 +446,13 @@ def delete_folder(notes_dir: str, folder_path: str) -> bool:
full_path = Path(notes_dir) / folder_path full_path = Path(notes_dir) / folder_path
if not validate_path_security(notes_dir, full_path): if not validate_path_security(notes_dir, full_path):
print(f"Security: Path is outside notes directory: {full_path}") logger.warning("Security: Path is outside notes directory: %s", full_path)
return False return False
if not full_path.exists(): if not full_path.exists():
print(f"Folder does not exist: {full_path}") logger.warning("Folder does not exist: %s", full_path)
return False return False
if not full_path.is_dir(): if not full_path.is_dir():
print(f"Path is not a directory: {full_path}") logger.warning("Path is not a directory: %s", full_path)
return False return False
_drop_prefix_caches(full_path) _drop_prefix_caches(full_path)
@ -458,8 +461,8 @@ def delete_folder(notes_dir: str, folder_path: str) -> bool:
_scan_cache_invalidate() _scan_cache_invalidate()
return True return True
except Exception as e: except Exception as e:
print(f"Error deleting folder '{folder_path}': {e}") logger.error("Error deleting folder '%s': %s", folder_path, e)
traceback.print_exc() logger.error(traceback.format_exc())
return False return False
@ -734,7 +737,7 @@ def save_uploaded_image(
f.write(file_data) f.write(file_data)
return str(full_path.relative_to(base).as_posix()) return str(full_path.relative_to(base).as_posix())
except OSError as e: except OSError as e:
print(f"Error saving image: {e}") logger.error("Error saving image: %s", e)
return None return None
sanitized_name = sanitize_filename(filename) sanitized_name = sanitize_filename(filename)
@ -746,14 +749,14 @@ def save_uploaded_image(
attachments_dir.mkdir(parents=True, exist_ok=True) attachments_dir.mkdir(parents=True, exist_ok=True)
full_path = attachments_dir / final_filename full_path = attachments_dir / final_filename
if not validate_path_security(notes_dir, full_path): if not validate_path_security(notes_dir, full_path):
print(f"Security: Attempted to save image outside notes directory: {full_path}") logger.warning("Security: Attempted to save image outside notes directory: %s", full_path)
return None return None
try: try:
with open(full_path, "wb") as f: with open(full_path, "wb") as f:
f.write(file_data) f.write(file_data)
return str(full_path.relative_to(base).as_posix()) return str(full_path.relative_to(base).as_posix())
except OSError as e: except OSError as e:
print(f"Error saving image: {e}") logger.error("Error saving image: %s", e)
return None return None
@ -869,8 +872,7 @@ def parse_tags(content: str) -> List[str]:
return sorted(list(set(tags))) return sorted(list(set(tags)))
except Exception as e: except Exception as e:
# If parsing fails, return empty list logger.error("Error parsing tags: %s", e)
print(f"Error parsing tags: {e}")
return [] return []
@ -923,15 +925,14 @@ def get_templates(notes_dir: str) -> List[Dict]:
# Security check: ensure _templates folder is within notes directory # Security check: ensure _templates folder is within notes directory
if not validate_path_security(notes_dir, templates_path): if not validate_path_security(notes_dir, templates_path):
print(f"Security: Templates directory is outside notes directory: {templates_path}") logger.warning("Security: Templates directory is outside notes directory: %s", templates_path)
return templates return templates
try: try:
for template_file in templates_path.glob("*.md"): for template_file in templates_path.glob("*.md"):
try: try:
# Security check: ensure each template is within notes directory
if not validate_path_security(notes_dir, template_file): if not validate_path_security(notes_dir, template_file):
print(f"Security: Skipping template outside notes directory: {template_file}") logger.warning("Security: Skipping template outside notes directory: %s", template_file)
continue continue
stat = template_file.stat() stat = template_file.stat()
@ -941,10 +942,10 @@ def get_templates(notes_dir: str) -> List[Dict]:
"modified": datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc).isoformat() "modified": datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc).isoformat()
}) })
except Exception as e: except Exception as e:
print(f"Error reading template {template_file}: {e}") logger.error("Error reading template %s: %s", template_file, e)
continue continue
except Exception as e: except Exception as e:
print(f"Error accessing templates directory: {e}") logger.error("Error accessing templates directory: %s", e)
return sorted(templates, key=lambda x: x['name']) return sorted(templates, key=lambda x: x['name'])
@ -967,14 +968,14 @@ def get_template_content(notes_dir: str, template_name: str) -> Optional[str]:
# Security check: ensure template is within notes directory # Security check: ensure template is within notes directory
if not validate_path_security(notes_dir, template_path): if not validate_path_security(notes_dir, template_path):
print(f"Security: Template path is outside notes directory: {template_path}") logger.warning("Security: Template path is outside notes directory: %s", template_path)
return None return None
try: try:
with open(template_path, 'r', encoding='utf-8') as f: with open(template_path, 'r', encoding='utf-8') as f:
return f.read() return f.read()
except Exception as e: except Exception as e:
print(f"Error reading template {template_name}: {e}") logger.error("Error reading template %s: %s", template_name, e)
return None return None