From da57e066aee3c39c7adf13a4a61575f5dd154d1a Mon Sep 17 00:00:00 2001 From: Scheianu Ionut Date: Sun, 29 Jun 2025 17:04:23 +0300 Subject: [PATCH] final update --- Dockerfile | 1 + __pycache__/app.cpython-312.pyc | Bin 38513 -> 36644 bytes app.py | 18 ++++++++++- entrypoint.sh | 26 ++++++++++++++-- requirements.txt | 53 ++++++++++++++++++++++---------- 5 files changed, 78 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index 36f1c1f..7b78d42 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,7 @@ WORKDIR /app # Install system dependencies, including Rust and build tools RUN apt-get update && apt-get install -y \ libreoffice poppler-utils ffmpeg \ + libpoppler-cpp-dev libmagic1 \ libffi-dev libssl-dev g++ curl libjpeg-dev zlib1g-dev \ libxml2-dev libxslt-dev build-essential cargo \ && rm -rf /var/lib/apt/lists/* diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc index 20adede5ee2c2482e5545d6445189b9b71d59ebe..7cfd5c34a4d1c1631b94323981f3fa49ac9063f0 100644 GIT binary patch delta 10689 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 diff --git a/app.py b/app.py index 6ddb6cf..89eed42 100644 --- a/app.py +++ b/app.py @@ -622,6 +622,22 @@ def debug_content_positions(group_id): return jsonify(content_data) +@app.cli.command("create-admin") +@click.option("--username", default="admin", help="Admin username") +@click.option("--password", help="Admin password") +def create_admin(username, password): + """Create an admin user.""" + from models import User + from extensions import bcrypt + + hashed_password = bcrypt.generate_password_hash(password).decode('utf-8') + user = User(username=username, password=hashed_password, role='admin') + db.session.add(user) + db.session.commit() + print(f"Admin user '{username}' created successfully.") + + # Add this at the end of app.py if __name__ == '__main__': - app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file + app.run(debug=True, host='0.0.0.0', port=5000) + diff --git a/entrypoint.sh b/entrypoint.sh index 0d62989..9739953 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,11 +1,31 @@ #!/bin/bash set -e -# Initialize the database and run migrations -flask db upgrade - # Create necessary directories mkdir -p static/uploads static/resurse +mkdir -p instance +# Check if database exists +if [ ! -f instance/dashboard.db ]; then + echo "No database found, initializing..." + + # Initialize the database + flask db init + flask db migrate -m "Initial migration" + flask db upgrade + + # Create admin user if environment variables are set + if [ -n "$ADMIN_USER" ] && [ -n "$ADMIN_PASSWORD" ]; then + echo "Creating admin user: $ADMIN_USER" + flask create-admin --username "$ADMIN_USER" --password "$ADMIN_PASSWORD" + else + echo "Warning: ADMIN_USER or ADMIN_PASSWORD not set, skipping admin creation" + fi +else + echo "Existing database found, applying migrations..." + flask db upgrade +fi + +echo "Starting DigiServer..." # Start the application exec flask run --host=0.0.0.0 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2326d7a..3e41b2d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,25 +1,46 @@ -alembic==1.14.1 -bcrypt==4.2.1 -blinker==1.9.0 -click==8.1.8 +# Core Flask Flask==3.1.0 +Werkzeug==3.1.3 +Jinja2==3.1.5 +itsdangerous==2.2.0 +click==8.1.8 +blinker==1.9.0 + +# Flask Extensions +Flask-SQLAlchemy==3.1.1 +Flask-Migrate==4.1.0 Flask-Bcrypt==1.0.1 Flask-Login==0.6.3 -Flask-Migrate==4.1.0 -Flask-SQLAlchemy==3.1.1 -greenlet==3.1.1 -itsdangerous==2.2.0 -Jinja2==3.1.5 -Mako==1.3.8 -MarkupSafe==3.0.2 + +# Database SQLAlchemy==2.0.37 -typing_extensions==4.12.2 -Werkzeug==3.1.3 -gunicorn==20.1.0 +alembic==1.14.1 +Mako==1.3.8 +greenlet==3.1.1 + +# File Processing pdf2image==1.17.0 +PyPDF2==3.0.1 python-pptx==0.6.21 -cairosvg==2.7.0 Pillow==10.0.1 +cairosvg==2.7.0 ffmpeg-python==0.2.0 python-magic==0.4.27 -PyPDF2==3.0.1 + +# Security +bcrypt==4.2.1 +Flask-Talisman==1.1.0 +Flask-Cors==4.0.0 + +# Production Server +gunicorn==20.1.0 +gevent==23.9.1 + +# Monitoring & Performance +prometheus-flask-exporter==0.22.4 +sentry-sdk[flask]==1.40.0 + +# Utilities +typing_extensions==4.12.2 +MarkupSafe==3.0.2 +python-dotenv==1.0.1