feat(backend): Complete SyncService action computation; Refine DiffEngine rename/skip logic

This commit is contained in:
2026-05-15 17:13:31 +03:00
parent 08e1e322f1
commit 7e22aae1a0
2 changed files with 51 additions and 5 deletions
+17 -2
View File
@@ -30,13 +30,28 @@ class DiffEngine:
for item in remote:
desired_name = desired_names[item.video_id]
# If DB knows the current local filename and it already matches and exists -> nothing to do
if item.local_filename == desired_name and desired_name in fs_by_name:
continue
if desired_name in fs_by_name:
actions.append(SyncAction(SyncActionType.RENAME, item=item, from_name=item.local_filename, to_name=desired_name))
# If DB knows a different current filename and it exists -> plan a rename
if item.local_filename and item.local_filename in fs_by_name and item.local_filename != desired_name:
actions.append(
SyncAction(
SyncActionType.RENAME,
item=item,
from_name=item.local_filename,
to_name=desired_name,
)
)
continue
# If the desired file already exists on disk but DB doesn't reflect it -> skip (already correct)
if desired_name in fs_by_name:
actions.append(SyncAction(SyncActionType.SKIP, item=item, to_name=desired_name))
continue
# Otherwise, we need to download
actions.append(SyncAction(SyncActionType.DOWNLOAD, item=item, to_name=desired_name))
known_ids = {i.video_id for i in remote}
+34 -3
View File
@@ -5,7 +5,7 @@ from pathlib import Path
from typing import List
from ..database.db import Database
from ..models import PlaylistItem
from ..models import PlaylistItem, SyncAction
from ..scanner.playlist_scanner import PlaylistScanner
from ..sync.diff_engine import DiffEngine
from ..sync.filesystem import list_files
@@ -28,7 +28,7 @@ class SyncService:
return [".mp3", ".mp4"]
return [".mp3"]
def sync_from_config(self, playlist_cfg: dict) -> List[dict]:
def sync_from_config(self, playlist_cfg: dict) -> List[SyncAction]:
url: str = playlist_cfg.get("url")
mode: str = playlist_cfg.get("download_mode", "audio")
save_path = Path(playlist_cfg.get("save_path", "./downloads")).resolve()
@@ -76,8 +76,39 @@ class SyncService:
downloaded=bool(row["downloaded"]),
)
# Augment remote items with DB-known filenames/download flags
augmented: List[PlaylistItem] = []
for it in sanitized:
known = db_index.get(it.video_id)
if known is None:
augmented.append(it)
else:
augmented.append(
PlaylistItem(
playlist_id=it.playlist_id,
video_id=it.video_id,
title=it.title,
playlist_index=it.playlist_index,
local_filename=known.local_filename,
downloaded=known.downloaded,
)
)
exts = self._mode_to_extensions(mode)
merged_actions = []
merged_actions: List[SyncAction] = []
# Compute per-extension actions against respective roots
for ext in exts:
if ext == ".mp3":
fs = list_files(save_path / "audio", [".mp3"])
elif ext == ".mp4":
fs = list_files(save_path / "video", [".mp4"])
else:
fs = list_files(save_path, [ext])
actions = self.diff.compute_actions(augmented, db_index, fs, ext)
merged_actions.extend(actions)
return merged_actions
for ext in exts:
mode_dir = "audio" if ext == ".mp3" else "video"
fs_root = (save_path / mode_dir)