sailing_forms/app.py
Feiko Wielsma c160446eac Enhance event registration system:
- Update Google Sheets integration to support optional tab names.
- Add functionality to fetch and display public participants.
- Revise event configuration in YAML for clarity and consistency.
- Improve form layout with additional fields for contact information and meal preferences.
- Create a new home page template for event selection.
- Update success page to link back to the participants list.
2025-11-26 17:47:20 +01:00

152 lines
No EOL
5.7 KiB
Python

import os
import yaml
import gspread
from flask import Flask, render_template, request, redirect, url_for, abort
from datetime import datetime
app = Flask(__name__)
# Load Configuration
def load_config():
with open('events.yaml', 'r') as f:
return yaml.safe_load(f)
# Connect to Google Sheets
# UPDATED: Now accepts an optional tab_name
def get_google_sheet(sheet_id, tab_name=None):
gc = gspread.service_account(filename='credentials.json')
try:
sh = gc.open_by_key(sheet_id)
if tab_name:
# Open specific tab by name
return sh.worksheet(tab_name)
else:
# Default to first tab
return sh.sheet1
except Exception as e:
print(f"Error connecting to Google Sheet (ID: {sheet_id}, Tab: {tab_name}): {e}")
return None
# NEW: Fetch and filter participants for public display
# UPDATED: Now accepts tab_name
def get_public_participants(sheet_id, tab_name=None):
sheet = get_google_sheet(sheet_id, tab_name)
if not sheet:
return []
try:
# Get all rows
rows = sheet.get_all_values()
# Skip header row (assuming row 1 is header)
if len(rows) > 1:
data_rows = rows[1:]
else:
return []
public_list = []
for row in data_rows:
# Ensure row is long enough to avoid errors
if len(row) < 17:
continue
# Extract ONLY non-sensitive columns based on our save order
# 1: Klasse, 2: Zeilnummer, 3: Bootnaam, 4: Boottype
# 7: Naam, 10: Plaats, 16: Vereniging
entry = {
'klasse': row[1],
'zeilnummer': row[2],
'bootnaam': row[3],
'boottype': row[4],
'naam': row[7],
'plaats': row[10],
'vereniging': row[16]
}
public_list.append(entry)
return public_list
except Exception as e:
print(f"Error fetching participants: {e}")
return []
@app.route('/')
def home():
config = load_config()
events = config.get('events', {})
return render_template('home.html', events=events)
@app.route('/<event_slug>', methods=['GET', 'POST'])
def event_form(event_slug):
config = load_config()
events = config.get('events', {})
# Check for global sheet_id fallback
global_sheet_id = config.get('master_sheet_id')
if event_slug not in events:
abort(404)
event_data = events[event_slug]
# Determine which Sheet ID to use (Event specific > Global)
sheet_id = event_data.get('sheet_id', global_sheet_id)
# Get Tab Name (optional)
tab_name = event_data.get('tab_name')
# Ensure we have a valid sheet ID before proceeding
if not sheet_id:
return "Configuration Error: No 'sheet_id' found in event config or 'master_sheet_id' in root config."
# Update event_data with resolved sheet_id so templates work correctly
event_data['sheet_id'] = sheet_id
if request.method == 'POST':
form_data = [
datetime.now().strftime("%Y-%m-%d %H:%M:%S"), # 0: Timestamp
request.form.get('klasse'), # 1: Klasse
request.form.get('zeilnummer'), # 2: Zeilnummer
request.form.get('bootnaam'), # 3: Bootnaam
request.form.get('boottype'), # 4: Boottype
", ".join([k for k in ['genua', 'rolfok', 'spinaker', 'halfwinder', 'genaker', 'dacron'] if k in request.form]), # 5: Zeilvoering
request.form.get('schroef'), # 6: Schroef
request.form.get('naam'), # 7: Naam (Keep public)
request.form.get('straat'), # 8: Straat (PRIVATE)
request.form.get('postcode'), # 9: Postcode (PRIVATE)
request.form.get('plaats'), # 10: Plaats
request.form.get('land'), # 11: Land
request.form.get('telefoonmobiel'), # 12: Mobiel (PRIVATE)
request.form.get('telefoonvast'), # 13: Vast (PRIVATE)
request.form.get('email'), # 14: Email (PRIVATE)
request.form.get('startlicentienummer'), # 15: Licentie
request.form.get('vereniging'), # 16: Vereniging
request.form.get('buffet', '0'), # 17: Buffet
request.form.get('ontbijt', '0'), # 18: Ontbijt
request.form.get('opmerkingen') # 19: Opmerkingen
]
sheet = get_google_sheet(sheet_id, tab_name)
if sheet:
sheet.append_row(form_data)
return redirect(url_for('success', event_slug=event_slug))
else:
return f"Error: Could not connect to Google Sheet Tab '{tab_name}'. Check server logs."
# GET Request: Fetch participants to show at bottom of form
participants = get_public_participants(sheet_id, tab_name)
return render_template('form.html', event=event_data, slug=event_slug, participants=participants)
@app.route('/<event_slug>/success')
def success(event_slug):
config = load_config()
event_data = config['events'].get(event_slug)
# Resolve sheet ID for the success page link too
global_sheet_id = config.get('master_sheet_id')
sheet_id = event_data.get('sheet_id', global_sheet_id)
event_data['sheet_id'] = sheet_id
# Pass slug so we can link back
return render_template('success.html', event=event_data, slug=event_slug)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)