diff --git a/.env b/.env new file mode 100644 index 0000000..817f4ab --- /dev/null +++ b/.env @@ -0,0 +1 @@ +YOUTUBE_API_KEY=AIzaSyBodFSevdvTVDkpxbrCR9M8r42ALVTax1E \ No newline at end of file diff --git a/assets/pasted-20251118-044256-eeb6184a.jpg b/assets/pasted-20251118-044256-eeb6184a.jpg new file mode 100644 index 0000000..5b9f7c9 Binary files /dev/null and b/assets/pasted-20251118-044256-eeb6184a.jpg differ diff --git a/assets/pasted-20251118-044502-e7a78f8a.jpg b/assets/pasted-20251118-044502-e7a78f8a.jpg new file mode 100644 index 0000000..5b9f7c9 Binary files /dev/null and b/assets/pasted-20251118-044502-e7a78f8a.jpg differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 7e03fe1..3f87c77 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index 261a5dc..8c6b714 100644 --- a/config/settings.py +++ b/config/settings.py @@ -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 = [ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 71451a1..d587b41 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index c170026..c056baf 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/templates/base.html b/core/templates/base.html index 6794b64..aaa66aa 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -20,6 +20,6 @@
{% block content %}{% endblock %}
- + \ No newline at end of file diff --git a/core/templates/core/testimonials.html b/core/templates/core/testimonials.html index 3793ecc..3e06bdd 100644 --- a/core/templates/core/testimonials.html +++ b/core/templates/core/testimonials.html @@ -1,25 +1,28 @@ {% extends "base.html" %} {% block title %}Testimonials{% endblock %} {% block content %} -
-

Testimonials

- -
-
-

"This is the best SEO tool I've ever used! It's helped me rank my videos higher and get more views."

-

- John Doe

-
-
-

"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."

-

- Jane Smith

-
-
-

"I love how easy it is to use this tool. It's saved me so much time and effort."

-

- David Johnson

-
-
-

"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."

-

- Sarah Williams

+
+
+
+

Testimonials

+
+
+

"This is the best SEO tool I've ever used! It's helped me rank my videos higher and get more views."

+

- John Doe

+
+
+

"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."

+

- Jane Smith

+
+
+

"I love how easy it is to use this tool. It's saved me so much time and effort."

+

- David Johnson

+
+
+

"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."

+

- Sarah Williams

+
+
diff --git a/core/templates/core/website_seo.html b/core/templates/core/website_seo.html index feb7c3f..de2ac1e 100644 --- a/core/templates/core/website_seo.html +++ b/core/templates/core/website_seo.html @@ -3,5 +3,44 @@ {% block content %}

Website SEO

+

Enter a URL to analyze its title, meta description, and keywords.

+
+ {% csrf_token %} +
+ + +
+ +
+ + {% if error %} + + {% endif %} + + {% if title %} +
+

Analysis for {{ url }}

+
+
+
Title
+

{{ title }}

+
+
+
+
+
Meta Description
+

{{ description }}

+
+
+
+
+
Meta Keywords
+

{{ keywords }}

+
+
+
+ {% endif %}
-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/core/templates/core/youtube_seo.html b/core/templates/core/youtube_seo.html index 1d0ecf5..58a393c 100644 --- a/core/templates/core/youtube_seo.html +++ b/core/templates/core/youtube_seo.html @@ -3,5 +3,33 @@ {% block content %}

YouTube SEO

+ +
+ + +
+ +
+ {% for video in videos %} +
+
+ {{ video.snippet.title }} +
+
{{ video.snippet.title }}
+

{{ video.snippet.description }}

+ {% if video.details.snippet.tags %} +
Tags:
+

+ {% for tag in video.details.snippet.tags %} + {{ tag }} + {% endfor %} +

+ {% endif %} + Watch +
+
+
+ {% endfor %} +
-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/core/urls.py b/core/urls.py index 6299e3d..592239b 100644 --- a/core/urls.py +++ b/core/urls.py @@ -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"), ] diff --git a/core/views.py b/core/views.py index b642800..1e5b70f 100644 --- a/core/views.py +++ b/core/views.py @@ -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}) diff --git a/requirements.txt b/requirements.txt index e22994c..53d997b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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