mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-20 11:29:57 -06:00
- Add organized screenshot sections for better visual presentation - Include all 12 available screenshots from assets/screenshots/ - Group screenshots into logical categories: * Core Application Views (Dashboard, Projects, Tasks, Clients) * Management & Analytics (Reports, Visual Analytics, Task Management, Admin) * Data Entry & Creation (Log Time, New Task, New Client, New Project) - Improve visual layout with proper spacing and responsive design - Enhance user experience by showcasing full application capabilities
132 lines
5.2 KiB
Python
132 lines
5.2 KiB
Python
import os
|
|
import click
|
|
from flask.cli import with_appcontext
|
|
from app import db
|
|
from app.models import User, Project, TimeEntry, Settings, Client
|
|
from datetime import datetime, timedelta
|
|
import shutil
|
|
|
|
def register_cli_commands(app):
|
|
"""Register CLI commands for the application"""
|
|
|
|
@app.cli.command()
|
|
@with_appcontext
|
|
def init_db():
|
|
"""Initialize the database with tables and default data"""
|
|
from app.models import Settings, User
|
|
|
|
# Create all tables
|
|
db.create_all()
|
|
|
|
# Initialize settings if they don't exist
|
|
if not Settings.query.first():
|
|
settings = Settings()
|
|
db.session.add(settings)
|
|
db.session.commit()
|
|
click.echo("Database initialized with default settings")
|
|
|
|
# Create admin user if it doesn't exist
|
|
admin_username = os.getenv('ADMIN_USERNAMES', 'admin').split(',')[0]
|
|
if not User.query.filter_by(username=admin_username).first():
|
|
admin_user = User(username=admin_username, role='admin')
|
|
admin_user.is_active = True
|
|
db.session.add(admin_user)
|
|
db.session.commit()
|
|
click.echo(f"Created admin user: {admin_username}")
|
|
|
|
click.echo("Database initialization complete!")
|
|
|
|
@app.cli.command()
|
|
@with_appcontext
|
|
def create_admin():
|
|
"""Create an admin user"""
|
|
username = click.prompt("Enter admin username")
|
|
if not username:
|
|
click.echo("Username cannot be empty")
|
|
return
|
|
|
|
if User.query.filter_by(username=username).first():
|
|
click.echo(f"User {username} already exists")
|
|
return
|
|
|
|
user = User(username=username, role='admin')
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
click.echo(f"Created admin user: {username}")
|
|
|
|
@app.cli.command()
|
|
@with_appcontext
|
|
def backup_db():
|
|
"""Create a backup of the database"""
|
|
from app.config import Config
|
|
|
|
url = Config.SQLALCHEMY_DATABASE_URI
|
|
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
|
|
if url.startswith('sqlite:///'):
|
|
# SQLite file copy
|
|
db_path = url.replace('sqlite:///', '')
|
|
if not os.path.exists(db_path):
|
|
click.echo(f"Database file not found: {db_path}")
|
|
return
|
|
backup_dir = os.path.join(os.path.dirname(db_path), 'backups')
|
|
os.makedirs(backup_dir, exist_ok=True)
|
|
backup_filename = f"timetracker_backup_{timestamp}.db"
|
|
backup_path = os.path.join(backup_dir, backup_filename)
|
|
shutil.copy2(db_path, backup_path)
|
|
click.echo(f"Database backed up to: {backup_path}")
|
|
else:
|
|
click.echo("For PostgreSQL, please use pg_dump, e.g.: pg_dump --format=custom --dbname=\"$DATABASE_URL\" --file=backup.dump")
|
|
|
|
# Clean up old backups
|
|
if url.startswith('sqlite:///'):
|
|
try:
|
|
backup_retention_days = int(os.getenv('BACKUP_RETENTION_DAYS', 30))
|
|
cutoff_date = datetime.now() - timedelta(days=backup_retention_days)
|
|
|
|
for backup_file in os.listdir(backup_dir):
|
|
backup_file_path = os.path.join(backup_dir, backup_file)
|
|
if os.path.isfile(backup_file_path):
|
|
file_time = datetime.fromtimestamp(os.path.getctime(backup_file_path))
|
|
if file_time < cutoff_date:
|
|
os.remove(backup_file_path)
|
|
click.echo(f"Removed old backup: {backup_file}")
|
|
except Exception as e:
|
|
click.echo(f"Warning: Could not clean up old backups: {e}")
|
|
|
|
@app.cli.command()
|
|
@with_appcontext
|
|
def migrate_to_flask_migrate():
|
|
"""Migrate from custom migration system to Flask-Migrate"""
|
|
click.echo("This command is deprecated. Use the migration management script instead:")
|
|
click.echo("python migrations/manage_migrations.py")
|
|
click.echo("\nOr use Flask-Migrate commands directly:")
|
|
click.echo("flask db init # Initialize migrations (first time only)")
|
|
click.echo("flask db migrate # Create a new migration")
|
|
click.echo("flask db upgrade # Apply pending migrations")
|
|
click.echo("flask db downgrade # Rollback last migration")
|
|
click.echo("flask db current # Show current migration")
|
|
click.echo("flask db history # Show migration history")
|
|
|
|
@app.cli.command()
|
|
@with_appcontext
|
|
def db_status():
|
|
"""Show database migration status"""
|
|
try:
|
|
from flask_migrate import current
|
|
current()
|
|
except Exception as e:
|
|
click.echo(f"Error getting migration status: {e}")
|
|
click.echo("Make sure Flask-Migrate is properly initialized")
|
|
|
|
@app.cli.command()
|
|
@with_appcontext
|
|
def db_history():
|
|
"""Show database migration history"""
|
|
try:
|
|
from flask_migrate import history
|
|
history()
|
|
except Exception as e:
|
|
click.echo(f"Error getting migration history: {e}")
|
|
click.echo("Make sure Flask-Migrate is properly initialized")
|