#!/usr/bin/env python3 """ Seed script to delete all existing rooms and create 50 sample luxury hotel rooms """ import sys import os from pathlib import Path # Add the parent directory to the path so we can import from src sys.path.insert(0, str(Path(__file__).parent)) from sqlalchemy.orm import Session from src.config.database import SessionLocal, engine from src.models.room import Room, RoomStatus from src.models.room_type import RoomType from datetime import datetime import json import random def get_db(): """Get database session""" db = SessionLocal() try: return db finally: pass def seed_rooms(db: Session): """Delete all existing rooms and create 50 sample luxury rooms""" print("=" * 80) print("SEEDING ROOMS - DELETING EXISTING AND CREATING 50 NEW LUXURY ROOMS") print("=" * 80) # Get all room types room_types = db.query(RoomType).all() if not room_types: print("āŒ No room types found! Please create room types first.") return print(f"\nāœ“ Found {len(room_types)} room type(s)") for rt in room_types: print(f" - {rt.name} (ID: {rt.id}, Base Price: {rt.base_price})") # Delete all existing rooms # First, we need to handle related records that reference these rooms from src.models.booking import Booking from src.models.review import Review from src.models.favorite import Favorite existing_rooms = db.query(Room).all() if existing_rooms: print(f"\nšŸ—‘ļø Deleting {len(existing_rooms)} existing room(s)...") # Get all room IDs room_ids = [room.id for room in existing_rooms] # Delete bookings that reference these rooms bookings_with_rooms = db.query(Booking).filter(Booking.room_id.in_(room_ids)).all() if bookings_with_rooms: print(f" āš ļø Found {len(bookings_with_rooms)} booking(s) referencing these rooms") for booking in bookings_with_rooms: db.delete(booking) print(f" āœ“ Deleted {len(bookings_with_rooms)} booking(s)") # Delete reviews that reference these rooms reviews_with_rooms = db.query(Review).filter(Review.room_id.in_(room_ids)).all() if reviews_with_rooms: print(f" āš ļø Found {len(reviews_with_rooms)} review(s) referencing these rooms") for review in reviews_with_rooms: db.delete(review) print(f" āœ“ Deleted {len(reviews_with_rooms)} review(s)") # Delete favorites that reference these rooms favorites_with_rooms = db.query(Favorite).filter(Favorite.room_id.in_(room_ids)).all() if favorites_with_rooms: print(f" āš ļø Found {len(favorites_with_rooms)} favorite(s) referencing these rooms") for favorite in favorites_with_rooms: db.delete(favorite) print(f" āœ“ Deleted {len(favorites_with_rooms)} favorite(s)") # Now delete the rooms for room in existing_rooms: db.delete(room) db.commit() print(f"āœ“ Deleted {len(existing_rooms)} room(s)") # Luxury room configurations views = [ "Ocean View", "City View", "Garden View", "Mountain View", "Pool View", "Beach View", "Panoramic View", "Sea View" ] room_sizes = [ "35 sqm", "40 sqm", "45 sqm", "50 sqm", "55 sqm", "60 sqm", "70 sqm", "80 sqm", "90 sqm", "100 sqm", "120 sqm", "150 sqm", "180 sqm", "200 sqm", "250 sqm" ] # Real luxury hotel room images from Unsplash (defined once, used for all rooms) luxury_room_images = [ # Luxury hotel rooms "https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop", # Suite images "https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop", # Additional luxury rooms "https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1566073771259-6a8506099945?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1578683010236-d716f9a3f461?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1631049307264-da0ec9d70304?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1611892440504-42a792e24d32?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1590490360182-c33d57733427?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1564501049412-61c2a3083791?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1618221195710-dd6b41faaea8?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1566665797739-1674de7a421a?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1618773928121-c32242e63f39?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1582719508461-905c673771fd?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1595576508898-0ad5c879a061?w=1200&h=800&fit=crop", "https://images.unsplash.com/photo-1571003123894-1f0594d2b5d9?w=1200&h=800&fit=crop", ] # Comprehensive luxury amenities all_amenities = [ "Free WiFi", "High-Speed Internet", "Smart TV", "Netflix", "Air Conditioning", "Climate Control", "Private Balcony", "Ocean View", "City View", "Minibar", "Coffee Maker", "Espresso Machine", "Refrigerator", "Safe", "Iron & Ironing Board", "Hair Dryer", "Premium Toiletries", "Bathrobes", "Slippers", "Work Desk", "Ergonomic Chair", "USB Charging Ports", "Bluetooth Speaker", "Sound System", "Blackout Curtains", "Pillow Menu", "Turndown Service", "Room Service", "24/7 Concierge" ] premium_amenities = [ "Jacuzzi Bathtub", "Steam Shower", "Rain Shower", "Bidet", "Private Pool", "Outdoor Terrace", "Fireplace", "Wine Cellar", "Private Bar", "Butler Service", "Private Elevator", "Helipad Access" ] # Room configurations: (floor_range, room_numbers_per_floor, view, size_range, amenities_count, featured) room_configs = [ # Standard Rooms (Floors 1-3) ((1, 3), 8, "Garden View", (35, 45), 8, False), ((1, 3), 8, "City View", (40, 50), 9, False), # Superior Rooms (Floors 4-6) ((4, 6), 6, "City View", (45, 55), 10, False), ((4, 6), 6, "Pool View", (50, 60), 11, True), # Deluxe Rooms (Floors 7-9) ((7, 9), 5, "Ocean View", (55, 70), 12, True), ((7, 9), 5, "Mountain View", (60, 75), 12, False), # Executive Suites (Floors 10-12) ((10, 12), 4, "Panoramic View", (80, 100), 14, True), ((10, 12), 4, "Sea View", (90, 110), 15, True), # Luxury Suites (Floors 13-15) ((13, 15), 3, "Ocean View", (120, 150), 16, True), ((13, 15), 3, "Beach View", (130, 160), 17, True), # Presidential Suites (Floor 16) ((16, 16), 2, "Panoramic View", (200, 250), 20, True), ] rooms_created = [] room_counter = 101 # Starting room number print(f"\nšŸØ Creating 50 luxury rooms...\n") for config in room_configs: floor_range, rooms_per_floor, view_type, size_range, amenities_count, featured = config for floor in range(floor_range[0], floor_range[1] + 1): for _ in range(rooms_per_floor): if len(rooms_created) >= 50: break # Select random room type based on floor if floor <= 3: room_type = random.choice([rt for rt in room_types if 'standard' in rt.name.lower() or 'superior' in rt.name.lower()] or room_types) elif floor <= 6: room_type = random.choice([rt for rt in room_types if 'superior' in rt.name.lower() or 'deluxe' in rt.name.lower()] or room_types) elif floor <= 9: room_type = random.choice([rt for rt in room_types if 'deluxe' in rt.name.lower() or 'executive' in rt.name.lower()] or room_types) elif floor <= 12: room_type = random.choice([rt for rt in room_types if 'executive' in rt.name.lower() or 'suite' in rt.name.lower()] or room_types) else: room_type = random.choice([rt for rt in room_types if 'suite' in rt.name.lower() or 'presidential' in rt.name.lower()] or room_types) # If no matching room type, use random if not room_type: room_type = random.choice(room_types) # Calculate price (base price + floor premium + view premium + random variation) base_price = float(room_type.base_price) floor_premium = (floor - 1) * 5 # +5 per floor view_premium = 20 if "Ocean" in view_type or "Sea" in view_type or "Beach" in view_type else 0 view_premium += 15 if "Panoramic" in view_type else 0 view_premium += 10 if "Mountain" in view_type else 0 view_premium += 5 if "Pool" in view_type else 0 # Add random variation (-5% to +10% of base price) random_variation = base_price * random.uniform(-0.05, 0.10) # Size premium (larger rooms cost more) size_min, size_max = size_range size_premium = (size_min + size_max) / 2 * 0.5 # ~0.5 per sqm price = base_price + floor_premium + view_premium + random_variation + size_premium # Ensure minimum price and round to 2 decimal places price = max(base_price * 0.95, price) price = round(price, 2) # Select amenities selected_amenities = random.sample(all_amenities, min(amenities_count, len(all_amenities))) if floor >= 13: # Add premium amenities for luxury suites premium_count = min(2, len(premium_amenities)) selected_amenities.extend(random.sample(premium_amenities, premium_count)) # Room size size_min, size_max = size_range room_size = f"{random.randint(size_min, size_max)} sqm" # Capacity (based on room type, with some variation) capacity = room_type.capacity if random.random() > 0.7: # 30% chance to have different capacity capacity = max(1, capacity + random.randint(-1, 1)) # Room number room_number = f"{floor}{room_counter % 100:02d}" room_counter += 1 # Select 3 unique images for each room (ensure we always have images) # Shuffle the list each time to get different combinations shuffled_images = luxury_room_images.copy() random.shuffle(shuffled_images) image_urls = shuffled_images[:3] # Always take first 3 after shuffle # Description descriptions = [ f"Elegantly designed {view_type.lower()} room with modern luxury amenities and breathtaking views.", f"Spacious {view_type.lower()} accommodation featuring premium furnishings and world-class comfort.", f"Luxurious {view_type.lower()} room with sophisticated decor and exceptional attention to detail.", f"Exquisite {view_type.lower()} suite offering unparalleled elegance and personalized service.", f"Opulent {view_type.lower()} accommodation with bespoke interiors and premium amenities.", ] description = random.choice(descriptions) # Status (mostly available, some in maintenance/cleaning) status_weights = [0.85, 0.05, 0.05, 0.05] # available, occupied, maintenance, cleaning status = random.choices( [RoomStatus.available, RoomStatus.occupied, RoomStatus.maintenance, RoomStatus.cleaning], weights=status_weights )[0] # Create room room = Room( room_type_id=room_type.id, room_number=room_number, floor=floor, status=status, price=price, featured=featured, capacity=capacity, room_size=room_size, view=view_type, images=json.dumps(image_urls), amenities=json.dumps(selected_amenities), description=description ) db.add(room) rooms_created.append({ 'number': room_number, 'floor': floor, 'type': room_type.name, 'view': view_type, 'price': price }) print(f" āœ“ Created Room {room_number} - Floor {floor}, {room_type.name}, {view_type}, {room_size}, €{price:.2f}") db.commit() print(f"\nāœ… Successfully created {len(rooms_created)} luxury rooms!") print(f"\nšŸ“Š Summary:") featured_count = sum(1 for r in rooms_created if any( config[5] and r['floor'] >= config[0][0] and r['floor'] <= config[0][1] for config in room_configs )) print(f" - Featured rooms: {featured_count}") print(f" - Floors: {min(r['floor'] for r in rooms_created)} - {max(r['floor'] for r in rooms_created)}") print(f" - Price range: €{min(r['price'] for r in rooms_created):.2f} - €{max(r['price'] for r in rooms_created):.2f}") print("=" * 80) if __name__ == "__main__": db = get_db() try: seed_rooms(db) except Exception as e: print(f"\nāŒ Error: {e}") import traceback traceback.print_exc() db.rollback() finally: db.close()