diff --git a/settings.json b/settings.json deleted file mode 100644 index 585d118..0000000 --- a/settings.json +++ /dev/null @@ -1 +0,0 @@ -{"settings": {"quick_connect_code": "", "server_ip": ""}} \ No newline at end of file diff --git a/src/Resurse/log.txt b/src/Resurse/log.txt new file mode 100644 index 0000000..08d14f2 --- /dev/null +++ b/src/Resurse/log.txt @@ -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 diff --git a/src/__pycache__/python_functions.cpython-311.pyc b/src/__pycache__/python_functions.cpython-311.pyc index a558a83..682a8bd 100644 Binary files a/src/__pycache__/python_functions.cpython-311.pyc and b/src/__pycache__/python_functions.cpython-311.pyc differ diff --git a/src/media_player.py b/src/media_player.py index 4869c22..1b515c8 100644 --- a/src/media_player.py +++ b/src/media_player.py @@ -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 - download_media_files(self.playlist) # Download new media files - clean_unused_files(self.playlist) # Remove unused files - self.play_media() # Restart media playback + 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.""" diff --git a/src/python_functions.py b/src/python_functions.py index 0a30d05..9ffeb7b 100644 --- a/src/python_functions.py +++ b/src/python_functions.py @@ -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}") \ No newline at end of file + Logger.error(f"python_functions: Failed to delete {file_path}: {e}") \ No newline at end of file diff --git a/src/settings.json b/src/settings.json deleted file mode 100644 index 585d118..0000000 --- a/src/settings.json +++ /dev/null @@ -1 +0,0 @@ -{"settings": {"quick_connect_code": "", "server_ip": ""}} \ No newline at end of file