kin: KIN-070 Исправить sync с Obsidian: auto-create vault dir + корректный vault_path
- obsidian_sync.py: заменить проверку is_dir() на mkdir(parents=True, exist_ok=True) вместо ошибки при отсутствующей директории — автоматически создаём её - test_obsidian_sync.py: обновить тест #9 под новое поведение (директория создаётся) - БД fix: исправлен obsidian_vault_path (убраны лишние кавычки и /kin суффикс), теперь путь указывает на vault root, а не на подпапку проекта Результат: Exported: 79 decisions, errors: [] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8007960332
commit
71c697bf68
2 changed files with 34 additions and 31 deletions
|
|
@ -141,36 +141,39 @@ def sync_obsidian(conn: sqlite3.Connection, project_id: str) -> dict:
|
||||||
vault_path = Path(vault_path_str)
|
vault_path = Path(vault_path_str)
|
||||||
errors: list[str] = []
|
errors: list[str] = []
|
||||||
|
|
||||||
|
# --- Создаём vault_path если не существует ---
|
||||||
|
try:
|
||||||
|
vault_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
except Exception as e:
|
||||||
|
errors.append(f"Cannot create vault path {vault_path_str}: {e}")
|
||||||
|
return {"exported_decisions": 0, "tasks_updated": 0, "errors": errors, "vault_path": vault_path_str}
|
||||||
|
|
||||||
# --- Export decisions ---
|
# --- Export decisions ---
|
||||||
exported_count = 0
|
exported_count = 0
|
||||||
if not vault_path.is_dir():
|
try:
|
||||||
errors.append(f"Vault path does not exist or is not a directory: {vault_path_str}")
|
decisions = models.get_decisions(conn, project_id)
|
||||||
else:
|
created_files = export_decisions_to_md(project_id, decisions, vault_path)
|
||||||
try:
|
exported_count = len(created_files)
|
||||||
decisions = models.get_decisions(conn, project_id)
|
except Exception as e:
|
||||||
created_files = export_decisions_to_md(project_id, decisions, vault_path)
|
errors.append(f"Export error: {e}")
|
||||||
exported_count = len(created_files)
|
|
||||||
except Exception as e:
|
|
||||||
errors.append(f"Export error: {e}")
|
|
||||||
|
|
||||||
# --- Import checkboxes ---
|
# --- Import checkboxes ---
|
||||||
tasks_updated = 0
|
tasks_updated = 0
|
||||||
if vault_path.is_dir():
|
try:
|
||||||
try:
|
checkboxes = parse_task_checkboxes(vault_path, project_id)
|
||||||
checkboxes = parse_task_checkboxes(vault_path, project_id)
|
for item in checkboxes:
|
||||||
for item in checkboxes:
|
if not item["done"]:
|
||||||
if not item["done"]:
|
continue
|
||||||
continue
|
task = models.get_task(conn, item["task_id"])
|
||||||
task = models.get_task(conn, item["task_id"])
|
if task is None:
|
||||||
if task is None:
|
continue
|
||||||
continue
|
if task.get("project_id") != project_id:
|
||||||
if task.get("project_id") != project_id:
|
continue
|
||||||
continue
|
if task.get("status") != "done":
|
||||||
if task.get("status") != "done":
|
models.update_task(conn, item["task_id"], status="done")
|
||||||
models.update_task(conn, item["task_id"], status="done")
|
tasks_updated += 1
|
||||||
tasks_updated += 1
|
except Exception as e:
|
||||||
except Exception as e:
|
errors.append(f"Import error: {e}")
|
||||||
errors.append(f"Import error: {e}")
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"exported_decisions": exported_count,
|
"exported_decisions": exported_count,
|
||||||
|
|
|
||||||
|
|
@ -227,19 +227,19 @@ def test_export_frontmatter_has_yaml_delimiters(tmp_vault):
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# 9. sync_obsidian — несуществующий vault_path → ошибка в errors, не исключение
|
# 9. sync_obsidian — несуществующий vault_path → директория создаётся автоматически
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def test_sync_nonexistent_vault_records_error(db, tmp_path):
|
def test_sync_nonexistent_vault_creates_directory(db, tmp_path):
|
||||||
"""Если vault_path не существует, sync возвращает ошибку в errors без raise."""
|
"""Если vault_path не существует, sync автоматически создаёт директорию."""
|
||||||
nonexistent = tmp_path / "ghost_vault"
|
nonexistent = tmp_path / "ghost_vault"
|
||||||
models.update_project(db, "proj1", obsidian_vault_path=str(nonexistent))
|
models.update_project(db, "proj1", obsidian_vault_path=str(nonexistent))
|
||||||
|
|
||||||
result = sync_obsidian(db, "proj1")
|
result = sync_obsidian(db, "proj1")
|
||||||
|
|
||||||
assert len(result["errors"]) > 0
|
assert result["errors"] == []
|
||||||
assert "does not exist" in result["errors"][0].lower() or "not exist" in result["errors"][0].lower()
|
assert nonexistent.is_dir() # директория автоматически создана
|
||||||
assert result["exported_decisions"] == 0
|
assert result["exported_decisions"] == 0 # нет decisions в DB
|
||||||
assert result["tasks_updated"] == 0
|
assert result["tasks_updated"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue