#!/usr/bin/env python3 """ Map Route Management Script Utility for managing map routes in the database """ import sys import os from flask import Flask # Add the project root to Python path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from app import create_app, db from app.models import Post, GPXFile, MapRoute, User from app.utils.gpx_processor import create_map_route_from_gpx, process_post_approval def show_help(): """Show available commands""" print(""" πŸ—ΊοΈ Map Route Management Script Available commands: list - List all map routes create - Create map route for a specific post recreate - Recreate map route for a specific post recreate-all - Recreate all map routes stats - Show database statistics cleanup - Remove map routes for unpublished posts help - Show this help message Examples: python manage_routes.py list python manage_routes.py create 1 python manage_routes.py recreate-all python manage_routes.py stats """) def list_routes(): """List all map routes""" app = create_app() with app.app_context(): routes = MapRoute.query.join(Post).all() if not routes: print("❌ No map routes found") return print(f"πŸ“ Found {len(routes)} map routes:\n") print("ID | Post | Title | Author | Published | Points | Distance") print("-" * 70) for route in routes: status = "βœ…" if route.post.published else "❌" print(f"{route.id:2d} | {route.post_id:4d} | {route.post.title[:20]:20s} | {route.post.author.nickname[:10]:10s} | {status:2s} | {route.simplified_points:6d} | {route.total_distance:7.2f} km") def create_route(post_id): """Create map route for a specific post""" app = create_app() with app.app_context(): post = Post.query.get(post_id) if not post: print(f"❌ Post {post_id} not found") return False gpx_files = GPXFile.query.filter_by(post_id=post_id).all() if not gpx_files: print(f"❌ No GPX files found for post {post_id}") return False print(f"πŸ”„ Creating map route for post {post_id}: {post.title}") success = create_map_route_from_gpx(gpx_files[0].id) if success: print(f"βœ… Successfully created map route for post {post_id}") else: print(f"❌ Failed to create map route for post {post_id}") return success def recreate_route(post_id): """Recreate map route for a specific post""" app = create_app() with app.app_context(): # Delete existing route existing = MapRoute.query.filter_by(post_id=post_id).first() if existing: db.session.delete(existing) db.session.commit() print(f"πŸ—‘οΈ Deleted existing map route for post {post_id}") # Create new route return create_route(post_id) def recreate_all_routes(): """Recreate all map routes""" app = create_app() with app.app_context(): # Get all posts with GPX files posts_with_gpx = db.session.query(Post).join(GPXFile).distinct().all() if not posts_with_gpx: print("❌ No posts with GPX files found") return print(f"πŸ”„ Recreating map routes for {len(posts_with_gpx)} posts...") # Delete all existing routes MapRoute.query.delete() db.session.commit() print("πŸ—‘οΈ Deleted all existing map routes") success_count = 0 error_count = 0 for post in posts_with_gpx: print(f"\nπŸ”„ Processing post {post.id}: {post.title}") success = process_post_approval(post.id) if success: success_count += 1 else: error_count += 1 print(f"\nπŸ“Š Results:") print(f"βœ… Successfully processed: {success_count}") print(f"❌ Errors: {error_count}") print(f"πŸ“ Total posts: {len(posts_with_gpx)}") def show_stats(): """Show database statistics""" app = create_app() with app.app_context(): total_posts = Post.query.count() published_posts = Post.query.filter_by(published=True).count() posts_with_gpx = db.session.query(Post).join(GPXFile).distinct().count() total_routes = MapRoute.query.count() published_routes = MapRoute.query.join(Post).filter(Post.published == True).count() print("πŸ“Š Database Statistics:") print(f" πŸ“ Total posts: {total_posts}") print(f" βœ… Published posts: {published_posts}") print(f" πŸ—ΊοΈ Posts with GPX: {posts_with_gpx}") print(f" πŸ“ Total map routes: {total_routes}") print(f" 🌍 Published routes: {published_routes}") if total_routes > 0: routes = MapRoute.query.all() total_points = sum(r.total_points for r in routes) simplified_points = sum(r.simplified_points for r in routes) total_distance = sum(r.total_distance for r in routes) print(f"\n🎯 Route Statistics:") print(f" πŸ“Š Total coordinate points: {total_points:,}") print(f" 🎯 Simplified points: {simplified_points:,}") print(f" πŸ“ Total distance: {total_distance:.2f} km") print(f" πŸ—œοΈ Compression ratio: {simplified_points/total_points*100:.1f}%") def cleanup_routes(): """Remove map routes for unpublished posts""" app = create_app() with app.app_context(): unpublished_routes = MapRoute.query.join(Post).filter(Post.published == False).all() if not unpublished_routes: print("βœ… No unpublished routes to clean up") return print(f"πŸ—‘οΈ Found {len(unpublished_routes)} routes for unpublished posts") for route in unpublished_routes: print(f" Removing route for post {route.post_id}: {route.post.title}") db.session.delete(route) db.session.commit() print(f"βœ… Cleaned up {len(unpublished_routes)} routes") def main(): if len(sys.argv) < 2: show_help() return command = sys.argv[1].lower() if command == 'help': show_help() elif command == 'list': list_routes() elif command == 'create': if len(sys.argv) < 3: print("❌ Please provide a post ID") print("Usage: python manage_routes.py create ") return try: post_id = int(sys.argv[2]) create_route(post_id) except ValueError: print("❌ Invalid post ID. Please provide a number.") elif command == 'recreate': if len(sys.argv) < 3: print("❌ Please provide a post ID") print("Usage: python manage_routes.py recreate ") return try: post_id = int(sys.argv[2]) recreate_route(post_id) except ValueError: print("❌ Invalid post ID. Please provide a number.") elif command == 'recreate-all': recreate_all_routes() elif command == 'stats': show_stats() elif command == 'cleanup': cleanup_routes() else: print(f"❌ Unknown command: {command}") show_help() if __name__ == "__main__": main()