Merge pull request #66 from exislow/63-feature-provide-feedback-if-ffmpeg-not-found-on-path
63 feature provide feedback if ffmpeg not found on path
This commit is contained in:
+1
-1
@@ -170,7 +170,7 @@ profile = "black"
|
||||
multi_line_output = 3
|
||||
indent = 4
|
||||
color_output = true
|
||||
known_third_party = ["Crypto", "PySide6", "coloredlogs", "dataclasses_json", "ffmpeg", "m3u8", "mpegdash", "mutagen", "pathvalidate", "requests", "rich", "tidalapi", "typer"]
|
||||
known_third_party = ["Crypto", "PySide6", "coloredlogs", "dataclasses_json", "ffmpeg", "helper", "m3u8", "mpegdash", "mutagen", "pathvalidate", "requests", "rich", "tidalapi", "typer"]
|
||||
|
||||
[tool.mypy]
|
||||
# https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file
|
||||
|
||||
+50
-22
@@ -2,6 +2,7 @@ import os.path
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
|
||||
from helper.path import is_installed_ffmpeg
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
from tidalapi import Quality as QualityAudio
|
||||
|
||||
@@ -86,19 +87,39 @@ class DialogPreferences(QtWidgets.QDialog):
|
||||
pixmapi: QtWidgets.QStyle.StandardPixmap = QtWidgets.QStyle.SP_MessageBoxQuestion
|
||||
self.icon = self.style().standardIcon(pixmapi)
|
||||
|
||||
self.parameters_checkboxes = [
|
||||
"lyrics_embed",
|
||||
"lyrics_file",
|
||||
"video_download",
|
||||
"download_delay",
|
||||
"video_convert_mp4",
|
||||
]
|
||||
self.parameters_combo = [
|
||||
("skip_existing", SkipExisting),
|
||||
("quality_audio", QualityAudio),
|
||||
("quality_video", QualityVideo),
|
||||
("metadata_cover_dimension", CoverDimensions),
|
||||
]
|
||||
self._init_checkboxes()
|
||||
self._init_comboboxes()
|
||||
self._init_line_edit()
|
||||
|
||||
# Create an instance of the GUI
|
||||
self.ui = Ui_DialogSettings()
|
||||
|
||||
# Run the .setupUi() method to show the GUI
|
||||
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, int):
|
||||
if self.ui.cb_video_convert_mp4.isChecked():
|
||||
# Check if ffmpeg is in PATH otherwise show error message.
|
||||
if 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",
|
||||
"format_album",
|
||||
@@ -108,15 +129,22 @@ class DialogPreferences(QtWidgets.QDialog):
|
||||
"format_video",
|
||||
]
|
||||
|
||||
# Create an instance of the GUI
|
||||
self.ui = Ui_DialogSettings()
|
||||
def _init_comboboxes(self):
|
||||
self.parameters_combo = [
|
||||
("skip_existing", SkipExisting),
|
||||
("quality_audio", QualityAudio),
|
||||
("quality_video", QualityVideo),
|
||||
("metadata_cover_dimension", CoverDimensions),
|
||||
]
|
||||
|
||||
# Run the .setupUi() method to show the GUI
|
||||
self.ui.setupUi(self)
|
||||
# Set data.
|
||||
self.gui_populate()
|
||||
|
||||
self.exec()
|
||||
def _init_checkboxes(self):
|
||||
self.parameters_checkboxes = [
|
||||
"lyrics_embed",
|
||||
"lyrics_file",
|
||||
"video_download",
|
||||
"download_delay",
|
||||
"video_convert_mp4",
|
||||
]
|
||||
|
||||
def gui_populate(self):
|
||||
self.populate_checkboxes()
|
||||
@@ -190,7 +218,7 @@ class DialogPreferences(QtWidgets.QDialog):
|
||||
checkbox.setChecked(getattr(self.data, pn))
|
||||
|
||||
def accept(self):
|
||||
# Get settings. TODO
|
||||
# Get settings.
|
||||
self.to_settings()
|
||||
self.done(1)
|
||||
|
||||
|
||||
+11
-2
@@ -29,7 +29,7 @@ from tidal_dl_ng.constants import (
|
||||
)
|
||||
from tidal_dl_ng.helper.decryption import decrypt_file, decrypt_security_token
|
||||
from tidal_dl_ng.helper.exceptions import MediaMissing, UnknownManifestFormat
|
||||
from tidal_dl_ng.helper.path import check_file_exists, format_path_media, path_file_sanitize
|
||||
from tidal_dl_ng.helper.path import check_file_exists, format_path_media, is_installed_ffmpeg, path_file_sanitize
|
||||
from tidal_dl_ng.helper.tidal import (
|
||||
instantiate_media,
|
||||
items_results_all,
|
||||
@@ -82,6 +82,13 @@ class Download:
|
||||
self.progress = progress
|
||||
self.path_base = path_base
|
||||
|
||||
if not is_installed_ffmpeg() and self.settings.data.video_convert_mp4:
|
||||
self.settings.data.video_convert_mp4 = False
|
||||
self.fn_logger.error(
|
||||
"Cannot find FFmpeg in PATH. Videos can be downloaded but will not be processed. "
|
||||
"Make sure FFmpeg is installed correctly and present within your environmental PATH variable."
|
||||
)
|
||||
|
||||
def _download(
|
||||
self,
|
||||
media: Track | Video,
|
||||
@@ -284,7 +291,9 @@ class Download:
|
||||
def metadata_write(self, track: Track, path_file: str):
|
||||
result: bool = False
|
||||
release_date: str = (
|
||||
track.album.available_release_date.strftime("%Y-%m-%d") if track.album.available_release_date else track.album.release_date.strftime("%Y-%m-%d") if track.album.release_date else ""
|
||||
track.album.available_release_date.strftime("%Y-%m-%d")
|
||||
if track.album.available_release_date
|
||||
else track.album.release_date.strftime("%Y-%m-%d") if track.album.release_date else ""
|
||||
)
|
||||
copy_right: str = track.copyright if hasattr(track, "copyright") and track.copyright else ""
|
||||
isrc: str = track.isrc if hasattr(track, "isrc") and track.isrc else ""
|
||||
|
||||
+10
-10
@@ -287,16 +287,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
self.thread_it(self.list_items_show_result, point=point)
|
||||
|
||||
def on_download_list_media(self, point: QtCore.QPoint):
|
||||
self.b_download.setEnabled(False)
|
||||
self.b_download.setText("Downloading...")
|
||||
self.pb_download.setEnabled(False)
|
||||
self.pb_download.setText("Downloading...")
|
||||
|
||||
item = self.tr_lists_user.itemAt(point)
|
||||
media = item.data(3, QtCore.Qt.ItemDataRole.UserRole)
|
||||
|
||||
self.download(media, self.dl)
|
||||
|
||||
self.b_download.setText("Download")
|
||||
self.b_download.setEnabled(True)
|
||||
self.pb_download.setText("Download")
|
||||
self.pb_download.setEnabled(True)
|
||||
|
||||
def search_populate_results(self, query: str, type_media: SearchTypes):
|
||||
self.tr_results.clear()
|
||||
@@ -447,11 +447,11 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
return result
|
||||
|
||||
def _init_signals(self):
|
||||
self.b_download.clicked.connect(lambda: self.thread_it(self.on_download_results))
|
||||
self.pb_download.clicked.connect(lambda: self.thread_it(self.on_download_results))
|
||||
self.l_search.returnPressed.connect(
|
||||
lambda: self.search_populate_results(self.l_search.text(), self.cb_search_type.currentData())
|
||||
)
|
||||
self.b_search.clicked.connect(
|
||||
self.pb_search.clicked.connect(
|
||||
lambda: self.search_populate_results(self.l_search.text(), self.cb_search_type.currentData())
|
||||
)
|
||||
self.cb_quality_audio.currentIndexChanged.connect(self.on_quality_set_audio)
|
||||
@@ -543,8 +543,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
self.threadpool.start(worker)
|
||||
|
||||
def on_download_results(self):
|
||||
self.b_download.setEnabled(False)
|
||||
self.b_download.setText("Downloading...")
|
||||
self.pb_download.setEnabled(False)
|
||||
self.pb_download.setText("Downloading...")
|
||||
|
||||
items: [QtWidgets.QTreeWidgetItem] = self.tr_results.selectedItems()
|
||||
|
||||
@@ -564,8 +564,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
|
||||
self.download(media, self.dl, delay_track=download_delay)
|
||||
|
||||
self.b_download.setText("Download")
|
||||
self.b_download.setEnabled(True)
|
||||
self.pb_download.setText("Download")
|
||||
self.pb_download.setEnabled(True)
|
||||
|
||||
def download(self, media: Track | Album | Playlist | Video | Mix, dl: Download, delay_track: bool = False) -> None:
|
||||
self.s_pb_reset.emit()
|
||||
|
||||
@@ -2,6 +2,7 @@ import glob
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from pathlib import Path, PosixPath
|
||||
|
||||
from pathvalidate import sanitize_filename, sanitize_filepath
|
||||
@@ -10,7 +11,7 @@ from tidalapi import Album, Mix, Playlist, Track, UserPlaylist, Video
|
||||
|
||||
from tidal_dl_ng import __name_display__
|
||||
from tidal_dl_ng.constants import FILENAME_SANITIZE_PLACEHOLDER, UNIQUIFY_THRESHOLD, AudioExtensions, MediaType
|
||||
from tidal_dl_ng.helper.tidal import name_builder_artist, name_builder_title, name_builder_album_artist
|
||||
from tidal_dl_ng.helper.tidal import name_builder_album_artist, name_builder_artist, name_builder_title
|
||||
|
||||
|
||||
def path_home() -> str:
|
||||
@@ -261,3 +262,10 @@ def check_file_exists(path_file: str, extension_ignore: bool = False) -> bool:
|
||||
result = bool(sum([glob.glob(_file) for _file in path_files], []))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def is_installed_ffmpeg() -> bool:
|
||||
# Checks if ffmpeg is found in PATH.
|
||||
result: bool = bool(shutil.which("ffmpeg"))
|
||||
|
||||
return result
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from tidalapi import Album, Mix, Playlist, Session, Track, UserPlaylist, Video
|
||||
from tidalapi.artist import Role, Artist
|
||||
from tidalapi.artist import Artist, Role
|
||||
from tidalapi.session import SearchTypes
|
||||
|
||||
from tidal_dl_ng.constants import MediaType
|
||||
|
||||
+19
-19
@@ -187,26 +187,26 @@ class Ui_MainWindow:
|
||||
|
||||
self.lh_search.addWidget(self.cb_search_type)
|
||||
|
||||
self.b_search = QPushButton(self.w_central)
|
||||
self.b_search.setObjectName("b_search")
|
||||
self.pb_search = QPushButton(self.w_central)
|
||||
self.pb_search.setObjectName("pb_search")
|
||||
# if QT_CONFIG(statustip)
|
||||
self.b_search.setStatusTip("")
|
||||
self.pb_search.setStatusTip("")
|
||||
# endif // QT_CONFIG(statustip)
|
||||
# if QT_CONFIG(whatsthis)
|
||||
self.b_search.setWhatsThis("")
|
||||
self.pb_search.setWhatsThis("")
|
||||
# endif // QT_CONFIG(whatsthis)
|
||||
# if QT_CONFIG(accessibility)
|
||||
self.b_search.setAccessibleName("")
|
||||
self.pb_search.setAccessibleName("")
|
||||
# endif // QT_CONFIG(accessibility)
|
||||
# if QT_CONFIG(accessibility)
|
||||
self.b_search.setAccessibleDescription("")
|
||||
self.pb_search.setAccessibleDescription("")
|
||||
# endif // QT_CONFIG(accessibility)
|
||||
self.b_search.setText("Search")
|
||||
self.pb_search.setText("Search")
|
||||
# if QT_CONFIG(shortcut)
|
||||
self.b_search.setShortcut("")
|
||||
self.pb_search.setShortcut("")
|
||||
# endif // QT_CONFIG(shortcut)
|
||||
|
||||
self.lh_search.addWidget(self.b_search)
|
||||
self.lh_search.addWidget(self.pb_search)
|
||||
|
||||
self.lv_search_result.addLayout(self.lh_search)
|
||||
|
||||
@@ -315,29 +315,29 @@ class Ui_MainWindow:
|
||||
|
||||
self.lh_download.addWidget(self.cb_quality_video)
|
||||
|
||||
self.b_download = QPushButton(self.w_central)
|
||||
self.b_download.setObjectName("b_download")
|
||||
self.pb_download = QPushButton(self.w_central)
|
||||
self.pb_download.setObjectName("pb_download")
|
||||
# if QT_CONFIG(tooltip)
|
||||
self.b_download.setToolTip("")
|
||||
self.pb_download.setToolTip("")
|
||||
# endif // QT_CONFIG(tooltip)
|
||||
# if QT_CONFIG(statustip)
|
||||
self.b_download.setStatusTip("")
|
||||
self.pb_download.setStatusTip("")
|
||||
# endif // QT_CONFIG(statustip)
|
||||
# if QT_CONFIG(whatsthis)
|
||||
self.b_download.setWhatsThis("")
|
||||
self.pb_download.setWhatsThis("")
|
||||
# endif // QT_CONFIG(whatsthis)
|
||||
# if QT_CONFIG(accessibility)
|
||||
self.b_download.setAccessibleName("")
|
||||
self.pb_download.setAccessibleName("")
|
||||
# endif // QT_CONFIG(accessibility)
|
||||
# if QT_CONFIG(accessibility)
|
||||
self.b_download.setAccessibleDescription("")
|
||||
self.pb_download.setAccessibleDescription("")
|
||||
# endif // QT_CONFIG(accessibility)
|
||||
self.b_download.setText("Download")
|
||||
self.pb_download.setText("Download")
|
||||
# if QT_CONFIG(shortcut)
|
||||
self.b_download.setShortcut("")
|
||||
self.pb_download.setShortcut("")
|
||||
# endif // QT_CONFIG(shortcut)
|
||||
|
||||
self.lh_download.addWidget(self.b_download)
|
||||
self.lh_download.addWidget(self.pb_download)
|
||||
|
||||
self.lh_download.setStretch(0, 5)
|
||||
self.lh_download.setStretch(2, 5)
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="b_search">
|
||||
<widget class="QPushButton" name="pb_search">
|
||||
<property name="statusTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
@@ -436,7 +436,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="b_download">
|
||||
<widget class="QPushButton" name="pb_download">
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user