Files
fotohost/app/bootstrap.py
T

164 lines
4.6 KiB
Python

import os
import re
from sqlalchemy import inspect, text
from app import db
from app.models import User, UserGroup
def ensure_schema():
inspector = inspect(db.engine)
tables = inspector.get_table_names()
if "photos" in tables:
db.session.execute(
text(
"ALTER TABLE photos ADD COLUMN IF NOT EXISTS "
"user_id INTEGER REFERENCES users(id)"
)
)
db.session.commit()
if "users" in tables and "user_groups" in tables:
db.session.execute(
text(
"ALTER TABLE users ADD COLUMN IF NOT EXISTS "
"group_id INTEGER REFERENCES user_groups(id)"
)
)
db.session.commit()
def ensure_default_group(app):
default_quota = int(os.getenv("DEFAULT_GROUP_QUOTA_MB", "100"))
default_max_folders = int(os.getenv("DEFAULT_GROUP_MAX_FOLDERS", "10"))
default_max_photos = int(os.getenv("DEFAULT_GROUP_MAX_PHOTOS", "500"))
default_group = UserGroup.query.filter_by(is_default=True).first()
if not default_group:
default_group = UserGroup.query.filter_by(slug="users").first()
if default_group:
default_group.is_default = True
else:
default_group = UserGroup(
name="Пользователи",
slug="users",
disk_quota_mb=default_quota,
max_folders=default_max_folders,
max_photos=default_max_photos,
is_default=True,
)
db.session.add(default_group)
db.session.commit()
app.logger.info(
"Default user group 'users' created (quota=%s MB, folders=%s, photos=%s)",
default_quota,
default_max_folders,
default_max_photos,
)
User.query.filter(User.group_id.is_(None)).update({"group_id": default_group.id})
db.session.commit()
def ensure_group_limit_columns():
inspector = inspect(db.engine)
if "user_groups" not in inspector.get_table_names():
return
db.session.execute(
text(
"ALTER TABLE user_groups ADD COLUMN IF NOT EXISTS "
"max_folders INTEGER NOT NULL DEFAULT 10"
)
)
db.session.execute(
text(
"ALTER TABLE user_groups ADD COLUMN IF NOT EXISTS "
"max_photos INTEGER NOT NULL DEFAULT 500"
)
)
db.session.commit()
def ensure_site_settings(app):
from app.models import SiteSettings
if SiteSettings.query.get(1) is None:
db.session.add(SiteSettings(id=1))
db.session.commit()
app.logger.info("Site settings initialized")
def ensure_photo_storage_column():
inspector = inspect(db.engine)
if "photos" not in inspector.get_table_names():
return
db.session.execute(
text(
"ALTER TABLE photos ADD COLUMN IF NOT EXISTS "
"storage_backend VARCHAR(20) DEFAULT 'local'"
)
)
db.session.commit()
def run_schema_migrations():
ensure_schema()
ensure_group_limit_columns()
from app.folders import ensure_folder_schema
ensure_folder_schema()
ensure_photo_storage_column()
def run_database_setup(app):
run_schema_migrations()
ensure_default_group(app)
ensure_site_settings(app)
create_first_admin(app)
def slugify(name):
slug = re.sub(r"[^a-z0-9]+", "-", name.lower().strip())
slug = slug.strip("-") or "group"
return slug[:80]
def create_first_admin(app):
username = os.getenv("ADMIN_USERNAME", "").strip()
email = os.getenv("ADMIN_EMAIL", "").strip()
password = os.getenv("ADMIN_PASSWORD", "").strip()
if not username or not email or not password:
app.logger.info("ADMIN_* env vars not set — first admin was not created automatically")
return None
if User.query.filter_by(is_admin=True).first():
return None
default_group = UserGroup.query.filter_by(is_default=True).first()
if User.query.filter_by(username=username).first():
user = User.query.filter_by(username=username).first()
user.is_admin = True
user.set_password(password)
if default_group and not user.group_id:
user.group_id = default_group.id
db.session.commit()
app.logger.info("Existing user '%s' promoted to admin", username)
return user
user = User(
username=username,
email=email,
is_admin=True,
group_id=default_group.id if default_group else None,
)
user.set_password(password)
db.session.add(user)
db.session.commit()
app.logger.info("First admin '%s' created", username)
return user