11 Commits

Author SHA1 Message Date
celex 80d06c653d list tasks in textual 2026-05-18 16:46:52 +02:00
celex a6e3738b7a add textual app skeleton 2026-05-18 16:28:17 +02:00
celex c7f8016c4b add textual as a dependancy 2026-05-18 16:26:59 +02:00
celex b8e2052549 rename done to is_done 2026-05-18 16:18:11 +02:00
celex 926669f28f add basic database functionality 2026-05-18 16:16:40 +02:00
celex 25093ce833 add basic test 2026-05-14 09:55:02 +02:00
celex 2082aedc05 add basic src layout/example 2026-05-14 09:09:44 +02:00
celex f77a603c8e add __pycache__ to .gitignore 2026-05-14 09:09:05 +02:00
celex 58870f1a81 add egg-info to git ignore 2026-05-14 09:04:17 +02:00
celex efcdaed5d6 replace - with _ in module name 2026-05-14 09:01:23 +02:00
celex 3561b83c45 add basic pyproject.toml 2026-05-14 08:50:53 +02:00
7 changed files with 104 additions and 0 deletions
+3
View File
@@ -1 +1,4 @@
.venv/
src/chore_manager.egg-info/
__pycache__/
+20
View File
@@ -0,0 +1,20 @@
[build-system]
requires = ["setuptools >= 77.0.3"]
build-backend = "setuptools.build_meta"
[project]
name="chore-manager"
dynamic = ["version"]
dependencies = ["textual"]
requires-python = ">=3.13"
readme = "README.md"
[project.optional-dependencies]
dev = [
"pytest",
"ruff",
]
[project.scripts]
chore-manager-tui = "chore_manager:main_tui"
+1
View File
@@ -0,0 +1 @@
from .main import main_tui
+52
View File
@@ -0,0 +1,52 @@
import sqlite3
from pathlib import Path
import os
from dataclasses import dataclass, fields
@dataclass
class Task:
title: str
is_done: bool
def __post_init__(self):
for field in fields(self):
if field.type is bool:
value = getattr(self, field.name)
setattr(self, field.name, bool(value))
class Database:
def __init__(self, filepath: Path|str):
is_new_database = not Path(filepath).exists()
self.con = sqlite3.connect(filepath)
self.cur = self.con.cursor()
if is_new_database:
self.initialize_table()
for i in range(0, 15):
self.create_task(f"task{i}", bool(i%2))
def initialize_table(self):
self.cur.execute("CREATE TABLE tasks(title TEXT, is_done INTEGER)")
def create_task(self, title: str, done:bool=False) -> None:
converted_done = ""
if done:
converted_done = "TRUE"
else:
converted_done = "FALSE"
self.cur.execute(f"""INSERT INTO tasks VALUES ("{title}", {converted_done});""")
self.con.commit()
def get_all_tasks(self) -> list[Task]:
self.cur.execute("SELECT * FROM tasks")
raw_data = self.cur.fetchall()
return [Task(*task) for task in raw_data]
if __name__ == '__main__':
try:
os.remove("DEBUG.db")
except FileNotFoundError:
pass
database = Database("DEBUG.db")
database.create_task("test")
print(database.get_all_tasks())
+5
View File
@@ -0,0 +1,5 @@
from .tui import ChoreManagerTui
def main_tui() -> None:
app = ChoreManagerTui()
app.run()
+19
View File
@@ -0,0 +1,19 @@
from textual.app import App, ComposeResult
from textual.widgets import Header, Checkbox
from textual.containers import VerticalScroll
from .database import Database
class ChoreManagerTui(App):
def __init__(self):
super().__init__()
self.database = Database("DEBUG")
def compose(self) -> ComposeResult:
yield Header()
tasks = self.database.get_all_tasks()
with VerticalScroll():
for task in tasks:
yield Checkbox(task.title, task.is_done)
+4
View File
@@ -0,0 +1,4 @@
from chore_manager.main import main_tui
def test_tui() -> None:
assert main_tui() is None