newapi-clone / routers /wordpress.py
habulaj's picture
Update routers/wordpress.py
f4ee8de verified
import os
import httpx
from typing import Optional
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
router = APIRouter()
# 🔧 Configuração do WordPress
WP_URL = os.getenv("WP_URL")
WP_USER = os.getenv("WP_USER")
WP_PASS = os.getenv("WP_PASS")
if not WP_URL or not WP_USER or not WP_PASS:
raise ValueError("❌ WP_URL, WP_USER ou WP_PASS não configurados!")
AUTH = (WP_USER, WP_PASS)
class WPPost(BaseModel):
title: str
content: str
subhead: Optional[str] = None # 👈 campo ACF mapeado para "subtitulo"
image_url: Optional[str] = None
author_username: Optional[str] = None # 👈 novo campo para o username do author
status: str = "publish"
async def get_user_id_by_username(client: httpx.AsyncClient, username: str) -> Optional[int]:
"""Busca o ID do usuário pelo username"""
try:
response = await client.get(f"{WP_URL}/users?search={username}", auth=AUTH)
if response.status_code == 200:
users = response.json()
for user in users:
if user.get("slug") == username or user.get("name") == username:
return user.get("id")
return None
except Exception:
return None
@router.post("/wordpress/post")
async def create_wordpress_post(post: WPPost):
async with httpx.AsyncClient(timeout=20.0) as client:
featured_media_id = None
author_id = None
# 👤 Buscar ID do author se username fornecido
if post.author_username:
author_id = await get_user_id_by_username(client, post.author_username)
if not author_id:
raise HTTPException(
status_code=404,
detail=f"Usuário '{post.author_username}' não encontrado"
)
# Upload de imagem se fornecida
if post.image_url:
try:
img_resp = await client.get(post.image_url, timeout=15.0)
if img_resp.status_code == 200:
filename = post.image_url.split("/")[-1].split("?")[0]
media_headers = {
"Content-Disposition": f"attachment; filename={filename}",
"Content-Type": img_resp.headers.get("content-type", "image/jpeg")
}
upload = await client.post(
f"{WP_URL}/media",
auth=AUTH,
headers=media_headers,
content=img_resp.content
)
if upload.status_code in [200, 201]:
featured_media_id = upload.json().get("id")
except Exception:
pass # Ignora erro de imagem para não quebrar o post
# Dados do post
post_data = {
"title": post.title,
"content": post.content,
"status": post.status
}
if featured_media_id:
post_data["featured_media"] = featured_media_id
# 👤 Adicionar author se encontrado
if author_id:
post_data["author"] = author_id
# Campo ACF: subhead → subtitulo
if post.subhead:
post_data["subtitulo"] = post.subhead
# Criar post
response = await client.post(f"{WP_URL}/posts", auth=AUTH, json=post_data)
if response.status_code not in [200, 201]:
raise HTTPException(status_code=response.status_code, detail=response.text)
result = response.json()
# 🔄 Fallback: Se ACF não foi salvo, tentar novamente
if post.subhead and not result.get("acf", {}).get("subtitulo"):
post_id = result.get("id")
if post_id:
acf_data = {"acf": {"subtitulo": post.subhead}}
update_resp = await client.post(f"{WP_URL}/posts/{post_id}", auth=AUTH, json=acf_data)
if update_resp.status_code in [200, 201]:
result = update_resp.json()
return result