From 137279bcc5030d71b4e3440141137b5bb104dd88 Mon Sep 17 00:00:00 2001 From: xds Date: Fri, 6 Feb 2026 19:53:05 +0300 Subject: [PATCH] fix --- api/service/generation_service.py | 42 ++++++++++++------ .../.minio.sys/buckets/.heal/mrf/list.bin | Bin 0 -> 4 bytes .../.minio.sys/config/config.json/xl.meta | Bin 0 -> 9811 bytes .../.minio.sys/config/iam/format.json/xl.meta | Bin 0 -> 434 bytes minio_data/.minio.sys/format.json | 1 + minio_data/.minio.sys/pool.bin/xl.meta | Bin 0 -> 479 bytes .../tmp/c5ee5e82-c0e5-43dc-a6db-06e7913fe449 | Bin 0 -> 2049 bytes models/__pycache__/Generation.cpython-313.pyc | Bin 2470 -> 2496 bytes 8 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 minio_data/.minio.sys/buckets/.heal/mrf/list.bin create mode 100644 minio_data/.minio.sys/config/config.json/xl.meta create mode 100644 minio_data/.minio.sys/config/iam/format.json/xl.meta create mode 100644 minio_data/.minio.sys/format.json create mode 100644 minio_data/.minio.sys/pool.bin/xl.meta create mode 100644 minio_data/.minio.sys/tmp/c5ee5e82-c0e5-43dc-a6db-06e7913fe449 diff --git a/api/service/generation_service.py b/api/service/generation_service.py index 75ab456..e217ab1 100644 --- a/api/service/generation_service.py +++ b/api/service/generation_service.py @@ -15,6 +15,7 @@ from models.Asset import Asset, AssetType from models.Generation import Generation, GenerationStatus from models.enums import AspectRatios, Quality, GenType from repos.dao import DAO +from adapters.s3_adapter import S3Adapter logger = logging.getLogger(__name__) @@ -25,7 +26,8 @@ async def generate_image_task( media_group_bytes: List[bytes], aspect_ratio: AspectRatios, quality: Quality, - gemini: GoogleAdapter + gemini: GoogleAdapter, + ) -> Tuple[List[bytes], Dict[str, Any]]: """ Обертка для вызова синхронного метода Gemini в отдельном потоке. @@ -60,9 +62,10 @@ async def generate_image_task( return images_bytes, metrics 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.gemini = gemini + self.s3_adapter = s3_adapter 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}") reference_assets = await self.dao.assets.get_assets_by_ids(generation.assets_list) + # Извлекаем данные (bytes) из ассетов для отправки в Gemini - # Фильтруем, чтобы отправлять только картинки, и где есть data - media_group_bytes.extend( - asset.data - for asset in reference_assets - if asset.data is not None and asset.type == AssetType.IMAGE - ) + for asset in reference_assets: + if asset.type != AssetType.IMAGE: + continue + + 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: 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): # Generate thumbnail 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 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( - name=f"Generated_{generation.linked_character_id}_{random.randint(1000, 9999)}", + name=f"Generated_{generation.linked_character_id}", type=AssetType.IMAGE, - linked_char_id=generation.linked_character_id, # Если генерация привязана к персонажу - data=img_bytes, + linked_char_id=generation.linked_character_id, + data=None, # Not storing bytes in DB anymore + minio_object_name=filename, + minio_bucket=self.s3_adapter.bucket_name, thumbnail=thumbnail_bytes - # Остальные поля заполнятся дефолтными значениями (created_at) ) # Сохраняем в БД diff --git a/minio_data/.minio.sys/buckets/.heal/mrf/list.bin b/minio_data/.minio.sys/buckets/.heal/mrf/list.bin new file mode 100644 index 0000000000000000000000000000000000000000..a3568729c698aec1d183514222bafc72dafa7007 GIT binary patch literal 4 LcmZQ%U}OLQ015yD literal 0 HcmV?d00001 diff --git a/minio_data/.minio.sys/config/config.json/xl.meta b/minio_data/.minio.sys/config/config.json/xl.meta new file mode 100644 index 0000000000000000000000000000000000000000..8ecef2b9d88c84bb155f5f4057f5528d6a5dbef1 GIT binary patch literal 9811 zcmeHNPl#Me8J{M>lZO>t@FEP&vcaW$X3{g0nIs_Ynh_Q@tB@#ytVMNIb$6xfy?Rqs zZ)Q4Sz+FL6VIe0y8qJzjT=e2e7ZfH692bP2LoLSc1pHmltC$4myClBCWgKdGoW^ z(kPqq<`<}OFQ<{c-TATqxO1J3?XR5Dzuxtq;O954UYC(5Pjm08 zaP->DzWS?!ek5b5`!aUI#8kltC1cU&)X}4}&ZHv4e$krO?!uh$pO)Fi#`gBc#`@-f zUEo{Wn|yO~jd3wpzeqRMh8q`u$~3GMyS@V%{hTI=l8id3P`tIu0 zTV0yS?xkB@(!KPRTivOcbuV>|*iD6XmPGWR+w1O8l?wQIt$WxzhA@>{I2Yl9a(^rY zJHKWzP#a6AQhJ|gBgZmE$mbBwh)6p@oT0Hzv~f)<4<=}W0v(dwRGTzHOIl|na|mWc zDJGH_343regr}*~EoeAA+1F+&j71YR*RUAy>K?DmxM9wDJS97!^lEEFVyJag36dsC zQ*H@Ug2rh=GJ^u0piN!Cf(d7dgG3s9;=u+6bD;!?ea_mO5t0v=mJVT0noA=<&L_r! zK=nZ#qv7#QnGij^0rRn7^=O1ZMr%hXW5Na)ypEm4jEFsOhyW5SlRw7WG1&t>g3vMc z;$X18zBO1|zp%Zzv9-0iy|&doeC4p$r74$=OzCJ!tG*#(F93A#aNkZRlA%#_q@mFj zTS9}DT18UpBSnN)uR;=PEf^(lenhrPB-n(;(qgwr6a~-2?khoV#3?W!dbD>=f(;v?oV+4D`?H3DI4*cZcz*3(nkgNS*e!DE9(%P8taMjV(0j*4hcg$5R?s8u~f>e!@qbo7J| zBb)LV-o1=)L72g!&BmJI);i7<6Xz1*AerhEi)#}w-Y2u8RHcvOZxO4>K9zX>T7(}0 zk}}$5S@Ssj&YzIQ&&Bv`heq#%2UqvVY(f$Zxf+`<7bBV~*SCf(pR+=Z&MluyV@pS( zFCey`e9KwGxy#Fz8JPqVyuj?G)zvgkrsEZ+qsz<7KoMdHta#lz4C#O3)4UZhjbksw z+RGp^hK$d_i_#(25d;&A4t+7hCr0?Jh0Hz#88H&Z0D-7UCePsgoGkSBCnD}MqpdA| z$&Gaf=uBc*5{2=E}JtR5i>JO ze6DX5gg5|7S4~VS?!fg{lpgn1nBD8Gcz)Mgan$ry4kFcC83w^T0-qtC6Jnh>Sa|ih zUX>*VKlrs^DQae`nmGYhlKHBg&fsSZ%#+r_(CPuC8ejeH zCjux~AOo3+#?6T0G^rn~!W+xx4h_;$gCXAwLL8f~5v$ z`7r1dI3UQz!P@A&Ax=S_hqHid@Ky<8Od~1tHd0!IPDCsljJ@3^fN2A1o6XTT#O#qA zlhj~pg%nbd2Y75Fb1Q~HWRRZQAXG-x9TWi@b4ic#7A516ZeGb~C>m;^KG>{ZWS(b( zUuQK399XtI1R)5Yfu{siJk+sepc8BYXfse#aNXh#5DFM%wkh}{RhVL<`6Y&O=mE5A zDDy&Chi5ev1CHLZU|z*YlU#6A})Edx~SE7*{CvdV7e_;WTD zWLlYVih{XL){vzDo!MLWSeU9ZUmXl_VWPTW|tik|jq2rQb>J z3zy3aUnQfkSVWS`5lsz&LeD}`>m>SC_7peKGG(lI3Ih$XA{Z<+8PiO(L#Wm zcU@|G@v(ibX(ySjRHu;1|9fUnOwVkwDJ-z1xlOmmu#SB-2S9}l9@tPNRxT0BIvhNk zi47eL@v;FtGQsg&g|}SQC!|8Er^5<74W!)x)$osc-*3aN`gYldDLT- zO7dL{U%&aB;(KeAON2pADhtbsDcnX>2{##ebue&bNK~ zx}%iWqee|11M&_WWV70}c56M-(j-EwJ?5@co-K*LwHhGJXOY%F)rfJ!bxf^d@leYs zWbE37oJ~YfXBKyH$hIVhc4ZZY#^JRLxD|lv8$x2!iv?M$snl429%;pEZF;ZY;U}iYRz`&Tr%*=R1ZTb-b1~hP4V&c|=EX!_Z9bsu>>wL(_#=v-#(WZGx zNM%7P#Y41$Y1T`;vSadF8kIwBCL$Mil~%YW8n4V?gv#ZNt#xh6a2q~|j( zc1`vL5q=EIU6Y-HGpkZBF#xRxay;`=QY#pN>Rd95OC~a|a1Jib1#4LmkXTgWSDITq zk#Qx6=^B!lUVH$|1nDoH$h!(8>Iho0c zC7Jno`dP*Kc}svMrr%UBH&0DVvPd;fOEfY!OEEDsH?cG}GPX2IG&3_bHBB{HSavRB z?|RX5Y?{*+XZyX?UA5VAfj1wopJaBm PQdw$IG0-L@E5ljF;ZY;U}iYRz`$6<%*=R1ZTb-b1~hP4V&c|=EI#G$j#Y41$Y1T`;vSadF8kIwEjXkXvzcx~uxUt@8wHPaer!=9=u7lb+AG z*frS~MEEf*cTIK*&a6tk!~nD&$nnfeNv&W6s&mOKE}6)JoVsK?~ z5G?|ilR%Oa0LcY26-mah!qp3c#e|BaV)%f%g`p~>fhuI6CW=7CWRb)~fnxO_qvU{s zd{BjAP=)eHV&YIS1tc*EkQm5`!IDx8U=Jw9C;=^(f{RN-#g)P0GGH@gi&WB?H05q_ zxu@o(7A2NsPIh5wRnTO-#h;RzmROoo5}%fsT#{c@d5b%-xHz?>I6fz{xMcH7mK%(W zs*?|~6^U>Ht-Zwp5-rjNGK<)N#AIjoL`J#EOW7-hZ^|ldFu5pe(cnEnWJ2;p$;&Jj Jn>9G<7y%~XQzrlb delta 374 zcmX>gyiAz)GcPX}0}wppZ_7Nhk++tKan%#IVA}1i@lLMUpXmK;6Pn6;ePI(ohpcpkgveVxmwnS)dpnP+dL9 zYB8vw98?e_CJq&oM-r0&iGiFLEGfkRcBDd#B2cXqTwEF|t^^jB0h=LPq@2#ADR+y@ zJvA@2D6u3nKkuag&>+8COqnT@V^}H`ZgD3T7pImK$LC}gmuNEH;!jCUODxSPiBC&R zF3B&d-29d01|y@&lMQXDX HM;#*ooTyP1