File size: 7,535 Bytes
7b84343 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | from flask import Flask, render_template, request, jsonify
from flask_cors import CORS
import csv
import io
import os
from werkzeug.utils import secure_filename
app = Flask(__name__)
CORS(app)
# Configure upload settings
UPLOAD_FOLDER = '/tmp/uploads' # Use /tmp for AWS Lambda compatibility
ALLOWED_EXTENSIONS = {'csv'}
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def parse_csv_file(file_content):
"""Parse CSV content and extract guest information from name and message columns"""
try:
# Decode the file content
if isinstance(file_content, bytes):
file_content = file_content.decode('utf-8')
# Create a StringIO object to read the CSV
csv_file = io.StringIO(file_content)
# Read CSV with different possible delimiters
for delimiter in [',', ';', '\t']:
try:
csv_file.seek(0) # Reset file pointer
reader = csv.DictReader(csv_file, delimiter=delimiter)
# Get the header row
headers = reader.fieldnames
if not headers or len(headers) < 2:
continue
# Use the first two columns: name and message
name_column = headers[0]
message_column = headers[1]
# Parse the data and filter out entries with blank names or descriptions
guests = []
for i, row in enumerate(reader):
name = row.get(name_column, '').strip()
title = row.get(message_column, '').strip()
# Only add if both name and description are not blank
if name and title:
guests.append({
'id': i,
'name': name,
'title': title
})
if guests:
return {'success': True, 'guests': guests, 'total': len(guests)}
except Exception as e:
continue
return {'success': False, 'error': 'Could not parse CSV file. Please ensure it has at least 2 columns (name and message).'}
except Exception as e:
return {'success': False, 'error': f'Error parsing CSV: {str(e)}'}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload-csv', methods=['POST'])
def upload_csv():
"""Handle CSV file upload"""
try:
if 'file' not in request.files:
return jsonify({'success': False, 'error': 'No file uploaded'})
file = request.files['file']
if file.filename == '':
return jsonify({'success': False, 'error': 'No file selected'})
if not allowed_file(file.filename):
return jsonify({'success': False, 'error': 'Please upload a CSV file'})
# Read file content
file_content = file.read()
# Parse CSV
result = parse_csv_file(file_content)
if result['success']:
return jsonify({
'success': True,
'guests': result['guests'],
'total': result['total'],
'message': f'Successfully loaded {result["total"]} guests from CSV (filtered out entries with blank names or descriptions)'
})
else:
return jsonify(result)
except Exception as e:
return jsonify({'success': False, 'error': f'Upload error: {str(e)}'})
@app.route('/arrange-tables', methods=['POST'])
def arrange_tables():
data = request.get_json()
selected_guests = data.get('selected_guests', [])
if not selected_guests:
return jsonify({'success': False, 'error': 'No guests selected for arrangement'})
# Smart arrangement algorithm - create unlimited tables of 10
tables = arrange_guests_into_tables(selected_guests)
return jsonify({'success': True, 'tables': tables})
def arrange_guests_into_tables(guests):
"""Arrange guests into tables of 10 people each with smart distribution"""
if not guests:
return []
# Categorize guests by industry/role type based on message content
categories = {
'tech': ['engineer', 'developer', 'programmer', 'software', 'tech', 'it', 'data', 'ai', 'ml', 'technology', 'scientist'],
'business': ['manager', 'director', 'ceo', 'founder', 'executive', 'business', 'strategy', 'operations', 'consultant', 'product'],
'creative': ['designer', 'creative', 'marketing', 'content', 'writer', 'artist', 'media', 'communications', 'strategist'],
'sales': ['sales', 'account', 'client', 'business development', 'partnership', 'account manager'],
'finance': ['finance', 'accounting', 'investment', 'banking', 'financial', 'analyst', 'cfo'],
'other': []
}
categorized_guests = {cat: [] for cat in categories.keys()}
# Categorize each guest based on their message/description
for guest in guests:
title_lower = guest['title'].lower()
categorized = False
for category, keywords in categories.items():
if category == 'other':
continue
if any(keyword in title_lower for keyword in keywords):
categorized_guests[category].append(guest)
categorized = True
break
if not categorized:
categorized_guests['other'].append(guest)
# Calculate how many tables we need
total_guests = len(guests)
num_tables = (total_guests + 9) // 10 # Ceiling division to get number of tables needed
# Initialize tables
tables = [[] for _ in range(num_tables)]
# Distribute guests strategically across all tables
# First, distribute major categories evenly
major_categories = ['tech', 'business', 'creative', 'sales']
for category in major_categories:
guests_in_category = categorized_guests[category]
if guests_in_category:
# Distribute evenly across all tables
for i, guest in enumerate(guests_in_category):
table_index = i % num_tables
if len(tables[table_index]) < 10:
tables[table_index].append(guest)
# Then distribute remaining guests (finance, other)
remaining_guests = []
for category in ['finance', 'other']:
remaining_guests.extend(categorized_guests[category])
# Also add any guests that didn't fit in the first round
for table in tables:
for guest in guests:
if guest not in [g for table_guests in tables for g in table_guests]:
if len(table) < 10:
table.append(guest)
break
# Fill remaining slots with any leftover guests
for guest in guests:
if guest not in [g for table_guests in tables for g in table_guests]:
for table in tables:
if len(table) < 10:
table.append(guest)
break
return tables
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000) |