from flask import Flask from app.extensions import db, migrate, login_manager, mail from config import config import os def create_app(config_name=None): app = Flask(__name__) config_name = config_name or os.environ.get('FLASK_CONFIG') or 'default' app.config.from_object(config[config_name]) # Initialize extensions db.init_app(app) migrate.init_app(app, db) login_manager.init_app(app) mail.init_app(app) # Configure login manager login_manager.login_view = 'auth.login' login_manager.login_message = 'Please log in to access this page.' login_manager.login_message_category = 'info' @login_manager.user_loader def load_user(user_id): from app.models import User return User.query.get(int(user_id)) # Page view tracking @app.before_request def track_page_views(): from app.models import PageView from flask import request from flask_login import current_user import re # Skip tracking for static files, admin API calls, and certain paths if (request.endpoint and (request.endpoint.startswith('static') or request.endpoint.startswith('admin.api') or request.path.startswith('/favicon') or request.path.startswith('/_'))) : return # Extract post_id from community post URLs post_id = None if request.endpoint == 'community.post_detail': post_id = request.view_args.get('post_id') # Create page view record page_view = PageView( path=request.path, user_agent=request.headers.get('User-Agent', ''), ip_address=request.remote_addr, referer=request.headers.get('Referer'), user_id=current_user.id if current_user.is_authenticated else None, post_id=post_id ) try: db.session.add(page_view) db.session.commit() except Exception: # Don't let page view tracking break the app db.session.rollback() # Import models from app.models import User, Post, PostImage, GPXFile, Comment, Like, PageView # Add custom template filters @app.template_filter('nl2br') def nl2br_filter(text): """Convert newlines to
tags""" if text is None: return '' return text.replace('\n', '
') # Register blueprints from app.routes.main import main app.register_blueprint(main) from app.routes.auth import auth app.register_blueprint(auth, url_prefix='/auth') from app.routes.community import community app.register_blueprint(community, url_prefix='/community') from app.routes.admin import admin app.register_blueprint(admin, url_prefix='/admin') # Create upload directories upload_dir = os.path.join(app.instance_path, 'uploads') os.makedirs(upload_dir, exist_ok=True) os.makedirs(os.path.join(upload_dir, 'images'), exist_ok=True) os.makedirs(os.path.join(upload_dir, 'gpx'), exist_ok=True) # --- Initial Admin Creation from .env --- from app.models import User with app.app_context(): admin_email = os.environ.get('ADMIN_EMAIL') admin_nickname = os.environ.get('ADMIN_NICKNAME') admin_password = os.environ.get('ADMIN_PASSWORD') if admin_email and admin_nickname and admin_password: if not User.query.filter_by(email=admin_email).first(): user = User(nickname=admin_nickname, email=admin_email, is_admin=True, is_active=True) user.set_password(admin_password) db.session.add(user) db.session.commit() print(f"[INFO] Admin user {admin_nickname} <{admin_email}> created from .env.") else: print(f"[INFO] Admin with email {admin_email} already exists.") else: print("[INFO] ADMIN_EMAIL, ADMIN_NICKNAME, or ADMIN_PASSWORD not set in .env. Skipping admin creation.") return app