From 80fc3d21c7a6a1e1a5caea2a087d66bfb21dd4be Mon Sep 17 00:00:00 2001 From: "stephane.david" Date: Sun, 24 May 2026 12:33:40 +0200 Subject: [PATCH] New version --- Dockerfile | 13 +-- app/main.py | 183 ++++-------------------------------------- app/pptx_generator.py | 21 +++++ app/template.pptx | Bin 0 -> 32618 bytes 4 files changed, 44 insertions(+), 173 deletions(-) create mode 100644 app/pptx_generator.py create mode 100644 app/template.pptx diff --git a/Dockerfile b/Dockerfile index 1b364a6..96acdab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,13 @@ -FROM python:3.12-slim +FROM python:3.11-slim WORKDIR /app -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +RUN apt-get update && apt-get install -y \ + libxml2 libxslt1.1 libjpeg62-turbo && \ + pip install --no-cache-dir fastapi uvicorn python-pptx pydantic -COPY app ./app +COPY app /app -EXPOSE 8000 +EXPOSE 5000 -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "5000"] \ No newline at end of file diff --git a/app/main.py b/app/main.py index 0d275de..ab939e1 100644 --- a/app/main.py +++ b/app/main.py @@ -1,172 +1,21 @@ -from fastapi import FastAPI, HTTPExceptionfrom fastapi import FastAPI, HTTP(BaseModel): - filename: Optional[str] = "presentation" - title: str = "Présentation" - subtitle: Optional[str] = None - slides: List[SlideData] = Field(default_factory=list) +from fastapi import FastAPI +from fastapi.responses import FileResponse +from pydantic import BaseModel +from pptx_generator import generate_pptx +import uuid +import os +app = FastAPI() -# ---------------------------- -# Utilitaires -# ---------------------------- - -def sanitize_filename(name: str) -> str: - cleaned = re.sub(r"[^a-zA-Z0-9_-]", "_", name.strip()) - return cleaned or "presentation" - - -def add_title_slide(prs: Presentation, title: str, subtitle: Optional[str]) -> None: - slide_layout = prs.slide_layouts[6] # blank - slide = prs.slides.add_slide(slide_layout) - - # Fond visuel simple via zone blanche implicite - title_box = slide.shapes.add_textbox(Inches(0.6), Inches(1.0), Inches(11.5), Inches(1.0)) - tf = title_box.text_frame - p = tf.paragraphs[0] - p.text = title - p.font.size = Pt(24) - p.font.bold = True - p.alignment = PP_ALIGN.LEFT - - if subtitle: - subtitle_box = slide.shapes.add_textbox(Inches(0.6), Inches(1.8), Inches(11.0), Inches(0.8)) - tf2 = subtitle_box.text_frame - p2 = tf2.paragraphs[0] - p2.text = subtitle - p2.font.size = Pt(14) - p2.alignment = PP_ALIGN.LEFT - - -def add_content_slide(prs: Presentation, slide_data: SlideData) -> None: - slide_layout = prs.slide_layouts[6] # blank - slide = prs.slides.add_slide(slide_layout) - - # Titre - title_box = slide.shapes.add_textbox(Inches(0.5), Inches(0.4), Inches(12.0), Inches(0.8)) - tf_title = title_box.text_frame - p_title = tf_title.paragraphs[0] - p_title.text = slide_data.title - p_title.font.size = Pt(22) - p_title.font.bold = True - p_title.alignment = PP_ALIGN.LEFT - - current_top = 1.3 - - # Texte libre - if slide_data.text: - text_box = slide.shapes.add_textbox(Inches(0.7), Inches(current_top), Inches(11.0), Inches(1.2)) - tf_text = text_box.text_frame - tf_text.word_wrap = True - p_text = tf_text.paragraphs[0] - p_text.text = slide_data.text - p_text.font.size = Pt(16) - p_text.alignment = PP_ALIGN.LEFT - current_top += 1.0 - - # Liste à puces - if slide_data.bullets: - bullets_box = slide.shapes.add_textbox(Inches(1.0), Inches(current_top), Inches(10.8), Inches(4.0)) - tf_bullets = bullets_box.text_frame - tf_bullets.word_wrap = True - - first = True - for bullet in slide_data.bullets: - if first: - p = tf_bullets.paragraphs[0] - first = False - else: - p = tf_bullets.add_paragraph() - - p.text = bullet - p.level = 0 - p.font.size = Pt(18) - p.alignment = PP_ALIGN.LEFT - p.bullet = True - - -def generate_pptx(data: PresentationRequest) -> str: - prs = Presentation() - prs.slide_width = Inches(13.333) # 16:9 - prs.slide_height = Inches(7.5) - - # Métadonnées - prs.core_properties.title = data.title - prs.core_properties.subject = data.title - prs.core_properties.author = "M365 Copilot" - prs.core_properties.company = "Votre organisation" - - # Slide de titre - add_title_slide(prs, data.title, data.subtitle) - - # Slides de contenu - for slide in data.slides: - add_content_slide(prs, slide) - - filename = sanitize_filename(data.filename) - tmp_dir = tempfile.gettempdir() - full_path = os.path.join(tmp_dir, f"{filename}_{uuid.uuid4().hex}.pptx") - prs.save(full_path) - return full_path - - -# ---------------------------- -# Endpoints -# ---------------------------- - -@app.get("/health") -def health(): - return {"status": "ok"} +class Slide(BaseModel): + title: str + bullets: list[str] +class PresentationData(BaseModel): + slides: list[Slide] @app.post("/generate") -def generate_presentation(payload: PresentationRequest): - try: - output_path = generate_pptx(payload) - download_name = f"{sanitize_filename(payload.filename)}.pptx" - - return FileResponse( - path=output_path, - media_type="application/vnd.openxmlformats-officedocument.presentationml.presentation", - filename=download_name - ) - except Exception as e: - raise HTTPException(status_code=500, detail=f"Erreur lors de la génération du PPTX : {str(e)}") - - -@app.get("/") -def root(): - return JSONResponse({ - "service": "pptx-service", - "status": "running", - "endpoints": { - "health": "/health", - "generate": "/generate" - } - }) -from fastapi.responses import FileResponse, JSONResponse -from pydantic import BaseModel, Field -from typing import List, Optional -from pptx import Presentation -from pptx.util import Inches, Pt -from pptx.enum.text import PP_ALIGN -import tempfile -import os -import re -import uuid - -app = FastAPI( - title="PPTX JSON Service", - description="Génère un fichier PowerPoint (.pptx) à partir d'un JSON", - version="1.0.0" -) - - -# ---------------------------- -# Modèles de données -# ---------------------------- - -class SlideData(BaseModel): - title: str - text: Optional[str] = None - bullets: Optional[List[str]] = Field(default_factory=list) - - +def generate(data: PresentationData): + output_file = f"/tmp/{uuid.uuid4()}.pptx" + generate_pptx(data.slides, output_file) + return FileResponse(output_file, media_type="application/vnd.openxmlformats-officedocument.presentationml.presentation") diff --git a/app/pptx_generator.py b/app/pptx_generator.py new file mode 100644 index 0000000..3cf68c5 --- /dev/null +++ b/app/pptx_generator.py @@ -0,0 +1,21 @@ +from pptx import Presentation + +def generate_pptx(slides, output_file): + prs = Presentation("template.pptx") + + for slide_data in slides: + slide_layout = prs.slide_layouts[1] # Title + Content + slide = prs.slides.add_slide(slide_layout) + + title = slide.shapes.title + body = slide.placeholders[1].text_frame + + title.text = slide_data.title + body.clear() + + for bullet in slide_data.bullets: + p = body.add_paragraph() + p.text = bullet + p.level = 0 + + prs.save(output_file) diff --git a/app/template.pptx b/app/template.pptx new file mode 100644 index 0000000000000000000000000000000000000000..3e9f084d7a53e5eeb2041834d73374e62c54d0ec GIT binary patch literal 32618 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 P>`N9_^#RrK?6>~`+p_@J literal 0 HcmV?d00001