File size: 6,800 Bytes
09cc9dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor
import tempfile
import logging

logger = logging.getLogger(__name__)

class PresentationGenerator:
    def __init__(self):
        self.styles = {
            "professionnel": {
                "title_color": RGBColor(0, 0, 128),
                "text_color": RGBColor(0, 0, 0),
                "background_color": RGBColor(255, 255, 255),
                "font_name": "Calibri"
            },
            "moderne": {
                "title_color": RGBColor(220, 20, 60),
                "text_color": RGBColor(50, 50, 50),
                "background_color": RGBColor(240, 240, 240),
                "font_name": "Segoe UI"
            },
            "creatif": {
                "title_color": RGBColor(75, 0, 130),
                "text_color": RGBColor(0, 0, 0),
                "background_color": RGBColor(255, 250, 240),
                "font_name": "Arial"
            }
        }
    
    def generate_presentation(self, structure, style="professionnel"):
        """Génère une présentation PowerPoint à partir de la structure IA"""
        try:
            logger.info("📄 Initialisation de la présentation...")
            prs = Presentation()
            style_config = self.styles.get(style, self.styles["professionnel"])
            
            logger.info("🎯 Ajout de la slide de titre...")
            self._add_title_slide(prs, structure, style_config)
            
            logger.info("📄 Ajout des slides de contenu...")
            for i, slide_data in enumerate(structure.get('slides', [])):
                logger.info(f"  ➕ Slide {i+1}: {slide_data.get('title', 'Sans titre')}")
                self._add_content_slide(prs, slide_data, style_config)
            
            if structure.get('key_points'):
                logger.info("🧠 Ajout des points clés...")
                self._add_keypoints_slide(prs, structure, style_config)
            
            logger.info("🏁 Ajout de la conclusion...")
            self._add_conclusion_slide(prs, style_config)
            
            logger.info("💾 Sauvegarde de la présentation...")
            temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.pptx')
            prs.save(temp_file.name)
            
            logger.info(f"✅ Présentation enregistrée dans : {temp_file.name}")
            return temp_file.name

        except Exception as e:
            logger.error(f"❌ Erreur génération présentation: {e}")
            raise

    def _add_title_slide(self, prs, structure, style_config):
        """Ajoute la slide de titre"""
        slide_layout = prs.slide_layouts[0]
        slide = prs.slides.add_slide(slide_layout)
        title = slide.shapes.title
        subtitle = slide.placeholders[1]
        
        title.text = structure.get('title', 'Présentation Générée par IA')
        subtitle.text = f"Style: {style_config}\nGénéré intelligemment par IA"

    def _add_content_slide(self, prs, slide_data, style_config):
        """Ajoute une slide de contenu"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)

        title_shape = slide.shapes.title
        try:
            content_shape = slide.placeholders[1]
        except IndexError:
            logger.warning("⚠️ Placeholder 1 non trouvé. Création d'une textbox manuelle.")
            content_shape = slide.shapes.add_textbox(Inches(1), Inches(2), Inches(8), Inches(5))
            content_shape.text_frame.text = ""

        title_shape.text = slide_data.get('title', 'Slide')
        content_shape.text = slide_data.get('content', '')

        self._apply_style(title_shape, style_config, is_title=True)
        self._apply_style(content_shape, style_config, is_title=False)

    def _add_keypoints_slide(self, prs, structure, style_config):
        """Ajoute la slide des points clés"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        try:
            content_shape = slide.placeholders[1]
        except IndexError:
            logger.warning("⚠️ Placeholder 1 non trouvé. Création d'une textbox manuelle.")
            content_shape = slide.shapes.add_textbox(Inches(1), Inches(2), Inches(8), Inches(5))
            content_shape.text_frame.text = ""
        
        title_shape.text = "Points Clés Identifiés par IA"
        content_shape.text = "\n".join([f"• {point}" for point in structure['key_points']])
        
        self._apply_style(title_shape, style_config, is_title=True)
        self._apply_style(content_shape, style_config, is_title=False)
    
    def _add_conclusion_slide(self, prs, style_config):
        """Ajoute la slide de conclusion"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        try:
            content_shape = slide.placeholders[1]
        except IndexError:
            logger.warning("⚠️ Placeholder 1 non trouvé. Création d'une textbox manuelle.")
            content_shape = slide.shapes.add_textbox(Inches(1), Inches(2), Inches(8), Inches(5))
            content_shape.text_frame.text = ""
        
        title_shape.text = "Conclusion"
        content_shape.text = "Présentation générée automatiquement avec IA\nAnalyse sémantique avancée\nMerci pour votre attention !"
        
        self._apply_style(title_shape, style_config, is_title=True)
        self._apply_style(content_shape, style_config, is_title=False)
    
    def _apply_style(self, shape, style_config, is_title=True):
        """Applique le style aux éléments textuels"""
        if not hasattr(shape, "text_frame") or shape.text_frame is None:
            logger.warning("⚠️ Shape sans text_frame, style non appliqué.")
            return

        try:
            for paragraph in shape.text_frame.paragraphs:
                for run in paragraph.runs:
                    if run.font:
                        run.font.name = style_config["font_name"]
                        run.font.color.rgb = (
                            style_config["title_color"] if is_title else style_config["text_color"]
                        )
                        run.font.size = Pt(32 if is_title else 18)
                        run.font.bold = is_title
        except Exception as e:
            logger.warning(f"❌ Échec de l'application du style: {e}")
            print("présentation générée")