144 lines
6.3 KiB
Python
144 lines
6.3 KiB
Python
from django.http import JsonResponse
|
|
from django.shortcuts import render
|
|
from ai.local_ai_api import LocalAIApi
|
|
import logging
|
|
from django.conf import settings
|
|
from googleapiclient.discovery import build
|
|
import requests
|
|
from bs4 import BeautifulSoup
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def home(request):
|
|
"""
|
|
Render the landing page and handle the content generation form.
|
|
"""
|
|
if request.method == 'POST':
|
|
topic = request.POST.get('topic', '').strip()
|
|
form_type = request.POST.get('form_type', 'website')
|
|
|
|
if not topic:
|
|
return JsonResponse({'error': 'Please enter a topic.'}, status=400)
|
|
|
|
try:
|
|
if form_type == 'website':
|
|
prompt = {
|
|
"input": [
|
|
{"role": "system", "content": "You are an expert SEO content strategist. Generate a compelling blog post title and a list of relevant SEO keywords for a given topic. Return the result as a JSON object with two keys: 'title' and 'keywords'. The 'keywords' should be a list of strings."},
|
|
{"role": "user", "content": f"The topic is: {topic}"},
|
|
],
|
|
"text": {"format": {"type": "json_object"}},
|
|
}
|
|
response = LocalAIApi.create_response(prompt)
|
|
|
|
if response.get("success"):
|
|
payload = LocalAIApi.decode_json_from_response(response)
|
|
if payload:
|
|
payload['topic'] = topic
|
|
return JsonResponse(payload)
|
|
else:
|
|
return JsonResponse({'error': 'Failed to generate content. The AI response was not valid JSON.'}, status=500)
|
|
else:
|
|
logger.warning("AI error: %s", response.get("error"))
|
|
return JsonResponse({'error': 'Failed to generate content due to an AI error.'}, status=500)
|
|
|
|
elif form_type == 'youtube':
|
|
prompt = {
|
|
"input": [
|
|
{"role": "system", "content": "You are a YouTube content expert.. Generate a catchy title, a list of relevant keywords, and a list of hashtags for a given video topic. Return the result as a JSON object with three keys: 'title', 'keywords', and 'hashtags'. 'keywords' and 'hashtags' should be lists of strings."},
|
|
{"role": "user", "content": f"The topic is: {topic}"},
|
|
],
|
|
"text": {"format": {"type": "json_object"}},
|
|
}
|
|
response = LocalAIApi.create_response(prompt)
|
|
|
|
if response.get("success"):
|
|
payload = LocalAIApi.decode_json_from_response(response)
|
|
if payload:
|
|
payload['topic'] = topic
|
|
return JsonResponse(payload)
|
|
else:
|
|
return JsonResponse({'error': 'Failed to generate content. The AI response was not valid JSON.'}, status=500)
|
|
else:
|
|
logger.warning("AI error: %s", response.get("error"))
|
|
return JsonResponse({'error': 'Failed to generate content due to an AI error.'}, status=500)
|
|
|
|
except Exception as e:
|
|
logger.error("An unexpected error occurred: %s", e)
|
|
return JsonResponse({'error': 'An unexpected error occurred.'}, status=500)
|
|
|
|
return render(request, "core/index.html", {})
|
|
|
|
def faq(request):
|
|
return render(request, "core/faq.html")
|
|
|
|
def testimonials(request):
|
|
return render(request, "core/testimonials.html")
|
|
|
|
def website_seo(request):
|
|
if request.method == 'POST':
|
|
url = request.POST.get('url')
|
|
if not url:
|
|
return render(request, 'core/website_seo.html', {'error': 'Please provide a URL.'})
|
|
|
|
try:
|
|
response = requests.get(url)
|
|
response.raise_for_status()
|
|
soup = BeautifulSoup(response.content, 'html.parser')
|
|
|
|
title = soup.title.string if soup.title else 'No title found'
|
|
description = soup.find('meta', attrs={'name': 'description'})
|
|
keywords = soup.find('meta', attrs={'name': 'keywords'})
|
|
|
|
description_content = description['content'] if description else 'No description found'
|
|
keywords_content = keywords['content'] if keywords else 'No keywords found'
|
|
|
|
context = {
|
|
'title': title,
|
|
'description': description_content,
|
|
'keywords': keywords_content,
|
|
'url': url,
|
|
}
|
|
return render(request, 'core/website_seo.html', context)
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
return render(request, 'core/website_seo.html', {'error': f'Error fetching URL: {e}'})
|
|
|
|
return render(request, "core/website_seo.html")
|
|
|
|
def youtube_seo(request):
|
|
videos = []
|
|
if request.method == 'GET':
|
|
search_query = request.GET.get('q', '')
|
|
if search_query:
|
|
try:
|
|
youtube = build('youtube', 'v3', developerKey=settings.YOUTUBE_API_KEY)
|
|
search_response = youtube.search().list(
|
|
q=search_query,
|
|
part='snippet',
|
|
maxResults=25
|
|
).execute()
|
|
|
|
video_ids = [item['id']['videoId'] for item in search_response.get('items', []) if item['id']['kind'] == 'youtube#video']
|
|
|
|
if video_ids:
|
|
video_details_response = youtube.videos().list(
|
|
part='snippet,statistics',
|
|
id=','.join(video_ids)
|
|
).execute()
|
|
|
|
video_details = {item['id']: item for item in video_details_response.get('items', [])}
|
|
|
|
videos = []
|
|
for item in search_response.get('items', []):
|
|
if item['id']['kind'] == 'youtube#video':
|
|
video_id = item['id']['videoId']
|
|
if video_id in video_details:
|
|
item['details'] = video_details[video_id]
|
|
videos.append(item)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error fetching YouTube videos: {e}")
|
|
|
|
return render(request, "core/youtube_seo.html", {'videos': videos})
|