#!/usr/bin/env python3 """Database initialization script for NetEvent platform.""" import mysql.connector from mysql.connector import Error DB_HOST = 'roast.duckdns.org' DB_PORT = 33062 DB_USER = 'root' DB_PASSWORD = 'Tiegl!!!111...' DB_NAME = 'netevent' APP_USER = 'netevent_app' APP_PASSWORD = 'netevent_pass_2024' def create_database(): """Create the database and dedicated user.""" try: conn = mysql.connector.connect( host=DB_HOST, port=DB_PORT, user=DB_USER, password=DB_PASSWORD ) cursor = conn.cursor() # Create database if not exists cursor.execute(f"CREATE DATABASE IF NOT EXISTS {DB_NAME}") print(f"Database '{DB_NAME}' created or already exists.") # Create dedicated application user cursor.execute(f"CREATE USER IF NOT EXISTS '{APP_USER}'@'%' IDENTIFIED BY '{APP_PASSWORD}'") cursor.execute(f"GRANT ALL PRIVILEGES ON {DB_NAME}.* TO '{APP_USER}'@'%'") cursor.execute("FLUSH PRIVILEGES") print(f"User '{APP_USER}' created with privileges on '{DB_NAME}'.") conn.commit() cursor.close() conn.close() return True except Error as e: print(f"Error creating database/user: {e}") return False def create_tables(): """Create all required tables.""" tables = [ """ CREATE TABLE IF NOT EXISTS organizers ( id INT PRIMARY KEY AUTO_INCREMENT, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """, """ CREATE TABLE IF NOT EXISTS events ( id INT PRIMARY KEY AUTO_INCREMENT, organizer_id INT NOT NULL, code VARCHAR(10) UNIQUE NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, start_time DATETIME NOT NULL, end_time DATETIME, location VARCHAR(255), max_attendees INT DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (organizer_id) REFERENCES organizers(id) ON DELETE CASCADE ) """, """ CREATE TABLE IF NOT EXISTS attendees ( id INT PRIMARY KEY AUTO_INCREMENT, event_id INT NOT NULL, email VARCHAR(255) NOT NULL, password_hash VARCHAR(255) NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, organisation VARCHAR(255), role VARCHAR(255), introduction TEXT, profile_picture VARCHAR(255) DEFAULT NULL, checked_in BOOLEAN DEFAULT FALSE, attendance_status ENUM('attending', 'not_attending') DEFAULT 'attending', confirmation_token VARCHAR(64) DEFAULT NULL, attendee_code VARCHAR(10) UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE, UNIQUE KEY unique_attendee_event (event_id, email) ) """, """ CREATE TABLE IF NOT EXISTS connections ( id INT PRIMARY KEY AUTO_INCREMENT, attendee_id INT NOT NULL, connected_attendee_id INT NOT NULL, status ENUM('pending', 'accepted', 'rejected') DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (attendee_id) REFERENCES attendees(id) ON DELETE CASCADE, FOREIGN KEY (connected_attendee_id) REFERENCES attendees(id) ON DELETE CASCADE, UNIQUE KEY unique_connection (attendee_id, connected_attendee_id) ) """, """ CREATE TABLE IF NOT EXISTS appointments ( id INT PRIMARY KEY AUTO_INCREMENT, event_id INT NOT NULL, requester_id INT NOT NULL, target_id INT NOT NULL, appointment_time DATETIME NOT NULL, location VARCHAR(255), notes TEXT, status ENUM('pending', 'accepted', 'rejected') DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE, FOREIGN KEY (requester_id) REFERENCES attendees(id) ON DELETE CASCADE, FOREIGN KEY (target_id) REFERENCES attendees(id) ON DELETE CASCADE ) """, """ CREATE TABLE IF NOT EXISTS breakout_sessions ( id INT PRIMARY KEY AUTO_INCREMENT, code VARCHAR(10) NOT NULL UNIQUE, event_id INT NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, location VARCHAR(255), max_attendees INT DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE ) """, """ CREATE TABLE IF NOT EXISTS breakout_session_organizers ( id INT PRIMARY KEY AUTO_INCREMENT, breakout_session_id INT NOT NULL, organizer_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (breakout_session_id) REFERENCES breakout_sessions(id) ON DELETE CASCADE, FOREIGN KEY (organizer_id) REFERENCES organizers(id) ON DELETE CASCADE, UNIQUE KEY unique_session_organizer (breakout_session_id, organizer_id) ) """, """ CREATE TABLE IF NOT EXISTS breakout_session_rsvps ( id INT PRIMARY KEY AUTO_INCREMENT, breakout_session_id INT NOT NULL, attendee_id INT NOT NULL, status ENUM('registered', 'cancelled') DEFAULT 'registered', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (breakout_session_id) REFERENCES breakout_sessions(id) ON DELETE CASCADE, FOREIGN KEY (attendee_id) REFERENCES attendees(id) ON DELETE CASCADE, UNIQUE KEY unique_rsvp (breakout_session_id, attendee_id) ) """, """ CREATE TABLE IF NOT EXISTS staff ( id INT PRIMARY KEY AUTO_INCREMENT, event_id INT NOT NULL, email VARCHAR(255) NOT NULL, password_hash VARCHAR(255) DEFAULT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, invite_token VARCHAR(64) DEFAULT NULL, invite_used BOOLEAN DEFAULT FALSE, preferred_language VARCHAR(5) DEFAULT 'en', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE, UNIQUE KEY unique_staff_event (event_id, email) ) """, # Languages table """ CREATE TABLE IF NOT EXISTS languages ( code VARCHAR(5) PRIMARY KEY, name VARCHAR(50) NOT NULL, native_name VARCHAR(50) NOT NULL, is_active BOOLEAN DEFAULT TRUE, is_default BOOLEAN DEFAULT FALSE, date_format VARCHAR(30) DEFAULT '%B %d, %Y at %H:%M', sort_order INT DEFAULT 0 ) """, """ CREATE TABLE IF NOT EXISTS attendee_types ( id INT PRIMARY KEY AUTO_INCREMENT, event_id INT NOT NULL, code VARCHAR(10) UNIQUE NOT NULL, name VARCHAR(100) NOT NULL, price DECIMAL(10,2) DEFAULT 0.00, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE ) """ ] # Alter existing tables to add preferred_language column alter_statements = [ "ALTER TABLE organizers ADD COLUMN preferred_language VARCHAR(5) DEFAULT 'en'", "ALTER TABLE attendees ADD COLUMN preferred_language VARCHAR(5) DEFAULT 'en'", "ALTER TABLE attendees ADD COLUMN attendee_code VARCHAR(10) UNIQUE", "ALTER TABLE attendees ADD COLUMN phone VARCHAR(50) DEFAULT ''", "ALTER TABLE attendees ADD COLUMN linkedin VARCHAR(255) DEFAULT ''", "ALTER TABLE attendees ADD COLUMN attendee_type_id INT DEFAULT NULL", ] try: conn = mysql.connector.connect( host=DB_HOST, port=DB_PORT, user=APP_USER, password=APP_PASSWORD, database=DB_NAME ) cursor = conn.cursor() for table_sql in tables: cursor.execute(table_sql) # Alter existing tables for alter_sql in alter_statements: try: cursor.execute(alter_sql) except Error as e: # Column might already exist if e.errno != 1060: # Duplicate column name print(f"Warning: {e}") # Add foreign key constraint for attendee_type_id try: cursor.execute(""" ALTER TABLE attendees ADD CONSTRAINT fk_attendee_type FOREIGN KEY (attendee_type_id) REFERENCES attendee_types(id) ON DELETE SET NULL """) except Error as e: if e.errno != 1060 and e.errno != 1826: # Not duplicate column or duplicate FK print(f"Warning adding FK: {e}") conn.commit() cursor.close() conn.close() print("All tables created successfully.") return True except Error as e: print(f"Error creating tables: {e}") return False def seed_languages(): """Seed the languages table with EU languages.""" languages = [ ('en', 'English', 'English', True, True, '%B %d, %Y at %H:%M', 1), ('nl', 'Dutch', 'Nederlands', True, False, '%d %B %Y om %H:%M', 2), ('de', 'German', 'Deutsch', True, False, '%d. %B %Y um %H:%M', 3), ('fr', 'French', 'Français', True, False, '%d %B %Y à %H:%M', 4), ('es', 'Spanish', 'Español', True, False, '%d de %B de %Y a las %H:%M', 5), ('it', 'Italian', 'Italiano', True, False, '%d %B %Y alle %H:%M', 6), ('pl', 'Polish', 'Polski', True, False, '%d %B %Y o %H:%M', 7), ] try: conn = mysql.connector.connect( host=DB_HOST, port=DB_PORT, user=APP_USER, password=APP_PASSWORD, database=DB_NAME ) cursor = conn.cursor() for lang in languages: cursor.execute(""" INSERT IGNORE INTO languages (code, name, native_name, is_active, is_default, date_format, sort_order) VALUES (%s, %s, %s, %s, %s, %s, %s) """, lang) conn.commit() cursor.close() conn.close() print("Languages seeded successfully.") return True except Error as e: print(f"Error seeding languages: {e}") return False def init_database(): """Initialize the complete database.""" print("Initializing NetEvent database...") if create_database(): if create_tables(): seed_languages() print("Database initialization complete!") return True print("Database initialization failed.") return False if __name__ == '__main__': init_database()