File size: 3,711 Bytes
c4f0411
 
 
 
837227b
1303dea
2ce54f6
 
cd0a3ca
 
 
c4f0411
 
 
 
 
 
 
 
 
1303dea
 
 
 
 
e5c3fa4
cd0a3ca
 
c4f0411
 
1303dea
 
e5c3fa4
1303dea
 
e5c3fa4
 
 
1303dea
 
 
e5c3fa4
 
2ce54f6
e5c3fa4
2ce54f6
 
e5c3fa4
2ce54f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
837227b
 
 
 
1303dea
2ce54f6
837227b
2ce54f6
 
837227b
2ce54f6
 
837227b
2ce54f6
837227b
1303dea
2ce54f6
 
 
 
 
 
1303dea
2ce54f6
1303dea
 
 
 
 
2ce54f6
 
 
 
 
 
1303dea
c4f0411
2ce54f6
 
 
 
 
 
1303dea
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
from fastapi import FastAPI, HTTPException
from fastapi.responses import Response
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from playwright.async_api import async_playwright
from typing import Optional
import tempfile
import os

app = FastAPI()

# Configura CORS para permitir requisições do frontend
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Em produção, especifique os domínios permitidos
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Modelo para criar posts (gerar imagem a partir de HTML)
class PostRequest(BaseModel):
    html: str
    width: Optional[int] = 1080  # Largura padrão para posts (Instagram)
    height: Optional[int] = 1350  # Altura padrão para posts (Instagram)

@app.get("/")
def greet_json():
    return {"Hello": "World!"}

@app.post("/create-post")
async def create_post(request: PostRequest):
    """
    Cria uma imagem a partir de HTML para posts.
    Recebe HTML e retorna uma imagem PNG.
    
    Exemplo de uso:
    {
        "html": "<div>Conteúdo do post</div>",
        "width": 1080,
        "height": 1350
    }
    """
    html_file = None
    try:
        # Garantir que o HTML está completo
        html_content = request.html
        
        # Se o HTML não tiver estrutura completa, adicionar
        if "<!DOCTYPE" not in html_content and "<html" not in html_content:
            html_content = f"""<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
{html_content}
</body>
</html>"""
        
        # Criar arquivo temporário para o HTML
        with tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False, encoding='utf-8') as f:
            f.write(html_content)
            html_file = f.name
        
        try:
            # Usar Playwright Async API para renderizar HTML e gerar screenshot
            async with async_playwright() as p:
                browser = await p.chromium.launch(headless=True)
                page = await browser.new_page(viewport={'width': request.width, 'height': request.height})
                
                # Carrega o HTML do arquivo temporário
                await page.goto(f'file://{html_file}')
                
                # Espera o conteúdo carregar (especialmente imagens base64)
                await page.wait_for_timeout(2000)  # Aguarda 2 segundos para garantir que imagens e fontes carreguem
                
                # Tira screenshot
                screenshot_bytes = await page.screenshot(full_page=True, type='png')
                
                await browser.close()
            
            # Remove arquivo temporário
            if os.path.exists(html_file):
                os.unlink(html_file)
                html_file = None
            
            # Retorna a imagem
            return Response(
                content=screenshot_bytes,
                media_type="image/png",
                headers={
                    "Content-Disposition": "attachment; filename=post.png"
                }
            )
        
        except Exception as e:
            # Remove arquivo temporário em caso de erro
            if html_file and os.path.exists(html_file):
                os.unlink(html_file)
            raise e
    
    except Exception as e:
        # Garantir limpeza do arquivo temporário
        if html_file and os.path.exists(html_file):
            try:
                os.unlink(html_file)
            except:
                pass
        raise HTTPException(status_code=500, detail=f"Erro ao gerar imagem do post: {str(e)}")