diff --git a/ai/__pycache__/__init__.cpython-311.pyc b/ai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..8bcb2fb Binary files /dev/null and b/ai/__pycache__/__init__.cpython-311.pyc differ diff --git a/ai/__pycache__/local_ai_api.cpython-311.pyc b/ai/__pycache__/local_ai_api.cpython-311.pyc new file mode 100644 index 0000000..93112e3 Binary files /dev/null and b/ai/__pycache__/local_ai_api.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 1e42323..89b7e7b 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 eb209e3..6794b64 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -7,11 +7,14 @@ - + {% load static %} {% block head %}{% endblock %} +
diff --git a/core/templates/core/index.html b/core/templates/core/index.html index 7d7a4ad..9ea9049 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,23 +1,143 @@ {% extends "base.html" %} {% load static %} -{% block title %}Viral YouTube Content Generator{% endblock %} +{% block title %}AI-Powered Content Generator{% endblock %} {% block head %} - - - + + + +{% endblock %} + +{% block structured_data %} +{ + "@context": "https://schema.org", + "@type": "FAQPage", + "mainEntity": [{ + "@type": "Question", + "name": "What is an SEO Content Generator?", + "acceptedAnswer": { + "@type": "Answer", + "text": "An SEO Content Generator is a tool that uses artificial intelligence to help you create search-engine-optimized content for your website or social media channels. By inputting a topic, you can generate relevant keywords, compelling titles, and other content to improve your search rankings and attract more traffic." + } + },{ + "@type": "Question", + "name": "How do I use the AI generator?", + "acceptedAnswer": { + "@type": "Answer", + "text": "Using the generator is simple. Just choose your desired content type (Website SEO or YouTube SEO), enter a topic or keyword into the input field, and click the 'Generate' button. The tool will then provide you with a list of suggestions that you can copy and use in your content." + } + },{ + "@type": "Question", + "name": "Can I use the generated keywords for free?", + "acceptedAnswer": { + "@type": "Answer", + "text": "Yes, all keywords, titles, and hashtags generated by our tool are completely free to use. There are no hidden fees or subscription costs." + } + }] +} {% endblock %} {% block content %}
-

Free YouTube Tag Generator & SEO Tool

-
-

Instantly generate thousands of relevant YouTube tags for your videos. Our free tool helps you boost your video's SEO and get more views.

-
- A person using a laptop with code on the screen, representing the YouTube tag generation process. -
+

AI-Powered Content Generator

+
+

Choose your content type and enter a topic to generate titles, keywords, and more.

+ + + +
+
+
+ {% csrf_token %} + +
+ + +
+
+ + {% if results %} +
+

Your Results for "{{ topic }}"

+
+
+
+

Suggested Title

+
+

{{ results.title }}

+ +
+
+
+
+
+

SEO Keywords

+
+

{{ results.keywords|join:", " }}

+ +
+
+
+
+
+ {% endif %} +
+ +
+
+ {% csrf_token %} + +
+ + +
+
+ + {% if youtube_results %} +
+

Your YouTube Results for "{{ topic }}"

+
+
+
+

Suggested Title

+
+

{{ youtube_results.title }}

+ +
+
+
+
+
+

Keywords

+
+

{{ youtube_results.keywords|join:", " }}

+ +
+
+
+
+
+

Hashtags

+
+

{{ youtube_results.hashtags|join:" " }}

+ +
+
+
+
+
+ {% endif %} +
+
{% if error %} @@ -26,33 +146,113 @@
-{% if results %} -
-

Your Results for "{{ topic }}"

+ +
-
-
-

Suggested Viral Title (H1)

-

{{ results.title }}

+
+

What Our Users Say

+
+
+
+
+
+

"This tool is a game-changer! I was able to generate a month's worth of content ideas in just a few minutes. Highly recommended!"

+

- Sarah J.

-
-
-

Suggested Hashtags

-
- {% for tag in results.hashtags %} - {{ tag }} - {% endfor %} -
+
+
+

"I love how easy it is to use. The interface is clean and intuitive, and the results are always top-notch."

+

- Mark T.

-
-
-

Suggested Tags

-

{{ results.tags|join:", " }}

+
+
+

"The best SEO tool I've ever used. It's saved me hours of research and helped me rank my videos higher than ever before."

+

- Emily R.

-{% endif %} -{% endblock %} + + +
+
+
+

Frequently Asked Questions

+
+
+
+
+
+
+

+ +

+
+
+ An SEO Content Generator is a tool that uses artificial intelligence to help you create search-engine-optimized content for your website or social media channels. By inputting a topic, you can generate relevant keywords, compelling titles, and other content to improve your search rankings and attract more traffic. +
+
+
+
+

+ +

+
+
+ Using the generator is simple. Just choose your desired content type (Website SEO or YouTube SEO), enter a topic or keyword into the input field, and click the 'Generate' button. The tool will then provide you with a list of suggestions that you can copy and use in your content. +
+
+
+
+

+ +

+
+
+ Yes, all keywords, titles, and hashtags generated by our tool are completely free to use. There are no hidden fees or subscription costs. +
+
+
+
+
+
+
+ + +
+
+
+
+

About the Developer

+

This website was created by a passionate developer dedicated to building helpful and easy-to-use tools for content creators. With a background in web development and a passion for SEO, the goal is to empower creators with the resources they need to succeed.

+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/core/views.py b/core/views.py index af8c5da..fb4b5b0 100644 --- a/core/views.py +++ b/core/views.py @@ -1,4 +1,8 @@ from django.shortcuts import render +from ai.local_ai_api import LocalAIApi +import logging + +logger = logging.getLogger(__name__) def home(request): """ @@ -7,18 +11,57 @@ def home(request): context = {} if request.method == 'POST': topic = request.POST.get('topic', '').strip() + form_type = request.POST.get('form_type', 'website') # Default to website + context['topic'] = topic + context['form_type'] = form_type if not topic: - context['error'] = 'Please enter a video topic.' + context['error'] = 'Please enter a topic.' else: - # Mock data for demonstration purposes - context['results'] = { - 'title': f'🚀 The Ultimate Guide to {topic.title()} in 2025 | SEO Secrets', - 'hashtags': ['#' + ''.join(word.capitalize() for word in topic.split()), '#YouTube', '#SEO', '#Viral', '#ContentCreation'], - 'tags': [topic, f'{topic} tutorial`, `learn {topic}', 'how to', '2025', 'SEO tips', 'viral video'] - } - context['meta_description'] = f'Get the best viral tags, hashtags, and titles for your video about {topic}. Boost your views with our AI-powered suggestions.' - context['slug'] = f'viral-guide-{topic.lower().replace(" ", "-")}' + 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: + context['results'] = payload + else: + context['error'] = 'Failed to generate content. The AI response was not valid JSON.' + else: + logger.warning("AI error: %s", response.get("error")) + context['error'] = 'Failed to generate content due to an AI error.' + + 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: + context['youtube_results'] = payload + else: + context['error'] = 'Failed to generate content. The AI response was not valid JSON.' + else: + logger.warning("AI error: %s", response.get("error")) + context['error'] = 'Failed to generate content due to an AI error.' + + except Exception as e: + logger.error("An unexpected error occurred: %s", e) + context['error'] = 'An unexpected error occurred.' return render(request, "core/index.html", context) diff --git a/static/css/custom.css b/static/css/custom.css index 2a01c49..9220be7 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -1,54 +1,53 @@ /* General Body Styles */ body { - background-color: #0F3460; /* Dark Blue */ - color: #FFFFFF; - font-family: 'Roboto', sans-serif; + background-color: #000000; /* Black */ + color: #FFFFFF; /* White */ + font-family: 'Playfair Display', serif; } -/* Hero Section */ -.hero { +/* Remove background image overlay */ +body::before { + display: none; +} + +/* Make sure content is on top of the overlay */ +.hero-section, .results-section { position: relative; - padding: 100px 0; - text-align: center; - background-image: url('../pasted-20251118-024426-e59dd4cc.jpg'); - background-size: cover; - background-position: center; - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; -} - -.hero::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(15, 52, 96, 0.6); /* Dark Blue overlay, slightly more transparent */ z-index: 1; } -.hero .container { - position: relative; - z-index: 2; + +/* Hero Section */ +.hero-section { + padding: 6rem 0; + text-align: center; + background-color: transparent; } +.hero-content { + background-color: rgba(255, 255, 255, 0.05); /* Subtle glass effect */ + padding: 2rem; + border-radius: 15px; + display: inline-block; +} + + /* Typography */ -h1, .h1 { - font-family: 'Poppins', sans-serif; +h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 { + font-family: 'Playfair Display', serif; font-weight: 700; color: #FFFFFF; - font-size: 3.8rem; /* Slightly larger */ - margin-bottom: 1rem; - text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.7); /* Stylish shadow */ } -p.lead { - color: rgba(255, 255, 255, 0.9); /* Brighter lead text */ - margin-bottom: 2rem; - text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6); /* Subtle shadow */ +h1, .h1 { + font-size: 3.8rem; + margin-bottom: 1rem; + text-shadow: none; +} + +p, .lead { + color: rgba(255, 255, 255, 0.9); + text-shadow: none; } /* Form Styles */ @@ -65,42 +64,41 @@ p.lead { .form-control:focus { background-color: rgba(255, 255, 255, 0.2); - border-color: #E94560; /* Accent Pink/Red */ + border-color: #FFFFFF; color: #FFFFFF; - box-shadow: 0 0 0 0.25rem rgba(233, 69, 96, 0.25); + box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.25); } /* Button Styles */ .btn-primary { - background-color: #E94560; /* Accent Pink/Red */ - border-color: #E94560; + background-color: #FFFFFF; + border-color: #FFFFFF; + color: #000000; padding: 1rem 2rem; font-weight: 700; transition: background-color 0.3s ease, border-color 0.3s ease; } .btn-primary:hover { - background-color: #c73049; - border-color: #c73049; + background-color: #CCCCCC; + border-color: #CCCCCC; } /* Results Section */ .results-section { - background-color: #1A1A2E; /* Deep Navy */ - padding: 4rem; + background-color: rgba(255, 255, 255, 0.05); /* Subtle glass effect */ + padding: 2rem; border-radius: 15px; - margin-top: 3rem; + margin-top: 2rem; border: 1px solid rgba(255, 255, 255, 0.1); } .results-section h2 { - font-family: 'Poppins', sans-serif; - color: #E94560; /* Accent Pink/Red */ + color: #FFFFFF; margin-bottom: 1.5rem; } .results-section h3 { - font-family: 'Poppins', sans-serif; font-size: 1.5rem; color: #FFFFFF; margin-top: 1.5rem; @@ -110,9 +108,7 @@ p.lead { .generated-title { font-size: 1.75rem; font-weight: bold; - background: -webkit-linear-gradient(45deg, #E94560, #FFC700); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; + color: #FFFFFF; } .hashtag { @@ -125,3 +121,121 @@ p.lead { margin-bottom: 0.5rem; font-size: 0.9rem; } + + +/* Custom CSS for the new SEO generator */ +.result-item { + margin-bottom: 2rem; +} + +.result-item h3 { + color: #FFFFFF; +} + +.result-item .form-control { + background-color: #333333; + border-color: #555555; + color: #FFFFFF; + min-height: 50px; +} + +.result-item .btn-outline-secondary { + color: #FFFFFF; + border-color: #FFFFFF; +} + +.result-item .btn-outline-secondary:hover { + background-color: #FFFFFF; + color: #000000; +} + +/* Tab Styles */ +.nav-tabs { + border-bottom: 1px solid #FFFFFF; +} + +.nav-tabs .nav-link { + background-color: transparent; + border: none; + color: rgba(255, 255, 255, 0.7); +} + +.nav-tabs .nav-link.active { + color: #000000; + background-color: #FFFFFF; + border-color: #FFFFFF; +} + +.tab-content { + padding-top: 1rem; +} + +/* Section Title */ +.section-title { + font-family: 'Playfair Display', serif; + font-weight: 700; + color: #FFFFFF; + font-size: 2.5rem; + margin-bottom: 2rem; + text-shadow: none; +} + +/* Review Section */ +.review-card { + background-color: rgba(255, 255, 255, 0.05); + padding: 2rem; + border-radius: 15px; + border: 1px solid rgba(255, 255, 255, 0.1); + height: 100%; +} + +.review-text { + font-style: italic; + color: rgba(255, 255, 255, 0.9); +} + +.review-author { + font-weight: 700; + color: #FFFFFF; + text-align: right; +} + +/* FAQ Section */ +.accordion-item { + background-color: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + margin-bottom: 1rem; + border-radius: 15px !important; +} + +.accordion-button { + background-color: transparent; + color: #FFFFFF; + font-family: 'Playfair Display', serif; + font-weight: 700; + border: none; + box-shadow: none; +} + +.accordion-button:not(.collapsed) { + color: #FFFFFF; + background-color: transparent; +} + +.accordion-body { + color: rgba(255, 255, 255, 0.9); +} + +/* About Section */ +.about-card { + background-color: rgba(255, 255, 255, 0.05); + padding: 2rem; + border-radius: 15px; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.about-text { + color: rgba(255, 255, 255, 0.9); + font-size: 1.1rem; + line-height: 1.8; +}