- Create MapRoute database records for all GPX files for map visualization - Populate route statistics (distance, elevation, coordinates) from GPX parsing - Update GPX file statistics to mirror MapRoute data for post detail pages - Enable /community/api/routes endpoint to return proper route data for map iframe - Fix post detail page GPX statistics display This resolves the issue where the community map showed '2 routes discovered' but routes weren't actually rendering on the Leaflet.js map visualization. Changes: - Dockerfile: Updated init script paths and added migrate-db call - app/__init__.py: Added admin user auto-creation with error handling - app/routes/community.py: Added debug logging and API route for map data - docker-compose.yml: Simplified to use .env for environment variables - run.py: Added comprehensive database schema migration command
128 lines
4.7 KiB
Python
128 lines
4.7 KiB
Python
from flask import Flask
|
|
from app.extensions import db, migrate, login_manager, mail
|
|
from app.utils.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 <br> tags"""
|
|
if text is None:
|
|
return ''
|
|
return text.replace('\n', '<br>')
|
|
|
|
# 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')
|
|
|
|
from app.routes.chat import chat
|
|
app.register_blueprint(chat, url_prefix='/chat')
|
|
|
|
from app.routes.chat_api import chat_api
|
|
app.register_blueprint(chat_api, url_prefix='/api/v1/chat')
|
|
|
|
# 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:
|
|
try:
|
|
# Check if users table exists first
|
|
db.session.execute('SELECT 1 FROM users LIMIT 1')
|
|
# If we got here, table exists, now check for admin user
|
|
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.")
|
|
except Exception as e:
|
|
# Table doesn't exist yet, skip admin creation
|
|
print(f"[INFO] Database not initialized yet. Skipping admin creation. Run migrations with: flask db upgrade")
|
|
else:
|
|
print("[INFO] ADMIN_EMAIL, ADMIN_NICKNAME, or ADMIN_PASSWORD not set in .env. Skipping admin creation.")
|
|
|
|
return app
|