mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-01-31 23:29:10 +00:00
fix: restore environment before launching external programs (#707)
* rename promptless_Popen * linux: restore env before calling popen * windows: set dll directory to default before calling popen * ruff formatting suggestions * edited silent_popen docstring
This commit is contained in:
@@ -11,6 +11,7 @@ from pathlib import Path
|
||||
import structlog
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QLabel
|
||||
from src.qt.helpers.silent_popen import silent_Popen
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
@@ -38,7 +39,7 @@ def open_file(path: str | Path, file_manager: bool = False):
|
||||
|
||||
# For some reason, if the args are passed in a list, this will error when the
|
||||
# path has spaces, even while surrounded in double quotes.
|
||||
subprocess.Popen(
|
||||
silent_Popen(
|
||||
command_name + command_arg,
|
||||
shell=True,
|
||||
close_fds=True,
|
||||
@@ -47,7 +48,7 @@ def open_file(path: str | Path, file_manager: bool = False):
|
||||
)
|
||||
else:
|
||||
command = f'"{normpath}"'
|
||||
subprocess.Popen(
|
||||
silent_Popen(
|
||||
command,
|
||||
shell=True,
|
||||
close_fds=True,
|
||||
@@ -79,7 +80,7 @@ def open_file(path: str | Path, file_manager: bool = False):
|
||||
command_args = [str(path)]
|
||||
command = shutil.which(command_name)
|
||||
if command is not None:
|
||||
subprocess.Popen([command] + command_args, close_fds=True)
|
||||
silent_Popen([command] + command_args, close_fds=True)
|
||||
else:
|
||||
logger.info("Could not find command on system PATH", command=command_name)
|
||||
except Exception:
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
# Copyright (C) 2024 Travis Abendshien (CyanVoxel).
|
||||
# Licensed under the GPL-3.0 License.
|
||||
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
"""Implementation of subprocess.Popen that does not spawn console windows or log output."""
|
||||
"""Implementation of subprocess.Popen that does not spawn console windows or log output
|
||||
and sanitizes pyinstall environment variables."""
|
||||
|
||||
|
||||
def promptless_Popen( # noqa: N802
|
||||
def silent_Popen( # noqa: N802
|
||||
args,
|
||||
bufsize=-1,
|
||||
executable=None,
|
||||
@@ -21,6 +23,7 @@ def promptless_Popen( # noqa: N802
|
||||
env=None,
|
||||
universal_newlines=None,
|
||||
startupinfo=None,
|
||||
creationflags=0,
|
||||
restore_signals=True,
|
||||
start_new_session=False,
|
||||
pass_fds=(),
|
||||
@@ -36,9 +39,20 @@ def promptless_Popen( # noqa: N802
|
||||
process_group=None,
|
||||
):
|
||||
"""Call subprocess.Popen without creating a console window."""
|
||||
creation_flags = 0
|
||||
if sys.platform == "win32":
|
||||
creation_flags = subprocess.CREATE_NO_WINDOW
|
||||
creationflags |= subprocess.CREATE_NO_WINDOW
|
||||
import ctypes
|
||||
|
||||
ctypes.windll.kernel32.SetDllDirectoryW(None)
|
||||
elif (
|
||||
sys.platform == "linux"
|
||||
or sys.platform.startswith("freebsd")
|
||||
or sys.platform.startswith("openbsd")
|
||||
):
|
||||
# pass clean environment to the subprocess
|
||||
env = os.environ
|
||||
original_env = env.get("LD_LIBRARY_PATH_ORIG")
|
||||
env["LD_LIBRARY_PATH"] = original_env if original_env else ""
|
||||
|
||||
return subprocess.Popen(
|
||||
args=args,
|
||||
@@ -54,7 +68,7 @@ def promptless_Popen( # noqa: N802
|
||||
env=env,
|
||||
universal_newlines=universal_newlines,
|
||||
startupinfo=startupinfo,
|
||||
creationflags=creation_flags,
|
||||
creationflags=creationflags,
|
||||
restore_signals=restore_signals,
|
||||
start_new_session=start_new_session,
|
||||
pass_fds=pass_fds,
|
||||
|
||||
@@ -9,7 +9,7 @@ import subprocess
|
||||
|
||||
import ffmpeg
|
||||
import structlog
|
||||
from src.qt.helpers.silent_popen import promptless_Popen
|
||||
from src.qt.helpers.silent_popen import silent_Popen
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
@@ -44,7 +44,7 @@ def _probe(filename, cmd=FFPROBE_CMD, timeout=None, **kwargs):
|
||||
args += [filename]
|
||||
|
||||
# PATCHED
|
||||
p = promptless_Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p = silent_Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
communicate_kwargs = {}
|
||||
if timeout is not None:
|
||||
communicate_kwargs["timeout"] = timeout
|
||||
|
||||
@@ -40,7 +40,7 @@ from pydub.utils import (
|
||||
get_encoder_name,
|
||||
ratio_to_db,
|
||||
)
|
||||
from src.qt.helpers.silent_popen import promptless_Popen
|
||||
from src.qt.helpers.silent_popen import silent_Popen
|
||||
from src.qt.helpers.vendored.pydub.utils import _mediainfo_json
|
||||
|
||||
basestring = str
|
||||
@@ -606,7 +606,7 @@ class _AudioSegment:
|
||||
|
||||
with open(os.devnull, "rb") as devnull:
|
||||
# PATCHED
|
||||
p = promptless_Popen(
|
||||
p = silent_Popen(
|
||||
conversion_command, stdin=devnull, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
p_out, p_err = p.communicate()
|
||||
@@ -785,7 +785,7 @@ class _AudioSegment:
|
||||
log_conversion(conversion_command)
|
||||
|
||||
# PATCHED
|
||||
p = promptless_Popen(
|
||||
p = silent_Popen(
|
||||
conversion_command,
|
||||
stdin=stdin_parameter,
|
||||
stdout=subprocess.PIPE,
|
||||
@@ -1012,7 +1012,7 @@ class _AudioSegment:
|
||||
# read stdin / write stdout
|
||||
with open(os.devnull, "rb") as devnull:
|
||||
# PATCHED
|
||||
p = promptless_Popen(
|
||||
p = silent_Popen(
|
||||
conversion_command, stdin=devnull, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
p_out, p_err = p.communicate()
|
||||
|
||||
@@ -8,7 +8,7 @@ from pydub.utils import (
|
||||
get_extra_info,
|
||||
get_prober_name,
|
||||
)
|
||||
from src.qt.helpers.silent_popen import promptless_Popen
|
||||
from src.qt.helpers.silent_popen import silent_Popen
|
||||
|
||||
|
||||
def _mediainfo_json(filepath, read_ahead_limit=-1):
|
||||
@@ -38,7 +38,7 @@ def _mediainfo_json(filepath, read_ahead_limit=-1):
|
||||
|
||||
command = [prober, "-of", "json"] + command_args
|
||||
# PATCHED
|
||||
res = promptless_Popen(
|
||||
res = silent_Popen(
|
||||
command, stdin=stdin_parameter, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
output, stderr = res.communicate(input=stdin_data)
|
||||
|
||||
Reference in New Issue
Block a user