From 77ef9ef75ecd96efe888fcf1499e761f48aea330 Mon Sep 17 00:00:00 2001 From: Robert Honz Date: Fri, 29 Mar 2024 10:54:04 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Can=20explicitly=20set=20`ffmpeg`?= =?UTF-8?q?=20path.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tidal_dl_ng/dialog.py | 49 ++++++++++++---------------- tidal_dl_ng/model/cfg.py | 4 ++- tidal_dl_ng/ui/dialog_settings.py | 38 ++++++++++++++++++++++ tidal_dl_ng/ui/dialog_settings.ui | 54 +++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 29 deletions(-) diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index 8d48037..c8abdc8 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -9,7 +9,6 @@ from tidalapi import Quality as QualityAudio from tidal_dl_ng import __version__ from tidal_dl_ng.config import Settings from tidal_dl_ng.constants import CoverDimensions, QualityVideo, SkipExisting -from tidal_dl_ng.helper.path import is_installed_ffmpeg from tidal_dl_ng.model.cfg import HelpSettings from tidal_dl_ng.model.cfg import Settings as ModelSettings from tidal_dl_ng.model.meta import ReleaseLatest @@ -132,26 +131,9 @@ class DialogPreferences(QtWidgets.QDialog): self.ui.setupUi(self) # Set data. self.gui_populate() - self._init_signals() self.exec() - def _init_signals(self): - self.ui.cb_video_convert_mp4.stateChanged.connect(self.on_cb_video_convert_mp4) - - def on_cb_video_convert_mp4(self, change_status: int): - # Check if ffmpeg is in PATH otherwise show error message. - if self.ui.cb_video_convert_mp4.isChecked() and not is_installed_ffmpeg(): - self.ui.cb_video_convert_mp4.setChecked(False) - self.ui.cb_video_convert_mp4.setCheckState(QtCore.Qt.CheckState.Unchecked) - QtWidgets.QMessageBox.critical( - self, - "FFmpeg not found!", - "Either FFmpeg is not installed on your computer or not set within " - "your PATH variable. You cannot activate this option until FFmpeg " - "is correctly installed and set to your environmental PATH variable.", - ) - def _init_line_edit(self): self.parameters_line_edit = [ "download_base_path", @@ -160,6 +142,7 @@ class DialogPreferences(QtWidgets.QDialog): "format_mix", "format_track", "format_video", + "path_binary_ffmpeg", ] def _init_comboboxes(self): @@ -184,30 +167,36 @@ class DialogPreferences(QtWidgets.QDialog): self.populate_combo() self.populate_line_edit() - def dialog_dir_open(self, obj_line_edit): + def dialog_chose_file( + self, + obj_line_edit: QtWidgets.QLineEdit, + file_mode: QtWidgets.QFileDialog | QtWidgets.QFileDialog.FileMode = QtWidgets.QFileDialog.Directory, + ): # If a path is set, use it otherwise the users home directory. settings_path: str = os.path.expanduser(obj_line_edit.text()) if obj_line_edit.text() else "" - dir_current = settings_path if settings_path and os.path.exists(settings_path) else str(Path.home()) - dialog = QtWidgets.QFileDialog() + dir_current: str = settings_path if settings_path and os.path.exists(settings_path) else str(Path.home()) + dialog: QtWidgets.QFileDialog = QtWidgets.QFileDialog() # Set to directory mode only but show files. - dialog.setFileMode(QtWidgets.QFileDialog.Directory) + dialog.setFileMode(file_mode) dialog.setViewMode(QtWidgets.QFileDialog.Detail) dialog.setOption(QtWidgets.QFileDialog.ShowDirsOnly, False) + dialog.setOption(QtWidgets.QFileDialog.DontResolveSymlinks, True) + # There is a bug in the PyQt implementation, which hides files in Directory mode. # Thus, we need to use the PyQt dialog instead of the native dialog. - if os.name == "nt": + if os.name == "nt" and file_mode == QtWidgets.QFileDialog.Directory: dialog.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, True) + dialog.setDirectory(dir_current) # Execute dialog and set path is something is choosen. if dialog.exec(): - dir_name = dialog.selectedFiles()[0] - path = Path(dir_name) + dir_name: str = dialog.selectedFiles()[0] + path: Path = Path(dir_name) obj_line_edit.setText(str(path)) def populate_line_edit(self): - for pn in self.parameters_line_edit: label_icon: QtWidgets.QLabel = getattr(self.ui, self.prefix_label + self.prefix_icon + pn) label: QtWidgets.QLabel = getattr(self.ui, self.prefix_label + pn) @@ -219,10 +208,14 @@ class DialogPreferences(QtWidgets.QDialog): line_edit.setText(getattr(self.data, pn)) # Base Path File Dialog - self.ui.pb_download_base_path.clicked.connect(lambda x: self.dialog_dir_open(self.ui.le_download_base_path)) + self.ui.pb_download_base_path.clicked.connect(lambda x: self.dialog_chose_file(self.ui.le_download_base_path)) + self.ui.pb_path_binary_ffmpeg.clicked.connect( + lambda x: self.dialog_chose_file( + self.ui.le_path_binary_ffmpeg, file_mode=QtWidgets.QFileDialog.FileMode.ExistingFiles + ) + ) def populate_combo(self): - for p in self.parameters_combo: pn: str = p[0] values: Enum = p[1] diff --git a/tidal_dl_ng/model/cfg.py b/tidal_dl_ng/model/cfg.py index 98b5470..a99e335 100644 --- a/tidal_dl_ng/model/cfg.py +++ b/tidal_dl_ng/model/cfg.py @@ -31,6 +31,7 @@ class Settings: format_track: str = "Tracks/{artist_name} - {track_title}" format_video: str = "Videos/{artist_name} - {track_title}" video_convert_mp4: bool = True + path_binary_ffmpeg: str = "" metadata_cover_dimension: CoverDimensions = CoverDimensions.Px320 @@ -65,8 +66,9 @@ class HelpSettings: format_video: str = "Where to download videos and how to name the items." video_convert_mp4: str = ( "Videos are downloaded as MPEG Transport Stream (TS) files. With this option each video " - "will be converted to MP4. FFMPEG must be installed and added to your 'PATH' variable." + "will be converted to MP4. FFmpeg must be installed and the binary path must be configured." ) + path_binary_ffmpeg: str = "If you like to convert videos, this must point to your installed ffmpeg binary." metadata_cover_dimension: str = ( "The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640x 1280x1280." ) diff --git a/tidal_dl_ng/ui/dialog_settings.py b/tidal_dl_ng/ui/dialog_settings.py index eb358e1..b276b62 100644 --- a/tidal_dl_ng/ui/dialog_settings.py +++ b/tidal_dl_ng/ui/dialog_settings.py @@ -364,6 +364,24 @@ class Ui_DialogSettings: self.verticalLayout_2.addLayout(self.lh_path_fmt_mix) + self.lh_path_binary_ffmpeg = QHBoxLayout() + self.lh_path_binary_ffmpeg.setObjectName("lh_path_binary_ffmpeg") + self.l_icon_path_binary_ffmpeg = QLabel(self.gb_path) + self.l_icon_path_binary_ffmpeg.setObjectName("l_icon_path_binary_ffmpeg") + sizePolicy4.setHeightForWidth(self.l_icon_path_binary_ffmpeg.sizePolicy().hasHeightForWidth()) + self.l_icon_path_binary_ffmpeg.setSizePolicy(sizePolicy4) + + self.lh_path_binary_ffmpeg.addWidget(self.l_icon_path_binary_ffmpeg) + + self.l_path_binary_ffmpeg = QLabel(self.gb_path) + self.l_path_binary_ffmpeg.setObjectName("l_path_binary_ffmpeg") + sizePolicy3.setHeightForWidth(self.l_path_binary_ffmpeg.sizePolicy().hasHeightForWidth()) + self.l_path_binary_ffmpeg.setSizePolicy(sizePolicy3) + + self.lh_path_binary_ffmpeg.addWidget(self.l_path_binary_ffmpeg) + + self.verticalLayout_2.addLayout(self.lh_path_binary_ffmpeg) + self.horizontalLayout_2.addLayout(self.verticalLayout_2) self.verticalLayout = QVBoxLayout() @@ -432,6 +450,23 @@ class Ui_DialogSettings: self.verticalLayout.addLayout(self.horizontalLayout_8) + self.horizontalLayout_31 = QHBoxLayout() + self.horizontalLayout_31.setObjectName("horizontalLayout_31") + self.le_path_binary_ffmpeg = QLineEdit(self.gb_path) + self.le_path_binary_ffmpeg.setObjectName("le_path_binary_ffmpeg") + sizePolicy2.setHeightForWidth(self.le_path_binary_ffmpeg.sizePolicy().hasHeightForWidth()) + self.le_path_binary_ffmpeg.setSizePolicy(sizePolicy2) + self.le_path_binary_ffmpeg.setDragEnabled(True) + + self.horizontalLayout_31.addWidget(self.le_path_binary_ffmpeg) + + self.pb_path_binary_ffmpeg = QPushButton(self.gb_path) + self.pb_path_binary_ffmpeg.setObjectName("pb_path_binary_ffmpeg") + + self.horizontalLayout_31.addWidget(self.pb_path_binary_ffmpeg) + + self.verticalLayout.addLayout(self.horizontalLayout_31) + self.horizontalLayout_2.addLayout(self.verticalLayout) self.horizontalLayout_2.setStretch(1, 50) @@ -488,6 +523,9 @@ class Ui_DialogSettings: self.l_format_playlist.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_icon_format_mix.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_format_mix.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) + self.l_icon_path_binary_ffmpeg.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) + self.l_path_binary_ffmpeg.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.pb_download_base_path.setText(QCoreApplication.translate("DialogSettings", "...", None)) + self.pb_path_binary_ffmpeg.setText(QCoreApplication.translate("DialogSettings", "...", None)) # retranslateUi diff --git a/tidal_dl_ng/ui/dialog_settings.ui b/tidal_dl_ng/ui/dialog_settings.ui index acdb1cf..4dfa38c 100644 --- a/tidal_dl_ng/ui/dialog_settings.ui +++ b/tidal_dl_ng/ui/dialog_settings.ui @@ -518,6 +518,36 @@ + + + + + + + 0 + 0 + + + + TextLabel + + + + + + + + 0 + 0 + + + + TextLabel + + + + + @@ -588,6 +618,30 @@ + + + + + + + 0 + 0 + + + + true + + + + + + + ... + + + + +