-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
189 lines (162 loc) · 7.01 KB
/
app.js
File metadata and controls
189 lines (162 loc) · 7.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/**
* FixYourCode - AI-powered code analysis application
* This application helps developers improve their code by providing analysis,
* suggestions, and educational resources using Google's Gemini AI.
*/
import 'dotenv/config'; // Loads environment variables from .env file for API keys and configuration
import express from 'express'; // Web framework to handle routing and HTTP requests
import bodyParser from 'body-parser'; // Middleware to parse incoming request bodies
import axios from 'axios'; // HTTP client for making API requests to Gemini AI
import path from 'path'; // Utility for working with file and directory paths
import hljs from 'highlight.js'; // Library for code syntax highlighting and language detection
import { fileURLToPath } from 'url'; // Utility to convert file URL to path
// Get directory name in ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const PORT = process.env.PORT || 3000;
// Set up middleware for parsing requests and serving static files
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static('public'));
// Set EJS as view engine for rendering dynamic content
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
/**
* Helper function to detect programming language of code snippets
* Uses highlight.js for language detection based on code syntax
*/
function detectLanguage(code) {
try {
const result = hljs.highlightAuto(code);
return result.language || 'plaintext';
} catch (error) {
console.error('Error detecting language:', error);
return 'plaintext';
}
}
// ===== ROUTES =====
/**
* Home page route - renders the index page with code input form
* This is where users enter their code for analysis
*/
app.get('/', (req, res) => {
res.render('index', {
codeResult: null,
languages: [
'plaintext', 'javascript', 'python', 'java', 'cpp', 'csharp', 'php',
'ruby', 'go', 'swift', 'kotlin', 'rust', 'typescript'
]
});
});
/**
* About page route - displays information about the project and developer
*/
app.get('/about', (req, res) => {
res.render('about');
});
/**
* Code analysis route - processes the submitted code and returns AI analysis
* This is the core functionality of the application:
* 1. Takes user's code input
* 2. Sends it to Gemini AI API
* 3. Returns structured analysis with suggestions and improvements
*/
app.post('/analyze', async (req, res) => {
try {
// Extract code and language from form submission
const { code, language } = req.body;
// Validate that code was submitted
if (!code) {
return res.render('index', {
error: 'Please provide code to analyze',
languages: [
'plaintext', 'javascript', 'python', 'java', 'cpp', 'csharp', 'php',
'ruby', 'go', 'swift', 'kotlin', 'rust', 'typescript'
]
});
}
// Auto-detect programming language if not specified by user
const detectedLanguage = language || detectLanguage(code);
// Prepare the prompt for Gemini AI with detailed instructions
// This carefully crafted prompt ensures consistent and helpful responses
const data = {
contents: [{
parts: [{
text: `You are a code tutor. Analyze the following ${detectedLanguage} code and provide feedback in JSON format:
${code}
Respond with a JSON object with the following structure:
{
"language": "detected language name",
"isCorrect": true/false, // Set to true if the code is already well-structured and follows best practices
"fix": "improved version of the code with better practices and fixed issues (if needed, otherwise same as original)",
"suggestions": ["list of best practices and improvements", "or praise if code is already well-structured"],
"descriptions": ["line-by-line explanation of what the code is doing"],
"learn": [
{
"text": "Topic name or description",
"url": "URL to a learning resource like W3Schools, GeeksforGeeks, MDN, etc."
}
]
}
IMPORTANT: For the "fix" field, if you make changes to the code, please add comments explaining what you changed and why, but make sure to place these comments INSIDE the code string, not in the JSON structure itself.
Example of CORRECT way (comments inside the code string):
"fix": "function example() {\\n // Changed var to const for better scoping\\n const x = 5;\\n return x;\\n}"
Example of INCORRECT way (comments in JSON structure):
"fix": function example() { // Changed var to const for better scoping
const x = 5;
return x;
}
For the "learn" field, include at least 3-5 learning resources with URLs to sites like W3Schools, GeeksforGeeks, MDN Web Docs, or other reputable programming tutorial sites related to the code's language and concepts.
If the code is already well-structured and follows best practices, set "isCorrect" to true, keep "fix" the same as the original code, and provide positive feedback in "suggestions".
IMPORTANT: Return ONLY the JSON object without any markdown formatting, explanation, or code blocks. Do not wrap the JSON in \`\`\` or any other formatting.`
}]
}],
generationConfig: {
temperature: 0.2,
maxOutputTokens: 8192
}
};
// Call the Gemini AI API with our prepared prompt
const API_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${process.env.GEMINI_API_KEY}`;
const response = await axios.post(API_URL, data);
// Extract the AI response text
const responseText = response.data.candidates[0].content.parts[0].text;
// Clean up the response if it contains markdown formatting
let jsonText = responseText;
if (jsonText.includes('```')) {
const jsonRegex = /```(?:json)?\s*([\s\S]*?)```/;
const match = jsonText.match(jsonRegex);
if (match && match[1]) {
jsonText = match[1].trim();
}
}
// Parse the JSON response from Gemini AI
const result = JSON.parse(jsonText);
// Render the results page with the AI analysis
res.render('index', {
codeResult: result,
originalCode: code,
languages: [
'plaintext', 'javascript', 'python', 'java', 'cpp', 'csharp', 'php',
'ruby', 'go', 'swift', 'kotlin', 'rust', 'typescript'
],
selectedLanguage: detectedLanguage
});
} catch (error) {
// Log the actual error details for debugging
console.error('Error:', error.message);
// Show a simple, user-friendly error message
res.render('index', {
error: 'Something went wrong. Please try again later.',
languages: [
'plaintext', 'javascript', 'python', 'java', 'cpp', 'csharp', 'php',
'ruby', 'go', 'swift', 'kotlin', 'rust', 'typescript'
]
});
}
});
// Start the server and listen on configured port
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});