SEction 2 part 2
This commit is contained in:
@@ -1044,6 +1044,127 @@ class ContentViewSet(SiteSectorModelViewSet):
|
||||
request=request
|
||||
)
|
||||
|
||||
@action(detail=True, methods=['post'], url_path='schedule', url_name='schedule', permission_classes=[IsAuthenticatedAndActive, IsEditorOrAbove])
|
||||
def schedule(self, request, pk=None):
|
||||
"""
|
||||
Schedule content for publishing at a specific date/time.
|
||||
Sets site_status to 'scheduled' and scheduled_publish_at to the provided datetime.
|
||||
|
||||
POST /api/v1/writer/content/{id}/schedule/
|
||||
{
|
||||
"scheduled_publish_at": "2026-01-15T09:00:00Z" // Required: ISO 8601 datetime
|
||||
}
|
||||
"""
|
||||
from django.utils import timezone
|
||||
from django.utils.dateparse import parse_datetime
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
content = self.get_object()
|
||||
|
||||
# Validate content status - must be approved to schedule
|
||||
if content.status != 'approved':
|
||||
return error_response(
|
||||
error=f'Only approved content can be scheduled. Current status: {content.status}',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Check if already published
|
||||
if content.site_status == 'published':
|
||||
return error_response(
|
||||
error='Content is already published',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Get scheduled_publish_at from request
|
||||
scheduled_at_str = request.data.get('scheduled_publish_at')
|
||||
if not scheduled_at_str:
|
||||
return error_response(
|
||||
error='scheduled_publish_at is required',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Parse datetime
|
||||
scheduled_at = parse_datetime(scheduled_at_str)
|
||||
if not scheduled_at:
|
||||
return error_response(
|
||||
error='Invalid datetime format. Use ISO 8601 format (e.g., 2026-01-15T09:00:00Z)',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Ensure datetime is in the future
|
||||
if scheduled_at <= timezone.now():
|
||||
return error_response(
|
||||
error='Scheduled time must be in the future',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Update content
|
||||
content.site_status = 'scheduled'
|
||||
content.scheduled_publish_at = scheduled_at
|
||||
content.site_status_updated_at = timezone.now()
|
||||
content.save(update_fields=['site_status', 'scheduled_publish_at', 'site_status_updated_at', 'updated_at'])
|
||||
|
||||
logger.info(f"[ContentViewSet.schedule] Content {content.id} scheduled for {scheduled_at}")
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
'content_id': content.id,
|
||||
'site_status': content.site_status,
|
||||
'scheduled_publish_at': content.scheduled_publish_at.isoformat(),
|
||||
},
|
||||
message=f'Content scheduled for {scheduled_at.strftime("%Y-%m-%d %H:%M")}',
|
||||
request=request
|
||||
)
|
||||
|
||||
@action(detail=True, methods=['post'], url_path='unschedule', url_name='unschedule', permission_classes=[IsAuthenticatedAndActive, IsEditorOrAbove])
|
||||
def unschedule(self, request, pk=None):
|
||||
"""
|
||||
Remove content from publishing schedule.
|
||||
Clears site_status and scheduled_publish_at.
|
||||
|
||||
POST /api/v1/writer/content/{id}/unschedule/
|
||||
"""
|
||||
from django.utils import timezone
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
content = self.get_object()
|
||||
|
||||
# Check if content is scheduled
|
||||
if content.site_status not in ['scheduled', 'publishing']:
|
||||
return error_response(
|
||||
error=f'Content is not scheduled. Current site_status: {content.site_status}',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Store old values
|
||||
old_scheduled_at = content.scheduled_publish_at
|
||||
|
||||
# Clear scheduling
|
||||
content.site_status = 'not_published'
|
||||
content.scheduled_publish_at = None
|
||||
content.site_status_updated_at = timezone.now()
|
||||
content.save(update_fields=['site_status', 'scheduled_publish_at', 'site_status_updated_at', 'updated_at'])
|
||||
|
||||
logger.info(f"[ContentViewSet.unschedule] Content {content.id} removed from schedule (was {old_scheduled_at})")
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
'content_id': content.id,
|
||||
'site_status': content.site_status,
|
||||
'was_scheduled_for': old_scheduled_at.isoformat() if old_scheduled_at else None,
|
||||
},
|
||||
message='Content removed from publishing schedule',
|
||||
request=request
|
||||
)
|
||||
|
||||
@action(detail=False, methods=['post'], url_path='generate_image_prompts', url_name='generate_image_prompts')
|
||||
def generate_image_prompts(self, request):
|
||||
"""Generate image prompts for content records - same pattern as other AI functions"""
|
||||
|
||||
Reference in New Issue
Block a user