base.html passed the cache-busting query string INSIDE the filename argument:
url_for('static', filename='uploads/header_logo.png?v=1')
Flask percent-encodes the '?' to '%3F', producing a request for a file
literally named "header_logo.png%3Fv=1", which does not exist. Every
authenticated page therefore logged:
GET /static/uploads/header_logo.png%3Fv=1 404
The logo silently stayed hidden too, because the element carries
onerror="this.style.display='none'".
Changes:
- base.html / login.html: append "?v=..." OUTSIDE url_for(), matching what
admin/customize_logos.html already did correctly.
- Inject logo_version from a context processor instead of hardcoding it.
It is derived from the newest logo's mtime, so uploading a new logo in
Admin -> Customize Logos is reflected immediately. The previous value was
a literal 1, which defeated cache-busting entirely; login.html used
range(1, 999999) | random, which changed on every request and made the
logo uncacheable.
Verified: /, /content/ and /players/ now render
/static/uploads/header_logo.png?v=<mtime> (HTTP 200), and no %3F requests
appear in the logs.
- Changed ownership of all files to scheianu:scheianu
- Set directories to 755 permissions (rwxr-xr-x)
- Set files to 644 permissions (rw-r--r--)
- Made shell scripts executable (755)
- Allows development without requiring sudo for file modifications
- Improves development workflow and security
- Added auto-creation of PlayerUser records from player metadata (user_card_data)
- Fixed player_user table schema (removed player_id, made user_code unique globally)
- Created admin page for managing editing users (view, update names, delete)
- Updated permissions: normal users can now access admin panel, editing users, and leftover media
- Admin-only access: user management, system dependencies, logo customization
- Fixed edited media workflow to preserve original files
- Content.filename now points to edited_media folder, keeping originals intact
- Added user display names in edited media page (shows name if set, code otherwise)
- Fixed leftover media file size calculation (handle None values)
- Split editing users into separate card on admin panel with description
- Created 10 SVG icon files in app/static/icons/ (Feather Icons style)
- Updated base.html with SVG icons in navigation and dark mode toggle
- Updated dashboard.html with icons in stats cards and quick actions
- Updated content_list_new.html (playlist management) with SVG icons
- Updated upload_media.html with upload-related icons
- Updated manage_player.html with player management icons
- Icons use currentColor for automatic theme adaptation
- Removed emoji dependency for better Raspberry Pi compatibility
- Added ICON_INTEGRATION.md documentation
Templates (8 basic templates):
- base.html: Main layout with navigation, flash messages, responsive design
- login.html: User login form with remember me option
- register.html: User registration with validation
- dashboard.html: Main dashboard with statistics cards and recent activity
- players_list.html: Players list placeholder
- add_player.html: Add player form
- groups_list.html: Groups list placeholder
- create_group.html: Create group form
- content_list.html: Content list placeholder
- upload_content.html: File upload form
- admin.html: Admin panel with system overview
Development Setup:
- run_dev.sh: Automated development server setup script
- Creates virtual environment
- Installs dependencies
- Initializes database
- Creates default admin user (admin/admin123)
- Runs Flask development server on port 5000
Static Files:
- static/uploads/ directory with .gitkeep
- Ready for media file uploads
Testing Features:
✅ Basic navigation and routing
✅ Authentication flow (login/register/logout)
✅ Dashboard with statistics
✅ Flash message system
✅ Responsive design with clean UI
✅ Placeholder templates for all routes
Ready for manual testing at http://localhost:5000