diff --git a/__snapshots__/tests/test_initial_layout.raw b/__snapshots__/tests/test_initial_layout.raw
index 7c612d4..c498016 100644
--- a/__snapshots__/tests/test_initial_layout.raw
+++ b/__snapshots__/tests/test_initial_layout.raw
@@ -19,208 +19,208 @@
font-weight: 700;
}
- .terminal-1669918775-matrix {
+ .terminal-1161314305-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
- .terminal-1669918775-title {
+ .terminal-1161314305-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
- .terminal-1669918775-r1 { fill: #c5c8c6 }
-.terminal-1669918775-r2 { fill: #e0e0e0 }
-.terminal-1669918775-r3 { fill: #121212 }
-.terminal-1669918775-r4 { fill: #0178d4 }
-.terminal-1669918775-r5 { fill: #7ae998 }
-.terminal-1669918775-r6 { fill: #2d2d2d }
-.terminal-1669918775-r7 { fill: #797979 }
-.terminal-1669918775-r8 { fill: #0a180e;font-weight: bold }
-.terminal-1669918775-r9 { fill: #e0e0e0;font-weight: bold }
-.terminal-1669918775-r10 { fill: #008139 }
-.terminal-1669918775-r11 { fill: #0d0d0d }
-.terminal-1669918775-r12 { fill: #000000 }
-.terminal-1669918775-r13 { fill: #495259 }
-.terminal-1669918775-r14 { fill: #ffa62b;font-weight: bold }
+ .terminal-1161314305-r1 { fill: #c5c8c6 }
+.terminal-1161314305-r2 { fill: #e0e0e0 }
+.terminal-1161314305-r3 { fill: #121212 }
+.terminal-1161314305-r4 { fill: #0178d4 }
+.terminal-1161314305-r5 { fill: #7ae998 }
+.terminal-1161314305-r6 { fill: #2d2d2d }
+.terminal-1161314305-r7 { fill: #797979 }
+.terminal-1161314305-r8 { fill: #0a180e;font-weight: bold }
+.terminal-1161314305-r9 { fill: #e0e0e0;font-weight: bold }
+.terminal-1161314305-r10 { fill: #008139 }
+.terminal-1161314305-r11 { fill: #0d0d0d }
+.terminal-1161314305-r12 { fill: #000000 }
+.terminal-1161314305-r13 { fill: #495259 }
+.terminal-1161314305-r14 { fill: #ffa62b;font-weight: bold }
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
- SammlerApp
+ SammlerApp
-
-
-
- ⭘SammlerApp
-▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-▊Enter Teilchen information: name, description, #tags▎ Add Search
-▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
- pk Name Description Number Tags
- 019c5d37-d43b-72d0-a4dd-b4816f4c5b3a name0 description0 9001 tag0 tag0-0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-▆▆
-
-▏^p palette
+
+
+
+ ⭘SammlerApp
+▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
+▊Enter Teilchen information: name, description, #tags▎ Add Search
+▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
+ pk Name Description Number Tags
+ 0 Name0 Description0 9000 #tag0 #tag00 #tag000
+ 1 Name1 Description1 9001 #tag1 #tag11 #tag111
+ 2 Name2 Description2 9002 #tag2 #tag22 #tag222
+ 3 Name3 Description3 9003 #tag3 #tag33 #tag333
+ 4 Name4 Description4 9004 #tag4 #tag44 #tag444
+ 5 Name5 Description5 9005 #tag5 #tag55 #tag555
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+▆▆
+
+▏^p palette
diff --git a/justfile b/justfile
index 5196518..bfc462d 100644
--- a/justfile
+++ b/justfile
@@ -21,8 +21,8 @@ exports-deps:
uv export {{ uv_export_options }} --output-file requirements.txt
uv export {{ uv_export_options }} --only-dev --output-file requirements.dev.txt
-test *ARGS:
- uv run pytest tests.py {{ ARGS }}
+test:
+ uv run pytest tests.py
coverage:
uv run pytest tests.py --cov=src/ --cov-report term --cov-report xml --cov-report html --cov-config pyproject.toml
diff --git a/src/teilchensammler_cli/database.py b/src/teilchensammler_cli/database.py
index d919349..6f39922 100644
--- a/src/teilchensammler_cli/database.py
+++ b/src/teilchensammler_cli/database.py
@@ -1,6 +1,6 @@
from sqlmodel import SQLModel, create_engine
-sqlite_url = "sqlite:///database.db" # TODO: get url from environment
+sqlite_url = "sqlite:///:memory:" # TODO: get url from environment
engine = create_engine(sqlite_url, echo=True)
diff --git a/src/teilchensammler_cli/main.py b/src/teilchensammler_cli/main.py
index c1706ef..fc4d680 100644
--- a/src/teilchensammler_cli/main.py
+++ b/src/teilchensammler_cli/main.py
@@ -4,10 +4,12 @@ This is where the application is implemented.
import logging
+from sqlmodel import Session
from textual.app import App
from textual.logging import TextualHandler
-from .database import create_db_and_tables
+from .database import create_db_and_tables, engine
+from .models import Teilchen, make_teilchen_input
from .tui import AddInventoryScreen
logging.basicConfig(
@@ -17,9 +19,29 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
+FAKE_INPUT = """
+ Ein Teilchen. #Tag03 #tag12 "Dieses Teilchen ist nur zum testen" #tag1 #tag2
+ """.strip(" \n")
+
+
+def try_this():
+ teilchen_data = make_teilchen_input(FAKE_INPUT)
+ if not teilchen_data:
+ logger.error("oh no!")
+
+ with Session(engine) as session:
+ db_teilchen = Teilchen.model_validate(teilchen_data)
+ session.add(db_teilchen)
+ session.commit()
+ session.refresh(db_teilchen)
+
+ logger.info(f"{db_teilchen=}")
+
+
class SammlerApp(App[None]):
async def on_mount(self) -> None:
create_db_and_tables()
+ try_this()
_ = self.push_screen(AddInventoryScreen())
diff --git a/src/teilchensammler_cli/models.py b/src/teilchensammler_cli/models.py
index 7a49d5c..1cc6633 100644
--- a/src/teilchensammler_cli/models.py
+++ b/src/teilchensammler_cli/models.py
@@ -4,14 +4,14 @@ import uuid
from sqlmodel import (
Field,
SQLModel,
- Session,
- select,
- Sequence,
)
logger = logging.getLogger(__name__)
+TeilchenDatum = tuple[int, str, str, str, str]
+
+
class TeilchenCreate(SQLModel):
description: str | None
name: str = Field(index=True)
@@ -25,15 +25,6 @@ class Teilchen(TeilchenCreate, table=True):
async def make_teilchen_input(text: str) -> TeilchenCreate | None:
- """Constructor to create new Teilchen from user input.
-
- Args:
- text: The whole input string as provided by the user.
-
- Returns:
- Returns new Teilchen instance if enough parts could be extracted.
- Returns `None` otherwise.
- """
import re
from natsort import natsorted
@@ -45,7 +36,6 @@ async def make_teilchen_input(text: str) -> TeilchenCreate | None:
name = text[0:name_end]
if not name:
logger.error("Could not extract name.")
- logger.debug("Could not extract name from input: %s", text)
return None
description_start = text.find('"', name_end + 1)
@@ -57,26 +47,22 @@ async def make_teilchen_input(text: str) -> TeilchenCreate | None:
tags = re.findall(r"#\w+", text.lower())
if not tags:
- logger.info("Could not extract tags.")
- logger.debug("Could not extract tags from input: %s", text)
+ logger.info("No tags found in text.")
- teilchen = TeilchenCreate(
+ return TeilchenCreate(
name=name,
description=description,
tags=" ".join(natsorted(tags)),
text=text,
)
- logger.debug("Created new Teilchen: %r", teilchen)
-
- return teilchen
-async def load_initial_data() -> Sequence[Teilchen]:
- from .database import engine
-
- with Session(engine) as session:
- statement = select(
- Teilchen.id, Teilchen.name, Teilchen.description, Teilchen.number, Teilchen.tags
- )
- all_teilchen = session.exec(statement).all()
- return all_teilchen
+async def load_initial_data() -> list[TeilchenDatum]:
+ return [
+ (0, "Name0", "Description0", "9000", "#tag0 #tag00 #tag000"),
+ (1, "Name1", "Description1", "9001", "#tag1 #tag11 #tag111"),
+ (2, "Name2", "Description2", "9002", "#tag2 #tag22 #tag222"),
+ (3, "Name3", "Description3", "9003", "#tag3 #tag33 #tag333"),
+ (4, "Name4", "Description4", "9004", "#tag4 #tag44 #tag444"),
+ (5, "Name5", "Description5", "9005", "#tag5 #tag55 #tag555"),
+ ]
diff --git a/src/teilchensammler_cli/tui.py b/src/teilchensammler_cli/tui.py
index 288bc8a..f1ccd78 100644
--- a/src/teilchensammler_cli/tui.py
+++ b/src/teilchensammler_cli/tui.py
@@ -7,7 +7,7 @@ from textual.widgets import Button, DataTable, Footer, Header, Input, Static
from .models import load_initial_data
-FAKE_DATA_HEADER = "pk Name Description Number Tags".split()
+FAKE_DATA_HEADER = "pk Name Description Number Tags"
class SearchBar(Static):
@@ -47,7 +47,7 @@ class SearchResults(Widget):
async def on_mount(self) -> None:
table: DataTable[None] = self.query_one(DataTable[None])
- _ = table.add_columns(*FAKE_DATA_HEADER)
+ _ = table.add_columns(FAKE_DATA_HEADER)
_ = table.add_rows(await load_initial_data()) # ty:ignore[invalid-argument-type]