
Complete church management system with bulletin management, media processing, live streaming integration, and web interface. Includes authentication, email notifications, database migrations, and comprehensive test suite.
139 lines
4.5 KiB
Python
139 lines
4.5 KiB
Python
import json
|
|
import psycopg2
|
|
import os
|
|
from datetime import datetime
|
|
import uuid
|
|
|
|
# Connect to database
|
|
conn = psycopg2.connect(os.environ['DATABASE_URL'])
|
|
cur = conn.cursor()
|
|
|
|
def load_json(filename):
|
|
try:
|
|
with open(f'/tmp/pb_migration/{filename}', 'r') as f:
|
|
data = json.load(f)
|
|
return data.get('items', [])
|
|
except Exception as e:
|
|
print(f"Error loading {filename}: {e}")
|
|
return []
|
|
|
|
def convert_pb_date(pb_date):
|
|
"""Convert PocketBase date to PostgreSQL timestamp"""
|
|
if not pb_date:
|
|
return None
|
|
try:
|
|
dt_str = pb_date.replace('Z', '+00:00')
|
|
return datetime.fromisoformat(dt_str)
|
|
except:
|
|
return None
|
|
|
|
def clean_recurring_type(value):
|
|
"""Clean recurring type field"""
|
|
if not value or value == '':
|
|
return None
|
|
return value
|
|
|
|
# Rollback any pending transaction
|
|
conn.rollback()
|
|
|
|
# Clear existing data
|
|
print("🧹 Clearing existing data...")
|
|
cur.execute("DELETE FROM bulletins")
|
|
cur.execute("DELETE FROM events")
|
|
|
|
# Import bulletins
|
|
print("📄 Importing bulletins...")
|
|
bulletins = load_json('bulletins.json')
|
|
print(f"Found {len(bulletins)} bulletins to import")
|
|
|
|
for i, bulletin in enumerate(bulletins):
|
|
try:
|
|
cur.execute("""
|
|
INSERT INTO bulletins (id, title, date, url, pdf_url, is_active, pdf_file,
|
|
sabbath_school, divine_worship, scripture_reading, sunset,
|
|
cover_image, created_at, updated_at)
|
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
""", (
|
|
str(uuid.uuid4()),
|
|
bulletin.get('title', ''),
|
|
bulletin.get('date'),
|
|
bulletin.get('url'),
|
|
bulletin.get('pdf_url'),
|
|
bulletin.get('is_active', True),
|
|
bulletin.get('pdf'),
|
|
bulletin.get('sabbath_school', ''),
|
|
bulletin.get('divine_worship', ''),
|
|
bulletin.get('scripture_reading'),
|
|
bulletin.get('sunset', ''),
|
|
bulletin.get('cover_image'),
|
|
convert_pb_date(bulletin.get('created')),
|
|
convert_pb_date(bulletin.get('updated'))
|
|
))
|
|
print(f" ✅ Imported bulletin {i+1}: {bulletin.get('title')}")
|
|
except Exception as e:
|
|
print(f" ❌ Failed to import bulletin {i+1}: {e}")
|
|
continue
|
|
|
|
# Import events
|
|
print("📅 Importing events...")
|
|
events = load_json('events.json')
|
|
print(f"Found {len(events)} events to import")
|
|
|
|
for i, event in enumerate(events):
|
|
try:
|
|
cur.execute("""
|
|
INSERT INTO events (id, title, description, start_time, end_time, location,
|
|
location_url, image, thumbnail, category, is_featured,
|
|
recurring_type, approved_from, created_at, updated_at)
|
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
|
""", (
|
|
str(uuid.uuid4()),
|
|
event.get('title', ''),
|
|
event.get('description', ''),
|
|
event.get('start_time'),
|
|
event.get('end_time'),
|
|
event.get('location', ''),
|
|
event.get('location_url'),
|
|
event.get('image'),
|
|
event.get('thumbnail'),
|
|
event.get('category', 'Other'),
|
|
event.get('is_featured', False),
|
|
clean_recurring_type(event.get('reoccuring')), # Fix this field
|
|
event.get('approved_from') if event.get('approved_from') else None,
|
|
convert_pb_date(event.get('created')),
|
|
convert_pb_date(event.get('updated'))
|
|
))
|
|
print(f" ✅ Imported event {i+1}: {event.get('title')}")
|
|
except Exception as e:
|
|
print(f" ❌ Failed to import event {i+1}: {e}")
|
|
print(f" Title: {event.get('title')}")
|
|
continue
|
|
|
|
# Commit all changes
|
|
conn.commit()
|
|
print("✅ Migration completed!")
|
|
|
|
# Show final results
|
|
cur.execute("SELECT COUNT(*) FROM bulletins")
|
|
bulletin_count = cur.fetchone()[0]
|
|
cur.execute("SELECT COUNT(*) FROM events")
|
|
event_count = cur.fetchone()[0]
|
|
|
|
print(f"📊 Final Results:")
|
|
print(f" Bulletins: {bulletin_count}")
|
|
print(f" Events: {event_count}")
|
|
|
|
# Show sample data
|
|
print(f"\n📄 Sample bulletins:")
|
|
cur.execute("SELECT title, date FROM bulletins ORDER BY date DESC LIMIT 3")
|
|
for row in cur.fetchall():
|
|
print(f" - {row[0]} ({row[1]})")
|
|
|
|
print(f"\n📅 Sample events:")
|
|
cur.execute("SELECT title, start_time FROM events ORDER BY start_time LIMIT 3")
|
|
for row in cur.fetchall():
|
|
print(f" - {row[0]} ({row[1]})")
|
|
|
|
cur.close()
|
|
conn.close()
|