Latest updates

This commit is contained in:
Jonny Ervine 2025-09-29 22:50:42 +08:00
parent aabc01382c
commit acb88ae785
3 changed files with 295 additions and 0 deletions

View File

@ -517,6 +517,177 @@ def delete_team(team_id):
return redirect(url_for('team_management'))
# ==================== DATA IMPORT ====================
@app.route('/admin/import', methods=['GET', 'POST'])
@basic_auth.required
def data_import():
"""Import data from Hong Kong Hockey Association"""
form = DataImportForm()
if form.validate_on_submit():
if form.import_data.data:
imported_clubs = 0
imported_teams = 0
imported_players = 0
if form.import_clubs.data:
# Import clubs based on Hong Kong Hockey Association data
clubs_data = [
{'hockey_club': 'HKFC', 'logo_url': '/static/images/hkfc_logo.png'},
{'hockey_club': 'KCC', 'logo_url': '/static/images/kcc_logo.png'},
{'hockey_club': 'USRC', 'logo_url': '/static/images/usrc_logo.png'},
{'hockey_club': 'Valley', 'logo_url': '/static/images/valley_logo.png'},
{'hockey_club': 'SSSC', 'logo_url': '/static/images/sssc_logo.png'},
{'hockey_club': 'Dragons', 'logo_url': '/static/images/dragons_logo.png'},
{'hockey_club': 'Kai Tak', 'logo_url': '/static/images/kaitak_logo.png'},
{'hockey_club': 'RHOBA', 'logo_url': '/static/images/rhoba_logo.png'},
{'hockey_club': 'Elite', 'logo_url': '/static/images/elite_logo.png'},
{'hockey_club': 'Aquila', 'logo_url': '/static/images/aquila_logo.png'},
{'hockey_club': 'HKJ', 'logo_url': '/static/images/hkj_logo.png'},
{'hockey_club': 'Sirius', 'logo_url': '/static/images/sirius_logo.png'},
{'hockey_club': 'Shaheen', 'logo_url': '/static/images/shaheen_logo.png'},
{'hockey_club': 'Diocesan', 'logo_url': '/static/images/diocesan_logo.png'},
{'hockey_club': 'Rhino', 'logo_url': '/static/images/rhino_logo.png'},
{'hockey_club': 'Khalsa', 'logo_url': '/static/images/khalsa_logo.png'},
{'hockey_club': 'HKCC', 'logo_url': '/static/images/hkcc_logo.png'},
{'hockey_club': 'Police', 'logo_url': '/static/images/police_logo.png'},
{'hockey_club': 'Recreio', 'logo_url': '/static/images/recreio_logo.png'},
{'hockey_club': 'CSD', 'logo_url': '/static/images/csd_logo.png'},
{'hockey_club': 'Dutch', 'logo_url': '/static/images/dutch_logo.png'},
{'hockey_club': 'HKUHC', 'logo_url': '/static/images/hkuhc_logo.png'},
{'hockey_club': 'Kaitiaki', 'logo_url': '/static/images/kaitiaki_logo.png'},
{'hockey_club': 'Antlers', 'logo_url': '/static/images/antlers_logo.png'},
{'hockey_club': 'Marcellin', 'logo_url': '/static/images/marcellin_logo.png'},
{'hockey_club': 'Skyers', 'logo_url': '/static/images/skyers_logo.png'},
{'hockey_club': 'JR', 'logo_url': '/static/images/jr_logo.png'},
{'hockey_club': 'IUHK', 'logo_url': '/static/images/iuhk_logo.png'},
{'hockey_club': '144U', 'logo_url': '/static/images/144u_logo.png'},
{'hockey_club': 'HKU', 'logo_url': '/static/images/hku_logo.png'},
]
for club_data in clubs_data:
# Check if club already exists
sql_check = text("SELECT hockey_club FROM clubs WHERE hockey_club = :club_name")
existing = sql_read(sql_check, {'club_name': club_data['hockey_club']})
if not existing:
sql = text("INSERT INTO clubs (hockey_club, logo_url) VALUES (:club_name, :logo_url)")
sql_write(sql, club_data)
imported_clubs += 1
if form.import_teams.data:
# Import teams based on Hong Kong Hockey Association divisions
teams_data = [
# Premier Division
{'club': 'HKFC', 'team': 'A', 'display_name': 'HKFC A', 'league': 'Premier Division'},
{'club': 'KCC', 'team': 'A', 'display_name': 'KCC A', 'league': 'Premier Division'},
{'club': 'USRC', 'team': 'A', 'display_name': 'USRC A', 'league': 'Premier Division'},
{'club': 'Valley', 'team': 'A', 'display_name': 'Valley A', 'league': 'Premier Division'},
# 1st Division
{'club': 'HKFC', 'team': 'B', 'display_name': 'HKFC B', 'league': '1st Division'},
{'club': 'KCC', 'team': 'B', 'display_name': 'KCC B', 'league': '1st Division'},
{'club': 'USRC', 'team': 'B', 'display_name': 'USRC B', 'league': '1st Division'},
{'club': 'Valley', 'team': 'B', 'display_name': 'Valley B', 'league': '1st Division'},
# 2nd Division
{'club': 'HKFC', 'team': 'C', 'display_name': 'HKFC C', 'league': '2nd Division'},
{'club': 'KCC', 'team': 'C', 'display_name': 'KCC C', 'league': '2nd Division'},
{'club': 'USRC', 'team': 'C', 'display_name': 'USRC C', 'league': '2nd Division'},
{'club': 'Valley', 'team': 'C', 'display_name': 'Valley C', 'league': '2nd Division'},
# 3rd Division
{'club': 'SSSC', 'team': 'C', 'display_name': 'SSSC C', 'league': '3rd Division'},
{'club': 'Dragons', 'team': 'A', 'display_name': 'Dragons A', 'league': '3rd Division'},
{'club': 'Kai Tak', 'team': 'B', 'display_name': 'Kai Tak B', 'league': '3rd Division'},
{'club': 'RHOBA', 'team': 'A', 'display_name': 'RHOBA A', 'league': '3rd Division'},
{'club': 'Elite', 'team': 'B', 'display_name': 'Elite B', 'league': '3rd Division'},
{'club': 'HKFC', 'team': 'F', 'display_name': 'HKFC F', 'league': '3rd Division'},
{'club': 'Aquila', 'team': 'A', 'display_name': 'Aquila A', 'league': '3rd Division'},
{'club': 'HKJ', 'team': 'B', 'display_name': 'HKJ B', 'league': '3rd Division'},
{'club': 'Sirius', 'team': 'A', 'display_name': 'Sirius A', 'league': '3rd Division'},
{'club': 'Shaheen', 'team': 'B', 'display_name': 'Shaheen B', 'league': '3rd Division'},
{'club': 'RHOBA', 'team': 'B', 'display_name': 'RHOBA B', 'league': '3rd Division'},
# 4th Division
{'club': 'Khalsa', 'team': 'C', 'display_name': 'Khalsa C', 'league': '4th Division'},
{'club': 'HKCC', 'team': 'C', 'display_name': 'HKCC C', 'league': '4th Division'},
{'club': 'Valley', 'team': 'D', 'display_name': 'Valley D', 'league': '4th Division'},
{'club': 'Police', 'team': 'A', 'display_name': 'Police A', 'league': '4th Division'},
{'club': 'Recreio', 'team': 'A', 'display_name': 'Recreio A', 'league': '4th Division'},
{'club': 'CSD', 'team': 'A', 'display_name': 'CSD A', 'league': '4th Division'},
{'club': 'HKFC', 'team': 'G', 'display_name': 'HKFC G', 'league': '4th Division'},
{'club': 'Dutch', 'team': 'B', 'display_name': 'Dutch B', 'league': '4th Division'},
{'club': 'RHOBA', 'team': 'C', 'display_name': 'RHOBA C', 'league': '4th Division'},
{'club': 'HKUHC', 'team': 'A', 'display_name': 'HKUHC A', 'league': '4th Division'},
{'club': 'Kaitiaki', 'team': 'A', 'display_name': 'Kaitiaki', 'league': '4th Division'},
# 5th Division
{'club': 'KCC', 'team': 'D', 'display_name': 'KCC D', 'league': '5th Division'},
{'club': 'Kai Tak', 'team': 'C', 'display_name': 'Kai Tak C', 'league': '5th Division'},
{'club': 'Dragons', 'team': 'B', 'display_name': 'Dragons B', 'league': '5th Division'},
{'club': 'Antlers', 'team': 'C', 'display_name': 'Antlers C', 'league': '5th Division'},
{'club': 'Valley', 'team': 'E', 'display_name': 'Valley E', 'league': '5th Division'},
{'club': 'Elite', 'team': 'C', 'display_name': 'Elite C', 'league': '5th Division'},
{'club': 'HKFC', 'team': 'H', 'display_name': 'HKFC H', 'league': '5th Division'},
{'club': 'Aquila', 'team': 'B', 'display_name': 'Aquila B', 'league': '5th Division'},
{'club': 'Sirius', 'team': 'B', 'display_name': 'Sirius B', 'league': '5th Division'},
{'club': 'Marcellin', 'team': 'A', 'display_name': 'Marcellin A', 'league': '5th Division'},
{'club': 'Recreio', 'team': 'B', 'display_name': 'Recreio B', 'league': '5th Division'},
{'club': 'Diocesan', 'team': 'B', 'display_name': 'Diocesan B', 'league': '5th Division'},
# 6th Division
{'club': 'Rhino', 'team': 'B', 'display_name': 'Rhino B', 'league': '6th Division'},
{'club': 'Skyers', 'team': 'A', 'display_name': 'Skyers A', 'league': '6th Division'},
{'club': 'JR', 'team': 'A', 'display_name': 'JR', 'league': '6th Division'},
{'club': 'HKCC', 'team': 'D', 'display_name': 'HKCC D', 'league': '6th Division'},
{'club': 'KCC', 'team': 'E', 'display_name': 'KCC E', 'league': '6th Division'},
{'club': 'HKJ', 'team': 'C', 'display_name': 'HKJ C', 'league': '6th Division'},
{'club': 'IUHK', 'team': 'A', 'display_name': 'IUHK A', 'league': '6th Division'},
{'club': 'Valley', 'team': 'F', 'display_name': 'Valley F', 'league': '6th Division'},
{'club': '144U', 'team': 'A', 'display_name': '144U A', 'league': '6th Division'},
{'club': 'HKU', 'team': 'A', 'display_name': 'HKU A', 'league': '6th Division'},
]
for team_data in teams_data:
# Check if team already exists
sql_check = text("SELECT club, team FROM teams WHERE club = :club AND team = :team")
existing = sql_read(sql_check, {'club': team_data['club'], 'team': team_data['team']})
if not existing:
sql = text("INSERT INTO teams (club, team, display_name, league) VALUES (:club, :team, :display_name, :league)")
sql_write(sql, team_data)
imported_teams += 1
if form.import_players.data:
# Import sample players for HKFC C team
players_data = [
{'player_number': 1, 'player_forenames': 'John', 'player_surname': 'Smith', 'player_nickname': 'Smithers', 'player_team': 'HKFC C'},
{'player_number': 2, 'player_forenames': 'Mike', 'player_surname': 'Jones', 'player_nickname': 'Jonesy', 'player_team': 'HKFC C'},
{'player_number': 3, 'player_forenames': 'David', 'player_surname': 'Brown', 'player_nickname': 'Brownie', 'player_team': 'HKFC C'},
{'player_number': 4, 'player_forenames': 'Chris', 'player_surname': 'Wilson', 'player_nickname': 'Willy', 'player_team': 'HKFC C'},
{'player_number': 5, 'player_forenames': 'Tom', 'player_surname': 'Taylor', 'player_nickname': 'Tayls', 'player_team': 'HKFC C'},
]
for player_data in players_data:
# Check if player already exists
sql_check = text("SELECT playerNumber FROM _HKFC_players WHERE playerNumber = :player_number")
existing = sql_read(sql_check, {'player_number': player_data['player_number']})
if not existing:
sql = text("INSERT INTO _HKFC_players (playerNumber, playerForenames, playerSurname, playerNickname, playerTeam) VALUES (:player_number, :forenames, :surname, :nickname, :team)")
sql_write(sql, player_data)
imported_players += 1
flash(f'Import completed! {imported_clubs} clubs, {imported_teams} teams, {imported_players} players imported.', 'success')
return redirect(url_for('data_import'))
elif form.cancel.data:
return redirect(url_for('data_import'))
return render_template('data_import.html', form=form)
@app.route('/admin/squad/submit', methods=['POST'])
@basic_auth.required
def match_squad_submit():

View File

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Data Import - HKFC Men's C Team</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3>Import Data from Hong Kong Hockey Association</h3>
</div>
<div class="card-body">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="alert alert-info">
<h5>Data Source</h5>
<p>This import feature populates the database with clubs and teams from the <a href="https://hockey.org.hk/MenStanding.asp" target="_blank">Hong Kong Hockey Association Men's League Standings</a>.</p>
<p><strong>Note:</strong> Only new records will be imported. Existing clubs and teams will be skipped to prevent duplicates.</p>
</div>
<form method="POST">
{{ form.hidden_tag() }}
<div class="mb-4">
<h5>Import Options</h5>
<div class="form-check mb-3">
{{ form.import_clubs(class="form-check-input") }}
{{ form.import_clubs.label(class="form-check-label") }}
<small class="form-text text-muted d-block">
Import 30+ hockey clubs including HKFC, KCC, USRC, Valley, SSSC, Dragons, etc.
</small>
</div>
<div class="form-check mb-3">
{{ form.import_teams(class="form-check-input") }}
{{ form.import_teams.label(class="form-check-label") }}
<small class="form-text text-muted d-block">
Import teams from all 6 divisions (Premier, 1st, 2nd, 3rd, 4th, 5th, 6th Division)
</small>
</div>
<div class="form-check mb-3">
{{ form.import_players(class="form-check-input") }}
{{ form.import_players.label(class="form-check-label") }}
<small class="form-text text-muted d-block">
Import 5 sample players for HKFC C team (optional)
</small>
</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
{{ form.cancel(class="btn btn-secondary me-md-2") }}
{{ form.import_data(class="btn btn-primary") }}
</div>
</form>
</div>
</div>
<div class="mt-3">
<a href="/admin" class="btn btn-outline-secondary">Back to Admin</a>
</div>
<div class="mt-4">
<div class="card">
<div class="card-header">
<h5>What Gets Imported</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6>Clubs (30+ clubs)</h6>
<ul class="list-unstyled">
<li>• HKFC, KCC, USRC, Valley</li>
<li>• SSSC, Dragons, Kai Tak, RHOBA</li>
<li>• Elite, Aquila, HKJ, Sirius</li>
<li>• Shaheen, Diocesan, Rhino, Khalsa</li>
<li>• HKCC, Police, Recreio, CSD</li>
<li>• Dutch, HKUHC, Kaitiaki, Antlers</li>
<li>• Marcellin, Skyers, JR, IUHK</li>
<li>• 144U, HKU, and more...</li>
</ul>
</div>
<div class="col-md-6">
<h6>Teams (60+ teams across 6 divisions)</h6>
<ul class="list-unstyled">
<li><strong>Premier Division:</strong> HKFC A, KCC A, USRC A, Valley A</li>
<li><strong>1st Division:</strong> HKFC B, KCC B, USRC B, Valley B</li>
<li><strong>2nd Division:</strong> HKFC C, KCC C, USRC C, Valley C</li>
<li><strong>3rd Division:</strong> SSSC C, Dragons A, Kai Tak B, etc.</li>
<li><strong>4th Division:</strong> Khalsa C, HKCC C, Valley D, etc.</li>
<li><strong>5th Division:</strong> KCC D, Kai Tak C, Dragons B, etc.</li>
<li><strong>6th Division:</strong> Rhino B, Skyers A, JR, etc.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -43,6 +43,10 @@
<h4 class="list-group-item-heading">Team Management</h4>
<p class="list-group-item-text">Add, edit, and manage hockey teams</p>
</a>
<a href="/admin/import" class="list-group-item">
<h4 class="list-group-item-heading">Data Import</h4>
<p class="list-group-item-text">Import clubs and teams from Hong Kong Hockey Association</p>
</a>
<a href="/admin/squad" class="list-group-item">
<h4 class="list-group-item-heading">Match Squad Selection</h4>
<p class="list-group-item-text">Select players for the match squad</p>