114 lines
4.7 KiB
Python
114 lines
4.7 KiB
Python
"""Тестовая страница: прикрепляете .zip с XML, он распаковывается,
|
||
обрабатывается тем же парсером, что и прод, а готовый отчёт/протокол/лог
|
||
грузятся в OpenCloud. Без SMB на входе — специально для локального теста
|
||
всей цепочки целиком.
|
||
|
||
Не трогает main.py и основной SMB-пайплайн.
|
||
|
||
Запуск:
|
||
streamlit run scripts/local_zip_test_app.py
|
||
|
||
Токен/папку можно один раз прописать в .env (см. .env.example) — поля
|
||
на странице предзаполнятся, но их всегда можно поменять руками.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
import sys
|
||
import tempfile
|
||
from pathlib import Path
|
||
|
||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||
|
||
import streamlit as st
|
||
from dotenv import load_dotenv
|
||
|
||
from app.app_config import OPENCLOUD_SPACE_ID
|
||
from app.pipeline.service import run_local_zip_batch
|
||
|
||
load_dotenv()
|
||
|
||
st.set_page_config(page_title="СФМ — локальный тест", page_icon="📦")
|
||
st.title("Локальный тест: zip → обработка → OpenCloud")
|
||
st.caption(
|
||
"Прикрепляете .zip с XML-файлами, он распаковывается и обрабатывается "
|
||
"тем же кодом парсинга, что и прод (app/pipeline/parser.py), а отчёт, "
|
||
"протокол и лог грузятся в OpenCloud (app/opencloud_access.py). "
|
||
"SMB тут не используется вообще."
|
||
)
|
||
|
||
username = st.text_input(
|
||
"Username (для Basic Auth в OpenCloud)",
|
||
value=os.getenv("SFM_OPENCLOUD_USERNAME", ""),
|
||
help="Логин, под которым заказчик создал App Token в OpenCloud. Можно прописать в .env как SFM_OPENCLOUD_USERNAME.",
|
||
)
|
||
access_token = st.text_input(
|
||
"App Token",
|
||
value=os.getenv("SFM_OPENCLOUD_ACCESS_TOKEN", ""),
|
||
type="password",
|
||
help=(
|
||
"Долгоживущий App Token из веб-интерфейса OpenCloud (не Bearer из Keycloak — "
|
||
"авторизация теперь через HTTP Basic Auth). Можно прописать в .env как "
|
||
"SFM_OPENCLOUD_ACCESS_TOKEN."
|
||
),
|
||
)
|
||
space_id = st.text_input(
|
||
"SPACE_ID",
|
||
value=os.getenv("SFM_OPENCLOUD_SPACE_ID", OPENCLOUD_SPACE_ID),
|
||
)
|
||
folder = st.text_input(
|
||
"Папка (личная папка участника в OpenCloud)",
|
||
value=os.getenv("SFM_OPENCLOUD_FOLDER", ""),
|
||
placeholder="Райков М.С.",
|
||
)
|
||
launcher = st.text_input("Запустил (для протокола)", value="local-test")
|
||
|
||
uploaded_zip = st.file_uploader("Архив с XML-файлами (.zip)", type=["zip"])
|
||
|
||
if st.button("Начать обработку", type="primary", use_container_width=True):
|
||
if not username:
|
||
st.error("Укажите username.")
|
||
elif not access_token:
|
||
st.error("Укажите App Token.")
|
||
elif not folder:
|
||
st.error("Укажите папку.")
|
||
elif uploaded_zip is None:
|
||
st.error("Прикрепите .zip-архив.")
|
||
else:
|
||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||
zip_path = Path(tmp_dir) / uploaded_zip.name
|
||
zip_path.write_bytes(uploaded_zip.getvalue())
|
||
with st.spinner("Распаковываем, обрабатываем, грузим в OpenCloud..."):
|
||
result = run_local_zip_batch(
|
||
zip_path=zip_path,
|
||
launcher=launcher or "local-test",
|
||
opencloud_space_id=space_id,
|
||
opencloud_folder=folder,
|
||
opencloud_username=username,
|
||
opencloud_access_token=access_token,
|
||
)
|
||
|
||
if result.status == "success":
|
||
st.success("Обработка завершена успешно.")
|
||
elif result.status == "partial":
|
||
st.warning("Обработка завершена частично.")
|
||
else:
|
||
st.error("Обработка завершена с ошибками.")
|
||
|
||
st.write(
|
||
{
|
||
"processed": result.processed,
|
||
"partial": result.partial,
|
||
"errors": result.errors,
|
||
"report_path": result.report_path,
|
||
"protocol_path": result.protocol_path,
|
||
"log_path": result.log_path,
|
||
"duration_seconds": result.duration_seconds,
|
||
}
|
||
)
|
||
if result.messages:
|
||
st.caption("Сообщения обработки:")
|
||
for message in result.messages:
|
||
st.write(f"- {message}")
|