From 698517037880987b42833d9d4087db2104dc0fd9 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Fri, 8 Dec 2023 17:26:04 +0000 Subject: [PATCH] Audacity class --- app/helpers.py | 99 ++++++++++++++++++++++-------------------------- app/playlists.py | 22 ++++++++++- 2 files changed, 66 insertions(+), 55 deletions(-) diff --git a/app/helpers.py b/app/helpers.py index 32e2df5..6ab7b5b 100644 --- a/app/helpers.py +++ b/app/helpers.py @@ -3,7 +3,6 @@ from email.message import EmailMessage from typing import Any, Dict, Optional import functools import os -import psutil import re import shutil import smtplib @@ -22,8 +21,52 @@ from log import log start_time_re = re.compile(r"@\d\d:\d\d") -# Classes are defined after global functions so that classes can use -# those functions. + +class AudacityManager: + """ + Manage comms with Audacity + """ + + def __init__(self, path: str) -> None: + """ + Open passed file in Audacity + + Return True if apparently opened successfully, else False + """ + + self.to_pipe: str = "/tmp/audacity_script_pipe.to." + str(os.getuid()) + self.from_pipe: str = "/tmp/audacity_script_pipe.from." + str(os.getuid()) + self.eol: str = "\n" + self.path = path + self.do_command(f'Import2: Filename="{self.path}"') + + def send_command(self, command: str) -> None: + """Send a single command.""" + self.to_audacity.write(command + self.eol) + self.to_audacity.flush() + + def get_response(self) -> str: + """Return the command response.""" + + result: str = "" + line: str = "" + + while True: + result += line + line = self.from_audacity.readline() + if line == "\n" and len(result) > 0: + break + return result + + def do_command(self, command: str) -> str: + """Send one command, and return the response.""" + + with open(self.to_pipe, "w") as self.to_audacity, open( + self.from_pipe, "rt" + ) as self.from_audacity: + self.send_command(command) + response = self.get_response() + return response def ask_yes_no(title: str, question: str, default_yes: bool = False) -> bool: @@ -314,56 +357,6 @@ def normalise_track(path): os.remove(temp_path) -def open_in_audacity(path: str) -> bool: - """ - Open passed file in Audacity - - Return True if apparently opened successfully, else False - """ - - # Return if audacity not running - if "audacity" not in [i.name() for i in psutil.process_iter()]: - return False - - # Return if path not given - if not path: - return False - - to_pipe: str = "/tmp/audacity_script_pipe.to." + str(os.getuid()) - from_pipe: str = "/tmp/audacity_script_pipe.from." + str(os.getuid()) - eol: str = "\n" - - def send_command(command: str) -> None: - """Send a single command.""" - to_audacity.write(command + eol) - to_audacity.flush() - - def get_response() -> str: - """Return the command response.""" - - result: str = "" - line: str = "" - - while True: - result += line - line = from_audacity.readline() - if line == "\n" and len(result) > 0: - break - return result - - def do_command(command: str) -> str: - """Send one command, and return the response.""" - - send_command(command) - response = get_response() - return response - - with open(to_pipe, "w") as to_audacity, open(from_pipe, "rt") as from_audacity: - do_command(f'Import2: Filename="{path}"') - - return True - - def send_mail(to_addr, from_addr, subj, body): # From https://docs.python.org/3/library/email.examples.html diff --git a/app/playlists.py b/app/playlists.py index 3e70c8b..567b384 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -1,5 +1,6 @@ +import psutil from pprint import pprint -from typing import Callable, cast, List, Optional, overload, TYPE_CHECKING +from typing import Callable, cast, List, Optional, TYPE_CHECKING from PyQt6.QtCore import ( QEvent, @@ -34,6 +35,7 @@ from config import Config from helpers import ( ask_yes_no, ms_to_mmss, + open_file_in_audacity, show_OK, show_warning, ) @@ -351,7 +353,7 @@ class PlaylistTab(QTableView): # Open in Audacity if track_row and not current_row: self._add_context_menu( - "Open in Audacity", lambda: model.open_in_audacity(model_row_number) + "Open in Audacity", lambda: self.open_in_audacity(model_row_number) ) # Rescan @@ -553,6 +555,22 @@ class PlaylistTab(QTableView): self.data_model.mark_unplayed(row_numbers) self.clear_selection() + def open_in_audacity(self, row_number: int) -> None: + """ + Open track in passed row in Audacity + """ + + # Notify user if audacity not running + if "audacity" not in [i.name() for i in psutil.process_iter()]: + show_warning(self.musicmuster, "Audacity", "Audacity is not running") + return + + path = self.data_model.get_row_track_path(row_number) + if not path: + return + + open_file_in_audacity(path) + def _rescan(self, row_number: int) -> None: """Rescan track"""