Files
Counter_website/app.py
Angoosh Leviocki bd3ac69ac9
All checks were successful
release-tag / release-image (push) Successful in 26s
added visit counter
2026-05-26 11:29:28 +02:00

149 lines
4.8 KiB
Python

from flask import Flask, render_template_string, jsonify
import sqlite3
app = Flask(__name__)
DB_FILE = '/db/counter.db'
def init_db():
"""Initialize the database and set the starting number to 0 if it doesn't exist."""
with sqlite3.connect(DB_FILE) as conn:
c = conn.cursor()
# 1. Setup Button Counter Table
c.execute('CREATE TABLE IF NOT EXISTS counter (id INTEGER PRIMARY KEY, value INTEGER)')
c.execute('SELECT value FROM counter WHERE id = 1')
if c.fetchone() is None:
c.execute('INSERT INTO counter (id, value) VALUES (1, 0)')
# 2. Setup Visit Counter Table
c.execute('CREATE TABLE IF NOT EXISTS visits (id INTEGER PRIMARY KEY, count INTEGER)')
c.execute('SELECT count FROM visits WHERE id = 1')
if c.fetchone() is None:
c.execute('INSERT INTO visits (id, count) VALUES (1, 0)')
conn.commit()
# We added an ID to the counter div and a JavaScript block at the bottom
HTML_TEMPLATE = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Counter</title>
<style>
html, body {
height: 100%; /* Ensures the body takes up the full screen height */
margin: 0;
display: flex;
flex-direction: column;
}
body {
font-family: sans-serif;
text-align: center;
}
.content {
flex: 1; /* Pushes the footer to the bottom */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.counter-display {
font-size: 72px;
font-weight: bold;
margin-bottom: 20px;
}
.blue-button {
background-color: #007BFF;
color: white;
border: none;
padding: 15px 32px;
font-size: 18px;
font-weight: bold;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
transition: background-color 0.3s ease;
}
.blue-button:hover {
background-color: #0056b3;
}
.footer {
background-color: #f8f9fa;
color: #6c757d;
padding: 15px;
font-size: 14px;
border-top: 1px solid #dee2e6;
}
</style>
</head>
<body>
<div class="content">
<div class="counter-display" id="counter">{{ count }}</div>
<button class="blue-button" onclick="incrementCounter()">Add One</button>
</div>
<div class="footer">
Total Page Visits: <strong>{{ visits }}</strong>
</div>
<script>
function incrementCounter() {
// Send a background POST request to the server
fetch('/increment', {
method: 'POST'
})
.then(response => response.json()) // Parse the JSON response from Flask
.then(data => {
// Update the number on the screen without reloading the page
document.getElementById('counter').innerText = data.new_count;
})
.catch(error => console.error('Error:', error));
}
</script>
</body>
</html>
'''
@app.route('/')
def index():
"""Update visit count, fetch both counts, and load the page."""
with sqlite3.connect(DB_FILE) as conn:
c = conn.cursor()
# Increment the visit counter every time this route is hit
c.execute('UPDATE visits SET count = count + 1 WHERE id = 1')
conn.commit()
# Fetch the newly updated visit count
c.execute('SELECT count FROM visits WHERE id = 1')
visit_count = c.fetchone()[0]
# Fetch the current button count
c.execute('SELECT value FROM counter WHERE id = 1')
button_count = c.fetchone()[0]
# Pass both variables into the HTML template
return render_template_string(HTML_TEMPLATE, count=button_count, visits=visit_count)
@app.route('/increment', methods=['POST'])
def increment():
"""Add 1 to the database value and return the new number as JSON."""
with sqlite3.connect(DB_FILE) as conn:
c = conn.cursor()
# Update the database
c.execute('UPDATE counter SET value = value + 1 WHERE id = 1')
# Grab the new value so we can send it back to the frontend
c.execute('SELECT value FROM counter WHERE id = 1')
new_count = c.fetchone()[0]
conn.commit()
# Return JSON instead of redirecting the whole page
return jsonify({'new_count': new_count})
if __name__ == '__main__':
init_db()
# Keeping the host='0.0.0.0' so your outside connections still work!
app.run(host='0.0.0.0', port=5000, debug=True)