Files
thrillwiki_django_no_react/parks/management/commands/seed_data.py
2024-12-26 03:11:52 +00:00

306 lines
11 KiB
Python

import json
import os
import shutil
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.files.temp import NamedTemporaryFile
from django.core.files import File
import requests
from parks.models import Park
from rides.models import Ride, RollerCoasterStats
from companies.models import Company, Manufacturer
from reviews.models import Review
from media.models import Photo
from django.contrib.auth.models import Permission
from datetime import datetime, timedelta
import secrets
User = get_user_model()
# Park coordinates mapping
PARK_COORDINATES = {
"Walt Disney World Magic Kingdom": {
"latitude": "28.418778",
"longitude": "-81.581212",
"street_address": "1180 Seven Seas Dr",
"city": "Orlando",
"state": "Florida",
"postal_code": "32836"
},
"Cedar Point": {
"latitude": "41.482207",
"longitude": "-82.683523",
"street_address": "1 Cedar Point Dr",
"city": "Sandusky",
"state": "Ohio",
"postal_code": "44870"
},
"Universal's Islands of Adventure": {
"latitude": "28.470891",
"longitude": "-81.471756",
"street_address": "6000 Universal Blvd",
"city": "Orlando",
"state": "Florida",
"postal_code": "32819"
},
"Alton Towers": {
"latitude": "52.988889",
"longitude": "-1.892778",
"street_address": "Farley Ln",
"city": "Alton",
"state": "Staffordshire",
"postal_code": "ST10 4DB"
},
"Europa-Park": {
"latitude": "48.266031",
"longitude": "7.722044",
"street_address": "Europa-Park-Straße 2",
"city": "Rust",
"state": "Baden-Württemberg",
"postal_code": "77977"
}
}
class Command(BaseCommand):
help = "Seeds the database with initial data"
def handle(self, *args, **kwargs):
self.stdout.write("Starting database seed...")
# Clean up media directory
self.stdout.write("Cleaning up media directory...")
media_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'media')
if os.path.exists(media_dir):
for item in os.listdir(media_dir):
if item != '__init__.py': # Preserve __init__.py
item_path = os.path.join(media_dir, item)
if os.path.isdir(item_path):
shutil.rmtree(item_path)
else:
os.remove(item_path)
# Delete all existing data
self.stdout.write("Deleting existing data...")
User.objects.exclude(username='admin').delete() # Delete all users except admin
Park.objects.all().delete()
Ride.objects.all().delete()
Company.objects.all().delete()
Manufacturer.objects.all().delete()
Review.objects.all().delete()
Photo.objects.all().delete()
# Create users and set permissions
self.create_users()
self.setup_permissions()
# Create parks and rides
self.stdout.write("Creating parks and rides from seed data...")
self.create_companies()
self.create_manufacturers()
self.create_parks_and_rides()
# Create reviews
self.stdout.write("Creating reviews...")
self.create_reviews()
self.stdout.write("Successfully seeded database")
def setup_permissions(self):
"""Set up photo permissions for all users"""
self.stdout.write("Setting up photo permissions...")
# Get photo permissions
photo_content_type = ContentType.objects.get_for_model(Photo)
photo_permissions = Permission.objects.filter(content_type=photo_content_type)
# Update all users
users = User.objects.all()
for user in users:
for perm in photo_permissions:
user.user_permissions.add(perm)
user.save()
self.stdout.write(f"Updated permissions for user: {user.username}")
def create_users(self):
self.stdout.write("Creating users...")
# Try to get admin user
try:
admin = User.objects.get(username="admin")
self.stdout.write("Admin user exists, updating permissions...")
except User.DoesNotExist:
admin = User.objects.create_superuser("admin", "admin@example.com", "admin")
self.stdout.write("Created admin user")
# Create 10 regular users
usernames = [
"thrillseeker1",
"coasterrider2",
"parkfan3",
"adventurer4",
"funseeker5",
"parkexplorer6",
"ridetester7",
"themepark8",
"coaster9",
"parkvisitor10"
]
for username in usernames:
User.objects.create_user(
username=username,
email=f"{username}@example.com",
[PASSWORD-REMOVED]",
)
self.stdout.write(f"Created user: {username}")
def create_companies(self):
self.stdout.write("Creating companies...")
companies = [
"The Walt Disney Company",
"Cedar Fair",
"NBCUniversal",
"Merlin Entertainments",
"Mack Rides",
]
for name in companies:
Company.objects.create(name=name)
self.stdout.write(f"Created company: {name}")
def create_manufacturers(self):
self.stdout.write("Creating manufacturers...")
manufacturers = [
"Walt Disney Imagineering",
"Bolliger & Mabillard",
"Intamin",
"Rocky Mountain Construction",
"Vekoma",
"Mack Rides",
"Oceaneering International",
]
for name in manufacturers:
Manufacturer.objects.create(name=name)
self.stdout.write(f"Created manufacturer: {name}")
def download_image(self, url):
"""Download image from URL and return as Django File object"""
response = requests.get(url)
if response.status_code == 200:
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(response.content)
img_temp.flush()
return File(img_temp)
return None
def create_parks_and_rides(self):
# Load seed data
with open(os.path.join(os.path.dirname(__file__), "seed_data.json")) as f:
data = json.load(f)
for park_data in data["parks"]:
try:
# Create park with location data
park_coords = PARK_COORDINATES[park_data["name"]]
park = Park.objects.create(
name=park_data["name"],
country=park_data["country"],
opening_date=park_data["opening_date"],
status=park_data["status"],
description=park_data["description"],
website=park_data["website"],
owner=Company.objects.get(name=park_data["owner"]),
size_acres=park_data["size_acres"],
# Add location fields
latitude=park_coords["latitude"],
longitude=park_coords["longitude"],
street_address=park_coords["street_address"],
city=park_coords["city"],
state=park_coords["state"],
postal_code=park_coords["postal_code"]
)
# Add park photos
for photo_url in park_data["photos"]:
img_file = self.download_image(photo_url)
if img_file:
Photo.objects.create(
image=img_file,
content_type=ContentType.objects.get_for_model(park),
object_id=park.id,
is_primary=True, # First photo is primary
)
# Create rides
for ride_data in park_data["rides"]:
ride = Ride.objects.create(
name=ride_data["name"],
park=park,
category=ride_data["category"],
opening_date=ride_data["opening_date"],
status=ride_data["status"],
manufacturer=Manufacturer.objects.get(
name=ride_data["manufacturer"]
),
description=ride_data["description"],
)
# Add ride photos
for photo_url in ride_data["photos"]:
img_file = self.download_image(photo_url)
if img_file:
Photo.objects.create(
image=img_file,
content_type=ContentType.objects.get_for_model(ride),
object_id=ride.id,
is_primary=True, # First photo is primary
)
# Add coaster stats if present
if "stats" in ride_data:
RollerCoasterStats.objects.create(
ride=ride,
height_ft=ride_data["stats"]["height_ft"],
length_ft=ride_data["stats"]["length_ft"],
speed_mph=ride_data["stats"]["speed_mph"],
inversions=ride_data["stats"]["inversions"],
ride_time_seconds=ride_data["stats"]["ride_time_seconds"],
)
self.stdout.write(f"Created park and rides: {park.name}")
except Exception as e:
self.stdout.write(self.style.ERROR(f"Error creating park {park_data['name']}: {str(e)}"))
continue
def create_reviews(self):
users = list(User.objects.exclude(username="admin"))
parks = list(Park.objects.all())
# Generate random dates within the last year
today = datetime.now().date()
one_year_ago = today - timedelta(days=365)
for park in parks:
# Create 3-5 reviews per park
num_reviews = secrets.SystemRandom().randint(3, 5)
for _ in range(num_reviews):
# Generate random visit date
days_offset = secrets.SystemRandom().randint(0, 365)
visit_date = one_year_ago + timedelta(days=days_offset)
Review.objects.create(
user=secrets.choice(users),
content_type=ContentType.objects.get_for_model(park),
object_id=park.id,
title=f"Great experience at {park.name}",
content="Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
rating=secrets.SystemRandom().randint(7, 10),
visit_date=visit_date,
)
self.stdout.write(f"Created reviews for {park.name}")