very first dummy version of a search with all the project Kladeradatsch

This commit is contained in:
flukx 2024-07-26 19:41:56 +02:00
parent 479b973d43
commit 6bd6bbb14c
12 changed files with 148 additions and 2 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.idea
testasync.py
out

4
.gitmodules vendored
View file

@ -1,4 +1,4 @@
[submodule "src/flinventory"]
path = src/flinventory
[submodule "flinventory_gui/flinventory"]
path = flinventory_gui/flinventory
url = https://flugit.hilsky.de/flukx/flinventory.git
branch = bikeparts

4
.mypyrc Normal file
View file

@ -0,0 +1,4 @@
[mypy]
packages=flinventoryGUI
[mypy-flinventoryGUI.flinventory.*]
ignore_errors=True

21
.pylintrc Normal file
View file

@ -0,0 +1,21 @@
[tool.pylint.main]
# Add files or directories matching the regular expressions patterns to the
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\\' represents the directory delimiter on Windows systems, it
# can't be used as an escape character.
# Unfortunately this does not what I expect. I get errors from the submodule.
ignore-paths = 'flinventoryGUI/flinventory/.*'
# List of module names for which member attributes should not be checked and will
# not be imported (useful for modules/projects where namespaces are manipulated
# during runtime and thus existing member attributes cannot be deduced by static
# analysis). It supports qualified module names, as well as Unix pattern
# matching.
ignored-modules=flinventoryGUI.flinventory.part
# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode = true
[MESSAGES CONTROL]
disable=logging-format-interpolation,logging-not-lazy,logging-fstring-interpolation

View file

@ -3,3 +3,15 @@
A GUI for the flinventory project/ data format.
Currently only intended for bike part lists.
It's run with `python flinventory_gui/search.py`.
## Packages and importing
I still don't understand the import and package mechanism of python.
I tried a lot of different combinations of . and import and import from
but could not get search.py working at the same time as keeping the
scripts like datacleanup.py in flinventory working.
My terrible workaround now is to symlink the necessary python files
in flinventory_gui from the subdirectory (and submodule) inventory.
Please fix this if you have understood python import mechanism.

16
environment.yml Normal file
View file

@ -0,0 +1,16 @@
# this file specifies what the suitable conda environment for this
# project looks like
name: bikeparts-gui
channels:
- conda-forge
dependencies:
# from submodule flinventory:
- pypandoc
- python-slugify
- imagesize
- treelib
- pylint
- mypy
# imagemagick for datacleanup rotate
- nicegui

View file

@ -0,0 +1,7 @@
"""This is run if the module is run as python -m flinventory_gui.
The GUI is served in a web browser.
"""
from . import search
search.search_page()

1
flinventory_gui/location.py Symbolic link
View file

@ -0,0 +1 @@
flinventory/location.py

1
flinventory_gui/part.py Symbolic link
View file

@ -0,0 +1 @@
flinventory/part.py

80
flinventory_gui/search.py Normal file
View file

@ -0,0 +1,80 @@
"""Search in a parts list."""
import asyncio
from typing import Optional, Iterable, NamedTuple
import nicegui
from nicegui import ui
from part import Part
class ImageDirectories(NamedTuple):
images_landscape: str
images_portrait: str
DEFAULT_IMAGE_DIRECTORIES = ImageDirectories(images_landscape = "", images_portrait = "")
async def find_parts(search_string: str) -> list[Part]:
"""Gives parts that the user might have searched for.
Args:
search_string: Input of user
Returns:
list of parts that somehow include the search string
"""
return [Part({"name_de": "Dummy thing"}, DEFAULT_IMAGE_DIRECTORIES, {})]
def list_parts(ui_element: nicegui.ui.element, parts: Iterable[Part]) -> None:
"""Replaces content of ui_element with information about the parts.
Args:
ui_element: Some UI element that can be changed.
parts: list of parts to be displayed.
"""
ui_element.clear()
with ui_element:
# enter the context of the the ui element
# inside this context all ui things are placed in this element
if not parts:
ui.label("Nothing found.")
else:
for part in parts:
ui.label(part.name)
def search_page() -> None:
"""Add a search page to the UI."""
results: Optional[ui.element] = None
"""UI container for the search results."""
running_queries: list[asyncio.Task] = []
"""Search queries (max. 1) running. Here to be cancellable by different search coroutines."""
async def search(event: nicegui.events.ValueChangeEventArguments) -> None:
"""Search for cocktails as you type.
Args:
event: the input field change event. The new value event.value is used.
"""
if running_queries:
for query in running_queries:
query.cancel()
query = asyncio.create_task(find_parts(event.value))
running_queries.append(query)
try:
response = await query
except asyncio.exceptions.CancelledError:
pass
else:
if results:
list_parts(results, response)
else:
ui.notify("Internal error: results element is None.")
search_field = ui.input(on_change=search) \
.props('autofocus outlined rounded item-aligned input-class="ml-3"') \
.classes('w-96 self-center mt-24 transition-all')
results = ui.column()
if __name__ in {"__main__", "__mp_main__"}:
search_page()
ui.run()

1
flinventory_gui/sign.py Symbolic link
View file

@ -0,0 +1 @@
flinventory/sign.py