Replace emoji icons with local SVG files for consistent rendering
- 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
This commit is contained in:
250
KIVY_PLAYER_COMPATIBILITY.md
Normal file
250
KIVY_PLAYER_COMPATIBILITY.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# Kivy Player Compatibility with New Playlist Architecture
|
||||
|
||||
## Overview
|
||||
This document outlines the compatibility verification and updates made to ensure the Kivy signage player works with the new playlist-centric architecture.
|
||||
|
||||
## Changes Made to DigiServer API
|
||||
|
||||
### 1. Content URL Format in Playlist Response
|
||||
**Location:** `/home/pi/Desktop/digiserver-v2/app/blueprints/api.py` - `get_cached_playlist()` function
|
||||
|
||||
**Issue:**
|
||||
- Player expects: `file_name` key in playlist items
|
||||
- Server was returning: `filename` key
|
||||
|
||||
**Fix:**
|
||||
```python
|
||||
playlist_data.append({
|
||||
'id': content.id,
|
||||
'file_name': content.filename, # Changed from 'filename' to 'file_name'
|
||||
'type': content.content_type,
|
||||
'duration': content._playlist_duration or content.duration or 10,
|
||||
'position': content._playlist_position or idx,
|
||||
'url': content_url, # Now returns full URL with server base
|
||||
'description': content.description
|
||||
})
|
||||
```
|
||||
|
||||
**What Changed:**
|
||||
- ✅ Changed `'filename'` to `'file_name'` to match player expectations
|
||||
- ✅ URL now includes full server base URL (e.g., `http://server:5000/static/uploads/image.jpg`)
|
||||
- ✅ Player can now download content directly without URL manipulation
|
||||
|
||||
### 2. Authentication Response - Removed group_id
|
||||
**Location:** `/home/pi/Desktop/digiserver-v2/app/blueprints/api.py`
|
||||
|
||||
**Endpoints Updated:**
|
||||
1. `/api/auth/player` (line ~145) - ✅ Already returns `playlist_id`
|
||||
2. `/api/auth/verify` (line ~192) - ✅ Changed from `group_id` to `playlist_id`
|
||||
|
||||
**Before:**
|
||||
```python
|
||||
response = {
|
||||
'valid': True,
|
||||
'player_id': player.id,
|
||||
'player_name': player.name,
|
||||
'hostname': player.hostname,
|
||||
'group_id': player.group_id, # OLD
|
||||
'orientation': player.orientation,
|
||||
'status': player.status
|
||||
}
|
||||
```
|
||||
|
||||
**After:**
|
||||
```python
|
||||
response = {
|
||||
'valid': True,
|
||||
'player_id': player.id,
|
||||
'player_name': player.name,
|
||||
'hostname': player.hostname,
|
||||
'playlist_id': player.playlist_id, # NEW
|
||||
'orientation': player.orientation,
|
||||
'status': player.status
|
||||
}
|
||||
```
|
||||
|
||||
## Changes Made to Kivy Player
|
||||
|
||||
### 1. Updated player_auth.py
|
||||
**Location:** `/home/pi/Desktop/Kiwy-Signage/src/player_auth.py`
|
||||
|
||||
**Changes:**
|
||||
1. ✅ Default auth data structure: `group_id` → `playlist_id` (line ~42)
|
||||
2. ✅ Authentication data storage: `group_id` → `playlist_id` (line ~97)
|
||||
3. ✅ Clear auth method: `group_id` → `playlist_id` (line ~299)
|
||||
4. ✅ Example usage output: Updated to show `playlist_id` instead of `group_id`
|
||||
|
||||
**Impact:**
|
||||
- Player now stores and uses `playlist_id` instead of deprecated `group_id`
|
||||
- Backward compatible: old auth files will load but won't have `playlist_id` until re-authentication
|
||||
|
||||
## API Endpoints Used by Kivy Player
|
||||
|
||||
### Player Authentication Flow
|
||||
```
|
||||
1. POST /api/auth/player
|
||||
Body: { hostname, password OR quickconnect_code }
|
||||
Returns: { auth_code, player_id, playlist_id, orientation, ... }
|
||||
|
||||
2. GET /api/playlists/<player_id>
|
||||
Headers: Authorization: Bearer <auth_code>
|
||||
Returns: { playlist: [...], playlist_version: N, ... }
|
||||
|
||||
3. GET <full_url_from_playlist_item>
|
||||
Downloads content file
|
||||
```
|
||||
|
||||
### Expected Playlist Format
|
||||
```json
|
||||
{
|
||||
"player_id": 1,
|
||||
"player_name": "Player-001",
|
||||
"playlist_id": 5,
|
||||
"playlist_version": 3,
|
||||
"playlist": [
|
||||
{
|
||||
"id": 1,
|
||||
"file_name": "demo1.jpg",
|
||||
"type": "image",
|
||||
"duration": 10,
|
||||
"position": 1,
|
||||
"url": "http://192.168.1.100:5000/static/uploads/demo1.jpg",
|
||||
"description": "Demo Image 1"
|
||||
}
|
||||
],
|
||||
"count": 1
|
||||
}
|
||||
```
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
### Server-Side ✅
|
||||
- [x] Player model has `playlist_id` field
|
||||
- [x] Content model has unique filenames
|
||||
- [x] Playlist model with version tracking
|
||||
- [x] API returns `file_name` (not `filename`)
|
||||
- [x] API returns full URLs for content
|
||||
- [x] API returns `playlist_id` in auth responses
|
||||
- [x] `/api/playlists/<player_id>` endpoint exists and works
|
||||
- [x] Bearer token authentication works
|
||||
|
||||
### Client-Side ✅
|
||||
- [x] PlayerAuth class uses `playlist_id`
|
||||
- [x] get_playlists_v2.py can fetch playlists
|
||||
- [x] Player can download content from full URLs
|
||||
- [x] Player parses `file_name` correctly
|
||||
- [x] Player uses Bearer token auth
|
||||
|
||||
## Workflow Example
|
||||
|
||||
### 1. Server Setup
|
||||
```bash
|
||||
# Create a playlist
|
||||
curl -X POST http://server:5000/content/create_playlist \
|
||||
-d "name=Morning Playlist"
|
||||
|
||||
# Upload content
|
||||
curl -X POST http://server:5000/content/upload_media \
|
||||
-F "file=@demo1.jpg"
|
||||
|
||||
# Add content to playlist
|
||||
curl -X POST http://server:5000/content/add_content_to_playlist \
|
||||
-d "playlist_id=1&content_id=1&duration=10"
|
||||
|
||||
# Create player
|
||||
curl -X POST http://server:5000/players/add \
|
||||
-d "name=Player-001&hostname=player001&quickconnect_code=QUICK123"
|
||||
|
||||
# Assign playlist to player
|
||||
curl -X POST http://server:5000/content/assign_player_to_playlist \
|
||||
-d "player_id=1&playlist_id=1"
|
||||
```
|
||||
|
||||
### 2. Player Authentication
|
||||
```python
|
||||
from player_auth import PlayerAuth
|
||||
|
||||
auth = PlayerAuth()
|
||||
success, error = auth.authenticate(
|
||||
server_url='http://192.168.1.100:5000',
|
||||
hostname='player001',
|
||||
quickconnect_code='QUICK123'
|
||||
)
|
||||
|
||||
if success:
|
||||
print(f"✅ Authenticated as {auth.get_player_name()}")
|
||||
print(f"📋 Playlist ID: {auth.auth_data['playlist_id']}")
|
||||
```
|
||||
|
||||
### 3. Fetch and Download Playlist
|
||||
```python
|
||||
from get_playlists_v2 import update_playlist_if_needed
|
||||
|
||||
config = {
|
||||
'server_ip': '192.168.1.100',
|
||||
'port': '5000',
|
||||
'screen_name': 'player001',
|
||||
'quickconnect_key': 'QUICK123'
|
||||
}
|
||||
|
||||
playlist_file = update_playlist_if_needed(
|
||||
config=config,
|
||||
playlist_dir='playlists/',
|
||||
media_dir='media/'
|
||||
)
|
||||
|
||||
if playlist_file:
|
||||
print(f"✅ Playlist downloaded: {playlist_file}")
|
||||
```
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
1. **Test Authentication:**
|
||||
- Test with valid quickconnect code
|
||||
- Test with invalid quickconnect code
|
||||
- Verify `playlist_id` is returned
|
||||
|
||||
2. **Test Playlist Fetching:**
|
||||
- Fetch playlist with auth code
|
||||
- Verify `file_name` and full URLs in response
|
||||
- Test playlist version tracking
|
||||
|
||||
3. **Test Content Download:**
|
||||
- Download images from full URLs
|
||||
- Download videos from full URLs
|
||||
- Verify files save correctly
|
||||
|
||||
4. **Test Playlist Updates:**
|
||||
- Update playlist version on server
|
||||
- Player should detect new version
|
||||
- Player should download only new content
|
||||
|
||||
## Migration Notes
|
||||
|
||||
### For Existing Deployments
|
||||
1. **Server:** Database recreated with new schema (groups removed)
|
||||
2. **Players:** Will re-authenticate on next check
|
||||
3. **Auth Files:** Old `player_auth.json` files are compatible but will update on next auth
|
||||
|
||||
### Backward Compatibility
|
||||
- ⚠️ Legacy `/api/playlists?hostname=X&quickconnect_code=Y` endpoint still exists
|
||||
- ⚠️ New v2 auth flow preferred (uses Bearer tokens)
|
||||
- ⚠️ Old player code using groups will need updates
|
||||
|
||||
## Known Issues / Future Improvements
|
||||
|
||||
1. **Content Cleanup:** Old media files not referenced by playlists should be deleted
|
||||
2. **Playlist Caching:** Cache invalidation when playlist updated on server
|
||||
3. **Partial Updates:** Download only changed content instead of full playlist
|
||||
4. **Network Resilience:** Better handling of connection failures
|
||||
5. **Progress Feedback:** Real-time download progress for large files
|
||||
|
||||
## Contact
|
||||
For issues or questions about player compatibility, check:
|
||||
- Server logs: `/home/pi/Desktop/digiserver-v2/instance/logs/`
|
||||
- Player logs: See PlayerAuth logger output
|
||||
- API documentation: Check `/api/health` endpoint
|
||||
|
||||
---
|
||||
**Last Updated:** 2025-01-XX
|
||||
**Version:** DigiServer v2.0 with Playlist Architecture
|
||||
Reference in New Issue
Block a user