410 lines
14 KiB
Python
410 lines
14 KiB
Python
"""
|
|
WordPress API Routes
|
|
REST API endpoints for WordPress integration management.
|
|
"""
|
|
|
|
from fastapi import APIRouter, HTTPException, Depends, status
|
|
from fastapi.responses import JSONResponse
|
|
from typing import List, Optional, Dict, Any
|
|
from pydantic import BaseModel, HttpUrl
|
|
from loguru import logger
|
|
|
|
from services.integrations.wordpress_service import WordPressService
|
|
from services.integrations.wordpress_publisher import WordPressPublisher
|
|
from middleware.auth_middleware import get_current_user
|
|
|
|
|
|
router = APIRouter(prefix="/wordpress", tags=["WordPress"])
|
|
|
|
|
|
# Pydantic Models
|
|
class WordPressSiteRequest(BaseModel):
|
|
site_url: str
|
|
site_name: str
|
|
username: str
|
|
app_password: str
|
|
|
|
|
|
class WordPressSiteResponse(BaseModel):
|
|
id: int
|
|
site_url: str
|
|
site_name: str
|
|
username: str
|
|
is_active: bool
|
|
created_at: str
|
|
updated_at: str
|
|
|
|
|
|
class WordPressPublishRequest(BaseModel):
|
|
site_id: int
|
|
title: str
|
|
content: str
|
|
excerpt: Optional[str] = ""
|
|
featured_image_path: Optional[str] = None
|
|
categories: Optional[List[str]] = None
|
|
tags: Optional[List[str]] = None
|
|
status: str = "draft"
|
|
meta_description: Optional[str] = ""
|
|
|
|
|
|
class WordPressPublishResponse(BaseModel):
|
|
success: bool
|
|
post_id: Optional[int] = None
|
|
post_url: Optional[str] = None
|
|
error: Optional[str] = None
|
|
|
|
|
|
class WordPressPostResponse(BaseModel):
|
|
id: int
|
|
wp_post_id: int
|
|
title: str
|
|
status: str
|
|
published_at: Optional[str]
|
|
created_at: str
|
|
site_name: str
|
|
site_url: str
|
|
|
|
|
|
class WordPressStatusResponse(BaseModel):
|
|
connected: bool
|
|
sites: Optional[List[WordPressSiteResponse]] = None
|
|
total_sites: int = 0
|
|
|
|
|
|
# Initialize services
|
|
wp_service = WordPressService()
|
|
wp_publisher = WordPressPublisher()
|
|
|
|
|
|
@router.get("/status", response_model=WordPressStatusResponse)
|
|
async def get_wordpress_status(user: dict = Depends(get_current_user)):
|
|
"""Get WordPress connection status for the current user."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Checking WordPress status for user: {user_id}")
|
|
|
|
# Get user's WordPress sites
|
|
sites = wp_service.get_all_sites(user_id)
|
|
|
|
if sites:
|
|
# Convert to response format
|
|
site_responses = [
|
|
WordPressSiteResponse(
|
|
id=site['id'],
|
|
site_url=site['site_url'],
|
|
site_name=site['site_name'],
|
|
username=site['username'],
|
|
is_active=site['is_active'],
|
|
created_at=site['created_at'],
|
|
updated_at=site['updated_at']
|
|
)
|
|
for site in sites
|
|
]
|
|
|
|
logger.info(f"Found {len(sites)} WordPress sites for user {user_id}")
|
|
return WordPressStatusResponse(
|
|
connected=True,
|
|
sites=site_responses,
|
|
total_sites=len(sites)
|
|
)
|
|
else:
|
|
logger.info(f"No WordPress sites found for user {user_id}")
|
|
return WordPressStatusResponse(
|
|
connected=False,
|
|
sites=[],
|
|
total_sites=0
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting WordPress status for user {user_id}: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error checking WordPress status: {str(e)}")
|
|
|
|
|
|
@router.post("/sites", response_model=WordPressSiteResponse)
|
|
async def add_wordpress_site(
|
|
site_request: WordPressSiteRequest,
|
|
user: dict = Depends(get_current_user)
|
|
):
|
|
"""Add a new WordPress site connection."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Adding WordPress site for user {user_id}: {site_request.site_name}")
|
|
|
|
# Add the site
|
|
success = wp_service.add_site(
|
|
user_id=user_id,
|
|
site_url=site_request.site_url,
|
|
site_name=site_request.site_name,
|
|
username=site_request.username,
|
|
app_password=site_request.app_password
|
|
)
|
|
|
|
if not success:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="Failed to connect to WordPress site. Please check your credentials."
|
|
)
|
|
|
|
# Get the added site info
|
|
sites = wp_service.get_all_sites(user_id)
|
|
if sites:
|
|
latest_site = sites[0] # Most recent site
|
|
return WordPressSiteResponse(
|
|
id=latest_site['id'],
|
|
site_url=latest_site['site_url'],
|
|
site_name=latest_site['site_name'],
|
|
username=latest_site['username'],
|
|
is_active=latest_site['is_active'],
|
|
created_at=latest_site['created_at'],
|
|
updated_at=latest_site['updated_at']
|
|
)
|
|
else:
|
|
raise HTTPException(status_code=500, detail="Site added but could not retrieve details")
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error adding WordPress site: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error adding WordPress site: {str(e)}")
|
|
|
|
|
|
@router.get("/sites", response_model=List[WordPressSiteResponse])
|
|
async def get_wordpress_sites(user: dict = Depends(get_current_user)):
|
|
"""Get all WordPress sites for the current user."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Getting WordPress sites for user: {user_id}")
|
|
|
|
sites = wp_service.get_all_sites(user_id)
|
|
|
|
site_responses = [
|
|
WordPressSiteResponse(
|
|
id=site['id'],
|
|
site_url=site['site_url'],
|
|
site_name=site['site_name'],
|
|
username=site['username'],
|
|
is_active=site['is_active'],
|
|
created_at=site['created_at'],
|
|
updated_at=site['updated_at']
|
|
)
|
|
for site in sites
|
|
]
|
|
|
|
logger.info(f"Retrieved {len(sites)} WordPress sites for user {user_id}")
|
|
return site_responses
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting WordPress sites for user {user_id}: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error retrieving WordPress sites: {str(e)}")
|
|
|
|
|
|
@router.delete("/sites/{site_id}")
|
|
async def disconnect_wordpress_site(
|
|
site_id: int,
|
|
user: dict = Depends(get_current_user)
|
|
):
|
|
"""Disconnect a WordPress site."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Disconnecting WordPress site {site_id} for user {user_id}")
|
|
|
|
success = wp_service.disconnect_site(user_id, site_id)
|
|
|
|
if not success:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="WordPress site not found or already disconnected"
|
|
)
|
|
|
|
logger.info(f"WordPress site {site_id} disconnected successfully")
|
|
return {"success": True, "message": "WordPress site disconnected successfully"}
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error disconnecting WordPress site {site_id}: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error disconnecting WordPress site: {str(e)}")
|
|
|
|
|
|
@router.post("/publish", response_model=WordPressPublishResponse)
|
|
async def publish_to_wordpress(
|
|
publish_request: WordPressPublishRequest,
|
|
user: dict = Depends(get_current_user)
|
|
):
|
|
"""Publish content to a WordPress site."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Publishing to WordPress site {publish_request.site_id} for user {user_id}")
|
|
|
|
# Publish the content
|
|
result = wp_publisher.publish_blog_post(
|
|
user_id=user_id,
|
|
site_id=publish_request.site_id,
|
|
title=publish_request.title,
|
|
content=publish_request.content,
|
|
excerpt=publish_request.excerpt,
|
|
featured_image_path=publish_request.featured_image_path,
|
|
categories=publish_request.categories,
|
|
tags=publish_request.tags,
|
|
status=publish_request.status,
|
|
meta_description=publish_request.meta_description
|
|
)
|
|
|
|
if result['success']:
|
|
logger.info(f"Content published successfully to WordPress: {result['post_id']}")
|
|
return WordPressPublishResponse(
|
|
success=True,
|
|
post_id=result['post_id'],
|
|
post_url=result.get('post_url')
|
|
)
|
|
else:
|
|
logger.error(f"Failed to publish content: {result['error']}")
|
|
return WordPressPublishResponse(
|
|
success=False,
|
|
error=result['error']
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error publishing to WordPress: {e}")
|
|
return WordPressPublishResponse(
|
|
success=False,
|
|
error=f"Error publishing content: {str(e)}"
|
|
)
|
|
|
|
|
|
@router.get("/posts", response_model=List[WordPressPostResponse])
|
|
async def get_wordpress_posts(
|
|
site_id: Optional[int] = None,
|
|
user: dict = Depends(get_current_user)
|
|
):
|
|
"""Get published posts from WordPress sites."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Getting WordPress posts for user {user_id}, site_id: {site_id}")
|
|
|
|
posts = wp_service.get_posts_for_site(user_id, site_id) if site_id else wp_service.get_posts_for_all_sites(user_id)
|
|
|
|
post_responses = [
|
|
WordPressPostResponse(
|
|
id=post['id'],
|
|
wp_post_id=post['wp_post_id'],
|
|
title=post['title'],
|
|
status=post['status'],
|
|
published_at=post['published_at'],
|
|
created_at=post['created_at'],
|
|
site_name=post['site_name'],
|
|
site_url=post['site_url']
|
|
)
|
|
for post in posts
|
|
]
|
|
|
|
logger.info(f"Retrieved {len(posts)} WordPress posts for user {user_id}")
|
|
return post_responses
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting WordPress posts for user {user_id}: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error retrieving WordPress posts: {str(e)}")
|
|
|
|
|
|
@router.put("/posts/{post_id}/status")
|
|
async def update_post_status(
|
|
post_id: int,
|
|
status: str,
|
|
user: dict = Depends(get_current_user)
|
|
):
|
|
"""Update the status of a WordPress post (draft/publish)."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
if status not in ['draft', 'publish', 'private']:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="Invalid status. Must be 'draft', 'publish', or 'private'"
|
|
)
|
|
|
|
logger.info(f"Updating WordPress post {post_id} status to {status} for user {user_id}")
|
|
|
|
success = wp_publisher.update_post_status(user_id, post_id, status)
|
|
|
|
if not success:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="Post not found or update failed"
|
|
)
|
|
|
|
logger.info(f"WordPress post {post_id} status updated to {status}")
|
|
return {"success": True, "message": f"Post status updated to {status}"}
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error updating WordPress post {post_id} status: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error updating post status: {str(e)}")
|
|
|
|
|
|
@router.delete("/posts/{post_id}")
|
|
async def delete_wordpress_post(
|
|
post_id: int,
|
|
force: bool = False,
|
|
user: dict = Depends(get_current_user)
|
|
):
|
|
"""Delete a WordPress post."""
|
|
try:
|
|
user_id = user.get('id')
|
|
if not user_id:
|
|
raise HTTPException(status_code=400, detail="User ID not found")
|
|
|
|
logger.info(f"Deleting WordPress post {post_id} for user {user_id}, force: {force}")
|
|
|
|
success = wp_publisher.delete_post(user_id, post_id, force)
|
|
|
|
if not success:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="Post not found or deletion failed"
|
|
)
|
|
|
|
logger.info(f"WordPress post {post_id} deleted successfully")
|
|
return {"success": True, "message": "Post deleted successfully"}
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error deleting WordPress post {post_id}: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error deleting post: {str(e)}")
|
|
|
|
|
|
@router.get("/health")
|
|
async def wordpress_health_check():
|
|
"""WordPress integration health check."""
|
|
try:
|
|
return {
|
|
"status": "healthy",
|
|
"service": "wordpress",
|
|
"timestamp": "2024-01-01T00:00:00Z",
|
|
"version": "1.0.0"
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"WordPress health check failed: {e}")
|
|
raise HTTPException(status_code=500, detail="WordPress service unhealthy")
|