Commit Graph

22 Commits

Author SHA1 Message Date
ske087 477128de81 First-run setup: ship no credentials, ask for them on first start
The exe shipped config/app_config.json AND src/player_auth.json inside the
bundle, and because a frozen app runs with cwd = _internal/, the player loaded
that snapshot as its live auth state. A stale snapshot therefore made a fresh
build boot "already authenticated" against an old server and play an outdated
playlist. It also meant every install inherited the build machine's server_ip,
screen_name and auth_code.

Both files are now excluded from the bundle (app_config.json is no longer added
to datas, player_auth.json is excluded from Tree(src)), and the runtime hook no
longer copies a config into place on first run.

New behaviour, all in src/main.py so it applies to the Pi build too:

  - The player starts with blank credentials. A missing file, an empty or
    unparseable file, missing keys, and leftover placeholder values
    (localhost, 127.0.0.1, kivy-player, 1234567) all count as UNCONFIGURED.
    config_is_configured() is the single source of truth for that decision.
  - After the splash video a notice appears ("Player is not configured"), and
    after 5 seconds the Settings screen opens automatically so the operator can
    enter the server details.
  - Saving valid values writes config/app_config.json next to the .exe and
    starts playback immediately - no restart needed.
  - On a machine that IS configured, the notice and Settings are skipped and the
    cached playlist plays straight away.
  - Settings refuses to close while the three required fields are blank, so it
    cannot be dismissed into a permanently blank screen with no way back.
  - The 30s playlist timer does not fight the setup flow while unconfigured.

on_intro_finished() is the single decision point after the splash; both intro
paths (video end and "no intro file") go through it so they cannot drift apart.

Also loads config over DEFAULT_CONFIG rather than replacing it, so a partial or
older config file keeps working defaults instead of losing keys.

Note for future changes: when adding a new REQUIRED config key, add it to
CONFIG_REQUIRED_KEYS or the first-run flow will not ask for it.

Verified on the packaged exe by removing the config to simulate a fresh install:
setup_required_shown -> setup_opening_settings exactly 5s later ->
setup_completed, with the config written next to the exe and playback resuming.
Restarting with that config produced no setup events at all.
Covered by windows/test_first_run_setup.py.
2026-09-13 10:14:56 +03:00
ske087 a19627885c Add unified WeblinkSession controller and interaction-driven playback
Web links were implemented three times (main.py subprocess, run_win.py
subprocess + Win32 overlay, cef_browser.py embedded CEF), each owning its own
process handle, watchdog and teardown. That ambiguity caused leaked browsers,
skipped items, lost foreground and blank screens when a page failed to load.

Replace all three with a single owner in src/weblink_session.py:

- WeblinkSession: validate -> launch -> verify -> watch -> teardown.
  Generation-tokened so stale callbacks are ignored, idempotent close(),
  atexit-safe, never more than one browser alive.
- WeblinkAdapter: the only platform-specific part (launch / wait_visible /
  is_alive / teardown / prewarm). Platform layers inject engines through
  SignagePlayer.weblink_adapter_factory.
- ChromiumSubprocessAdapter: default engine (Pi chromium, Windows chrome/msedge).
- InteractionWatcher: decides when an item is finished.
- WebInputSources: /dev/input/event* (Linux) plus a GetCursorPos pointer tap
  (needed on Windows for embedded CEF, which has no child process).

Interaction model: web links are an interactive surface, not timed media.
The player advances only when the configured duration has elapsed AND the
viewer has not interacted for 10s, measured from the most recent interaction.
A touch in the final seconds of a slot therefore pushes the advance 10s past
that touch, and each further touch pushes it again, so a page is never pulled
out from under someone using it. An untouched page still advances on schedule.
A drag burst counts as one interaction but the countdown tracks its last event,
so an item cannot be cut off mid-gesture. max_dwell (duration x factor, floored
by min_max_dwell) is an absolute backstop against a wedged browser or a jammed
touchscreen.

Verified start-up: the visibility wait runs on the watcher thread, never on
Kivy's main thread. If the browser window never appears the item is reported
failed and skipped, instead of resetting the error counter and leaving a black
screen up for the whole duration.

Config: new "weblink" block in config/app_config.json (engine,
interaction_postpone, interaction_debounce, interaction_grace,
max_dwell_factor, min_max_dwell, launch_timeout, prewarm) with safe defaults,
so an absent block still works.

Also add weblink_session to the PyInstaller hiddenimports so the frozen exe
bundles the new module.
2026-09-10 16:43:36 +03:00
ske087 3845830a86 Add Windows Player support and related files
- New windows/ directory with build scripts, specs, and configuration
- Windows-specific requirements (requirements_win.txt)
- Launch and runtime scripts for Windows (run_win.py, launch_player.bat)
- PyInstaller build configuration (build.spec)
- Updated .gitignore to exclude windows/venv312/
- Updated config and source files for Windows compatibility
- Moved working_files to proper directory
2026-07-24 08:34:00 +03:00
SKE087 fb9f46a94f Fix ffpyplayer offline wheel and update install scripts
- Rebuilt evdev wheel for cp313 aarch64 (was missing from repo)
- Updated install.sh: add --system-site-packages to venv, verify imports
- Updated start.sh: activate .venv before running player
- Updated run_player.sh: activate .venv before running player
- Added pip fallback for kivy/ffpyplayer if apt/pip install misses them
2026-07-17 13:02:59 +03:00
SKE087 9d8eb0cf21 Fix Python 3.13 compatibility and installation issues
- Replaced all cp311 wheels with cp313 wheels for Python 3.13 compatibility
- Added new dependency wheels: aiohappyeyeballs, evdev, ffpyplayer
- Rebuilt install.sh with virtual environment + offline wheel installation
- Added --sudo-user/-U and --sudo-password/-W CLI arguments
- Added run_sudo() helper to avoid password prompts during installation
- Fixed 'Setting Up Player Directories' hang (cat->stdin) by using touch
- Updated start.sh to activate virtual environment before running player
- Updated run_player.sh to activate virtual environment
- Removed old cp311 incompatible wheels
- Added backup of previous install.sh as install.sh.bak
2026-07-17 10:21:32 +03:00
Kiwy Signage Player 609d9169d2 updated player for deploy from server 2026-06-29 19:59:49 +03:00
Kiwy Player c5bf6c1eaf Fix: Handle HTTPS certificate endpoint 404 gracefully
- Modified ssl_utils.py to treat 404 errors as expected when server doesn't have /api/certificate endpoint
- Changed verify_ssl setting to false in app_config.json to allow HTTPS connections without certificate verification
- This allows the player to connect to servers that don't implement the certificate endpoint
2026-01-16 22:25:59 +02:00
Kiwy Signage Player 5843bb5215 renamed card checked 2025-12-13 19:09:06 +02:00
ske087 2b42999008 aded card check 2025-12-13 17:05:49 +00:00
Kiwy Signage Player f1a84d05d5 updated buttons in settings 2025-12-08 21:52:03 +02:00
ske087 02227a12e5 updeated to read specific card 2025-12-08 15:45:37 +02:00
ske087 9d32f43ac7 Add edit feature enable/disable setting
- Added checkbox in Settings screen to enable/disable edit feature
- Setting stored in app_config.json as 'edit_feature_enabled'
- Edit workflow now validates: player setting, media type, server permission, card auth
- Shows appropriate error message when edit is blocked at any validation step
- Defaults to enabled (true) if not set
- All conditions must be met for edit interface to open
2025-12-08 14:30:12 +02:00
ske087 af1e671c7f Add USB card reader authentication for edit feature
- Implemented CardReader class to read data from USB card readers
- Added CardSwipePopup with 5-second timeout and visual feedback
- Card data is captured and included in edit metadata
- Card data sent to server when edited images are uploaded
- Added evdev dependency for USB input device handling
- Fallback mode when evdev not available (for development)
- Created test utility (test_card_reader.py) for card reader testing
- Added comprehensive documentation (CARD_READER_AUTHENTICATION.md)
- Added access-card.png icon for authentication popup
- Edit interface requires card swipe or times out after 5 seconds
2025-12-08 14:05:04 +02:00
Kiwy Signage Player fba2007bdf Improve edit interface: full-screen layout with toolbars, versioned saving to edited_media folder 2025-12-05 00:25:53 +02:00
ske087 3f9674517d updated player 2025-11-22 09:48:48 +02:00
ske087 da1d515cc5 updated 2025-11-21 22:20:23 +02:00
ske087 4d803d4fe9 updated files 2025-11-21 22:20:06 +02:00
Kivy Signage Player 9f957bbd5d updated get playlist function 2025-11-12 16:06:48 +02:00
Kivy Signage Player a2fddfa312 updated view 2025-10-27 16:46:08 +02:00
Kivy Signage Player e3831d1594 updated view 2025-10-27 14:08:27 +02:00
Kivy Signage Player 88b28a5937 update location and setting 2025-09-30 10:36:30 +03:00
Kivy Signage Player 04d4ea5916 Initial commit: Kivy Signage Player
- Complete Kivy-based signage player application
- Fetches playlists from DigiServer via REST API
- Supports images (JPG, PNG, GIF, BMP) and videos (MP4, AVI, MKV, MOV, WEBM)
- Modern UI with touch controls and settings popup
- Separated UI (KV file) from business logic (Python)
- Fullscreen media display with proper scaling
- Server feedback system for player status reporting
- Auto-hide controls with mouse/touch activation
- Virtual environment setup with requirements.txt
- Installation and run scripts included

Features:
 Cross-platform Kivy framework
 Server integration with DigiServer
 Media playback with duration control
 Player feedback and status reporting
 Settings management with persistent config
 Error handling and recovery
 Clean architecture with KV file separation
2025-09-26 16:48:26 +03:00