Move config.py, create_admin.py, manage_media.py, manage_routes.py to app/utils/ for better organization
This commit is contained in:
187
app/utils/manage_media.py
Executable file
187
app/utils/manage_media.py
Executable file
@@ -0,0 +1,187 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Media Management Utility for Motorcycle Adventure Community
|
||||
|
||||
This script provides utilities for managing post media files:
|
||||
- Create missing media folders for existing posts
|
||||
- Clean up orphaned media folders
|
||||
- Migrate files from old structure to new structure
|
||||
- Generate thumbnails for images
|
||||
|
||||
Usage:
|
||||
python manage_media.py --help
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
|
||||
# Add the app directory to the path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'app'))
|
||||
|
||||
from app import create_app
|
||||
from app.models import Post, PostImage, GPXFile
|
||||
from app.extensions import db
|
||||
|
||||
def create_missing_media_folders():
|
||||
"""Create media folders for existing posts that don't have them"""
|
||||
app = create_app()
|
||||
|
||||
with app.app_context():
|
||||
posts_without_folders = Post.query.filter_by(media_folder=None).all()
|
||||
|
||||
print(f"Found {len(posts_without_folders)} posts without media folders")
|
||||
|
||||
for post in posts_without_folders:
|
||||
# Generate a media folder name
|
||||
folder_name = f"post_{uuid.uuid4().hex[:8]}_{post.created_at.strftime('%Y%m%d')}"
|
||||
post.media_folder = folder_name
|
||||
|
||||
# Create the folder structure
|
||||
media_path = os.path.join(app.root_path, 'static', 'media', 'posts', folder_name)
|
||||
os.makedirs(os.path.join(media_path, 'images'), exist_ok=True)
|
||||
os.makedirs(os.path.join(media_path, 'gpx'), exist_ok=True)
|
||||
|
||||
print(f"Created media folder for post {post.id}: {folder_name}")
|
||||
|
||||
db.session.commit()
|
||||
print("Media folders created successfully!")
|
||||
|
||||
def migrate_old_files():
|
||||
"""Migrate files from old upload structure to new media structure"""
|
||||
app = create_app()
|
||||
|
||||
with app.app_context():
|
||||
# Migrate images
|
||||
old_images_path = os.path.join(app.instance_path, 'uploads', 'images')
|
||||
if os.path.exists(old_images_path):
|
||||
print("Migrating image files...")
|
||||
|
||||
for image in PostImage.query.all():
|
||||
if image.post.media_folder:
|
||||
old_path = os.path.join(old_images_path, image.filename)
|
||||
new_path = os.path.join(app.root_path, 'static', 'media', 'posts',
|
||||
image.post.media_folder, 'images', image.filename)
|
||||
|
||||
if os.path.exists(old_path) and not os.path.exists(new_path):
|
||||
os.makedirs(os.path.dirname(new_path), exist_ok=True)
|
||||
shutil.move(old_path, new_path)
|
||||
print(f"Moved image: {image.filename}")
|
||||
|
||||
# Migrate GPX files
|
||||
old_gpx_path = os.path.join(app.instance_path, 'uploads', 'gpx')
|
||||
if os.path.exists(old_gpx_path):
|
||||
print("Migrating GPX files...")
|
||||
|
||||
for gpx_file in GPXFile.query.all():
|
||||
if gpx_file.post.media_folder:
|
||||
old_path = os.path.join(old_gpx_path, gpx_file.filename)
|
||||
new_path = os.path.join(app.root_path, 'static', 'media', 'posts',
|
||||
gpx_file.post.media_folder, 'gpx', gpx_file.filename)
|
||||
|
||||
if os.path.exists(old_path) and not os.path.exists(new_path):
|
||||
os.makedirs(os.path.dirname(new_path), exist_ok=True)
|
||||
shutil.move(old_path, new_path)
|
||||
print(f"Moved GPX file: {gpx_file.filename}")
|
||||
|
||||
print("File migration completed!")
|
||||
|
||||
def clean_orphaned_folders():
|
||||
"""Remove media folders that don't have corresponding posts"""
|
||||
app = create_app()
|
||||
|
||||
with app.app_context():
|
||||
media_posts_path = os.path.join(app.root_path, 'static', 'media', 'posts')
|
||||
|
||||
if not os.path.exists(media_posts_path):
|
||||
print("No media posts directory found")
|
||||
return
|
||||
|
||||
# Get all folder names from database
|
||||
used_folders = set(post.media_folder for post in Post.query.filter(Post.media_folder.isnot(None)).all())
|
||||
|
||||
# Get all actual folders
|
||||
actual_folders = set(name for name in os.listdir(media_posts_path)
|
||||
if os.path.isdir(os.path.join(media_posts_path, name)))
|
||||
|
||||
# Find orphaned folders
|
||||
orphaned_folders = actual_folders - used_folders
|
||||
|
||||
if orphaned_folders:
|
||||
print(f"Found {len(orphaned_folders)} orphaned folders:")
|
||||
for folder in orphaned_folders:
|
||||
folder_path = os.path.join(media_posts_path, folder)
|
||||
print(f" {folder}")
|
||||
|
||||
# Ask for confirmation before deleting
|
||||
response = input(f"Delete folder {folder}? (y/N): ")
|
||||
if response.lower() == 'y':
|
||||
shutil.rmtree(folder_path)
|
||||
print(f" Deleted: {folder}")
|
||||
else:
|
||||
print(f" Skipped: {folder}")
|
||||
else:
|
||||
print("No orphaned folders found")
|
||||
|
||||
def show_media_stats():
|
||||
"""Show statistics about media storage"""
|
||||
app = create_app()
|
||||
|
||||
with app.app_context():
|
||||
total_posts = Post.query.count()
|
||||
posts_with_media_folders = Post.query.filter(Post.media_folder.isnot(None)).count()
|
||||
total_images = PostImage.query.count()
|
||||
total_gpx_files = GPXFile.query.count()
|
||||
|
||||
print("Media Storage Statistics:")
|
||||
print(f" Total posts: {total_posts}")
|
||||
print(f" Posts with media folders: {posts_with_media_folders}")
|
||||
print(f" Posts without media folders: {total_posts - posts_with_media_folders}")
|
||||
print(f" Total images: {total_images}")
|
||||
print(f" Total GPX files: {total_gpx_files}")
|
||||
|
||||
# Calculate total storage used
|
||||
media_posts_path = os.path.join(app.root_path, 'static', 'media', 'posts')
|
||||
if os.path.exists(media_posts_path):
|
||||
total_size = 0
|
||||
for root, dirs, files in os.walk(media_posts_path):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
total_size += os.path.getsize(file_path)
|
||||
|
||||
print(f" Total storage used: {total_size / (1024*1024):.2f} MB")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Media Management Utility')
|
||||
parser.add_argument('--create-folders', action='store_true',
|
||||
help='Create missing media folders for existing posts')
|
||||
parser.add_argument('--migrate-files', action='store_true',
|
||||
help='Migrate files from old structure to new structure')
|
||||
parser.add_argument('--clean-orphaned', action='store_true',
|
||||
help='Clean up orphaned media folders')
|
||||
parser.add_argument('--stats', action='store_true',
|
||||
help='Show media storage statistics')
|
||||
parser.add_argument('--all', action='store_true',
|
||||
help='Run all operations (create folders, migrate files)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.all:
|
||||
create_missing_media_folders()
|
||||
migrate_old_files()
|
||||
elif args.create_folders:
|
||||
create_missing_media_folders()
|
||||
elif args.migrate_files:
|
||||
migrate_old_files()
|
||||
elif args.clean_orphaned:
|
||||
clean_orphaned_folders()
|
||||
elif args.stats:
|
||||
show_media_stats()
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user