This commit is contained in:
Nikita Tyukalov, ASUS, Work
2026-02-11 21:30:56 +03:00
parent 3f518221ea
commit 7c07a0f8a1
3 changed files with 129 additions and 1 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
__pycache__ __pycache__
warehouse_*/
*.swo *.swo
*.swp *.swp
*.json *.json

View File

@@ -1,5 +1,6 @@
# 2026-linux-skladman # 2026-linux-skladman
## Что это ## Что это
`2026-linux-skladman` - это ИИ-сервис для учёта вещей на складе. Он позволяет: `2026-linux-skladman` - это ИИ-сервис для учёта вещей на складе. Он позволяет:
@@ -15,3 +16,40 @@
Учтено то, что может возникнуть необходимость работы как с self-hosted LLM, так Учтено то, что может возникнуть необходимость работы как с self-hosted LLM, так
и с крупными ИИ-сервисами (Gemini, OpenAI и т.д.). и с крупными ИИ-сервисами (Gemini, OpenAI и т.д.).
## Пример взаимодействия
#### Найти что-то и взять сколько-нибудь
```
USER: Мне надо из 12 вольт сделать 5 вольт
SYSTEM: В "Y12" лежат buck DCDC преобразователи, 5 штук
USER: Взял 2
SYSTEM: Записал, что их осталось 3 штуки
```
#### Узнать, что лежит в ячейке, и исправить данные
```
USER: че в s3
SYSTEM: В "S3" лежат 12 штук Arduino
USER: уже нет, они переехали в p4
SYSTEM: Записал, что теперь в "S3" пусто, а в "P4" лежит 12 штук Arduino.
```
#### Реорганизация склада
```
USER: Мы объединили S3 и S4, теперь оно называется Q2
SYSTEM: Записал, что больше ячеек S3 и S4 не существуют, но теперь есть
ячейка Q2, в которой лежат Arduino (12 штук) и ESP32 (5 штук).
USER: И ещё ардуин осталось 8, а есп кончились
SYSTEM: Записал, что теперь в Q2 лежат 8 штук Arduino
```
#### И так далее
## Структура файлов
* `main.py` - скрипт, который нужно запускать
* `config.json` - конфигурация сервиса, генерируется автоматически при первом запуске
* `warehouse_<NAME>/` - папка с данными склада, не редактируйте файлы оттуда вручную

89
warehouse.py Normal file
View File

@@ -0,0 +1,89 @@
""" Warehouse API """
import os
from dataclasses import dataclass
#
# Dataclasses
#
@dataclass
class WarehouseLocation:
""" Location inside warehouse """
# human readable name of location within warehouse
name: str
# description on how to find the location
how_to_find: str = 'Somewhere inside the warehouse'
# remarks
remarks: str = ''
@dataclass
class WarehouseItem:
""" Item stored within warehouse """
# human readable name of item
name: str
# human readable name of measurement unit
unit: str = 'units'
# count of item in units
count: int = 1
# remarks
remarks: str = ''
# location ID where the item is stored
location_id: int = 0
#
# Private
#
_warehouse_name = None
_warehouse_path = None
_locations = {}
_entries = {}
async def _read_file(path: str) -> str:
""" Read file content and strip it.
Empty string on error.
"""
try:
with open(path, 'r') as f:
return f.read().strip()
except:
return ''
async def _write_file(path: str, content: str) -> bool:
""" Write file content. """
try:
with open(path, 'w') as f:
f.write(content)
return True
except:
return False
async def _fsck_warehouse(path: str) -> bool:
""" Check warehouse for errors and fix them if possible.
Returns True if warehouse is usable.
"""
if not os.path.isdir(path):
return False
async def _create_warehouse(path: str) -> bool:
""" Create warehouse.
Returns True if warehouse is usable.
"""
if os.path.isdir(path):
return await _fsck_warehouse(path)
locations[0] = WarehouseLocation(
name='Unsorted',
how_to_find='',
remarks='Pseudolocation for unsorted items'
)
#
# Public
#
async def init(name: str) -> bool:
""" Initialize warehouse API. """
global _warehouse_name, _warehouse_path
_warehouse_name = name
_warehouse_path = f'warehouse_{name}'
return await _create_warehouse(_warehouse_path)