From d85af196b2ca59d985674fe2a7aa4d9f8f03c7e4 Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Sat, 10 May 2025 20:49:01 +0200 Subject: [PATCH] some quality of life improvents --- radioPlayer.py | 23 +- radioPlaylist.py | 638 ++++++++++++++++++++++++----------------------- 2 files changed, 350 insertions(+), 311 deletions(-) diff --git a/radioPlayer.py b/radioPlayer.py index b28de9e..b58b114 100644 --- a/radioPlayer.py +++ b/radioPlayer.py @@ -148,10 +148,25 @@ def play_playlist(playlist_path, play_newest_first=False): subprocess.run(['ffplay', '-nodisp', '-stats', '-hide_banner', '-autoexit', track_path]) def main(): - play_newest_first = len(sys.argv) > 1 and sys.argv[1].lower() == "n" - - if play_newest_first: - print("Newest song will be played first") + arg = sys.argv[1] if len(sys.argv) > 1 else None + play_newest_first = False + pre_track_path = None + + if arg: + if arg.lower() == "n": + play_newest_first = True + print("Newest song will be played first") + elif os.path.isfile(os.path.join(playlist_dir, arg)): + pre_track_path = os.path.join(playlist_dir, arg) + print(f"Will play requested song first: {os.path.basename(pre_track_path)}") + else: + print(f"Invalid argument or file not found: {arg}") + + if pre_track_path: + track_name = os.path.basename(pre_track_path) + print(f"Now playing: {track_name}") + update_rds(track_name) + subprocess.run(['ffplay', '-nodisp', '-stats', '-hide_banner', '-autoexit', pre_track_path]) while True: current_hour = get_current_hour() diff --git a/radioPlaylist.py b/radioPlaylist.py index 24b7859..1103a40 100644 --- a/radioPlaylist.py +++ b/radioPlaylist.py @@ -16,406 +16,430 @@ formats = ('.mp3', '.m4a') p = ("Polskie", "Dzem") def get_audio_files(directory) -> list[str]: - audio_files = [] - try: - for file in os.listdir(directory): - file: str - if file.lower().endswith(formats): - audio_files.append(file) - return sorted(audio_files) - except FileNotFoundError: - print(f"Error: Directory '{directory}' not found.") - return [] - except PermissionError: - print(f"Error: Permission denied for directory '{directory}'.") - return [] + audio_files = [] + try: + for file in os.listdir(directory): + file: str + if file.lower().endswith(formats): + audio_files.append(file) + return sorted(audio_files) + except FileNotFoundError: + print(f"Error: Directory '{directory}' not found.") + return [] + except PermissionError: + print(f"Error: Permission denied for directory '{directory}'.") + return [] def get_char() -> str: - fd = sys.stdin.fileno() - old_settings = termios.tcgetattr(fd) - try: - tty.setraw(sys.stdin.fileno()) - ch = sys.stdin.read(1) - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - return ch + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(sys.stdin.fileno()) + ch = sys.stdin.read(1) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + return ch def clear_screen() -> None: - print("\033c", end="") + print("\033c", end="") def get_terminal_size() -> os.terminal_size: - return shutil.get_terminal_size() + return shutil.get_terminal_size() def get_days_of_week() -> list[str]: - days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] - today = datetime.now().weekday() - return days[today:] + days[:today] + days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] + today = datetime.now().weekday() + return days[today:] + days[:today] def ensure_playlist_dir(day: str) -> str: - playlist_dir = os.path.expanduser(os.path.join(playlists_dir, day)) - if not os.path.exists(playlist_dir): - os.makedirs(playlist_dir) - return playlist_dir + playlist_dir = os.path.expanduser(os.path.join(playlists_dir, day)) + if not os.path.exists(playlist_dir): + os.makedirs(playlist_dir) + return playlist_dir -def calculate_category_percentages(playlists, current_day): - category_counts = {'late_night': 0, 'morning': 0, 'day': 0, 'night': 0} - polskie_counts = {'late_night': 0, 'morning': 0, 'day': 0, 'night': 0} +def calculate_category_percentages(audio_files, playlists, current_day): + category_counts = {'late_night': 0, 'morning': 0, 'day': 0, 'night': 0} + polskie_counts = {'late_night': 0, 'morning': 0, 'day': 0, 'night': 0} - for category in category_counts.keys(): - for file in playlists[current_day][category]: - category_counts[category] += 1 - if any(element in file for element in p): - polskie_counts[category] += 1 + for category in category_counts.keys(): + for file in playlists[current_day][category]: + category_counts[category] += 1 + if any(element in file for element in p): + polskie_counts[category] += 1 - total_count = sum(category_counts.values()) + total_count = sum(category_counts.values()) + + # Calculate unassigned percentage + total_files = len(set().union(*playlists[current_day].values())) + unassigned_count = len(set(audio_files) - set().union(*playlists[current_day].values())) + unassigned_percentage = (unassigned_count / len(audio_files)) * 100 if audio_files else 0 - if total_count == 0: - return None - percentages = { - category: (count / total_count) * 100 for category, count in category_counts.items() - } + if total_count == 0: + return None - polskie_percentages = { - category: (polskie_counts[category] / category_counts[category]) * 100 if category_counts[category] > 0 else 0 - for category in category_counts - } + percentages = { + category: (count / total_count) * 100 for category, count in category_counts.items() + } - return percentages, polskie_percentages, (sum(polskie_counts.values())/sum(category_counts.values()))*100 + polskie_percentages = { + category: (polskie_counts[category] / category_counts[category]) * 100 if category_counts[category] > 0 else 0 + for category in category_counts + } + + return percentages, polskie_percentages, (sum(polskie_counts.values())/sum(category_counts.values()))*100, unassigned_percentage def update_playlist_file(day: str, period: str, filepath: str, add: bool): - playlist_dir = ensure_playlist_dir(day) - playlist_file = os.path.join(playlist_dir, period) + playlist_dir = ensure_playlist_dir(day) + playlist_file = os.path.join(playlist_dir, period) - full_filepath = os.path.join(files_dir, filepath) + full_filepath = os.path.join(files_dir, filepath) - if not os.path.exists(playlist_file): - with open(playlist_file, 'w') as f: - pass + if not os.path.exists(playlist_file): + with open(playlist_file, 'w') as f: + pass - with open(playlist_file, 'r') as f: - lines = f.read().splitlines() + with open(playlist_file, 'r') as f: + lines = f.read().splitlines() - if add and full_filepath not in lines: - lines.append(full_filepath) - elif not add and full_filepath in lines: - lines.remove(full_filepath) + if add and full_filepath not in lines: + lines.append(full_filepath) + elif not add and full_filepath in lines: + lines.remove(full_filepath) - with open(playlist_file, 'w') as f: - f.write('\n'.join(lines) + ('\n' if lines else '')) + with open(playlist_file, 'w') as f: + f.write('\n'.join(lines) + ('\n' if lines else '')) def load_playlists(days: list[str]): - playlists = {} - for day in days: - playlists[day] = {'late_night': set(), 'morning': set(), 'day': set(), 'night': set()} - playlist_dir = os.path.expanduser(os.path.join(playlists_dir, day)) + playlists = {} + for day in days: + playlists[day] = {'late_night': set(), 'morning': set(), 'day': set(), 'night': set()} + playlist_dir = os.path.expanduser(os.path.join(playlists_dir, day)) - if os.path.exists(playlist_dir): - for period in ['late_night', 'morning', 'day', 'night']: - playlist_file = os.path.join(playlist_dir, period) - if os.path.exists(playlist_file): - with open(playlist_file, 'r') as f: - for line in f: - line = line.strip() - if line: - filename = os.path.basename(line) - playlists[day][period].add(filename) + if os.path.exists(playlist_dir): + for period in ['late_night', 'morning', 'day', 'night']: + playlist_file = os.path.join(playlist_dir, period) + if os.path.exists(playlist_file): + with open(playlist_file, 'r') as f: + for line in f: + line = line.strip() + if line: + filename = os.path.basename(line) + playlists[day][period].add(filename) - return playlists + return playlists def copy_day_to_all(playlists: dict, source_day: str, days: list[str]): - periods = ['late_night', 'morning', 'day', 'night'] + periods = ['late_night', 'morning', 'day', 'night'] - for target_day in days: - if target_day == source_day: - continue + for target_day in days: + if target_day == source_day: + continue - for period in periods: - target_dir = ensure_playlist_dir(target_day) - target_file = os.path.join(target_dir, period) + for period in periods: + target_dir = ensure_playlist_dir(target_day) + target_file = os.path.join(target_dir, period) - filepaths = [] - for filename in playlists[source_day][period]: - full_path = os.path.join(files_dir, filename) - filepaths.append(full_path) + filepaths = [] + for filename in playlists[source_day][period]: + full_path = os.path.join(files_dir, filename) + filepaths.append(full_path) - with open(target_file, 'w') as f: - f.write('\n'.join(filepaths) + ('\n' if filepaths else '')) + with open(target_file, 'w') as f: + f.write('\n'.join(filepaths) + ('\n' if filepaths else '')) - playlists[target_day][period] = set(playlists[source_day][period]) + playlists[target_day][period] = set(playlists[source_day][period]) - return playlists + return playlists def copy_current_file_to_all(playlists: dict, source_day: str, days: list[str], current_file: str): - source_periods = { - 'late_night': current_file in playlists[source_day]['late_night'], - 'morning': current_file in playlists[source_day]['morning'], - 'day': current_file in playlists[source_day]['day'], - 'night': current_file in playlists[source_day]['night'], - } + source_periods = { + 'late_night': current_file in playlists[source_day]['late_night'], + 'morning': current_file in playlists[source_day]['morning'], + 'day': current_file in playlists[source_day]['day'], + 'night': current_file in playlists[source_day]['night'], + } - if not any(source_periods.values()): - return playlists, False + if not any(source_periods.values()): + return playlists, False - for target_day in days: - if target_day == source_day: - continue + for target_day in days: + if target_day == source_day: + continue - for period, is_present in source_periods.items(): - target_set = playlists[target_day][period] - full_path = os.path.join(files_dir, current_file) + for period, is_present in source_periods.items(): + target_set = playlists[target_day][period] + full_path = os.path.join(files_dir, current_file) - if is_present: - target_set.add(current_file) - else: - target_set.discard(current_file) + if is_present: + target_set.add(current_file) + else: + target_set.discard(current_file) - playlist_dir = ensure_playlist_dir(target_day) - playlist_file = os.path.join(playlist_dir, period) + playlist_dir = ensure_playlist_dir(target_day) + playlist_file = os.path.join(playlist_dir, period) - if os.path.exists(playlist_file): - with open(playlist_file, 'r') as f: - lines = [line.strip() for line in f.readlines()] - else: - lines = [] + if os.path.exists(playlist_file): + with open(playlist_file, 'r') as f: + lines = [line.strip() for line in f.readlines()] + else: + lines = [] - if is_present and full_path not in lines: - lines.append(full_path) - elif not is_present: - while full_path in lines: - lines.remove(full_path) + if is_present and full_path not in lines: + lines.append(full_path) + elif not is_present: + while full_path in lines: + lines.remove(full_path) - with open(playlist_file, 'w') as f: - f.write('\n'.join(lines) + ('\n' if lines else '')) + with open(playlist_file, 'w') as f: + f.write('\n'.join(lines) + ('\n' if lines else '')) - return playlists, True + return playlists, True def draw_interface(audio_files: list, playlists: dict, selected_idx: int, current_day_idx: int, scroll_offset: int, terminal_size_cache: libcache.Cache, message=None): - clear_screen() - term_width, term_height = terminal_size_cache.getElement("width", False), terminal_size_cache.getElement("height", False) - if term_width is None or term_height is None: - term_width, term_height = get_terminal_size() - terminal_size_cache.saveElement("width", term_width, 5, False, True) - terminal_size_cache.saveElement("height", term_height, 5, False, True) - days = get_days_of_week() - current_day = days[current_day_idx] + clear_screen() + term_width, term_height = terminal_size_cache.getElement("width", False), terminal_size_cache.getElement("height", False) + if term_width is None or term_height is None: + term_width, term_height = get_terminal_size() + terminal_size_cache.saveElement("width", term_width, 5, False, True) + terminal_size_cache.saveElement("height", term_height, 5, False, True) + days = get_days_of_week() + current_day = days[current_day_idx] - percentages, polskie_percentages, total_pl = calculate_category_percentages(playlists, current_day) or ({}, {}, 0) + percentages, polskie_percentages, total_pl, unassigned = calculate_category_percentages(audio_files, playlists, current_day) or ({}, {}, 0, 0) - available_lines = term_height - 6 - start_idx = max(0, min(scroll_offset, len(audio_files) - available_lines)) - end_idx = min(start_idx + available_lines, len(audio_files)) + available_lines = term_height - 6 + start_idx = max(0, min(scroll_offset, len(audio_files) - available_lines)) + end_idx = min(start_idx + available_lines, len(audio_files)) - print("\033[1;37mCategory Distribution:\033[0m".center(term_width)) - category_bar = "" - for category in ['late_night', 'morning', 'day', 'night']: - percent = percentages.get(category, 0) - polskie_percent = polskie_percentages.get(category, 0) - category_bar += f"{category[:4].capitalize()}: {percent:.1f}% (P:{polskie_percent:.1f}%) | " - category_bar += f"TP:{total_pl:0.1f}%" + print("\033[1;37mCategory Distribution:\033[0m".center(term_width)) + category_bar = "" + for category in ['late_night', 'morning', 'day', 'night']: + percent = percentages.get(category, 0) + polskie_percent = polskie_percentages.get(category, 0) + category_bar += f"{category[:4].capitalize()}: {percent:.1f}% (P:{polskie_percent:.1f}%) | " + category_bar += f"TP:{total_pl:0.1f}% | " + category_bar += f"UA:{unassigned:0.1}%" - if len(category_bar) > term_width - 2: - category_bar = category_bar[:term_width - 5] + "..." - print(category_bar.center(term_width)) + if len(category_bar) > term_width - 2: + category_bar = category_bar[:term_width - 5] + "..." + print(category_bar.center(term_width)) - day_bar = "" - for i, day in enumerate(days): - if i == current_day_idx: - day_bar += f"\033[1;44m[{day}]\033[0m " - else: - day_bar += f"[{day}] " - print(day_bar.strip()) + day_bar = "" + for i, day in enumerate(days): + if i == current_day_idx: + day_bar += f"\033[1;44m[{day}]\033[0m " + else: + day_bar += f"[{day}] " + print(day_bar.strip()) - print("UP/DOWN: Navigate | D/N/L: Toggle | C: Copy day to all | F: Copy file to all | Q: Quit") + print("UP/DOWN: Navigate | D/N/L: Toggle | C: Copy day to all | F: Copy file to all | Q: Quit") - if start_idx > 0: - print("↑", end="") - else: - print(" ", end="") + if start_idx > 0: + print("↑", end="") + else: + print(" ", end="") - position_info = f" {current_day.capitalize()} | File {selected_idx + 1}/{len(audio_files)} " - padding = term_width - len(position_info) - 2 - print(position_info.center(padding), end="") + position_info = f" {current_day.capitalize()} | File {selected_idx + 1}/{len(audio_files)} " + padding = term_width - len(position_info) - 2 + print(position_info.center(padding), end="") - if end_idx < len(audio_files): - print("↓") - else: - print(" ") + if end_idx < len(audio_files): + print("↓") + else: + print(" ") - if message: - print(f"\033[1;32m{message}\033[0m") - else: - print() + if message: + print(f"\033[1;32m{message}\033[0m") + else: + print() - for idx in range(start_idx, end_idx): - file = audio_files[idx] + for idx in range(start_idx, end_idx): + file = audio_files[idx] - in_late_night = file in playlists[current_day]['late_night'] - in_morning = file in playlists[current_day]['morning'] - in_day = file in playlists[current_day]['day'] - in_night = file in playlists[current_day]['night'] + in_late_night = file in playlists[current_day]['late_night'] + in_morning = file in playlists[current_day]['morning'] + in_day = file in playlists[current_day]['day'] + in_night = file in playlists[current_day]['night'] - l_color = "\033[1;32m" if in_late_night else "\033[1;30m" - m_color = "\033[1;32m" if in_morning else "\033[1;30m" - d_color = "\033[1;32m" if in_day else "\033[1;30m" - n_color = "\033[1;32m" if in_night else "\033[1;30m" + l_color = "\033[1;32m" if in_late_night else "\033[1;30m" + m_color = "\033[1;32m" if in_morning else "\033[1;30m" + d_color = "\033[1;32m" if in_day else "\033[1;30m" + n_color = "\033[1;32m" if in_night else "\033[1;30m" - if idx == selected_idx: - row_highlight = "\033[1;44m" - else: - row_highlight = "" + if idx == selected_idx: + row_highlight = "\033[1;44m" + else: + row_highlight = "" - max_filename_length = term_width - 15 - if len(file) > max_filename_length: - file = file[:max_filename_length-3] + "..." + max_filename_length = term_width - 15 + if len(file) > max_filename_length: + file = file[:max_filename_length-3] + "..." - print(f"{row_highlight}[{l_color}L\033[0m{row_highlight}] [{m_color}M\033[0m{row_highlight}] [{d_color}D\033[0m{row_highlight}] [{n_color}N\033[0m{row_highlight}] {file}\033[0m") + print(f"{row_highlight}[{l_color}L\033[0m{row_highlight}] [{m_color}M\033[0m{row_highlight}] [{d_color}D\033[0m{row_highlight}] [{n_color}N\033[0m{row_highlight}] {file}\033[0m") def main(): - audio_files = get_audio_files(files_dir) + audio_files = get_audio_files(files_dir) - if not audio_files: - print("No audio files found. Exiting.") - return + if not audio_files: + print("No audio files found. Exiting.") + return 1 - days_of_week = get_days_of_week() - playlists = load_playlists(days_of_week) + days_of_week = get_days_of_week() + playlists = load_playlists(days_of_week) - selected_idx = 0 - current_day_idx = 0 - scroll_offset = 0 - flash_message = None - message_timer = 0 + selected_idx = 0 + current_day_idx = 0 + scroll_offset = 0 + flash_message = None + message_timer = 0 - def signal_handler(sig, frame): - clear_screen() - sys.exit(0) + def signal_handler(sig, frame): + clear_screen() + sys.exit(0) - signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGINT, signal_handler) - terminal_size_cache = libcache.Cache() + terminal_size_cache = libcache.Cache() - while True: - term_width, term_height = terminal_size_cache.getElement("width", False), terminal_size_cache.getElement("height", False) - if term_width is None or term_height is None: - term_width, term_height = get_terminal_size() - terminal_size_cache.saveElement("width", term_width, 5, False, True) - terminal_size_cache.saveElement("height", term_height, 5, False, True) - visible_lines = term_height - 6 + while True: + term_width, term_height = terminal_size_cache.getElement("width", False), terminal_size_cache.getElement("height", False) + if term_width is None or term_height is None: + term_width, term_height = get_terminal_size() + terminal_size_cache.saveElement("width", term_width, 5, False, True) + terminal_size_cache.saveElement("height", term_height, 5, False, True) + visible_lines = term_height - 6 - if selected_idx < scroll_offset: - scroll_offset = selected_idx - elif selected_idx >= scroll_offset + visible_lines: - scroll_offset = selected_idx - visible_lines + 1 + if selected_idx < scroll_offset: + scroll_offset = selected_idx + elif selected_idx >= scroll_offset + visible_lines: + scroll_offset = selected_idx - visible_lines + 1 - draw_interface(audio_files, playlists, selected_idx, current_day_idx, scroll_offset, terminal_size_cache, flash_message) + draw_interface(audio_files, playlists, selected_idx, current_day_idx, scroll_offset, terminal_size_cache, flash_message) - if flash_message: - message_timer += 1 - if message_timer > 1: - flash_message = None - message_timer = 0 + if flash_message: + message_timer += 1 + if message_timer > 1: + flash_message = None + message_timer = 0 - key = get_char() + key = get_char() - if key == 'q': - clear_screen() - break - elif key == '\x1b': - next_key = get_char() - if next_key == '[': - arrow_key = get_char() - if arrow_key == 'A': - selected_idx = max(0, selected_idx - 1) - elif arrow_key == 'B': - selected_idx = min(len(audio_files) - 1, selected_idx + 1) - elif arrow_key == 'C': - current_day_idx = (current_day_idx + 1) % len(days_of_week) - elif arrow_key == 'D': - current_day_idx = (current_day_idx - 1) % len(days_of_week) - elif arrow_key == '5': - try: - next_key = get_char() - except: - pass - selected_idx = max(0, selected_idx - visible_lines) - elif arrow_key == '6': - try: - next_key = get_char() - except: - pass - selected_idx = min(len(audio_files) - 1, selected_idx + visible_lines) - elif key == ' ': - selected_idx = min(len(audio_files) - 1, selected_idx + visible_lines) - elif key.lower() == 'm': - current_day = days_of_week[current_day_idx] - file = audio_files[selected_idx] - is_in_playlist = file in playlists[current_day]['morning'] + if key == 'q': + clear_screen() + break + elif key == '\x1b': + next_key = get_char() + if next_key == '[': + arrow_key = get_char() + if arrow_key == 'A': + selected_idx = max(0, selected_idx - 1) + elif arrow_key == 'B': + selected_idx = min(len(audio_files) - 1, selected_idx + 1) + elif arrow_key == 'C': + current_day_idx = (current_day_idx + 1) % len(days_of_week) + elif arrow_key == 'D': + current_day_idx = (current_day_idx - 1) % len(days_of_week) + elif arrow_key == '5': + try: + next_key = get_char() + except: + pass + selected_idx = max(0, selected_idx - visible_lines) + elif arrow_key == '6': + try: + next_key = get_char() + except: + pass + selected_idx = min(len(audio_files) - 1, selected_idx + visible_lines) + elif arrow_key == '1': + if get_char() == '~': + selected_idx = 0 + elif arrow_key == '4': + if get_char() == '~': + selected_idx = len(audio_files) - 1 + elif key == ' ': + selected_idx = min(len(audio_files) - 1, selected_idx + visible_lines) + elif key.lower() == 'm': + current_day = days_of_week[current_day_idx] + file = audio_files[selected_idx] + is_in_playlist = file in playlists[current_day]['morning'] - if is_in_playlist: - playlists[current_day]['morning'].remove(file) - else: - playlists[current_day]['morning'].add(file) + if is_in_playlist: + playlists[current_day]['morning'].remove(file) + else: + playlists[current_day]['morning'].add(file) - update_playlist_file(current_day, 'morning', file, not is_in_playlist) - elif key.lower() == 'd': - current_day = days_of_week[current_day_idx] - file = audio_files[selected_idx] - is_in_playlist = file in playlists[current_day]['day'] + update_playlist_file(current_day, 'morning', file, not is_in_playlist) + elif key.lower() == 'd': + current_day = days_of_week[current_day_idx] + file = audio_files[selected_idx] + is_in_playlist = file in playlists[current_day]['day'] - if is_in_playlist: - playlists[current_day]['day'].remove(file) - else: - playlists[current_day]['day'].add(file) + if is_in_playlist: + playlists[current_day]['day'].remove(file) + else: + playlists[current_day]['day'].add(file) - update_playlist_file(current_day, 'day', file, not is_in_playlist) + update_playlist_file(current_day, 'day', file, not is_in_playlist) - elif key.lower() == 'n': - current_day = days_of_week[current_day_idx] - file = audio_files[selected_idx] - is_in_playlist = file in playlists[current_day]['night'] + elif key.lower() == 'n': + current_day = days_of_week[current_day_idx] + file = audio_files[selected_idx] + is_in_playlist = file in playlists[current_day]['night'] - if is_in_playlist: - playlists[current_day]['night'].remove(file) - else: - playlists[current_day]['night'].add(file) + if is_in_playlist: + playlists[current_day]['night'].remove(file) + else: + playlists[current_day]['night'].add(file) - update_playlist_file(current_day, 'night', file, not is_in_playlist) + update_playlist_file(current_day, 'night', file, not is_in_playlist) - elif key.lower() == 'l': - current_day = days_of_week[current_day_idx] - file = audio_files[selected_idx] - is_in_playlist = file in playlists[current_day]['late_night'] + elif key.lower() == 'l': + current_day = days_of_week[current_day_idx] + file = audio_files[selected_idx] + is_in_playlist = file in playlists[current_day]['late_night'] - if is_in_playlist: - playlists[current_day]['late_night'].remove(file) - else: - playlists[current_day]['late_night'].add(file) + if is_in_playlist: + playlists[current_day]['late_night'].remove(file) + else: + playlists[current_day]['late_night'].add(file) - update_playlist_file(current_day, 'late_night', file, not is_in_playlist) + update_playlist_file(current_day, 'late_night', file, not is_in_playlist) - elif key.lower() == 'c': - current_day = days_of_week[current_day_idx] - playlists = copy_day_to_all(playlists, current_day, days_of_week) - flash_message = f"Playlists from {current_day} copied to all other days!" - message_timer = 0 + elif key.lower() == 'c': + current_day = days_of_week[current_day_idx] + playlists = copy_day_to_all(playlists, current_day, days_of_week) + flash_message = f"Playlists from {current_day} copied to all other days!" + message_timer = 0 - elif key.lower() == 'f': - current_day = days_of_week[current_day_idx] - current_file = audio_files[selected_idx] + elif key.lower() == 'f': + current_day = days_of_week[current_day_idx] + current_file = audio_files[selected_idx] - playlists, success = copy_current_file_to_all(playlists, current_day, days_of_week, current_file) + playlists, success = copy_current_file_to_all(playlists, current_day, days_of_week, current_file) - if success: - flash_message = f"File '{current_file}' copied to all days!" - else: - flash_message = f"File not in any playlist! Add it first." - message_timer = 0 + if success: + flash_message = f"File '{current_file}' copied to all days!" + else: + flash_message = f"File not in any playlist! Add it first." + message_timer = 0 - elif key == 'g': - selected_idx = 0 - elif key == 'G': - selected_idx = len(audio_files) - 1 + elif key.isupper() and len(key) == 1 and key.isalpha(): + target_letter = key.lower() + found_idx = -1 + for i in range(selected_idx + 1, len(audio_files)): + if audio_files[i].lower().startswith(target_letter): + found_idx = i + break + if found_idx == -1: + for i in range(0, selected_idx): + if audio_files[i].lower().startswith(target_letter): + found_idx = i + break + if found_idx != -1: + selected_idx = found_idx + return 0 if __name__ == "__main__": - main() + exit(main())