This commit is contained in:
xds
2026-02-06 19:53:05 +03:00
parent 553335940f
commit 137279bcc5
8 changed files with 29 additions and 14 deletions

View File

@@ -15,6 +15,7 @@ from models.Asset import Asset, AssetType
from models.Generation import Generation, GenerationStatus from models.Generation import Generation, GenerationStatus
from models.enums import AspectRatios, Quality, GenType from models.enums import AspectRatios, Quality, GenType
from repos.dao import DAO from repos.dao import DAO
from adapters.s3_adapter import S3Adapter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -25,7 +26,8 @@ async def generate_image_task(
media_group_bytes: List[bytes], media_group_bytes: List[bytes],
aspect_ratio: AspectRatios, aspect_ratio: AspectRatios,
quality: Quality, quality: Quality,
gemini: GoogleAdapter gemini: GoogleAdapter,
) -> Tuple[List[bytes], Dict[str, Any]]: ) -> Tuple[List[bytes], Dict[str, Any]]:
""" """
Обертка для вызова синхронного метода Gemini в отдельном потоке. Обертка для вызова синхронного метода Gemini в отдельном потоке.
@@ -60,9 +62,10 @@ async def generate_image_task(
return images_bytes, metrics return images_bytes, metrics
class GenerationService: class GenerationService:
def __init__(self, dao: DAO, gemini: GoogleAdapter, bot: Optional[Bot] = None): def __init__(self, dao: DAO, gemini: GoogleAdapter, s3_adapter: S3Adapter, bot: Optional[Bot] = None):
self.dao = dao self.dao = dao
self.gemini = gemini self.gemini = gemini
self.s3_adapter = s3_adapter
self.bot = bot self.bot = bot
@@ -169,13 +172,21 @@ class GenerationService:
generation_prompt = generation_prompt.replace("$char_bio_inserted", f"1. CHARACTER BIO (Must be strictly followed): {char_info.character_bio}") generation_prompt = generation_prompt.replace("$char_bio_inserted", f"1. CHARACTER BIO (Must be strictly followed): {char_info.character_bio}")
reference_assets = await self.dao.assets.get_assets_by_ids(generation.assets_list) reference_assets = await self.dao.assets.get_assets_by_ids(generation.assets_list)
# Извлекаем данные (bytes) из ассетов для отправки в Gemini # Извлекаем данные (bytes) из ассетов для отправки в Gemini
# Фильтруем, чтобы отправлять только картинки, и где есть data for asset in reference_assets:
media_group_bytes.extend( if asset.type != AssetType.IMAGE:
asset.data continue
for asset in reference_assets
if asset.data is not None and asset.type == AssetType.IMAGE img_data = None
) if asset.minio_object_name:
img_data = await self.s3_adapter.get_file(asset.minio_object_name)
elif asset.data:
img_data = asset.data
if img_data:
media_group_bytes.append(img_data)
if media_group_bytes: if media_group_bytes:
generation_prompt += " \n\n[Reference Image Guidance]: Use the provided image(s) as the STRICT reference for the main character's facial features and hair, enviroment or clothes. Maintain high fidelity to the reference identity." generation_prompt += " \n\n[Reference Image Guidance]: Use the provided image(s) as the STRICT reference for the main character's facial features and hair, enviroment or clothes. Maintain high fidelity to the reference identity."
@@ -230,18 +241,21 @@ class GenerationService:
for idx, img_bytes in enumerate(generated_bytes_list): for idx, img_bytes in enumerate(generated_bytes_list):
# Generate thumbnail # Generate thumbnail
thumbnail_bytes = None thumbnail_bytes = None
# Assuming AssetType.IMAGE since we are in generated_bytes_list which are images usually
# Or use explicit check if we have distinct types in list (not currently)
from utils.image_utils import create_thumbnail from utils.image_utils import create_thumbnail
thumbnail_bytes = await asyncio.to_thread(create_thumbnail, img_bytes) thumbnail_bytes = await asyncio.to_thread(create_thumbnail, img_bytes)
# Save to S3
filename = f"generated/{generation.linked_character_id}/{datetime.now().strftime('%Y%m%d_%H%M%S')}_{random.randint(1000, 9999)}.png"
await self.s3_adapter.upload_file(filename, img_bytes, content_type="image/png")
new_asset = Asset( new_asset = Asset(
name=f"Generated_{generation.linked_character_id}_{random.randint(1000, 9999)}", name=f"Generated_{generation.linked_character_id}",
type=AssetType.IMAGE, type=AssetType.IMAGE,
linked_char_id=generation.linked_character_id, # Если генерация привязана к персонажу linked_char_id=generation.linked_character_id,
data=img_bytes, data=None, # Not storing bytes in DB anymore
minio_object_name=filename,
minio_bucket=self.s3_adapter.bucket_name,
thumbnail=thumbnail_bytes thumbnail=thumbnail_bytes
# Остальные поля заполнятся дефолтными значениями (created_at)
) )
# Сохраняем в БД # Сохраняем в БД

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
{"version":"1","format":"xl-single","id":"22cb59f6-a28f-4194-824b-0bc79aaeaa13","xl":{"version":"3","this":"07eaea19-42ca-4e79-b42a-5b6349962b4f","sets":[["07eaea19-42ca-4e79-b42a-5b6349962b4f"]],"distributionAlgo":"SIPMOD+PARITY"}}

Binary file not shown.