56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
import asyncio
|
|
import subprocess
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
|
|
class Journal:
|
|
def __init__(
|
|
self,
|
|
vault_path: Path,
|
|
daily_notes_dir: str,
|
|
note_path_format: str,
|
|
message_time_format: str,
|
|
) -> None:
|
|
self.vault_path = vault_path
|
|
self.notes_path = vault_path / daily_notes_dir
|
|
self.note_path_format = note_path_format
|
|
self.message_time_format = message_time_format
|
|
self._lock = asyncio.Lock()
|
|
|
|
async def append(self, text: str) -> None:
|
|
async with self._lock:
|
|
await asyncio.to_thread(self._append_and_sync, text)
|
|
|
|
def _append_and_sync(self, text: str) -> None:
|
|
self._git("pull", "--rebase")
|
|
|
|
now = datetime.now().astimezone()
|
|
note_path = self.notes_path / now.strftime(self.note_path_format)
|
|
note_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
entry = f"- {now.strftime(self.message_time_format)} {text.strip()}\n"
|
|
with note_path.open("a", encoding="utf-8") as file:
|
|
file.write(entry)
|
|
|
|
relative_note_path = note_path.relative_to(self.vault_path)
|
|
self._git("add", str(relative_note_path))
|
|
if not self._has_staged_changes():
|
|
return
|
|
|
|
self._git("commit", "-m", f"Update daily note {note_path.stem}")
|
|
self._git("push")
|
|
|
|
def _has_staged_changes(self) -> bool:
|
|
process = self._git("diff", "--cached", "--quiet", check=False)
|
|
return process.returncode == 1
|
|
|
|
def _git(self, *args: str, check: bool = True) -> subprocess.CompletedProcess[str]:
|
|
return subprocess.run(
|
|
("git", *args),
|
|
cwd=self.vault_path,
|
|
check=check,
|
|
text=True,
|
|
capture_output=True,
|
|
)
|