Initial commit: conference app with Flask
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+302
@@ -0,0 +1,302 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user