openfree commited on
Commit
f2d66b9
ยท
verified ยท
1 Parent(s): 5af6963

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -81
app.py CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env python
2
 
3
  import os
4
  import re
@@ -350,68 +349,115 @@ def get_emoji_for_content(text: str) -> str:
350
  return 'โ–ถ๏ธ'
351
 
352
  ##############################################################################
353
- # Diagram Type Detection with Priority Score
354
  ##############################################################################
355
- def detect_diagram_type_with_score(title: str, content: str) -> Tuple[Optional[str], float]:
356
- """์Šฌ๋ผ์ด๋“œ ๋‚ด์šฉ์„ ๋ถ„์„ํ•˜์—ฌ ์ ์ ˆํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž…๊ณผ ํ•„์š”๋„ ์ ์ˆ˜ ๊ฒฐ์ •"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  combined_text = f"{title} {content}".lower()
358
 
359
- # ๊ฐ ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž…๋ณ„ ํ‚ค์›Œ๋“œ์™€ ๊ฐ€์ค‘์น˜
360
- diagram_scores = {
361
- "Process Flow": 0,
362
- "WBS Diagram": 0,
363
- "Concept Map": 0,
364
- "Radial Diagram": 0,
365
- "Synoptic Chart": 0
366
- }
 
 
 
 
 
 
 
 
 
 
 
367
 
368
- # Process Flow keywords with weights
369
- if any(word in combined_text for word in ['ํ”„๋กœ์„ธ์Šค', 'process', '์ ˆ์ฐจ', 'procedure']):
370
- diagram_scores["Process Flow"] += 3
371
- if any(word in combined_text for word in ['๋‹จ๊ณ„', 'step', 'flow', 'ํ๋ฆ„']):
372
- diagram_scores["Process Flow"] += 2
373
- if any(word in combined_text for word in ['์›Œํฌํ”Œ๋กœ์šฐ', 'workflow', '์ˆœ์„œ', 'sequence']):
374
- diagram_scores["Process Flow"] += 2
375
-
376
- # WBS keywords with weights
377
- if any(word in combined_text for word in ['wbs', '์ž‘์—…๋ถ„ํ•ด', 'ํ”„๋กœ์ ํŠธ', 'project']):
378
- diagram_scores["WBS Diagram"] += 3
379
- if any(word in combined_text for word in ['์—…๋ฌด๋ถ„ํ•ด', 'breakdown', '๊ตฌ์กฐ๋„', '์ž‘์—…๊ตฌ์กฐ']):
380
- diagram_scores["WBS Diagram"] += 2
381
-
382
- # Concept Map keywords with weights
383
- if any(word in combined_text for word in ['๊ฐœ๋…', 'concept', '๊ด€๊ณ„', 'relationship']):
384
- diagram_scores["Concept Map"] += 3
385
- if any(word in combined_text for word in ['์—ฐ๊ด€', 'connection', '๋งˆ์ธ๋“œ๋งต', 'mindmap']):
386
- diagram_scores["Concept Map"] += 2
387
- if any(word in combined_text for word in ['๊ตฌ์กฐ', 'structure', '์ฒด๊ณ„', 'system']):
388
- diagram_scores["Concept Map"] += 1
389
-
390
- # Radial Diagram keywords with weights
391
- if any(word in combined_text for word in ['์ค‘์‹ฌ', 'central', '๋ฐฉ์‚ฌํ˜•', 'radial']):
392
- diagram_scores["Radial Diagram"] += 3
393
- if any(word in combined_text for word in ['ํ•ต์‹ฌ', 'core', '์ฃผ์š”', 'main']):
394
- diagram_scores["Radial Diagram"] += 2
395
-
396
- # Synoptic Chart keywords with weights
397
- if any(word in combined_text for word in ['๊ฐœ์š”', 'overview', '์ „์ฒด', 'overall']):
398
- diagram_scores["Synoptic Chart"] += 3
399
- if any(word in combined_text for word in ['์š”์•ฝ', 'summary', '์‹œ๋†‰ํ‹ฑ', 'synoptic']):
400
- diagram_scores["Synoptic Chart"] += 2
401
-
402
- # ์ถ”๊ฐ€ ์ ์ˆ˜ ๋ถ€์—ฌ: ๋ฆฌ์ŠคํŠธ๋‚˜ ๊ตฌ์กฐํ™”๋œ ๋‚ด์šฉ์ด ๋งŽ์€ ๊ฒฝ์šฐ
403
- if content.count('\n-') > 3 or content.count('\nโ€ข') > 3:
404
- diagram_scores["Concept Map"] += 1
405
- if any(char in content for char in ['1.', '2.', '3.', 'โ‘ ', 'โ‘ก', 'โ‘ข']):
406
- diagram_scores["Process Flow"] += 1
407
-
408
- # ๊ฐ€์žฅ ๋†’์€ ์ ์ˆ˜์˜ ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž… ์„ ํƒ
409
- max_score = max(diagram_scores.values())
410
- if max_score > 0:
411
- best_type = max(diagram_scores.items(), key=lambda x: x[1])[0]
412
- # ํ•„์š”๋„ ์ ์ˆ˜ ๊ณ„์‚ฐ (0-1 ๋ฒ”์œ„)
413
- necessity_score = min(max_score / 5.0, 1.0) # ์ตœ๋Œ€ 5์ ์„ 1.0์œผ๋กœ ์ •๊ทœํ™”
414
- return best_type, necessity_score
415
 
416
  return None, 0.0
417
 
@@ -2392,12 +2438,13 @@ def generate_ppt(
2392
 
2393
  # AI ์ด๋ฏธ์ง€ ๋ฐ ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ ์•Œ๋ฆผ
2394
  visual_features = []
2395
- if include_ai_image and (AI_IMAGE_ENABLED or FLUX_API_ENABLED):
2396
  visual_features.append("AI 3D ํ‘œ์ง€ ์ด๋ฏธ์ง€")
2397
  if include_diagrams and DIAGRAM_GENERATORS_AVAILABLE:
2398
- visual_features.append("๋‹ค์ด์–ด๊ทธ๋žจ (์ตœ๋Œ€ 2๊ฐœ)")
2399
  if include_flux_images and FLUX_API_ENABLED:
2400
- visual_features.append("AI ์ƒ์„ฑ ์ด๋ฏธ์ง€ (๊ฐ API๋ณ„ ์ตœ๋Œ€ 3๊ฐœ)")
 
2401
 
2402
  if visual_features:
2403
  yield None, f"๐Ÿ“ ์Šฌ๋ผ์ด๋“œ ์ƒ์„ฑ ์™„๋ฃŒ!\n\n๐ŸŽจ ์ƒ์„ฑ ์ค‘: {', '.join(visual_features)}... (์‹œ๊ฐ„์ด ์†Œ์š”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)", llm_response
@@ -2419,12 +2466,14 @@ def generate_ppt(
2419
  success_msg += f"๐ŸŽจ ๋””์ž์ธ ํ…Œ๋งˆ: {DESIGN_THEMES[design_theme]['name']}\n"
2420
  success_msg += f"๐Ÿ“ ๋ ˆ์ด์•„์›ƒ ์Šคํƒ€์ผ: {layout_style}\n"
2421
 
2422
- if include_ai_image and (AI_IMAGE_ENABLED or FLUX_API_ENABLED):
2423
- success_msg += f"๐Ÿ–ผ๏ธ AI ์ƒ์„ฑ ํ‘œ์ง€ ์ด๋ฏธ์ง€ ํฌํ•จ\n"
 
 
2424
  if include_diagrams and DIAGRAM_GENERATORS_AVAILABLE:
2425
- success_msg += f"๐Ÿ“Š AI ์ƒ์„ฑ ๋‹ค์ด์–ด๊ทธ๋žจ ํฌํ•จ (์ตœ๋Œ€ 2๊ฐœ)\n"
2426
  if include_flux_images and FLUX_API_ENABLED:
2427
- success_msg += f"๐ŸŽจ AI ์ƒ์„ฑ ์Šฌ๋ผ์ด๋“œ ์ด๋ฏธ์ง€ ํฌํ•จ (API๋ณ„ ์ตœ๋Œ€ 3๊ฐœ)\n"
2428
 
2429
  success_msg += f"๐Ÿ“ ์ƒ์„ฑ๋œ ์Šฌ๋ผ์ด๋“œ:\n"
2430
 
@@ -2742,7 +2791,7 @@ with gr.Blocks(css=css, title="AI PPT Generator Pro") as demo:
2742
  include_diagrams = gr.Checkbox(
2743
  label="๐Ÿ“Š AI ๋‹ค์ด์–ด๊ทธ๋žจ",
2744
  value=False,
2745
- info="ํ•„์š”๋„๊ฐ€ ๋†’์€ 2๊ฐœ ์Šฌ๏ฟฝ๏ฟฝ๏ฟฝ์ด๋“œ์— ๋‹ค์ด์–ด๊ทธ๋žจ ์ž๋™ ์ƒ์„ฑ"
2746
  )
2747
 
2748
  include_flux_images = gr.Checkbox(
@@ -2797,17 +2846,26 @@ with gr.Blocks(css=css, title="AI PPT Generator Pro") as demo:
2797
  5. **์ฐธ๊ณ  ์ž๋ฃŒ ์—…๋กœ๋“œ**: PDF, CSV, TXT ํŒŒ์ผ ์ง€์›
2798
  6. **์ƒ์„ฑ ๋ฒ„ํŠผ ํด๋ฆญ**: AI๊ฐ€ ์ž๋™์œผ๋กœ PPT ์ƒ์„ฑ
2799
 
2800
- ### ๐ŸŽจ ๊ฐœ์„ ๋œ ๊ธฐ๋Šฅ - ์ตœ์ ํ™”๋œ ์‹œ๊ฐ ์š”์†Œ
2801
- - **๋‹ค์ด์–ด๊ทธ๋žจ ๊ฐœ์ˆ˜ ์ œํ•œ**: ์ „์ฒด ์Šฌ๋ผ์ด๋“œ ์ค‘ ํ•„์š”๋„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ 2๊ฐœ ์Šฌ๋ผ์ด๋“œ์—๋งŒ ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ
2802
- - **์ด๋ฏธ์ง€ ๊ฐœ์ˆ˜ ์ œํ•œ**: ๊ฐ API๋ณ„๋กœ ์ตœ๋Œ€ 3๊ฐœ์”ฉ, ์ด 6๊ฐœ์˜ AI ์ƒ์„ฑ ์ด๋ฏธ์ง€
2803
- - **ํ•œ๊ธ€ ํฐํŠธ ์ง€์›**: NanumGothic-Regular.ttf๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์ด์–ด๊ทธ๋žจ์˜ ํ•œ๊ธ€ ๊นจ์ง ๋ฌธ์ œ ํ•ด๊ฒฐ
2804
- - **์Šค๋งˆํŠธ ๋ฐฐ์น˜**: ๋‹ค์ด์–ด๊ทธ๋žจ๊ณผ ์ด๋ฏธ์ง€๋Š” ํ…์ŠคํŠธ์™€ ๊ฒน์น˜์ง€ ์•Š๋„๋ก ์šฐ์ธก์— ์ž๋™ ๋ฐฐ์น˜
 
 
 
 
 
 
 
 
 
2805
 
2806
  ### ๐Ÿ’ก ๊ณ ๊ธ‰ ํŒ
2807
- - **๋‹ค์ด์–ด๊ทธ๋žจ ์šฐ์„ ์ˆœ์œ„**: ํ”„๋กœ์„ธ์Šค, WBS, ๊ฐœ๋…๋„ ๋“ฑ์˜ ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ๋Š” ์Šฌ๋ผ์ด๋“œ๊ฐ€ ์šฐ์„  ์„ ํƒ๋ฉ๋‹ˆ๋‹ค
2808
- - **์ด๋ฏธ์ง€ ๋ถ„๋ฐฐ**: 3D ์Šคํƒ€์ผ๊ณผ ํฌํ† ๋ฆฌ์–ผ๋ฆฌ์Šคํ‹ฑ ์ด๋ฏธ์ง€๊ฐ€ ๊ท ํ˜•์žˆ๊ฒŒ ๋ถ„๋ฐฐ๋ฉ๋‹ˆ๋‹ค
2809
- - **ํ‘œ์ง€ ์ด๋ฏธ์ง€**: ์ฃผ์ œ์— ๋งž๋Š” ํ”„๋ฆฌ๋ฏธ์—„ ํ‘œ์ง€ ์ด๋ฏธ์ง€๊ฐ€ ์ž๋™ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค
2810
- - **ํ•œ๊ธ€ ์ง€์›**: app.py์™€ ๊ฐ™์€ ๊ฒฝ๋กœ์— NanumGothic-Regular.ttf ํŒŒ์ผ์„ ๋ฐฐ์น˜ํ•˜์„ธ์š”
2811
  """
2812
  )
2813
 
@@ -2848,12 +2906,12 @@ with gr.Blocks(css=css, title="AI PPT Generator Pro") as demo:
2848
 
2849
  # Initialize APIs on startup
2850
  if __name__ == "__main__":
2851
- # ํ•œ๊ธ€ ํฐํŠธ ํ™•์ธ
2852
  if os.path.exists(KOREAN_FONT_PATH):
2853
  logger.info(f"โœ… ํ•œ๊ธ€ ํฐํŠธ ํŒŒ์ผ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค: {KOREAN_FONT_PATH}")
2854
  else:
2855
  logger.warning(f"โš ๏ธ ํ•œ๊ธ€ ํฐํŠธ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค: {KOREAN_FONT_PATH}")
2856
- logger.warning("๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ํ•œ๊ธ€์ด ๊นจ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. NanumGothic-Regular.ttf ํŒŒ์ผ์„ app.py์™€ ๊ฐ™์€ ๊ฒฝ๋กœ์— ๋ฐฐ์น˜ํ•˜์„ธ์š”.")
2857
 
2858
  # Try to initialize APIs in parallel
2859
  with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
@@ -2872,9 +2930,13 @@ if __name__ == "__main__":
2872
 
2873
  # ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ๊ธฐ ๋ชจ๋“ˆ ์ƒํƒœ ํ™•์ธ
2874
  if DIAGRAM_GENERATORS_AVAILABLE:
2875
- logger.info("โœ… ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ๊ธฐ ๋ชจ๋“ˆ์ด ์ •์ƒ์ ์œผ๋กœ ๋กœ๋“œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค")
2876
- logger.info("์ง€์›๋˜๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž…: Process Flow, Concept Map, WBS, Radial, Synoptic Chart")
2877
  else:
2878
- logger.warning("โš ๏ธ ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ๊ธฐ ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์ด์–ด๊ทธ๋žจ ๊ธฐ๋Šฅ์ด ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.")
 
 
 
 
2879
 
2880
  demo.launch()
 
 
1
 
2
  import os
3
  import re
 
349
  return 'โ–ถ๏ธ'
350
 
351
  ##############################################################################
352
+ # FLUX Diagram Types and Prompts
353
  ##############################################################################
354
+ FLUX_DIAGRAM_TYPES = {
355
+ "Flowchart": {
356
+ "keywords": ['ํ”„๋กœ์„ธ์Šค', 'process', '์ ˆ์ฐจ', 'procedure', '๋‹จ๊ณ„', 'step', 'flow', 'ํ๋ฆ„', '์›Œํฌํ”Œ๋กœ์šฐ', 'workflow'],
357
+ "priority": 5, # ๋†’์€ ์šฐ์„ ์ˆœ์œ„
358
+ "prompt_template": """A hand-drawn style flowchart, vibrant colors, minimalistic icons.
359
+ {title}
360
+ START [Green Button ~40px]
361
+ โ”œโ”€โ”€ {step1} [Relevant Icon]
362
+ โ”œโ”€โ”€ {step2} [Relevant Icon]
363
+ โ”œโ”€โ”€ {step3} [Relevant Icon]
364
+ โ””โ”€โ”€ END [Checkered Flag ~40px]
365
+ Professional business style, clear hierarchy, modern design"""
366
+ },
367
+ "Mindmap": {
368
+ "keywords": ['๊ฐœ๋…', 'concept', '๊ด€๊ณ„', 'relationship', '๋งˆ์ธ๋“œ๋งต', 'mindmap', '์—ฐ๊ด€', 'connection'],
369
+ "priority": 4,
370
+ "prompt_template": """A handrawn colorful mind map diagram, educational style, vibrant colors, clear hierarchy.
371
+ {title}
372
+ โ”œโ”€โ”€ {branch1} [Relevant Icon ~60px]
373
+ โ”‚ โ”œโ”€โ”€ {sub1_1}
374
+ โ”‚ โ””โ”€โ”€ {sub1_2}
375
+ โ”œโ”€โ”€ {branch2} [Relevant Icon ~50px]
376
+ โ”‚ โ”œโ”€โ”€ {sub2_1}
377
+ โ”‚ โ””โ”€โ”€ {sub2_2}
378
+ โ””โ”€โ”€ {branch3} [Relevant Icon ~45px]
379
+ Modern business presentation style"""
380
+ },
381
+ "Infographic": {
382
+ "keywords": ['๋ฐ์ดํ„ฐ', 'data', 'ํ†ต๊ณ„', 'statistics', '๋ถ„์„', 'analysis', '์ฐจํŠธ', 'chart', '๊ทธ๋ž˜ํ”„', 'graph'],
383
+ "priority": 4,
384
+ "prompt_template": """A sophisticated flat-style infographic for business presentation:
385
+ Title: "{title}"
386
+ Visual Elements:
387
+ - Bar charts comparing key metrics
388
+ - Pie chart showing distribution
389
+ - Trend lines indicating growth
390
+ - Modern minimalist icons
391
+ - Clean grid layout with pastel accents
392
+ Professional corporate design, data visualization focus"""
393
+ },
394
+ "Diagram": {
395
+ "keywords": ['๊ตฌ์กฐ', 'structure', '์ฒด๊ณ„', 'system', '๊ด€๊ณ„๋„', 'diagram', '๋ชจ๋ธ', 'model'],
396
+ "priority": 3,
397
+ "prompt_template": """A detailed hand-drawn business diagram:
398
+ Title: "{title}"
399
+ Components:
400
+ - Clear visual hierarchy
401
+ - Connected elements with arrows
402
+ - Modern iconography
403
+ - Color-coded sections
404
+ - Professional annotations
405
+ Clean business presentation style"""
406
+ },
407
+ "Mockup": {
408
+ "keywords": ['๋””์ž์ธ', 'design', 'ui', 'ux', 'ํ™”๋ฉด', 'screen', '์ธํ„ฐํŽ˜์ด์Šค', 'interface', '์•ฑ', 'app'],
409
+ "priority": 3,
410
+ "prompt_template": """A clean hand-drawn style wireframe:
411
+ {title}
412
+ - Main screen layout
413
+ - Key UI elements
414
+ - Navigation structure
415
+ - User flow indicators
416
+ Modern app design mockup style"""
417
+ },
418
+ "Product Design": {
419
+ "keywords": ['์ œํ’ˆ', 'product', '๋””์ž์ธ', 'design', '์ปจ์…‰', 'concept', '์•„์ด๋””์–ด', 'idea'],
420
+ "priority": 2,
421
+ "prompt_template": """A sleek design concept:
422
+ {title}
423
+ - Modern aesthetic design
424
+ - Key features highlighted
425
+ - Professional sketch style
426
+ - Innovation focused
427
+ Clean product presentation"""
428
+ }
429
+ }
430
+
431
+ ##############################################################################
432
+ # Diagram Type Detection with FLUX Priority
433
+ ##############################################################################
434
+ def detect_flux_diagram_type(title: str, content: str) -> Tuple[Optional[str], float]:
435
+ """FLUX ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž… ๊ฐ์ง€ ๋ฐ ์šฐ์„ ์ˆœ์œ„ ์ ์ˆ˜ ๊ณ„์‚ฐ"""
436
  combined_text = f"{title} {content}".lower()
437
 
438
+ diagram_scores = {}
439
+
440
+ for diagram_type, config in FLUX_DIAGRAM_TYPES.items():
441
+ score = 0
442
+ # ํ‚ค์›Œ๋“œ ๋งค์นญ
443
+ for keyword in config['keywords']:
444
+ if keyword in combined_text:
445
+ score += config['priority']
446
+
447
+ # ์ถ”๊ฐ€ ์ ์ˆ˜ ๋ถ€์—ฌ
448
+ if diagram_type == "Flowchart" and any(char in content for char in ['1.', '2.', '3.', 'โ‘ ', 'โ‘ก', 'โ‘ข']):
449
+ score += 2
450
+ elif diagram_type == "Infographic" and any(word in combined_text for word in ['%', '์ฆ๊ฐ€', 'increase', '๊ฐ์†Œ', 'decrease']):
451
+ score += 2
452
+ elif diagram_type == "Mindmap" and (content.count('\n-') > 3 or content.count('\nโ€ข') > 3):
453
+ score += 2
454
+
455
+ if score > 0:
456
+ diagram_scores[diagram_type] = score
457
 
458
+ if diagram_scores:
459
+ best_type = max(diagram_scores.items(), key=lambda x: x[1])
460
+ return best_type[0], min(best_type[1] / 10.0, 1.0) # ์ •๊ทœํ™”
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
 
462
  return None, 0.0
463
 
 
2438
 
2439
  # AI ์ด๋ฏธ์ง€ ๋ฐ ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ ์•Œ๋ฆผ
2440
  visual_features = []
2441
+ if include_ai_image and AI_IMAGE_ENABLED:
2442
  visual_features.append("AI 3D ํ‘œ์ง€ ์ด๋ฏธ์ง€")
2443
  if include_diagrams and DIAGRAM_GENERATORS_AVAILABLE:
2444
+ visual_features.append("๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ (์ตœ๋Œ€ 2๊ฐœ)")
2445
  if include_flux_images and FLUX_API_ENABLED:
2446
+ visual_features.append("FLUX ๋‹ค์ด์–ด๊ทธ๋žจ (์ตœ์†Œ 5๊ฐœ)")
2447
+ visual_features.append("AI ์ƒ์„ฑ ์ด๋ฏธ์ง€")
2448
 
2449
  if visual_features:
2450
  yield None, f"๐Ÿ“ ์Šฌ๋ผ์ด๋“œ ์ƒ์„ฑ ์™„๋ฃŒ!\n\n๐ŸŽจ ์ƒ์„ฑ ์ค‘: {', '.join(visual_features)}... (์‹œ๊ฐ„์ด ์†Œ์š”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)", llm_response
 
2466
  success_msg += f"๐ŸŽจ ๋””์ž์ธ ํ…Œ๋งˆ: {DESIGN_THEMES[design_theme]['name']}\n"
2467
  success_msg += f"๐Ÿ“ ๋ ˆ์ด์•„์›ƒ ์Šคํƒ€์ผ: {layout_style}\n"
2468
 
2469
+ if include_ai_image and AI_IMAGE_ENABLED:
2470
+ success_msg += f"๐Ÿ–ผ๏ธ AI ์ƒ์„ฑ 3D ํ‘œ์ง€ ์ด๋ฏธ์ง€ ํฌํ•จ\n"
2471
+ if include_diagrams and FLUX_API_ENABLED:
2472
+ success_msg += f"๐Ÿ“Š FLUX ๋‹ค์ด์–ด๊ทธ๋žจ ํฌํ•จ (6๊ฐ€์ง€ ํƒ€์ž…)\n"
2473
  if include_diagrams and DIAGRAM_GENERATORS_AVAILABLE:
2474
+ success_msg += f"๐Ÿ“ˆ ๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ ํฌํ•จ (1-2๊ฐœ)\n"
2475
  if include_flux_images and FLUX_API_ENABLED:
2476
+ success_msg += f"๐ŸŽจ AI ์ƒ์„ฑ ์Šฌ๋ผ์ด๋“œ ์ด๋ฏธ์ง€ ํฌํ•จ\n"
2477
 
2478
  success_msg += f"๐Ÿ“ ์ƒ์„ฑ๋œ ์Šฌ๋ผ์ด๋“œ:\n"
2479
 
 
2791
  include_diagrams = gr.Checkbox(
2792
  label="๐Ÿ“Š AI ๋‹ค์ด์–ด๊ทธ๋žจ",
2793
  value=False,
2794
+ info="FLUX ๋‹ค์ด์–ด๊ทธ๋žจ 5๊ฐœ + ๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ 1-2๊ฐœ ์ƒ์„ฑ"
2795
  )
2796
 
2797
  include_flux_images = gr.Checkbox(
 
2846
  5. **์ฐธ๊ณ  ์ž๋ฃŒ ์—…๋กœ๋“œ**: PDF, CSV, TXT ํŒŒ์ผ ์ง€์›
2847
  6. **์ƒ์„ฑ ๋ฒ„ํŠผ ํด๋ฆญ**: AI๊ฐ€ ์ž๋™์œผ๋กœ PPT ์ƒ์„ฑ
2848
 
2849
+ ### ๐ŸŽจ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ - FLUX ๋‹ค์ด์–ด๊ทธ๋žจ 6๊ฐ€์ง€ ํƒ€์ž…
2850
+ - **Flowchart**: ํ”„๋กœ์„ธ์Šค์™€ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์‹œ๊ฐํ™” (์šฐ์„ ์ˆœ์œ„ ๋†’์Œ)
2851
+ - **Mindmap**: ๊ฐœ๋…๊ณผ ๊ด€๊ณ„๋ฅผ ๊ตฌ์กฐํ™”ํ•˜์—ฌ ํ‘œํ˜„
2852
+ - **Infographic**: ๋ฐ์ดํ„ฐ์™€ ํ†ต๊ณ„๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„
2853
+ - **Diagram**: ๊ตฌ์กฐ์™€ ์‹œ์Šคํ…œ์„ ๋‹ค์ด์–ด๊ทธ๋žจ์œผ๋กœ ํ‘œํ˜„
2854
+ - **Mockup**: UI/UX ๋””์ž์ธ ์™€์ด์–ดํ”„๋ ˆ์ž„
2855
+ - **Product Design**: ์ œํ’ˆ ์ปจ์…‰ ๋””์ž์ธ
2856
+
2857
+ ### ๐Ÿ“Š ์‹œ๊ฐ ์š”์†Œ ๋ถ„๋ฐฐ (10ํŽ˜์ด์ง€ ๊ธฐ์ค€)
2858
+ - **ํ‘œ์ง€**: 3D ์ด๋ฏธ์ง€ 1๊ฐœ
2859
+ - **FLUX ๋‹ค์ด์–ด๊ทธ๋žจ**: ์ตœ์†Œ 5๊ฐœ (6๊ฐ€์ง€ ํƒ€์ž… ์ค‘ ์ž๋™ ์„ ํƒ)
2860
+ - **๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ**: 1-2๊ฐœ (WBS, ๋ณต์žกํ•œ ํ”„๋กœ์„ธ์Šค ๋“ฑ)
2861
+ - **3D/ํฌํ†  ์ด๋ฏธ์ง€**: ๋‚˜๋จธ์ง€ ์Šฌ๋ผ์ด๋“œ์— ๋ถ„๋ฐฐ
2862
+ - **๋ชจ๋“  ์Šฌ๋ผ์ด๋“œ**์— ์‹œ๊ฐ์  ์š”์†Œ ํฌํ•จ
2863
 
2864
  ### ๐Ÿ’ก ๊ณ ๊ธ‰ ํŒ
2865
+ - **ํ•œ๊ธ€ ์ง€์›**: FLUX API๋ฅผ ํ†ตํ•ด ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ์œผ๋กœ ํ•œ๊ธ€ ๊นจ์ง ๋ฌธ์ œ ํ•ด๊ฒฐ
2866
+ - **์Šค๋งˆํŠธ ๋‹ค์ด์–ด๊ทธ๋žจ ์„ ํƒ**: ์Šฌ๋ผ์ด๋“œ ๋‚ด์šฉ์„ ๋ถ„์„ํ•˜์—ฌ ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž… ์ž๋™ ์„ ํƒ
2867
+ - **ํ”„๋กœ์„ธ์Šค ํ”Œ๋กœ์šฐ ์šฐ์„ **: ํ”„๋กœ์„ธ์Šค ๊ด€๋ จ ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด Flowchart๋ฅผ ์šฐ์„  ์ ์šฉ
2868
+ - **๊ท ํ˜•์žกํžŒ ์‹œ๊ฐํ™”**: ๋ชจ๋“  ์Šฌ๋ผ์ด๋“œ์— ์ ์ ˆํ•œ ์‹œ๊ฐ ์š”์†Œ๋ฅผ ๋ฐฐ์น˜ํ•˜์—ฌ ์ผ๊ด€๋œ ํ’ˆ์งˆ ์œ ์ง€
2869
  """
2870
  )
2871
 
 
2906
 
2907
  # Initialize APIs on startup
2908
  if __name__ == "__main__":
2909
+ # ํ•œ๊ธ€ ํฐํŠธ ํ™•์ธ (๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ์šฉ)
2910
  if os.path.exists(KOREAN_FONT_PATH):
2911
  logger.info(f"โœ… ํ•œ๊ธ€ ํฐํŠธ ํŒŒ์ผ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค: {KOREAN_FONT_PATH}")
2912
  else:
2913
  logger.warning(f"โš ๏ธ ํ•œ๊ธ€ ํฐํŠธ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค: {KOREAN_FONT_PATH}")
2914
+ logger.warning("๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ํ•œ๊ธ€์ด ๊นจ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. NanumGothic-Regular.ttf ํŒŒ์ผ์„ app.py์™€ ๊ฐ™์€ ๊ฒฝ๋กœ์— ๋ฐฐ์น˜ํ•˜์„ธ์š”.")
2915
 
2916
  # Try to initialize APIs in parallel
2917
  with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
 
2930
 
2931
  # ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ๊ธฐ ๋ชจ๋“ˆ ์ƒํƒœ ํ™•์ธ
2932
  if DIAGRAM_GENERATORS_AVAILABLE:
2933
+ logger.info("โœ… ๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ๊ธฐ ๋ชจ๋“ˆ์ด ์ •์ƒ์ ์œผ๋กœ ๋กœ๋“œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค")
2934
+ logger.info("๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž…: Process Flow, Concept Map, WBS, Radial, Synoptic Chart")
2935
  else:
2936
+ logger.warning("โš ๏ธ ๋กœ์ปฌ ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ๊ธฐ ๋ชจ๋“ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
2937
+
2938
+ if FLUX_API_ENABLED:
2939
+ logger.info("โœ… FLUX ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ ๊ฐ€๋Šฅ")
2940
+ logger.info("FLUX ๋‹ค์ด์–ด๊ทธ๋žจ ํƒ€์ž…: Flowchart, Mindmap, Infographic, Diagram, Mockup, Product Design")
2941
 
2942
  demo.launch()