Compare commits
9 commits
8da542a1f6
...
093250cc9e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
093250cc9e | ||
|
|
de0cd8034a | ||
|
|
d6bcb90431 | ||
|
|
b068bd1e2a | ||
|
|
814d5eade7 | ||
|
|
0d80c686c7 | ||
|
|
61f259ecfc | ||
|
|
a34135ef6f | ||
|
|
17a9593b32 |
6 changed files with 134 additions and 142 deletions
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 29 KiB |
4
justfile
4
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:
|
||||
uv run pytest tests.py
|
||||
test *ARGS:
|
||||
uv run pytest tests.py {{ ARGS }}
|
||||
|
||||
coverage:
|
||||
uv run pytest tests.py --cov=src/ --cov-report term --cov-report xml --cov-report html --cov-config pyproject.toml
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from sqlmodel import SQLModel, create_engine
|
||||
|
||||
sqlite_url = "sqlite:///:memory:" # TODO: get url from environment
|
||||
sqlite_url = "sqlite:///database.db" # TODO: get url from environment
|
||||
engine = create_engine(sqlite_url, echo=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@ 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, engine
|
||||
from .models import Teilchen, make_teilchen_input
|
||||
from .database import create_db_and_tables
|
||||
from .tui import AddInventoryScreen
|
||||
|
||||
logging.basicConfig(
|
||||
|
|
@ -19,29 +17,9 @@ 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())
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,6 +25,15 @@ 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
|
||||
|
||||
|
|
@ -36,6 +45,7 @@ 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)
|
||||
|
|
@ -47,22 +57,26 @@ async def make_teilchen_input(text: str) -> TeilchenCreate | None:
|
|||
|
||||
tags = re.findall(r"#\w+", text.lower())
|
||||
if not tags:
|
||||
logger.info("No tags found in text.")
|
||||
logger.info("Could not extract tags.")
|
||||
logger.debug("Could not extract tags from input: %s", text)
|
||||
|
||||
return TeilchenCreate(
|
||||
teilchen = 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() -> 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"),
|
||||
]
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
FAKE_DATA_HEADER = "pk Name Description Number Tags".split()
|
||||
|
||||
|
||||
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]
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue