Initial import: clean snapshot from /home/olafn/infoscreen-dev (2025-10-25)
This commit is contained in:
36
scripts/infoscreen-display.service
Normal file
36
scripts/infoscreen-display.service
Normal file
@@ -0,0 +1,36 @@
|
||||
[Unit]
|
||||
Description=Infoscreen Display Manager
|
||||
Documentation=https://github.com/RobbStarkAustria/infoscreen_client_2025
|
||||
After=network.target graphical.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=olafn
|
||||
Group=olafn
|
||||
WorkingDirectory=/home/olafn/infoscreen-dev
|
||||
Environment="DISPLAY=:0"
|
||||
Environment="XAUTHORITY=/home/olafn/.Xauthority"
|
||||
Environment="ENV=production"
|
||||
|
||||
# Start display manager
|
||||
ExecStart=/home/olafn/infoscreen-dev/scripts/start-display-manager.sh
|
||||
|
||||
# Restart on failure
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=infoscreen-display
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical.target
|
||||
163
scripts/present-pdf-auto-advance.sh
Executable file
163
scripts/present-pdf-auto-advance.sh
Executable file
@@ -0,0 +1,163 @@
|
||||
#!/bin/bash
|
||||
# PDF Presentation with Auto-Advance
|
||||
# Works for both native PDF and converted PPTX files
|
||||
|
||||
PDF_FILE="$1"
|
||||
INTERVAL="${2:-10}"
|
||||
LOOP="${3:-false}"
|
||||
|
||||
if [ -z "$PDF_FILE" ]; then
|
||||
echo "Usage: $0 <file.pdf> [interval-seconds] [loop:true|false]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$PDF_FILE" ]; then
|
||||
echo "Error: File not found: $PDF_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo " PDF Presentation Mode"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "File: $(basename "$PDF_FILE")"
|
||||
echo "Auto-advance: ${INTERVAL}s per slide"
|
||||
echo "Loop: $LOOP"
|
||||
echo ""
|
||||
|
||||
# Count pages in PDF
|
||||
PAGE_COUNT=$(pdfinfo "$PDF_FILE" 2>/dev/null | grep "Pages:" | awk '{print $2}')
|
||||
|
||||
if [ -z "$PAGE_COUNT" ] || [ "$PAGE_COUNT" -eq 0 ]; then
|
||||
echo "Warning: Could not determine page count, assuming 10 pages"
|
||||
PAGE_COUNT=10
|
||||
else
|
||||
echo "Detected $PAGE_COUNT pages"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check for required tools
|
||||
if ! command -v xdotool &> /dev/null; then
|
||||
echo "Error: xdotool not installed"
|
||||
echo "Install with: sudo apt-get install xdotool"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Choose best PDF viewer (prefer Impressive for auto-advance)
|
||||
PDF_VIEWER=""
|
||||
PDF_VIEWER_CMD=""
|
||||
|
||||
if command -v impressive &> /dev/null; then
|
||||
PDF_VIEWER="impressive"
|
||||
PDF_VIEWER_CMD="impressive --fullscreen --nooverview --auto $INTERVAL"
|
||||
|
||||
if [ "$LOOP" = "true" ]; then
|
||||
PDF_VIEWER_CMD="$PDF_VIEWER_CMD --wrap"
|
||||
else
|
||||
PDF_VIEWER_CMD="$PDF_VIEWER_CMD --autoquit"
|
||||
fi
|
||||
|
||||
# Impressive handles auto-advance natively, no xdotool needed!
|
||||
echo "Using Impressive (built-in auto-advance)..."
|
||||
$PDF_VIEWER_CMD "$PDF_FILE"
|
||||
exit 0
|
||||
|
||||
elif command -v evince &> /dev/null; then
|
||||
PDF_VIEWER="evince"
|
||||
PDF_VIEWER_CMD="evince --presentation"
|
||||
elif command -v okular &> /dev/null; then
|
||||
PDF_VIEWER="okular"
|
||||
PDF_VIEWER_CMD="okular --presentation"
|
||||
else
|
||||
echo "Error: No suitable PDF viewer found"
|
||||
echo "Install impressive: sudo apt-get install impressive"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using PDF viewer: $PDF_VIEWER"
|
||||
echo "Starting presentation mode..."
|
||||
echo ""
|
||||
|
||||
# Start PDF viewer in presentation mode
|
||||
$PDF_VIEWER_CMD "$PDF_FILE" &
|
||||
VIEWER_PID=$!
|
||||
|
||||
echo "Viewer PID: $VIEWER_PID"
|
||||
echo "Waiting for viewer to start..."
|
||||
sleep 5
|
||||
|
||||
# Verify it's still running
|
||||
if ! ps -p $VIEWER_PID > /dev/null 2>&1; then
|
||||
echo "Error: PDF viewer exited unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting auto-advance..."
|
||||
echo "Press Ctrl+C to stop"
|
||||
echo ""
|
||||
|
||||
# Auto-advance loop
|
||||
CURRENT_PAGE=1
|
||||
MAX_LOOPS=0
|
||||
|
||||
if [ "$LOOP" = "false" ]; then
|
||||
# Calculate total slides to advance (pages - 1, since we start on page 1)
|
||||
MAX_ADVANCES=$((PAGE_COUNT - 1))
|
||||
else
|
||||
# Infinite loop
|
||||
MAX_ADVANCES=999999
|
||||
fi
|
||||
|
||||
ADVANCE_COUNT=0
|
||||
|
||||
while ps -p $VIEWER_PID > /dev/null 2>&1 && [ $ADVANCE_COUNT -lt $MAX_ADVANCES ]; do
|
||||
sleep $INTERVAL
|
||||
|
||||
# Find the PDF viewer window
|
||||
VIEWER_WINDOW=$(xdotool search --pid $VIEWER_PID 2>/dev/null | tail -1)
|
||||
|
||||
if [ -z "$VIEWER_WINDOW" ]; then
|
||||
# Fallback: search by window name
|
||||
VIEWER_WINDOW=$(xdotool search --name "$(basename "$PDF_FILE")" 2>/dev/null | tail -1)
|
||||
fi
|
||||
|
||||
if [ -n "$VIEWER_WINDOW" ]; then
|
||||
# Ensure window is focused
|
||||
xdotool windowactivate --sync "$VIEWER_WINDOW" 2>/dev/null
|
||||
sleep 0.2
|
||||
|
||||
# Send Right Arrow or Page Down (both work in most PDF viewers)
|
||||
xdotool key --clearmodifiers --window "$VIEWER_WINDOW" Right
|
||||
|
||||
CURRENT_PAGE=$((CURRENT_PAGE + 1))
|
||||
ADVANCE_COUNT=$((ADVANCE_COUNT + 1))
|
||||
|
||||
echo "[$(date '+%H:%M:%S')] Advanced to page $CURRENT_PAGE"
|
||||
|
||||
# Check if we've reached the end
|
||||
if [ $CURRENT_PAGE -gt $PAGE_COUNT ]; then
|
||||
if [ "$LOOP" = "true" ]; then
|
||||
echo "Reached end, looping back to start..."
|
||||
CURRENT_PAGE=1
|
||||
else
|
||||
echo ""
|
||||
echo "Reached end of presentation (page $PAGE_COUNT)"
|
||||
echo "Keeping viewer open..."
|
||||
# Keep viewer running, just stop advancing
|
||||
wait $VIEWER_PID
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Fallback: send key to active window
|
||||
xdotool key --clearmodifiers Right
|
||||
CURRENT_PAGE=$((CURRENT_PAGE + 1))
|
||||
ADVANCE_COUNT=$((ADVANCE_COUNT + 1))
|
||||
echo "[$(date '+%H:%M:%S')] Advanced (fallback) #$ADVANCE_COUNT"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Presentation ended"
|
||||
exit 0
|
||||
5
scripts/start-dev.sh
Executable file
5
scripts/start-dev.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")/.."
|
||||
source venv/bin/activate
|
||||
export $(cat .env | xargs)
|
||||
python3 src/simclient.py
|
||||
43
scripts/start-display-manager.sh
Executable file
43
scripts/start-display-manager.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# Start Display Manager - Controls display software for infoscreen events
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
VENV_PATH="$PROJECT_ROOT/venv"
|
||||
DISPLAY_MANAGER="$PROJECT_ROOT/src/display_manager.py"
|
||||
|
||||
echo "🖥️ Starting Display Manager..."
|
||||
echo "Project root: $PROJECT_ROOT"
|
||||
|
||||
# Check if virtual environment exists
|
||||
if [ ! -d "$VENV_PATH" ]; then
|
||||
echo "❌ Virtual environment not found at: $VENV_PATH"
|
||||
echo "Please create it with: python3 -m venv venv"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Activate virtual environment
|
||||
source "$VENV_PATH/bin/activate"
|
||||
|
||||
# Check if display_manager.py exists
|
||||
if [ ! -f "$DISPLAY_MANAGER" ]; then
|
||||
echo "❌ Display manager not found at: $DISPLAY_MANAGER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make sure DISPLAY is set (required for GUI applications)
|
||||
if [ -z "$DISPLAY" ]; then
|
||||
export DISPLAY=:0
|
||||
echo "📺 DISPLAY not set, using: $DISPLAY"
|
||||
fi
|
||||
|
||||
# Check if we're in development or production
|
||||
ENV="${ENV:-development}"
|
||||
echo "Environment: $ENV"
|
||||
|
||||
# Start display manager
|
||||
echo "Starting display manager..."
|
||||
echo "---"
|
||||
python3 "$DISPLAY_MANAGER"
|
||||
210
scripts/test-display-manager.sh
Executable file
210
scripts/test-display-manager.sh
Executable file
@@ -0,0 +1,210 @@
|
||||
#!/bin/bash
|
||||
# Test Display Manager functionality
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
EVENT_FILE="$PROJECT_ROOT/src/current_event.json"
|
||||
|
||||
echo "🧪 Testing Display Manager"
|
||||
echo "========================="
|
||||
echo ""
|
||||
|
||||
# Function to create test event
|
||||
create_test_event() {
|
||||
local event_type=$1
|
||||
echo "📝 Creating test event: $event_type"
|
||||
|
||||
case $event_type in
|
||||
"presentation")
|
||||
cat > "$EVENT_FILE" <<EOF
|
||||
{
|
||||
"id": 999,
|
||||
"title": "Test Presentation with Impressive",
|
||||
"start": "2025-01-01 00:00:00",
|
||||
"end": "2025-12-31 23:59:59",
|
||||
"presentation": {
|
||||
"type": "slideshow",
|
||||
"files": [
|
||||
{
|
||||
"name": "LPUV4I_Folien_Nowitzki_Bewertungskriterien.pptx",
|
||||
"url": "http://example.com/test.pptx"
|
||||
}
|
||||
],
|
||||
"auto_advance": true,
|
||||
"slide_interval": 5,
|
||||
"loop": true
|
||||
}
|
||||
}
|
||||
EOF
|
||||
;;
|
||||
"webpage")
|
||||
cat > "$EVENT_FILE" <<EOF
|
||||
{
|
||||
"id": 998,
|
||||
"title": "Test Webpage",
|
||||
"start": "2025-01-01 00:00:00",
|
||||
"end": "2025-12-31 23:59:59",
|
||||
"web": {
|
||||
"url": "https://www.wikipedia.org"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
;;
|
||||
"video")
|
||||
cat > "$EVENT_FILE" <<EOF
|
||||
{
|
||||
"id": 997,
|
||||
"title": "Test Video",
|
||||
"start": "2025-01-01 00:00:00",
|
||||
"end": "2025-12-31 23:59:59",
|
||||
"video": {
|
||||
"url": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
||||
"loop": false
|
||||
}
|
||||
}
|
||||
EOF
|
||||
;;
|
||||
"none")
|
||||
echo "📝 Removing event file (no active event)"
|
||||
rm -f "$EVENT_FILE"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f "$EVENT_FILE" ]; then
|
||||
echo "✅ Event file created:"
|
||||
cat "$EVENT_FILE"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Function to check if display manager is running
|
||||
check_display_manager() {
|
||||
if pgrep -f "display_manager.py" > /dev/null; then
|
||||
echo "✅ Display Manager is running"
|
||||
echo " PID: $(pgrep -f display_manager.py)"
|
||||
return 0
|
||||
else
|
||||
echo "❌ Display Manager is NOT running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check for display processes
|
||||
check_display_processes() {
|
||||
echo "🔍 Active display processes:"
|
||||
|
||||
# Check for LibreOffice
|
||||
if pgrep -f "libreoffice.*impress" > /dev/null; then
|
||||
echo " 📊 LibreOffice Impress: PID $(pgrep -f 'libreoffice.*impress')"
|
||||
fi
|
||||
|
||||
# Check for browsers
|
||||
if pgrep -f "chromium.*kiosk" > /dev/null; then
|
||||
echo " 🌐 Chromium (kiosk): PID $(pgrep -f 'chromium.*kiosk')"
|
||||
fi
|
||||
|
||||
# Check for video players
|
||||
if pgrep -f "vlc" > /dev/null; then
|
||||
echo " 🎬 VLC: PID $(pgrep -f 'vlc')"
|
||||
fi
|
||||
|
||||
if pgrep -f "mpv" > /dev/null; then
|
||||
echo " 🎬 MPV: PID $(pgrep -f 'mpv')"
|
||||
fi
|
||||
|
||||
# Check for PDF viewers
|
||||
if pgrep -f "evince" > /dev/null; then
|
||||
echo " 📄 Evince: PID $(pgrep -f 'evince')"
|
||||
fi
|
||||
|
||||
# Check for Impressive
|
||||
if pgrep -f "impressive" > /dev/null; then
|
||||
echo " 📊 Impressive: PID $(pgrep -f 'impressive')"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main menu
|
||||
echo "Display Manager Test Menu"
|
||||
echo "========================="
|
||||
echo ""
|
||||
echo "What would you like to test?"
|
||||
echo "1) Check Display Manager status"
|
||||
echo "2) Create PRESENTATION test event"
|
||||
echo "3) Create WEBPAGE test event"
|
||||
echo "4) Create VIDEO test event"
|
||||
echo "5) Remove event (no display)"
|
||||
echo "6) Check active display processes"
|
||||
echo "7) View current event file"
|
||||
echo "8) Interactive test (cycle through events)"
|
||||
echo "9) Exit"
|
||||
echo ""
|
||||
|
||||
read -p "Enter choice [1-9]: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
check_display_manager
|
||||
check_display_processes
|
||||
;;
|
||||
2)
|
||||
create_test_event "presentation"
|
||||
echo "⏱️ Display Manager will pick this up within 5 seconds..."
|
||||
;;
|
||||
3)
|
||||
create_test_event "webpage"
|
||||
echo "⏱️ Display Manager will pick this up within 5 seconds..."
|
||||
;;
|
||||
4)
|
||||
create_test_event "video"
|
||||
echo "⏱️ Display Manager will pick this up within 5 seconds..."
|
||||
;;
|
||||
5)
|
||||
create_test_event "none"
|
||||
echo "⏱️ Display Manager will stop display within 5 seconds..."
|
||||
;;
|
||||
6)
|
||||
check_display_manager
|
||||
check_display_processes
|
||||
;;
|
||||
7)
|
||||
if [ -f "$EVENT_FILE" ]; then
|
||||
echo "📄 Current event file:"
|
||||
cat "$EVENT_FILE"
|
||||
else
|
||||
echo "❌ No event file found"
|
||||
fi
|
||||
;;
|
||||
8)
|
||||
echo "🔄 Interactive test - cycling through event types"
|
||||
echo " Display Manager must be running for this test!"
|
||||
echo ""
|
||||
check_display_manager || exit 1
|
||||
|
||||
echo "1️⃣ Testing PRESENTATION (10 seconds)..."
|
||||
create_test_event "presentation"
|
||||
sleep 10
|
||||
|
||||
echo "2️⃣ Testing WEBPAGE (10 seconds)..."
|
||||
create_test_event "webpage"
|
||||
sleep 10
|
||||
|
||||
echo "3️⃣ Testing NO EVENT (5 seconds)..."
|
||||
create_test_event "none"
|
||||
sleep 5
|
||||
|
||||
echo "4️⃣ Back to PRESENTATION..."
|
||||
create_test_event "presentation"
|
||||
|
||||
echo "✅ Interactive test complete!"
|
||||
;;
|
||||
9)
|
||||
echo "👋 Goodbye!"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "❌ Invalid choice"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
92
scripts/test-impressive-loop.sh
Executable file
92
scripts/test-impressive-loop.sh
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash
|
||||
# Test Impressive with LOOP mode (for events/kiosks)
|
||||
|
||||
echo "=========================================="
|
||||
echo " Test: Impressive with LOOP"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "This tests kiosk/event mode where the"
|
||||
echo "presentation loops continuously."
|
||||
echo ""
|
||||
|
||||
cd ~/infoscreen-dev
|
||||
PPTX=$(find src/presentation -name "*.pptx" | head -1)
|
||||
|
||||
if [ -z "$PPTX" ]; then
|
||||
echo "Error: No PPTX file found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Convert to PDF
|
||||
PDF="/tmp/impressive_loop_test.pdf"
|
||||
echo "Converting PPTX to PDF..."
|
||||
libreoffice --headless --convert-to pdf --outdir /tmp "$PPTX" > /dev/null 2>&1
|
||||
|
||||
PPTX_BASE=$(basename "$PPTX" .pptx)
|
||||
ACTUAL_PDF="/tmp/${PPTX_BASE}.pdf"
|
||||
|
||||
if [ -f "$ACTUAL_PDF" ]; then
|
||||
cp "$ACTUAL_PDF" "$PDF"
|
||||
fi
|
||||
|
||||
if [ ! -f "$PDF" ]; then
|
||||
echo "Error: PDF conversion failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PAGE_COUNT=$(pdfinfo "$PDF" 2>/dev/null | grep "Pages:" | awk '{print $2}')
|
||||
echo "[OK] PDF ready: $PAGE_COUNT pages"
|
||||
echo ""
|
||||
|
||||
echo "Starting Impressive in LOOP mode..."
|
||||
echo ""
|
||||
echo "Settings:"
|
||||
echo " - Auto-advance: 3 seconds per slide"
|
||||
echo " - Loop: YES (--wrap)"
|
||||
echo " - Will go: Slide 1 → 2 → 3 → 4 → 5 → 1 → 2 → ..."
|
||||
echo ""
|
||||
echo "What to watch for:"
|
||||
echo " ✅ Advances through all $PAGE_COUNT slides"
|
||||
echo " ✅ After slide $PAGE_COUNT, goes back to slide 1"
|
||||
echo " ✅ Continues looping forever"
|
||||
echo ""
|
||||
echo "Press 'Q' or Escape to quit"
|
||||
echo ""
|
||||
|
||||
sleep 2
|
||||
|
||||
# Start with --wrap for loop mode
|
||||
impressive \
|
||||
--fullscreen \
|
||||
--nooverview \
|
||||
--auto 3 \
|
||||
--wrap \
|
||||
--nologo \
|
||||
"$PDF"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " Test Complete"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
read -p "Did it loop back to slide 1 after slide $PAGE_COUNT? (y/n): " worked
|
||||
|
||||
if [ "$worked" = "y" ]; then
|
||||
echo ""
|
||||
echo "✅ Perfect! Impressive loop mode works!"
|
||||
echo ""
|
||||
echo "This is ideal for:"
|
||||
echo " - Event displays (loop presentation during event)"
|
||||
echo " - Kiosk mode (continuous display)"
|
||||
echo " - Information screens (repeat content)"
|
||||
echo ""
|
||||
echo "Event JSON should use:"
|
||||
echo ' "loop": true'
|
||||
else
|
||||
echo ""
|
||||
echo "Something unexpected?"
|
||||
read -p "What happened?: " issue
|
||||
echo "Issue: $issue"
|
||||
fi
|
||||
|
||||
rm -f "$PDF"
|
||||
115
scripts/test-impressive.sh
Executable file
115
scripts/test-impressive.sh
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
# Test Impressive - Python PDF presenter with native auto-advance
|
||||
|
||||
echo "=========================================="
|
||||
echo " Test: Impressive PDF Presenter"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Impressive is a Python-based PDF presenter with"
|
||||
echo "BUILT-IN auto-advance. No xdotool needed!"
|
||||
echo ""
|
||||
|
||||
# Check if impressive is installed
|
||||
if ! command -v impressive &> /dev/null; then
|
||||
echo "Impressive not installed. Installing..."
|
||||
echo ""
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y impressive
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not install impressive"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Impressive installed: $(which impressive)"
|
||||
echo ""
|
||||
|
||||
# Convert PPTX to PDF
|
||||
cd ~/infoscreen-dev
|
||||
PPTX=$(find src/presentation -name "*.pptx" | head -1)
|
||||
|
||||
if [ -z "$PPTX" ]; then
|
||||
echo "Error: No PPTX file found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PDF="/tmp/impressive_test.pdf"
|
||||
echo "Converting PPTX to PDF..."
|
||||
libreoffice --headless --convert-to pdf --outdir /tmp "$PPTX" > /dev/null 2>&1
|
||||
|
||||
PPTX_BASE=$(basename "$PPTX" .pptx)
|
||||
ACTUAL_PDF="/tmp/${PPTX_BASE}.pdf"
|
||||
|
||||
if [ -f "$ACTUAL_PDF" ]; then
|
||||
cp "$ACTUAL_PDF" "$PDF"
|
||||
fi
|
||||
|
||||
if [ ! -f "$PDF" ]; then
|
||||
echo "Error: PDF conversion failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PAGE_COUNT=$(pdfinfo "$PDF" 2>/dev/null | grep "Pages:" | awk '{print $2}')
|
||||
echo "[OK] PDF ready: $PAGE_COUNT pages"
|
||||
echo ""
|
||||
|
||||
echo "Starting Impressive with 3-second auto-advance..."
|
||||
echo ""
|
||||
echo "Impressive features:"
|
||||
echo " - Native auto-advance (no xdotool!)"
|
||||
echo " - Fullscreen by default"
|
||||
echo " - Professional transitions"
|
||||
echo " - Loop support"
|
||||
echo ""
|
||||
echo "Controls:"
|
||||
echo " Right Arrow / Space = Next slide"
|
||||
echo " Left Arrow = Previous slide"
|
||||
echo " Q / Escape = Quit"
|
||||
echo ""
|
||||
|
||||
sleep 2
|
||||
|
||||
# Start Impressive with auto-advance
|
||||
# --auto 3 = auto-advance every 3 seconds
|
||||
# --fullscreen = fullscreen mode
|
||||
# --nooverview = skip overview at start
|
||||
# --autoquit = quit after last slide (for non-loop mode)
|
||||
|
||||
impressive \
|
||||
--fullscreen \
|
||||
--auto 3 \
|
||||
--nooverview \
|
||||
--autoquit \
|
||||
"$PDF"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " Test Complete"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
read -p "Did it work perfectly? (y/n): " worked
|
||||
|
||||
if [ "$worked" = "y" ]; then
|
||||
echo ""
|
||||
echo "✅ EXCELLENT! Impressive is your solution!"
|
||||
echo ""
|
||||
echo "Why Impressive is perfect:"
|
||||
echo " ✅ Built-in auto-advance (no xdotool hacks)"
|
||||
echo " ✅ Reliable on Raspberry Pi"
|
||||
echo " ✅ Professional presenter tool"
|
||||
echo " ✅ Supports loop mode natively"
|
||||
echo " ✅ Fast and lightweight"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Update Display Manager to use Impressive"
|
||||
echo " 2. Simple command: impressive --auto N --fullscreen file.pdf"
|
||||
echo " 3. Works for both PPTX (convert to PDF) and PDF files"
|
||||
else
|
||||
echo ""
|
||||
echo "What didn't work?"
|
||||
read -p "Describe the issue: " issue
|
||||
echo "Issue: $issue"
|
||||
fi
|
||||
|
||||
rm -f "$PDF"
|
||||
9
scripts/test-mqtt.sh
Executable file
9
scripts/test-mqtt.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
source "$(dirname "$0")/../.env"
|
||||
|
||||
echo "Testing MQTT connection to $MQTT_BROKER:$MQTT_PORT"
|
||||
echo "Publishing test message..."
|
||||
mosquitto_pub -h "$MQTT_BROKER" -p "$MQTT_PORT" -t "infoscreen/test" -m "Hello from Pi development setup"
|
||||
|
||||
echo "Subscribing to test topic (press Ctrl+C to stop)..."
|
||||
mosquitto_sub -h "$MQTT_BROKER" -p "$MQTT_PORT" -t "infoscreen/test"
|
||||
174
scripts/test-progress-bars.sh
Executable file
174
scripts/test-progress-bars.sh
Executable file
@@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
# Test script for page_progress and auto_progress features in presentations
|
||||
|
||||
echo "=========================================="
|
||||
echo "Progress Bar Features Test"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check if MQTT broker is configured
|
||||
if [ -f ../.env ]; then
|
||||
source ../.env
|
||||
MQTT_HOST=${MQTT_BROKER:-localhost}
|
||||
else
|
||||
MQTT_HOST=localhost
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Using MQTT broker: ${MQTT_HOST}${NC}"
|
||||
echo ""
|
||||
|
||||
# Menu for testing different progress bar configurations
|
||||
echo "Select a test configuration:"
|
||||
echo ""
|
||||
echo "1. No progress bars (default)"
|
||||
echo "2. Page progress only (overall position)"
|
||||
echo "3. Auto-progress only (per-page countdown)"
|
||||
echo "4. Both progress bars (maximum feedback)"
|
||||
echo ""
|
||||
read -p "Enter choice (1-4): " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
PAGE_PROG=false
|
||||
AUTO_PROG=false
|
||||
DESC="No progress bars"
|
||||
;;
|
||||
2)
|
||||
PAGE_PROG=true
|
||||
AUTO_PROG=false
|
||||
DESC="Page progress only (--page-progress)"
|
||||
;;
|
||||
3)
|
||||
PAGE_PROG=false
|
||||
AUTO_PROG=true
|
||||
DESC="Auto-progress only (--auto-progress)"
|
||||
;;
|
||||
4)
|
||||
PAGE_PROG=true
|
||||
AUTO_PROG=true
|
||||
DESC="Both progress bars"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Configuration: $DESC${NC}"
|
||||
echo " page_progress: $PAGE_PROG"
|
||||
echo " auto_progress: $AUTO_PROG"
|
||||
echo ""
|
||||
|
||||
# Create test event with progress bar settings
|
||||
TEST_EVENT=$(cat <<EOF
|
||||
{
|
||||
"id": 888,
|
||||
"group_id": 2,
|
||||
"title": "Progress Bar Test Event",
|
||||
"start": "2025-01-01T00:00:00+00:00",
|
||||
"end": "2025-12-31T23:59:59+00:00",
|
||||
"presentation": {
|
||||
"type": "slideshow",
|
||||
"auto_advance": true,
|
||||
"slide_interval": 5,
|
||||
"loop": true,
|
||||
"page_progress": $PAGE_PROG,
|
||||
"auto_progress": $AUTO_PROG,
|
||||
"files": [
|
||||
{
|
||||
"name": "Wissenschaftliches Arbeiten Literaturrecherche.pdf",
|
||||
"url": "http://server:8000/api/files/test.pdf"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
echo "Sending test event to MQTT..."
|
||||
echo ""
|
||||
|
||||
mosquitto_pub -h "$MQTT_HOST" -t "infoscreen/events/2" -m "$TEST_EVENT"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ Event sent successfully${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Failed to send event${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Waiting for Display Manager to process event..."
|
||||
sleep 3
|
||||
|
||||
echo ""
|
||||
echo "Checking Display Manager log for progress bar settings..."
|
||||
echo ""
|
||||
|
||||
LOG_FILE="../logs/display_manager.log"
|
||||
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
echo -e "${YELLOW}Recent log entries:${NC}"
|
||||
tail -30 "$LOG_FILE" | grep -E "(progress|Progress|Impressive)" | tail -10
|
||||
else
|
||||
echo -e "${YELLOW}Log file not found: $LOG_FILE${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Expected Behavior"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
echo "• No progress indicators visible"
|
||||
echo "• Clean presentation display"
|
||||
;;
|
||||
2)
|
||||
echo "• Progress bar at bottom of screen"
|
||||
echo "• Shows current position: [=====> ] 50%"
|
||||
echo "• Updates as slides change"
|
||||
;;
|
||||
3)
|
||||
echo "• Countdown bar for each slide"
|
||||
echo "• Shows time remaining until next slide"
|
||||
echo "• Resets on each slide transition"
|
||||
;;
|
||||
4)
|
||||
echo "• Overall progress bar at bottom"
|
||||
echo "• Per-slide countdown overlay"
|
||||
echo "• Both indicators update in real-time"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Impressive Command Options"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "The Display Manager translates event fields to Impressive options:"
|
||||
echo ""
|
||||
echo "Event Field → Impressive Option"
|
||||
echo "-------------------- → ------------------"
|
||||
echo "page_progress: true → --page-progress (or -q)"
|
||||
echo "auto_progress: true → --auto-progress (or -k)"
|
||||
echo ""
|
||||
echo "Check the impressive.out.log for the exact command used:"
|
||||
echo " tail -20 ../logs/impressive.out.log"
|
||||
echo ""
|
||||
|
||||
echo -e "${GREEN}Test complete!${NC}"
|
||||
echo ""
|
||||
echo "Tips:"
|
||||
echo " • Press 'q' to quit the presentation"
|
||||
echo " • Run this script again to test different configurations"
|
||||
echo " • Check logs/display_manager.log for detailed output"
|
||||
echo ""
|
||||
143
scripts/test-scheduler-fields.sh
Executable file
143
scripts/test-scheduler-fields.sh
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/bin/bash
|
||||
# Test script to verify scheduler fields (page_progress, auto_progress) are preserved
|
||||
|
||||
echo "=========================================="
|
||||
echo "Scheduler Fields Preservation Test"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check if MQTT broker is configured
|
||||
if [ -f ../.env ]; then
|
||||
source ../.env
|
||||
MQTT_HOST=${MQTT_BROKER:-localhost}
|
||||
else
|
||||
MQTT_HOST=localhost
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Using MQTT broker: ${MQTT_HOST}${NC}"
|
||||
echo ""
|
||||
|
||||
# Test event with scheduler fields
|
||||
TEST_EVENT='{
|
||||
"id": 999,
|
||||
"occurrence_of_id": 999,
|
||||
"group_id": 2,
|
||||
"title": "Test Event with Scheduler Fields",
|
||||
"start": "2025-01-01T10:00:00+00:00",
|
||||
"end": "2025-12-31T23:59:59+00:00",
|
||||
"recurrence_rule": "FREQ=DAILY",
|
||||
"recurrence_end": "2025-12-31T23:59:59",
|
||||
"presentation": {
|
||||
"type": "slideshow",
|
||||
"auto_advance": true,
|
||||
"slide_interval": 10,
|
||||
"page_progress": true,
|
||||
"auto_progress": true,
|
||||
"files": [
|
||||
{
|
||||
"name": "test.pdf",
|
||||
"url": "http://server:8000/api/files/test.pdf"
|
||||
}
|
||||
]
|
||||
}
|
||||
}'
|
||||
|
||||
echo "1. Sending test event with scheduler fields to MQTT..."
|
||||
echo ""
|
||||
echo "Event contains:"
|
||||
echo " - page_progress: true (show overall progress bar)"
|
||||
echo " - auto_progress: true (show per-page countdown)"
|
||||
echo " - recurrence_rule: FREQ=DAILY"
|
||||
echo " - occurrence_of_id: 999"
|
||||
echo ""
|
||||
|
||||
mosquitto_pub -h "$MQTT_HOST" -t "infoscreen/events/2" -m "$TEST_EVENT"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ Event sent successfully${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Failed to send event${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "2. Waiting for event to be processed..."
|
||||
sleep 2
|
||||
|
||||
echo ""
|
||||
echo "3. Checking current_event.json for scheduler fields..."
|
||||
echo ""
|
||||
|
||||
EVENT_FILE="../src/current_event.json"
|
||||
|
||||
if [ ! -f "$EVENT_FILE" ]; then
|
||||
echo -e "${RED}✗ Event file not found: $EVENT_FILE${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Current event content:${NC}"
|
||||
cat "$EVENT_FILE" | jq '.'
|
||||
echo ""
|
||||
|
||||
# Check for specific fields
|
||||
echo "4. Verifying scheduler fields are preserved..."
|
||||
echo ""
|
||||
|
||||
PAGE_PROGRESS=$(cat "$EVENT_FILE" | jq -r '.[0].page_progress // .page_progress // "not_found"')
|
||||
AUTO_PROGRESS=$(cat "$EVENT_FILE" | jq -r '.[0].auto_progress // .auto_progress // "not_found"')
|
||||
OCCURRENCE_ID=$(cat "$EVENT_FILE" | jq -r '.[0].occurrence_of_id // .occurrence_of_id // "not_found"')
|
||||
RECURRENCE=$(cat "$EVENT_FILE" | jq -r '.[0].recurrence_rule // .recurrence_rule // "not_found"')
|
||||
|
||||
if [ "$PAGE_PROGRESS" = "true" ]; then
|
||||
echo -e "${GREEN}✓ page_progress preserved: $PAGE_PROGRESS${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ page_progress missing or incorrect: $PAGE_PROGRESS${NC}"
|
||||
fi
|
||||
|
||||
if [ "$AUTO_PROGRESS" = "true" ]; then
|
||||
echo -e "${GREEN}✓ auto_progress preserved: $AUTO_PROGRESS${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ auto_progress missing or incorrect: $AUTO_PROGRESS${NC}"
|
||||
fi
|
||||
|
||||
if [ "$OCCURRENCE_ID" = "999" ]; then
|
||||
echo -e "${GREEN}✓ occurrence_of_id preserved: $OCCURRENCE_ID${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ occurrence_of_id missing or incorrect: $OCCURRENCE_ID${NC}"
|
||||
fi
|
||||
|
||||
if [ "$RECURRENCE" = "FREQ=DAILY" ]; then
|
||||
echo -e "${GREEN}✓ recurrence_rule preserved: $RECURRENCE${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ recurrence_rule missing or incorrect: $RECURRENCE${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "5. Checking simclient log for debug messages..."
|
||||
echo ""
|
||||
|
||||
LOG_FILE="../logs/simclient.log"
|
||||
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
echo -e "${YELLOW}Recent log entries mentioning scheduler fields:${NC}"
|
||||
tail -20 "$LOG_FILE" | grep -E "page_progress|auto_progress" || echo " (no debug messages - set LOG_LEVEL=DEBUG to see them)"
|
||||
else
|
||||
echo -e "${YELLOW}Log file not found: $LOG_FILE${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo -e "${GREEN}Test Complete${NC}"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
echo " - Scheduler fields (page_progress, auto_progress) should be preserved in current_event.json"
|
||||
echo " - All metadata from the scheduler is automatically stored without filtering"
|
||||
echo " - Set LOG_LEVEL=DEBUG in .env to see field logging in simclient.log"
|
||||
echo ""
|
||||
27
scripts/test-screenshot.sh
Executable file
27
scripts/test-screenshot.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
SCREENSHOT_DIR="$(dirname "$0")/../screenshots"
|
||||
mkdir -p "$SCREENSHOT_DIR"
|
||||
|
||||
# Ensure DISPLAY is set for screenshot capture
|
||||
if [ -z "$DISPLAY" ]; then
|
||||
export DISPLAY=:0
|
||||
fi
|
||||
|
||||
# Test screenshot capture
|
||||
echo "Testing screenshot capture with DISPLAY=$DISPLAY"
|
||||
if scrot "$SCREENSHOT_DIR/test_$(date +%Y%m%d_%H%M%S).png" 2>/dev/null; then
|
||||
echo "✅ Screenshot captured successfully"
|
||||
echo "📁 Screenshot saved to: $SCREENSHOT_DIR"
|
||||
ls -la "$SCREENSHOT_DIR"/test_*.png | tail -1
|
||||
else
|
||||
echo "❌ Screenshot failed with scrot, trying imagemagick..."
|
||||
if import -window root "$SCREENSHOT_DIR/test_$(date +%Y%m%d_%H%M%S).png" 2>/dev/null; then
|
||||
echo "✅ Screenshot captured with imagemagick"
|
||||
echo "📁 Screenshot saved to: $SCREENSHOT_DIR"
|
||||
ls -la "$SCREENSHOT_DIR"/test_*.png | tail -1
|
||||
else
|
||||
echo "❌ Screenshot capture failed. Check DISPLAY variable and X11 access."
|
||||
echo "💡 Try: export DISPLAY=:0"
|
||||
echo "💡 Or run from local Pi terminal instead of SSH"
|
||||
fi
|
||||
fi
|
||||
149
scripts/test-utc-timestamps.sh
Executable file
149
scripts/test-utc-timestamps.sh
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/bin/bash
|
||||
# Test UTC timestamp handling in Display Manager
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
EVENT_FILE="$PROJECT_ROOT/src/current_event.json"
|
||||
|
||||
echo "🕐 UTC Timestamp Test for Display Manager"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Get current UTC and local times
|
||||
UTC_NOW=$(date -u '+%Y-%m-%d %H:%M:%S')
|
||||
LOCAL_NOW=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
TIMEZONE=$(date +%Z)
|
||||
UTC_OFFSET=$(date +%z)
|
||||
|
||||
echo "📅 Current Time Information:"
|
||||
echo " UTC Time: $UTC_NOW"
|
||||
echo " Local Time: $LOCAL_NOW"
|
||||
echo " Timezone: $TIMEZONE (UTC$UTC_OFFSET)"
|
||||
echo ""
|
||||
|
||||
# Calculate timestamps for testing
|
||||
# Start: 1 minute ago (UTC)
|
||||
START_TIME=$(date -u -d '1 minute ago' '+%Y-%m-%d %H:%M:%S')
|
||||
# End: 10 minutes from now (UTC)
|
||||
END_TIME=$(date -u -d '10 minutes' '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
echo "🧪 Test Scenarios:"
|
||||
echo ""
|
||||
echo "1️⃣ Test Active Event (should display NOW)"
|
||||
echo " Create event with:"
|
||||
echo " - Start: $START_TIME UTC (1 minute ago)"
|
||||
echo " - End: $END_TIME UTC (in 10 minutes)"
|
||||
echo ""
|
||||
|
||||
read -p "Press Enter to create test event..."
|
||||
|
||||
cat > "$EVENT_FILE" <<EOF
|
||||
{
|
||||
"id": 998,
|
||||
"title": "UTC Test - Active Event",
|
||||
"start": "$START_TIME",
|
||||
"end": "$END_TIME",
|
||||
"web": {
|
||||
"url": "https://www.timeanddate.com/worldclock/timezone/utc"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Created test event:"
|
||||
cat "$EVENT_FILE" | jq .
|
||||
echo ""
|
||||
echo "⏱️ Display Manager should detect this as ACTIVE and start displaying"
|
||||
echo " Check the logs with: tail -f logs/display_manager.log"
|
||||
echo ""
|
||||
|
||||
read -p "Press Enter to continue to next test..."
|
||||
echo ""
|
||||
|
||||
# Test 2: Event in the future
|
||||
FUTURE_START=$(date -u -d '5 minutes' '+%Y-%m-%d %H:%M:%S')
|
||||
FUTURE_END=$(date -u -d '15 minutes' '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
echo "2️⃣ Test Future Event (should NOT display yet)"
|
||||
echo " Create event with:"
|
||||
echo " - Start: $FUTURE_START UTC (in 5 minutes)"
|
||||
echo " - End: $FUTURE_END UTC (in 15 minutes)"
|
||||
echo ""
|
||||
|
||||
read -p "Press Enter to create future event..."
|
||||
|
||||
cat > "$EVENT_FILE" <<EOF
|
||||
{
|
||||
"id": 997,
|
||||
"title": "UTC Test - Future Event",
|
||||
"start": "$FUTURE_START",
|
||||
"end": "$FUTURE_END",
|
||||
"web": {
|
||||
"url": "https://www.timeanddate.com/worldclock/timezone/utc"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Created future event:"
|
||||
cat "$EVENT_FILE" | jq .
|
||||
echo ""
|
||||
echo "⏱️ Display Manager should detect this as NOT ACTIVE YET"
|
||||
echo " It should stop any current display"
|
||||
echo " Check logs: tail -f logs/display_manager.log"
|
||||
echo ""
|
||||
|
||||
read -p "Press Enter to continue to next test..."
|
||||
echo ""
|
||||
|
||||
# Test 3: Event in the past
|
||||
PAST_START=$(date -u -d '30 minutes ago' '+%Y-%m-%d %H:%M:%S')
|
||||
PAST_END=$(date -u -d '20 minutes ago' '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
echo "3️⃣ Test Past Event (should NOT display - already ended)"
|
||||
echo " Create event with:"
|
||||
echo " - Start: $PAST_START UTC (30 minutes ago)"
|
||||
echo " - End: $PAST_END UTC (20 minutes ago)"
|
||||
echo ""
|
||||
|
||||
read -p "Press Enter to create past event..."
|
||||
|
||||
cat > "$EVENT_FILE" <<EOF
|
||||
{
|
||||
"id": 996,
|
||||
"title": "UTC Test - Past Event",
|
||||
"start": "$PAST_START",
|
||||
"end": "$PAST_END",
|
||||
"web": {
|
||||
"url": "https://www.timeanddate.com/worldclock/timezone/utc"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Created past event:"
|
||||
cat "$EVENT_FILE" | jq .
|
||||
echo ""
|
||||
echo "⏱️ Display Manager should detect this as ALREADY ENDED"
|
||||
echo " It should stop any current display"
|
||||
echo " Check logs: tail -f logs/display_manager.log"
|
||||
echo ""
|
||||
|
||||
read -p "Press Enter to clean up..."
|
||||
|
||||
# Clean up
|
||||
rm -f "$EVENT_FILE"
|
||||
echo ""
|
||||
echo "🧹 Cleaned up test event file"
|
||||
echo ""
|
||||
echo "📊 Summary:"
|
||||
echo "==========="
|
||||
echo ""
|
||||
echo "✅ Test 1: Active event (past start, future end) → Should DISPLAY"
|
||||
echo "✅ Test 2: Future event (future start, future end) → Should NOT display yet"
|
||||
echo "✅ Test 3: Past event (past start, past end) → Should NOT display"
|
||||
echo ""
|
||||
echo "📝 The Display Manager should now correctly handle UTC timestamps!"
|
||||
echo ""
|
||||
echo "💡 Tips for debugging:"
|
||||
echo " • Watch logs: tail -f logs/display_manager.log"
|
||||
echo " • Check timezone: date; date -u"
|
||||
echo " • The Display Manager logs show both UTC and comparison times"
|
||||
echo ""
|
||||
75
scripts/test_cdp.py
Executable file
75
scripts/test_cdp.py
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Quick CDP tester: lists targets and evaluates a small script in the first target.
|
||||
|
||||
Usage:
|
||||
python3 scripts/test_cdp.py
|
||||
|
||||
Requires: requests, websocket-client
|
||||
"""
|
||||
import requests
|
||||
import websocket
|
||||
import json
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
resp = requests.get('http://127.0.0.1:9222/json', timeout=3)
|
||||
tabs = resp.json()
|
||||
except Exception as e:
|
||||
print('ERROR: could not fetch http://127.0.0.1:9222/json ->', e)
|
||||
return
|
||||
|
||||
if not tabs:
|
||||
print('No targets returned')
|
||||
return
|
||||
|
||||
print('Found targets:')
|
||||
for i, t in enumerate(tabs):
|
||||
print(i, t.get('type'), t.get('url'), '-', t.get('title'))
|
||||
|
||||
target = tabs[0]
|
||||
ws_url = target.get('webSocketDebuggerUrl')
|
||||
print('\nUsing target[0]:', target.get('url'))
|
||||
print('webSocketDebuggerUrl:', ws_url)
|
||||
|
||||
if not ws_url:
|
||||
print('No webSocketDebuggerUrl for target')
|
||||
return
|
||||
|
||||
try:
|
||||
# Some Chromium builds require an Origin header to avoid 403 during the websocket handshake
|
||||
try:
|
||||
ws = websocket.create_connection(ws_url, timeout=5, header=["Origin: http://127.0.0.1"])
|
||||
except TypeError:
|
||||
# older websocket-client accepts origin kw instead
|
||||
ws = websocket.create_connection(ws_url, timeout=5, origin="http://127.0.0.1")
|
||||
except Exception as e:
|
||||
print('ERROR: could not open websocket to', ws_url, '->', e)
|
||||
return
|
||||
|
||||
idn = 1
|
||||
# Enable runtime
|
||||
msg = {'id': idn, 'method': 'Runtime.enable'}
|
||||
ws.send(json.dumps(msg))
|
||||
idn += 1
|
||||
try:
|
||||
print('Runtime.enable =>', ws.recv())
|
||||
except Exception as e:
|
||||
print('No response to Runtime.enable:', e)
|
||||
|
||||
# Evaluate a script that logs and returns a value
|
||||
script = "console.log('cdp-test-log'); 12345"
|
||||
msg = {'id': idn, 'method': 'Runtime.evaluate', 'params': {'expression': script, 'returnByValue': True}}
|
||||
ws.send(json.dumps(msg))
|
||||
idn += 1
|
||||
try:
|
||||
resp = ws.recv()
|
||||
print('Runtime.evaluate =>', resp)
|
||||
except Exception as e:
|
||||
print('No response to Runtime.evaluate:', e)
|
||||
|
||||
ws.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
76
scripts/test_cdp_origins.py
Normal file
76
scripts/test_cdp_origins.py
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
# scripts/test_cdp_origins.py
|
||||
# Tries several Origin headers when connecting to Chromium DevTools websocket
|
||||
import requests, websocket, json, sys, time
|
||||
|
||||
def try_origin(ws_url, origin_header):
|
||||
try:
|
||||
# websocket-client accepts header=[...] or origin=... depending on version
|
||||
try:
|
||||
ws = websocket.create_connection(ws_url, timeout=5, header=[f"Origin: {origin_header}"])
|
||||
except TypeError:
|
||||
ws = websocket.create_connection(ws_url, timeout=5, origin=origin_header)
|
||||
return True, "connected"
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
def main():
|
||||
try:
|
||||
tabs = requests.get('http://127.0.0.1:9222/json', timeout=3).json()
|
||||
except Exception as e:
|
||||
print("ERROR: could not fetch DevTools json:", e)
|
||||
return
|
||||
|
||||
if not tabs:
|
||||
print("No DevTools targets found")
|
||||
return
|
||||
|
||||
target = tabs[0]
|
||||
ws_url = target.get('webSocketDebuggerUrl')
|
||||
print("Using target url:", target.get('url'))
|
||||
print("DevTools websocket:", ws_url)
|
||||
if not ws_url:
|
||||
print("No webSocketDebuggerUrl found in target")
|
||||
return
|
||||
|
||||
# candidate origins to try
|
||||
candidates = [
|
||||
"http://127.0.0.1",
|
||||
"http://localhost",
|
||||
"https://www.computerbase.de", # page origin (use the exact scheme + host of the page)
|
||||
"https://computerbase.de",
|
||||
"null",
|
||||
"chrome-devtools://devtools",
|
||||
""
|
||||
]
|
||||
|
||||
print("\nTrying origins (may need to match page origin exactly):")
|
||||
for orig in candidates:
|
||||
ok, msg = try_origin(ws_url, orig)
|
||||
print(f"Origin={repr(orig):30} -> {ok} : {msg}")
|
||||
|
||||
# If one of them connected, try to send a Runtime.evaluate to confirm:
|
||||
# (try the first that succeeded)
|
||||
for orig in candidates:
|
||||
try:
|
||||
try:
|
||||
ws = websocket.create_connection(ws_url, timeout=5, header=[f"Origin: {orig}"])
|
||||
except TypeError:
|
||||
ws = websocket.create_connection(ws_url, timeout=5, origin=orig)
|
||||
print("\nConnected with origin:", orig)
|
||||
msg_id = 1
|
||||
payload = {"id": msg_id, "method": "Runtime.enable"}
|
||||
ws.send(json.dumps(payload))
|
||||
print("Runtime.enable ->", ws.recv())
|
||||
msg_id += 1
|
||||
payload = {"id": msg_id, "method": "Runtime.evaluate", "params": {"expression": "1+2", "returnByValue": True}}
|
||||
ws.send(json.dumps(payload))
|
||||
print("Runtime.evaluate ->", ws.recv())
|
||||
ws.close()
|
||||
break
|
||||
except Exception as e:
|
||||
# try next origin
|
||||
continue
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user