finish
This commit is contained in:
@@ -1 +0,0 @@
|
||||
{"settings": {"quick_connect_code": "", "server_ip": ""}}
|
||||
91
src/Resurse/log.txt
Normal file
91
src/Resurse/log.txt
Normal file
@@ -0,0 +1,91 @@
|
||||
2025-03-27 08:17:12 - STARTED: car_modular.jpg
|
||||
2025-03-27 08:17:27 - STOPPED: car_modular.jpg
|
||||
2025-03-27 08:17:27 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:17:27 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:17:27 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 08:17:47 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 08:17:47 - STARTED: car_modular.jpg
|
||||
2025-03-27 08:18:07 - STOPPED: car_modular.jpg
|
||||
2025-03-27 08:18:07 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:20:58 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:20:58 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 08:21:18 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 08:21:18 - STARTED: car_modular.jpg
|
||||
2025-03-27 08:21:38 - STOPPED: car_modular.jpg
|
||||
2025-03-27 08:21:38 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:22:09 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:24:29 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:24:29 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 08:24:49 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 08:24:49 - STARTED: car_modular.jpg
|
||||
2025-03-27 08:24:58 - STOPPED: car_modular.jpg
|
||||
2025-03-27 08:24:58 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:25:09 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 08:25:09 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:18:55 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:19:11 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:19:11 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:19:12 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:19:12 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:19:31 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:19:31 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:19:51 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:19:51 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:22:42 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:22:42 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:23:02 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:23:02 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:23:22 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:23:22 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:26:13 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:26:13 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:26:33 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:26:33 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:26:53 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:26:53 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:29:44 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:29:44 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:30:04 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:30:04 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:30:24 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:30:24 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:33:15 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:33:15 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:33:35 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:33:35 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:33:55 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:33:55 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:36:46 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:36:46 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:37:06 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:37:06 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:37:26 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:37:26 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:40:17 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:40:17 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:40:37 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:40:37 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:40:57 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:40:57 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:43:48 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:43:48 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:44:08 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:44:08 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:44:28 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:44:28 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:47:18 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:47:18 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:47:38 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:47:38 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:47:58 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:47:58 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:50:49 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:50:49 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:51:09 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:51:09 - STARTED: car_modular.jpg
|
||||
2025-03-27 09:51:29 - STOPPED: car_modular.jpg
|
||||
2025-03-27 09:51:29 - STARTED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:54:20 - STOPPED: SampleVideo_1280x720_30mb.mp4
|
||||
2025-03-27 09:54:20 - STARTED: harting_contactor.jpg
|
||||
2025-03-27 09:54:40 - STOPPED: harting_contactor.jpg
|
||||
2025-03-27 09:54:40 - STARTED: car_modular.jpg
|
||||
Binary file not shown.
@@ -11,6 +11,7 @@ from kivy.logger import Logger # Import Logger for logging messages
|
||||
from kivy.lang import Builder # Import Builder for loading KV files
|
||||
import os # Import os for file and directory operations
|
||||
import json # Import json for handling JSON data
|
||||
import datetime # Import datetime for timestamping logs
|
||||
|
||||
# Import functions from python_functions.py
|
||||
from python_functions import load_playlist, download_media_files, clean_unused_files
|
||||
@@ -30,6 +31,8 @@ class MediaPlayer(Screen):
|
||||
self.current_index = 0 # Index of the currently playing media
|
||||
self.video_player = self.ids.video_player # Reference to the Video widget
|
||||
self.image_display = self.ids.image_display # Reference to the Image widget
|
||||
self.log_file = os.path.join(os.path.dirname(__file__), 'Resurse', 'log.txt') # Path to the log file
|
||||
|
||||
# Schedule periodic updates to check for playlist updates
|
||||
Clock.schedule_interval(self.check_playlist_updates, 300) # Every 5 minutes
|
||||
# Bind key events to handle fullscreen toggle
|
||||
@@ -62,6 +65,14 @@ class MediaPlayer(Screen):
|
||||
clean_unused_files(self.playlist) # Remove unused files from the resource folder
|
||||
self.play_media() # Start playing media
|
||||
|
||||
def log_event(self, file_name, event):
|
||||
"""Log the start or stop event of a media file."""
|
||||
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # Get the current timestamp
|
||||
log_message = f"{timestamp} - {event}: {file_name}\n" # Format the log message
|
||||
with open(self.log_file, 'a') as log: # Open the log file in append mode
|
||||
log.write(log_message) # Write the log message
|
||||
Logger.info(f"Logged event: {log_message.strip()}") # Log the event to the console
|
||||
|
||||
def play_media(self):
|
||||
"""Play the current media in the playlist."""
|
||||
if self.playlist:
|
||||
@@ -76,6 +87,9 @@ class MediaPlayer(Screen):
|
||||
|
||||
Logger.info(f"Playing media: {file_path}")
|
||||
|
||||
# Log the start of the media
|
||||
self.log_event(file_name, "STARTED")
|
||||
|
||||
# Determine the type of media and play it
|
||||
if file_extension in ['.mp4', '.avi', '.mov']:
|
||||
self.play_video(file_path) # Play video
|
||||
@@ -104,15 +118,25 @@ class MediaPlayer(Screen):
|
||||
|
||||
def next_media(self, dt):
|
||||
"""Move to the next media in the playlist."""
|
||||
# Log the stop of the current media
|
||||
current_media = self.playlist[self.current_index].get('file_name', '')
|
||||
self.log_event(current_media, "STOPPED")
|
||||
|
||||
# Move to the next media
|
||||
self.current_index = (self.current_index + 1) % len(self.playlist) # Increment the index
|
||||
self.play_media() # Play the next media
|
||||
|
||||
def check_playlist_updates(self, dt):
|
||||
"""Check for updates to the playlist."""
|
||||
self.playlist = load_playlist() # Reload the playlist
|
||||
new_playlist = load_playlist() # Load the new playlist
|
||||
if new_playlist != self.playlist: # Compare the new playlist with the current one
|
||||
Logger.info("Playlist updated. Changes detected.")
|
||||
self.playlist = new_playlist # Update the playlist
|
||||
download_media_files(self.playlist) # Download new media files
|
||||
clean_unused_files(self.playlist) # Remove unused files
|
||||
self.play_media() # Restart media playback
|
||||
else:
|
||||
Logger.info("Playlist update skipped. No changes detected.")
|
||||
|
||||
class SettingsScreen(Screen):
|
||||
"""Settings screen for configuring the app."""
|
||||
|
||||
@@ -9,9 +9,10 @@ def load_config():
|
||||
"""Load configuration from app_config.txt."""
|
||||
if os.path.exists(CONFIG_FILE):
|
||||
with open(CONFIG_FILE, 'r') as file:
|
||||
Logger.info("python_functions: Configuration file loaded successfully.")
|
||||
return json.load(file)
|
||||
else:
|
||||
Logger.error(f"Configuration file {CONFIG_FILE} not found.")
|
||||
Logger.error(f"python_functions: Configuration file {CONFIG_FILE} not found.")
|
||||
return {
|
||||
"screen_orientation": "Landscape",
|
||||
"screen_name": "",
|
||||
@@ -32,46 +33,48 @@ if server and host and quick and port:
|
||||
else:
|
||||
config_status = "not_ok"
|
||||
|
||||
Logger.info(f"Configuration loaded: server={server}, host={host}, quick={quick}, port={port}")
|
||||
Logger.info(f"Configuration status: {config_status}")
|
||||
Logger.info(f"python_functions: Configuration loaded: server={server}, host={host}, quick={quick}, port={port}")
|
||||
Logger.info(f"python_functions: Configuration status: {config_status}")
|
||||
|
||||
def load_playlist():
|
||||
# Load playlist from the server or local storage
|
||||
"""Load playlist from the server or local storage."""
|
||||
try:
|
||||
Logger.debug("Attempting to load playlist from server...")
|
||||
server_ip = f'http://{server}:{port}'
|
||||
hostname = host
|
||||
quickconnect_code = quick
|
||||
url = f'{server_ip}/api/playlists'
|
||||
Logger.info("python_functions: Attempting to load playlist from server...")
|
||||
server_ip = f'{server}:{port}' # Construct the server IP with port
|
||||
url = f'http://{server_ip}/api/playlists'
|
||||
params = {
|
||||
'hostname': hostname,
|
||||
'quickconnect_code': quickconnect_code
|
||||
'hostname': host,
|
||||
'quickconnect_code': quick
|
||||
}
|
||||
response = requests.get(url, params=params)
|
||||
|
||||
# Print the raw response content and status code for debugging
|
||||
Logger.debug(f'Status Code: {response.status_code}')
|
||||
Logger.debug(f'Response Content: {response.text}')
|
||||
Logger.debug(f"python_functions: Status Code: {response.status_code}")
|
||||
Logger.debug(f"python_functions: Response Content: {response.text}")
|
||||
|
||||
# Check if the request was successful
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
# Parse the JSON response
|
||||
playlist = response.json().get('playlist', [])
|
||||
Logger.debug(f'Playlist: {playlist}')
|
||||
Logger.info("python_functions: Playlist loaded successfully.")
|
||||
Logger.debug(f"python_functions: Loaded playlist: {playlist}")
|
||||
return playlist
|
||||
except json.JSONDecodeError as e:
|
||||
Logger.error(f'Failed to parse JSON response: {e}')
|
||||
Logger.error(f"python_functions: Failed to parse JSON response: {e}")
|
||||
else:
|
||||
Logger.error(f'Failed to retrieve playlist: {response.text}')
|
||||
Logger.error(f"python_functions: Failed to retrieve playlist: {response.text}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
Logger.error(f"Failed to load playlist: {e}")
|
||||
Logger.error(f"python_functions: Failed to load playlist: {e}")
|
||||
return []
|
||||
|
||||
def download_media_files(playlist):
|
||||
"""Download media files from the playlist."""
|
||||
Logger.info("python_functions: Starting media file download...")
|
||||
base_dir = os.path.join(os.path.dirname(__file__), 'static', 'resurse') # Update this to the correct path
|
||||
if not os.path.exists(base_dir):
|
||||
os.makedirs(base_dir)
|
||||
Logger.info(f"python_functions: Created directory {base_dir} for media files.")
|
||||
|
||||
for media in playlist:
|
||||
file_name = media.get('file_name', '')
|
||||
@@ -83,16 +86,18 @@ def download_media_files(playlist):
|
||||
if response.status_code == 200:
|
||||
with open(file_path, 'wb') as file:
|
||||
file.write(response.content)
|
||||
Logger.debug(f"Downloaded {file_name} to {file_path}")
|
||||
Logger.info(f"python_functions: Downloaded {file_name} to {file_path}")
|
||||
else:
|
||||
Logger.error(f"Failed to download {file_name}: {response.status_code}")
|
||||
Logger.error(f"python_functions: Failed to download {file_name}: {response.status_code}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
Logger.error(f"Failed to download {file_name}: {e}")
|
||||
Logger.error(f"python_functions: Failed to download {file_name}: {e}")
|
||||
|
||||
def clean_unused_files(playlist):
|
||||
"""Remove unused media files from the resource folder."""
|
||||
Logger.info("python_functions: Cleaning unused media files...")
|
||||
base_dir = os.path.join(os.path.dirname(__file__), 'static', 'resurse') # Update this to the correct path
|
||||
if not os.path.exists(base_dir):
|
||||
Logger.debug(f"Directory {base_dir} does not exist. No files to clean.")
|
||||
Logger.debug(f"python_functions: Directory {base_dir} does not exist. No files to clean.")
|
||||
return
|
||||
|
||||
# Get all file names from the playlist
|
||||
@@ -109,6 +114,6 @@ def clean_unused_files(playlist):
|
||||
file_path = os.path.join(base_dir, file_name)
|
||||
try:
|
||||
os.remove(file_path)
|
||||
Logger.debug(f"Deleted unused file: {file_path}")
|
||||
Logger.info(f"python_functions: Deleted unused file: {file_path}")
|
||||
except OSError as e:
|
||||
Logger.error(f"Failed to delete {file_path}: {e}")
|
||||
Logger.error(f"python_functions: Failed to delete {file_path}: {e}")
|
||||
@@ -1 +0,0 @@
|
||||
{"settings": {"quick_connect_code": "", "server_ip": ""}}
|
||||
Reference in New Issue
Block a user