init
This commit is contained in:
92
src/state.py
Normal file
92
src/state.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""
|
||||
Хранение состояния скачивания в SQLite.
|
||||
"""
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
|
||||
DB_PATH = Path("/app/state/progress.db")
|
||||
|
||||
|
||||
class StateDB:
|
||||
def __init__(self, db_path: Path = DB_PATH):
|
||||
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
self.conn = sqlite3.connect(str(db_path))
|
||||
self._init()
|
||||
|
||||
def _init(self):
|
||||
self.conn.execute("""
|
||||
CREATE TABLE IF NOT EXISTS chapters (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
manga_url TEXT NOT NULL,
|
||||
chapter_url TEXT NOT NULL UNIQUE,
|
||||
title TEXT,
|
||||
number REAL,
|
||||
volume INTEGER,
|
||||
status TEXT DEFAULT 'pending',
|
||||
output_cbz TEXT,
|
||||
output_pdf TEXT,
|
||||
output_epub TEXT,
|
||||
updated_at TEXT
|
||||
)
|
||||
""")
|
||||
self.conn.commit()
|
||||
|
||||
def upsert_chapter(self, manga_url: str, chapter_url: str,
|
||||
title: str = "", number: float = 0, volume: int = 0):
|
||||
self.conn.execute("""
|
||||
INSERT INTO chapters (manga_url, chapter_url, title, number, volume, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(chapter_url) DO UPDATE SET
|
||||
title = excluded.title,
|
||||
number = excluded.number,
|
||||
volume = excluded.volume
|
||||
""", (manga_url, chapter_url, title, number, volume, _now()))
|
||||
self.conn.commit()
|
||||
|
||||
def mark_done(self, chapter_url: str, fmt: str, output_path: str):
|
||||
col = f"output_{fmt}"
|
||||
self.conn.execute(f"""
|
||||
UPDATE chapters SET status='done', {col}=?, updated_at=?
|
||||
WHERE chapter_url=?
|
||||
""", (output_path, _now(), chapter_url))
|
||||
self.conn.commit()
|
||||
|
||||
def mark_failed(self, chapter_url: str):
|
||||
self.conn.execute("""
|
||||
UPDATE chapters SET status='failed', updated_at=? WHERE chapter_url=?
|
||||
""", (_now(), chapter_url))
|
||||
self.conn.commit()
|
||||
|
||||
def get_pending(self, manga_url: str) -> list[dict]:
|
||||
cur = self.conn.execute("""
|
||||
SELECT chapter_url, title, number, volume
|
||||
FROM chapters
|
||||
WHERE manga_url=? AND status != 'done'
|
||||
ORDER BY volume, number
|
||||
""", (manga_url,))
|
||||
cols = [d[0] for d in cur.description]
|
||||
return [dict(zip(cols, row)) for row in cur.fetchall()]
|
||||
|
||||
def get_all(self, manga_url: str) -> list[dict]:
|
||||
cur = self.conn.execute("""
|
||||
SELECT * FROM chapters WHERE manga_url=? ORDER BY volume, number
|
||||
""", (manga_url,))
|
||||
cols = [d[0] for d in cur.description]
|
||||
return [dict(zip(cols, row)) for row in cur.fetchall()]
|
||||
|
||||
def chapter_status(self, chapter_url: str) -> Optional[str]:
|
||||
cur = self.conn.execute(
|
||||
"SELECT status FROM chapters WHERE chapter_url=?", (chapter_url,))
|
||||
row = cur.fetchone()
|
||||
return row[0] if row else None
|
||||
|
||||
def close(self):
|
||||
self.conn.close()
|
||||
|
||||
|
||||
def _now() -> str:
|
||||
return datetime.utcnow().isoformat()
|
||||
|
||||
Reference in New Issue
Block a user