Files
thrillwiki_django_no_react/backend/apps/media/commands/move_photos.py

198 lines
7.9 KiB
Python

import os
from django.core.management.base import BaseCommand
from apps.parks.models import ParkPhoto
from apps.rides.models import RidePhoto
from django.conf import settings
import shutil
class Command(BaseCommand):
help = "Move photo files to their normalized locations"
def handle(self, *args, **kwargs):
self.stdout.write("Moving photo files to normalized locations...")
# Get all photos
park_photos = ParkPhoto.objects.all()
ride_photos = RidePhoto.objects.all()
# Track processed files to clean up later
processed_files = set()
# Process park photos
for photo in park_photos:
try:
# Get current file path
current_name = photo.image.name
current_path = os.path.join(settings.MEDIA_ROOT, current_name)
# Try to find the actual file
if not os.path.exists(current_path):
# Check if file exists in the old location structure
parts = current_name.split("/")
if len(parts) >= 2:
content_type = "park"
identifier = photo.park.slug
# Look for any files in that directory
old_dir = os.path.join(
settings.MEDIA_ROOT, content_type, identifier
)
if os.path.exists(old_dir):
files = [
f
for f in os.listdir(old_dir)
if not f.startswith(".") # Skip hidden files
and not f.startswith("tmp") # Skip temp files
and os.path.isfile(os.path.join(old_dir, f))
]
if files:
current_path = os.path.join(old_dir, files[0])
# Skip if file still not found
if not os.path.exists(current_path):
self.stdout.write(f"Skipping {current_name} - file not found")
continue
# Get content type and object
content_type_model = "park"
obj = photo.park
identifier = getattr(obj, "slug", obj.id)
# Get photo number
photo_number = ParkPhoto.objects.filter(
park=photo.park,
created_at__lte=photo.created_at,
).count()
# Create new filename
_, ext = os.path.splitext(current_path)
if not ext:
ext = ".jpg"
ext = ext.lower()
new_filename = f"{identifier}_{photo_number}{ext}"
# Create new path
new_relative_path = f"{content_type_model}/{identifier}/{new_filename}"
new_full_path = os.path.join(settings.MEDIA_ROOT, new_relative_path)
# Create directory if it doesn't exist
os.makedirs(os.path.dirname(new_full_path), exist_ok=True)
# Move the file
if current_path != new_full_path:
shutil.copy2(
current_path, new_full_path
) # Use copy2 to preserve metadata
processed_files.add(current_path)
else:
processed_files.add(current_path)
# Update database
photo.image.name = new_relative_path
photo.save()
self.stdout.write(f"Moved {current_name} to {new_relative_path}")
except Exception as e:
self.stdout.write(f"Error moving park photo {photo.id}: {str(e)}")
continue
# Process ride photos
for photo in ride_photos:
try:
# Get current file path
current_name = photo.image.name
current_path = os.path.join(settings.MEDIA_ROOT, current_name)
# Try to find the actual file
if not os.path.exists(current_path):
# Check if file exists in the old location structure
parts = current_name.split("/")
if len(parts) >= 2:
content_type = parts[0] # 'park' or 'ride'
identifier = parts[1] # e.g., 'alton-towers'
# Look for any files in that directory
old_dir = os.path.join(
settings.MEDIA_ROOT, content_type, identifier
)
if os.path.exists(old_dir):
files = [
f
for f in os.listdir(old_dir)
if not f.startswith(".") # Skip hidden files
and not f.startswith("tmp") # Skip temp files
and os.path.isfile(os.path.join(old_dir, f))
]
if files:
current_path = os.path.join(old_dir, files[0])
# Skip if file still not found
if not os.path.exists(current_path):
self.stdout.write(f"Skipping {current_name} - file not found")
continue
# Get content type and object
content_type_model = "ride"
obj = photo.ride
identifier = getattr(obj, "slug", obj.id)
# Get photo number
photo_number = RidePhoto.objects.filter(
ride=photo.ride,
created_at__lte=photo.created_at,
).count()
# Create new filename
_, ext = os.path.splitext(current_path)
if not ext:
ext = ".jpg"
ext = ext.lower()
new_filename = f"{identifier}_{photo_number}{ext}"
# Create new path
new_relative_path = f"{content_type_model}/{identifier}/{new_filename}"
new_full_path = os.path.join(settings.MEDIA_ROOT, new_relative_path)
# Create directory if it doesn't exist
os.makedirs(os.path.dirname(new_full_path), exist_ok=True)
# Move the file
if current_path != new_full_path:
shutil.copy2(
current_path, new_full_path
) # Use copy2 to preserve metadata
processed_files.add(current_path)
else:
processed_files.add(current_path)
# Update database
photo.image.name = new_relative_path
photo.save()
self.stdout.write(f"Moved {current_name} to {new_relative_path}")
except Exception as e:
self.stdout.write(f"Error moving ride photo {photo.id}: {str(e)}")
continue
# Clean up old files
self.stdout.write("Cleaning up old files...")
for content_type in ["park", "ride"]:
base_dir = os.path.join(settings.MEDIA_ROOT, content_type)
if os.path.exists(base_dir):
for root, dirs, files in os.walk(base_dir):
for file in files:
file_path = os.path.join(root, file)
if file_path not in processed_files:
try:
os.remove(file_path)
self.stdout.write(f"Removed old file: {file_path}")
except Exception as e:
self.stdout.write(
f"Error removing {file_path}: {str(e)}"
)
self.stdout.write("Finished moving photo files and cleaning up")