Skip to content

Commit

Permalink
fix: Do not create command prompt window on subprocess (#436)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
seakrueger authored Sep 3, 2024
1 parent 85b6d9d commit fc714e0
Show file tree
Hide file tree
Showing 7 changed files with 1,596 additions and 4 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[tool.ruff]
exclude = ["main_window.py", "home_ui.py", "resources.py", "resources_rc.py"]
exclude = ["main_window.py", "home_ui.py", "resources.py", "resources_rc.py", "**/vendored/"]

[tool.mypy]
strict_optional = false
disable_error_code = ["union-attr", "annotation-unchecked", "import-untyped"]
explicit_package_bases = true
warn_unused_ignores = true
exclude = ['tests']
exclude = ['tests', 'src/qt/helpers/vendored']
4 changes: 3 additions & 1 deletion tagstudio/src/qt/helpers/file_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import ffmpeg
from pathlib import Path

from src.qt.helpers.vendored.ffmpeg import _probe


def is_readable_video(filepath: Path | str):
"""Test if a video is in a readable format. Examples of unreadable videos
Expand All @@ -15,7 +17,7 @@ def is_readable_video(filepath: Path | str):
filepath (Path | str):
"""
try:
probe = ffmpeg.probe(Path(filepath))
probe = _probe(Path(filepath))
for stream in probe["streams"]:
# DRM check
if stream.get("codec_tag_string") in [
Expand Down
64 changes: 64 additions & 0 deletions tagstudio/src/qt/helpers/silent_popen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import subprocess
import sys


def promptless_Popen(
args,
bufsize=-1,
executable=None,
stdin=None,
stdout=None,
stderr=None,
preexec_fn=None,
close_fds=True,
shell=False,
cwd=None,
env=None,
universal_newlines=None,
startupinfo=None,
restore_signals=True,
start_new_session=False,
pass_fds=(),
*,
group=None,
extra_groups=None,
user=None,
umask=-1,
encoding=None,
errors=None,
text=None,
pipesize=-1,
process_group=None,
):
creation_flags = 0
if sys.platform == "win32":
creation_flags = subprocess.CREATE_NO_WINDOW

return subprocess.Popen(
args=args,
bufsize=bufsize,
executable=executable,
stdin=stdin,
stdout=stdout,
stderr=stderr,
preexec_fn=preexec_fn,
close_fds=close_fds,
shell=shell,
cwd=cwd,
env=env,
universal_newlines=universal_newlines,
startupinfo=startupinfo,
creationflags=creation_flags,
restore_signals=restore_signals,
start_new_session=start_new_session,
pass_fds=pass_fds,
group=group,
extra_groups=extra_groups,
user=user,
umask=umask,
encoding=encoding,
errors=errors,
text=text,
pipesize=pipesize,
process_group=process_group,
)
34 changes: 34 additions & 0 deletions tagstudio/src/qt/helpers/vendored/ffmpeg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (C) 2022 Karl Kroening (kkroening).
# Licensed under the GPL-3.0 License.
# Vendored from ffmpeg-python and ffmpeg-python PR#790 by amamic1803

import subprocess
import json
import sys

import ffmpeg

from src.qt.helpers.silent_popen import promptless_Popen

def _probe(filename, cmd='ffprobe', timeout=None, **kwargs):
"""Run ffprobe on the specified file and return a JSON representation of the output.
Raises:
:class:`ffmpeg.Error`: if ffprobe returns a non-zero exit code,
an :class:`Error` is returned with a generic error message.
The stderr output can be retrieved by accessing the
``stderr`` property of the exception.
"""
args = [cmd, '-show_format', '-show_streams', '-of', 'json']
args += ffmpeg._utils.convert_kwargs_to_cmd_line_args(kwargs)
args += [filename]

# PATCHED
p = promptless_Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
communicate_kwargs = {}
if timeout is not None:
communicate_kwargs['timeout'] = timeout
out, err = p.communicate(**communicate_kwargs)
if p.returncode != 0:
raise ffmpeg.Error('ffprobe', out, err)
return json.loads(out.decode('utf-8'))
Loading

0 comments on commit fc714e0

Please sign in to comment.