Fix: Reload playlist after edited media is uploaded to server
CRITICAL FIX - This was the main issue preventing edited images from appearing! Problem: - Edited media was being uploaded to server successfully - Server updated the playlist (new version returned: 34) - BUT player never reloaded the playlist - So edited images stayed invisible until restart Solution: 1. EditPopup now sets should_refresh_playlist flag when upload succeeds 2. Main player checks this flag in check_playlist_and_play() 3. When flag is set, player immediately reloads playlist 4. Edited media appears instantly without needing restart Testing: - Created diagnostic script test_edited_media_upload.py - Confirmed server accepts edited media and returns new playlist version - Verified SSL fix works correctly (verify=False) Now edited images should appear immediately after save!
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
1768679578.0929108
|
|
||||||
BIN
media/edited_media/4k1_e_v1.jpg
Normal file
BIN
media/edited_media/4k1_e_v1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
8
media/edited_media/4k1_e_v1_metadata.json
Normal file
8
media/edited_media/4k1_e_v1_metadata.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"time_of_modification": "2026-01-17T21:53:55.318456",
|
||||||
|
"original_name": "4k1.jpg",
|
||||||
|
"new_name": "4k1_e_v1.jpg",
|
||||||
|
"original_path": "/home/pi/Desktop/Kiwy-Signage/media/4k1.jpg",
|
||||||
|
"version": 1,
|
||||||
|
"user_card_data": "0007206239"
|
||||||
|
}
|
||||||
@@ -491,6 +491,23 @@ class EditPopup(Popup):
|
|||||||
Logger.info(f" - Image: {image_path}")
|
Logger.info(f" - Image: {image_path}")
|
||||||
Logger.info(f" - Metadata: {metadata_path}")
|
Logger.info(f" - Metadata: {metadata_path}")
|
||||||
|
|
||||||
|
# Trigger playlist reload if server provides new version
|
||||||
|
try:
|
||||||
|
new_version = response_data.get('new_playlist_version')
|
||||||
|
if new_version:
|
||||||
|
Logger.info(f"EditPopup: 📡 Server reports new playlist version: {new_version}")
|
||||||
|
Logger.info(f"EditPopup: Triggering playlist reload on next cycle...")
|
||||||
|
|
||||||
|
# Set a flag in the player to reload playlist
|
||||||
|
# This will be checked in the main playback loop
|
||||||
|
if hasattr(self.player, 'should_refresh_playlist'):
|
||||||
|
self.player.should_refresh_playlist = True
|
||||||
|
Logger.info(f"EditPopup: ✓ Playlist reload flag set")
|
||||||
|
else:
|
||||||
|
Logger.warning(f"EditPopup: Could not set playlist reload flag (player method not available)")
|
||||||
|
except Exception as e:
|
||||||
|
Logger.warning(f"EditPopup: Could not process playlist version from server: {e}")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
elif response.status_code == 404:
|
elif response.status_code == 404:
|
||||||
Logger.error("EditPopup: ❌ Upload endpoint not found on server (404)")
|
Logger.error("EditPopup: ❌ Upload endpoint not found on server (404)")
|
||||||
|
|||||||
11
src/main.py
11
src/main.py
@@ -903,6 +903,7 @@ class SignagePlayer(Widget):
|
|||||||
self.auto_resume_event = None # Track scheduled auto-resume
|
self.auto_resume_event = None # Track scheduled auto-resume
|
||||||
self.config = {}
|
self.config = {}
|
||||||
self.playlist_version = None
|
self.playlist_version = None
|
||||||
|
self.should_refresh_playlist = False # Flag to reload playlist after edit upload
|
||||||
self.consecutive_errors = 0 # Track consecutive playback errors
|
self.consecutive_errors = 0 # Track consecutive playback errors
|
||||||
self.max_consecutive_errors = 10 # Maximum errors before stopping
|
self.max_consecutive_errors = 10 # Maximum errors before stopping
|
||||||
self.intro_played = False # Track if intro has been played
|
self.intro_played = False # Track if intro has been played
|
||||||
@@ -1218,6 +1219,16 @@ class SignagePlayer(Widget):
|
|||||||
if not self.intro_played:
|
if not self.intro_played:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Check if playlist needs to be refreshed (after edited media upload)
|
||||||
|
if self.should_refresh_playlist:
|
||||||
|
Logger.info("SignagePlayer: Reloading playlist due to edited media upload...")
|
||||||
|
self.should_refresh_playlist = False
|
||||||
|
self.load_playlist()
|
||||||
|
# If we were playing, restart from current position
|
||||||
|
if self.is_playing and self.playlist:
|
||||||
|
self.play_current_media(force_reload=True)
|
||||||
|
return
|
||||||
|
|
||||||
if not self.playlist:
|
if not self.playlist:
|
||||||
self.load_playlist()
|
self.load_playlist()
|
||||||
|
|
||||||
|
|||||||
165
test_edited_media_upload.py
Normal file
165
test_edited_media_upload.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test script to diagnose edited media upload issues
|
||||||
|
Run this to test if the server endpoint exists and works correctly
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Add src to path
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
|
||||||
|
|
||||||
|
def test_upload():
|
||||||
|
"""Test the edited media upload functionality"""
|
||||||
|
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("EDITED MEDIA UPLOAD DIAGNOSTICS")
|
||||||
|
print("="*60)
|
||||||
|
|
||||||
|
# Get authentication
|
||||||
|
try:
|
||||||
|
from get_playlists_v2 import get_auth_instance
|
||||||
|
auth = get_auth_instance()
|
||||||
|
|
||||||
|
if not auth or not auth.is_authenticated():
|
||||||
|
print("❌ ERROR: Not authenticated!")
|
||||||
|
print(" Please ensure player_auth.json exists and is valid")
|
||||||
|
return False
|
||||||
|
|
||||||
|
server_url = auth.auth_data.get('server_url')
|
||||||
|
auth_code = auth.auth_data.get('auth_code')
|
||||||
|
|
||||||
|
print(f"\n✓ Authentication successful")
|
||||||
|
print(f" Server URL: {server_url}")
|
||||||
|
print(f" Auth Code: {auth_code[:20]}..." if auth_code else " Auth Code: None")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Authentication error: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check for edited media files
|
||||||
|
edited_media_dir = os.path.join(os.path.dirname(__file__), 'media', 'edited_media')
|
||||||
|
edited_files = list(Path(edited_media_dir).glob('*_e_v*.jpg'))
|
||||||
|
metadata_files = list(Path(edited_media_dir).glob('*_metadata.json'))
|
||||||
|
|
||||||
|
print(f"\n✓ Edited Media Directory: {edited_media_dir}")
|
||||||
|
print(f" Edited images: {len(edited_files)}")
|
||||||
|
print(f" Metadata files: {len(metadata_files)}")
|
||||||
|
|
||||||
|
if not edited_files:
|
||||||
|
print("\n⚠️ No edited images found!")
|
||||||
|
print(" Create an edit first, then run this test")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Test with the first edited image
|
||||||
|
image_path = str(edited_files[0])
|
||||||
|
metadata_file = str(edited_files[0]).replace('.jpg', '_metadata.json')
|
||||||
|
|
||||||
|
if not os.path.exists(metadata_file):
|
||||||
|
print(f"\n❌ Metadata file not found: {metadata_file}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"\nTesting upload with:")
|
||||||
|
print(f" Image: {os.path.basename(image_path)}")
|
||||||
|
print(f" Size: {os.path.getsize(image_path):,} bytes")
|
||||||
|
print(f" Metadata: {os.path.basename(metadata_file)}")
|
||||||
|
|
||||||
|
# Load and display metadata
|
||||||
|
with open(metadata_file, 'r') as f:
|
||||||
|
metadata = json.load(f)
|
||||||
|
|
||||||
|
print(f"\nMetadata content:")
|
||||||
|
for key, value in metadata.items():
|
||||||
|
print(f" {key}: {value}")
|
||||||
|
|
||||||
|
# Add original_filename if not present
|
||||||
|
metadata['original_filename'] = os.path.basename(metadata['original_path'])
|
||||||
|
|
||||||
|
# Prepare upload request
|
||||||
|
upload_url = f"{server_url}/api/player-edit-media"
|
||||||
|
headers = {'Authorization': f'Bearer {auth_code}'}
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print("TESTING UPLOAD...")
|
||||||
|
print(f"{'='*60}")
|
||||||
|
print(f"Endpoint: {upload_url}")
|
||||||
|
print(f"Headers: Authorization: Bearer {auth_code[:20]}...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(image_path, 'rb') as img_file:
|
||||||
|
files = {
|
||||||
|
'image_file': (metadata['original_filename'], img_file, 'image/jpeg')
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
'metadata': json.dumps(metadata),
|
||||||
|
'original_file': metadata['original_filename']
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"\nSending request (30s timeout, SSL verify=False)...")
|
||||||
|
response = requests.post(
|
||||||
|
upload_url,
|
||||||
|
headers=headers,
|
||||||
|
files=files,
|
||||||
|
data=data,
|
||||||
|
timeout=30,
|
||||||
|
verify=False
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"\n✓ Response received!")
|
||||||
|
print(f" Status Code: {response.status_code}")
|
||||||
|
print(f" Headers: {dict(response.headers)}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
print(f"\n✅ SUCCESS! Server accepted the upload")
|
||||||
|
print(f" Response: {response.json()}")
|
||||||
|
return True
|
||||||
|
elif response.status_code == 404:
|
||||||
|
print(f"\n❌ ENDPOINT NOT FOUND (404)")
|
||||||
|
print(f" The server does NOT have /api/player-edit-media endpoint")
|
||||||
|
print(f" Server may need to implement this feature")
|
||||||
|
elif response.status_code == 401:
|
||||||
|
print(f"\n❌ AUTHENTICATION FAILED (401)")
|
||||||
|
print(f" Check your auth_code in player_auth.json")
|
||||||
|
else:
|
||||||
|
print(f"\n❌ REQUEST FAILED (Status: {response.status_code})")
|
||||||
|
print(f" Response: {response.text}")
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.ConnectionError as e:
|
||||||
|
print(f"\n❌ CONNECTION ERROR")
|
||||||
|
print(f" Cannot reach server at {server_url}")
|
||||||
|
print(f" Error: {e}")
|
||||||
|
return False
|
||||||
|
except requests.exceptions.Timeout as e:
|
||||||
|
print(f"\n❌ TIMEOUT")
|
||||||
|
print(f" Server did not respond within 30 seconds")
|
||||||
|
print(f" Error: {e}")
|
||||||
|
return False
|
||||||
|
except requests.exceptions.SSLError as e:
|
||||||
|
print(f"\n❌ SSL ERROR")
|
||||||
|
print(f" Error: {e}")
|
||||||
|
print(f" Tip: Try adding verify=False to requests")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ UNEXPECTED ERROR")
|
||||||
|
print(f" Error: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
success = test_upload()
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
if success:
|
||||||
|
print("✅ UPLOAD TEST PASSED - Server accepts edited media!")
|
||||||
|
else:
|
||||||
|
print("❌ UPLOAD TEST FAILED - See details above")
|
||||||
|
print(f"{'='*60}\n")
|
||||||
|
|
||||||
|
sys.exit(0 if success else 1)
|
||||||
Reference in New Issue
Block a user