Fix Interactive Route Map: Create MapRoute records from GPX files

- 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
This commit is contained in:
2025-12-31 18:46:21 +02:00
parent 16cc3fb0ba
commit f8508a436a
5 changed files with 142 additions and 90 deletions

View File

@@ -100,22 +100,28 @@ def create_app(config_name=None):
os.makedirs(os.path.join(upload_dir, 'gpx'), exist_ok=True)
# --- Initial Admin Creation from .env ---
# Temporarily disabled for migration setup
# 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.")
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

View File

@@ -15,6 +15,32 @@ import gpxpy
community = Blueprint('community', __name__)
@community.route('/debug')
def debug():
"""Debug endpoint to check posts"""
posts = Post.query.filter_by(published=True).order_by(Post.created_at.desc()).paginate(
page=1, per_page=12, error_out=False
)
debug_info = {
'total_posts': posts.total,
'items_count': len(posts.items),
'pages': posts.pages,
'posts': []
}
for post in posts.items:
debug_info['posts'].append({
'id': post.id,
'title': post.title,
'published': post.published,
'author': post.author.nickname if post.author else None,
'images_count': post.images.count(),
'media_folder': post.media_folder
})
return jsonify(debug_info)
@community.route('/')
def index():
"""Community main page with map and posts"""
@@ -26,6 +52,11 @@ def index():
# Get posts with GPX files for map display
posts_with_routes = Post.query.filter_by(published=True).join(GPXFile).all()
# Debug logging
current_app.logger.info(f"Community index: Found {posts.total} total posts, {len(posts.items)} on page {page}")
for post in posts.items:
current_app.logger.info(f" - Post {post.id}: {post.title}, images: {post.images.count()}")
return render_template('community/index.html', posts=posts, posts_with_routes=posts_with_routes)
@community.route('/test-map')