229 lines
7.5 KiB
Python
Executable File
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()
|