Skip to content

Commit fc714e0

Browse files
authored
fix: Do not create command prompt window on subprocess (#436)
* fix: Do not create command prompt window on subcmd Patches files from abandoned libraries are located and updated in src/qt/helpers/vendored with modified sections labeld PATCHED. A wrapper around subprocess.Popen automatically sets the creation flag to no window on windows. * fix: Replace Popen in mediainfo_json decoder * fixup: Pipe stdin to stdin * chore: Exclude vendored dir from tooling checks * suppress mypy warnings
1 parent 85b6d9d commit fc714e0

File tree

7 files changed

+1596
-4
lines changed

7 files changed

+1596
-4
lines changed

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[tool.ruff]
2-
exclude = ["main_window.py", "home_ui.py", "resources.py", "resources_rc.py"]
2+
exclude = ["main_window.py", "home_ui.py", "resources.py", "resources_rc.py", "**/vendored/"]
33

44
[tool.mypy]
55
strict_optional = false
66
disable_error_code = ["union-attr", "annotation-unchecked", "import-untyped"]
77
explicit_package_bases = true
88
warn_unused_ignores = true
9-
exclude = ['tests']
9+
exclude = ['tests', 'src/qt/helpers/vendored']

tagstudio/src/qt/helpers/file_tester.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import ffmpeg
77
from pathlib import Path
88

9+
from src.qt.helpers.vendored.ffmpeg import _probe
10+
911

1012
def is_readable_video(filepath: Path | str):
1113
"""Test if a video is in a readable format. Examples of unreadable videos
@@ -15,7 +17,7 @@ def is_readable_video(filepath: Path | str):
1517
filepath (Path | str):
1618
"""
1719
try:
18-
probe = ffmpeg.probe(Path(filepath))
20+
probe = _probe(Path(filepath))
1921
for stream in probe["streams"]:
2022
# DRM check
2123
if stream.get("codec_tag_string") in [
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import subprocess
2+
import sys
3+
4+
5+
def promptless_Popen(
6+
args,
7+
bufsize=-1,
8+
executable=None,
9+
stdin=None,
10+
stdout=None,
11+
stderr=None,
12+
preexec_fn=None,
13+
close_fds=True,
14+
shell=False,
15+
cwd=None,
16+
env=None,
17+
universal_newlines=None,
18+
startupinfo=None,
19+
restore_signals=True,
20+
start_new_session=False,
21+
pass_fds=(),
22+
*,
23+
group=None,
24+
extra_groups=None,
25+
user=None,
26+
umask=-1,
27+
encoding=None,
28+
errors=None,
29+
text=None,
30+
pipesize=-1,
31+
process_group=None,
32+
):
33+
creation_flags = 0
34+
if sys.platform == "win32":
35+
creation_flags = subprocess.CREATE_NO_WINDOW
36+
37+
return subprocess.Popen(
38+
args=args,
39+
bufsize=bufsize,
40+
executable=executable,
41+
stdin=stdin,
42+
stdout=stdout,
43+
stderr=stderr,
44+
preexec_fn=preexec_fn,
45+
close_fds=close_fds,
46+
shell=shell,
47+
cwd=cwd,
48+
env=env,
49+
universal_newlines=universal_newlines,
50+
startupinfo=startupinfo,
51+
creationflags=creation_flags,
52+
restore_signals=restore_signals,
53+
start_new_session=start_new_session,
54+
pass_fds=pass_fds,
55+
group=group,
56+
extra_groups=extra_groups,
57+
user=user,
58+
umask=umask,
59+
encoding=encoding,
60+
errors=errors,
61+
text=text,
62+
pipesize=pipesize,
63+
process_group=process_group,
64+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (C) 2022 Karl Kroening (kkroening).
2+
# Licensed under the GPL-3.0 License.
3+
# Vendored from ffmpeg-python and ffmpeg-python PR#790 by amamic1803
4+
5+
import subprocess
6+
import json
7+
import sys
8+
9+
import ffmpeg
10+
11+
from src.qt.helpers.silent_popen import promptless_Popen
12+
13+
def _probe(filename, cmd='ffprobe', timeout=None, **kwargs):
14+
"""Run ffprobe on the specified file and return a JSON representation of the output.
15+
16+
Raises:
17+
:class:`ffmpeg.Error`: if ffprobe returns a non-zero exit code,
18+
an :class:`Error` is returned with a generic error message.
19+
The stderr output can be retrieved by accessing the
20+
``stderr`` property of the exception.
21+
"""
22+
args = [cmd, '-show_format', '-show_streams', '-of', 'json']
23+
args += ffmpeg._utils.convert_kwargs_to_cmd_line_args(kwargs)
24+
args += [filename]
25+
26+
# PATCHED
27+
p = promptless_Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
28+
communicate_kwargs = {}
29+
if timeout is not None:
30+
communicate_kwargs['timeout'] = timeout
31+
out, err = p.communicate(**communicate_kwargs)
32+
if p.returncode != 0:
33+
raise ffmpeg.Error('ffprobe', out, err)
34+
return json.loads(out.decode('utf-8'))

0 commit comments

Comments
 (0)