Files
admin 209f81aa3d
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled
first commit
2026-07-16 00:55:29 +02:00

762 lines
28 KiB
Bash

#!/bin/bash
# =============================================================================
# photobooth-config.sh - Gestion rapide de la config photobooth-app
# =============================================================================
# Usage:
# bash photobooth-config.sh quality high|low|status
# bash photobooth-config.sh livestream on|off|status
# bash photobooth-config.sh frontpage manuel|direct|noprint|status
# bash photobooth-config.sh restart
# =============================================================================
set -uo pipefail
API_URL="http://127.0.0.1:8083"
API_USER="admin"
API_PASS="PhotoBooth2026!"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m'
# --- Auth ---
get_token() {
curl -s -X POST "${API_URL}/api/admin/auth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&username=${API_USER}&password=${API_PASS}" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])'
}
get_config() {
local token="$1"
curl -s "${API_URL}/api/admin/config/app" \
-H "Authorization: Bearer ${token}"
}
set_config() {
local token="$1"
local config="$2"
curl -s -X PATCH "${API_URL}/api/admin/config/app" \
-H "Authorization: Bearer ${token}" \
-H "Content-Type: application/json" \
-d "${config}" > /dev/null
}
# =============================================================================
# QUALITE
# =============================================================================
quality_status() {
local token
token=$(get_token)
local config
config=$(get_config "$token")
local capture_w quality
capture_w=$(echo "$config" | python3 -c 'import sys,json;c=json.load(sys.stdin);print(c["backends"]["group_backends"][0]["backend_config"]["CAPTURE_CAM_RESOLUTION_WIDTH"])')
quality=$(echo "$config" | python3 -c 'import sys,json;c=json.load(sys.stdin);print(c["backends"]["group_backends"][0]["backend_config"]["original_still_quality"])')
if [ "$capture_w" -ge 4000 ]; then
echo -e "Qualite: ${GREEN}HAUTE${NC} (${capture_w}px, quality ${quality})"
else
echo -e "Qualite: ${YELLOW}BASSE${NC} (${capture_w}px, quality ${quality})"
fi
}
quality_high() {
local token
token=$(get_token)
set_config "$token" '{
"backends": {
"group_backends": [{
"enabled": true,
"description": "pi camera module V3",
"backend_config": {
"orientation": "1: 0°",
"backend_type": "Picamera2",
"camera_num": 0,
"CAPTURE_CAM_RESOLUTION_WIDTH": 4608,
"CAPTURE_CAM_RESOLUTION_HEIGHT": 3072,
"PREVIEW_CAM_RESOLUTION_WIDTH": 2304,
"PREVIEW_CAM_RESOLUTION_HEIGHT": 1536,
"LIVEVIEW_RESOLUTION_WIDTH": 750,
"LIVEVIEW_RESOLUTION_HEIGHT": 500,
"framerate_still_mode": 20,
"framerate_video_mode": 25,
"frame_skip_count": 4,
"optimized_lowlight_short_exposure": false,
"videostream_quality": "MEDIUM",
"original_still_quality": 100
}
}]
},
"mediaprocessing": {
"full_still_length": 4608,
"preview_still_length": 2304,
"thumbnail_still_length": 960
}
}'
echo -e "${GREEN}Qualite HAUTE activee${NC} (4608x3072, quality 100)"
echo " -> systemctl --user restart photobooth-app"
}
quality_low() {
local token
token=$(get_token)
set_config "$token" '{
"backends": {
"group_backends": [{
"enabled": true,
"description": "pi camera module V3",
"backend_config": {
"orientation": "1: 0°",
"backend_type": "Picamera2",
"camera_num": 0,
"CAPTURE_CAM_RESOLUTION_WIDTH": 2304,
"CAPTURE_CAM_RESOLUTION_HEIGHT": 1536,
"PREVIEW_CAM_RESOLUTION_WIDTH": 1152,
"PREVIEW_CAM_RESOLUTION_HEIGHT": 768,
"LIVEVIEW_RESOLUTION_WIDTH": 750,
"LIVEVIEW_RESOLUTION_HEIGHT": 500,
"framerate_still_mode": 20,
"framerate_video_mode": 25,
"frame_skip_count": 4,
"optimized_lowlight_short_exposure": false,
"videostream_quality": "MEDIUM",
"original_still_quality": 90
}
}]
},
"mediaprocessing": {
"full_still_length": 2304,
"preview_still_length": 1200,
"thumbnail_still_length": 480
}
}'
echo -e "${YELLOW}Qualite BASSE activee${NC} (2304x1536, quality 90)"
echo " -> systemctl --user restart photobooth-app"
}
# =============================================================================
# LIVESTREAM
# =============================================================================
livestream_status() {
local token
token=$(get_token)
local config
config=$(get_config "$token")
local idle_stream
idle_stream=$(echo "$config" | python3 -c 'import sys,json;c=json.load(sys.stdin);print(c["uisettings"]["enable_livestream_when_idle"])')
if [ "$idle_stream" = "True" ]; then
echo -e "Livestream idle: ${GREEN}ACTIVE${NC}"
else
echo -e "Livestream idle: ${RED}DESACTIVE${NC}"
fi
}
livestream_on() {
local token
token=$(get_token)
set_config "$token" '{
"uisettings": {
"enable_livestream_when_idle": true
}
}'
echo -e "${GREEN}Livestream idle ACTIVE${NC}"
echo " Les visiteurs voient la camera en direct sur l'ecran d'accueil"
}
livestream_off() {
local token
token=$(get_token)
set_config "$token" '{
"uisettings": {
"enable_livestream_when_idle": false
}
}'
echo -e "${RED}Livestream idle DESACTIVE${NC}"
echo " L'ecran d'accueil affiche le slideshow"
}
# =============================================================================
# FRONTPAGE TEXT
# =============================================================================
frontpage_status() {
local token
token=$(get_token)
local config
config=$(get_config "$token")
local text
text=$(echo "$config" | python3 -c 'import sys,json;c=json.load(sys.stdin);t=c["uisettings"]["FRONTPAGE_TEXT"];print("impression" if "Impression" in t else "noprint" if "Appui long" not in t else "unknown")')
echo -e "Frontpage: ${CYAN}${text}${NC}"
}
# --- HTML templates ---
FRONTPAGE_MANUEL='<div> <div class="fixed-top-right q-mt-lg q-mr-lg" style="pointer-events: none; max-width: 400px;"> <div class="q-pa-md" style="background: rgba(226,235,242,0.85); border-radius: 12px; backdrop-filter: blur(4px); border: 2px solid #89a9c2;"> <div class="text-h3 text-weight-bold" style="color: #335e7e;">Bienvenue !</div> <div style="font-size: 1.3rem; line-height: 1.6; color: #335e7e; margin-top: 10px;"> <div>Appui court = Photo</div> <div>Appui long (3s) = Demande d'\''impression</div> </div> </div> </div> <div class="fixed-bottom-left q-mb-sm q-ml-lg" style="pointer-events: none;"> <div class="q-pa-sm" style="background: rgba(226,235,242,0.75); border-radius: 8px; border: 1px solid #89a9c2; white-space: nowrap;"> <span style="font-size: 0.85rem; color: #335e7e;"> Photomaton propos\u00e9 par Les Sapins Du Web. En l'\''utilisant, vous acceptez que les photos puissent etre utilis\u00e9es par Les Sapins Du Web et ses partenaires. </span> </div> </div> <div class="fixed-bottom-right q-mb-lg q-mr-lg" style="pointer-events: none;"> <img src="/userdata/LSDW/logo/logo.jpeg" alt="Les Sapins Du Web" style="width:180px; height:180px; border-radius: 12px; box-shadow: 2px 2px 10px rgba(0,0,0,0.5);"> </div></div>'
FRONTPAGE_DIRECT='<div> <div class="fixed-top-right q-mt-lg q-mr-lg" style="pointer-events: none; max-width: 400px;"> <div class="q-pa-md" style="background: rgba(226,235,242,0.85); border-radius: 12px; backdrop-filter: blur(4px); border: 2px solid #89a9c2;"> <div class="text-h3 text-weight-bold" style="color: #335e7e;">Bienvenue !</div> <div style="font-size: 1.3rem; line-height: 1.6; color: #335e7e; margin-top: 10px;"> <div>Appui court = Photo</div> <div>Appui long (3s) = Impression</div> </div> </div> </div> <div class="fixed-bottom-left q-mb-sm q-ml-lg" style="pointer-events: none;"> <div class="q-pa-sm" style="background: rgba(226,235,242,0.75); border-radius: 8px; border: 1px solid #89a9c2; white-space: nowrap;"> <span style="font-size: 0.85rem; color: #335e7e;"> Photomaton propos\u00e9 par Les Sapins Du Web. En l'\''utilisant, vous acceptez que les photos puissent etre utilis\u00e9es par Les Sapins Du Web et ses partenaires. </span> </div> </div> <div class="fixed-bottom-right q-mb-lg q-mr-lg" style="pointer-events: none;"> <img src="/userdata/LSDW/logo/logo.jpeg" alt="Les Sapins Du Web" style="width:180px; height:180px; border-radius: 12px; box-shadow: 2px 2px 10px rgba(0,0,0,0.5);"> </div></div>'
FRONTPAGE_NOPRINT='<div> <div class="fixed-top-right q-mt-lg q-mr-lg" style="pointer-events: none; max-width: 400px;"> <div class="q-pa-md" style="background: rgba(226,235,242,0.85); border-radius: 12px; backdrop-filter: blur(4px); border: 2px solid #89a9c2;"> <div class="text-h3 text-weight-bold" style="color: #335e7e;">Bienvenue !</div> <div style="font-size: 1.3rem; line-height: 1.6; color: #335e7e; margin-top: 10px;"> <div>Appuyez sur le bouton pour prendre une photo</div> </div> </div> </div> <div class="fixed-bottom-left q-mb-sm q-ml-lg" style="pointer-events: none;"> <div class="q-pa-sm" style="background: rgba(226,235,242,0.75); border-radius: 8px; border: 1px solid #89a9c2; white-space: nowrap;"> <span style="font-size: 0.85rem; color: #335e7e;"> Photomaton propos\u00e9 par Les Sapins Du Web. En l'\''utilisant, vous acceptez que les photos puissent etre utilis\u00e9es par Les Sapins Du Web et ses partenaires. </span> </div> </div> <div class="fixed-bottom-right q-mb-lg q-mr-lg" style="pointer-events: none;"> <img src="/userdata/LSDW/logo/logo.jpeg" alt="Les Sapins Du Web" style="width:180px; height:180px; border-radius: 12px; box-shadow: 2px 2px 10px rgba(0,0,0,0.5);"> </div></div>'
frontpage_set() {
local mode="$1"
local token
token=$(get_token)
local html=""
case "$mode" in
manuel)
html="$FRONTPAGE_MANUEL"
;;
direct)
html="$FRONTPAGE_DIRECT"
;;
noprint)
html="$FRONTPAGE_NOPRINT"
;;
esac
# Utiliser python3 pour construire le JSON proprement (gestion des quotes)
python3 -c "
import json, urllib.request
data = json.dumps({'uisettings': {'FRONTPAGE_TEXT': '''${html}'''}}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
"
case "$mode" in
manuel)
echo -e "${CYAN}Frontpage: MODE MANUEL${NC}"
echo " Appui court = Photo / Appui long = Demande d'impression"
;;
direct)
echo -e "${CYAN}Frontpage: MODE DIRECT${NC}"
echo " Appui court = Photo / Appui long = Impression"
;;
noprint)
echo -e "${CYAN}Frontpage: SANS IMPRESSION${NC}"
echo " Appuyez sur le bouton pour prendre une photo"
;;
esac
}
# =============================================================================
# ACTIONS IMAGE
# =============================================================================
ACTIONS_DIR="${HOME}/photobooth-data/actions-backups"
actions_init() {
mkdir -p "$ACTIONS_DIR"
}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DISPLAY_ACTIONS_PY="${SCRIPT_DIR}/display_actions.py"
actions_list() {
local token
token=$(get_token)
local config
config=$(get_config "$token")
echo "=== Actions image actuelles ==="
echo "$config" | python3 "$DISPLAY_ACTIONS_PY"
}
actions_backup() {
local name="$1"
actions_init
local token
token=$(get_token)
local config
config=$(get_config "$token")
local filepath="${ACTIONS_DIR}/${name}.json"
echo "$config" | python3 -c "
import sys, json
c = json.load(sys.stdin)
with open('${filepath}', 'w') as f:
json.dump(c['actions'], f, indent=2, ensure_ascii=False)
"
local count
count=$(python3 -c "import json;print(len(json.load(open('${filepath}'))['image']))")
echo -e "${GREEN}Backup sauvegarde: ${filepath}${NC}"
echo " ${count} action(s) image"
}
actions_restore() {
local name="$1"
actions_init
local filepath="${ACTIONS_DIR}/${name}.json"
if [ ! -f "$filepath" ]; then
echo -e "${RED}Backup introuvable: ${filepath}${NC}"
echo "Backups disponibles:"
actions_list_backups
return 1
fi
local token
token=$(get_token)
python3 -c "
import json, urllib.request
with open('${filepath}') as f:
actions = json.load(f)
data = json.dumps({'actions': actions}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
"
local count
count=$(python3 -c "import json;print(len(json.load(open('${filepath}'))['image']))")
echo -e "${GREEN}Backup restaure: ${name}${NC}"
echo " ${count} action(s) image chargees"
echo " -> systemctl --user restart photobooth-app"
}
actions_list_backups() {
actions_init
echo "=== Backups disponibles ==="
local found=false
for f in "${ACTIONS_DIR}"/*.json; do
if [ -f "$f" ]; then
found=true
local basename
basename=$(basename "$f" .json)
local count
count=$(python3 -c "import json;print(len(json.load(open('${f}'))['image']))" 2>/dev/null || echo "?")
local date
date=$(stat -c '%y' "$f" 2>/dev/null | cut -d. -f1)
echo " ${basename} (${count} actions, ${date})"
fi
done
if ! $found; then
echo " (aucun)"
fi
}
actions_show() {
local name="$1"
actions_init
local filepath="${ACTIONS_DIR}/${name}.json"
if [ ! -f "$filepath" ]; then
echo -e "${RED}Backup introuvable: ${filepath}${NC}"
return 1
fi
echo "=== Backup: ${name} ==="
python3 "$DISPLAY_ACTIONS_PY" --file "$filepath"
}
actions_move() {
local from="$1"
local to="$2"
local token
token=$(get_token)
local tmpfile
tmpfile=$(mktemp /tmp/photobooth-config-XXXXXX.json)
get_config "$token" > "$tmpfile"
python3 -c "
import json, urllib.request, sys
with open('${tmpfile}') as f:
config = json.load(f)
actions = config['actions']['image']
count = len(actions)
f, t = int('${from}'), int('${to}')
if f < 0 or f >= count or t < 0 or t >= count:
print(f'Erreur: index invalide (0-{count-1})')
sys.exit(1)
item = actions.pop(f)
actions.insert(t, item)
config['actions']['image'] = actions
data = json.dumps({'actions': config['actions']}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
print(f'Action [{f}] deplacee vers [{t}]')
for i, a in enumerate(actions):
marker = ' <--' if i == t else ''
print(f' [{i}] {a[\"name\"]}{marker}')
"
rm -f "$tmpfile"
}
actions_enable() {
local index="$1"
local token
token=$(get_token)
local tmpfile
tmpfile=$(mktemp /tmp/photobooth-config-XXXXXX.json)
get_config "$token" > "$tmpfile"
python3 -c "
import json, urllib.request, sys
with open('${tmpfile}') as f:
config = json.load(f)
actions = config['actions']['image']
idx = int('${index}')
if idx < 0 or idx >= len(actions):
print(f'Erreur: index invalide (0-{len(actions)-1})')
sys.exit(1)
actions[idx]['trigger']['ui_trigger']['show_button'] = True
data = json.dumps({'actions': config['actions']}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
print(f'Action [{idx}] {actions[idx][\"name\"]} : bouton VISIBLE')
"
rm -f "$tmpfile"
}
actions_disable() {
local index="$1"
local token
token=$(get_token)
local tmpfile
tmpfile=$(mktemp /tmp/photobooth-config-XXXXXX.json)
get_config "$token" > "$tmpfile"
python3 -c "
import json, urllib.request, sys
with open('${tmpfile}') as f:
config = json.load(f)
actions = config['actions']['image']
idx = int('${index}')
if idx < 0 or idx >= len(actions):
print(f'Erreur: index invalide (0-{len(actions)-1})')
sys.exit(1)
actions[idx]['trigger']['ui_trigger']['show_button'] = False
data = json.dumps({'actions': config['actions']}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
print(f'Action [{idx}] {actions[idx][\"name\"]} : bouton CACHE')
"
rm -f "$tmpfile"
}
actions_duplicate() {
local index="$1"
local token
token=$(get_token)
local tmpfile
tmpfile=$(mktemp /tmp/photobooth-config-XXXXXX.json)
get_config "$token" > "$tmpfile"
python3 -c "
import json, urllib.request, copy, sys
with open('${tmpfile}') as f:
config = json.load(f)
actions = config['actions']['image']
idx = int('${index}')
if idx < 0 or idx >= len(actions):
print(f'Erreur: index invalide (0-{len(actions)-1})')
sys.exit(1)
new_action = copy.deepcopy(actions[idx])
new_action['name'] = new_action['name'] + ' (copie)'
new_action['trigger']['ui_trigger']['show_button'] = False
actions.insert(idx + 1, new_action)
data = json.dumps({'actions': config['actions']}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
print(f'Action [{idx}] dupliquee vers [{idx+1}]')
for i, a in enumerate(actions):
marker = ' <-- copie' if i == idx + 1 else ''
print(f' [{i}] {a[\"name\"]}{marker}')
"
rm -f "$tmpfile"
}
actions_remove() {
local indices="$@"
local token
token=$(get_token)
local tmpfile
tmpfile=$(mktemp /tmp/photobooth-config-XXXXXX.json)
get_config "$token" > "$tmpfile"
python3 -c "
import json, urllib.request, sys
with open('${tmpfile}') as f:
config = json.load(f)
actions = config['actions']['image']
indices = sorted([int(x) for x in '${indices}'.split()], reverse=True)
for idx in indices:
if idx < 0 or idx >= len(actions):
print(f'Erreur: index {idx} invalide (0-{len(actions)-1})')
sys.exit(1)
removed = []
for idx in indices:
removed.append(f'[{idx}] {actions[idx][\"name\"]}')
actions.pop(idx)
data = json.dumps({'actions': config['actions']}).encode()
req = urllib.request.Request('${API_URL}/api/admin/config/app', data=data, method='PATCH')
req.add_header('Authorization', 'Bearer ${token}')
req.add_header('Content-Type', 'application/json')
urllib.request.urlopen(req)
print('Actions supprimees:')
for r in removed:
print(f' - {r}')
print()
print('Actions restantes:')
for i, a in enumerate(actions):
print(f' [{i}] {a[\"name\"]}')
print(f' Total: {len(actions)} action(s)')
"
rm -f "$tmpfile"
}
# =============================================================================
# RESTART
# =============================================================================
do_restart() {
echo "Redemarrage de photobooth-app..."
systemctl --user restart photobooth-app
sleep 3
if systemctl --user is-active photobooth-app &>/dev/null; then
echo -e "${GREEN}photobooth-app redemarre avec succes${NC}"
else
echo -e "${RED}ERREUR: photobooth-app n'a pas redemarre${NC}"
systemctl --user status photobooth-app
fi
}
# =============================================================================
# AIDE
# =============================================================================
show_help() {
cat << 'HELP'
===============================================================================
photobooth-config.sh - Gestion rapide de la config photobooth-app
===============================================================================
USAGE: photobooth-config.sh <commande> [arguments]
COMMANDES GENERALES:
status, s Afficher la config actuelle (qualite, livestream, frontpage)
restart, r Redemarrer photobooth-app
help, -h, --help Afficher cette aide
QUALITE D'IMAGE:
quality status Voir la qualite actuelle
quality high Haute qualite (4608x3072, JPEG 100%)
Meilleure qualite d'impression mais consomme plus de RAM
quality low Basse qualite (2304x1536, JPEG 90%)
Economise la RAM, suffisant pour impression Selphy
Note: necessite un restart apres changement
LIVESTREAM:
livestream status Voir si le livestream idle est actif
livestream on Activer le livestream sur l'ecran d'accueil
Les visiteurs voient la camera en direct
livestream off Desactiver le livestream idle
L'ecran d'accueil affiche le slideshow
TEXTE D'ACCUEIL (FRONTPAGE):
frontpage status Voir le mode actuel
frontpage manuel "Appui long (3s) = Demande d'impression"
Pour les events avec validation admin
frontpage direct "Appui long (3s) = Impression"
Pour les events avec impression automatique
frontpage noprint "Appuyez sur le bouton pour prendre une photo"
Pas de mention d'impression
ACTIONS IMAGE:
actions list Lister toutes les actions avec leurs parametres
L'index [0] = simple clic, [1] = double clic, etc.
actions backup <nom> Sauvegarder les actions actuelles
Ex: actions backup hopnbloc
actions restore <nom> Restaurer un backup d'actions
Ex: actions restore hopnbloc
Note: necessite un restart apres
actions backups Lister les backups disponibles
actions show <nom> Voir le contenu d'un backup
actions move <de> <vers> Deplacer une action dans la liste
Ex: actions move 3 0 (met l'action 3 en premier)
Important: l'ordre determine le bouton physique
[0] = simple clic
[1] = double clic
[2] = triple clic
[3] = quadruple clic
actions enable <index> Rendre le bouton visible sur l'ecran tactile
actions disable <index> Cacher le bouton de l'ecran tactile
actions dup <index> Dupliquer une action (copie inseree apres)
actions remove <i> [i...] Supprimer une ou plusieurs actions
Ex: actions remove 5 (supprime l'action 5)
Ex: actions remove 3 5 7 (supprime les actions 3, 5 et 7)
EXEMPLES:
# Preparer un event Hop'N Bloc
photobooth-config.sh actions backup config-avant
photobooth-config.sh actions restore hopnbloc
photobooth-config.sh frontpage manuel
photobooth-config.sh livestream on
photobooth-config.sh quality low
photobooth-config.sh restart
# Passer en haute qualite pour un event special
photobooth-config.sh quality high
photobooth-config.sh restart
# Apres l'event, tout remettre
photobooth-config.sh actions restore config-avant
photobooth-config.sh restart
===============================================================================
HELP
}
# =============================================================================
# MAIN
# =============================================================================
CMD="${1:-help}"
ARG="${2:-status}"
case "$CMD" in
quality|q)
case "$ARG" in
high|haute|hq) quality_high ;;
low|basse|lq) quality_low ;;
status|info) quality_status ;;
*) echo "Usage: $0 quality {high|low|status}" ;;
esac
;;
livestream|ls)
case "$ARG" in
on|true|1) livestream_on ;;
off|false|0) livestream_off ;;
status|info) livestream_status ;;
*) echo "Usage: $0 livestream {on|off|status}" ;;
esac
;;
frontpage|fp)
case "$ARG" in
manuel|manual) frontpage_set manuel ;;
direct) frontpage_set direct ;;
noprint|sans|off) frontpage_set noprint ;;
status|info) frontpage_status ;;
*) echo "Usage: $0 frontpage {manuel|direct|noprint|status}" ;;
esac
;;
actions|a)
case "$ARG" in
list|ls) actions_list ;;
backup|save)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions backup <nom>"
echo " Exemple: $0 actions backup hopnbloc"
exit 1
fi
actions_backup "$3"
;;
restore|load)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions restore <nom>"
actions_list_backups
exit 1
fi
actions_restore "$3"
;;
backups) actions_list_backups ;;
show)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions show <nom>"
actions_list_backups
exit 1
fi
actions_show "$3"
;;
move|mv)
if [ -z "${3:-}" ] || [ -z "${4:-}" ]; then
echo "Usage: $0 actions move <from> <to>"
echo " Exemple: $0 actions move 3 0 (deplace l'action 3 en position 0)"
exit 1
fi
actions_move "$3" "$4"
;;
enable|on)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions enable <index>"
actions_list
exit 1
fi
actions_enable "$3"
;;
disable|off)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions disable <index>"
actions_list
exit 1
fi
actions_disable "$3"
;;
dup|duplicate|copy)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions dup <index>"
actions_list
exit 1
fi
actions_duplicate "$3"
;;
remove|rm|del|delete)
if [ -z "${3:-}" ]; then
echo "Usage: $0 actions remove <index> [index...]"
echo " Exemple: $0 actions remove 5"
echo " Exemple: $0 actions remove 3 5 7"
actions_list
exit 1
fi
shift 2
actions_remove "$@"
;;
*) echo "Usage: $0 actions {list|backup|restore|backups|show|move|enable|disable|dup|remove}" ;;
esac
;;
restart|r)
do_restart
;;
status|s)
echo "=== Photobooth Config ==="
quality_status
livestream_status
frontpage_status
;;
help|-h|--help)
show_help
;;
*)
show_help
;;
esac