mirror of
https://github.com/sakaljurgis/kob.git
synced 2026-07-08 22:17:41 +00:00
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
import json
|
|
import shutil
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
|
|
class Storage:
|
|
def __init__(self, data_dir: Path):
|
|
self.data_dir = Path(data_dir)
|
|
self.articles_dir = self.data_dir / "articles"
|
|
self.index_file = self.data_dir / "index.json"
|
|
self.articles_dir.mkdir(parents=True, exist_ok=True)
|
|
if not self.index_file.exists():
|
|
self._write_index({"articles": []})
|
|
|
|
def _read_index(self) -> dict:
|
|
with open(self.index_file) as f:
|
|
return json.load(f)
|
|
|
|
def _write_index(self, data: dict) -> None:
|
|
tmp = self.index_file.with_suffix(".json.tmp")
|
|
with open(tmp, "w") as f:
|
|
json.dump(data, f, indent=2)
|
|
tmp.replace(self.index_file)
|
|
|
|
def list_articles(self) -> list[dict]:
|
|
return self._read_index()["articles"]
|
|
|
|
def get_article(self, article_id: str) -> Optional[dict]:
|
|
for a in self.list_articles():
|
|
if a["id"] == article_id:
|
|
return a
|
|
return None
|
|
|
|
def add_article(
|
|
self,
|
|
article_id: str,
|
|
title: str,
|
|
url: str,
|
|
markdown: str,
|
|
epub_bytes: bytes,
|
|
) -> None:
|
|
folder = self.articles_dir / article_id
|
|
folder.mkdir(parents=True, exist_ok=False)
|
|
(folder / "source.md").write_text(markdown, encoding="utf-8")
|
|
(folder / "article.epub").write_bytes(epub_bytes)
|
|
meta = {
|
|
"id": article_id,
|
|
"url": url,
|
|
"title": title,
|
|
"fetched_at": _now(),
|
|
}
|
|
(folder / "meta.json").write_text(json.dumps(meta, indent=2))
|
|
|
|
index = self._read_index()
|
|
index["articles"].insert(0, meta)
|
|
self._write_index(index)
|
|
|
|
def delete_article(self, article_id: str) -> bool:
|
|
index = self._read_index()
|
|
before = len(index["articles"])
|
|
index["articles"] = [a for a in index["articles"] if a["id"] != article_id]
|
|
if len(index["articles"]) == before:
|
|
return False
|
|
self._write_index(index)
|
|
folder = self.articles_dir / article_id
|
|
if folder.exists():
|
|
shutil.rmtree(folder)
|
|
return True
|
|
|
|
def epub_path(self, article_id: str) -> Path:
|
|
return self.articles_dir / article_id / "article.epub"
|
|
|
|
|
|
def _now() -> str:
|
|
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|