233 lines
19 KiB
Python
233 lines
19 KiB
Python
<<<<<<< HEAD
|
|
#!/usr/bin/env python3
|
|
"""
|
|
Database initialization script for Family Hub.
|
|
Creates tables and populates with demo data.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from datetime import datetime, timedelta
|
|
|
|
# Add parent directory to path to import from app
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from app.core.database import engine, SessionLocal, Base
|
|
from app.models import User, Chore
|
|
from passlib.context import CryptContext
|
|
|
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
|
|
def init_db():
|
|
"""Initialize the database with tables and demo data."""
|
|
print("Initializing Family Hub database...")
|
|
|
|
# Create all tables
|
|
print("Creating database tables...")
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
db = SessionLocal()
|
|
|
|
try:
|
|
# Check if data already exists
|
|
existing_users = db.query(User).count()
|
|
if existing_users > 0:
|
|
print(f"Database already has {existing_users} users. Skipping initialization.")
|
|
print(" To reset the database, delete the file and run this script again.")
|
|
return
|
|
|
|
# Create demo users
|
|
print("\nCreating demo users...")
|
|
users_data = [
|
|
{"username": "jess", "email": "jess@family.local", "full_name": "Jess", "is_admin": True},
|
|
{"username": "lou", "email": "lou@family.local", "full_name": "Lou", "is_admin": False},
|
|
{"username": "william", "email": "william@family.local", "full_name": "William", "is_admin": False},
|
|
{"username": "xander", "email": "xander@family.local", "full_name": "Xander", "is_admin": False},
|
|
{"username": "bella", "email": "bella@family.local", "full_name": "Bella", "is_admin": False},
|
|
]
|
|
|
|
users = []
|
|
for user_data in users_data:
|
|
user = User(
|
|
username=user_data["username"],
|
|
email=user_data["email"],
|
|
full_name=user_data["full_name"],
|
|
hashed_password=pwd_context.hash("password123"),
|
|
is_admin=user_data["is_admin"],
|
|
is_active=True
|
|
)
|
|
db.add(user)
|
|
users.append(user)
|
|
admin_badge = " [ADMIN]" if user.is_admin else ""
|
|
print(f" + {user.full_name} ({user.username}){admin_badge}")
|
|
|
|
db.flush() # Flush to get user IDs
|
|
|
|
# Create demo chores
|
|
print("\nCreating demo chores...")
|
|
|
|
# Get user IDs for assignment
|
|
jess = next(u for u in users if u.username == "jess")
|
|
lou = next(u for u in users if u.username == "lou")
|
|
william = next(u for u in users if u.username == "william")
|
|
xander = next(u for u in users if u.username == "xander")
|
|
bella = next(u for u in users if u.username == "bella")
|
|
|
|
demo_chores = [
|
|
# Daily chores
|
|
{
|
|
"title": "Feed the pets",
|
|
"description": "Feed cats in the morning and evening",
|
|
"frequency": "daily",
|
|
"assignment_type": "any_one",
|
|
"points": 5,
|
|
"room": "Kitchen",
|
|
"assigned_user_id": bella.id,
|
|
"status": "pending"
|
|
},
|
|
{
|
|
"title": "Take out trash",
|
|
"description": "Empty kitchen and bathroom bins",
|
|
"frequency": "daily",
|
|
"assignment_type": "any_one",
|
|
"points": 3,
|
|
"room": "Kitchen",
|
|
"assigned_user_id": xander.id,
|
|
"status": "pending"
|
|
},
|
|
{
|
|
"title": "Tidy living room",
|
|
"description": "Pick up toys, straighten cushions, clear coffee table",
|
|
"frequency": "daily",
|
|
"assignment_type": "any_one",
|
|
"points": 5,
|
|
"room": "Living Room",
|
|
"assigned_user_id": william.id,
|
|
"status": "in_progress"
|
|
},
|
|
|
|
# Weekly chores
|
|
{
|
|
"title": "Vacuum entire house",
|
|
"description": "Vacuum all carpeted areas including stairs",
|
|
"frequency": "weekly",
|
|
"assignment_type": "any_one",
|
|
"points": 15,
|
|
"room": "Whole House",
|
|
"assigned_user_id": lou.id,
|
|
"status": "pending"
|
|
},
|
|
{
|
|
"title": "Clean bathrooms",
|
|
"description": "Clean toilets, sinks, mirrors, and mop floors",
|
|
"frequency": "weekly",
|
|
"assignment_type": "any_one",
|
|
"points": 20,
|
|
"room": "Bathrooms",
|
|
"assigned_user_id": jess.id,
|
|
"status": "completed",
|
|
"completed_at": datetime.now() - timedelta(days=1)
|
|
},
|
|
{
|
|
"title": "Mow the lawn",
|
|
"description": "Mow front and back yard, edge walkways",
|
|
"frequency": "weekly",
|
|
"assignment_type": "any_one",
|
|
"points": 25,
|
|
"room": "Yard",
|
|
"assigned_user_id": william.id,
|
|
"status": "pending"
|
|
},
|
|
|
|
# Monthly chores
|
|
{
|
|
"title": "Deep clean kitchen",
|
|
"description": "Clean oven, fridge, cabinets, and behind appliances",
|
|
"frequency": "monthly",
|
|
"assignment_type": "any_one",
|
|
"points": 50,
|
|
"room": "Kitchen",
|
|
"assigned_user_id": jess.id,
|
|
"status": "pending"
|
|
},
|
|
{
|
|
"title": "Wash windows",
|
|
"description": "Clean all interior and exterior windows",
|
|
"frequency": "monthly",
|
|
"assignment_type": "any_one",
|
|
"points": 40,
|
|
"room": "Whole House",
|
|
"assigned_user_id": lou.id,
|
|
"status": "pending"
|
|
},
|
|
{
|
|
"title": "Organize garage",
|
|
"description": "Sort items, sweep floor, arrange tools",
|
|
"frequency": "monthly",
|
|
"assignment_type": "any_one",
|
|
"points": 35,
|
|
"room": "Garage",
|
|
"assigned_user_id": william.id,
|
|
"status": "in_progress"
|
|
},
|
|
{
|
|
"title": "Change air filters",
|
|
"description": "Replace HVAC filters throughout house",
|
|
"frequency": "monthly",
|
|
"assignment_type": "any_one",
|
|
"points": 10,
|
|
"room": "Whole House",
|
|
"assigned_user_id": jess.id,
|
|
"status": "pending"
|
|
},
|
|
|
|
# On-trigger chores
|
|
{
|
|
"title": "Grocery shopping",
|
|
"description": "Weekly grocery shopping trip",
|
|
"frequency": "on_trigger",
|
|
"assignment_type": "any_one",
|
|
"points": 30,
|
|
"room": "Shopping",
|
|
"assigned_user_id": lou.id,
|
|
"status": "pending"
|
|
},
|
|
{
|
|
"title": "Car wash",
|
|
"description": "Wash and vacuum family car",
|
|
"frequency": "on_trigger",
|
|
"assignment_type": "any_one",
|
|
"points": 20,
|
|
"room": "Driveway",
|
|
"assigned_user_id": xander.id,
|
|
"status": "pending"
|
|
},
|
|
]
|
|
|
|
for chore_data in demo_chores:
|
|
chore = Chore(**chore_data)
|
|
db.add(chore)
|
|
|
|
# Pretty print status
|
|
status_marker = "[DONE]" if chore_data["status"] == "completed" else "[WIP]" if chore_data["status"] == "in_progress" else "[TODO]"
|
|
print(f" {status_marker} {chore_data['title']} - {chore_data['frequency']} ({chore_data['room']})")
|
|
|
|
db.commit()
|
|
print(f"\n[SUCCESS] Database initialized with {len(users_data)} users and {len(demo_chores)} demo chores!")
|
|
print("\nLogin credentials:")
|
|
print(" Username: jess (admin) or lou, william, xander, bella")
|
|
print(" Password: password123")
|
|
|
|
except Exception as e:
|
|
print(f"[ERROR] Error initializing database: {e}")
|
|
db.rollback()
|
|
raise
|
|
finally:
|
|
db.close()
|
|
|
|
if __name__ == "__main__":
|
|
init_db()
|
|
=======
|
|
IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKRGF0YWJhc2UgaW5pdGlhbGl6YXRpb24gc2NyaXB0IGZvciBGYW1pbHkgSHViLgpDcmVhdGVzIHRhYmxlcyBhbmQgcG9wdWxhdGVzIHdpdGggZGVtbyBkYXRhLgoiIiIKCmltcG9ydCBzeXMKZnJvbSBwYXRobGliIGltcG9ydCBQYXRoCmZyb20gZGF0ZXRpbWUgaW1wb3J0IGRhdGV0aW1lLCB0aW1lZGVsdGEKCiMgQWRkIHBhcmVudCBkaXJlY3RvcnkgdG8gcGF0aCB0byBpbXBvcnQgZnJvbSBhcHAKc3lzLnBhdGguaW5zZXJ0KDAsIHN0cihQYXRoKF9fZmlsZV9fKS5wYXJlbnQpKQoKZnJvbSBhcHAuY29yZS5kYXRhYmFzZSBpbXBvcnQgZW5naW5lLCBTZXNzaW9uTG9jYWwsIEJhc2UKZnJvbSBhcHAubW9kZWxzIGltcG9ydCBVc2VyLCBDaG9yZQpmcm9tIHBhc3NsaWIuY29udGV4dCBpbXBvcnQgQ3J5cHRDb250ZXh0Cgpwd2RfY29udGV4dCA9IENyeXB0Q29udGV4dChzY2hlbWVzPVsiYmNyeXB0Il0sIGRlcHJlY2F0ZWQ9ImF1dG8iKQoKZGVmIGluaXRfZGIoKToKICAgICIiIkluaXRpYWxpemUgdGhlIGRhdGFiYXNlIHdpdGggdGFibGVzIGFuZCBkZW1vIGRhdGEuIiIiCiAgICBwcmludCgi8J+agCBJbml0aWFsaXppbmcgRmFtaWx5IEh1YiBkYXRhYmFzZS4uLiIpCiAgICAKICAgICMgQ3JlYXRlIGFsbCB0YWJsZXMKICAgIHByaW50KCLwn5SnIENyZWF0aW5nIGRhdGFiYXNlIHRhYmxlcy4uLiIpCiAgICBCYXNlLm1ldGFkYXRhLmNyZWF0ZV9hbGwoYmluZD1lbmdpbmUpCiAgICAKICAgIGRiID0gU2Vzc2lvbkxvY2FsKCkKICAgIAogICAgdHJ5OgogICAgICAgICMgQ2hlY2sgaWYgZGF0YSBhbHJlYWR5IGV4aXN0cwogICAgICAgIGV4aXN0aW5nX3VzZXJzID0gZGIucXVlcnkoVXNlcikuY291bnQoKQogICAgICAgIGlmIGV4aXN0aW5nX3VzZXJzID4gMDoKICAgICAgICAgICAgcHJpbnQoZiLimqDvuI8gIERhdGFiYXNlIGFscmVhZHkgaGFzIHtleGlzdGluZ191c2Vyc30gdXNlcnMuIFNraXBwaW5nIGluaXRpYWxpemF0aW9uLiIpCiAgICAgICAgICAgIHByaW50KCIgICBUbyByZXNldCB0aGUgZGF0YWJhc2UsIGRlbGV0ZSB0aGUgZmlsZSBhbmQgcnVuIHRoaXMgc2NyaXB0IGFnYWluLiIpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIAogICAgICAgICMgQ3JlYXRlIGRlbW8gdXNlcnMKICAgICAgICBwcmludCgiXG7wn5GlIENyZWF0aW5nIGRlbW8gdXNlcnMuLi4iKQogICAgICAgIHVzZXJzX2RhdGEgPSBbCiAgICAgICAgICAgIHsidXNlcm5hbWUiOiAiamVzcyIsICJlbWFpbCI6ICJqZXNzQGZhbWlseS5sb2NhbCIsICJmdWxsX25hbWUiOiAiSmVzcyIsICJpc19hZG1pbiI6IFRydWV9LAogICAgICAgICAgICB7InVzZXJuYW1lIjogImxvdSIsICJlbWFpbCI6ICJsb3VAZmFtaWx5LmxvY2FsIiwgImZ1bGxfbmFtZSI6ICJMb3UiLCAiaXNfYWRtaW4iOiBGYWxzZX0sCiAgICAgICAgICAgIHsidXNlcm5hbWUiOiAid2lsbGlhbSIsICJlbWFpbCI6ICJ3aWxsaWFtQGZhbWlseS5sb2NhbCIsICJmdWxsX25hbWUiOiAiV2lsbGlhbSIsICJpc19hZG1pbiI6IEZhbHNlfSwKICAgICAgICAgICAgeyJ1c2VybmFtZSI6ICJ4YW5kZXIiLCAiZW1haWwiOiAieGFuZGVyQGZhbWlseS5sb2NhbCIsICJmdWxsX25hbWUiOiAiWGFuZGVyIiwgImlzX2FkbWluIjogRmFsc2V9LAogICAgICAgICAgICB7InVzZXJuYW1lIjogImJlbGxhIiwgImVtYWlsIjogImJlbGxhQGZhbWlseS5sb2NhbCIsICJmdWxsX25hbWUiOiAiQmVsbGEiLCAiaXNfYWRtaW4iOiBGYWxzZX0sCiAgICAgICAgXQogICAgICAgIAogICAgICAgIHVzZXJzID0gW10KICAgICAgICBmb3IgdXNlcl9kYXRhIGluIHVzZXJzX2RhdGE6CiAgICAgICAgICAgIHVzZXIgPSBVc2VyKAogICAgICAgICAgICAgICAgdXNlcm5hbWU9dXNlcl9kYXRhWyJ1c2VybmFtZSJdLAogICAgICAgICAgICAgICAgZW1haWw9dXNlcl9kYXRhWyJlbWFpbCJdLAogICAgICAgICAgICAgICAgZnVsbF9uYW1lPXVzZXJfZGF0YVsiZnVsbF9uYW1lIl0sCiAgICAgICAgICAgICAgICBoYXNoZWRfcGFzc3dvcmQ9cHdkX2NvbnRleHQuaGFzaCgicGFzc3dvcmQxMjMiKSwKICAgICAgICAgICAgICAgIGlzX2FkbWluPXVzZXJfZGF0YVsiaXNfYWRtaW4iXSwKICAgICAgICAgICAgICAgIGlzX2FjdGl2ZT1UcnVlCiAgICAgICAgICAgICkKICAgICAgICAgICAgZGIuYWRkKHVzZXIpCiAgICAgICAgICAgIHVzZXJzLmFwcGVuZCh1c2VyKQogICAgICAgICAgICBhZG1pbl9iYWRnZSA9ICIg8J+RkSIgaWYgdXNlci5pc19hZG1pbiBlbHNlICIiCiAgICAgICAgICAgIHByaW50KGYiICDinJMge3VzZXIuZnVsbF9uYW1lfSAoe3VzZXIudXNlcm5hbWV9KXthZG1pbl9iYWRnZX0iKQogICAgICAgIAogICAgICAgIGRiLmZsdXNoKCkgICMgRmx1c2ggdG8gZ2V0IHVzZXIgSURzCiAgICAgICAgCiAgICAgICAgIyBDcmVhdGUgZGVtbyBjaG9yZXMKICAgICAgICBwcmludCgiXG7wn6e5IENyZWF0aW5nIGRlbW8gY2hvcmVzLi4uIikKICAgICAgICAKICAgICAgICAjIEdldCB1c2VyIElEcyBmb3IgYXNzaWdubWVudAogICAgICAgIGplc3MgPSBuZXh0KHUgZm9yIHUgaW4gdXNlcnMgaWYgdS51c2VybmFtZSA9PSAiamVzcyIpCiAgICAgICAgbG91ID0gbmV4dCh1IGZvciB1IGluIHVzZXJzIGlmIHUudXNlcm5hbWUgPT0gImxvdSIpCiAgICAgICAgd2lsbGlhbSA9IG5leHQodSBmb3IgdSBpbiB1c2VycyBpZiB1LnVzZXJuYW1lID09ICJ3aWxsaWFtIikKICAgICAgICB4YW5kZXIgPSBuZXh0KHUgZm9yIHUgaW4gdXNlcnMgaWYgdS51c2VybmFtZSA9PSAieGFuZGVyIikKICAgICAgICBiZWxsYSA9IG5leHQodSBmb3IgdSBpbiB1c2VycyBpZiB1LnVzZXJuYW1lID09ICJiZWxsYSIpCiAgICAgICAgCiAgICAgICAgZGVtb19jaG9yZXMgPSBbCiAgICAgICAgICAgICMgRGFpbHkgY2hvcmVzCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJ0aXRsZSI6ICJGZWVkIHRoZSBwZXRzIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJGZWVkIGNhdHMgaW4gdGhlIG1vcm5pbmcgYW5kIGV2ZW5pbmciLAogICAgICAgICAgICAgICAgImZyZXF1ZW5jeSI6ICJEQUlMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogNSwKICAgICAgICAgICAgICAgICJyb29tIjogIktpdGNoZW4iLAogICAgICAgICAgICAgICAgImFzc2lnbmVkX3VzZXJfaWQiOiBiZWxsYS5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiUEVORElORyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIlRha2Ugb3V0IHRyYXNoIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJFbXB0eSBraXRjaGVuIGFuZCBiYXRocm9vbSBiaW5zIiwKICAgICAgICAgICAgICAgICJmcmVxdWVuY3kiOiAiREFJTFkiLAogICAgICAgICAgICAgICAgInBvaW50cyI6IDMsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJLaXRjaGVuIiwKICAgICAgICAgICAgICAgICJhc3NpZ25lZF91c2VyX2lkIjogeGFuZGVyLmlkLAogICAgICAgICAgICAgICAgInN0YXR1cyI6ICJQRU5ESU5HIgogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAidGl0bGUiOiAiVGlkeSBsaXZpbmcgcm9vbSIsCiAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUGljayB1cCB0b3lzLCBzdHJhaWdodGVuIGN1c2hpb25zLCBjbGVhciBjb2ZmZWUgdGFibGUiLAogICAgICAgICAgICAgICAgImZyZXF1ZW5jeSI6ICJEQUlMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogNSwKICAgICAgICAgICAgICAgICJyb29tIjogIkxpdmluZyBSb29tIiwKICAgICAgICAgICAgICAgICJhc3NpZ25lZF91c2VyX2lkIjogd2lsbGlhbS5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiSU5fUFJPR1JFU1MiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIAogICAgICAgICAgICAjIFdlZWtseSBjaG9yZXMKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIlZhY3V1bSBlbnRpcmUgaG91c2UiLAogICAgICAgICAgICAgICAgImRlc2NyaXB0aW9uIjogIlZhY3V1bSBhbGwgY2FycGV0ZWQgYXJlYXMgaW5jbHVkaW5nIHN0YWlycyIsCiAgICAgICAgICAgICAgICAiZnJlcXVlbmN5IjogIldFRUtMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogMTUsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJXaG9sZSBIb3VzZSIsCiAgICAgICAgICAgICAgICAiYXNzaWduZWRfdXNlcl9pZCI6IGxvdS5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiUEVORElORyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIkNsZWFuIGJhdGhyb29tcyIsCiAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ2xlYW4gdG9pbGV0cywgc2lua3MsIG1pcnJvcnMsIGFuZCBtb3AgZmxvb3JzIiwKICAgICAgICAgICAgICAgICJmcmVxdWVuY3kiOiAiV0VFS0xZIiwKICAgICAgICAgICAgICAgICJwb2ludHMiOiAyMCwKICAgICAgICAgICAgICAgICJyb29tIjogIkJhdGhyb29tcyIsCiAgICAgICAgICAgICAgICAiYXNzaWduZWRfdXNlcl9pZCI6IGplc3MuaWQsCiAgICAgICAgICAgICAgICAic3RhdHVzIjogIkNPTVBMRVRFRCIsCiAgICAgICAgICAgICAgICAiY29tcGxldGVkX2F0IjogZGF0ZXRpbWUubm93KCkgLSB0aW1lZGVsdGEoZGF5cz0xKQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAidGl0bGUiOiAiTW93IHRoZSBsYXduIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJNb3cgZnJvbnQgYW5kIGJhY2sgeWFyZCwgZWRnZSB3YWxrd2F5cyIsCiAgICAgICAgICAgICAgICAiZnJlcXVlbmN5IjogIldFRUtMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogMjUsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJZYXJkIiwKICAgICAgICAgICAgICAgICJhc3NpZ25lZF91c2VyX2lkIjogd2lsbGlhbS5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiUEVORElORyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgCiAgICAgICAgICAgICMgTW9udGhseSBjaG9yZXMKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIkRlZXAgY2xlYW4ga2l0Y2hlbiIsCiAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ2xlYW4gb3ZlbiwgZnJpZGdlLCBjYWJpbmV0cywgYW5kIGJlaGluZCBhcHBsaWFuY2VzIiwKICAgICAgICAgICAgICAgICJmcmVxdWVuY3kiOiAiTU9OVEhMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogNTAsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJLaXRjaGVuIiwKICAgICAgICAgICAgICAgICJhc3NpZ25lZF91c2VyX2lkIjogamVzcy5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiUEVORElORyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIldhc2ggd2luZG93cyIsCiAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ2xlYW4gYWxsIGludGVyaW9yIGFuZCBleHRlcmlvciB3aW5kb3dzIiwKICAgICAgICAgICAgICAgICJmcmVxdWVuY3kiOiAiTU9OVEhMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogNDAsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJXaG9sZSBIb3VzZSIsCiAgICAgICAgICAgICAgICAiYXNzaWduZWRfdXNlcl9pZCI6IGxvdS5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiUEVORElORyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIk9yZ2FuaXplIGdhcmFnZSIsCiAgICAgICAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiU29ydCBpdGVtcywgc3dlZXAgZmxvb3IsIGFycmFuZ2UgdG9vbHMiLAogICAgICAgICAgICAgICAgImZyZXF1ZW5jeSI6ICJNT05USExZIiwKICAgICAgICAgICAgICAgICJwb2ludHMiOiAzNSwKICAgICAgICAgICAgICAgICJyb29tIjogIkdhcmFnZSIsCiAgICAgICAgICAgICAgICAiYXNzaWduZWRfdXNlcl9pZCI6IHdpbGxpYW0uaWQsCiAgICAgICAgICAgICAgICAic3RhdHVzIjogIklOX1BST0dSRVNTIgogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAidGl0bGUiOiAiQ2hhbmdlIGFpciBmaWx0ZXJzIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJSZXBsYWNlIEhWQUMgZmlsdGVycyB0aHJvdWdob3V0IGhvdXNlIiwKICAgICAgICAgICAgICAgICJmcmVxdWVuY3kiOiAiTU9OVEhMWSIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogMTAsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJXaG9sZSBIb3VzZSIsCiAgICAgICAgICAgICAgICAiYXNzaWduZWRfdXNlcl9pZCI6IGplc3MuaWQsCiAgICAgICAgICAgICAgICAic3RhdHVzIjogIlBFTkRJTkciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIAogICAgICAgICAgICAjIE9uLXRyaWdnZXIgY2hvcmVzCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJ0aXRsZSI6ICJHcm9jZXJ5IHNob3BwaW5nIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJXZWVrbHkgZ3JvY2VyeSBzaG9wcGluZyB0cmlwIiwKICAgICAgICAgICAgICAgICJmcmVxdWVuY3kiOiAiT05fVFJJR0dFUiIsCiAgICAgICAgICAgICAgICAicG9pbnRzIjogMzAsCiAgICAgICAgICAgICAgICAicm9vbSI6ICJTaG9wcGluZyIsCiAgICAgICAgICAgICAgICAiYXNzaWduZWRfdXNlcl9pZCI6IGxvdS5pZCwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiUEVORElORyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInRpdGxlIjogIkNhciB3YXNoIiwKICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJXYXNoIGFuZCB2YWN1dW0gZmFtaWx5IGNhciIsCiAgICAgICAgICAgICAgICAiZnJlcXVlbmN5IjogIk9OX1RSSUdHRVIiLAogICAgICAgICAgICAgICAgInBvaW50cyI6IDIwLAogICAgICAgICAgICAgICAgInJvb20iOiAiRHJpdmV3YXkiLAogICAgICAgICAgICAgICAgImFzc2lnbmVkX3VzZXJfaWQiOiB4YW5kZXIuaWQsCiAgICAgICAgICAgICAgICAic3RhdHVzIjogIlBFTkRJTkciCiAgICAgICAgICAgIH0sCiAgICAgICAgXQogICAgICAgIAogICAgICAgIGZvciBjaG9yZV9kYXRhIGluIGRlbW9fY2hvcmVzOgogICAgICAgICAgICBjaG9yZSA9IENob3JlKCoqY2hvcmVfZGF0YSkKICAgICAgICAgICAgZGIuYWRkKGNob3JlKQogICAgICAgICAgICAKICAgICAgICAgICAgIyBQcmV0dHkgcHJpbnQgd2l0aCBlbW9qaXMKICAgICAgICAgICAgc3RhdHVzX2Vtb2ppID0gIuKchSIgaWYgY2hvcmVfZGF0YVsic3RhdHVzIl0gPT0gIkNPTVBMRVRFRCIgZWxzZSAi8J+UhCIgaWYgY2hvcmVfZGF0YVsic3RhdHVzIl0gPT0gIklOX1BST0dSRVNTIiBlbHNlICLij7MiCiAgICAgICAgICAgIHByaW50KGYiICB7c3RhdHVzX2Vtb2ppfSB7Y2hvcmVfZGF0YVsndGl0bGUnXX0gLSB7Y2hvcmVfZGF0YVsnZnJlcXVlbmN5J119ICh7Y2hvcmVfZGF0YVsncm9vbSddfSkiKQogICAgICAgIAogICAgICAgIGRiLmNvbW1pdCgpCiAgICAgICAgcHJpbnQoZiJcbuKchSBEYXRhYmFzZSBpbml0aWFsaXplZCBzdWNjZXNzZnVsbHkgd2l0aCB7bGVuKHVzZXJzX2RhdGEpfSB1c2VycyBhbmQge2xlbihkZW1vX2Nob3Jlcyl9IGRlbW8gY2hvcmVzISIpCiAgICAgICAgcHJpbnQoIlxu8J+UkSBMb2dpbiBjcmVkZW50aWFsczoiKQogICAgICAgIHByaW50KCIgICBVc2VybmFtZTogamVzcyAoYWRtaW4pIG9yIGxvdSwgd2lsbGlhbSwgeGFuZGVyLCBiZWxsYSIpCiAgICAgICAgcHJpbnQoIiAgIFBhc3N3b3JkOiBwYXNzd29yZDEyMyIpCiAgICAgICAgCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiLinYwgRXJyb3IgaW5pdGlhbGl6aW5nIGRhdGFiYXNlOiB7ZX0iKQogICAgICAgIGRiLnJvbGxiYWNrKCkKICAgICAgICByYWlzZQogICAgZmluYWxseToKICAgICAgICBkYi5jbG9zZSgpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgaW5pdF9kYigpCg==
|
|
>>>>>>> 65c71b3d67d462fe9ecc01a1c2aa17e54b626fe2
|