Files
moto-adv-website/app/utils/manage_routes.py

229 lines
7.5 KiB
Python
Executable File

#!/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 <post_id> - Create map route for a specific post
recreate <post_id> - 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 <post_id>")
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 <post_id>")
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()