c1aac7ecac
Co-authored-by: Cursor <cursoragent@cursor.com>
127 lines
3.7 KiB
Python
127 lines
3.7 KiB
Python
import os
|
|
|
|
from flask import Flask
|
|
from flask_login import LoginManager
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
db = SQLAlchemy()
|
|
login_manager = LoginManager()
|
|
login_manager.login_view = "auth.login"
|
|
login_manager.login_message = "Войдите для доступа к этой странице."
|
|
login_manager.login_message_category = "error"
|
|
|
|
|
|
@login_manager.user_loader
|
|
def load_user(user_id):
|
|
from app.models import User
|
|
|
|
return db.session.get(User, int(user_id))
|
|
|
|
|
|
def create_app():
|
|
app = Flask(__name__)
|
|
|
|
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY", "dev-secret-change-me")
|
|
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv(
|
|
"DATABASE_URL",
|
|
"postgresql://photohost:photohost_secret@localhost:5432/photohost",
|
|
)
|
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
|
app.config["UPLOAD_FOLDER"] = os.getenv("UPLOAD_FOLDER", "uploads")
|
|
app.config["MAX_CONTENT_LENGTH"] = int(os.getenv("MAX_UPLOAD_MB", "10")) * 1024 * 1024
|
|
app.config["ALLOWED_EXTENSIONS"] = {"png", "jpg", "jpeg", "gif", "webp", "bmp"}
|
|
app.config["GIT_REPO_PATH"] = os.getenv("GIT_REPO_PATH", "/repo")
|
|
app.config["ALLOW_GIT_DEPLOY"] = os.getenv("ALLOW_GIT_DEPLOY", "false").lower() in (
|
|
"1",
|
|
"true",
|
|
"yes",
|
|
)
|
|
app.config["DEFAULT_GROUP_QUOTA_MB"] = int(os.getenv("DEFAULT_GROUP_QUOTA_MB", "100"))
|
|
|
|
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
|
|
|
|
db.init_app(app)
|
|
login_manager.init_app(app)
|
|
|
|
from .routes import bp as main_bp, cabinet_bp
|
|
from .auth import bp as auth_bp
|
|
from .admin import bp as admin_bp
|
|
from .folders import bp as folders_bp
|
|
|
|
app.register_blueprint(main_bp)
|
|
app.register_blueprint(cabinet_bp)
|
|
app.register_blueprint(auth_bp)
|
|
app.register_blueprint(admin_bp)
|
|
app.register_blueprint(folders_bp)
|
|
|
|
register_cli(app)
|
|
|
|
with app.app_context():
|
|
from app.models import ( # noqa: F401
|
|
Folder,
|
|
FolderInvite,
|
|
FolderMember,
|
|
PasswordResetToken,
|
|
Photo,
|
|
SiteSettings,
|
|
User,
|
|
UserGroup,
|
|
)
|
|
|
|
db.create_all()
|
|
from app.bootstrap import (
|
|
create_first_admin,
|
|
ensure_default_group,
|
|
ensure_photo_storage_column,
|
|
ensure_schema,
|
|
ensure_site_settings,
|
|
)
|
|
from app.folders import ensure_folder_schema
|
|
|
|
ensure_schema()
|
|
ensure_default_group(app)
|
|
ensure_folder_schema()
|
|
ensure_site_settings(app)
|
|
ensure_photo_storage_column()
|
|
create_first_admin(app)
|
|
|
|
return app
|
|
|
|
|
|
def register_cli(app):
|
|
@app.cli.command("create-admin")
|
|
def create_admin_command():
|
|
"""Create or update admin user interactively."""
|
|
from getpass import getpass
|
|
|
|
from app.models import User
|
|
|
|
username = input("Username: ").strip()
|
|
email = input("Email: ").strip()
|
|
password = getpass("Password: ")
|
|
password2 = getpass("Confirm password: ")
|
|
|
|
if not username or not email or not password:
|
|
print("All fields are required.")
|
|
return
|
|
if password != password2:
|
|
print("Passwords do not match.")
|
|
return
|
|
|
|
user = User.query.filter_by(username=username).first()
|
|
if user:
|
|
user.email = email
|
|
user.is_admin = True
|
|
user.set_password(password)
|
|
print(f"User '{username}' updated and promoted to admin.")
|
|
else:
|
|
user = User(username=username, email=email, is_admin=True)
|
|
user.set_password(password)
|
|
db.session.add(user)
|
|
print(f"Admin '{username}' created.")
|
|
|
|
db.session.commit()
|