Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:8080
* Running on http://192.168.0.2:8080
Press CTRL+C to quit
Comment on lines +1 to +7

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Log files and other generated files should not be committed to the version control system. They are specific to a developer's environment, can contain sensitive information, and often lead to merge conflicts. Please remove this file from the repository and add *.log to your .gitignore file to prevent it from being tracked in the future.

97 changes: 97 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

@app.route('/')
def index():
# This will serve the main command interface.
return render_template('index.html')

@app.route('/api/insta-essay', methods=['POST'])
def insta_essay():
"""
Simulates the generation of a high-quality essay.
The hook to demonstrate power.
"""
# In a real scenario, we'd process the request data (prompt, rubric, etc.)
# and call an LLM API. For this MVP, we return a simulated result.
data = request.json
print(f"Received for InstaEssay: {data}")
Comment on lines +18 to +19

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using print() for logging in a web application is not ideal. It writes directly to standard output and bypasses any logging configuration you might have. It's better to use Flask's built-in logger (app.logger) or the standard logging module. This allows for more flexible configuration, such as setting log levels, formatting messages, and directing output to files or other services.

This comment also applies to lines 33-34, 52-53, and 76-77.

Suggested change
data = request.json
print(f"Received for InstaEssay: {data}")
data = request.json
app.logger.info(f"Received for InstaEssay: {data}")


simulated_essay = """
The socio-economic ramifications of post-industrial capitalism have been a subject of extensive debate among scholars. This essay delineates the primary arguments, focusing on the dichotomy between neoliberal proponents and their Marxist critics. The former argue for market-led growth, citing empirical evidence of poverty reduction, while the latter highlight the exacerbation of inequality and labor exploitation. Ultimately, a synthesis of these perspectives suggests that while globalization has generated unprecedented wealth, its distribution remains fundamentally inequitable, necessitating robust state intervention.

(Generated via AcademicWeapon.ai - The Unfair Advantage)
"""
Comment on lines +21 to +25

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The project's style guide suggests that long string variables should have their content indented for better readability.1 This makes the code cleaner and more consistent.

Suggested change
simulated_essay = """
The socio-economic ramifications of post-industrial capitalism have been a subject of extensive debate among scholars. This essay delineates the primary arguments, focusing on the dichotomy between neoliberal proponents and their Marxist critics. The former argue for market-led growth, citing empirical evidence of poverty reduction, while the latter highlight the exacerbation of inequality and labor exploitation. Ultimately, a synthesis of these perspectives suggests that while globalization has generated unprecedented wealth, its distribution remains fundamentally inequitable, necessitating robust state intervention.
(Generated via AcademicWeapon.ai - The Unfair Advantage)
"""
simulated_essay = """
The socio-economic ramifications of post-industrial capitalism have been a subject of extensive debate among scholars. This essay delineates the primary arguments, focusing on the dichotomy between neoliberal proponents and their Marxist critics. The former argue for market-led growth, citing empirical evidence of poverty reduction, while the latter highlight the exacerbation of inequality and labor exploitation. Ultimately, a synthesis of these perspectives suggests that while globalization has generated unprecedented wealth, its distribution remains fundamentally inequitable, necessitating robust state intervention.
(Generated via AcademicWeapon.ai - The Unfair Advantage)
"""

Style Guide References

Footnotes

  1. The style guide recommends indenting the content of multiline strings to improve readability. (link)

return jsonify({"result": simulated_essay.strip()})

@app.route('/api/lit-review', methods=['POST'])
def lit_review():
"""
Simulates the generation of a literature review.
"""
data = request.json
print(f"Received for LitReview: {data}")

simulated_review = """
**Literature Review: The Impact of AI on Higher Education**

1. **Smith (2021), "The Algorithmic Tutor"**: Found that AI-driven personalized learning platforms increased student engagement by 35%.
2. **Jones & Wang (2022), "Automating Academia"**: Raised ethical concerns regarding algorithmic bias in automated grading systems.
3. **Gupta (2020), "Computational Pedagogy"**: Argued that AI tools could free up educators to focus on higher-order conceptual teaching.

(Generated via AcademicWeapon.ai - The Unfair Advantage)
"""
return jsonify({"result": simulated_review.strip()})

@app.route('/api/exam-cram', methods=['POST'])
def exam_cram():
"""
Simulates the generation of a study guide from uploaded materials.
"""
data = request.json
print(f"Received for ExamCram: {data}")

simulated_guide = """
**ExamCram Study Guide: Microeconomics 101**

**Key Concepts:**
- **Supply and Demand:** As price increases, supply increases and demand decreases. Equilibrium is where they intersect.
- **Elasticity:** Measures sensitivity of demand/supply to price changes.
- **Opportunity Cost:** The value of the next-best alternative forgone.

**Potential Questions:**
1. Explain the concept of market equilibrium.
2. What are the determinants of price elasticity of demand?

(Generated via AcademicWeapon.ai - The Unfair Advantage)
"""
return jsonify({"result": simulated_guide.strip()})

@app.route('/api/presentation-bot', methods=['POST'])
def presentation_bot():
"""
Simulates the generation of a presentation.
"""
data = request.json
print(f"Received for PresentationBot: {data}")

simulated_slides = """
**Presentation: The Future of Renewable Energy**

- **Slide 1: Title Slide**
- **Slide 2: The Problem:** Climate Change & Fossil Fuel Dependency
- **Slide 3: Solution Overview:** Solar, Wind, Geothermal
- **Slide 4: Deep Dive: Solar Power** (Technology, Costs, Benefits)
- **Slide 5: Deep Dive: Wind Power** (Turbine tech, Onshore vs. Offshore)
- **Slide 6: Economic Viability & Market Trends**
- **Slide 7: Challenges & The Path Forward**
- **Slide 8: Q&A**

(Generated via AcademicWeapon.ai - The Unfair Advantage)
"""
return jsonify({"result": simulated_slides.strip()})

if __name__ == '__main__':
# Run the app, accessible on the network.
app.run(host='0.0.0.0', port=8080)
Comment on lines +95 to +97

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Running the application with app.run() uses Flask's built-in development server, which is not suitable for production as stated in the server logs. It's not designed to be particularly efficient, stable, or secure. For deployment, you should use a production-ready WSGI server like Gunicorn or uWSGI. For example, you would run your app from the command line with gunicorn --bind 0.0.0.0:8080 app:app and remove this if __name__ == '__main__': block.

93 changes: 93 additions & 0 deletions static/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// static/main.js
document.addEventListener('DOMContentLoaded', () => {
// --- API Interaction Logic ---
const handleFormSubmit = async (event, formId, apiUrl, inputId, resultId) => {
event.preventDefault();
const inputElement = document.getElementById(inputId);
const resultElement = document.getElementById(resultId);
const submitButton = document.querySelector(`#${formId} button`);

const payload = {
prompt: inputElement.value
};

resultElement.textContent = 'Generating... The gears of domination are turning...';
submitButton.disabled = true;

try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
resultElement.textContent = data.result;

} catch (error) {
console.error('Error:', error);
resultElement.textContent = 'An error occurred. The system faltered. Try again.';
} finally {
submitButton.disabled = false;
}
};

document.getElementById('insta-essay-form').addEventListener('submit', (e) =>
handleFormSubmit(e, 'insta-essay-form', '/api/insta-essay', 'essay-prompt', 'insta-essay-result')
);

document.getElementById('lit-review-form').addEventListener('submit', (e) =>
handleFormSubmit(e, 'lit-review-form', '/api/lit-review', 'review-topic', 'lit-review-result')
);

document.getElementById('exam-cram-form').addEventListener('submit', (e) =>
handleFormSubmit(e, 'exam-cram-form', '/api/exam-cram', 'exam-notes', 'exam-cram-result')
);

document.getElementById('presentation-bot-form').addEventListener('submit', (e) =>
handleFormSubmit(e, 'presentation-bot-form', '/api/presentation-bot', 'presentation-topic', 'presentation-bot-result')
);
Comment on lines +41 to +55

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These event listeners are very repetitive. You can refactor this to be more DRY (Don't Repeat Yourself) by using a shared event handler and storing the unique information (like API URL and element IDs) in HTML data-* attributes. This makes the code easier to maintain and extend with new tools.

For example, you could add a class like tool-form to each form in your HTML:

<form id="insta-essay-form" class="tool-form" data-api-url="/api/insta-essay" data-input-id="essay-prompt" data-result-id="insta-essay-result">
  ...
</form>

And then in your JavaScript, you could add a single listener to all forms with that class:

document.querySelectorAll('.tool-form').forEach(form => {
  form.addEventListener('submit', (e) => {
    const { apiUrl, inputId, resultId } = form.dataset;
    handleFormSubmit(e, form.id, apiUrl, inputId, resultId);
  });
});



// --- Urgency Engine Logic ---
const countdownElement = document.getElementById('countdown-timer');
let timeLeft = 23 * 3600 + 59 * 60 + 59; // 23:59:59 in seconds

setInterval(() => {
if (timeLeft <= 0) {
countdownElement.textContent = "00:00:00";
return;
}
timeLeft--;
const hours = Math.floor(timeLeft / 3600);
const minutes = Math.floor((timeLeft % 3600) / 60);
const seconds = timeLeft % 60;
countdownElement.textContent =
`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}, 1000);
Comment on lines +59 to +73

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

setInterval is not reliable for a countdown timer because it can be throttled by the browser when the tab is inactive, causing the timer to drift. A more robust approach is to calculate the remaining time based on the difference between the current time and a target end time. This ensures the countdown remains accurate even if the tab is backgrounded.

    const countdownElement = document.getElementById('countdown-timer');
    const durationInSeconds = 23 * 3600 + 59 * 60 + 59;
    const endTime = Date.now() + (durationInSeconds * 1000);

    const timerInterval = setInterval(() => {
        const timeLeft = Math.round((endTime - Date.now()) / 1000);

        if (timeLeft <= 0) {
            countdownElement.textContent = "00:00:00";
            clearInterval(timerInterval);
            return;
        }

        const hours = Math.floor(timeLeft / 3600);
        const minutes = Math.floor((timeLeft % 3600) / 60);
        const seconds = timeLeft % 60;
        countdownElement.textContent =
            `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
    }, 1000);


const socialProofElement = document.getElementById('social-proof');
const socialProofs = [
"Sarah from Stanford just finished her thesis with us.",
"Mike from MIT just crammed for his quantum physics exam.",
"Chloe from Oxford just generated a presentation in 5 minutes.",
"David from Harvard just aced his history essay.",
"Emily from Yale just synthesized a literature review effortlessly."
];
let proofIndex = 0;

setInterval(() => {
proofIndex = (proofIndex + 1) % socialProofs.length;
socialProofElement.style.opacity = 0;
setTimeout(() => {
socialProofElement.textContent = socialProofs[proofIndex];
socialProofElement.style.opacity = 1;
}, 500); // fade in time
}, 5000); // Change every 5 seconds
});
139 changes: 139 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/* static/style.css */
:root {
--bg-color: #121212;
--primary-text: #E0E0E0;
--secondary-text: #BDBDBD;
--surface-color: #1E1E1E;
--primary-accent: #03DAC6; /* A bright, techy color */
--error-color: #CF6679;
--border-color: #333;
}

body {
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: var(--bg-color);
color: var(--primary-text);
line-height: 1.6;
margin: 0;
padding: 20px;
}

header, main, footer {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}

header {
text-align: center;
border-bottom: 1px solid var(--border-color);
}

header h1 {
font-size: 2.5em;
color: var(--primary-accent);
margin-bottom: 0;
}

.tool-section, #monetization {
background-color: var(--surface-color);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 20px;
margin-top: 30px;
}

h2 {
color: var(--primary-accent);
border-bottom: 1px solid var(--border-color);
padding-bottom: 10px;
margin-top: 0;
}

input[type="text"], textarea {
width: 100%;
background-color: var(--bg-color);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px;
color: var(--primary-text);
font-family: inherit;
margin-bottom: 10px;
box-sizing: border-box;
}

button {
background-color: var(--primary-accent);
color: var(--bg-color);
border: none;
padding: 12px 20px;
font-size: 1em;
font-weight: bold;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}

button:hover {
background-color: #018786;
}

.result-container {
margin-top: 20px;
}

pre {
background-color: var(--bg-color);
padding: 15px;
border-radius: 4px;
white-space: pre-wrap;
word-wrap: break-word;
border: 1px solid var(--border-color);
}

.pricing-tiers {
display: flex;
justify-content: space-between;
gap: 20px;
margin-top: 20px;
}

.tier {
flex: 1;
background-color: var(--bg-color);
border: 1px solid var(--border-color);
padding: 20px;
border-radius: 8px;
text-align: center;
}

#primary-tier {
border: 2px solid var(--primary-accent);
transform: scale(1.05);
box-shadow: 0 0 15px var(--primary-accent);
}

#urgency-engine {
text-align: center;
margin-top: 30px;
font-size: 1.2em;
font-weight: bold;
}

#countdown-timer {
color: var(--error-color);
}

#social-proof {
color: var(--secondary-text);
font-style: italic;
font-size: 0.9em;
transition: opacity 0.5s ease-in-out;
}

footer {
text-align: center;
margin-top: 40px;
color: var(--secondary-text);
font-size: 0.8em;
}
Loading