import asyncio from typing import List, Tuple from models.image_prompt import ImagePrompt from models.sql.image_asset import ImageAsset from models.sql.slide import SlideModel from services.icon_finder_service import IconFinderService from services.image_generation_service import ImageGenerationService from utils.asset_directory_utils import get_images_directory from utils.dict_utils import get_dict_at_path, get_dict_paths_with_key, set_dict_at_path async def process_slide_and_fetch_assets( image_generation_service: ImageGenerationService, icon_finder_service: IconFinderService, slide: SlideModel, ) -> List[ImageAsset]: async_tasks = [] image_paths = get_dict_paths_with_key(slide.content, "image_prompt_") icon_paths = get_dict_paths_with_key(slide.content, "icon_query_") for image_path in image_paths: image_prompt_parent = get_dict_at_path(slide.content, image_path) async_tasks.append( image_generation_service.generate_image( ImagePrompt( prompt=image_prompt_parent["image_prompt_"], ) ) ) for icon_path in icon_paths: icon_query_parent = get_dict_at_path(slide.content, icon_path) async_tasks.append( icon_finder_service.search_icons(icon_query_parent["icon_query_"]) ) results = await asyncio.gather(*async_tasks) results.reverse() return_assets = [] for image_path in image_paths: image_dict = get_dict_at_path(slide.content, image_path) result = results.pop() if isinstance(result, ImageAsset): return_assets.append(result) image_dict["image_url_"] = result.path else: image_dict["image_url_"] = result set_dict_at_path(slide.content, image_path, image_dict) for icon_path in icon_paths: icon_dict = get_dict_at_path(slide.content, icon_path) icon_dict["icon_url_"] = results.pop()[0] set_dict_at_path(slide.content, icon_path, icon_dict) return return_assets async def process_old_and_new_slides_and_fetch_assets( image_generation_service: ImageGenerationService, icon_finder_service: IconFinderService, old_slide_content: dict, new_slide_content: dict, ) -> List[ImageAsset]: # Finds all old images old_image_dict_paths = get_dict_paths_with_key( old_slide_content, "image_prompt_" ) old_image_dicts = [ get_dict_at_path(old_slide_content, path) for path in old_image_dict_paths ] old_image_prompts = [ old_image_dict["image_prompt_"] for old_image_dict in old_image_dicts ] # Finds all old icons old_icon_dict_paths = get_dict_paths_with_key(old_slide_content, "icon_query_") old_icon_dicts = [ get_dict_at_path(old_slide_content, path) for path in old_icon_dict_paths ] old_icon_queries = [ old_icon_dict["icon_query_"] for old_icon_dict in old_icon_dicts ] # Finds all new images new_image_dict_paths = get_dict_paths_with_key( new_slide_content, "image_prompt_" ) new_image_dicts = [ get_dict_at_path(new_slide_content, path) for path in new_image_dict_paths ] # Finds all new icons new_icon_dict_paths = get_dict_paths_with_key(new_slide_content, "icon_query_") new_icon_dicts = [ get_dict_at_path(new_slide_content, path) for path in new_icon_dict_paths ] # Creates async tasks for fetching new images async_image_fetch_tasks = [] new_images_fetch_status = [] # Creates async tasks for fetching new icons async_icon_fetch_tasks = [] new_icons_fetch_status = [] # Creates async tasks for fetching new images # Use old image url if prompt is same for new_image in new_image_dicts: if new_image["image_prompt_"] in old_image_prompts: old_image_url = old_image_dicts[ old_image_prompts.index(new_image["image_prompt_"]) ]["image_url_"] new_image["image_url_"] = old_image_url new_images_fetch_status.append(False) continue async_image_fetch_tasks.append( image_generation_service.generate_image( ImagePrompt( prompt=new_image["image_prompt_"], ) ) ) new_images_fetch_status.append(True) # Creates async tasks for fetching new icons # Use old icon url if query is same for new_icon in new_icon_dicts: if new_icon["icon_query_"] in old_icon_queries: old_icon_url = old_icon_dicts[ old_icon_queries.index(new_icon["icon_query_"]) ]["icon_url_"] new_icon["icon_url_"] = old_icon_url new_icons_fetch_status.append(False) continue async_icon_fetch_tasks.append( icon_finder_service.search_icons(new_icon["icon_query_"]) ) new_icons_fetch_status.append(True) new_images = await asyncio.gather(*async_image_fetch_tasks) new_icons = await asyncio.gather(*async_icon_fetch_tasks) # list of new assets new_assets = [] # Sets new image and icon urls for assets that were fetched for i, new_image in enumerate(new_images): if new_images_fetch_status[i]: fetched_image = new_images[i] if isinstance(fetched_image, ImageAsset): new_assets.append(fetched_image) image_url = fetched_image.path else: image_url = fetched_image new_image_dicts[i]["image_url_"] = image_url for i, new_icon in enumerate(new_icons): if new_icons_fetch_status[i]: new_icon_dicts[i]["icon_url_"] = new_icons[i][0] for i, new_image_dict in enumerate(new_image_dicts): set_dict_at_path(new_slide_content, new_image_dict_paths[i], new_image_dict) for i, new_icon_dict in enumerate(new_icon_dicts): set_dict_at_path(new_slide_content, new_icon_dict_paths[i], new_icon_dict) return new_assets