
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.
120 lines
4.1 KiB
Python
120 lines
4.1 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:
|
|
# Remove 'Z' and parse
|
|
dt_str = pb_date.replace('Z', '+00:00')
|
|
return datetime.fromisoformat(dt_str)
|
|
except:
|
|
print(f"Failed to parse date: {pb_date}")
|
|
return None
|
|
|
|
# Clear existing data (except users)
|
|
print("🧹 Clearing existing data...")
|
|
cur.execute("DELETE FROM bulletins WHERE id != '00000000-0000-0000-0000-000000000000'")
|
|
cur.execute("DELETE FROM events WHERE id != '00000000-0000-0000-0000-000000000000'")
|
|
|
|
# Import bulletins
|
|
print("📄 Importing bulletins...")
|
|
bulletins = load_json('bulletins.json')
|
|
print(f"Found {len(bulletins)} bulletins to import")
|
|
|
|
for bulletin in 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'), # PocketBase dates should work directly
|
|
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.get('title')}")
|
|
except Exception as e:
|
|
print(f" ❌ Failed to import bulletin: {e}")
|
|
print(f" Data: {bulletin}")
|
|
|
|
# Import events
|
|
print("📅 Importing events...")
|
|
events = load_json('events.json')
|
|
print(f"Found {len(events)} events to import")
|
|
|
|
for event in 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'), # Let PostgreSQL handle the date conversion
|
|
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),
|
|
event.get('reoccuring'), # Note: PocketBase spells it 'reoccuring'
|
|
event.get('approved_from'),
|
|
convert_pb_date(event.get('created')),
|
|
convert_pb_date(event.get('updated'))
|
|
))
|
|
print(f" ✅ Imported: {event.get('title')}")
|
|
except Exception as e:
|
|
print(f" ❌ Failed to import event: {e}")
|
|
print(f" Data: {event}")
|
|
|
|
# Commit changes
|
|
conn.commit()
|
|
print("✅ Migration fixed!")
|
|
|
|
# Show 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"📊 Results:")
|
|
print(f" Bulletins: {bulletin_count}")
|
|
print(f" Events: {event_count}")
|
|
|
|
cur.close()
|
|
conn.close()
|