Skip to content

Commit fd7b08c

Browse files
committed
add missing files
1 parent 89fca95 commit fd7b08c

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

app.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from flask import Flask, render_template, g
2+
import psycopg2
3+
import psycopg2.extras # For dictionary cursor
4+
import os # For environment variables (recommended for credentials)
5+
6+
app = Flask(__name__)
7+
8+
# --- Database Configuration ---
9+
# It's highly recommended to use environment variables for sensitive data in production.
10+
# For this example, we're using the provided values directly.
11+
DB_HOST = os.getenv("DB_HOST", "mydbserver")
12+
DB_PORT = int(os.getenv("DB_PORT", 5432))
13+
DB_NAME = os.getenv("DB_NAME", "myhost")
14+
DB_USER = os.getenv("DB_USER", "myuser")
15+
DB_PASS = os.getenv("DB_PASS", "mypass")
16+
DB_SSLMODE = os.getenv("DB_SSLMODE", "prefer")
17+
DB_TABLE = "logs"
18+
19+
def get_db_connection():
20+
"""Establishes a new database connection."""
21+
try:
22+
conn = psycopg2.connect(
23+
host=DB_HOST,
24+
port=DB_PORT,
25+
database=DB_NAME,
26+
user=DB_USER,
27+
password=DB_PASS,
28+
sslmode=DB_SSLMODE
29+
)
30+
return conn
31+
except psycopg2.Error as e:
32+
print(f"Error connecting to PostgreSQL database: {e}")
33+
return None
34+
35+
@app.before_request
36+
def before_request():
37+
"""Get a database connection before each request."""
38+
g.db_conn = get_db_connection()
39+
40+
@app.teardown_request
41+
def teardown_request(exception):
42+
"""Close the database connection after each request."""
43+
db_conn = g.pop('db_conn', None)
44+
if db_conn is not None:
45+
db_conn.close()
46+
47+
@app.route('/')
48+
def show_logs():
49+
if not g.db_conn:
50+
return render_template('logs.html',
51+
error_message="Failed to connect to the database. Please check server logs and configuration.",
52+
table_name=DB_TABLE, logs=[], columns=[])
53+
54+
logs_data = []
55+
column_names = []
56+
error = None
57+
58+
try:
59+
# Using DictCursor to get rows as dictionaries (column_name: value)
60+
with g.db_conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
61+
cur.execute(f"SELECT * FROM {DB_TABLE};")
62+
if cur.description:
63+
column_names = [desc[0] for desc in cur.description]
64+
logs_data = cur.fetchall()
65+
except psycopg2.Error as e:
66+
print(f"Database query error: {e}")
67+
error = f"Error fetching data from table '{DB_TABLE}': {e}"
68+
# You might want to rollback if it was a write operation, g.db_conn.rollback()
69+
70+
return render_template('logs.html',
71+
logs=logs_data,
72+
columns=column_names,
73+
table_name=DB_TABLE,
74+
error_message=error)
75+
76+
if __name__ == '__main__':
77+
# IMPORTANT: Set debug=False in a production environment!
78+
app.run(host='0.0.0.0', port=5000, debug=True)

templates/logs.html

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>PostgreSQL Table Viewer - {{ table_name }}</title>
7+
<style>
8+
body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; }
9+
h1 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }
10+
table { width: 100%; border-collapse: collapse; margin-top: 20px; box-shadow: 0 2px 3px rgba(0,0,0,0.1); }
11+
th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
12+
th { background-color: #007bff; color: white; }
13+
tr:nth-child(even) { background-color: #f9f9f9; }
14+
tr:hover { background-color: #f1f1f1; }
15+
.no-data { color: #777; font-style: italic; margin-top: 20px; }
16+
.error { color: #d9534f; font-weight: bold; background-color: #f2dede; border: 1px solid #ebccd1; padding: 15px; margin-top: 20px; border-radius: 4px;}
17+
</style>
18+
</head>
19+
<body>
20+
<h1>Contents of '{{ table_name }}' Table</h1>
21+
22+
{% if error_message %}
23+
<p class="error">{{ error_message }}</p>
24+
{% endif %}
25+
26+
{% if logs and columns %}
27+
<table>
28+
<thead>
29+
<tr>
30+
{% for col_name in columns %}
31+
<th>{{ col_name }}</th>
32+
{% endfor %}
33+
</tr>
34+
</thead>
35+
<tbody>
36+
{% for row in logs %}
37+
<tr>
38+
{% for col_name in columns %}
39+
<td>{{ row[col_name] }}</td>
40+
{% endfor %}
41+
</tr>
42+
{% endfor %}
43+
</tbody>
44+
</table>
45+
{% elif not error_message %}
46+
<p class="no-data">No data found in the '{{ table_name }}' table, or the table is empty.</p>
47+
{% endif %}
48+
</body>
49+
</html>

0 commit comments

Comments
 (0)