Add public kiosk page with QR/pricing cycle and configurable slide timing
This commit is contained in:
parent
a25bf3a9c9
commit
c726525c8e
5 changed files with 351 additions and 1 deletions
92
app.py
92
app.py
|
|
@ -282,6 +282,32 @@ def get_refresh_seconds():
|
|||
return val if val in (10, 20, 30) else 10
|
||||
|
||||
|
||||
def get_kiosk_cycle_seconds():
|
||||
"""Return the kiosk slide cycle interval in seconds. 0 = static price list; 5+ cycles QR and pricing."""
|
||||
cfg = load_booth_settings()
|
||||
try:
|
||||
val = int(cfg.get('kiosk_cycle_seconds', 10))
|
||||
except (ValueError, TypeError):
|
||||
val = 10
|
||||
if val == 0:
|
||||
return 0
|
||||
return max(5, val)
|
||||
|
||||
|
||||
def get_kiosk_mode():
|
||||
"""Return 'cycle', 'qr', or 'prices' based on kiosk_cycle_seconds setting."""
|
||||
cfg = load_booth_settings()
|
||||
try:
|
||||
val = int(cfg.get('kiosk_cycle_seconds', 10))
|
||||
except (ValueError, TypeError):
|
||||
val = 10
|
||||
if val == -1:
|
||||
return 'qr'
|
||||
if val == 0:
|
||||
return 'prices'
|
||||
return 'cycle'
|
||||
|
||||
|
||||
def get_hermes_api_key():
|
||||
"""
|
||||
Return the effective Hermes API key.
|
||||
|
|
@ -847,6 +873,49 @@ def admin_pricing():
|
|||
return render_template('admin/pricing.html', fixed=fixed, customs=customs)
|
||||
|
||||
|
||||
@app.route('/kiosk')
|
||||
def kiosk():
|
||||
"""
|
||||
Public kiosk display page for the booth.
|
||||
Shows open/closed banner, pricing, and optionally cycles with a QR code.
|
||||
Auto-refreshes so pricing updates are picked up quickly.
|
||||
"""
|
||||
cfg = load_booth_settings()
|
||||
pricing = cfg.get('pricing', {})
|
||||
|
||||
fixed_keys = {
|
||||
'one_song': 'One Song',
|
||||
'both_songs': 'Both Songs',
|
||||
'wav_per_song': 'WAV files / song',
|
||||
'stems_per_song': 'STEM files / song'
|
||||
}
|
||||
price_items = []
|
||||
for key, label in fixed_keys.items():
|
||||
val = pricing.get(key, '').strip()
|
||||
if val:
|
||||
price_items.append({'label': label, 'price': val})
|
||||
for i in range(1, 6):
|
||||
entry = pricing.get(f'custom_{i}')
|
||||
if isinstance(entry, dict):
|
||||
name = entry.get('name', '').strip()
|
||||
price = entry.get('price', '').strip()
|
||||
if name and price:
|
||||
price_items.append({'label': name, 'price': price})
|
||||
|
||||
cycle_seconds = get_kiosk_cycle_seconds()
|
||||
mode = get_kiosk_mode()
|
||||
booth_open = get_booth_open()
|
||||
|
||||
return render_template(
|
||||
'kiosk.html',
|
||||
booth_open=booth_open,
|
||||
price_items=price_items,
|
||||
cycle_seconds=cycle_seconds,
|
||||
mode=mode,
|
||||
refresh_seconds=30
|
||||
)
|
||||
|
||||
|
||||
@app.route('/admin/request/<int:rid>', methods=['GET', 'POST'])
|
||||
def admin_request(rid):
|
||||
"""
|
||||
|
|
@ -1248,6 +1317,28 @@ def admin_settings():
|
|||
flash(f'Dashboard auto-refresh set to {val} seconds.', 'success')
|
||||
return redirect(url_for('admin_settings'))
|
||||
|
||||
elif action == 'save_kiosk_cycle':
|
||||
# Update kiosk slide cycle interval. Special values:
|
||||
# -1 = show QR only, 0 = show pricing only, 5+ = cycle every N seconds.
|
||||
raw = request.form.get('kiosk_cycle_seconds', '10').strip()
|
||||
try:
|
||||
val = int(raw)
|
||||
except ValueError:
|
||||
val = 10
|
||||
if val not in (-1, 0) and val < 5:
|
||||
val = 5
|
||||
cfg = load_booth_settings()
|
||||
cfg['kiosk_cycle_seconds'] = val
|
||||
save_booth_settings(cfg)
|
||||
if val == -1:
|
||||
label = 'QR code only'
|
||||
elif val == 0:
|
||||
label = 'pricing only'
|
||||
else:
|
||||
label = f'cycle every {val} seconds'
|
||||
flash(f'Kiosk mode set to {label}.', 'success')
|
||||
return redirect(url_for('admin_settings'))
|
||||
|
||||
elif action == 'save_booth_open':
|
||||
# Toggle whether the public request form is accepting submissions.
|
||||
cfg = load_booth_settings()
|
||||
|
|
@ -1327,6 +1418,7 @@ def admin_settings():
|
|||
upload_path=str(upload_root),
|
||||
current_max_revisions=current_max_revisions,
|
||||
current_refresh_seconds=current_refresh_seconds,
|
||||
current_kiosk_cycle_seconds=get_kiosk_cycle_seconds(),
|
||||
booth_open=booth_open,
|
||||
email_form=email_form,
|
||||
metadata={
|
||||
|
|
|
|||
Reference in a new issue