Add upload images

This commit is contained in:
2026-01-04 04:58:41 +07:00
parent 81d992abe6
commit 65b2512d8c
4 changed files with 502 additions and 31 deletions

View File

@@ -1,8 +1,9 @@
from datetime import datetime
from fastapi import APIRouter, HTTPException, Query, Request
from fastapi import APIRouter, HTTPException, Query, Request, UploadFile, File, Form
from sqlalchemy import select, func
from sqlalchemy.orm import selectinload
from pydantic import BaseModel, Field
from typing import Optional
from app.api.deps import DbSession, CurrentUser, require_admin_with_2fa
from app.models import (
@@ -531,9 +532,10 @@ async def get_logs(
@limiter.limit("1/minute")
async def broadcast_to_all(
request: Request,
data: BroadcastRequest,
current_user: CurrentUser,
db: DbSession,
message: str = Form(""),
media: list[UploadFile] = File(default=[]),
):
"""Send broadcast message to all users with Telegram linked. Admin only."""
require_admin_with_2fa(current_user)
@@ -547,15 +549,40 @@ async def broadcast_to_all(
total_count = len(users)
sent_count = 0
# Read media files if provided (up to 10 files, Telegram limit)
media_items = []
for file in media[:10]:
if file and file.filename:
file_data = await file.read()
content_type = file.content_type or ""
if content_type.startswith("image/"):
media_items.append({
"type": "photo",
"data": file_data,
"filename": file.filename,
"content_type": content_type
})
elif content_type.startswith("video/"):
media_items.append({
"type": "video",
"data": file_data,
"filename": file.filename,
"content_type": content_type
})
for user in users:
if await telegram_notifier.send_message(user.telegram_id, data.message):
if await telegram_notifier.send_media_message(
user.telegram_id,
text=message if message.strip() else None,
media_items=media_items if media_items else None
):
sent_count += 1
# Log action
await log_admin_action(
db, current_user.id, AdminActionType.BROADCAST_ALL.value,
"broadcast", 0,
{"message": data.message[:100], "sent": sent_count, "total": total_count},
{"message": message[:100], "sent": sent_count, "total": total_count, "media_count": len(media_items)},
request.client.host if request.client else None
)
@@ -567,9 +594,10 @@ async def broadcast_to_all(
async def broadcast_to_marathon(
request: Request,
marathon_id: int,
data: BroadcastRequest,
current_user: CurrentUser,
db: DbSession,
message: str = Form(""),
media: list[UploadFile] = File(default=[]),
):
"""Send broadcast message to marathon participants. Admin only."""
require_admin_with_2fa(current_user)
@@ -580,7 +608,7 @@ async def broadcast_to_marathon(
if not marathon:
raise HTTPException(status_code=404, detail="Marathon not found")
# Get participants count
# Get participants with telegram
total_result = await db.execute(
select(User)
.join(Participant, Participant.user_id == User.id)
@@ -592,15 +620,41 @@ async def broadcast_to_marathon(
users = total_result.scalars().all()
total_count = len(users)
sent_count = await telegram_notifier.notify_marathon_participants(
db, marathon_id, data.message
)
# Read media files if provided (up to 10 files, Telegram limit)
media_items = []
for file in media[:10]:
if file and file.filename:
file_data = await file.read()
content_type = file.content_type or ""
if content_type.startswith("image/"):
media_items.append({
"type": "photo",
"data": file_data,
"filename": file.filename,
"content_type": content_type
})
elif content_type.startswith("video/"):
media_items.append({
"type": "video",
"data": file_data,
"filename": file.filename,
"content_type": content_type
})
sent_count = 0
for user in users:
if await telegram_notifier.send_media_message(
user.telegram_id,
text=message if message.strip() else None,
media_items=media_items if media_items else None
):
sent_count += 1
# Log action
await log_admin_action(
db, current_user.id, AdminActionType.BROADCAST_MARATHON.value,
"marathon", marathon_id,
{"title": marathon.title, "message": data.message[:100], "sent": sent_count, "total": total_count},
{"title": marathon.title, "message": message[:100], "sent": sent_count, "total": total_count, "media_count": len(media_items)},
request.client.host if request.client else None
)