Spaces:
Sleeping
Sleeping
File size: 5,300 Bytes
2197ab7 5fe3652 2197ab7 5fe3652 2197ab7 5fe3652 2197ab7 5fe3652 2197ab7 5fe3652 2197ab7 5fe3652 2197ab7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
"""Main entry point for the Fabric to Espanso conversion process."""
from typing import Optional
import sys
import signal
import logging
from contextlib import contextmanager
from src.fabrics_processor.database import initialize_qdrant_database
from src.fabrics_processor.file_change_detector import detect_file_changes
from src.fabrics_processor.database_updater import update_qdrant_database
from src.fabrics_processor.output_files_generator import generate_yaml_file
from src.fabrics_processor.logger import setup_logger
from src.fabrics_processor.config import config
from src.fabrics_processor.deduplicator import remove_duplicates
from src.fabrics_processor.exceptions import (
DatabaseConnectionError,
DatabaseInitializationError
)
# Setup logger
logger = setup_logger()
class GracefulExit(SystemExit):
"""Custom exception for graceful shutdown."""
pass
def signal_handler(signum, frame):
"""Handle shutdown signals gracefully."""
logger.info(f"Received signal {signum}. Initiating graceful shutdown...")
raise GracefulExit()
@contextmanager
def managed_qdrant_client():
"""Context manager for handling Qdrant client lifecycle."""
client = None
try:
client = initialize_qdrant_database()
yield client
finally:
if client:
logger.info("Closing Qdrant client connection...")
client.close()
logger.info("Qdrant client connection closed")
def process_changes(client) -> bool:
"""Process file changes and update database and YAML files.
Args:
client: Initialized Qdrant client
Returns:
bool: True if processing was successful, False otherwise
"""
try:
# Detect file changes
new_files, modified_files, deleted_files = detect_file_changes(client, config.fabric_patterns_folder)
# Log the results
if new_files:
logger.info(f"New files: {[file['filename'] for file in new_files]}")
if modified_files:
logger.info(f"Modified files: {[file['filename'] for file in modified_files]}")
if deleted_files:
logger.info(f"Deleted files: {deleted_files}")
# Track changes for summary
duplicates_removed = 0
# Update database if there are changes
if any([new_files, modified_files, deleted_files]):
logger.info("Changes detected. Updating database...")
update_qdrant_database(client, config.embedding.collection_name, new_files, modified_files, deleted_files)
# Deduplicate entries after updating the database
logger.info("Checking for and removing duplicate entries...")
duplicates_removed = remove_duplicates(client, config.embedding.collection_name)
if duplicates_removed > 0:
logger.info(f"Removed {duplicates_removed} duplicate entries from the database")
# Always generate output files to ensure consistency
generate_yaml_file(client, config.yaml_output_folder)
# Generate summary message
total_entries = len(client.scroll(collection_name=config.embedding.collection_name, limit=10000)[0])
summary_message = f"Database update summary: {len(new_files)} added, {len(modified_files)} modified, {len(deleted_files)} deleted, {duplicates_removed} duplicates removed. Total entries: {total_entries}"
logger.info(summary_message)
return True
except Exception as e:
logger.error(f"Error processing changes: {str(e)}", exc_info=True)
return False
def main() -> Optional[int]:
"""Main application entry point.
Returns:
Optional[int]: Exit code, None if successful, 1 if error
"""
# Setup signal handlers
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
logger.info("Fabric to Espanso conversion process started")
# Log configuration
logger.info(f"Using configuration:")
logger.info(f" Database URL: {config.database.url}")
logger.info(f" Fabric patterns folder: {config.fabric_patterns_folder}")
logger.info(f" YAML output folder: {config.yaml_output_folder}")
logger.info(f" Obsidian textgenerator markdown output folder: {config.markdown_output_folder}")
logger.info(f" Obsidian personal prompts input folder: {config.obsidian_input_folder}")
# Process changes with managed client
with managed_qdrant_client() as client:
if process_changes(client):
logger.info("Fabric to Espanso conversion completed successfully")
return None
else:
logger.error("Fabric to Espanso conversion completed with errors")
return 1
except GracefulExit:
logger.info("Gracefully shutting down...")
return None
except (DatabaseConnectionError, DatabaseInitializationError) as e:
logger.error(f"Database error: {str(e)}")
return 1
except Exception as e:
logger.error(f"Unexpected error: {str(e)}", exc_info=True)
return 1
if __name__ == "__main__":
sys.exit(main() or 0) |