This commit is contained in:
Flatlogic Bot 2025-11-18 07:45:21 +00:00
parent e2ba34438a
commit 64a48cfac7
14 changed files with 181 additions and 25 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
YOUTUBE_API_KEY=AIzaSyBodFSevdvTVDkpxbrCR9M8r42ALVTax1E

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

View File

@ -15,9 +15,10 @@ import os
from dotenv import load_dotenv
BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(BASE_DIR.parent / ".env")
load_dotenv(BASE_DIR / ".env")
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "change-me")
YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY", "")
DEBUG = os.getenv("DJANGO_DEBUG", "true").lower() == "true"
ALLOWED_HOSTS = [

View File

@ -20,6 +20,6 @@
<div class="container">
{% block content %}{% endblock %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" defer></script>
</body>
</html>

View File

@ -1,25 +1,28 @@
{% extends "base.html" %}
{% block title %}Testimonials{% endblock %}
{% block content %}
<div class="container">
<h1>Testimonials</h1>
<div id="testimonial-container">
<div class="testimonial show">
<p>"This is the best SEO tool I've ever used! It's helped me rank my videos higher and get more views."</p>
<p class="author">- John Doe</p>
</div>
<div class="testimonial">
<p>"I was struggling to grow my YouTube channel, but this tag generator has been a game-changer. I'm finally getting the traffic I deserve."</p>
<p class="author">- Jane Smith</p>
</div>
<div class="testimonial">
<p>"I love how easy it is to use this tool. It's saved me so much time and effort."</p>
<p class="author">- David Johnson</p>
</div>
<div class="testimonial">
<p>"I was skeptical at first, but this tool really works. I've seen a significant increase in my video's performance since I started using it."</p>
<p class="author">- Sarah Williams</p>
<div class="container d-flex justify-content-center align-items-center vh-100">
<div class="card text-center" style="width: 40rem;">
<div class="card-body">
<h1 class="card-title">Testimonials</h1>
<div id="testimonial-container">
<div class="testimonial show">
<p>"This is the best SEO tool I've ever used! It's helped me rank my videos higher and get more views."</p>
<p class="author">- John Doe</p>
</div>
<div class="testimonial">
<p>"I was struggling to grow my YouTube channel, but this tag generator has been a game-changer. I'm finally getting the traffic I deserve."</p>
<p class="author">- Jane Smith</p>
</div>
<div class="testimonial">
<p>"I love how easy it is to use this tool. It's saved me so much time and effort."</p>
<p class="author">- David Johnson</p>
</div>
<div class="testimonial">
<p>"I was skeptical at first, but this tool really works. I've seen a significant increase in my video's performance since I started using it."</p>
<p class="author">- Sarah Williams</p>
</div>
</div>
</div>
</div>
</div>

View File

@ -3,5 +3,44 @@
{% block content %}
<div class="container">
<h1>Website SEO</h1>
<p>Enter a URL to analyze its title, meta description, and keywords.</p>
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="url" class="form-label">Website URL</label>
<input type="url" class="form-control" id="url" name="url" placeholder="https://example.com" required>
</div>
<button type="submit" class="btn btn-primary">Analyze</button>
</form>
{% if error %}
<div class="alert alert-danger mt-3" role="alert">
{{ error }}
</div>
{% endif %}
{% if title %}
<div class="mt-4">
<h2>Analysis for {{ url }}</h2>
<div class="card">
<div class="card-body">
<h5 class="card-title">Title</h5>
<p class="card-text">{{ title }}</p>
</div>
</div>
<div class="card mt-3">
<div class="card-body">
<h5 class="card-title">Meta Description</h5>
<p class="card-text">{{ description }}</p>
</div>
</div>
<div class="card mt-3">
<div class="card-body">
<h5 class="card-title">Meta Keywords</h5>
<p class="card-text">{{ keywords }}</p>
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}
{% endblock %}

View File

@ -3,5 +3,33 @@
{% block content %}
<div class="container">
<h1>YouTube SEO</h1>
<form method="get" action=".">
<input type="text" name="q" placeholder="Search YouTube" value="{{ request.GET.q }}">
<button type="submit">Search</button>
</form>
<div class="row">
{% for video in videos %}
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img src="{{ video.snippet.thumbnails.medium.url }}" class="card-img-top" alt="{{ video.snippet.title }}">
<div class="card-body">
<h5 class="card-title">{{ video.snippet.title }}</h5>
<p class="card-text">{{ video.snippet.description }}</p>
{% if video.details.snippet.tags %}
<h6>Tags:</h6>
<p>
{% for tag in video.details.snippet.tags %}
<span class="badge bg-secondary">{{ tag }}</span>
{% endfor %}
</p>
{% endif %}
<a href="https://www.youtube.com/watch?v={{ video.id.videoId }}" target="_blank" class="btn btn-primary">Watch</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -1,7 +1,11 @@
from django.urls import path
from .views import home
from .views import home, faq, testimonials, website_seo, youtube_seo
urlpatterns = [
path("", home, name="home"),
path("faq/", faq, name="faq"),
path("testimonials/", testimonials, name="testimonials"),
path("website-seo/", website_seo, name="website_seo"),
path("youtube-seo/", youtube_seo, name="youtube_seo"),
]

View File

@ -2,6 +2,10 @@ 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__)
@ -41,7 +45,7 @@ def home(request):
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": "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"}},
@ -64,3 +68,76 @@ def home(request):
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})

View File

@ -1,3 +1,6 @@
Django==5.2.7
mysqlclient==2.2.7
python-dotenv==1.1.1
google-api-python-client==2.110.0
requests==2.31.0
beautifulsoup4==4.12.3