diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f5daecf --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +__pycache__/ +**/__pycache__/ +*.pyc +*.pyo +.env +data/ +*.db +.git/ diff --git a/Dockerfile b/Dockerfile index e0d7084..7c938dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,15 @@ -FROM python:3.12-slim +FROM python:3.11-slim + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 WORKDIR /app -# Устанавливаем maxapi из локального источника -# (build context = родительская папка caps/) -COPY maxapi-main/ /maxapi-main/ -RUN pip install --no-cache-dir /maxapi-main/ - -# Устанавливаем зависимости приложения -COPY support_bot/requirements.txt ./requirements.txt +COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Копируем исходный код -COPY support_bot/ . +COPY . . -# Папка для SQLite-файла RUN mkdir -p /app/data EXPOSE 8080 diff --git a/admin/routes/bot_users.py b/admin/routes/bot_users.py index 38c8c13..046d52b 100644 --- a/admin/routes/bot_users.py +++ b/admin/routes/bot_users.py @@ -23,9 +23,9 @@ async def list_bot_users( ) orgs = await get_all_organizations() return templates.TemplateResponse( - "bot_users/list.html", - { - "request": request, + request=request, + name="bot_users/list.html", + context={ "users": users, "orgs": orgs, "filter_authorized": is_authorized, diff --git a/admin/routes/chat_log.py b/admin/routes/chat_log.py index a6a4406..9baa100 100644 --- a/admin/routes/chat_log.py +++ b/admin/routes/chat_log.py @@ -12,7 +12,7 @@ router = APIRouter(prefix="/chat-log", dependencies=[Depends(require_admin)]) async def chat_list(request: Request): chats = await get_chat_list() return templates.TemplateResponse( - "chat_log/list.html", {"request": request, "chats": chats} + request=request, name="chat_log/list.html", context={"chats": chats} ) @@ -20,6 +20,7 @@ async def chat_list(request: Request): async def chat_history(request: Request, max_user_id: int): messages = await get_message_log(max_user_id=max_user_id, limit=200) return templates.TemplateResponse( - "chat_log/history.html", - {"request": request, "messages": messages, "max_user_id": max_user_id}, + request=request, + name="chat_log/history.html", + context={"messages": messages, "max_user_id": max_user_id}, ) diff --git a/admin/routes/org_users.py b/admin/routes/org_users.py index 876025d..2843d02 100644 --- a/admin/routes/org_users.py +++ b/admin/routes/org_users.py @@ -28,8 +28,9 @@ async def list_org_users(request: Request, org_id: int | None = None): users = await get_org_users(org_id=org_id) orgs = await get_all_organizations() return templates.TemplateResponse( - "org_users/list.html", - {"request": request, "users": users, "orgs": orgs, "filter_org_id": org_id}, + request=request, + name="org_users/list.html", + context={"users": users, "orgs": orgs, "filter_org_id": org_id}, ) @@ -37,7 +38,7 @@ async def list_org_users(request: Request, org_id: int | None = None): async def create_org_user_form(request: Request): orgs = await get_all_organizations() return templates.TemplateResponse( - "org_users/create.html", {"request": request, "orgs": orgs} + request=request, name="org_users/create.html", context={"orgs": orgs} ) diff --git a/admin/routes/organizations.py b/admin/routes/organizations.py index dcc98ac..0005d1c 100644 --- a/admin/routes/organizations.py +++ b/admin/routes/organizations.py @@ -19,13 +19,13 @@ router = APIRouter(prefix="/orgs", dependencies=[Depends(require_admin)]) async def list_orgs(request: Request): orgs = await get_all_organizations() return templates.TemplateResponse( - "orgs/list.html", {"request": request, "orgs": orgs} + request=request, name="orgs/list.html", context={"orgs": orgs} ) @router.get("/create", response_class=HTMLResponse) async def create_org_form(request: Request): - return templates.TemplateResponse("orgs/create.html", {"request": request}) + return templates.TemplateResponse(request=request, name="orgs/create.html", context={}) @router.post("/create") @@ -39,7 +39,7 @@ async def create_org(name: str = Form(...)): async def edit_org_form(request: Request, org_id: int): org = await get_organization(org_id) return templates.TemplateResponse( - "orgs/edit.html", {"request": request, "org": org} + request=request, name="orgs/edit.html", context={"org": org} ) diff --git a/admin/routes/tickets.py b/admin/routes/tickets.py index 64fe796..e3498bd 100644 --- a/admin/routes/tickets.py +++ b/admin/routes/tickets.py @@ -19,9 +19,9 @@ async def list_tickets( tickets = await get_all_tickets(org_id=org_id, status=status) orgs = await get_all_organizations() return templates.TemplateResponse( - "tickets/list.html", - { - "request": request, + request=request, + name="tickets/list.html", + context={ "tickets": tickets, "orgs": orgs, "filter_org_id": org_id, @@ -35,8 +35,9 @@ async def ticket_detail(request: Request, ticket_id: int): ticket = await get_ticket(ticket_id) attachments = await get_attachments(ticket_id) return templates.TemplateResponse( - "tickets/detail.html", - {"request": request, "ticket": ticket, "attachments": attachments}, + request=request, + name="tickets/detail.html", + context={"ticket": ticket, "attachments": attachments}, ) diff --git a/data/support.db-shm b/data/support.db-shm index e5c8a31..38e97fb 100644 Binary files a/data/support.db-shm and b/data/support.db-shm differ diff --git a/data/support.db-wal b/data/support.db-wal index b55e7d7..976552e 100644 Binary files a/data/support.db-wal and b/data/support.db-wal differ diff --git a/docker-compose.yml b/docker-compose.yml index 6f00780..e1bce85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,12 @@ services: support_bot: - build: - context: .. # родительская папка caps/ — нужна для доступа к maxapi-main/ - dockerfile: support_bot/Dockerfile + build: . env_file: .env environment: - DB_PATH: /app/data/support.db # переопределяем путь внутри контейнера + DB_PATH: /app/data/support.db ADMIN_HOST: "0.0.0.0" ports: - "${ADMIN_PORT:-8080}:8080" volumes: - - ./data:/app/data # SQLite-файл живёт здесь — данные сохраняются между перезапусками + - ./data:/app/data restart: unless-stopped