Skip to content

Commit

Permalink
Added dynamic category and tags using AI
Browse files Browse the repository at this point in the history
  • Loading branch information
Sawan-Kushwah committed Nov 9, 2024
1 parent c1546da commit 3cfbae5
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 57 deletions.
14 changes: 11 additions & 3 deletions backend/generateFromAi.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ def generate_content():
return jsonify({"error": "Title and summary are required"}), 400

# Define a prompt using the title and summary to generate content
prompt = (f"Write a detailed and informative blog post on the topic: '{title}'. "
f"Use the following summary as a reference: '{summary}'. "
"Make it engaging and informative, and elaborate based on the provided summary in 200 words.")
prompt = (
f"Write a detailed and informative blog post on the topic: '{title}'. "
f"Use the following summary as a reference: '{summary}'. "
"Make it engaging and informative, and elaborate based on the provided summary in 200 words."
"Generate the output in the following format: "
"<Content of the blog post here(in single paragraph of about 150 words)>"
"<5 category in single line each category should be comma seperated>"
"<3 tags in single line each tags should be comma seperated>"
)



# Call the generative model with the title and summary prompt
model = palm.GenerativeModel('gemini-pro')
Expand Down
1 change: 0 additions & 1 deletion backend/models/addBlog.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const blogPostSchema = new mongoose.Schema({
category: {
type: String,
required: true,
enum: ['vocabulary', 'grammar', 'pronunciation', 'culture', 'learning-tips'] // Add more categories as needed
},
summary: {
type: String,
Expand Down
108 changes: 67 additions & 41 deletions frontend/src/pages/AddBlog.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,6 @@ export function renderAddBlog(container) {
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white">
</div>
<div class="mb-6">
<label for="category" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Category</label>
<select id="category" name="category" required
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white">
<option value="">Select a category</option>
<option value="vocabulary">Vocabulary</option>
<option value="grammar">Grammar</option>
<option value="pronunciation">Pronunciation</option>
<option value="culture">Culture</option>
<option value="learning-tips">Learning Tips</option>
</select>
</div>
<div class="mb-6">
<label for="featured-image" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Featured Image</label>
<input type="file" id="featured-image" name="featured-image" accept="image/*"
Expand All @@ -41,23 +28,30 @@ export function renderAddBlog(container) {
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"></textarea>
</div>
<div class="mb-6 relative">
<label for="excerpt" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Content</label>
<div class="relative">
<!-- Button for generating content -->
<button id="generateContent" class="absolute top-2 right-2 text-2xl text-gray-500 dark:text-gray-300 hover:text-indigo-500 cursor-pointer" title="Generate AI Content">
<span class="tooltip absolute right-[95%] mr-2 hidden text-sm bg-gray-800 text-white p-1 rounded-md">
Generate AI Content
</span>
</button>
<!-- Textarea for content -->
<textarea id="excerpt" name="excerpt" rows="10" required
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"></textarea>
<div class="mb-6 relative">
<label for="excerpt" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Content</label>
<div class="relative">
<!-- Button for generating content -->
<button id="generateContent" class="absolute top-2 right-2 text-2xl text-gray-500 dark:text-gray-300 hover:text-indigo-500 cursor-pointer" title="Generate AI Content">
<span class="tooltip absolute right-[95%] mr-2 hidden text-sm bg-gray-800 text-white p-1 rounded-md">
Generate AI Content
</span>
</button>
<!-- Textarea for content -->
<textarea id="excerpt" name="excerpt" rows="10" required
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"></textarea>
</div>
</div>
</div>
<div class="mb-6">
<label for="category" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Category</label>
<select id="category" name="category" required
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white">
<!-- Categories will be populated here dynamically -->
</select>
</div>
<div class="mb-6">
<label for="tags" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Tags (comma-separated)</label>
Expand All @@ -82,7 +76,6 @@ export function renderAddBlog(container) {
</div>
`;


const generateContent = document.getElementById('generateContent');

generateContent.addEventListener('click', async function (e) {
Expand All @@ -92,7 +85,7 @@ export function renderAddBlog(container) {

// Check if the title is empty
if (title === '' && summary === '') {
toastr.error('Enter title and summary for more relavant content');
toastr.error('Enter title and summary for more relevant content');
return;
}

Expand All @@ -116,37 +109,70 @@ export function renderAddBlog(container) {
body: JSON.stringify({ title: title, summary: summary })
});


// Clear the loading message after the response
toastr.clear(loadingToastr);

// Check if the response is successful
if (response.ok) {
let data = await response.json();

const lines = data.content.split("\n").map(line => line.trim());

// Extract content, category, and tags
let servercontent = "";
let servercategory = "";
let servertags = "";

lines.forEach(line => {
if (line.startsWith("**Category:**") || line.startsWith("**Categories:**")) {
servercategory = line.replace("**Category:**", "").replace("**Categories:**", "").replace("**Categories**:", "").trim();
} else if (line.startsWith("**Tags:**")) {
servertags = line.replace("**Tags:**", "").replace("**Tags**:", "").trim();
} else if (line) {
servercontent += line + " "; // Append to content
}
});

// Display generated content in the textarea
excerpt.value = data.content;
excerpt.value = servercontent;

// // Show success message

const categories = servercategory.split(",").map(category => category.trim());

const selectElement = document.getElementById("category");
selectElement.innerHTML = '';

const defaultOption = document.createElement("option");
defaultOption.value = "";
defaultOption.textContent = "Select Category";
defaultOption.disabled = true;
defaultOption.selected = true;
selectElement.appendChild(defaultOption);
categories.forEach(category => {
const option = document.createElement("option");
option.value = category;
option.textContent = category;
selectElement.appendChild(option);
});

// // Update the tags field with comma-separated tags
const tagsInput = document.getElementById('tags');
tagsInput.value = servertags

// Show success message
toastr.success('Content generated successfully!');

} else {
toastr.error('Failed to generate content. Please try again.');
}
} catch (error) {
console.error('Error:', error);
toastr.error('An error occurred. Please check the console for details.');
} finally {
// Clear the loading message in case of any error or completion
toastr.clear(loadingToastr);
}

});







const form = document.getElementById('add-blog-form');
form.addEventListener('submit', async function (e) {
e.preventDefault();
Expand Down
16 changes: 4 additions & 12 deletions frontend/src/styles/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,10 @@ video {
gap: 1rem;
}

.gap-5 {
gap: 1.25rem;
}

.gap-6 {
gap: 1.5rem;
}
Expand All @@ -903,18 +907,6 @@ video {
gap: 2rem;
}

.gap-9 {
gap: 2.25rem;
}

.gap-3 {
gap: 0.75rem;
}

.gap-5 {
gap: 1.25rem;
}

.space-x-3 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.75rem * var(--tw-space-x-reverse));
Expand Down

0 comments on commit 3cfbae5

Please sign in to comment.