add sync status tool

Signed-off-by: phernandez <paul@basicmachines.co>
This commit is contained in:
phernandez
2025-06-04 22:24:10 -05:00
parent a3cae1064d
commit 91bfe2dc92
15 changed files with 845 additions and 252 deletions
+55 -2
View File
@@ -17,6 +17,7 @@ from basic_memory.models import Entity
from basic_memory.repository import EntityRepository, RelationRepository
from basic_memory.services import EntityService, FileService
from basic_memory.services.search_service import SearchService
from basic_memory.services.sync_status_service import sync_status_tracker, SyncStatus
@dataclass
@@ -80,23 +81,38 @@ class SyncService:
self.search_service = search_service
self.file_service = file_service
async def sync(self, directory: Path) -> SyncReport:
async def sync(self, directory: Path, project_name: Optional[str] = None) -> SyncReport:
"""Sync all files with database."""
start_time = time.time()
logger.info(f"Sync operation started for directory: {directory}")
# Start tracking sync for this project if project name provided
if project_name:
sync_status_tracker.start_project_sync(project_name)
# initial paths from db to sync
# path -> checksum
report = await self.scan(directory)
# Initialize progress tracking if requested
# Update progress with file counts
if project_name:
sync_status_tracker.update_project_progress(
project_name=project_name,
status=SyncStatus.SYNCING,
message="Processing file changes",
files_total=report.total,
files_processed=0,
)
# order of sync matters to resolve relations effectively
logger.info(
f"Sync changes detected: new_files={len(report.new)}, modified_files={len(report.modified)}, "
+ f"deleted_files={len(report.deleted)}, moved_files={len(report.moves)}"
)
files_processed = 0
# sync moves first
for old_path, new_path in report.moves.items():
# in the case where a file has been deleted and replaced by another file
@@ -109,19 +125,56 @@ class SyncService:
else:
await self.handle_move(old_path, new_path)
files_processed += 1
if project_name:
sync_status_tracker.update_project_progress(
project_name=project_name,
status=SyncStatus.SYNCING,
message="Processing moves",
files_processed=files_processed,
)
# deleted next
for path in report.deleted:
await self.handle_delete(path)
files_processed += 1
if project_name:
sync_status_tracker.update_project_progress(
project_name=project_name,
status=SyncStatus.SYNCING,
message="Processing deletions",
files_processed=files_processed,
)
# then new and modified
for path in report.new:
await self.sync_file(path, new=True)
files_processed += 1
if project_name:
sync_status_tracker.update_project_progress(
project_name=project_name,
status=SyncStatus.SYNCING,
message="Processing new files",
files_processed=files_processed,
)
for path in report.modified:
await self.sync_file(path, new=False)
files_processed += 1
if project_name:
sync_status_tracker.update_project_progress(
project_name=project_name,
status=SyncStatus.SYNCING,
message="Processing modified files",
files_processed=files_processed,
)
await self.resolve_relations()
# Mark sync as completed
if project_name:
sync_status_tracker.complete_project_sync(project_name)
duration_ms = int((time.time() - start_time) * 1000)
logger.info(
f"Sync operation completed: directory={directory}, total_changes={report.total}, duration_ms={duration_ms}"