Compare commits

..

No commits in common. "093250cc9ed27fb0f4c1dea3c598742b8548bbdc" and "8da542a1f629e0b45588f83870eb24c702ed4b5f" have entirely different histories.

6 changed files with 142 additions and 134 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before After
Before After

View file

@ -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

View file

@ -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)

View file

@ -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())

View file

@ -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"),
]

View file

@ -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]