Add datbase setup
This commit is contained in:
parent
538e9bc27b
commit
1b36a283d5
288
motm_app/db_setup.py
Normal file
288
motm_app/db_setup.py
Normal file
@ -0,0 +1,288 @@
|
||||
# encoding=utf-8
|
||||
"""
|
||||
Database setup and configuration management module.
|
||||
Handles database initialization, configuration saving/loading, and sample data creation.
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import configparser
|
||||
from datetime import datetime
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from database import Base, db_config, init_database
|
||||
from database import (
|
||||
Player, Club, Team, MatchSquad, HockeyFixture,
|
||||
AdminSettings, MotmVote, MatchComment, HockeyUser
|
||||
)
|
||||
|
||||
class DatabaseConfigManager:
|
||||
"""Manages database configuration and setup."""
|
||||
|
||||
def __init__(self, config_file='database_config.ini'):
|
||||
self.config_file = config_file
|
||||
self.config = configparser.ConfigParser()
|
||||
self.load_config()
|
||||
|
||||
def load_config(self):
|
||||
"""Load configuration from file."""
|
||||
if os.path.exists(self.config_file):
|
||||
self.config.read(self.config_file)
|
||||
else:
|
||||
# Create default configuration
|
||||
self.config['DATABASE'] = {
|
||||
'type': 'sqlite',
|
||||
'sqlite_database_path': 'hockey_results.db'
|
||||
}
|
||||
self.config['MYSQL'] = {
|
||||
'host': 'localhost',
|
||||
'port': '3306',
|
||||
'database': 'hockey_results',
|
||||
'username': 'root',
|
||||
'password': '',
|
||||
'charset': 'utf8mb4'
|
||||
}
|
||||
self.config['POSTGRESQL'] = {
|
||||
'host': 'localhost',
|
||||
'port': '5432',
|
||||
'database': 'hockey_results',
|
||||
'username': 'postgres',
|
||||
'password': ''
|
||||
}
|
||||
|
||||
def save_config(self, form_data):
|
||||
"""Save configuration from form data."""
|
||||
# Update database type
|
||||
self.config['DATABASE']['type'] = form_data['database_type']
|
||||
|
||||
# Update SQLite settings
|
||||
if 'sqlite_database_path' in form_data:
|
||||
self.config['DATABASE']['sqlite_database_path'] = form_data['sqlite_database_path']
|
||||
|
||||
# Update MySQL settings
|
||||
if 'mysql_host' in form_data:
|
||||
self.config['MYSQL']['host'] = form_data['mysql_host']
|
||||
if 'mysql_port' in form_data:
|
||||
self.config['MYSQL']['port'] = str(form_data['mysql_port'])
|
||||
if 'mysql_database' in form_data:
|
||||
self.config['MYSQL']['database'] = form_data['mysql_database']
|
||||
if 'mysql_username' in form_data:
|
||||
self.config['MYSQL']['username'] = form_data['mysql_username']
|
||||
if 'mysql_password' in form_data:
|
||||
self.config['MYSQL']['password'] = form_data['mysql_password']
|
||||
if 'mysql_charset' in form_data:
|
||||
self.config['MYSQL']['charset'] = form_data['mysql_charset']
|
||||
|
||||
# Update PostgreSQL settings
|
||||
if 'postgres_host' in form_data:
|
||||
self.config['POSTGRESQL']['host'] = form_data['postgres_host']
|
||||
if 'postgres_port' in form_data:
|
||||
self.config['POSTGRESQL']['port'] = str(form_data['postgres_port'])
|
||||
if 'postgres_database' in form_data:
|
||||
self.config['POSTGRESQL']['database'] = form_data['postgres_database']
|
||||
if 'postgres_username' in form_data:
|
||||
self.config['POSTGRESQL']['username'] = form_data['postgres_username']
|
||||
if 'postgres_password' in form_data:
|
||||
self.config['POSTGRESQL']['password'] = form_data['postgres_password']
|
||||
|
||||
# Save to file
|
||||
with open(self.config_file, 'w') as f:
|
||||
self.config.write(f)
|
||||
|
||||
# Update environment variables
|
||||
self._update_environment_variables()
|
||||
|
||||
def _update_environment_variables(self):
|
||||
"""Update environment variables based on configuration."""
|
||||
db_type = self.config['DATABASE']['type']
|
||||
|
||||
if db_type == 'sqlite':
|
||||
os.environ['DATABASE_TYPE'] = 'sqlite'
|
||||
os.environ['SQLITE_DATABASE_PATH'] = self.config['DATABASE']['sqlite_database_path']
|
||||
|
||||
elif db_type == 'mysql':
|
||||
os.environ['DATABASE_TYPE'] = 'mysql'
|
||||
os.environ['MYSQL_HOST'] = self.config['MYSQL']['host']
|
||||
os.environ['MYSQL_PORT'] = self.config['MYSQL']['port']
|
||||
os.environ['MYSQL_DATABASE'] = self.config['MYSQL']['database']
|
||||
os.environ['MYSQL_USER'] = self.config['MYSQL']['username']
|
||||
os.environ['MYSQL_PASSWORD'] = self.config['MYSQL']['password']
|
||||
os.environ['MYSQL_CHARSET'] = self.config['MYSQL']['charset']
|
||||
|
||||
elif db_type == 'postgresql':
|
||||
os.environ['DATABASE_TYPE'] = 'postgresql'
|
||||
os.environ['POSTGRES_HOST'] = self.config['POSTGRESQL']['host']
|
||||
os.environ['POSTGRES_PORT'] = self.config['POSTGRESQL']['port']
|
||||
os.environ['POSTGRES_DATABASE'] = self.config['POSTGRESQL']['database']
|
||||
os.environ['POSTGRES_USER'] = self.config['POSTGRESQL']['username']
|
||||
os.environ['POSTGRES_PASSWORD'] = self.config['POSTGRESQL']['password']
|
||||
|
||||
def test_connection(self, form_data):
|
||||
"""Test database connection with provided settings."""
|
||||
try:
|
||||
# Temporarily update environment variables
|
||||
old_env = {}
|
||||
for key in ['DATABASE_TYPE', 'SQLITE_DATABASE_PATH', 'MYSQL_HOST', 'MYSQL_PORT',
|
||||
'MYSQL_DATABASE', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_CHARSET',
|
||||
'POSTGRES_HOST', 'POSTGRES_PORT', 'POSTGRES_DATABASE', 'POSTGRES_USER', 'POSTGRES_PASSWORD']:
|
||||
old_env[key] = os.environ.get(key)
|
||||
|
||||
# Set new environment variables
|
||||
os.environ['DATABASE_TYPE'] = form_data['database_type']
|
||||
|
||||
if form_data['database_type'] == 'sqlite':
|
||||
os.environ['SQLITE_DATABASE_PATH'] = form_data['sqlite_database_path']
|
||||
elif form_data['database_type'] == 'mysql':
|
||||
os.environ['MYSQL_HOST'] = form_data['mysql_host']
|
||||
os.environ['MYSQL_PORT'] = str(form_data['mysql_port'])
|
||||
os.environ['MYSQL_DATABASE'] = form_data['mysql_database']
|
||||
os.environ['MYSQL_USER'] = form_data['mysql_username']
|
||||
os.environ['MYSQL_PASSWORD'] = form_data['mysql_password']
|
||||
os.environ['MYSQL_CHARSET'] = form_data['mysql_charset']
|
||||
elif form_data['database_type'] == 'postgresql':
|
||||
os.environ['POSTGRES_HOST'] = form_data['postgres_host']
|
||||
os.environ['POSTGRES_PORT'] = str(form_data['postgres_port'])
|
||||
os.environ['POSTGRES_DATABASE'] = form_data['postgres_database']
|
||||
os.environ['POSTGRES_USER'] = form_data['postgres_username']
|
||||
os.environ['POSTGRES_PASSWORD'] = form_data['postgres_password']
|
||||
|
||||
# Test connection
|
||||
from database import DatabaseConfig
|
||||
test_config = DatabaseConfig()
|
||||
engine = test_config.engine
|
||||
|
||||
with engine.connect() as conn:
|
||||
result = conn.execute(text("SELECT 1"))
|
||||
result.fetchone()
|
||||
|
||||
return True, "Connection successful!"
|
||||
|
||||
except Exception as e:
|
||||
return False, f"Connection failed: {str(e)}"
|
||||
|
||||
finally:
|
||||
# Restore original environment variables
|
||||
for key, value in old_env.items():
|
||||
if value is None:
|
||||
os.environ.pop(key, None)
|
||||
else:
|
||||
os.environ[key] = value
|
||||
|
||||
def initialize_database(self, create_sample_data=True):
|
||||
"""Initialize database with tables and optionally sample data."""
|
||||
try:
|
||||
# Create tables
|
||||
init_database()
|
||||
|
||||
if create_sample_data:
|
||||
self._create_sample_data()
|
||||
|
||||
return True, "Database initialized successfully!"
|
||||
|
||||
except Exception as e:
|
||||
return False, f"Database initialization failed: {str(e)}"
|
||||
|
||||
def _create_sample_data(self):
|
||||
"""Create sample data for testing."""
|
||||
from database import get_db_session
|
||||
|
||||
session = get_db_session()
|
||||
try:
|
||||
# Create sample clubs
|
||||
clubs_data = [
|
||||
{'hockey_club': 'HKFC', 'logo_url': '/static/images/hkfc_logo.png'},
|
||||
{'hockey_club': 'KCC', 'logo_url': '/static/images/kcc_logo.png'},
|
||||
{'hockey_club': 'USRC', 'logo_url': '/static/images/usrc_logo.png'},
|
||||
{'hockey_club': 'Valley', 'logo_url': '/static/images/valley_logo.png'},
|
||||
]
|
||||
|
||||
for club_data in clubs_data:
|
||||
club = Club(**club_data)
|
||||
session.add(club)
|
||||
|
||||
# Create sample teams
|
||||
teams_data = [
|
||||
{'club': 'HKFC', 'team': 'A', 'display_name': 'HKFC A', 'league': 'Premier Division'},
|
||||
{'club': 'HKFC', 'team': 'B', 'display_name': 'HKFC B', 'league': 'Division 1'},
|
||||
{'club': 'HKFC', 'team': 'C', 'display_name': 'HKFC C', 'league': 'Division 2'},
|
||||
{'club': 'HKFC', 'team': 'D', 'display_name': 'HKFC D', 'league': 'Division 3'},
|
||||
]
|
||||
|
||||
for team_data in teams_data:
|
||||
team = Team(**team_data)
|
||||
session.add(team)
|
||||
|
||||
# Create sample players
|
||||
players_data = [
|
||||
{'player_number': 1, 'player_forenames': 'John', 'player_surname': 'Smith', 'player_nickname': 'Smithers', 'player_team': 'HKFC D'},
|
||||
{'player_number': 2, 'player_forenames': 'Mike', 'player_surname': 'Jones', 'player_nickname': 'Jonesy', 'player_team': 'HKFC D'},
|
||||
{'player_number': 3, 'player_forenames': 'David', 'player_surname': 'Brown', 'player_nickname': 'Brownie', 'player_team': 'HKFC D'},
|
||||
{'player_number': 4, 'player_forenames': 'Chris', 'player_surname': 'Wilson', 'player_nickname': 'Willy', 'player_team': 'HKFC D'},
|
||||
{'player_number': 5, 'player_forenames': 'Tom', 'player_surname': 'Taylor', 'player_nickname': 'Tayls', 'player_team': 'HKFC D'},
|
||||
]
|
||||
|
||||
for player_data in players_data:
|
||||
player = Player(**player_data)
|
||||
session.add(player)
|
||||
|
||||
# Create sample admin settings
|
||||
admin_settings = AdminSettings(
|
||||
userid='admin',
|
||||
next_fixture=1,
|
||||
next_club='KCC',
|
||||
next_team='KCC A',
|
||||
curr_motm=1,
|
||||
curr_dotd=2,
|
||||
oppo_logo='/static/images/kcc_logo.png',
|
||||
hkfc_logo='/static/images/hkfc_logo.png',
|
||||
motm_url_suffix='abc123',
|
||||
prev_fixture=0
|
||||
)
|
||||
session.add(admin_settings)
|
||||
|
||||
# Create sample fixtures
|
||||
fixtures_data = [
|
||||
{'fixture_number': 1, 'date': datetime(2024, 1, 15), 'home_team': 'HKFC D', 'away_team': 'KCC A', 'venue': 'HKFC'},
|
||||
{'fixture_number': 2, 'date': datetime(2024, 1, 22), 'home_team': 'USRC A', 'away_team': 'HKFC D', 'venue': 'USRC'},
|
||||
{'fixture_number': 3, 'date': datetime(2024, 1, 29), 'home_team': 'HKFC D', 'away_team': 'Valley A', 'venue': 'HKFC'},
|
||||
]
|
||||
|
||||
for fixture_data in fixtures_data:
|
||||
fixture = HockeyFixture(**fixture_data)
|
||||
session.add(fixture)
|
||||
|
||||
session.commit()
|
||||
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
raise e
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
def get_config_dict(self):
|
||||
"""Get configuration as dictionary for form population."""
|
||||
config_dict = {}
|
||||
|
||||
# Database type
|
||||
config_dict['database_type'] = self.config['DATABASE'].get('type', 'sqlite')
|
||||
config_dict['sqlite_database_path'] = self.config['DATABASE'].get('sqlite_database_path', 'hockey_results.db')
|
||||
|
||||
# MySQL settings
|
||||
config_dict['mysql_host'] = self.config['MYSQL'].get('host', 'localhost')
|
||||
config_dict['mysql_port'] = int(self.config['MYSQL'].get('port', '3306'))
|
||||
config_dict['mysql_database'] = self.config['MYSQL'].get('database', 'hockey_results')
|
||||
config_dict['mysql_username'] = self.config['MYSQL'].get('username', 'root')
|
||||
config_dict['mysql_password'] = self.config['MYSQL'].get('password', '')
|
||||
config_dict['mysql_charset'] = self.config['MYSQL'].get('charset', 'utf8mb4')
|
||||
|
||||
# PostgreSQL settings
|
||||
config_dict['postgres_host'] = self.config['POSTGRESQL'].get('host', 'localhost')
|
||||
config_dict['postgres_port'] = int(self.config['POSTGRESQL'].get('port', '5432'))
|
||||
config_dict['postgres_database'] = self.config['POSTGRESQL'].get('database', 'hockey_results')
|
||||
config_dict['postgres_username'] = self.config['POSTGRESQL'].get('username', 'postgres')
|
||||
config_dict['postgres_password'] = self.config['POSTGRESQL'].get('password', '')
|
||||
|
||||
return config_dict
|
||||
|
||||
# Global instance
|
||||
db_config_manager = DatabaseConfigManager()
|
||||
@ -37,3 +37,39 @@ class goalsAssistsForm(FlaskForm):
|
||||
assists = SelectField('Assists:', choices=[(0, '0'), (1, '1'), (2, '2'), (3, '3'), (4, '4')])
|
||||
goals = SelectField('Goals:', choices=[(0, '0'), (1, '1'), (2, '2'), (3, '3'), (4, '4')])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class DatabaseSetupForm(FlaskForm):
|
||||
"""Form for database setup and configuration."""
|
||||
database_type = SelectField('Database Type',
|
||||
choices=[('sqlite', 'SQLite'), ('mysql', 'MySQL/MariaDB'), ('postgresql', 'PostgreSQL')],
|
||||
validators=[InputRequired()])
|
||||
|
||||
# SQLite fields
|
||||
sqlite_database_path = StringField('Database File Path',
|
||||
default='hockey_results.db',
|
||||
validators=[InputRequired()])
|
||||
|
||||
# MySQL/MariaDB fields
|
||||
mysql_host = StringField('Host', default='localhost')
|
||||
mysql_port = IntegerField('Port', default=3306)
|
||||
mysql_database = StringField('Database Name', default='hockey_results')
|
||||
mysql_username = StringField('Username', default='root')
|
||||
mysql_password = PasswordField('Password')
|
||||
mysql_charset = StringField('Charset', default='utf8mb4')
|
||||
|
||||
# PostgreSQL fields
|
||||
postgres_host = StringField('Host', default='localhost')
|
||||
postgres_port = IntegerField('Port', default=5432)
|
||||
postgres_database = StringField('Database Name', default='hockey_results')
|
||||
postgres_username = StringField('Username', default='postgres')
|
||||
postgres_password = PasswordField('Password')
|
||||
|
||||
# Setup options
|
||||
create_sample_data = BooleanField('Create Sample Data', default=True)
|
||||
initialize_tables = BooleanField('Initialize Database Tables', default=True)
|
||||
|
||||
# Action buttons
|
||||
test_connection = SubmitField('Test Connection')
|
||||
save_config = SubmitField('Save Configuration')
|
||||
initialize_database = SubmitField('Initialize Database')
|
||||
|
||||
126
motm_app/main.py
126
motm_app/main.py
@ -8,16 +8,18 @@ from datetime import datetime
|
||||
|
||||
from app import app, randomUrlSuffix
|
||||
from flask import Flask, flash, render_template, request, redirect, url_for, jsonify
|
||||
from sqlalchemy import text
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_bootstrap import Bootstrap
|
||||
from flask_basicauth import BasicAuth
|
||||
from wtforms import StringField, PasswordField, BooleanField
|
||||
from wtforms import DateField
|
||||
from wtforms.validators import InputRequired, Email, Length
|
||||
from forms import motmForm, adminSettingsForm2, goalsAssistsForm
|
||||
from forms import motmForm, adminSettingsForm2, goalsAssistsForm, DatabaseSetupForm
|
||||
from db_config import sql_write, sql_write_static, sql_read, sql_read_static
|
||||
from tables import matchSquadTable
|
||||
from readSettings import mySettings
|
||||
from db_setup import db_config_manager
|
||||
|
||||
app.config['BASIC_AUTH_USERNAME'] = 'admin'
|
||||
app.config['BASIC_AUTH_PASSWORD'] = 'letmein'
|
||||
@ -372,5 +374,127 @@ def poty_chart():
|
||||
return render_template('poty_chart.html')
|
||||
|
||||
|
||||
# ==================== DATABASE SETUP SECTION ====================
|
||||
|
||||
@app.route('/admin/database-setup', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def database_setup():
|
||||
"""Admin page for database setup and configuration"""
|
||||
form = DatabaseSetupForm()
|
||||
|
||||
# Load current configuration
|
||||
current_config = db_config_manager.get_config_dict()
|
||||
|
||||
# Populate form with current configuration
|
||||
for field_name, value in current_config.items():
|
||||
if hasattr(form, field_name):
|
||||
getattr(form, field_name).data = value
|
||||
|
||||
if request.method == 'POST':
|
||||
if form.test_connection.data:
|
||||
# Test database connection
|
||||
form_data = {
|
||||
'database_type': form.database_type.data,
|
||||
'sqlite_database_path': form.sqlite_database_path.data,
|
||||
'mysql_host': form.mysql_host.data,
|
||||
'mysql_port': form.mysql_port.data,
|
||||
'mysql_database': form.mysql_database.data,
|
||||
'mysql_username': form.mysql_username.data,
|
||||
'mysql_password': form.mysql_password.data,
|
||||
'mysql_charset': form.mysql_charset.data,
|
||||
'postgres_host': form.postgres_host.data,
|
||||
'postgres_port': form.postgres_port.data,
|
||||
'postgres_database': form.postgres_database.data,
|
||||
'postgres_username': form.postgres_username.data,
|
||||
'postgres_password': form.postgres_password.data,
|
||||
}
|
||||
|
||||
success, message = db_config_manager.test_connection(form_data)
|
||||
if success:
|
||||
flash(f'✅ {message}', 'success')
|
||||
else:
|
||||
flash(f'❌ {message}', 'error')
|
||||
|
||||
elif form.save_config.data:
|
||||
# Save configuration
|
||||
form_data = {
|
||||
'database_type': form.database_type.data,
|
||||
'sqlite_database_path': form.sqlite_database_path.data,
|
||||
'mysql_host': form.mysql_host.data,
|
||||
'mysql_port': form.mysql_port.data,
|
||||
'mysql_database': form.mysql_database.data,
|
||||
'mysql_username': form.mysql_username.data,
|
||||
'mysql_password': form.mysql_password.data,
|
||||
'mysql_charset': form.mysql_charset.data,
|
||||
'postgres_host': form.postgres_host.data,
|
||||
'postgres_port': form.postgres_port.data,
|
||||
'postgres_database': form.postgres_database.data,
|
||||
'postgres_username': form.postgres_username.data,
|
||||
'postgres_password': form.postgres_password.data,
|
||||
}
|
||||
|
||||
try:
|
||||
db_config_manager.save_config(form_data)
|
||||
flash('✅ Database configuration saved successfully!', 'success')
|
||||
except Exception as e:
|
||||
flash(f'❌ Failed to save configuration: {str(e)}', 'error')
|
||||
|
||||
elif form.initialize_database.data:
|
||||
# Initialize database
|
||||
try:
|
||||
success, message = db_config_manager.initialize_database(
|
||||
create_sample_data=form.create_sample_data.data
|
||||
)
|
||||
if success:
|
||||
flash(f'✅ {message}', 'success')
|
||||
else:
|
||||
flash(f'❌ {message}', 'error')
|
||||
except Exception as e:
|
||||
flash(f'❌ Database initialization failed: {str(e)}', 'error')
|
||||
|
||||
return render_template('database_setup.html', form=form, current_config=current_config)
|
||||
|
||||
|
||||
@app.route('/admin/database-status')
|
||||
@basic_auth.required
|
||||
def database_status():
|
||||
"""Admin page showing current database status and configuration"""
|
||||
try:
|
||||
from database import db_config
|
||||
engine = db_config.engine
|
||||
|
||||
# Test connection
|
||||
with engine.connect() as conn:
|
||||
result = conn.execute(text("SELECT 1"))
|
||||
result.fetchone()
|
||||
|
||||
connection_status = "✅ Connected"
|
||||
|
||||
# Get database info
|
||||
db_info = {
|
||||
'database_url': str(db_config.database_url),
|
||||
'database_type': os.getenv('DATABASE_TYPE', 'unknown'),
|
||||
'connection_status': connection_status
|
||||
}
|
||||
|
||||
# Try to get table count
|
||||
try:
|
||||
from database import Base
|
||||
table_count = len(Base.metadata.tables)
|
||||
db_info['table_count'] = table_count
|
||||
except:
|
||||
db_info['table_count'] = 'Unknown'
|
||||
|
||||
except Exception as e:
|
||||
db_info = {
|
||||
'database_url': 'Not configured',
|
||||
'database_type': 'Unknown',
|
||||
'connection_status': f'❌ Connection failed: {str(e)}',
|
||||
'table_count': 'Unknown'
|
||||
}
|
||||
|
||||
return render_template('database_status.html', db_info=db_info)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||
|
||||
260
motm_app/templates/database_setup.html
Normal file
260
motm_app/templates/database_setup.html
Normal file
@ -0,0 +1,260 @@
|
||||
{% extends "bootstrap/base.html" %}
|
||||
|
||||
{% block title %}Database Setup - MOTM Admin{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
.database-section {
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.database-section h3 {
|
||||
margin-top: 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.current-config {
|
||||
background-color: #e8f4f8;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.current-config h4 {
|
||||
margin-top: 0;
|
||||
color: #2c3e50;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Database Setup & Configuration</h1>
|
||||
<p class="lead">Configure and initialize the database for the MOTM application.</p>
|
||||
|
||||
<!-- Current Configuration Display -->
|
||||
<div class="current-config">
|
||||
<h4>Current Configuration</h4>
|
||||
<p><strong>Database Type:</strong> {{ current_config.database_type|title }}</p>
|
||||
{% if current_config.database_type == 'sqlite' %}
|
||||
<p><strong>Database File:</strong> {{ current_config.sqlite_database_path }}</p>
|
||||
{% elif current_config.database_type == 'mysql' %}
|
||||
<p><strong>Host:</strong> {{ current_config.mysql_host }}:{{ current_config.mysql_port }}</p>
|
||||
<p><strong>Database:</strong> {{ current_config.mysql_database }}</p>
|
||||
<p><strong>Username:</strong> {{ current_config.mysql_username }}</p>
|
||||
{% elif current_config.database_type == 'postgresql' %}
|
||||
<p><strong>Host:</strong> {{ current_config.postgres_host }}:{{ current_config.postgres_port }}</p>
|
||||
<p><strong>Database:</strong> {{ current_config.postgres_database }}</p>
|
||||
<p><strong>Username:</strong> {{ current_config.postgres_username }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<!-- Database Setup Form -->
|
||||
<form method="POST" action="{{ url_for('database_setup') }}">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<!-- Database Type Selection -->
|
||||
<div class="database-section">
|
||||
<h3>Database Type</h3>
|
||||
<div class="form-group">
|
||||
{{ form.database_type.label(class="control-label") }}
|
||||
{{ form.database_type(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SQLite Configuration -->
|
||||
<div class="database-section" id="sqlite-config">
|
||||
<h3>SQLite Configuration</h3>
|
||||
<div class="form-group">
|
||||
{{ form.sqlite_database_path.label(class="control-label") }}
|
||||
{{ form.sqlite_database_path(class="form-control") }}
|
||||
<small class="form-text text-muted">Path to the SQLite database file</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MySQL Configuration -->
|
||||
<div class="database-section" id="mysql-config">
|
||||
<h3>MySQL/MariaDB Configuration</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.mysql_host.label(class="control-label") }}
|
||||
{{ form.mysql_host(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.mysql_port.label(class="control-label") }}
|
||||
{{ form.mysql_port(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.mysql_database.label(class="control-label") }}
|
||||
{{ form.mysql_database(class="form-control") }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.mysql_username.label(class="control-label") }}
|
||||
{{ form.mysql_username(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.mysql_password.label(class="control-label") }}
|
||||
{{ form.mysql_password(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.mysql_charset.label(class="control-label") }}
|
||||
{{ form.mysql_charset(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PostgreSQL Configuration -->
|
||||
<div class="database-section" id="postgresql-config">
|
||||
<h3>PostgreSQL Configuration</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.postgres_host.label(class="control-label") }}
|
||||
{{ form.postgres_host(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.postgres_port.label(class="control-label") }}
|
||||
{{ form.postgres_port(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.postgres_database.label(class="control-label") }}
|
||||
{{ form.postgres_database(class="form-control") }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.postgres_username.label(class="control-label") }}
|
||||
{{ form.postgres_username(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
{{ form.postgres_password.label(class="control-label") }}
|
||||
{{ form.postgres_password(class="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Setup Options -->
|
||||
<div class="database-section">
|
||||
<h3>Setup Options</h3>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{ form.initialize_tables() }} {{ form.initialize_tables.label.text }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{ form.create_sample_data() }} {{ form.create_sample_data.label.text }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="btn-group">
|
||||
{{ form.test_connection(class="btn btn-info") }}
|
||||
{{ form.save_config(class="btn btn-primary") }}
|
||||
{{ form.initialize_database(class="btn btn-success") }}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="row" style="margin-top: 30px;">
|
||||
<div class="col-md-12">
|
||||
<a href="{{ url_for('database_status') }}" class="btn btn-default">View Database Status</a>
|
||||
<a href="{{ url_for('motm_admin') }}" class="btn btn-default">Back to MOTM Admin</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Show/hide database configuration sections based on selected type
|
||||
function toggleDatabaseConfig() {
|
||||
var dbType = document.getElementById('database_type').value;
|
||||
|
||||
// Hide all config sections
|
||||
document.getElementById('sqlite-config').style.display = 'none';
|
||||
document.getElementById('mysql-config').style.display = 'none';
|
||||
document.getElementById('postgresql-config').style.display = 'none';
|
||||
|
||||
// Show relevant config section
|
||||
if (dbType === 'sqlite') {
|
||||
document.getElementById('sqlite-config').style.display = 'block';
|
||||
} else if (dbType === 'mysql') {
|
||||
document.getElementById('mysql-config').style.display = 'block';
|
||||
} else if (dbType === 'postgresql') {
|
||||
document.getElementById('postgresql-config').style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
toggleDatabaseConfig();
|
||||
|
||||
// Add event listener for database type changes
|
||||
document.getElementById('database_type').addEventListener('change', toggleDatabaseConfig);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
162
motm_app/templates/database_status.html
Normal file
162
motm_app/templates/database_status.html
Normal file
@ -0,0 +1,162 @@
|
||||
{% extends "bootstrap/base.html" %}
|
||||
|
||||
{% block title %}Database Status - MOTM Admin{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
.status-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.status-card h3 {
|
||||
margin-top: 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
background-color: white;
|
||||
border-radius: 3px;
|
||||
border-left: 4px solid #3498db;
|
||||
}
|
||||
|
||||
.status-item.success {
|
||||
border-left-color: #27ae60;
|
||||
}
|
||||
|
||||
.status-item.error {
|
||||
border-left-color: #e74c3c;
|
||||
}
|
||||
|
||||
.status-item.warning {
|
||||
border-left-color: #f39c12;
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.status-value {
|
||||
color: #7f8c8d;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: 0 10px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Database Status</h1>
|
||||
<p class="lead">Current database configuration and connection status.</p>
|
||||
|
||||
<!-- Database Status Card -->
|
||||
<div class="status-card">
|
||||
<h3>Database Information</h3>
|
||||
|
||||
<div class="status-item {{ 'success' if 'Connected' in db_info.connection_status else 'error' }}">
|
||||
<div class="status-label">Connection Status:</div>
|
||||
<div class="status-value">{{ db_info.connection_status }}</div>
|
||||
</div>
|
||||
|
||||
<div class="status-item">
|
||||
<div class="status-label">Database Type:</div>
|
||||
<div class="status-value">{{ db_info.database_type|title }}</div>
|
||||
</div>
|
||||
|
||||
<div class="status-item">
|
||||
<div class="status-label">Database URL:</div>
|
||||
<div class="status-value">{{ db_info.database_url }}</div>
|
||||
</div>
|
||||
|
||||
<div class="status-item">
|
||||
<div class="status-label">Tables Count:</div>
|
||||
<div class="status-value">{{ db_info.table_count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="status-card">
|
||||
<h3>Quick Actions</h3>
|
||||
<div class="action-buttons">
|
||||
<a href="{{ url_for('database_setup') }}" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-cog"></i> Database Setup
|
||||
</a>
|
||||
<a href="{{ url_for('motm_admin') }}" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-arrow-left"></i> Back to MOTM Admin
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Database Tables Information -->
|
||||
{% if db_info.table_count != 'Unknown' and db_info.table_count > 0 %}
|
||||
<div class="status-card">
|
||||
<h3>Database Tables</h3>
|
||||
<p>The database contains {{ db_info.table_count }} tables. The following tables are available:</p>
|
||||
<ul>
|
||||
<li><strong>players</strong> - Player information and details</li>
|
||||
<li><strong>clubs</strong> - Hockey club information</li>
|
||||
<li><strong>teams</strong> - Team information and league details</li>
|
||||
<li><strong>match_squad</strong> - Match squad selections</li>
|
||||
<li><strong>hockey_fixtures</strong> - Match fixtures and results</li>
|
||||
<li><strong>admin_settings</strong> - Application configuration</li>
|
||||
<li><strong>motm_votes</strong> - Man of the Match voting data</li>
|
||||
<li><strong>match_comments</strong> - Match comments and feedback</li>
|
||||
<li><strong>hockey_users</strong> - User authentication data</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Configuration Help -->
|
||||
<div class="status-card">
|
||||
<h3>Configuration Help</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h4>SQLite</h4>
|
||||
<p>Best for development and small deployments. No server required.</p>
|
||||
<ul>
|
||||
<li>File-based database</li>
|
||||
<li>No installation required</li>
|
||||
<li>Good for testing</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h4>MySQL/MariaDB</h4>
|
||||
<p>Popular choice for web applications. Good performance and reliability.</p>
|
||||
<ul>
|
||||
<li>Server-based database</li>
|
||||
<li>Good for production</li>
|
||||
<li>Wide hosting support</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h4>PostgreSQL</h4>
|
||||
<p>Advanced features and excellent performance. Great for complex applications.</p>
|
||||
<ul>
|
||||
<li>Advanced SQL features</li>
|
||||
<li>Excellent performance</li>
|
||||
<li>Strong data integrity</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -55,6 +55,14 @@
|
||||
<h4 class="list-group-item-heading">Player of the Year</h4>
|
||||
<p class="list-group-item-text">View season totals and Player of the Year standings</p>
|
||||
</a>
|
||||
<a href="/admin/database-setup" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Database Setup</h4>
|
||||
<p class="list-group-item-text">Configure and initialize the database</p>
|
||||
</a>
|
||||
<a href="/admin/database-status" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Database Status</h4>
|
||||
<p class="list-group-item-text">View current database configuration and status</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user