- 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.
152 lines
No EOL
5.7 KiB
Python
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) |