110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
send_task.py — отправить задание на сервер-реле vprok.ru
|
||
|
||
Стрим вызывает этот скрипт когда нужно заполнить корзину:
|
||
python3 send_task.py "молоко 1, яйца С1 10шт, йогурт Активиа 4шт"
|
||
|
||
Формат строки:
|
||
<название товара> <количество>[шт], ...
|
||
|
||
Примеры:
|
||
python3 send_task.py "молоко 2, хлеб 1, масло сливочное 3шт"
|
||
python3 send_task.py "яйца С1 10, кефир Простоквашино 2шт, сметана 20% 1"
|
||
"""
|
||
|
||
import sys
|
||
import re
|
||
import json
|
||
import urllib.request
|
||
import urllib.error
|
||
|
||
SERVER_URL = "http://185.130.212.192:5000"
|
||
API_KEY = "vprok2024secret"
|
||
HEADERS = {"X-Api-Key": API_KEY, "Content-Type": "application/json"}
|
||
|
||
|
||
def parse_items(raw: str) -> list[dict]:
|
||
"""
|
||
Парсит строку вида "молоко 2, яйца С1 10шт, хлеб"
|
||
в список [{"query": "молоко", "qty": 2}, ...]
|
||
"""
|
||
items = []
|
||
# Разбиваем по запятой
|
||
parts = [p.strip() for p in raw.split(",") if p.strip()]
|
||
|
||
for part in parts:
|
||
# Ищем число в конце (возможно с "шт")
|
||
m = re.search(r'\s+(\d+)\s*шт?\.?$', part, re.IGNORECASE)
|
||
if m:
|
||
qty = int(m.group(1))
|
||
query = part[:m.start()].strip()
|
||
else:
|
||
# Попробуем просто число в конце
|
||
m2 = re.search(r'\s+(\d+)$', part)
|
||
if m2:
|
||
qty = int(m2.group(1))
|
||
query = part[:m2.start()].strip()
|
||
else:
|
||
qty = 1
|
||
query = part.strip()
|
||
|
||
if query:
|
||
items.append({"query": query, "qty": qty})
|
||
|
||
return items
|
||
|
||
|
||
def send_task(items: list) -> dict:
|
||
"""Отправляет задание на сервер. Возвращает ответ сервера."""
|
||
payload = json.dumps({"items": items}).encode("utf-8")
|
||
req = urllib.request.Request(
|
||
f"{SERVER_URL}/task",
|
||
data=payload,
|
||
headers=HEADERS,
|
||
method="POST"
|
||
)
|
||
with urllib.request.urlopen(req, timeout=15) as resp:
|
||
return json.loads(resp.read().decode())
|
||
|
||
|
||
def get_status() -> dict:
|
||
"""Получить текущий статус."""
|
||
req = urllib.request.Request(f"{SERVER_URL}/status", headers={"X-Api-Key": API_KEY})
|
||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||
return json.loads(resp.read().decode())
|
||
|
||
|
||
def main():
|
||
if len(sys.argv) < 2:
|
||
print(__doc__)
|
||
sys.exit(1)
|
||
|
||
raw = " ".join(sys.argv[1:])
|
||
items = parse_items(raw)
|
||
|
||
if not items:
|
||
print("❌ Не удалось распознать товары в строке:", raw)
|
||
sys.exit(1)
|
||
|
||
print(f"📋 Распознано {len(items)} товар(ов):")
|
||
for i, item in enumerate(items, 1):
|
||
print(f" {i}. {item['query']} × {item['qty']}")
|
||
|
||
print(f"\n📡 Отправляю на {SERVER_URL}...")
|
||
try:
|
||
result = send_task(items)
|
||
print(f"✅ Задание принято! ID: {result.get('task_id')}, товаров: {result.get('items_count')}")
|
||
print(" Windows клиент заберёт задание в течение 30 секунд.")
|
||
except urllib.error.HTTPError as e:
|
||
print(f"❌ HTTP ошибка: {e.code} — {e.read().decode()}")
|
||
sys.exit(1)
|
||
except urllib.error.URLError as e:
|
||
print(f"❌ Не удалось подключиться к серверу {SERVER_URL}: {e.reason}")
|
||
print(" Проверьте, запущен ли сервер-реле.")
|
||
sys.exit(1)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|