fixing wp-igny8-integration
This commit is contained in:
@@ -32,11 +32,18 @@ class WordPressAdapter(BaseAdapter):
|
||||
Args:
|
||||
content: Content instance or dict with content data
|
||||
destination_config: {
|
||||
# API Key method (preferred):
|
||||
'site_url': str,
|
||||
'api_key': str,
|
||||
|
||||
# OR username/password method:
|
||||
'site_url': str,
|
||||
'username': str,
|
||||
'app_password': str,
|
||||
'status': str (optional, default 'draft'),
|
||||
'featured_image_url': str (optional)
|
||||
|
||||
# Optional:
|
||||
'status': str (default 'draft'),
|
||||
'featured_image_url': str
|
||||
}
|
||||
|
||||
Returns:
|
||||
@@ -49,60 +56,46 @@ class WordPressAdapter(BaseAdapter):
|
||||
}
|
||||
"""
|
||||
try:
|
||||
# Get WordPress client
|
||||
client = self._get_client(destination_config)
|
||||
|
||||
# Extract content data
|
||||
if hasattr(content, 'title'):
|
||||
# Content model instance
|
||||
title = content.title
|
||||
# Stage 1 schema: content_html is the primary field
|
||||
content_html = getattr(content, 'content_html', '') or getattr(content, 'html_content', '') or getattr(content, 'content', '')
|
||||
content_html = getattr(content, 'content_html', '') or ''
|
||||
elif isinstance(content, dict):
|
||||
# Dict with content data
|
||||
title = content.get('title', '')
|
||||
content_html = content.get('content_html') or content.get('html_content') or content.get('content', '')
|
||||
content_html = content.get('content_html', '')
|
||||
else:
|
||||
raise ValueError(f"Unsupported content type: {type(content)}")
|
||||
|
||||
# Get publishing options
|
||||
status = destination_config.get('status', 'draft')
|
||||
featured_image_url = destination_config.get('featured_image_url')
|
||||
# Get site URL
|
||||
site_url = destination_config.get('site_url')
|
||||
if not site_url:
|
||||
raise ValueError("site_url is required in destination_config")
|
||||
|
||||
# Publish to WordPress
|
||||
result = client.create_post(
|
||||
title=title,
|
||||
content=content_html,
|
||||
status=status,
|
||||
featured_image_url=featured_image_url
|
||||
)
|
||||
# Check if using API key authentication
|
||||
api_key = destination_config.get('api_key')
|
||||
|
||||
# Handle different response formats (for compatibility with mocks and real API)
|
||||
if result.get('success') or result.get('id') or result.get('post_id'):
|
||||
# Extract post ID from various possible fields
|
||||
post_id = result.get('post_id') or result.get('id') or result.get('ID')
|
||||
url = result.get('url') or result.get('link')
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'external_id': str(post_id) if post_id else None,
|
||||
'url': url,
|
||||
'published_at': datetime.now(),
|
||||
'metadata': {
|
||||
'post_id': post_id,
|
||||
'status': status
|
||||
}
|
||||
}
|
||||
if api_key:
|
||||
# Use IGNY8 custom endpoint with API key
|
||||
return self._publish_via_api_key(
|
||||
site_url=site_url,
|
||||
api_key=api_key,
|
||||
content=content,
|
||||
title=title,
|
||||
content_html=content_html,
|
||||
destination_config=destination_config
|
||||
)
|
||||
else:
|
||||
return {
|
||||
'success': False,
|
||||
'external_id': None,
|
||||
'url': None,
|
||||
'published_at': None,
|
||||
'metadata': {
|
||||
'error': result.get('error', 'Unknown error')
|
||||
}
|
||||
}
|
||||
# Use standard WordPress REST API with username/password
|
||||
return self._publish_via_username_password(
|
||||
site_url=site_url,
|
||||
username=destination_config.get('username'),
|
||||
app_password=destination_config.get('app_password'),
|
||||
title=title,
|
||||
content_html=content_html,
|
||||
destination_config=destination_config
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
@@ -119,6 +112,139 @@ class WordPressAdapter(BaseAdapter):
|
||||
}
|
||||
}
|
||||
|
||||
def _publish_via_api_key(
|
||||
self,
|
||||
site_url: str,
|
||||
api_key: str,
|
||||
content: Any,
|
||||
title: str,
|
||||
content_html: str,
|
||||
destination_config: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Publish via IGNY8 custom WordPress endpoint using API key.
|
||||
This uses the /wp-json/igny8/v1/publish-content/ endpoint.
|
||||
"""
|
||||
import requests
|
||||
from django.utils.html import strip_tags
|
||||
|
||||
# Generate excerpt
|
||||
excerpt = ''
|
||||
if content_html:
|
||||
excerpt = strip_tags(content_html)[:150].strip()
|
||||
if len(content_html) > 150:
|
||||
excerpt += '...'
|
||||
|
||||
# Prepare payload
|
||||
content_data = {
|
||||
'content_id': content.id if hasattr(content, 'id') else None,
|
||||
'title': title,
|
||||
'content_html': content_html,
|
||||
'excerpt': excerpt,
|
||||
'status': destination_config.get('status', 'publish'),
|
||||
}
|
||||
|
||||
# Add optional fields from content model
|
||||
if hasattr(content, 'meta_title'):
|
||||
content_data['seo_title'] = content.meta_title or ''
|
||||
if hasattr(content, 'meta_description'):
|
||||
content_data['seo_description'] = content.meta_description or ''
|
||||
if hasattr(content, 'primary_keyword'):
|
||||
content_data['primary_keyword'] = content.primary_keyword or ''
|
||||
if hasattr(content, 'secondary_keywords'):
|
||||
content_data['secondary_keywords'] = content.secondary_keywords or []
|
||||
if hasattr(content, 'cluster') and content.cluster:
|
||||
content_data['cluster_id'] = content.cluster.id
|
||||
if hasattr(content, 'sector') and content.sector:
|
||||
content_data['sector_id'] = content.sector.id
|
||||
|
||||
# Call WordPress endpoint
|
||||
url = f"{site_url.rstrip('/')}/wp-json/igny8/v1/publish-content/"
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-IGNY8-API-KEY': api_key,
|
||||
}
|
||||
|
||||
response = requests.post(url, json=content_data, headers=headers, timeout=30)
|
||||
|
||||
if response.status_code == 201:
|
||||
wp_data = response.json().get('data', {})
|
||||
return {
|
||||
'success': True,
|
||||
'external_id': str(wp_data.get('post_id')),
|
||||
'url': wp_data.get('post_url'),
|
||||
'published_at': datetime.now(),
|
||||
'metadata': {
|
||||
'post_id': wp_data.get('post_id'),
|
||||
'status': destination_config.get('status', 'publish')
|
||||
}
|
||||
}
|
||||
else:
|
||||
error_msg = f"HTTP {response.status_code}: {response.text}"
|
||||
return {
|
||||
'success': False,
|
||||
'external_id': None,
|
||||
'url': None,
|
||||
'published_at': None,
|
||||
'metadata': {'error': error_msg}
|
||||
}
|
||||
|
||||
def _publish_via_username_password(
|
||||
self,
|
||||
site_url: str,
|
||||
username: str,
|
||||
app_password: str,
|
||||
title: str,
|
||||
content_html: str,
|
||||
destination_config: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Publish via standard WordPress REST API using username/password.
|
||||
"""
|
||||
if not username or not app_password:
|
||||
raise ValueError("username and app_password are required when not using API key")
|
||||
|
||||
# Get WordPress client
|
||||
client = WordPressClient(site_url, username, app_password)
|
||||
|
||||
# Get publishing options
|
||||
status = destination_config.get('status', 'draft')
|
||||
featured_image_url = destination_config.get('featured_image_url')
|
||||
|
||||
# Publish to WordPress
|
||||
result = client.create_post(
|
||||
title=title,
|
||||
content=content_html,
|
||||
status=status,
|
||||
featured_image_url=featured_image_url
|
||||
)
|
||||
|
||||
# Handle response
|
||||
if result.get('success') or result.get('post_id'):
|
||||
post_id = result.get('post_id') or result.get('id')
|
||||
url = result.get('url') or result.get('link')
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'external_id': str(post_id) if post_id else None,
|
||||
'url': url,
|
||||
'published_at': datetime.now(),
|
||||
'metadata': {
|
||||
'post_id': post_id,
|
||||
'status': status
|
||||
}
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'success': False,
|
||||
'external_id': None,
|
||||
'url': None,
|
||||
'published_at': None,
|
||||
'metadata': {
|
||||
'error': result.get('error', 'Unknown error')
|
||||
}
|
||||
}
|
||||
|
||||
def test_connection(
|
||||
self,
|
||||
config: Dict[str, Any]
|
||||
|
||||
@@ -138,8 +138,8 @@ class PublisherService:
|
||||
if not adapter:
|
||||
raise ValueError(f"No adapter found for destination: {destination}")
|
||||
|
||||
# Get destination config (for now, basic config - can be extended)
|
||||
destination_config = {'account': account}
|
||||
# Get destination config
|
||||
destination_config = {}
|
||||
|
||||
# If content has site, try to get integration config
|
||||
if hasattr(content, 'site') and content.site:
|
||||
@@ -151,8 +151,13 @@ class PublisherService:
|
||||
).first()
|
||||
|
||||
if integration:
|
||||
destination_config.update(integration.config_json)
|
||||
destination_config.update(integration.get_credentials())
|
||||
# Merge config_json and credentials_json
|
||||
destination_config.update(integration.config_json or {})
|
||||
destination_config.update(integration.get_credentials() or {})
|
||||
|
||||
# Ensure site_url is set (from config or from site model)
|
||||
if not destination_config.get('site_url'):
|
||||
destination_config['site_url'] = content.site.url
|
||||
|
||||
# Publish via adapter
|
||||
result = adapter.publish(content, destination_config)
|
||||
|
||||
Reference in New Issue
Block a user