ginipick commited on
Commit
79c8362
ยท
verified ยท
1 Parent(s): d3022ab

Update app-backup.py

Browse files
Files changed (1) hide show
  1. app-backup.py +170 -43
app-backup.py CHANGED
@@ -1957,16 +1957,21 @@ def create_interface():
1957
  logger.info(f"Successfully applied storyboard with {len(panel_data)} panels")
1958
  return panel_data, html, gr.update(visible=True, choices=panel_choices, value=[]), gr.update(visible=True, value=edited_text), panel_prompts
1959
 
 
 
1960
  def generate_selected_panel_images(panel_data, selected_panels, session_id, character_profiles, webtoon_system, panel_prompts, genre, progress=gr.Progress()):
1961
- """Generate images for selected panels only"""
1962
  if not REPLICATE_API_TOKEN:
1963
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=True, value="โš ๏ธ Replicate API ํ† ํฐ์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
 
1964
 
1965
  if not panel_data:
1966
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=True, value="โš ๏ธ ํŒจ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.")
 
1967
 
1968
  if not selected_panels:
1969
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=True, value="โš ๏ธ ์ƒ์„ฑํ•  ํŒจ๋„์„ ์„ ํƒํ•˜์„ธ์š”.")
 
1970
 
1971
  if not webtoon_system:
1972
  webtoon_system = WebtoonSystem()
@@ -1976,7 +1981,10 @@ def create_interface():
1976
  total = len(selected_numbers)
1977
  successful = 0
1978
 
1979
- for i, panel in enumerate(panel_data):
 
 
 
1980
  if panel['number'] in selected_numbers:
1981
  idx = selected_numbers.index(panel['number'])
1982
  progress((idx / total), desc=f"ํŒจ๋„ {panel['number']} ์ƒ์„ฑ ์ค‘...")
@@ -2010,25 +2018,32 @@ def create_interface():
2010
  time.sleep(0.5)
2011
 
2012
  progress(1.0, desc=f"์™„๋ฃŒ! {successful}/{total} ํŒจ๋„ ์ƒ์„ฑ ์„ฑ๊ณต")
2013
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=False)
2014
-
 
 
2015
  def generate_all_panel_images(panel_data, session_id, character_profiles, webtoon_system, panel_prompts, genre, progress=gr.Progress()):
2016
- """Generate images for all panels"""
2017
  if not REPLICATE_API_TOKEN:
2018
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=True, value="โš ๏ธ Replicate API ํ† ํฐ์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
 
2019
 
2020
  if not panel_data:
2021
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=True, value="โš ๏ธ ํŒจ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.")
 
2022
 
2023
  if not webtoon_system:
2024
  webtoon_system = WebtoonSystem()
2025
  webtoon_system.current_genre = genre
2026
 
2027
- total_panels = len(panel_data)
 
 
 
2028
  successful = 0
2029
  failed = 0
2030
 
2031
- for i, panel in enumerate(panel_data):
2032
  progress((i / total_panels), desc=f"ํŒจ๋„ {panel['number']}/{total_panels} ์ƒ์„ฑ ์ค‘...")
2033
 
2034
  panel_id = f"panel_{panel['number']}"
@@ -2063,12 +2078,118 @@ def create_interface():
2063
  time.sleep(0.5)
2064
 
2065
  progress(1.0, desc=f"์™„๋ฃŒ! ์„ฑ๊ณต: {successful}, ์‹คํŒจ: {failed}")
2066
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0], gr.update(visible=False)
2067
-
 
 
2068
  def clear_all_images(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre):
2069
- for panel in panel_data:
 
 
 
2070
  panel['image_url'] = None
2071
- return display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2072
 
2073
  def handle_random_theme(genre, language):
2074
  return generate_random_webtoon_theme(genre, language)
@@ -2158,8 +2279,10 @@ def create_interface():
2158
  fn=lambda: gr.update(visible=True, value="ํŽธ์ง‘ ๋‚ด์šฉ์ด ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."),
2159
  outputs=[generation_progress]
2160
  )
2161
-
2162
- # ์„ ํƒํ•œ ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
 
 
2163
  generate_selected_btn.click(
2164
  fn=lambda pd: (pd, gr.update(visible=True, value="์„ ํƒํ•œ ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹œ์ž‘...")),
2165
  inputs=[panel_data_state],
@@ -2167,10 +2290,10 @@ def create_interface():
2167
  ).then(
2168
  fn=generate_selected_panel_images,
2169
  inputs=[panel_data_state, panel_selector, current_session_id, character_profiles_state, webtoon_system, panel_prompts_state, current_genre],
2170
- outputs=[panels_display, generation_progress]
2171
  )
2172
-
2173
- # ๋ชจ๋“  ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
2174
  generate_all_images_btn.click(
2175
  fn=lambda pd: (pd, gr.update(visible=True, value="๋ชจ๋“  ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹œ์ž‘...")),
2176
  inputs=[panel_data_state],
@@ -2178,15 +2301,36 @@ def create_interface():
2178
  ).then(
2179
  fn=generate_all_panel_images,
2180
  inputs=[panel_data_state, current_session_id, character_profiles_state, webtoon_system, panel_prompts_state, current_genre],
2181
- outputs=[panels_display, generation_progress]
2182
  )
2183
-
2184
- # ์ด๋ฏธ์ง€ ์ดˆ๊ธฐํ™”
2185
  clear_images_btn.click(
2186
  fn=clear_all_images,
2187
  inputs=[panel_data_state, panel_prompts_state, current_session_id, character_profiles_state, webtoon_system, current_genre],
2188
- outputs=[panels_display]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2189
  )
 
2190
 
2191
  # ๋žœ๋ค ํ…Œ๋งˆ
2192
  random_btn.click(
@@ -2216,24 +2360,7 @@ def create_interface():
2216
  inputs=[storyboard_download_file],
2217
  outputs=[storyboard_download_file]
2218
  )
2219
-
2220
- # ์ „์ฒด ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ
2221
- download_all_images_btn.click(
2222
- fn=download_all_panel_images,
2223
- inputs=[panel_data_state, current_session_id, current_genre],
2224
- outputs=[images_download_file]
2225
- ).then(
2226
- fn=lambda x: gr.update(visible=True, value=x) if x else gr.update(visible=False),
2227
- inputs=[images_download_file],
2228
- outputs=[images_download_file]
2229
- ).then(
2230
- fn=lambda x: gr.update(
2231
- visible=True,
2232
- value="โœ… ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์ค€๋น„ ์™„๋ฃŒ!" if x else "โš ๏ธ ๋‹ค์šด๋กœ๋“œํ•  ์ด๋ฏธ์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”."
2233
- ),
2234
- inputs=[images_download_file],
2235
- outputs=[generation_progress]
2236
- )
2237
 
2238
  return interface
2239
 
 
1957
  logger.info(f"Successfully applied storyboard with {len(panel_data)} panels")
1958
  return panel_data, html, gr.update(visible=True, choices=panel_choices, value=[]), gr.update(visible=True, value=edited_text), panel_prompts
1959
 
1960
+ # ์ฃผ์š” ์ˆ˜์ • ๋ถ€๋ถ„๋งŒ ํฌํ•จํ•œ ํŒจ์น˜ ์ฝ”๋“œ
1961
+ # generate_selected_panel_images ํ•จ์ˆ˜ ์ˆ˜์ •
1962
  def generate_selected_panel_images(panel_data, selected_panels, session_id, character_profiles, webtoon_system, panel_prompts, genre, progress=gr.Progress()):
1963
+ """Generate images for selected panels only - ์ˆ˜์ •๋œ ๋ฒ„์ „"""
1964
  if not REPLICATE_API_TOKEN:
1965
+ html, _ = display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
1966
+ return panel_data, html, gr.update(visible=True, value="โš ๏ธ Replicate API ํ† ํฐ์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
1967
 
1968
  if not panel_data:
1969
+ html, _ = display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
1970
+ return panel_data, html, gr.update(visible=True, value="โš ๏ธ ํŒจ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.")
1971
 
1972
  if not selected_panels:
1973
+ html, _ = display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
1974
+ return panel_data, html, gr.update(visible=True, value="โš ๏ธ ์ƒ์„ฑํ•  ํŒจ๋„์„ ์„ ํƒํ•˜์„ธ์š”.")
1975
 
1976
  if not webtoon_system:
1977
  webtoon_system = WebtoonSystem()
 
1981
  total = len(selected_numbers)
1982
  successful = 0
1983
 
1984
+ # panel_data๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์ž‘์—… (์›๋ณธ ๋ณด์กด)
1985
+ updated_panel_data = panel_data.copy()
1986
+
1987
+ for i, panel in enumerate(updated_panel_data):
1988
  if panel['number'] in selected_numbers:
1989
  idx = selected_numbers.index(panel['number'])
1990
  progress((idx / total), desc=f"ํŒจ๋„ {panel['number']} ์ƒ์„ฑ ์ค‘...")
 
2018
  time.sleep(0.5)
2019
 
2020
  progress(1.0, desc=f"์™„๋ฃŒ! {successful}/{total} ํŒจ๋„ ์ƒ์„ฑ ์„ฑ๊ณต")
2021
+ html, _ = display_panels_with_editable_prompts(updated_panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
2022
+ return updated_panel_data, html, gr.update(visible=False)
2023
+
2024
+ # generate_all_panel_images ํ•จ์ˆ˜ ์ˆ˜์ •
2025
  def generate_all_panel_images(panel_data, session_id, character_profiles, webtoon_system, panel_prompts, genre, progress=gr.Progress()):
2026
+ """Generate images for all panels - ์ˆ˜์ •๋œ ๋ฒ„์ „"""
2027
  if not REPLICATE_API_TOKEN:
2028
+ html, _ = display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
2029
+ return panel_data, html, gr.update(visible=True, value="โš ๏ธ Replicate API ํ† ํฐ์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
2030
 
2031
  if not panel_data:
2032
+ html, _ = display_panels_with_editable_prompts(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
2033
+ return panel_data, html, gr.update(visible=True, value="โš ๏ธ ํŒจ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.")
2034
 
2035
  if not webtoon_system:
2036
  webtoon_system = WebtoonSystem()
2037
  webtoon_system.current_genre = genre
2038
 
2039
+ # panel_data๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์ž‘์—…
2040
+ updated_panel_data = panel_data.copy()
2041
+
2042
+ total_panels = len(updated_panel_data)
2043
  successful = 0
2044
  failed = 0
2045
 
2046
+ for i, panel in enumerate(updated_panel_data):
2047
  progress((i / total_panels), desc=f"ํŒจ๋„ {panel['number']}/{total_panels} ์ƒ์„ฑ ์ค‘...")
2048
 
2049
  panel_id = f"panel_{panel['number']}"
 
2078
  time.sleep(0.5)
2079
 
2080
  progress(1.0, desc=f"์™„๋ฃŒ! ์„ฑ๊ณต: {successful}, ์‹คํŒจ: {failed}")
2081
+ html, _ = display_panels_with_editable_prompts(updated_panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
2082
+ return updated_panel_data, html, gr.update(visible=False)
2083
+
2084
+ # clear_all_images ํ•จ์ˆ˜ ์ˆ˜์ •
2085
  def clear_all_images(panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre):
2086
+ """Clear all images - ์ˆ˜์ •๋œ ๋ฒ„์ „"""
2087
+ # panel_data๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์ˆ˜์ •
2088
+ updated_panel_data = panel_data.copy()
2089
+ for panel in updated_panel_data:
2090
  panel['image_url'] = None
2091
+ html, _ = display_panels_with_editable_prompts(updated_panel_data, panel_prompts, session_id, character_profiles, webtoon_system, genre)
2092
+ return updated_panel_data, html
2093
+
2094
+ # download_all_panel_images ํ•จ์ˆ˜ ์ˆ˜์ •
2095
+ def download_all_panel_images(panel_data, session_id, genre):
2096
+ """๋ชจ๋“  ํŒจ๋„ ์ด๋ฏธ์ง€๋ฅผ ZIP ํŒŒ์ผ๋กœ ๋‹ค์šด๋กœ๋“œ - ์ˆ˜์ •๋œ ๋ฒ„์ „"""
2097
+ try:
2098
+ logger.info(f"Starting image download - Panel data count: {len(panel_data) if panel_data else 0}")
2099
+
2100
+ if not panel_data:
2101
+ logger.warning("No panel data available")
2102
+ return None
2103
+
2104
+ # ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š” ํŒจ๋„๋งŒ ํ•„ํ„ฐ๋ง
2105
+ panels_with_images = [p for p in panel_data if p.get('image_url')]
2106
+ logger.info(f"Found {len(panels_with_images)} panels with images")
2107
+
2108
+ if not panels_with_images:
2109
+ logger.warning("No images to download")
2110
+ return None
2111
+
2112
+ # ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
2113
+ with tempfile.TemporaryDirectory() as temp_dir:
2114
+ image_dir = Path(temp_dir) / "webtoon_images"
2115
+ image_dir.mkdir(exist_ok=True)
2116
+
2117
+ # ๊ฐ ์ด๋ฏธ์ง€ ์ €์žฅ
2118
+ saved_count = 0
2119
+ for panel in panels_with_images:
2120
+ panel_num = panel['number']
2121
+ image_url = panel['image_url']
2122
+
2123
+ try:
2124
+ # base64 ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ
2125
+ if image_url.startswith('data:image'):
2126
+ # data URL์—์„œ base64 ๋ฐ์ดํ„ฐ ์ถ”์ถœ
2127
+ header, data = image_url.split(',', 1)
2128
+ image_data = base64.b64decode(data)
2129
+
2130
+ # ํŒŒ์ผ๋กœ ์ €์žฅ
2131
+ image_path = image_dir / f"panel_{panel_num:03d}.jpg"
2132
+ with open(image_path, 'wb') as f:
2133
+ f.write(image_data)
2134
+ saved_count += 1
2135
+ else:
2136
+ # URL์—์„œ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ
2137
+ response = requests.get(image_url, timeout=30)
2138
+ response.raise_for_status()
2139
+
2140
+ image_path = image_dir / f"panel_{panel_num:03d}.jpg"
2141
+ with open(image_path, 'wb') as f:
2142
+ f.write(response.content)
2143
+ saved_count += 1
2144
+
2145
+ logger.info(f"Saved panel {panel_num} image")
2146
+
2147
+ except Exception as e:
2148
+ logger.error(f"Failed to save panel {panel_num}: {e}")
2149
+ continue
2150
+
2151
+ logger.info(f"Successfully saved {saved_count} images")
2152
+
2153
+ if saved_count == 0:
2154
+ logger.warning("No images were saved successfully")
2155
+ return None
2156
+
2157
+ # ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํŒŒ์ผ ์ƒ์„ฑ
2158
+ metadata_path = image_dir / "metadata.txt"
2159
+ with open(metadata_path, 'w', encoding='utf-8') as f:
2160
+ f.write(f"์›นํˆฐ ์ด๋ฏธ์ง€ ์ •๋ณด\n")
2161
+ f.write(f"{'=' * 50}\n")
2162
+ f.write(f"์žฅ๋ฅด: {genre}\n")
2163
+ f.write(f"์„ธ์…˜ ID: {session_id}\n")
2164
+ f.write(f"์ด ์ด๋ฏธ์ง€ ์ˆ˜: {saved_count}๊ฐœ\n")
2165
+ f.write(f"์ด๋ฏธ์ง€ ํฌ๊ธฐ: {WEBTOON_IMAGE_WIDTH}ร—{WEBTOON_IMAGE_HEIGHT}px\n")
2166
+ f.write(f"์ƒ์„ฑ ๋‚ ์งœ: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
2167
+ f.write(f"{'=' * 50}\n\n")
2168
+
2169
+ for panel in panels_with_images:
2170
+ f.write(f"ํŒจ๋„ {panel['number']:03d}\n")
2171
+ f.write(f" - ์ƒท ํƒ€์ž…: {panel.get('shot', 'N/A')}\n")
2172
+ f.write(f" - ํ”„๋กฌํ”„ํŠธ: {panel.get('prompt', 'N/A')}\n")
2173
+ if panel.get('dialogue'):
2174
+ f.write(f" - ๋Œ€์‚ฌ: {panel['dialogue']}\n")
2175
+ if panel.get('narration'):
2176
+ f.write(f" - ๋‚˜๋ ˆ์ด์…˜: {panel['narration']}\n")
2177
+ f.write("\n")
2178
+
2179
+ # ZIP ํŒŒ์ผ ์ƒ์„ฑ
2180
+ zip_path = Path(temp_dir) / f"webtoon_{genre}_episode1_images.zip"
2181
+ shutil.make_archive(str(zip_path.with_suffix('')), 'zip', image_dir)
2182
+
2183
+ # ์ƒ์„ฑ๋œ ZIP ํŒŒ์ผ์„ ์ž„์‹œ ํŒŒ์ผ๋กœ ๋ณต์‚ฌ
2184
+ with tempfile.NamedTemporaryFile(suffix='.zip', delete=False) as final_zip:
2185
+ shutil.copy2(zip_path, final_zip.name)
2186
+ logger.info(f"Created ZIP file with {saved_count} images: {final_zip.name}")
2187
+ return final_zip.name
2188
+
2189
+ except Exception as e:
2190
+ logger.error(f"Failed to create image ZIP: {e}", exc_info=True)
2191
+ return None
2192
+
2193
 
2194
  def handle_random_theme(genre, language):
2195
  return generate_random_webtoon_theme(genre, language)
 
2279
  fn=lambda: gr.update(visible=True, value="ํŽธ์ง‘ ๋‚ด์šฉ์ด ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."),
2280
  outputs=[generation_progress]
2281
  )
2282
+
2283
+ # create_interface ํ•จ์ˆ˜ ๋‚ด์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ˆ˜์ • ๋ถ€๋ถ„
2284
+
2285
+ # ์„ ํƒํ•œ ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ - panel_data_state ์—…๋ฐ์ดํŠธ ์ถ”๊ฐ€
2286
  generate_selected_btn.click(
2287
  fn=lambda pd: (pd, gr.update(visible=True, value="์„ ํƒํ•œ ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹œ์ž‘...")),
2288
  inputs=[panel_data_state],
 
2290
  ).then(
2291
  fn=generate_selected_panel_images,
2292
  inputs=[panel_data_state, panel_selector, current_session_id, character_profiles_state, webtoon_system, panel_prompts_state, current_genre],
2293
+ outputs=[panel_data_state, panels_display, generation_progress] # panel_data_state ์ถœ๋ ฅ ์ถ”๊ฐ€
2294
  )
2295
+
2296
+ # ๋ชจ๋“  ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ - panel_data_state ์—…๋ฐ์ดํŠธ ์ถ”๊ฐ€
2297
  generate_all_images_btn.click(
2298
  fn=lambda pd: (pd, gr.update(visible=True, value="๋ชจ๋“  ํŒจ๋„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹œ์ž‘...")),
2299
  inputs=[panel_data_state],
 
2301
  ).then(
2302
  fn=generate_all_panel_images,
2303
  inputs=[panel_data_state, current_session_id, character_profiles_state, webtoon_system, panel_prompts_state, current_genre],
2304
+ outputs=[panel_data_state, panels_display, generation_progress] # panel_data_state ์ถœ๋ ฅ ์ถ”๊ฐ€
2305
  )
2306
+
2307
+ # ์ด๋ฏธ์ง€ ์ดˆ๊ธฐํ™” - panel_data_state ์—…๋ฐ์ดํŠธ ์ถ”๊ฐ€
2308
  clear_images_btn.click(
2309
  fn=clear_all_images,
2310
  inputs=[panel_data_state, panel_prompts_state, current_session_id, character_profiles_state, webtoon_system, current_genre],
2311
+ outputs=[panel_data_state, panels_display] # panel_data_state ์ถœ๋ ฅ ์ถ”๊ฐ€
2312
+ )
2313
+
2314
+ # ์ „์ฒด ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ - ์ˆ˜์ •๋œ ๋ฉ”์‹œ์ง€
2315
+ download_all_images_btn.click(
2316
+ fn=lambda pd, sid, genre: (
2317
+ download_all_panel_images(pd, sid, genre),
2318
+ gr.update(visible=True, value="์ด๋ฏธ์ง€ ZIP ํŒŒ์ผ ์ƒ์„ฑ ์ค‘...")
2319
+ ),
2320
+ inputs=[panel_data_state, current_session_id, current_genre],
2321
+ outputs=[images_download_file, generation_progress]
2322
+ ).then(
2323
+ fn=lambda x: (
2324
+ gr.update(visible=True, value=x) if x else gr.update(visible=False),
2325
+ gr.update(
2326
+ visible=True,
2327
+ value="โœ… ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์ค€๋น„ ์™„๋ฃŒ!" if x else "โš ๏ธ ๋‹ค์šด๋กœ๋“œํ•  ์ด๋ฏธ์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”."
2328
+ )
2329
+ ),
2330
+ inputs=[images_download_file],
2331
+ outputs=[images_download_file, generation_progress]
2332
  )
2333
+
2334
 
2335
  # ๋žœ๋ค ํ…Œ๋งˆ
2336
  random_btn.click(
 
2360
  inputs=[storyboard_download_file],
2361
  outputs=[storyboard_download_file]
2362
  )
2363
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2364
 
2365
  return interface
2366