mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-23 23:00:15 -05:00
1b3a703c04
- Remove redundant documentation files (DATABASE_INIT_FIX_*.md, TIMEZONE_FIX_README.md) - Delete unused Docker files (Dockerfile.test, Dockerfile.combined, docker-compose.yml) - Remove obsolete deployment scripts (deploy.sh) and unused files (index.html, _config.yml) - Clean up logs directory (remove 2MB timetracker.log, keep .gitkeep) - Remove .pytest_cache directory - Consolidate Docker setup to two main container types: * Simple container (recommended for production) * Public container (for development/testing) - Enhance timezone support in admin settings: * Add 100+ timezone options organized by region * Implement real-time timezone preview with current time display * Add timezone offset calculation and display * Remove search functionality for cleaner interface * Update timezone utility functions for database-driven configuration - Update documentation: * Revise README.md to reflect current project state * Add comprehensive timezone features documentation * Update Docker deployment instructions * Create PROJECT_STRUCTURE.md for project overview * Remove references to deleted files - Improve project structure: * Streamlined file organization * Better maintainability and focus * Preserved all essential functionality * Cleaner deployment options
148 lines
4.9 KiB
Bash
148 lines
4.9 KiB
Bash
#!/bin/bash
|
|
set -e
|
|
cd /app
|
|
export FLASK_APP=app
|
|
|
|
echo "=== Starting TimeTracker ==="
|
|
|
|
echo "Waiting for database to be ready..."
|
|
# Wait for Postgres to be ready
|
|
python - <<"PY"
|
|
import os
|
|
import time
|
|
import sys
|
|
from sqlalchemy import create_engine, text
|
|
from sqlalchemy.exc import OperationalError
|
|
|
|
url = os.getenv("DATABASE_URL", "")
|
|
if url.startswith("postgresql"):
|
|
for attempt in range(30):
|
|
try:
|
|
engine = create_engine(url, pool_pre_ping=True)
|
|
with engine.connect() as conn:
|
|
conn.execute(text("SELECT 1"))
|
|
print("Database connection established successfully")
|
|
break
|
|
except Exception as e:
|
|
print(f"Waiting for database... (attempt {attempt+1}/30): {e}")
|
|
time.sleep(2)
|
|
else:
|
|
print("Database not ready after waiting, exiting...")
|
|
sys.exit(1)
|
|
else:
|
|
print("No PostgreSQL database configured, skipping connection check")
|
|
PY
|
|
|
|
echo "Checking if database is initialized..."
|
|
# Check if database is initialized by looking for tables
|
|
python - <<"PY"
|
|
import os
|
|
import sys
|
|
from sqlalchemy import create_engine, text, inspect
|
|
|
|
url = os.getenv("DATABASE_URL", "")
|
|
if url.startswith("postgresql"):
|
|
try:
|
|
engine = create_engine(url, pool_pre_ping=True)
|
|
inspector = inspect(engine)
|
|
|
|
# Check if our main tables exist
|
|
existing_tables = inspector.get_table_names()
|
|
required_tables = ["users", "projects", "time_entries", "settings"]
|
|
|
|
missing_tables = [table for table in required_tables if table not in existing_tables]
|
|
|
|
if missing_tables:
|
|
print(f"Database not fully initialized. Missing tables: {missing_tables}")
|
|
print("Will initialize database...")
|
|
sys.exit(1) # Exit with error to trigger initialization
|
|
else:
|
|
print("Database is already initialized with all required tables")
|
|
# Check if migration is needed
|
|
try:
|
|
columns = inspector.get_columns("time_entries")
|
|
column_names = [col['name'] for col in columns]
|
|
has_old_fields = 'start_utc' in column_names or 'end_utc' in column_names
|
|
if has_old_fields:
|
|
print("Migration needed for field names")
|
|
sys.exit(2) # Special exit code for migration
|
|
else:
|
|
print("No migration needed")
|
|
sys.exit(0) # Exit successfully, no initialization needed
|
|
except Exception as e:
|
|
print(f"Error checking migration status: {e}")
|
|
sys.exit(0) # Assume no migration needed
|
|
|
|
except Exception as e:
|
|
print(f"Error checking database initialization: {e}")
|
|
sys.exit(1)
|
|
else:
|
|
print("No PostgreSQL database configured, skipping initialization check")
|
|
sys.exit(0)
|
|
PY
|
|
|
|
if [ $? -eq 1 ]; then
|
|
echo "Initializing database with SQL-based script..."
|
|
python /app/docker/init-database-sql.py
|
|
if [ $? -ne 0 ]; then
|
|
echo "Database initialization failed. Exiting to prevent infinite loop."
|
|
exit 1
|
|
fi
|
|
echo "Database initialized successfully"
|
|
|
|
# Run migration if needed
|
|
echo "Running database migration..."
|
|
python /app/docker/migrate-field-names.py
|
|
|
|
# Verify initialization worked
|
|
echo "Verifying database initialization..."
|
|
elif [ $? -eq 2 ]; then
|
|
echo "Running database migration for existing database..."
|
|
python /app/docker/migrate-field-names.py
|
|
if [ $? -ne 0 ]; then
|
|
echo "Database migration failed. Exiting."
|
|
exit 1
|
|
fi
|
|
echo "Database migration completed successfully"
|
|
python - <<"PY"
|
|
import os
|
|
import sys
|
|
from sqlalchemy import create_engine, text, inspect
|
|
|
|
url = os.getenv("DATABASE_URL", "")
|
|
if url.startswith("postgresql"):
|
|
try:
|
|
engine = create_engine(url, pool_pre_ping=True)
|
|
inspector = inspect(engine)
|
|
|
|
existing_tables = inspector.get_table_names()
|
|
required_tables = ["users", "projects", "time_entries", "settings"]
|
|
|
|
missing_tables = [table for table in required_tables if table not in existing_tables]
|
|
|
|
if missing_tables:
|
|
print(f"Database verification failed. Missing tables: {missing_tables}")
|
|
sys.exit(1)
|
|
else:
|
|
print("Database verification successful")
|
|
sys.exit(0)
|
|
|
|
except Exception as e:
|
|
print(f"Error verifying database: {e}")
|
|
sys.exit(1)
|
|
else:
|
|
print("No PostgreSQL database configured, skipping verification")
|
|
sys.exit(0)
|
|
PY
|
|
|
|
if [ $? -eq 1 ]; then
|
|
echo "Database verification failed after initialization. Exiting to prevent infinite loop."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "Database already initialized, skipping initialization"
|
|
fi
|
|
|
|
echo "Starting application..."
|
|
exec gunicorn --bind 0.0.0.0:8080 --worker-class eventlet --workers 1 --timeout 120 "app:create_app()"
|